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, as specified by RFC-3986, http://tools.ietf.org/html/rfc3986. | 8 * A parsed URI, as specified by RFC-3986, http://tools.ietf.org/html/rfc3986. |
9 */ | 9 */ |
10 class Uri { | 10 class Uri { |
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1120 */ | 1120 */ |
1121 static String decodeComponent(String encodedComponent) { | 1121 static String decodeComponent(String encodedComponent) { |
1122 return _uriDecode(encodedComponent); | 1122 return _uriDecode(encodedComponent); |
1123 } | 1123 } |
1124 | 1124 |
1125 /** | 1125 /** |
1126 * Decodes the percent-encoding in [encodedComponent], converting | 1126 * Decodes the percent-encoding in [encodedComponent], converting |
1127 * pluses to spaces. | 1127 * pluses to spaces. |
1128 * | 1128 * |
1129 * It will create a byte-list of the decoded characters, and then use | 1129 * It will create a byte-list of the decoded characters, and then use |
1130 * [decode] to decode the byte-list to a String. Default is a UTF-8 decoder. | 1130 * [encoding] to decode the byte-list to a String. The default encoding is |
| 1131 * UTF-8. |
1131 */ | 1132 */ |
1132 static String decodeQueryComponent( | 1133 static String decodeQueryComponent( |
1133 String encodedComponent, | 1134 String encodedComponent, |
1134 {String decode(List<int> bytes): null}) { | 1135 {Encoding encoding: UTF8}) { |
1135 return _uriDecode(encodedComponent, plusToSpace: true, decode: decode); | 1136 return _uriDecode(encodedComponent, plusToSpace: true, encoding: encoding); |
1136 } | 1137 } |
1137 | 1138 |
1138 /** | 1139 /** |
1139 * Encode the string [uri] using percent-encoding to make it | 1140 * Encode the string [uri] using percent-encoding to make it |
1140 * safe for literal use as a full URI. | 1141 * safe for literal use as a full URI. |
1141 * | 1142 * |
1142 * All characters except uppercase and lowercase letters, digits and | 1143 * All characters except uppercase and lowercase letters, digits and |
1143 * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This | 1144 * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This |
1144 * is the set of characters specified in in ECMA-262 version 5.1 for | 1145 * is the set of characters specified in in ECMA-262 version 5.1 for |
1145 * the encodeURI function . | 1146 * the encodeURI function . |
(...skipping 19 matching lines...) Expand all Loading... |
1165 * specified for FORM post in the | 1166 * specified for FORM post in the |
1166 * [HTML 4.01 specification section 17.13.4] | 1167 * [HTML 4.01 specification section 17.13.4] |
1167 * (http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 | 1168 * (http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 |
1168 * "HTML 4.01 section 17.13.4"). Each key and value in the returned | 1169 * "HTML 4.01 section 17.13.4"). Each key and value in the returned |
1169 * map has been decoded. If the [query] | 1170 * map has been decoded. If the [query] |
1170 * is the empty string an empty map is returned. | 1171 * is the empty string an empty map is returned. |
1171 * | 1172 * |
1172 * Keys in the query string that have no value are mapped to the | 1173 * Keys in the query string that have no value are mapped to the |
1173 * empty string. | 1174 * empty string. |
1174 * | 1175 * |
1175 * Each query component will be decoded using [decode]. Default is a UTF-8 | 1176 * Each query component will be decoded using [encoding]. The default encoding |
1176 * decoder. | 1177 * is UTF-8. |
1177 */ | 1178 */ |
1178 static Map<String, String> splitQueryString( | 1179 static Map<String, String> splitQueryString(String query, |
1179 String query, | 1180 {Encoding encoding: UTF8}) { |
1180 {String decode(List<int> bytes): null}) { | |
1181 return query.split("&").fold({}, (map, element) { | 1181 return query.split("&").fold({}, (map, element) { |
1182 int index = element.indexOf("="); | 1182 int index = element.indexOf("="); |
1183 if (index == -1) { | 1183 if (index == -1) { |
1184 if (element != "") map[decodeQueryComponent(element)] = ""; | 1184 if (element != "") { |
| 1185 map[decodeQueryComponent(element, encoding: encoding)] = ""; |
| 1186 } |
1185 } else if (index != 0) { | 1187 } else if (index != 0) { |
1186 var key = element.substring(0, index); | 1188 var key = element.substring(0, index); |
1187 var value = element.substring(index + 1); | 1189 var value = element.substring(index + 1); |
1188 map[Uri.decodeQueryComponent(key, decode: decode)] = | 1190 map[Uri.decodeQueryComponent(key, encoding: encoding)] = |
1189 decodeQueryComponent(value, decode: decode); | 1191 decodeQueryComponent(value, encoding: encoding); |
1190 } | 1192 } |
1191 return map; | 1193 return map; |
1192 }); | 1194 }); |
1193 } | 1195 } |
1194 | 1196 |
1195 /** | 1197 /** |
1196 * Parse the [host] as an IP version 4 (IPv4) address, returning the address | 1198 * Parse the [host] as an IP version 4 (IPv4) address, returning the address |
1197 * as a list of 4 bytes in network byte order (big endian). | 1199 * as a list of 4 bytes in network byte order (big endian). |
1198 * | 1200 * |
1199 * Throws a [FormatException] if [host] is not a valid IPv4 address | 1201 * Throws a [FormatException] if [host] is not a valid IPv4 address |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 /** | 1414 /** |
1413 * Uri-decode a percent-encoded string. | 1415 * Uri-decode a percent-encoded string. |
1414 * | 1416 * |
1415 * It unescapes the string [text] and returns the unescaped string. | 1417 * It unescapes the string [text] and returns the unescaped string. |
1416 * | 1418 * |
1417 * This function is similar to the JavaScript-function `decodeURI`. | 1419 * This function is similar to the JavaScript-function `decodeURI`. |
1418 * | 1420 * |
1419 * If [plusToSpace] is `true`, plus characters will be converted to spaces. | 1421 * If [plusToSpace] is `true`, plus characters will be converted to spaces. |
1420 * | 1422 * |
1421 * The decoder will create a byte-list of the percent-encoded parts, and then | 1423 * The decoder will create a byte-list of the percent-encoded parts, and then |
1422 * decode the byte-list using [decode]. Default is a UTF-8 decoder. | 1424 * decode the byte-list using [encoding]. The default encodingis UTF-8. |
1423 */ | 1425 */ |
1424 static String _uriDecode(String text, | 1426 static String _uriDecode(String text, |
1425 {bool plusToSpace: false, | 1427 {bool plusToSpace: false, |
1426 String decode(List<int> bytes): null}) { | 1428 Encoding encoding: UTF8}) { |
1427 StringBuffer result = new StringBuffer(); | 1429 StringBuffer result = new StringBuffer(); |
1428 List<int> codepoints = new List<int>(); | 1430 List<int> codepoints = new List<int>(); |
1429 for (int i = 0; i < text.length;) { | 1431 for (int i = 0; i < text.length;) { |
1430 int ch = text.codeUnitAt(i); | 1432 int ch = text.codeUnitAt(i); |
1431 if (ch != _PERCENT) { | 1433 if (ch != _PERCENT) { |
1432 if (plusToSpace && ch == _PLUS) { | 1434 if (plusToSpace && ch == _PLUS) { |
1433 result.write(" "); | 1435 result.write(" "); |
1434 } else { | 1436 } else { |
1435 result.writeCharCode(ch); | 1437 result.writeCharCode(ch); |
1436 } | 1438 } |
1437 i++; | 1439 i++; |
1438 } else { | 1440 } else { |
1439 codepoints.clear(); | 1441 codepoints.clear(); |
1440 while (ch == _PERCENT) { | 1442 while (ch == _PERCENT) { |
1441 if (++i > text.length - 2) { | 1443 if (++i > text.length - 2) { |
1442 throw new ArgumentError('Truncated URI'); | 1444 throw new ArgumentError('Truncated URI'); |
1443 } | 1445 } |
1444 codepoints.add(_hexCharPairToByte(text, i)); | 1446 codepoints.add(_hexCharPairToByte(text, i)); |
1445 i += 2; | 1447 i += 2; |
1446 if (i == text.length) break; | 1448 if (i == text.length) break; |
1447 ch = text.codeUnitAt(i); | 1449 ch = text.codeUnitAt(i); |
1448 } | 1450 } |
1449 result.write( | 1451 result.write(encoding.decode(codepoints)); |
1450 decode == null ? UTF8.decode(codepoints) : decode(codepoints)); | |
1451 } | 1452 } |
1452 } | 1453 } |
1453 return result.toString(); | 1454 return result.toString(); |
1454 } | 1455 } |
1455 | 1456 |
1456 // Tables of char-codes organized as a bit vector of 128 bits where | 1457 // Tables of char-codes organized as a bit vector of 128 bits where |
1457 // each bit indicate whether a character code on the 0-127 needs to | 1458 // each bit indicate whether a character code on the 0-127 needs to |
1458 // be escaped or not. | 1459 // be escaped or not. |
1459 | 1460 |
1460 // The unreserved characters of RFC 3986. | 1461 // The unreserved characters of RFC 3986. |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 void clear() { | 1641 void clear() { |
1641 throw new UnsupportedError("Cannot modify an unmodifiable map"); | 1642 throw new UnsupportedError("Cannot modify an unmodifiable map"); |
1642 } | 1643 } |
1643 void forEach(void f(K key, V value)) => _map.forEach(f); | 1644 void forEach(void f(K key, V value)) => _map.forEach(f); |
1644 Iterable<K> get keys => _map.keys; | 1645 Iterable<K> get keys => _map.keys; |
1645 Iterable<V> get values => _map.values; | 1646 Iterable<V> get values => _map.values; |
1646 int get length => _map.length; | 1647 int get length => _map.length; |
1647 bool get isEmpty => _map.isEmpty; | 1648 bool get isEmpty => _map.isEmpty; |
1648 bool get isNotEmpty => _map.isNotEmpty; | 1649 bool get isNotEmpty => _map.isNotEmpty; |
1649 } | 1650 } |
OLD | NEW |