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 |