| 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:** |
| 11 * | 11 * |
| 12 * * [URIs][uris] in the [library tour][libtour] | 12 * * [URIs][uris] in the [library tour][libtour] |
| 13 * * [RFC-3986](http://tools.ietf.org/html/rfc3986) | 13 * * [RFC-3986](http://tools.ietf.org/html/rfc3986) |
| 14 * | 14 * |
| 15 * [uris]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#c
h03-uri | 15 * [uris]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#c
h03-uri |
| 16 * [libtour]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.htm
l | 16 * [libtour]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.htm
l |
| 17 */ | 17 */ |
| 18 class Uri { | 18 class Uri { |
| 19 // The host name of the URI. | |
| 20 // Set to `null` if there is no authority in a URI. | |
| 21 final String _host; | |
| 22 // The port. Set to null if there is no port. Normalized to null if | |
| 23 // the port is the default port for the scheme. | |
| 24 // Set to the value of the default port if an empty port was supplied. | |
| 25 int _port; | |
| 26 // The path. Always non-null. | |
| 27 String _path; | |
| 28 | |
| 29 /** | 19 /** |
| 30 * Returns the scheme component. | 20 * The scheme component of the URI. |
| 31 * | 21 * |
| 32 * Returns the empty string if there is no scheme component. | 22 * Returns the empty string if there is no scheme component. |
| 33 * | 23 * |
| 34 * A URI scheme is case insensitive. | 24 * A URI scheme is case insensitive. |
| 35 * The returned scheme is canonicalized to lowercase letters. | 25 * The returned scheme is canonicalized to lowercase letters. |
| 36 */ | 26 */ |
| 37 // We represent the missing scheme as an empty string. | 27 // We represent the missing scheme as an empty string. |
| 38 // A valid scheme cannot be empty. | 28 // A valid scheme cannot be empty. |
| 39 final String scheme; | 29 final String scheme; |
| 40 | 30 |
| 41 /** | 31 /** |
| 32 * The user-info part of the authority. |
| 33 * |
| 34 * Does not distinguish between an empty user-info and an absent one. |
| 35 * The value is always non-null. |
| 36 * Is considered absent if [_host] is `null`. |
| 37 */ |
| 38 final String _userInfo; |
| 39 |
| 40 /** |
| 41 * The host name of the URI. |
| 42 * |
| 43 * Set to `null` if there is no authority in the URI. |
| 44 * The host name is the only mandatory part of an authority, so we use |
| 45 * it to mark whether an authority part was present or not. |
| 46 */ |
| 47 final String _host; |
| 48 |
| 49 /** |
| 50 * The port number part of the authority. |
| 51 * |
| 52 * The port. Set to null if there is no port. Normalized to null if |
| 53 * the port is the default port for the scheme. |
| 54 */ |
| 55 int _port; |
| 56 |
| 57 /** |
| 58 * The path of the URI. |
| 59 * |
| 60 * Always non-null. |
| 61 */ |
| 62 String _path; |
| 63 |
| 64 // The query content, or null if there is no query. |
| 65 final String _query; |
| 66 |
| 67 // The fragment content, or null if there is no fragment. |
| 68 final String _fragment; |
| 69 |
| 70 /** |
| 71 * Cache the computed return value of [pathSegements]. |
| 72 */ |
| 73 List<String> _pathSegments; |
| 74 |
| 75 /** |
| 76 * Cache the computed return value of [queryParameters]. |
| 77 */ |
| 78 Map<String, String> _queryParameters; |
| 79 |
| 80 /// Internal non-verifying constructor. Only call with validated arguments. |
| 81 Uri._internal(this.scheme, |
| 82 this._userInfo, |
| 83 this._host, |
| 84 this._port, |
| 85 this._path, |
| 86 this._query, |
| 87 this._fragment); |
| 88 |
| 89 /** |
| 90 * Creates a new URI from its components. |
| 91 * |
| 92 * Each component is set through a named argument. Any number of |
| 93 * components can be provided. The [path] and [query] components can be set |
| 94 * using either of two different named arguments. |
| 95 * |
| 96 * The scheme component is set through [scheme]. The scheme is |
| 97 * normalized to all lowercase letters. If the scheme is omitted or empty, |
| 98 * the URI will not have a scheme part. |
| 99 * |
| 100 * The user info part of the authority component is set through |
| 101 * [userInfo]. It defaults to the empty string, which will be omitted |
| 102 * from the string representation of the URI. |
| 103 * |
| 104 * The host part of the authority component is set through |
| 105 * [host]. The host can either be a hostname, an IPv4 address or an |
| 106 * IPv6 address, contained in '[' and ']'. If the host contains a |
| 107 * ':' character, the '[' and ']' are added if not already provided. |
| 108 * The host is normalized to all lowercase letters. |
| 109 * |
| 110 * The port part of the authority component is set through |
| 111 * [port]. |
| 112 * If [port] is omitted or `null`, it implies the default port for |
| 113 * the URI's scheme, and is equivalent to passing that port explicitly. |
| 114 * The recognized schemes, and their default ports, are "http" (80) and |
| 115 * "https" (443). All other schemes are considered as having zero as the |
| 116 * default port. |
| 117 * |
| 118 * If any of `userInfo`, `host` or `port` are provided, |
| 119 * the URI will have an autority according to [hasAuthority]. |
| 120 * |
| 121 * The path component is set through either [path] or |
| 122 * [pathSegments]. When [path] is used, it should be a valid URI path, |
| 123 * but invalid characters, except the general delimiters ':/@[]?#', |
| 124 * will be escaped if necessary. |
| 125 * When [pathSegments] is used, each of the provided segments |
| 126 * is first percent-encoded and then joined using the forward slash |
| 127 * separator. The percent-encoding of the path segments encodes all |
| 128 * characters except for the unreserved characters and the following |
| 129 * list of characters: `!$&'()*+,;=:@`. If the other components |
| 130 * calls for an absolute path a leading slash `/` is prepended if |
| 131 * not already there. |
| 132 * |
| 133 * The query component is set through either [query] or |
| 134 * [queryParameters]. When [query] is used the provided string should |
| 135 * be a valid URI query, but invalid characters other than general delimiters, |
| 136 * will be escaped if necessary. |
| 137 * When [queryParameters] is used the query is built from the |
| 138 * provided map. Each key and value in the map is percent-encoded |
| 139 * and joined using equal and ampersand characters. The |
| 140 * percent-encoding of the keys and values encodes all characters |
| 141 * except for the unreserved characters. |
| 142 * If `query` is the empty string, it is equivalent to omitting it. |
| 143 * To have an actual empty query part, |
| 144 * use an empty list for `queryParameters`. |
| 145 * If both `query` and `queryParameters` are omitted or `null`, the |
| 146 * URI will have no query part. |
| 147 * |
| 148 * The fragment component is set through [fragment]. |
| 149 * It should be a valid URI fragment, but invalid characters other than |
| 150 * general delimiters, will be escaped if necessary. |
| 151 * If `fragment` is omitted or `null`, the URI will have no fragment part. |
| 152 */ |
| 153 factory Uri({String scheme : "", |
| 154 String userInfo : "", |
| 155 String host, |
| 156 int port, |
| 157 String path, |
| 158 Iterable<String> pathSegments, |
| 159 String query, |
| 160 Map<String, String> queryParameters, |
| 161 String fragment}) { |
| 162 scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme)); |
| 163 userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo)); |
| 164 host = _makeHost(host, 0, _stringOrNullLength(host), false); |
| 165 // Special case this constructor for backwards compatibility. |
| 166 if (query == "") query = null; |
| 167 query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters); |
| 168 fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment)); |
| 169 port = _makePort(port, scheme); |
| 170 bool isFile = (scheme == "file"); |
| 171 if (host == null && |
| 172 (userInfo.isNotEmpty || port != null || isFile)) { |
| 173 host = ""; |
| 174 } |
| 175 bool hasAuthority = (host != null); |
| 176 path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, |
| 177 scheme, hasAuthority); |
| 178 if (scheme.isEmpty && host == null && !path.startsWith('/')) { |
| 179 path = _normalizeRelativePath(path); |
| 180 } else { |
| 181 path = _removeDotSegments(path); |
| 182 } |
| 183 return new Uri._internal(scheme, userInfo, host, port, |
| 184 path, query, fragment); |
| 185 } |
| 186 |
| 187 /** |
| 188 * Creates a new `http` URI from authority, path and query. |
| 189 * |
| 190 * Examples: |
| 191 * |
| 192 * ``` |
| 193 * // http://example.org/path?q=dart. |
| 194 * new Uri.http("google.com", "/search", { "q" : "dart" }); |
| 195 * |
| 196 * // http://user:pass@localhost:8080 |
| 197 * new Uri.http("user:pass@localhost:8080", ""); |
| 198 * |
| 199 * // http://example.org/a%20b |
| 200 * new Uri.http("example.org", "a b"); |
| 201 * |
| 202 * // http://example.org/a%252F |
| 203 * new Uri.http("example.org", "/a%2F"); |
| 204 * ``` |
| 205 * |
| 206 * The `scheme` is always set to `http`. |
| 207 * |
| 208 * The `userInfo`, `host` and `port` components are set from the |
| 209 * [authority] argument. If `authority` is `null` or empty, |
| 210 * the created `Uri` will have no authority, and will not be directly usable |
| 211 * as an HTTP URL, which must have a non-empty host. |
| 212 * |
| 213 * The `path` component is set from the [unencodedPath] |
| 214 * argument. The path passed must not be encoded as this constructor |
| 215 * encodes the path. |
| 216 * |
| 217 * The `query` component is set from the optional [queryParameters] |
| 218 * argument. |
| 219 */ |
| 220 factory Uri.http(String authority, |
| 221 String unencodedPath, |
| 222 [Map<String, String> queryParameters]) { |
| 223 return _makeHttpUri("http", authority, unencodedPath, queryParameters); |
| 224 } |
| 225 |
| 226 /** |
| 227 * Creates a new `https` URI from authority, path and query. |
| 228 * |
| 229 * This constructor is the same as [Uri.http] except for the scheme |
| 230 * which is set to `https`. |
| 231 */ |
| 232 factory Uri.https(String authority, |
| 233 String unencodedPath, |
| 234 [Map<String, String> queryParameters]) { |
| 235 return _makeHttpUri("https", authority, unencodedPath, queryParameters); |
| 236 } |
| 237 |
| 238 /** |
| 42 * Returns the authority component. | 239 * Returns the authority component. |
| 43 * | 240 * |
| 44 * The authority is formatted from the [userInfo], [host] and [port] | 241 * The authority is formatted from the [userInfo], [host] and [port] |
| 45 * parts. | 242 * parts. |
| 46 * | 243 * |
| 47 * Returns the empty string if there is no authority component. | 244 * Returns the empty string if there is no authority component. |
| 48 */ | 245 */ |
| 49 String get authority { | 246 String get authority { |
| 50 if (!hasAuthority) return ""; | 247 if (!hasAuthority) return ""; |
| 51 var sb = new StringBuffer(); | 248 var sb = new StringBuffer(); |
| 52 _writeAuthority(sb); | 249 _writeAuthority(sb); |
| 53 return sb.toString(); | 250 return sb.toString(); |
| 54 } | 251 } |
| 55 | 252 |
| 56 /** | 253 /** |
| 57 * The user-info part of the authority. | |
| 58 * | |
| 59 * Does not distinguish between an empty user-info and an absent one. | |
| 60 * The value is always non-null. | |
| 61 */ | |
| 62 final String _userInfo; | |
| 63 | |
| 64 /** | |
| 65 * Returns the user info part of the authority component. | 254 * Returns the user info part of the authority component. |
| 66 * | 255 * |
| 67 * Returns the empty string if there is no user info in the | 256 * Returns the empty string if there is no user info in the |
| 68 * authority component. | 257 * authority component. |
| 69 */ | 258 */ |
| 70 String get userInfo => _userInfo; | 259 String get userInfo => _userInfo; |
| 71 | 260 |
| 72 /** | 261 /** |
| 73 * Returns the host part of the authority component. | 262 * Returns the host part of the authority component. |
| 74 * | 263 * |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 /** | 300 /** |
| 112 * Returns the path component. | 301 * Returns the path component. |
| 113 * | 302 * |
| 114 * The returned path is encoded. To get direct access to the decoded | 303 * The returned path is encoded. To get direct access to the decoded |
| 115 * path use [pathSegments]. | 304 * path use [pathSegments]. |
| 116 * | 305 * |
| 117 * Returns the empty string if there is no path component. | 306 * Returns the empty string if there is no path component. |
| 118 */ | 307 */ |
| 119 String get path => _path; | 308 String get path => _path; |
| 120 | 309 |
| 121 // The query content, or null if there is no query. | |
| 122 final String _query; | |
| 123 | |
| 124 /** | 310 /** |
| 125 * Returns the query component. The returned query is encoded. To get | 311 * Returns the query component. The returned query is encoded. To get |
| 126 * direct access to the decoded query use [queryParameters]. | 312 * direct access to the decoded query use [queryParameters]. |
| 127 * | 313 * |
| 128 * Returns the empty string if there is no query component. | 314 * Returns the empty string if there is no query component. |
| 129 */ | 315 */ |
| 130 String get query => (_query == null) ? "" : _query; | 316 String get query => (_query == null) ? "" : _query; |
| 131 | 317 |
| 132 // The fragment content, or null if there is no fragment. | |
| 133 final String _fragment; | |
| 134 | |
| 135 /** | 318 /** |
| 136 * Returns the fragment identifier component. | 319 * Returns the fragment identifier component. |
| 137 * | 320 * |
| 138 * Returns the empty string if there is no fragment identifier | 321 * Returns the empty string if there is no fragment identifier |
| 139 * component. | 322 * component. |
| 140 */ | 323 */ |
| 141 String get fragment => (_fragment == null) ? "" : _fragment; | 324 String get fragment => (_fragment == null) ? "" : _fragment; |
| 142 | 325 |
| 143 /** | 326 /** |
| 144 * Cache the computed return value of [pathSegements]. | |
| 145 */ | |
| 146 List<String> _pathSegments; | |
| 147 | |
| 148 /** | |
| 149 * Cache the computed return value of [queryParameters]. | |
| 150 */ | |
| 151 Map<String, String> _queryParameters; | |
| 152 | |
| 153 /** | |
| 154 * Creates a new `Uri` object by parsing a URI string. | 327 * Creates a new `Uri` object by parsing a URI string. |
| 155 * | 328 * |
| 156 * If [start] and [end] are provided, only the substring from `start` | 329 * If [start] and [end] are provided, only the substring from `start` |
| 157 * to `end` is parsed as a URI. | 330 * to `end` is parsed as a URI. |
| 158 * | 331 * |
| 159 * If the string is not valid as a URI or URI reference, | 332 * If the string is not valid as a URI or URI reference, |
| 160 * a [FormatException] is thrown. | 333 * a [FormatException] is thrown. |
| 161 */ | 334 */ |
| 162 static Uri parse(String uri, [int start = 0, int end]) { | 335 static Uri parse(String uri, [int start = 0, int end]) { |
| 163 // This parsing will not validate percent-encoding, IPv6, etc. | 336 // This parsing will not validate percent-encoding, IPv6, etc. |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 path, | 581 path, |
| 409 query, | 582 query, |
| 410 fragment); | 583 fragment); |
| 411 } | 584 } |
| 412 | 585 |
| 413 // Report a parse failure. | 586 // Report a parse failure. |
| 414 static void _fail(String uri, int index, String message) { | 587 static void _fail(String uri, int index, String message) { |
| 415 throw new FormatException(message, uri, index); | 588 throw new FormatException(message, uri, index); |
| 416 } | 589 } |
| 417 | 590 |
| 418 /// Internal non-verifying constructor. Only call with validated arguments. | |
| 419 Uri._internal(this.scheme, | |
| 420 this._userInfo, | |
| 421 this._host, | |
| 422 this._port, | |
| 423 this._path, | |
| 424 this._query, | |
| 425 this._fragment); | |
| 426 | |
| 427 /** | |
| 428 * Creates a new URI from its components. | |
| 429 * | |
| 430 * Each component is set through a named argument. Any number of | |
| 431 * components can be provided. The [path] and [query] components can be set | |
| 432 * using either of two different named arguments. | |
| 433 * | |
| 434 * The scheme component is set through [scheme]. The scheme is | |
| 435 * normalized to all lowercase letters. If the scheme is omitted or empty, | |
| 436 * the URI will not have a scheme part. | |
| 437 * | |
| 438 * The user info part of the authority component is set through | |
| 439 * [userInfo]. It defaults to the empty string, which will be omitted | |
| 440 * from the string representation of the URI. | |
| 441 * | |
| 442 * The host part of the authority component is set through | |
| 443 * [host]. The host can either be a hostname, an IPv4 address or an | |
| 444 * IPv6 address, contained in '[' and ']'. If the host contains a | |
| 445 * ':' character, the '[' and ']' are added if not already provided. | |
| 446 * The host is normalized to all lowercase letters. | |
| 447 * | |
| 448 * The port part of the authority component is set through | |
| 449 * [port]. | |
| 450 * If [port] is omitted or `null`, it implies the default port for | |
| 451 * the URI's scheme, and is equivalent to passing that port explicitly. | |
| 452 * The recognized schemes, and their default ports, are "http" (80) and | |
| 453 * "https" (443). All other schemes are considered as having zero as the | |
| 454 * default port. | |
| 455 * | |
| 456 * If any of `userInfo`, `host` or `port` are provided, | |
| 457 * the URI will have an autority according to [hasAuthority]. | |
| 458 * | |
| 459 * The path component is set through either [path] or | |
| 460 * [pathSegments]. When [path] is used, it should be a valid URI path, | |
| 461 * but invalid characters, except the general delimiters ':/@[]?#', | |
| 462 * will be escaped if necessary. | |
| 463 * When [pathSegments] is used, each of the provided segments | |
| 464 * is first percent-encoded and then joined using the forward slash | |
| 465 * separator. The percent-encoding of the path segments encodes all | |
| 466 * characters except for the unreserved characters and the following | |
| 467 * list of characters: `!$&'()*+,;=:@`. If the other components | |
| 468 * calls for an absolute path a leading slash `/` is prepended if | |
| 469 * not already there. | |
| 470 * | |
| 471 * The query component is set through either [query] or | |
| 472 * [queryParameters]. When [query] is used the provided string should | |
| 473 * be a valid URI query, but invalid characters other than general delimiters, | |
| 474 * will be escaped if necessary. | |
| 475 * When [queryParameters] is used the query is built from the | |
| 476 * provided map. Each key and value in the map is percent-encoded | |
| 477 * and joined using equal and ampersand characters. The | |
| 478 * percent-encoding of the keys and values encodes all characters | |
| 479 * except for the unreserved characters. | |
| 480 * If `query` is the empty string, it is equivalent to omitting it. | |
| 481 * To have an actual empty query part, | |
| 482 * use an empty list for `queryParameters`. | |
| 483 * If both `query` and `queryParameters` are omitted or `null`, the | |
| 484 * URI will have no query part. | |
| 485 * | |
| 486 * The fragment component is set through [fragment]. | |
| 487 * It should be a valid URI fragment, but invalid characters other than | |
| 488 * general delimiters, will be escaped if necessary. | |
| 489 * If `fragment` is omitted or `null`, the URI will have no fragment part. | |
| 490 */ | |
| 491 factory Uri({String scheme : "", | |
| 492 String userInfo : "", | |
| 493 String host, | |
| 494 int port, | |
| 495 String path, | |
| 496 Iterable<String> pathSegments, | |
| 497 String query, | |
| 498 Map<String, String> queryParameters, | |
| 499 String fragment}) { | |
| 500 scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme)); | |
| 501 userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo)); | |
| 502 host = _makeHost(host, 0, _stringOrNullLength(host), false); | |
| 503 // Special case this constructor for backwards compatibility. | |
| 504 if (query == "") query = null; | |
| 505 query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters); | |
| 506 fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment)); | |
| 507 port = _makePort(port, scheme); | |
| 508 bool isFile = (scheme == "file"); | |
| 509 if (host == null && | |
| 510 (userInfo.isNotEmpty || port != null || isFile)) { | |
| 511 host = ""; | |
| 512 } | |
| 513 bool hasAuthority = (host != null); | |
| 514 path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, | |
| 515 scheme, hasAuthority); | |
| 516 if (scheme.isEmpty && host == null && !path.startsWith('/')) { | |
| 517 path = _normalizeRelativePath(path); | |
| 518 } else { | |
| 519 path = _removeDotSegments(path); | |
| 520 } | |
| 521 return new Uri._internal(scheme, userInfo, host, port, | |
| 522 path, query, fragment); | |
| 523 } | |
| 524 | |
| 525 /** | |
| 526 * Creates a new `http` URI from authority, path and query. | |
| 527 * | |
| 528 * Examples: | |
| 529 * | |
| 530 * ``` | |
| 531 * // http://example.org/path?q=dart. | |
| 532 * new Uri.http("google.com", "/search", { "q" : "dart" }); | |
| 533 * | |
| 534 * // http://user:pass@localhost:8080 | |
| 535 * new Uri.http("user:pass@localhost:8080", ""); | |
| 536 * | |
| 537 * // http://example.org/a%20b | |
| 538 * new Uri.http("example.org", "a b"); | |
| 539 * | |
| 540 * // http://example.org/a%252F | |
| 541 * new Uri.http("example.org", "/a%2F"); | |
| 542 * ``` | |
| 543 * | |
| 544 * The `scheme` is always set to `http`. | |
| 545 * | |
| 546 * The `userInfo`, `host` and `port` components are set from the | |
| 547 * [authority] argument. If `authority` is `null` or empty, | |
| 548 * the created `Uri` will have no authority, and will not be directly usable | |
| 549 * as an HTTP URL, which must have a non-empty host. | |
| 550 * | |
| 551 * The `path` component is set from the [unencodedPath] | |
| 552 * argument. The path passed must not be encoded as this constructor | |
| 553 * encodes the path. | |
| 554 * | |
| 555 * The `query` component is set from the optional [queryParameters] | |
| 556 * argument. | |
| 557 */ | |
| 558 factory Uri.http(String authority, | |
| 559 String unencodedPath, | |
| 560 [Map<String, String> queryParameters]) { | |
| 561 return _makeHttpUri("http", authority, unencodedPath, queryParameters); | |
| 562 } | |
| 563 | |
| 564 /** | |
| 565 * Creates a new `https` URI from authority, path and query. | |
| 566 * | |
| 567 * This constructor is the same as [Uri.http] except for the scheme | |
| 568 * which is set to `https`. | |
| 569 */ | |
| 570 factory Uri.https(String authority, | |
| 571 String unencodedPath, | |
| 572 [Map<String, String> queryParameters]) { | |
| 573 return _makeHttpUri("https", authority, unencodedPath, queryParameters); | |
| 574 } | |
| 575 | |
| 576 static Uri _makeHttpUri(String scheme, | 591 static Uri _makeHttpUri(String scheme, |
| 577 String authority, | 592 String authority, |
| 578 String unencodedPath, | 593 String unencodedPath, |
| 579 Map<String, String> queryParameters) { | 594 Map<String, String> queryParameters) { |
| 580 var userInfo = ""; | 595 var userInfo = ""; |
| 581 var host = null; | 596 var host = null; |
| 582 var port = null; | 597 var port = null; |
| 583 | 598 |
| 584 if (authority != null && authority.isNotEmpty) { | 599 if (authority != null && authority.isNotEmpty) { |
| 585 var hostStart = 0; | 600 var hostStart = 0; |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 if (scheme != null) { | 946 if (scheme != null) { |
| 932 scheme = _makeScheme(scheme, 0, scheme.length); | 947 scheme = _makeScheme(scheme, 0, scheme.length); |
| 933 schemeChanged = true; | 948 schemeChanged = true; |
| 934 } else { | 949 } else { |
| 935 scheme = this.scheme; | 950 scheme = this.scheme; |
| 936 } | 951 } |
| 937 bool isFile = (scheme == "file"); | 952 bool isFile = (scheme == "file"); |
| 938 if (userInfo != null) { | 953 if (userInfo != null) { |
| 939 userInfo = _makeUserInfo(userInfo, 0, userInfo.length); | 954 userInfo = _makeUserInfo(userInfo, 0, userInfo.length); |
| 940 } else { | 955 } else { |
| 941 userInfo = this.userInfo; | 956 userInfo = this._userInfo; |
| 942 } | 957 } |
| 943 if (port != null) { | 958 if (port != null) { |
| 944 port = _makePort(port, scheme); | 959 port = _makePort(port, scheme); |
| 945 } else { | 960 } else { |
| 946 port = this._port; | 961 port = this._port; |
| 947 if (schemeChanged) { | 962 if (schemeChanged) { |
| 948 // The default port might have changed. | 963 // The default port might have changed. |
| 949 port = _makePort(port, scheme); | 964 port = _makePort(port, scheme); |
| 950 } | 965 } |
| 951 } | 966 } |
| 952 if (host != null) { | 967 if (host != null) { |
| 953 host = _makeHost(host, 0, host.length, false); | 968 host = _makeHost(host, 0, host.length, false); |
| 954 } else if (this.hasAuthority) { | 969 } else if (this.hasAuthority) { |
| 955 host = this.host; | 970 host = this._host; |
| 956 } else if (userInfo.isNotEmpty || port != null || isFile) { | 971 } else if (userInfo.isNotEmpty || port != null || isFile) { |
| 957 host = ""; | 972 host = ""; |
| 958 } | 973 } |
| 959 | 974 |
| 960 bool hasAuthority = host != null; | 975 bool hasAuthority = host != null; |
| 961 if (path != null || pathSegments != null) { | 976 if (path != null || pathSegments != null) { |
| 962 path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, | 977 path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, |
| 963 scheme, hasAuthority); | 978 scheme, hasAuthority); |
| 964 } else { | 979 } else { |
| 965 path = this.path; | 980 path = this._path; |
| 966 if ((isFile || (hasAuthority && !path.isEmpty)) && | 981 if ((isFile || (hasAuthority && !path.isEmpty)) && |
| 967 !path.startsWith('/')) { | 982 !path.startsWith('/')) { |
| 968 path = "/" + path; | 983 path = "/" + path; |
| 969 } | 984 } |
| 970 } | 985 } |
| 971 | 986 |
| 972 if (query != null || queryParameters != null) { | 987 if (query != null || queryParameters != null) { |
| 973 query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters); | 988 query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters); |
| 974 } else if (this.hasQuery) { | 989 } else { |
| 975 query = this.query; | 990 query = this._query; |
| 976 } | 991 } |
| 977 | 992 |
| 978 if (fragment != null) { | 993 if (fragment != null) { |
| 979 fragment = _makeFragment(fragment, 0, fragment.length); | 994 fragment = _makeFragment(fragment, 0, fragment.length); |
| 980 } else if (this.hasFragment) { | 995 } else { |
| 981 fragment = this.fragment; | 996 fragment = this._fragment; |
| 982 } | 997 } |
| 983 | 998 |
| 984 return new Uri._internal( | 999 return new Uri._internal( |
| 985 scheme, userInfo, host, port, path, query, fragment); | 1000 scheme, userInfo, host, port, path, query, fragment); |
| 986 } | 1001 } |
| 987 | 1002 |
| 988 /** | 1003 /** |
| 989 * Returns a `Uri` that differs from this only in not having a fragment. | 1004 * Returns a `Uri` that differs from this only in not having a fragment. |
| 990 * | 1005 * |
| 991 * If this `Uri` does not have a fragment, it is itself returned. | 1006 * If this `Uri` does not have a fragment, it is itself returned. |
| 992 */ | 1007 */ |
| 993 Uri removeFragment() { | 1008 Uri removeFragment() { |
| 994 if (!this.hasFragment) return this; | 1009 if (!this.hasFragment) return this; |
| 995 return new Uri._internal(scheme, userInfo, host, port, path, query, null); | 1010 return new Uri._internal(scheme, _userInfo, _host, _port, |
| 1011 _path, _query, null); |
| 996 } | 1012 } |
| 997 | 1013 |
| 998 /** | 1014 /** |
| 999 * Returns the URI path split into its segments. Each of the | 1015 * Returns the URI path split into its segments. Each of the |
| 1000 * segments in the returned list have been decoded. If the path is | 1016 * segments in the returned list have been decoded. If the path is |
| 1001 * empty the empty list will be returned. A leading slash `/` does | 1017 * empty the empty list will be returned. A leading slash `/` does |
| 1002 * not affect the segments returned. | 1018 * not affect the segments returned. |
| 1003 * | 1019 * |
| 1004 * The returned list is unmodifiable and will throw [UnsupportedError] on any | 1020 * The returned list is unmodifiable and will throw [UnsupportedError] on any |
| 1005 * calls that would mutate it. | 1021 * calls that would mutate it. |
| (...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2591 0xafff, // 0x30 - 0x3f 1111111111110101 | 2607 0xafff, // 0x30 - 0x3f 1111111111110101 |
| 2592 // @ABCDEFGHIJKLMNO | 2608 // @ABCDEFGHIJKLMNO |
| 2593 0xffff, // 0x40 - 0x4f 1111111111111111 | 2609 0xffff, // 0x40 - 0x4f 1111111111111111 |
| 2594 // PQRSTUVWXYZ _ | 2610 // PQRSTUVWXYZ _ |
| 2595 0x87ff, // 0x50 - 0x5f 1111111111100001 | 2611 0x87ff, // 0x50 - 0x5f 1111111111100001 |
| 2596 // abcdefghijklmno | 2612 // abcdefghijklmno |
| 2597 0xfffe, // 0x60 - 0x6f 0111111111111111 | 2613 0xfffe, // 0x60 - 0x6f 0111111111111111 |
| 2598 // pqrstuvwxyz ~ | 2614 // pqrstuvwxyz ~ |
| 2599 0x47ff]; // 0x70 - 0x7f 1111111111100010 | 2615 0x47ff]; // 0x70 - 0x7f 1111111111100010 |
| 2600 } | 2616 } |
| OLD | NEW |