| Index: sdk/lib/core/uri.dart
|
| diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
|
| index c8277e7fc6b4b035ad7624e195049d0817a80740..55335e82c6c8a30fdf89a2142b54dcd6351b9123 100644
|
| --- a/sdk/lib/core/uri.dart
|
| +++ b/sdk/lib/core/uri.dart
|
| @@ -82,6 +82,16 @@ class Uri {
|
| final String fragment;
|
|
|
| /**
|
| + * Cache the computed return value of [pathSegements].
|
| + */
|
| + List<String> _pathSegments;
|
| +
|
| + /**
|
| + * Cache the computed return value of [queryParameters].
|
| + */
|
| + Map<String, String> _queryParameters;
|
| +
|
| + /**
|
| * Creates a new URI object by parsing a URI string.
|
| */
|
| static Uri parse(String uri) => new Uri._fromMatch(_splitRe.firstMatch(uri));
|
| @@ -167,10 +177,19 @@ class Uri {
|
| * Returns the URI path split into its segments. Each of the
|
| * segments in the returned list have been decoded. If the path is
|
| * empty the empty list will be returned.
|
| + *
|
| + * The returned list is immutable and will throw [StateError] on any
|
| + * calls that would mutate it.
|
| */
|
| List<String> get pathSegments {
|
| - if (path == "") return const<String>[];
|
| - return path.split("/").map(Uri.decodeComponent).toList(growable: false);
|
| + if (_pathSegments == null) {
|
| + _pathSegments = new UnmodifiableListView(
|
| + path == "" ? const<String>[]
|
| + : path.split("/")
|
| + .map(Uri.decodeComponent)
|
| + .toList(growable: false));
|
| + }
|
| + return _pathSegments;
|
| }
|
|
|
| /*
|
| @@ -178,9 +197,14 @@ class Uri {
|
| * specified for FORM post in the HTML 4.01 specification. Each key
|
| * and value in the returned map have been decoded. If there is no
|
| * query the empty map will be returned.
|
| + *
|
| + * The returned map is immutable and will throw [StateError] on any
|
| + * calls that would mutate it.
|
| */
|
| Map<String, String> get queryParameters {
|
| - return query.split("&").fold({}, (map, element) {
|
| + if (_queryParameters == null) {
|
| + var map;
|
| + map = query.split("&").fold({}, (map, element) {
|
| int index = element.indexOf("=");
|
| if (index == -1) {
|
| if (!element.isEmpty) map[element] = "";
|
| @@ -190,7 +214,10 @@ class Uri {
|
| map[Uri.decodeQueryComponent(key)] = decodeQueryComponent(value);
|
| }
|
| return map;
|
| - });
|
| + });
|
| + _queryParameters = new _UnmodifiableMap(map);
|
| + }
|
| + return _queryParameters;
|
| }
|
|
|
| static String _makeScheme(String scheme) {
|
| @@ -944,3 +971,30 @@ class Uri {
|
| // pqrstuvwxyz ~
|
| 0x47ff]; // 0x70 - 0x7f 1111111111100010
|
| }
|
| +
|
| +class _UnmodifiableMap<K, V> implements Map<K, V> {
|
| + final Map _map;
|
| + const _UnmodifiableMap(this._map);
|
| +
|
| + bool containsValue(V value) => _map.containsValue(value);
|
| + bool containsKey(K key) => _map.containsKey(key);
|
| + V operator [](K key) => _map[key];
|
| + void operator []=(K key, V value) {
|
| + throw new UnsupportedError("Cannot modify an unmodifiable map");
|
| + }
|
| + V putIfAbsent(K key, V ifAbsent()) {
|
| + throw new UnsupportedError("Cannot modify an unmodifiable map");
|
| + }
|
| + V remove(K key) {
|
| + throw new UnsupportedError("Cannot modify an unmodifiable map");
|
| + }
|
| + void clear() {
|
| + throw new UnsupportedError("Cannot modify an unmodifiable map");
|
| + }
|
| + void forEach(void f(K key, V value)) => _map.forEach(f);
|
| + Iterable<K> get keys => _map.keys;
|
| + Iterable<V> get values => _map.values;
|
| + int get length => _map.length;
|
| + bool get isEmpty => _map.isEmpty;
|
| + bool get isNotEmpty => _map.isNotEmpty;
|
| +}
|
|
|