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

Unified Diff: pkg/serialization/lib/src/serialization_helpers.dart

Issue 11293283: Initial version of a serialization framework (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/serialization/lib/src/reader_writer.dart ('k') | pkg/serialization/lib/src/serialization_rule.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/serialization/lib/src/serialization_helpers.dart
===================================================================
--- pkg/serialization/lib/src/serialization_helpers.dart (revision 0)
+++ pkg/serialization/lib/src/serialization_helpers.dart (revision 0)
@@ -0,0 +1,205 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This contains extra functions and classes useful for implementing
+ * serialiation. Some or all of these will be removed once the functionality is
+ * available in the core library.
+ */
+library serialization_helpers;
+import 'polyfill_identity_set.dart';
+
+/**
+ * A named function of one argument that just returns it. Useful for using
+ * as a default value for a function parameter or other places where you want
+ * to concisely provide a function that just returns its argument.
+ */
+doNothing(x) => x;
+
+/** Concatenate two lists. Handle the case where one or both might be null. */
+// TODO(alanknight): Remove once issue 5342 is resolved.
+List append(List a, List b) {
+ if (a == null) {
+ return (b == null) ? [] : new List.from(b);
+ }
+ if (b == null) return new List.from(a);
+ var result = new List.from(a);
+ result.addAll(b);
+ return result;
+}
+
+/**
+ * Return a sorted version of [aCollection], using the default sort criterion.
+ * Always returns a List, regardless of the type of [aCollection].
+ */
+List sorted(aCollection) {
+ var result = new List.from(aCollection);
+ result.sort();
+ return result;
+}
+
+/**
+ * Be able to iterate polymorphically between List-like and Map-like things.
+ * For example, keysAndValues(["a", "b", "c"]).forEach((key, value) => ...);
+ * will loop over the key/value pairs 1/"a", 2/"b", 3/"c", as if the argument
+ * was a Map from integer keys to string values.
+ * Only supports forEach() and map() operations because that was all the code
+ * needed for the moment.
+ */
+MapLikeIterable keysAndValues(x) {
+ if (x is Map) return new MapLikeIterableForMap(x);
+ if (x is Iterable) return new MapLikeIterableForList(x);
+ throw new ArgumentError("Invalid argument");
+}
+
+/**
+ * A class for iterating over things as if they were Maps, which primarily
+ * means that forEach() and map() pass two arguments, and map() returns a new
+ * Map with the same keys as [collection] and values which have been transformed
+ * by the argument to map().
+ */
+abstract class MapLikeIterable {
+ MapLikeIterable(this.collection);
+ final collection;
+
+ /** Iterate over the collection, passing both key and value parameters. */
+ void forEach(Function f);
+
+ /**
+ * Return a new collection whose keys are the same as [collection], but whose
+ * values are the result of applying [f] to the key/value pairs. So, if
+ * [collection] is a List, it will be the same as the map() method if the
+ * [key] parameter wasn't passed.
+ */
+ map(Function f) {
+ var result = copyEmpty();
+ forEach((key, value) {
+ result[key] = f(key, value);
+ });
+ return result;
+ }
+
+ /**
+ * Return an empty copy of our collection. Very limited, only knows enough
+ * to return a Map or List as appropriate.
+ */
+ copyEmpty();
+}
+
+
+
+class MapLikeIterableForMap extends MapLikeIterable {
+ MapLikeIterableForMap(collection) : super(collection);
+
+ void forEach(Function f) { collection.forEach(f);}
+ Map copyEmpty() => new Map();
+}
+
+class MapLikeIterableForList extends MapLikeIterable {
+ MapLikeIterableForList(collection) : super(collection);
+
+ void forEach(f) {
+ Iterator iterator = collection.iterator();
+ for (var i = 0; i < collection.length; i++) {
+ f(i, iterator.next());
+ }
+ }
+
+ List copyEmpty() => new List(collection.length);
+}
+
+/**
+ * An inverse of MapLikeIterable. Lets you iterate polymorphically between
+ * List-like and Map-like things, but making them behave like Lists, instead
+ * of behaving like Maps.
+ * So values(["a", "b", "c"]).forEach((value) => ...);
+ * will loop over the values "a", "b", "c", as if it were a List of values.
+ * Only supports forEach() and map() operations because that was all I needed
+ * for the moment.
+ */
+values(x) {
+ if (x is Iterable) return x;
+ if (x is Map) return new ListLikeIterable(x);
+ throw new ArgumentError("Invalid argument");
+}
+
+/**
+ * A class for iterating over things as if they were Lists, which primarily
+ * means that forEach passes one argument, and map() returns a new Map
+ * with the same keys as [collection] and values which haev been transformed
+ * by the argument to map().
+ */
+class ListLikeIterable {
+ ListLikeIterable(this.collection);
+ final Map collection;
+
+ /** Iterate over the collection, passing just the value parameters. */
+ forEach(f) {
+ collection.forEach((key, value) => f(value));
+ }
+
+ /**
+ * Return a new collection whose keys are the same as [collection], but whose
+ * values are the result of applying [f] to the key/value pairs. So, if
+ * [collection] is a List, it will be the same as if map() had been called
+ * directly on [collection].
+ */
+ map(Function f) {
+ var result = new Map();
+ collection.forEach((key, value) => result[key] = f(value));
+ return result;
+ }
+
+ /**
+ * Return an iterator that behaves like a List iterator, taking one parameter.
+ */
+ Iterator iterator() => collection.values.iterator();
+}
+
+/**
+ * This acts as a stand-in for some value that cannot be hashed. We can't
+ * just use const Object() because the compiler will fold them together.
+ */
+class _Sentinel {
+ final _wrappedObject;
+ const _Sentinel(this._wrappedObject);
+}
+
+/**
+ * This provides an identity map which allows true, false, and null as
+ * valid keys. It does this by special casing them and using some other
+ * known object as the key instead.
+ */
+class IdentityMapPlus<K, V> extends IdentityMap {
+ final trueish = const _Sentinel(true);
+ final falseish = const _Sentinel(false);
+ final nullish = const _Sentinel(null);
+
+ wrap(x) {
+ if (x == true) return trueish;
+ if (x == false) return falseish;
+ if (x == null) return nullish;
+ return x;
+ }
+
+ unwrap(x) {
+ if (x is _Sentinel) return x._wrappedObject;
+ return x;
+ }
+
+ operator [](key) => super[wrap(key)];
+ operator []=(key, value) => super[wrap(key)] = value;
+
+ putIfAbsent(key, ifAbsent) => super.putIfAbsent(wrap(key), ifAbsent);
+
+ containsKey(key) => super.containsKey(wrap(key));
+ forEach(f) => super.forEach((key, value) => f(unwrap(key), value));
+ remove(key) => super.remove(unwrap(key));
+ /**
+ * Note that keys is a very inefficient operation for this type. Don't do it.
+ */
+ get keys => super.keys.map((x) => unwrap(x));
+}
+
+
« no previous file with comments | « pkg/serialization/lib/src/reader_writer.dart ('k') | pkg/serialization/lib/src/serialization_rule.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698