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 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1235 bool isFile = (scheme == "file"); | 1235 bool isFile = (scheme == "file"); |
1236 bool ensureLeadingSlash = isFile || hasAuthority; | 1236 bool ensureLeadingSlash = isFile || hasAuthority; |
1237 if (path == null && pathSegments == null) return isFile ? "/" : ""; | 1237 if (path == null && pathSegments == null) return isFile ? "/" : ""; |
1238 if (path != null && pathSegments != null) { | 1238 if (path != null && pathSegments != null) { |
1239 throw new ArgumentError('Both path and pathSegments specified'); | 1239 throw new ArgumentError('Both path and pathSegments specified'); |
1240 } | 1240 } |
1241 var result; | 1241 var result; |
1242 if (path != null) { | 1242 if (path != null) { |
1243 result = _normalize(path, start, end, _pathCharOrSlashTable); | 1243 result = _normalize(path, start, end, _pathCharOrSlashTable); |
1244 } else { | 1244 } else { |
1245 result = pathSegments.map((s) => _uriEncode(_pathCharTable, s)).join("/"); | 1245 result = pathSegments.map((s) => |
1246 _uriEncode(_pathCharTable, s, UTF8, false)).join("/"); | |
1246 } | 1247 } |
1247 if (result.isEmpty) { | 1248 if (result.isEmpty) { |
1248 if (isFile) return "/"; | 1249 if (isFile) return "/"; |
1249 } else if (ensureLeadingSlash && !result.startsWith('/')) { | 1250 } else if (ensureLeadingSlash && !result.startsWith('/')) { |
1250 result = "/" + result; | 1251 result = "/" + result; |
1251 } | 1252 } |
1252 result = _normalizePath(result, scheme, hasAuthority); | 1253 result = _normalizePath(result, scheme, hasAuthority); |
1253 return result; | 1254 return result; |
1254 } | 1255 } |
1255 | 1256 |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1945 * string. | 1946 * string. |
1946 * | 1947 * |
1947 * For encoding the query part consider using | 1948 * For encoding the query part consider using |
1948 * [encodeQueryComponent]. | 1949 * [encodeQueryComponent]. |
1949 * | 1950 * |
1950 * To avoid the need for explicitly encoding use the [pathSegments] | 1951 * To avoid the need for explicitly encoding use the [pathSegments] |
1951 * and [queryParameters] optional named arguments when constructing | 1952 * and [queryParameters] optional named arguments when constructing |
1952 * a [Uri]. | 1953 * a [Uri]. |
1953 */ | 1954 */ |
1954 static String encodeComponent(String component) { | 1955 static String encodeComponent(String component) { |
1955 return _uriEncode(_unreserved2396Table, component); | 1956 return _uriEncode(_unreserved2396Table, component, UTF8, false); |
1956 } | 1957 } |
1957 | 1958 |
1958 /** | 1959 /** |
1959 * Encode the string [component] according to the HTML 4.01 rules | 1960 * Encode the string [component] according to the HTML 4.01 rules |
1960 * for encoding the posting of a HTML form as a query string | 1961 * for encoding the posting of a HTML form as a query string |
1961 * component. | 1962 * component. |
1962 * | 1963 * |
1963 * Encode the string [component] according to the HTML 4.01 rules | 1964 * Encode the string [component] according to the HTML 4.01 rules |
1964 * for encoding the posting of a HTML form as a query string | 1965 * for encoding the posting of a HTML form as a query string |
1965 * component. | 1966 * component. |
(...skipping 17 matching lines...) Expand all Loading... | |
1983 * | 1984 * |
1984 * To avoid the need for explicitly encoding the query use the | 1985 * To avoid the need for explicitly encoding the query use the |
1985 * [queryParameters] optional named arguments when constructing a | 1986 * [queryParameters] optional named arguments when constructing a |
1986 * [Uri]. | 1987 * [Uri]. |
1987 * | 1988 * |
1988 * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more | 1989 * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more |
1989 * details. | 1990 * details. |
1990 */ | 1991 */ |
1991 static String encodeQueryComponent(String component, | 1992 static String encodeQueryComponent(String component, |
1992 {Encoding encoding: UTF8}) { | 1993 {Encoding encoding: UTF8}) { |
1993 return _uriEncode( | 1994 return _uriEncode(_unreservedTable, component, encoding, true); |
1994 _unreservedTable, component, encoding: encoding, spaceToPlus: true); | |
1995 } | 1995 } |
1996 | 1996 |
1997 /** | 1997 /** |
1998 * Decodes the percent-encoding in [encodedComponent]. | 1998 * Decodes the percent-encoding in [encodedComponent]. |
1999 * | 1999 * |
2000 * Note that decoding a URI component might change its meaning as | 2000 * Note that decoding a URI component might change its meaning as |
2001 * some of the decoded characters could be characters with are | 2001 * some of the decoded characters could be characters with are |
2002 * delimiters for a given URI componene type. Always split a URI | 2002 * delimiters for a given URI componene type. Always split a URI |
2003 * component using the delimiters for the component before decoding | 2003 * component using the delimiters for the component before decoding |
2004 * the individual parts. | 2004 * the individual parts. |
(...skipping 23 matching lines...) Expand all Loading... | |
2028 /** | 2028 /** |
2029 * Encode the string [uri] using percent-encoding to make it | 2029 * Encode the string [uri] using percent-encoding to make it |
2030 * safe for literal use as a full URI. | 2030 * safe for literal use as a full URI. |
2031 * | 2031 * |
2032 * All characters except uppercase and lowercase letters, digits and | 2032 * All characters except uppercase and lowercase letters, digits and |
2033 * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This | 2033 * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This |
2034 * is the set of characters specified in in ECMA-262 version 5.1 for | 2034 * is the set of characters specified in in ECMA-262 version 5.1 for |
2035 * the encodeURI function . | 2035 * the encodeURI function . |
2036 */ | 2036 */ |
2037 static String encodeFull(String uri) { | 2037 static String encodeFull(String uri) { |
2038 return _uriEncode(_encodeFullTable, uri); | 2038 return _uriEncode(_encodeFullTable, uri, UTF8, false); |
2039 } | 2039 } |
2040 | 2040 |
2041 /** | 2041 /** |
2042 * Decodes the percent-encoding in [uri]. | 2042 * Decodes the percent-encoding in [uri]. |
2043 * | 2043 * |
2044 * Note that decoding a full URI might change its meaning as some of | 2044 * Note that decoding a full URI might change its meaning as some of |
2045 * the decoded characters could be reserved characters. In most | 2045 * the decoded characters could be reserved characters. In most |
2046 * cases an encoded URI should be parsed into components using | 2046 * cases an encoded URI should be parsed into components using |
2047 * [Uri.parse] before decoding the separate components. | 2047 * [Uri.parse] before decoding the separate components. |
2048 */ | 2048 */ |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2244 static const int _UPPER_CASE_F = 0x46; | 2244 static const int _UPPER_CASE_F = 0x46; |
2245 static const int _UPPER_CASE_Z = 0x5A; | 2245 static const int _UPPER_CASE_Z = 0x5A; |
2246 static const int _LEFT_BRACKET = 0x5B; | 2246 static const int _LEFT_BRACKET = 0x5B; |
2247 static const int _BACKSLASH = 0x5C; | 2247 static const int _BACKSLASH = 0x5C; |
2248 static const int _RIGHT_BRACKET = 0x5D; | 2248 static const int _RIGHT_BRACKET = 0x5D; |
2249 static const int _LOWER_CASE_A = 0x61; | 2249 static const int _LOWER_CASE_A = 0x61; |
2250 static const int _LOWER_CASE_F = 0x66; | 2250 static const int _LOWER_CASE_F = 0x66; |
2251 static const int _LOWER_CASE_Z = 0x7A; | 2251 static const int _LOWER_CASE_Z = 0x7A; |
2252 static const int _BAR = 0x7C; | 2252 static const int _BAR = 0x7C; |
2253 | 2253 |
2254 // Matches a String that _uriEncodes to itself regardless of the kind of | 2254 external static String _uriEncode(List<int> canonicalTable, |
2255 // component. This corresponds to [_unreservedTable], i.e. characters that | 2255 String text, |
2256 // are not encoded by any encoding table. | 2256 Encoding encoding, |
2257 static final RegExp _needsNoEncoding = new RegExp(r'^[\-\.0-9A-Z_a-z~]*$'); | 2257 bool spaceToPlus); |
Lasse Reichstein Nielsen
2015/11/04 10:15:53
I made the parameters non-optional. That's what I
| |
2258 | |
2259 /** | |
2260 * This is the internal implementation of JavaScript's encodeURI function. | |
2261 * It encodes all characters in the string [text] except for those | |
2262 * that appear in [canonicalTable], and returns the escaped string. | |
2263 */ | |
2264 static String _uriEncode(List<int> canonicalTable, | |
2265 String text, | |
2266 {Encoding encoding: UTF8, | |
2267 bool spaceToPlus: false}) { | |
2268 if (_needsNoEncoding.hasMatch(text)) return text; | |
2269 | |
2270 byteToHex(byte, buffer) { | |
2271 const String hex = '0123456789ABCDEF'; | |
2272 buffer.writeCharCode(hex.codeUnitAt(byte >> 4)); | |
2273 buffer.writeCharCode(hex.codeUnitAt(byte & 0x0f)); | |
2274 } | |
2275 | |
2276 // Encode the string into bytes then generate an ASCII only string | |
2277 // by percent encoding selected bytes. | |
2278 StringBuffer result = new StringBuffer(); | |
2279 var bytes = encoding.encode(text); | |
2280 for (int i = 0; i < bytes.length; i++) { | |
2281 int byte = bytes[i]; | |
2282 if (byte < 128 && | |
2283 ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) { | |
2284 result.writeCharCode(byte); | |
2285 } else if (spaceToPlus && byte == _SPACE) { | |
2286 result.writeCharCode(_PLUS); | |
2287 } else { | |
2288 result.writeCharCode(_PERCENT); | |
2289 byteToHex(byte, result); | |
2290 } | |
2291 } | |
2292 return result.toString(); | |
2293 } | |
2294 | 2258 |
2295 /** | 2259 /** |
2296 * Convert a byte (2 character hex sequence) in string [s] starting | 2260 * Convert a byte (2 character hex sequence) in string [s] starting |
2297 * at position [pos] to its ordinal value | 2261 * at position [pos] to its ordinal value |
2298 */ | 2262 */ |
2299 static int _hexCharPairToByte(String s, int pos) { | 2263 static int _hexCharPairToByte(String s, int pos) { |
2300 int byte = 0; | 2264 int byte = 0; |
2301 for (int i = 0; i < 2; i++) { | 2265 for (int i = 0; i < 2; i++) { |
2302 var charCode = s.codeUnitAt(pos + i); | 2266 var charCode = s.codeUnitAt(pos + i); |
2303 if (0x30 <= charCode && charCode <= 0x39) { | 2267 if (0x30 <= charCode && charCode <= 0x39) { |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2611 0xafff, // 0x30 - 0x3f 1111111111110101 | 2575 0xafff, // 0x30 - 0x3f 1111111111110101 |
2612 // @ABCDEFGHIJKLMNO | 2576 // @ABCDEFGHIJKLMNO |
2613 0xffff, // 0x40 - 0x4f 1111111111111111 | 2577 0xffff, // 0x40 - 0x4f 1111111111111111 |
2614 // PQRSTUVWXYZ _ | 2578 // PQRSTUVWXYZ _ |
2615 0x87ff, // 0x50 - 0x5f 1111111111100001 | 2579 0x87ff, // 0x50 - 0x5f 1111111111100001 |
2616 // abcdefghijklmno | 2580 // abcdefghijklmno |
2617 0xfffe, // 0x60 - 0x6f 0111111111111111 | 2581 0xfffe, // 0x60 - 0x6f 0111111111111111 |
2618 // pqrstuvwxyz ~ | 2582 // pqrstuvwxyz ~ |
2619 0x47ff]; // 0x70 - 0x7f 1111111111100010 | 2583 0x47ff]; // 0x70 - 0x7f 1111111111100010 |
2620 } | 2584 } |
OLD | NEW |