void BUrl::_ExplodeUrlString(const BString& url) { int16 urlIndex = 0; _ResetFields(); _ExtractProtocol(url, &urlIndex); _ExtractAuthority(url, &urlIndex); _ExtractPath(url, &urlIndex); _ExtractRequestAndFragment(url, &urlIndex); }
BUrl::BUrl() : fUrlString(), fProtocol(), fUser(), fPassword(), fHost(), fPort(0), fPath(), fRequest(), fHasAuthority(false) { _ResetFields(); }
BUrl::BUrl() : fUrlString(), fProtocol(), fUser(), fPassword(), fHost(), fPort(0), fPath(), fRequest(), fHasHost(false), fHasFragment(false) { _ResetFields(); }
void BUrl::_ExplodeUrlString(const BString& url) { // The regexp is provided in RFC3986 (URI generic syntax), Appendix B static RegExp urlMatcher( "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"); _ResetFields(); RegExp::MatchResult match = urlMatcher.Match(url.String()); if (!match.HasMatched()) return; // TODO error reporting // Scheme/Protocol url.CopyInto(fProtocol, match.GroupStartOffsetAt(1), match.GroupEndOffsetAt(1) - match.GroupStartOffsetAt(1)); if (!_IsProtocolValid()) { fHasProtocol = false; fProtocol.Truncate(0); } else fHasProtocol = true; // Authority (including user credentials, host, and port url.CopyInto(fAuthority, match.GroupStartOffsetAt(3), match.GroupEndOffsetAt(3) - match.GroupStartOffsetAt(3)); SetAuthority(fAuthority); // Path url.CopyInto(fPath, match.GroupStartOffsetAt(4), match.GroupEndOffsetAt(4) - match.GroupStartOffsetAt(4)); if (!fPath.IsEmpty()) fHasPath = true; // Query url.CopyInto(fRequest, match.GroupStartOffsetAt(6), match.GroupEndOffsetAt(6) - match.GroupStartOffsetAt(6)); if (!fRequest.IsEmpty()) fHasRequest = true; // Fragment url.CopyInto(fFragment, match.GroupStartOffsetAt(8), match.GroupEndOffsetAt(8) - match.GroupStartOffsetAt(8)); if (!fFragment.IsEmpty()) fHasFragment = true; }
BUrl::BUrl(BMessage* archive) : fUrlString(), fProtocol(), fUser(), fPassword(), fHost(), fPort(0), fPath(), fRequest(), fHasAuthority(false) { BString url; if (archive->FindString(kArchivedUrl, &url) == B_OK) SetUrlString(url); else _ResetFields(); }
/* * This function takes a URL in string-form and parses the components of the URL out. */ status_t BUrl::_ExplodeUrlString(const BString& url) { _ResetFields(); // RFC3986, Appendix C; the URL should not contain whitespace or delimiters // by this point. if (_ContainsDelimiter(url)) return B_BAD_VALUE; explode_url_parse_state state = EXPLODE_PROTOCOL; int32 offset = 0; int32 length = url.Length(); const char *url_c = url.String(); // The regexp is provided in RFC3986 (URI generic syntax), Appendix B // ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))? // The ensuing logic attempts to simulate the behaviour of extracting the groups // from the string without requiring a group-capable regex engine. while (offset < length) { switch (state) { case EXPLODE_PROTOCOL: { int32 end_protocol = char_offset_until_fn_false(url_c, length, offset, explode_is_protocol_char); if (end_protocol < length) { SetProtocol(BString(&url_c[offset], end_protocol - offset)); state = EXPLODE_PROTOCOLTERMINATOR; offset = end_protocol; } else { // No protocol was found, try parsing from the string // start, beginning with authority or path SetProtocol(""); offset = 0; state = EXPLODE_AUTHORITYORPATH; } break; } case EXPLODE_PROTOCOLTERMINATOR: { if (url[offset] == ':') { offset++; } else { // No protocol was found, try parsing from the string // start, beginning with authority or path SetProtocol(""); offset = 0; } state = EXPLODE_AUTHORITYORPATH; break; } case EXPLODE_AUTHORITYORPATH: { // The authority must start with //. If it isn't there, skip // to parsing the path. if (strncmp(&url_c[offset], "//", 2) == 0) { state = EXPLODE_AUTHORITY; offset += 2; } else { state = EXPLODE_PATH; } break; } case EXPLODE_AUTHORITY: { int end_authority = char_offset_until_fn_false(url_c, length, offset, explode_is_authority_char); SetAuthority(BString(&url_c[offset], end_authority - offset)); state = EXPLODE_PATH; offset = end_authority; break; } case EXPLODE_PATH: { int end_path = char_offset_until_fn_false(url_c, length, offset, explode_is_path_char); SetPath(BString(&url_c[offset], end_path - offset)); state = EXPLODE_REQUEST; offset = end_path; break; } case EXPLODE_REQUEST: // query { if (url_c[offset] == '?') { offset++; int end_request = char_offset_until_fn_false(url_c, length, offset, explode_is_request_char); SetRequest(BString(&url_c[offset], end_request - offset)); offset = end_request; } state = EXPLODE_FRAGMENT; break; } case EXPLODE_FRAGMENT: { if (url_c[offset] == '#') { offset++; SetFragment(BString(&url_c[offset], length - offset)); offset = length; } state = EXPLODE_COMPLETE; break; } case EXPLODE_COMPLETE: // should never be reached - keeps the compiler happy break; } } return B_OK; }