295 } 296 } 297 return -1; 298 } 299 300 static inline void checkEncodedString(const String& url) 301 { 302 ASSERT_UNUSED(url, url.containsOnlyASCII()); 303 ASSERT_UNUSED(url, url.isEmpty() || isSchemeFirstChar(url[0])); 304 } 305 306 inline bool URL::protocolIs(const String& string, const char* protocol) 307 { 308 return WebCore::protocolIs(string, protocol); 309 } 310 311 void URL::invalidate() 312 { 313 m_isValid = false; 314 m_protocolIsInHTTPFamily = false; 315 m_schemeEnd = 0; 316 m_userStart = 0; 317 m_userEnd = 0; 318 m_passwordEnd = 0; 319 m_hostEnd = 0; 320 m_portEnd = 0; 321 m_pathEnd = 0; 322 m_pathAfterLastSlash = 0; 323 m_queryEnd = 0; 324 m_fragmentEnd = 0; 325 } 326 327 URL::URL(ParsedURLStringTag, const String& url) 328 { 329 parse(url); 330 ASSERT(url == m_string); 331 } 332 333 URL::URL(const URL& base, const String& relative) 334 { 408 } 409 if (*p == ':') { 410 if (p[1] != '/' && equalIgnoringCase(base.protocol(), String(str, p - str)) && base.isHierarchical()) 411 str = p + 1; 412 else 413 absolute = true; 414 } 415 } 416 417 CharBuffer parseBuffer; 418 419 if (absolute) { 420 parse(str, &relative); 421 } else { 422 // If the base is empty or opaque (e.g. data: or javascript:), then the URL is invalid 423 // unless the relative URL is a single fragment. 424 if (!base.isHierarchical()) { 425 if (str[0] == '#') { 426 appendASCII(base.m_string.left(base.m_queryEnd), str, len, parseBuffer); 427 parse(parseBuffer.data(), &relative); 428 } else { 429 m_string = relative; 430 invalidate(); 431 } 432 return; 433 } 434 435 switch (str[0]) { 436 case '\0': 437 // The reference is empty, so this is a reference to the same document with any fragment identifier removed. 438 *this = base; 439 removeFragmentIdentifier(); 440 break; 441 case '#': { 442 // must be fragment-only reference 443 appendASCII(base.m_string.left(base.m_queryEnd), str, len, parseBuffer); 444 parse(parseBuffer.data(), &relative); 445 break; 446 } 447 case '?': { 1159 return; 1160 } 1161 1162 int userStart = schemeEnd + 1; 1163 int userEnd; 1164 int passwordStart; 1165 int passwordEnd; 1166 int hostStart; 1167 int hostEnd; 1168 int portStart; 1169 int portEnd; 1170 1171 bool hierarchical = url[schemeEnd + 1] == '/'; 1172 bool hasSecondSlash = hierarchical && url[schemeEnd + 2] == '/'; 1173 1174 bool isFile = schemeEnd == 4 1175 && isLetterMatchIgnoringCase(url[0], 'f') 1176 && isLetterMatchIgnoringCase(url[1], 'i') 1177 && isLetterMatchIgnoringCase(url[2], 'l') 1178 && isLetterMatchIgnoringCase(url[3], 'e'); 1179 1180 m_protocolIsInHTTPFamily = isLetterMatchIgnoringCase(url[0], 'h') 1181 && isLetterMatchIgnoringCase(url[1], 't') 1182 && isLetterMatchIgnoringCase(url[2], 't') 1183 && isLetterMatchIgnoringCase(url[3], 'p') 1184 && (url[4] == ':' || (isLetterMatchIgnoringCase(url[4], 's') && url[5] == ':')); 1185 1186 if ((hierarchical && hasSecondSlash) || isNonFileHierarchicalScheme(url, schemeEnd)) { 1187 // The part after the scheme is either a net_path or an abs_path whose first path segment is empty. 1188 // Attempt to find an authority. 1189 // FIXME: Authority characters may be scanned twice, and it would be nice to be faster. 1190 1191 if (hierarchical) 1192 userStart++; 1193 if (hasSecondSlash) 1194 userStart++; 1195 userEnd = userStart; 1196 1197 int colonPos = 0; 1198 while (isUserInfoChar(url[userEnd])) { | 295 } 296 } 297 return -1; 298 } 299 300 static inline void checkEncodedString(const String& url) 301 { 302 ASSERT_UNUSED(url, url.containsOnlyASCII()); 303 ASSERT_UNUSED(url, url.isEmpty() || isSchemeFirstChar(url[0])); 304 } 305 306 inline bool URL::protocolIs(const String& string, const char* protocol) 307 { 308 return WebCore::protocolIs(string, protocol); 309 } 310 311 void URL::invalidate() 312 { 313 m_isValid = false; 314 m_protocolIsInHTTPFamily = false; 315 #if PLATFORM(JAVA) 316 m_protocolIsInJar = false; 317 #endif 318 m_schemeEnd = 0; 319 m_userStart = 0; 320 m_userEnd = 0; 321 m_passwordEnd = 0; 322 m_hostEnd = 0; 323 m_portEnd = 0; 324 m_pathEnd = 0; 325 m_pathAfterLastSlash = 0; 326 m_queryEnd = 0; 327 m_fragmentEnd = 0; 328 } 329 330 URL::URL(ParsedURLStringTag, const String& url) 331 { 332 parse(url); 333 ASSERT(url == m_string); 334 } 335 336 URL::URL(const URL& base, const String& relative) 337 { 411 } 412 if (*p == ':') { 413 if (p[1] != '/' && equalIgnoringCase(base.protocol(), String(str, p - str)) && base.isHierarchical()) 414 str = p + 1; 415 else 416 absolute = true; 417 } 418 } 419 420 CharBuffer parseBuffer; 421 422 if (absolute) { 423 parse(str, &relative); 424 } else { 425 // If the base is empty or opaque (e.g. data: or javascript:), then the URL is invalid 426 // unless the relative URL is a single fragment. 427 if (!base.isHierarchical()) { 428 if (str[0] == '#') { 429 appendASCII(base.m_string.left(base.m_queryEnd), str, len, parseBuffer); 430 parse(parseBuffer.data(), &relative); 431 #if PLATFORM(JAVA) 432 } else if(base.isJarFile()) { 433 appendASCII(base.m_string.left(base.m_pathAfterLastSlash), str, len, parseBuffer); 434 parse(parseBuffer.data(), &relative); 435 #endif 436 } else { 437 m_string = relative; 438 invalidate(); 439 } 440 return; 441 } 442 443 switch (str[0]) { 444 case '\0': 445 // The reference is empty, so this is a reference to the same document with any fragment identifier removed. 446 *this = base; 447 removeFragmentIdentifier(); 448 break; 449 case '#': { 450 // must be fragment-only reference 451 appendASCII(base.m_string.left(base.m_queryEnd), str, len, parseBuffer); 452 parse(parseBuffer.data(), &relative); 453 break; 454 } 455 case '?': { 1167 return; 1168 } 1169 1170 int userStart = schemeEnd + 1; 1171 int userEnd; 1172 int passwordStart; 1173 int passwordEnd; 1174 int hostStart; 1175 int hostEnd; 1176 int portStart; 1177 int portEnd; 1178 1179 bool hierarchical = url[schemeEnd + 1] == '/'; 1180 bool hasSecondSlash = hierarchical && url[schemeEnd + 2] == '/'; 1181 1182 bool isFile = schemeEnd == 4 1183 && isLetterMatchIgnoringCase(url[0], 'f') 1184 && isLetterMatchIgnoringCase(url[1], 'i') 1185 && isLetterMatchIgnoringCase(url[2], 'l') 1186 && isLetterMatchIgnoringCase(url[3], 'e'); 1187 1188 #if PLATFORM(JAVA) 1189 m_protocolIsInJar = schemeEnd == 3 1190 && isLetterMatchIgnoringCase(url[0], 'j') 1191 && isLetterMatchIgnoringCase(url[1], 'a') 1192 && isLetterMatchIgnoringCase(url[2], 'r'); 1193 #endif 1194 1195 m_protocolIsInHTTPFamily = isLetterMatchIgnoringCase(url[0], 'h') 1196 && isLetterMatchIgnoringCase(url[1], 't') 1197 && isLetterMatchIgnoringCase(url[2], 't') 1198 && isLetterMatchIgnoringCase(url[3], 'p') 1199 && (url[4] == ':' || (isLetterMatchIgnoringCase(url[4], 's') && url[5] == ':')); 1200 1201 if ((hierarchical && hasSecondSlash) || isNonFileHierarchicalScheme(url, schemeEnd)) { 1202 // The part after the scheme is either a net_path or an abs_path whose first path segment is empty. 1203 // Attempt to find an authority. 1204 // FIXME: Authority characters may be scanned twice, and it would be nice to be faster. 1205 1206 if (hierarchical) 1207 userStart++; 1208 if (hasSecondSlash) 1209 userStart++; 1210 userEnd = userStart; 1211 1212 int colonPos = 0; 1213 while (isUserInfoChar(url[userEnd])) { |