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 |