uri.cpp revision 7b4c4bb29760b28b5727231ad446462a5b0cc01a
/* $Id$ */
/** @file
* IPRT - Uniform Resource Identifier handling.
*/
/*
* Copyright (C) 2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
/* General URI format:
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
*/
/*******************************************************************************
* Private RTUri helper *
*******************************************************************************/
/* The following defines characters which have to be % escaped:
control = 00-1F
space = ' '
delims = '<' , '>' , '#' , '%' , '"'
unwise = '{' , '}' , '|' , '\' , '^' , '[' , ']' , '`'
*/
#define URI_EXCLUDED(a) \
((a) >= 0x0 && (a) <= 0x20) \
|| ((a) >= 0x5B && (a) <= 0x5E) \
|| ((a) >= 0x7B && (a) <= 0x7D) \
|| (a) == '<' || (a) == '>' || (a) == '#' \
|| (a) == '%' || (a) == '"' || (a) == '`'
{
if (!pszString)
return NULL;
int rc = VINF_SUCCESS;
/* The new string can be max 3 times in size of the original string. */
if (!pszNew)
return NULL;
{
{
char szNum[3] = { 0, 0, 0 };
}
else
}
if (RT_SUCCESS(rc))
{
{
/* If the source and target strings have different size, recreate
* the target string with the correct size. */
}
else
}
else
return pszRes;
}
{
if (!pszString)
return NULL;
int rc = VINF_SUCCESS;
/* The new string can only get smaller. */
if (!pszNew)
return NULL;
{
{
/* % encoding means the percent sign and exactly 2 hexadecimal
* digits describing the ASCII number of the character. */
++iIn;
char szNum[3];
if (RT_FAILURE(rc))
break;
}
else
++iOut;
}
if (RT_SUCCESS(rc))
{
{
/* If the source and target strings have different size, recreate
* the target string with the correct size. */
}
else
}
else
return pszRes;
}
{
/* The scheme has to end with ':'. */
{
if (pszUri[i] == ':')
{
*piEnd = i;
return true;
}
++i;
}
return false;
}
static bool rtUriCheckAuthorityStart(const char *pszUri, size_t iStart, size_t cbLen, size_t *piStart)
{
/* The authority have to start with '//' */
if ( cbLen >= 2
{
return true;
}
return false;
}
{
/* The authority can end with '/' || '?' || '#'. */
{
if ( pszUri[i] == '/'
|| pszUri[i] == '?'
|| pszUri[i] == '#')
{
*piEnd = i;
return true;
}
++i;
}
return false;
}
{
/* The path could start with a '/'. */
if ( cbLen >= 1
{
return true;
}
/* '?' || '#' means there is no path. */
if ( cbLen >= 1
return false;
/* All other values are allowed. */
return true;
}
{
/* The path can end with '?' || '#'. */
{
if ( pszUri[i] == '?'
|| pszUri[i] == '#')
{
*piEnd = i;
return true;
}
++i;
}
return false;
}
{
/* The query start with a '?'. */
if ( cbLen >= 1
{
return true;
}
return false;
}
{
/* The query can end with '?' || '#'. */
{
if (pszUri[i] == '#')
{
*piEnd = i;
return true;
}
++i;
}
return false;
}
static bool rtUriCheckFragmentStart(const char *pszUri, size_t iStart, size_t cbLen, size_t *piStart)
{
/* The fragment start with a '#'. */
if ( cbLen >= 1
{
return true;
}
return false;
}
/*******************************************************************************
* Public RTUri interface *
*******************************************************************************/
/*******************************************************************************
* Generic Uri methods *
*******************************************************************************/
RTR3DECL(char *) RTUriCreate(const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, const char *pszFragment)
{
if (!pszScheme) /* Scheme is minimum requirement */
return NULL;
char *pszResult = 0;
char *pszAuthority1 = 0;
char *pszPath1 = 0;
char *pszQuery1 = 0;
char *pszFragment1 = 0;
do
{
/* Create the percent encoded strings and calculate the necessary uri
* length. */
if (pszAuthority)
{
if (!pszAuthority1)
break;
}
if (pszPath)
{
if (!pszPath1)
break;
}
if (pszQuery)
{
if (!pszQuery1)
break;
}
if (pszFragment)
{
if (!pszFragment1)
break;
}
if (!pszResult)
break;
/* Compose the target uri string. */
if (pszAuthority1)
{
}
if (pszPath1)
{
}
if (pszQuery1)
{
}
if (pszFragment1)
{
}
}while (0);
/* Cleanup */
if (pszAuthority1)
if (pszPath1)
if (pszQuery1)
if (pszFragment1)
return pszResult;
}
{
bool fRes = false;
if (pszTmp)
{
}
return fRes;
}
{
return NULL;
}
{
/* Find the end of the scheme. */
return NULL; /* no URI */
else
++iPos1; /* Skip ':' */
/* Find the start of the authority. */
{
/* Find the end of the authority. If not found, the rest of the string
* is used. */
else
return NULL;
}
return NULL;
}
{
/* Find the end of the scheme. */
return NULL; /* no URI */
else
++iPos1; /* Skip ':' */
/* Find the start of the authority. */
{
/* Find the end of the authority. If not found, then there is no path
* component, cause the authority is the rest of the string. */
return NULL; /* no path! */
}
/* Find the start of the path */
{
/* Search for the end of the scheme. */
}
return NULL;
}
{
/* Find the end of the scheme. */
return NULL; /* no URI */
else
++iPos1; /* Skip ':' */
/* Find the start of the authority. */
{
/* Find the end of the authority. If not found, then there is no path
* component, cause the authority is the rest of the string. */
return NULL; /* no path! */
}
/* Find the start of the path */
{
/* Find the end of the path. If not found, then there is no query
* component, cause the path is the rest of the string. */
return NULL; /* no query! */
}
/* Find the start of the query */
{
/* Search for the end of the query. */
}
return NULL;
}
{
/* Find the end of the scheme. */
return NULL; /* no URI */
else
++iPos1; /* Skip ':' */
/* Find the start of the authority. */
{
/* Find the end of the authority. If not found, then there is no path
* component, cause the authority is the rest of the string. */
return NULL; /* no path! */
}
/* Find the start of the path */
{
/* Find the end of the path. If not found, then there is no query
* component, cause the path is the rest of the string. */
return NULL; /* no query! */
}
/* Find the start of the query */
{
/* Find the end of the query If not found, then there is no fragment
* component, cause the query is the rest of the string. */
return NULL; /* no query! */
}
/* Find the start of the fragment */
{
/* There could be nothing behind a fragment. So use the rest of the
* string. */
}
return NULL;
}
/*******************************************************************************
* File Uri methods *
*******************************************************************************/
{
if (!pszPath)
return NULL;
char *pszResult = 0;
char *pszPath1 = 0;
do
{
/* Create the percent encoded strings and calculate the necessary uri
* length. */
if (!pszPath1)
break;
if (pszPath1[0] != '/')
++cbSize;
if (!pszResult)
break;
/* Compose the target uri string. */
if (pszPath1[0] != '/')
}while (0);
/* Cleanup */
if (pszPath1)
return pszResult;
}
{
}
{
/* Find the end of the scheme. */
return NULL; /* no URI */
else
++iPos1; /* Skip ':' */
/* Check that this is a file Uri */
return NULL;
/* Find the start of the authority. */
{
/* Find the end of the authority. If not found, then there is no path
* component, cause the authority is the rest of the string. */
return NULL; /* no path! */
}
/* Find the start of the path */
{
/* Auto is based on the current OS. */
if (uFormat == URI_FILE_FORMAT_AUTO)
#ifdef RT_OS_WINDOWS
#else /* RT_OS_WINDOWS */
#endif /* !RT_OS_WINDOWS */
if ( uFIntern != URI_FILE_FORMAT_UNIX
++iPos4;
/* Search for the end of the scheme. */
{
if (uFIntern == URI_FILE_FORMAT_UNIX)
return RTPathChangeToUnixSlashes(pszPath, true);
else if (uFIntern == URI_FILE_FORMAT_WIN)
return RTPathChangeToDosSlashes(pszPath, true);
else
{
return NULL;
}
}
}
return NULL;
}