uri.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,303 行 · 第 1/3 页
CPP
1,303 行
// authority = [ userinfo "@" ] host [ ":" port ]
if (*uri == wxT('/') && *(uri+1) == wxT('/'))
{
//skip past the two slashes
uri += 2;
// ############# DEVIATION FROM RFC #########################
// Don't parse the server component for file URIs
if(m_scheme != wxT("file"))
{
//normal way
uri = ParseUserInfo(uri);
uri = ParseServer(uri);
return ParsePort(uri);
}
}
return uri;
}
const wxChar* wxURI::ParseUserInfo(const wxChar* uri)
{
wxASSERT(uri != NULL);
//copy of the uri - used for figuring out
//length of each component
const wxChar* uricopy = uri;
// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
while(*uri && *uri != wxT('@') && *uri != wxT('/') && *uri != wxT('#') && *uri != wxT('?'))
{
if(IsUnreserved(*uri) ||
IsSubDelim(*uri) || *uri == wxT(':'))
m_userinfo += *uri++;
else if (IsEscape(uri))
{
m_userinfo += *uri++;
m_userinfo += *uri++;
m_userinfo += *uri++;
}
else
Escape(m_userinfo, *uri++);
}
if(*uri == wxT('@'))
{
//valid userinfo
m_fields |= wxURI_USERINFO;
uricopy = ++uri;
}
else
m_userinfo = wxEmptyString;
return uricopy;
}
const wxChar* wxURI::ParseServer(const wxChar* uri)
{
wxASSERT(uri != NULL);
//copy of the uri - used for figuring out
//length of each component
const wxChar* uricopy = uri;
// host = IP-literal / IPv4address / reg-name
// IP-literal = "[" ( IPv6address / IPvFuture ) "]"
if (*uri == wxT('['))
{
++uri; //some compilers don't support *&ing a ++*
if (ParseIPv6address(uri) && *uri == wxT(']'))
{
++uri;
m_hostType = wxURI_IPV6ADDRESS;
wxStringBufferLength theBuffer(m_server, uri - uricopy);
wxTmemcpy(theBuffer, uricopy, uri-uricopy);
theBuffer.SetLength(uri-uricopy);
}
else
{
uri = uricopy;
++uri; //some compilers don't support *&ing a ++*
if (ParseIPvFuture(uri) && *uri == wxT(']'))
{
++uri;
m_hostType = wxURI_IPVFUTURE;
wxStringBufferLength theBuffer(m_server, uri - uricopy);
wxTmemcpy(theBuffer, uricopy, uri-uricopy);
theBuffer.SetLength(uri-uricopy);
}
else
uri = uricopy;
}
}
else
{
if (ParseIPv4address(uri))
{
m_hostType = wxURI_IPV4ADDRESS;
wxStringBufferLength theBuffer(m_server, uri - uricopy);
wxTmemcpy(theBuffer, uricopy, uri-uricopy);
theBuffer.SetLength(uri-uricopy);
}
else
uri = uricopy;
}
if(m_hostType == wxURI_REGNAME)
{
uri = uricopy;
// reg-name = *( unreserved / pct-encoded / sub-delims )
while(*uri && *uri != wxT('/') && *uri != wxT(':') && *uri != wxT('#') && *uri != wxT('?'))
{
if(IsUnreserved(*uri) || IsSubDelim(*uri))
m_server += *uri++;
else if (IsEscape(uri))
{
m_server += *uri++;
m_server += *uri++;
m_server += *uri++;
}
else
Escape(m_server, *uri++);
}
}
//mark the server as valid
m_fields |= wxURI_SERVER;
return uri;
}
const wxChar* wxURI::ParsePort(const wxChar* uri)
{
wxASSERT(uri != NULL);
// port = *DIGIT
if(*uri == wxT(':'))
{
++uri;
while(IsDigit(*uri))
{
m_port += *uri++;
}
//mark the port as valid
m_fields |= wxURI_PORT;
}
return uri;
}
const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormalize)
{
wxASSERT(uri != NULL);
//copy of the uri - used for figuring out
//length of each component
const wxChar* uricopy = uri;
/// hier-part = "//" authority path-abempty
/// / path-absolute
/// / path-rootless
/// / path-empty
///
/// relative-part = "//" authority path-abempty
/// / path-absolute
/// / path-noscheme
/// / path-empty
///
/// path-abempty = *( "/" segment )
/// path-absolute = "/" [ segment-nz *( "/" segment ) ]
/// path-noscheme = segment-nz-nc *( "/" segment )
/// path-rootless = segment-nz *( "/" segment )
/// path-empty = 0<pchar>
///
/// segment = *pchar
/// segment-nz = 1*pchar
/// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
/// ; non-zero-length segment without any colon ":"
///
/// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
if (*uri == wxT('/'))
{
m_path += *uri++;
while(*uri && *uri != wxT('#') && *uri != wxT('?'))
{
if( IsUnreserved(*uri) || IsSubDelim(*uri) ||
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/'))
m_path += *uri++;
else if (IsEscape(uri))
{
m_path += *uri++;
m_path += *uri++;
m_path += *uri++;
}
else
Escape(m_path, *uri++);
}
if (bNormalize)
{
wxStringBufferLength theBuffer(m_path, m_path.length() + 1);
#if wxUSE_STL
wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1);
#endif
Normalize(theBuffer, true);
theBuffer.SetLength(wxStrlen(theBuffer));
}
//mark the path as valid
m_fields |= wxURI_PATH;
}
else if(*uri) //Relative path
{
if (bReference)
{
//no colon allowed
while(*uri && *uri != wxT('#') && *uri != wxT('?'))
{
if(IsUnreserved(*uri) || IsSubDelim(*uri) ||
*uri == wxT('@') || *uri == wxT('/'))
m_path += *uri++;
else if (IsEscape(uri))
{
m_path += *uri++;
m_path += *uri++;
m_path += *uri++;
}
else
Escape(m_path, *uri++);
}
}
else
{
while(*uri && *uri != wxT('#') && *uri != wxT('?'))
{
if(IsUnreserved(*uri) || IsSubDelim(*uri) ||
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/'))
m_path += *uri++;
else if (IsEscape(uri))
{
m_path += *uri++;
m_path += *uri++;
m_path += *uri++;
}
else
Escape(m_path, *uri++);
}
}
if (uri != uricopy)
{
if (bNormalize)
{
wxStringBufferLength theBuffer(m_path, m_path.length() + 1);
#if wxUSE_STL
wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1);
#endif
Normalize(theBuffer);
theBuffer.SetLength(wxStrlen(theBuffer));
}
//mark the path as valid
m_fields |= wxURI_PATH;
}
}
return uri;
}
const wxChar* wxURI::ParseQuery(const wxChar* uri)
{
wxASSERT(uri != NULL);
// query = *( pchar / "/" / "?" )
if (*uri == wxT('?'))
{
++uri;
while(*uri && *uri != wxT('#'))
{
if (IsUnreserved(*uri) || IsSubDelim(*uri) ||
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?'))
m_query += *uri++;
else if (IsEscape(uri))
{
m_query += *uri++;
m_query += *uri++;
m_query += *uri++;
}
else
Escape(m_query, *uri++);
}
//mark the server as valid
m_fields |= wxURI_QUERY;
}
return uri;
}
const wxChar* wxURI::ParseFragment(const wxChar* uri)
{
wxASSERT(uri != NULL);
// fragment = *( pchar / "/" / "?" )
if (*uri == wxT('#'))
{
++uri;
while(*uri)
{
if (IsUnreserved(*uri) || IsSubDelim(*uri) ||
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?'))
m_fragment += *uri++;
else if (IsEscape(uri))
{
m_fragment += *uri++;
m_fragment += *uri++;
m_fragment += *uri++;
}
else
Escape(m_fragment, *uri++);
}
//mark the server as valid
m_fields |= wxURI_FRAGMENT;
}
return uri;
}
// ---------------------------------------------------------------------------
// Resolve
//
// Builds missing components of this uri from a base uri
//
// A version of the algorithm outlined in the RFC is used here
// (it is shown in comments)
//
// Note that an empty URI inherits all components
// ---------------------------------------------------------------------------
void wxURI::Resolve(const wxURI& base, int flags)
{
wxASSERT_MSG(!base.IsReference(),
wxT("wxURI to inherit from must not be a reference!"));
// If we arn't being strict, enable the older (pre-RFC2396)
// loophole that allows this uri to inherit other
// properties from the base uri - even if the scheme
// is defined
if ( !(flags & wxURI_STRICT) &&
HasScheme() && base.HasScheme() &&
m_scheme == base.m_scheme )
{
m_fields -= wxURI_SCHEME;
}
// Do nothing if this is an absolute wxURI
// if defined(R.scheme) then
// T.scheme = R.scheme;
// T.authority = R.authority;
// T.path = remove_dot_segments(R.path);
// T.query = R.query;
if (HasScheme())
{
return;
}
//No scheme - inherit
m_scheme = base.m_scheme;
m_fields |= wxURI_SCHEME;
// All we need to do for relative URIs with an
// authority component is just inherit the scheme
// if defined(R.authority) then
// T.authority = R.authority;
// T.path = remove_dot_segments(R.path);
// T.query = R.query;
if (HasServer())
{
return;
}
//No authority - inherit
if (base.HasUserInfo())
{
m_userinfo = base.m_userinfo;
m_fields |= wxURI_USERINFO;
}
m_server = base.m_server;
m_hostType = base.m_hostType;
m_fields |= wxURI_SERVER;
if (base.HasPort())
{
m_port = base.m_port;
m_fields |= wxURI_PORT;
}
// Simple path inheritance from base
if (!HasPath())
{
// T.path = Base.path;
m_path = base.m_path;
m_fields |= wxURI_PATH;
// if defined(R.query) then
// T.query = R.query;
// else
// T.query = Base.query;
// endif;
if (!HasQuery())
{
m_query = base.m_query;
m_fields |= wxURI_QUERY;
}
}
else
{
// if (R.path starts-with "/") then
// T.path = remove_dot_segments(R.path);
// else
// T.path = merge(Base.path, R.path);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?