bool wxURI::ParseIPvFuture(const wxChar*& uri) { // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) if (*++uri != wxT('v') || !IsHex(*++uri)) return false; while (IsHex(*++uri)) {} if (*uri != wxT('.') || !(IsUnreserved(*++uri) || IsSubDelim(*uri) || *uri == wxT(':'))) return false; while(IsUnreserved(*++uri) || IsSubDelim(*uri) || *uri == wxT(':')) {} return true; }
const char* wxURI::ParseUserInfo(const char* uri) { const char * const start = uri; // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) while ( *uri && *uri != '@' && *uri != '/' && *uri != '#' && *uri != '?' ) { if ( IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == ':' ) m_userinfo += *uri++; else AppendNextEscaped(m_userinfo, uri); } if ( *uri++ == '@' ) { // valid userinfo m_fields |= wxURI_USERINFO; } else { uri = start; // rewind m_userinfo.clear(); } 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; }
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 char* wxURI::ParseFragment(const char* uri) { // fragment = *( pchar / "/" / "?" ) if ( *uri == '#' ) { ++uri; while ( *uri ) { if ( IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == ':' || *uri == '@' || *uri == '/' || *uri == '?') m_fragment += *uri++; else AppendNextEscaped(m_fragment, uri); } m_fields |= wxURI_FRAGMENT; } return uri; }
const char* wxURI::ParseQuery(const char* uri) { // query = *( pchar / "/" / "?" ) if ( *uri == '?' ) { ++uri; while ( *uri && *uri != '#' ) { if ( IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == ':' || *uri == '@' || *uri == '/' || *uri == '?' ) m_query += *uri++; else AppendNextEscaped(m_query, uri); } m_fields |= wxURI_QUERY; } 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 char* wxURI::ParsePath(const char* 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 ( IsEndPath(*uri) ) return uri; const bool isAbs = *uri == '/'; if ( isAbs ) m_path += *uri++; wxArrayString segments; wxString segment; for ( ;; ) { const bool endPath = IsEndPath(*uri); if ( endPath || *uri == '/' ) { // end of a segment, look at what we got if ( segment == ".." ) { if ( !segments.empty() && *segments.rbegin() != ".." ) segments.pop_back(); else if ( !isAbs ) segments.push_back(".."); } else if ( segment == "." ) { // normally we ignore "." but the last one should be taken into // account as "path/." is the same as "path/" and not just "path" if ( endPath ) segments.push_back(""); } else // normal segment { segments.push_back(segment); } if ( endPath ) break; segment.clear(); ++uri; continue; } if ( IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == ':' || *uri == '@' ) segment += *uri++; else AppendNextEscaped(segment, uri); } m_path += wxJoin(segments, '/', '\0'); m_fields |= wxURI_PATH; return uri; }
const char* wxURI::ParseServer(const char* uri) { const char * const start = uri; // host = IP-literal / IPv4address / reg-name // IP-literal = "[" ( IPv6address / IPvFuture ) "]" if (*uri == '[') { ++uri; if (ParseIPv6address(uri) && *uri == ']') { m_hostType = wxURI_IPV6ADDRESS; m_server.assign(start + 1, uri - start - 1); ++uri; } else { uri = start + 1; // skip the leading '[' again if (ParseIPvFuture(uri) && *uri == ']') { m_hostType = wxURI_IPVFUTURE; m_server.assign(start + 1, uri - start - 1); ++uri; } else // unrecognized IP literal { uri = start; } } } else // IPv4 or a reg-name { if (ParseIPv4address(uri)) { m_hostType = wxURI_IPV4ADDRESS; m_server.assign(start, uri - start); } else { uri = start; } } if ( m_hostType == wxURI_REGNAME ) { uri = start; // reg-name = *( unreserved / pct-encoded / sub-delims ) while ( *uri && *uri != '/' && *uri != ':' && *uri != '#' && *uri != '?' ) { if ( IsUnreserved(*uri) || IsSubDelim(*uri) ) m_server += *uri++; else AppendNextEscaped(m_server, uri); } } m_fields |= wxURI_SERVER; 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::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; }