Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: sdk/lib/core/uri.dart

Issue 16108003: Avoid parsing path and query string more than once (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fixes Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/corelib/uri_path_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 75
76 /** 76 /**
77 * Returns the fragment identifier component. 77 * Returns the fragment identifier component.
78 * 78 *
79 * Returns the empty string if there is no fragment identifier 79 * Returns the empty string if there is no fragment identifier
80 * component. 80 * component.
81 */ 81 */
82 final String fragment; 82 final String fragment;
83 83
84 /** 84 /**
85 * Cache the computed return value of [pathSegements].
86 */
87 List<String> _pathSegments;
88
89 /**
90 * Cache the computed return value of [queryParameters].
91 */
92 Map<String, String> _queryParameters;
93
94 /**
85 * Creates a new URI object by parsing a URI string. 95 * Creates a new URI object by parsing a URI string.
86 */ 96 */
87 static Uri parse(String uri) => new Uri._fromMatch(_splitRe.firstMatch(uri)); 97 static Uri parse(String uri) => new Uri._fromMatch(_splitRe.firstMatch(uri));
88 98
89 Uri._fromMatch(Match m) : 99 Uri._fromMatch(Match m) :
90 this(scheme: _emptyIfNull(m[_COMPONENT_SCHEME]), 100 this(scheme: _emptyIfNull(m[_COMPONENT_SCHEME]),
91 userInfo: _emptyIfNull(m[_COMPONENT_USER_INFO]), 101 userInfo: _emptyIfNull(m[_COMPONENT_USER_INFO]),
92 host: _eitherOf( 102 host: _eitherOf(
93 m[_COMPONENT_HOST], m[_COMPONENT_HOST_IPV6]), 103 m[_COMPONENT_HOST], m[_COMPONENT_HOST_IPV6]),
94 port: _parseIntOrZero(m[_COMPONENT_PORT]), 104 port: _parseIntOrZero(m[_COMPONENT_PORT]),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 _port = 0; 170 _port = 0;
161 } else { 171 } else {
162 _port = port; 172 _port = port;
163 } 173 }
164 } 174 }
165 175
166 /* 176 /*
167 * Returns the URI path split into its segments. Each of the 177 * Returns the URI path split into its segments. Each of the
168 * segments in the returned list have been decoded. If the path is 178 * segments in the returned list have been decoded. If the path is
169 * empty the empty list will be returned. 179 * empty the empty list will be returned.
180 *
181 * The returned list is immutable and will throw [StateError] on any
182 * calls that would mutate it.
170 */ 183 */
171 List<String> get pathSegments { 184 List<String> get pathSegments {
172 if (path == "") return const<String>[]; 185 if (_pathSegments == null) {
173 return path.split("/").map(Uri.decodeComponent).toList(growable: false); 186 _pathSegments = new UnmodifiableListView(
187 path == "" ? const<String>[]
188 : path.split("/")
189 .map(Uri.decodeComponent)
190 .toList(growable: false));
191 }
192 return _pathSegments;
174 } 193 }
175 194
176 /* 195 /*
177 * Returns the URI query split into a map according to the rules 196 * Returns the URI query split into a map according to the rules
178 * specified for FORM post in the HTML 4.01 specification. Each key 197 * specified for FORM post in the HTML 4.01 specification. Each key
179 * and value in the returned map have been decoded. If there is no 198 * and value in the returned map have been decoded. If there is no
180 * query the empty map will be returned. 199 * query the empty map will be returned.
200 *
201 * The returned map is immutable and will throw [StateError] on any
202 * calls that would mutate it.
181 */ 203 */
182 Map<String, String> get queryParameters { 204 Map<String, String> get queryParameters {
183 return query.split("&").fold({}, (map, element) { 205 if (_queryParameters == null) {
206 var map;
207 map = query.split("&").fold({}, (map, element) {
184 int index = element.indexOf("="); 208 int index = element.indexOf("=");
185 if (index == -1) { 209 if (index == -1) {
186 if (!element.isEmpty) map[element] = ""; 210 if (!element.isEmpty) map[element] = "";
187 } else if (index != 0) { 211 } else if (index != 0) {
188 var key = element.substring(0, index); 212 var key = element.substring(0, index);
189 var value = element.substring(index + 1); 213 var value = element.substring(index + 1);
190 map[Uri.decodeQueryComponent(key)] = decodeQueryComponent(value); 214 map[Uri.decodeQueryComponent(key)] = decodeQueryComponent(value);
191 } 215 }
192 return map; 216 return map;
193 }); 217 });
218 _queryParameters = new _UnmodifiableMap(map);
219 }
220 return _queryParameters;
194 } 221 }
195 222
196 static String _makeScheme(String scheme) { 223 static String _makeScheme(String scheme) {
197 bool isSchemeLowerCharacter(int ch) { 224 bool isSchemeLowerCharacter(int ch) {
198 return ch < 128 && 225 return ch < 128 &&
199 ((_schemeLowerTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); 226 ((_schemeLowerTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
200 } 227 }
201 228
202 bool isSchemeCharacter(int ch) { 229 bool isSchemeCharacter(int ch) {
203 return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); 230 return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 0xafff, // 0x30 - 0x3f 1111111111110101 964 0xafff, // 0x30 - 0x3f 1111111111110101
938 // @ABCDEFGHIJKLMNO 965 // @ABCDEFGHIJKLMNO
939 0xffff, // 0x40 - 0x4f 1111111111111111 966 0xffff, // 0x40 - 0x4f 1111111111111111
940 // PQRSTUVWXYZ _ 967 // PQRSTUVWXYZ _
941 0x87ff, // 0x50 - 0x5f 1111111111100001 968 0x87ff, // 0x50 - 0x5f 1111111111100001
942 // abcdefghijklmno 969 // abcdefghijklmno
943 0xfffe, // 0x60 - 0x6f 0111111111111111 970 0xfffe, // 0x60 - 0x6f 0111111111111111
944 // pqrstuvwxyz ~ 971 // pqrstuvwxyz ~
945 0x47ff]; // 0x70 - 0x7f 1111111111100010 972 0x47ff]; // 0x70 - 0x7f 1111111111100010
946 } 973 }
974
975 class _UnmodifiableMap<K, V> implements Map<K, V> {
976 final Map _map;
977 const _UnmodifiableMap(this._map);
978
979 bool containsValue(V value) => _map.containsValue(value);
980 bool containsKey(K key) => _map.containsKey(key);
981 V operator [](K key) => _map[key];
982 void operator []=(K key, V value) {
983 throw new UnsupportedError("Cannot modify an unmodifiable map");
984 }
985 V putIfAbsent(K key, V ifAbsent()) {
986 throw new UnsupportedError("Cannot modify an unmodifiable map");
987 }
988 V remove(K key) {
989 throw new UnsupportedError("Cannot modify an unmodifiable map");
990 }
991 void clear() {
992 throw new UnsupportedError("Cannot modify an unmodifiable map");
993 }
994 void forEach(void f(K key, V value)) => _map.forEach(f);
995 Iterable<K> get keys => _map.keys;
996 Iterable<V> get values => _map.values;
997 int get length => _map.length;
998 bool get isEmpty => _map.isEmpty;
999 bool get isNotEmpty => _map.isNotEmpty;
1000 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/uri_path_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698