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; }
bool wxURI::ParseIPv6address(const char*& uri) { // IPv6address = 6( h16 ":" ) ls32 // / "::" 5( h16 ":" ) ls32 // / [ h16 ] "::" 4( h16 ":" ) ls32 // / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 // / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 // / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 // / [ *4( h16 ":" ) h16 ] "::" ls32 // / [ *5( h16 ":" ) h16 ] "::" h16 // / [ *6( h16 ":" ) h16 ] "::" size_t numPrefix = 0, maxPostfix; bool bEndHex = false; for( ; numPrefix < 6; ++numPrefix) { if(!ParseH16(uri)) { --uri; bEndHex = true; break; } if(*uri != ':') { break; } } if(!bEndHex && !ParseH16(uri)) { --uri; if (numPrefix) return false; if (*uri == ':') { if (*++uri != ':') return false; maxPostfix = 5; } else maxPostfix = 6; } else { if (*uri != ':' || *(uri+1) != ':') { if (numPrefix != 6) return false; while (*--uri != ':') {} ++uri; const char * const start = uri; //parse ls32 // ls32 = ( h16 ":" h16 ) / IPv4address if (ParseH16(uri) && *uri == ':' && ParseH16(uri)) return true; uri = start; if (ParseIPv4address(uri)) return true; else return false; } else { uri += 2; if (numPrefix > 3) maxPostfix = 0; else maxPostfix = 4 - numPrefix; } } bool bAllowAltEnding = maxPostfix == 0; for(; maxPostfix != 0; --maxPostfix) { if(!ParseH16(uri) || *uri != ':') return false; } if(numPrefix <= 4) { const char * const start = uri; //parse ls32 // ls32 = ( h16 ":" h16 ) / IPv4address if (ParseH16(uri) && *uri == ':' && ParseH16(uri)) return true; uri = start; if (ParseIPv4address(uri)) return true; uri = start; if (!bAllowAltEnding) return false; } if(numPrefix <= 5 && ParseH16(uri)) return true; return true; }
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; }