Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A parsed URI, such as a URL. | 8 * A parsed URI, such as a URL. |
| 9 * | 9 * |
| 10 * **See also:** | 10 * **See also:** |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 List<String> _pathSegments; | 111 List<String> _pathSegments; |
| 112 | 112 |
| 113 /** | 113 /** |
| 114 * Cache the computed return value of [queryParameters]. | 114 * Cache the computed return value of [queryParameters]. |
| 115 */ | 115 */ |
| 116 Map<String, String> _queryParameters; | 116 Map<String, String> _queryParameters; |
| 117 | 117 |
| 118 /** | 118 /** |
| 119 * Creates a new URI object by parsing a URI string. | 119 * Creates a new URI object by parsing a URI string. |
| 120 */ | 120 */ |
| 121 static Uri parse(String uri) { | 121 static Uri parse(String uri) { |
|
kevmoo
2014/06/10 21:29:08
Need to update doc comment that this method will n
Lasse Reichstein Nielsen
2014/06/12 08:07:31
It threw before as well, now it just detects more
| |
| 122 // This parsing will not validate percent-encoding, IPv6, etc. When done | 122 // This parsing will not validate percent-encoding, IPv6, etc. When done |
| 123 // it will call `new Uri(...)` which will perform these validations. | 123 // it will call `new Uri(...)` which will perform these validations. |
| 124 // This is purely splitting up the URI string into components. | 124 // This is purely splitting up the URI string into components. |
| 125 // | 125 // |
| 126 // Important parts of the RFC 3986 used here: | 126 // Important parts of the RFC 3986 used here: |
| 127 // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | 127 // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] |
| 128 // | 128 // |
| 129 // hier-part = "//" authority path-abempty | 129 // hier-part = "//" authority path-abempty |
| 130 // / path-absolute | 130 // / path-absolute |
| 131 // / path-rootless | 131 // / path-rootless |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 // segment = *pchar | 165 // segment = *pchar |
| 166 // segment-nz = 1*pchar | 166 // segment-nz = 1*pchar |
| 167 // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) | 167 // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) |
| 168 // ; non-zero-length segment without any colon ":" | 168 // ; non-zero-length segment without any colon ":" |
| 169 // | 169 // |
| 170 // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" | 170 // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" |
| 171 // | 171 // |
| 172 // query = *( pchar / "/" / "?" ) | 172 // query = *( pchar / "/" / "?" ) |
| 173 // | 173 // |
| 174 // fragment = *( pchar / "/" / "?" ) | 174 // fragment = *( pchar / "/" / "?" ) |
| 175 bool isRegName(int ch) { | 175 if (uri.isEmpty) { |
| 176 return ch < 128 && ((_regNameTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); | 176 return new Uri(); |
| 177 } | 177 } |
| 178 | 178 String scheme; |
| 179 int ipV6Address(int index) { | 179 String userInfo = ""; |
| 180 // IPv6. Skip to ']'. | 180 String host = ""; |
| 181 index = uri.indexOf(']', index); | 181 int port = 0; |
| 182 if (index == -1) { | 182 String path = ""; |
| 183 throw new FormatException("Bad end of IPv6 host"); | 183 String query; |
| 184 } | 184 String fragment; |
| 185 return index + 1; | 185 bool allowColonInPath = false; |
| 186 } | 186 |
| 187 | 187 /// Index after current char. |
|
Søren Gjesse
2014/06/11 08:33:15
Why dart-doc comments here?
Lasse Reichstein Nielsen
2014/06/12 08:07:31
Because I assume the editor will display that comm
| |
| 188 int length = uri.length; | |
| 189 int index = 0; | 188 int index = 0; |
| 190 | 189 /// Current char. |
| 191 int schemeEndIndex = 0; | 190 int current = _EOI; |
| 192 | 191 /// Start index of current section being parsed. |
| 193 if (length == 0) { | 192 int start = 0; |
|
Anders Johnsen
2014/06/11 10:00:03
Start is a bit ambiguous. currentSectionStart ?
Lasse Reichstein Nielsen
2014/06/12 08:07:31
.... loooooong name.
But ok.
| |
| 194 return new Uri(); | 193 /// The position after the current character. If parsing a percent |
| 195 } | 194 /// escape, this is index + 3, otherwise index + 1. |
| 196 | 195 int nextIndex = 0; |
| 197 if (uri.codeUnitAt(0) != _SLASH) { | 196 |
| 198 // Can be scheme. | 197 void advance() { |
| 199 while (index < length) { | 198 index = nextIndex; |
| 200 // Look for ':'. If found, continue from the post of ':'. If not (end | 199 if (index < uri.length) { |
| 201 // reached or invalid scheme char found) back up one char, and continue | 200 current = uri.codeUnitAt(index); |
| 202 // to path. | 201 if (_MAX_VALID_CHAR >= current) { |
| 203 // Note that scheme-chars is contained in path-chars. | 202 if (_PERCENT != current) { |
| 204 int codeUnit = uri.codeUnitAt(index++); | 203 nextIndex = nextIndex + 1; |
| 205 if (!_isSchemeCharacter(codeUnit)) { | 204 return; |
| 206 if (codeUnit == _COLON) { | 205 } |
| 207 schemeEndIndex = index; | 206 if (index + 2 >= uri.length || |
| 208 } else { | 207 !_isHexDigit(uri.codeUnitAt(index + 1)) || |
| 209 // Back up one char, since we met an invalid scheme char. | 208 !_isHexDigit(uri.codeUnitAt(index + 2))) { |
| 210 index--; | 209 _fail(uri, index, "Incomplete percent escape"); |
| 211 } | 210 } |
| 212 break; | 211 // Valid escape, returns _PERCENT as current. |
| 213 } | 212 nextIndex = nextIndex + 3; |
| 214 } | 213 return; |
| 215 } | 214 } |
| 216 | 215 _fail(uri, index, "Unexpected character"); |
| 217 int userInfoEndIndex = -1; | 216 } |
| 218 int portIndex = -1; | 217 current = _EOI; |
| 219 int authorityEndIndex = schemeEndIndex; | 218 } |
| 220 // If we see '//', there must be an authority. | 219 |
| 221 if (authorityEndIndex == index && | 220 // Parse authority. |
| 222 authorityEndIndex + 1 < length && | 221 void parseAuth() { |
| 223 uri.codeUnitAt(authorityEndIndex) == _SLASH && | 222 start = index; |
| 224 uri.codeUnitAt(authorityEndIndex + 1) == _SLASH) { | 223 void parseIpV6() { |
| 225 // Skip '//'. | 224 assert(current == _LEFT_BRACKET); |
| 226 authorityEndIndex += 2; | 225 assert(start == index); |
| 227 // It can both be host and userInfo. | 226 for (int i = index + 1; i < uri.length; i++) { |
| 228 while (authorityEndIndex < length) { | 227 if (uri.codeUnitAt(i) == _RIGHT_BRACKET) { |
| 229 int codeUnit = uri.codeUnitAt(authorityEndIndex++); | 228 nextIndex = i + 1; |
| 230 if (!isRegName(codeUnit)) { | 229 advance(); |
| 231 if (codeUnit == _LEFT_BRACKET) { | 230 host = uri.substring(start, index); |
|
Søren Gjesse
2014/06/11 08:33:15
Are we doing proper IPv6 validation later, or is t
Lasse Reichstein Nielsen
2014/06/12 08:07:31
I believe we are doing it later.
I don't know if
| |
| 232 authorityEndIndex = ipV6Address(authorityEndIndex); | 231 return; |
| 233 } else if (portIndex == -1 && codeUnit == _COLON) { | 232 } |
| 234 // First time ':'. | 233 } |
| 235 portIndex = authorityEndIndex; | 234 _fail(uri, start, "Unmatched [ in host name"); |
|
kevmoo
2014/06/10 21:29:08
quote '['
| |
| 236 } else if (codeUnit == _AT_SIGN || codeUnit == _COLON) { | 235 } |
| 237 // Second time ':' or first '@'. Must be userInfo. | 236 |
| 238 userInfoEndIndex = uri.indexOf('@', authorityEndIndex - 1); | 237 void parseHost() { |
| 239 // Not found. Must be path then. | 238 assert(start == index); |
| 240 if (userInfoEndIndex == -1) { | 239 if (current == _LEFT_BRACKET) { |
| 241 authorityEndIndex = index; | 240 parseIpV6(); |
| 242 break; | 241 return; |
| 242 } | |
| 243 while (_isRegNameChar(current)) { | |
| 244 advance(); | |
| 245 } | |
| 246 host = uri.substring(start, index); | |
| 247 } | |
| 248 | |
| 249 int parsePort() { | |
| 250 assert(_isDigit(current)); | |
| 251 int portVal = current - _ZERO; | |
| 252 advance(); | |
| 253 while (_isDigit(current)) { | |
| 254 portVal = portVal * 10 + (current - _ZERO); | |
|
Søren Gjesse
2014/06/11 08:33:15
Any limitations on the port value in the spec?
| |
| 255 advance(); | |
| 256 } | |
| 257 return portVal; | |
| 258 } | |
| 259 | |
| 260 maybeUserInfo: { | |
| 261 // Break this when we know user-info is done or not there. | |
| 262 // user-info or reg-name | |
| 263 if (current == _LEFT_BRACKET) break maybeUserInfo; | |
| 264 while (_isRegNameChar(current)) { | |
| 265 advance(); | |
| 266 } | |
| 267 if (current == _SLASH) { | |
| 268 host = uri.substring(start, index); | |
| 269 return; | |
| 270 } | |
| 271 if (current == _AT_SIGN) { | |
| 272 userInfo = uri.substring(start, index); | |
| 273 advance(); | |
| 274 start = index; | |
| 275 break maybeUserInfo; | |
| 276 } | |
| 277 if (current == _COLON) { | |
| 278 // First colon seen after what might be a host name. | |
| 279 // Can be either part of user-info or preceeding a port. | |
| 280 int hostEnd = index; | |
| 281 advance(); | |
| 282 // user-info or port. | |
| 283 if (_isDigit(current)) { | |
| 284 int portVal = parsePort(); | |
| 285 if (current == _SLASH || current == _EOI) { | |
| 286 host = uri.substring(start, hostEnd); | |
| 287 port = portVal; | |
| 288 return; | |
| 243 } | 289 } |
| 244 portIndex = -1; | 290 } |
| 245 authorityEndIndex = userInfoEndIndex + 1; | 291 } |
| 246 // Now it can only be host:port. | 292 if (current == _EOI) { |
| 247 while (authorityEndIndex < length) { | 293 host = uri.substring(start, index); |
| 248 int codeUnit = uri.codeUnitAt(authorityEndIndex++); | 294 return; |
| 249 if (!isRegName(codeUnit)) { | 295 } |
| 250 if (codeUnit == _LEFT_BRACKET) { | 296 // A non-port character seen after a colon. |
| 251 authorityEndIndex = ipV6Address(authorityEndIndex); | 297 // This must be user-info. |
| 252 } else if (codeUnit == _COLON) { | 298 while (_isUserInfoChar(current)) { |
| 253 if (portIndex != -1) { | 299 advance(); |
| 254 throw new FormatException("Double port in host"); | 300 } |
| 255 } | 301 if (current != _AT_SIGN) { |
| 256 portIndex = authorityEndIndex; | 302 _fail(uri, index, "Expected @"); |
|
kevmoo
2014/06/10 21:29:08
quote '@'
| |
| 257 } else { | 303 } |
| 258 authorityEndIndex--; | 304 userInfo = uri.substring(start, index); |
| 259 break; | 305 advance(); |
| 260 } | 306 start = index; |
| 261 } | 307 } // end maybeUserInfo |
| 262 } | 308 parseHost(); |
| 263 break; | 309 if (current == _COLON) { |
| 264 } else { | 310 advance(); |
| 265 authorityEndIndex--; | 311 if (!_isDigit(current)) { |
| 266 break; | 312 _fail(uri, index, "Expected port number"); |
| 267 } | 313 } |
| 268 } | 314 port = parsePort(); |
| 269 } | 315 } |
| 270 } else { | 316 } // end parseAuth(). |
| 271 authorityEndIndex = schemeEndIndex; | 317 |
| 272 } | 318 // Start parsing. |
| 273 | 319 to_path: { // Break this block to go to parsing the path. |
| 274 // At path now. | 320 advance(); |
| 275 int pathEndIndex = authorityEndIndex; | 321 if (_isAlpha(current)) { |
|
Anders Johnsen
2014/06/11 10:00:03
Do we need 'scheme != null' to prevent double-pars
Lasse Reichstein Nielsen
2014/06/12 08:07:31
No, there is no parsing before this point. The cod
| |
| 276 while (pathEndIndex < length) { | 322 // May be scheme or path. |
| 277 int codeUnit = uri.codeUnitAt(pathEndIndex++); | 323 do { |
| 278 if (codeUnit == _QUESTION || codeUnit == _NUMBER_SIGN) { | 324 advance(); |
| 279 pathEndIndex--; | 325 } while (_isSchemeCharacter(current)); |
| 280 break; | 326 if (current != _COLON) { |
| 281 } | 327 break to_path; |
| 282 } | 328 } |
| 283 | 329 allowColonInPath = true; |
| 284 // Maybe query. | 330 scheme = uri.substring(0, index); |
| 285 int queryEndIndex = pathEndIndex; | 331 advance(); |
| 286 if (queryEndIndex < length && uri.codeUnitAt(queryEndIndex) == _QUESTION) { | 332 start = index; |
| 287 while (queryEndIndex < length) { | 333 } |
| 288 int codeUnit = uri.codeUnitAt(queryEndIndex++); | 334 // Path or authority. |
| 289 if (codeUnit == _NUMBER_SIGN) { | 335 if (current == _SLASH) { |
| 290 queryEndIndex--; | 336 allowColonInPath = true; |
| 291 break; | 337 advance(); |
| 292 } | 338 if (current == _SLASH) { |
| 293 } | 339 advance(); |
| 294 } | 340 parseAuth(); |
| 295 | 341 if (current == _EOI) { |
| 296 var scheme = null; | 342 start = index; |
| 297 if (schemeEndIndex > 0) { | 343 break to_path; |
| 298 scheme = uri.substring(0, schemeEndIndex - 1); | 344 } |
| 299 } | 345 if (current != _SLASH) { |
| 300 | 346 _fail(uri, index, "Expected /"); |
|
kevmoo
2014/06/10 21:29:08
quote '/'
| |
| 301 var host = ""; | 347 } |
| 302 var userInfo = ""; | 348 start = index; |
| 303 var port = 0; | 349 advance(); |
| 304 if (schemeEndIndex != authorityEndIndex) { | 350 } |
| 305 int startIndex = schemeEndIndex + 2; | 351 } |
| 306 if (userInfoEndIndex > 0) { | 352 } // end to_path. |
| 307 userInfo = uri.substring(startIndex, userInfoEndIndex); | 353 if (!allowColonInPath) { |
| 308 startIndex = userInfoEndIndex + 1; | 354 while (_isPathChar(current) || current == _PERCENT) { |
|
Anders Johnsen
2014/06/11 10:00:03
Will _isPathChar return true for '/' ?
Lasse Reichstein Nielsen
2014/06/12 08:07:31
No.
| |
| 309 } | 355 if (current == _COLON) { |
| 310 if (portIndex > 0) { | 356 _fail(uri, index, "Colon in path before first '/'"); |
| 311 var portStr = uri.substring(portIndex, authorityEndIndex); | 357 } |
| 312 try { | 358 advance(); |
| 313 port = int.parse(portStr); | 359 } |
| 314 } catch (_) { | 360 } |
| 315 throw new FormatException("Invalid port: '$portStr'"); | 361 // Start or continue path. May be empty. |
| 316 } | 362 while (_isPathChar(current) || current == _SLASH || current == _PERCENT) { |
| 317 host = uri.substring(startIndex, portIndex - 1); | 363 advance(); |
| 318 } else { | 364 } |
| 319 host = uri.substring(startIndex, authorityEndIndex); | 365 path = uri.substring(start, index); |
| 320 } | 366 |
| 321 } | 367 if (current == _QUESTION) { |
| 322 | 368 start = nextIndex; |
| 323 var path = uri.substring(authorityEndIndex, pathEndIndex); | 369 do { |
| 324 var query = ""; | 370 advance(); |
| 325 if (pathEndIndex < queryEndIndex) { | 371 } while (_isQueryChar(current) || current == _PERCENT); |
| 326 query = uri.substring(pathEndIndex + 1, queryEndIndex); | 372 query = uri.substring(start, index); |
| 327 } | 373 } |
| 328 var fragment = ""; | 374 |
| 329 // If queryEndIndex is not at end (length), there is a fragment. | 375 if (current == _NUMBER_SIGN) { |
| 330 if (queryEndIndex < length) { | 376 // Fragment can contain same characters as query. |
|
Søren Gjesse
2014/06/11 08:33:15
No number sign in fragment?
Lasse Reichstein Nielsen
2014/06/12 08:07:32
No. At most one # in any URL.
| |
| 331 fragment = uri.substring(queryEndIndex + 1, length); | 377 start = nextIndex; |
| 378 do { | |
| 379 advance(); | |
| 380 } while (_isQueryChar(current) || current == _PERCENT); | |
| 381 fragment = uri.substring(start, index); | |
| 382 } | |
| 383 | |
| 384 if (current != _EOI) { | |
| 385 _fail(uri, index, "Unexpected character"); | |
| 332 } | 386 } |
| 333 | 387 |
| 334 return new Uri(scheme: scheme, | 388 return new Uri(scheme: scheme, |
|
Anders Johnsen
2014/06/11 10:00:03
This constructor does some extra validation. Do we
Lasse Reichstein Nielsen
2014/06/12 08:07:31
As pointed out elsewhere, the validation needs to
| |
| 335 userInfo: userInfo, | 389 userInfo: userInfo, |
| 390 port: port, | |
|
kevmoo
2014/06/10 21:29:08
nit: might as well keep these params in the origin
Lasse Reichstein Nielsen
2014/06/12 08:07:31
ACK.
| |
| 336 host: host, | 391 host: host, |
| 337 port: port, | |
| 338 path: path, | 392 path: path, |
| 339 query: query, | 393 query: query, |
| 340 fragment: fragment); | 394 fragment: fragment); |
| 341 } | 395 } |
| 342 | 396 |
| 397 // Report a parse failure. | |
| 398 static void _fail(uri, index, message) { | |
|
kevmoo
2014/06/10 21:29:08
Add types to parameters
| |
| 399 if (index == uri.length) { | |
| 400 message += ": Unexpected end of input."; | |
|
kevmoo
2014/06/10 21:29:08
Could this be changed so each message reads like a
| |
| 401 } else { | |
| 402 message += ": Unexpected character at position $index.\n"; | |
|
kevmoo
2014/06/10 21:29:08
ditto for reading like a sentence from above.
| |
| 403 int min = 0; | |
| 404 int max = uri.length; | |
| 405 String pre = ""; | |
| 406 String post = ""; | |
|
kevmoo
2014/06/10 21:29:08
Code comments for what you're doing here? Is this
Lasse Reichstein Nielsen
2014/06/12 08:07:31
Yes, at most 78 characters of the source will be d
| |
| 407 if (uri.length > 78) { | |
| 408 min = index - 10; | |
| 409 if (min < 0) min = 0; | |
| 410 int max = min + 72; | |
| 411 if (max > uri.length) { | |
| 412 max = uri.length; | |
| 413 min = max - 72; | |
| 414 } | |
| 415 if (min != 0) pre = "..."; | |
| 416 if (max != uri.length) post = "..."; | |
| 417 } | |
| 418 message = "$message$pre${uri.substring(min, max)}$post\n" | |
| 419 "${' ' * (pre.length + index - min)}^"; | |
| 420 } | |
| 421 throw new FormatException(message); | |
| 422 } | |
| 423 | |
| 424 | |
| 343 /** | 425 /** |
| 344 * Creates a new URI from its components. | 426 * Creates a new URI from its components. |
| 345 * | 427 * |
| 346 * Each component is set through a named argument. Any number of | 428 * Each component is set through a named argument. Any number of |
| 347 * components can be provided. The default value for the components | 429 * components can be provided. The default value for the components |
| 348 * not provided is the empry string, except for [port] which has a | 430 * not provided is the empry string, except for [port] which has a |
| 349 * default value of 0. The [path] and [query] components can be set | 431 * default value of 0. The [path] and [query] components can be set |
| 350 * using two different named arguments. | 432 * using two different named arguments. |
| 351 * | 433 * |
| 352 * The scheme component is set through [scheme]. The scheme is | 434 * The scheme component is set through [scheme]. The scheme is |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 927 if (result != null && prevIndex != index) fillResult(); | 1009 if (result != null && prevIndex != index) fillResult(); |
| 928 assert(index == length); | 1010 assert(index == length); |
| 929 | 1011 |
| 930 return result.toString(); | 1012 return result.toString(); |
| 931 } | 1013 } |
| 932 | 1014 |
| 933 static bool _isSchemeCharacter(int ch) { | 1015 static bool _isSchemeCharacter(int ch) { |
| 934 return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); | 1016 return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); |
| 935 } | 1017 } |
| 936 | 1018 |
| 1019 static bool _isPathChar(int ch) { | |
| 1020 return ch < 128 && ((_pathCharTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); | |
| 1021 } | |
| 1022 | |
| 1023 static bool _isRegNameChar(int ch) { | |
| 1024 return ch < 128 && ((_regNameTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); | |
| 1025 } | |
| 1026 | |
| 1027 static bool _isUserInfoChar(int ch) { | |
| 1028 return ch < 128 && ( | |
| 1029 ((_regNameTable[ch >> 4] & (1 << (ch & 0x0f))) != 0) || ch == _COLON); | |
| 1030 } | |
| 1031 | |
| 1032 static bool _isQueryChar(int ch) { | |
| 1033 return ch < 128 && ((_queryCharTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); | |
| 1034 } | |
| 937 | 1035 |
| 938 /** | 1036 /** |
| 939 * Returns whether the URI is absolute. | 1037 * Returns whether the URI is absolute. |
| 940 */ | 1038 */ |
| 941 bool get isAbsolute => scheme != "" && fragment == ""; | 1039 bool get isAbsolute => scheme != "" && fragment == ""; |
| 942 | 1040 |
| 943 String _merge(String base, String reference) { | 1041 String _merge(String base, String reference) { |
| 944 if (base == "") return "/$reference"; | 1042 if (base == "") return "/$reference"; |
| 945 return "${base.substring(0, base.lastIndexOf("/") + 1)}$reference"; | 1043 return "${base.substring(0, base.lastIndexOf("/") + 1)}$reference"; |
| 946 } | 1044 } |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1544 static const int _UPPER_CASE_A = 0x41; | 1642 static const int _UPPER_CASE_A = 0x41; |
| 1545 static const int _UPPER_CASE_F = 0x46; | 1643 static const int _UPPER_CASE_F = 0x46; |
| 1546 static const int _UPPER_CASE_Z = 0x5A; | 1644 static const int _UPPER_CASE_Z = 0x5A; |
| 1547 static const int _LEFT_BRACKET = 0x5B; | 1645 static const int _LEFT_BRACKET = 0x5B; |
| 1548 static const int _BACKSLASH = 0x5C; | 1646 static const int _BACKSLASH = 0x5C; |
| 1549 static const int _RIGHT_BRACKET = 0x5D; | 1647 static const int _RIGHT_BRACKET = 0x5D; |
| 1550 static const int _LOWER_CASE_A = 0x61; | 1648 static const int _LOWER_CASE_A = 0x61; |
| 1551 static const int _LOWER_CASE_F = 0x66; | 1649 static const int _LOWER_CASE_F = 0x66; |
| 1552 static const int _LOWER_CASE_Z = 0x7A; | 1650 static const int _LOWER_CASE_Z = 0x7A; |
| 1553 static const int _BAR = 0x7C; | 1651 static const int _BAR = 0x7C; |
| 1652 static const int _MAX_VALID_CHAR = 0x7e; | |
| 1653 static const int _EOI = 0x10000; // Not a code unit. | |
|
Anders Johnsen
2014/06/11 10:00:03
-1?
Lasse Reichstein Nielsen
2014/06/12 08:07:31
Breaks the _isPathChar function (or requires an ex
| |
| 1654 | |
| 1655 static bool _isAlpha(int char) { | |
| 1656 char |= 0x20; | |
| 1657 return _LOWER_CASE_A <= char && _LOWER_CASE_Z >= char; | |
| 1658 // TODO: Test: | |
| 1659 // return ((char - _a) & 0xffff) <= (_z - _a); | |
| 1660 } | |
| 1661 | |
| 1662 static bool _isDigit(int char) { | |
| 1663 return _NINE >= char && _ZERO <= char; | |
| 1664 } | |
| 1665 | |
| 1666 static bool _isHexDigit(int char) { | |
| 1667 if (_NINE >= char) return _ZERO <= char; | |
| 1668 char |= 0x20; | |
| 1669 return _LOWER_CASE_A <= char && _LOWER_CASE_F >= char; | |
| 1670 } | |
| 1554 | 1671 |
| 1555 /** | 1672 /** |
| 1556 * This is the internal implementation of JavaScript's encodeURI function. | 1673 * This is the internal implementation of JavaScript's encodeURI function. |
| 1557 * It encodes all characters in the string [text] except for those | 1674 * It encodes all characters in the string [text] except for those |
| 1558 * that appear in [canonicalTable], and returns the escaped string. | 1675 * that appear in [canonicalTable], and returns the escaped string. |
| 1559 */ | 1676 */ |
| 1560 static String _uriEncode(List<int> canonicalTable, | 1677 static String _uriEncode(List<int> canonicalTable, |
| 1561 String text, | 1678 String text, |
| 1562 {Encoding encoding: UTF8, | 1679 {Encoding encoding: UTF8, |
| 1563 bool spaceToPlus: false}) { | 1680 bool spaceToPlus: false}) { |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1842 0xafff, // 0x30 - 0x3f 1111111111110101 | 1959 0xafff, // 0x30 - 0x3f 1111111111110101 |
| 1843 // @ABCDEFGHIJKLMNO | 1960 // @ABCDEFGHIJKLMNO |
| 1844 0xffff, // 0x40 - 0x4f 1111111111111111 | 1961 0xffff, // 0x40 - 0x4f 1111111111111111 |
| 1845 // PQRSTUVWXYZ _ | 1962 // PQRSTUVWXYZ _ |
| 1846 0x87ff, // 0x50 - 0x5f 1111111111100001 | 1963 0x87ff, // 0x50 - 0x5f 1111111111100001 |
| 1847 // abcdefghijklmno | 1964 // abcdefghijklmno |
| 1848 0xfffe, // 0x60 - 0x6f 0111111111111111 | 1965 0xfffe, // 0x60 - 0x6f 0111111111111111 |
| 1849 // pqrstuvwxyz ~ | 1966 // pqrstuvwxyz ~ |
| 1850 0x47ff]; // 0x70 - 0x7f 1111111111100010 | 1967 0x47ff]; // 0x70 - 0x7f 1111111111100010 |
| 1851 } | 1968 } |
| OLD | NEW |