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

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

Issue 12136002: Some fixes to work better with the services framework (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changes from review comments Created 7 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/serialization/lib/src/basic_rule.dart ('k') | pkg/serialization/lib/src/reader_writer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/serialization/lib/src/format.dart
diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart
index c1d122e064bfc999e1d268fa0b3a91cd7172750b..ab602c92a2b80c29997324b736f7a592c07b1f08 100644
--- a/pkg/serialization/lib/src/format.dart
+++ b/pkg/serialization/lib/src/format.dart
@@ -52,23 +52,22 @@ class SimpleMapFormat extends Format {
* This effectively defines a custom JSON serialization format, although
* the details of the format vary depending which rules were used.
*/
- String generateOutput(Writer w) {
+ Map<String, dynamic> generateOutput(Writer w) {
var result = {
"rules" : w.serializedRules(),
"data" : w.states,
"roots" : w._rootReferences()
};
- return json.stringify(result);
+ return result;
}
/**
- * Read a [json] encoded string representing serialized data in this format
+ * Read a [json] compatible representation of serialized data in this format
* and return the nested Map representation described in [generateOutput]. If
* the data also includes rule definitions, then these will replace the rules
* in the [Serialization] for [reader].
*/
- Map<String, dynamic> read(String input, Reader reader) {
- var topLevel = json.parse(input);
+ Map<String, dynamic> read(topLevel, Reader reader) {
var ruleString = topLevel["rules"];
reader.readRules(ruleString);
return topLevel;
@@ -76,12 +75,13 @@ class SimpleMapFormat extends Format {
}
/**
- * A format for "normal" JSON representation of objects. It stores
+ * A format for "normal" [json] representation of objects. It stores
* the fields of the objects as nested maps, and doesn't allow cycles. This can
- * be useful in talking to existing APIs that expect JSON format data. However,
- * note that since the classes of objects aren't stored, this isn't enough
- * information to read back the objects. This format also doesn't support the
- * [selfDescriptive] option on the [Serialization], as storing the rules.
+ * be useful in talking to existing APIs that expect [json] format data. The
+ * output will be either a simple object (string, num, bool), a List, or a Map,
+ * with nesting of those.
+ * Note that since the classes of objects aren't normally stored, this isn't
+ * enough information to read back the objects. However, if the
* If the [storeRoundTripData] field of the format is set to true, then this
* will store the rule number along with the data, allowing reconstruction.
*/
@@ -98,17 +98,27 @@ class SimpleJsonFormat extends Format {
/**
* If we store the rule numbers, what key should we use to store them.
*/
- String ruleIdentifier = "__rule";
+ static final String RULE = "_rule";
+ static final String RULES = "_rules";
+ static final String DATA = "_data";
+ static final String ROOTS = "_root";
SimpleJsonFormat({this.storeRoundTripInfo : false});
/**
- * Generate output for this format from [w] and return it as a String which
- * is the [json] representation of a nested Map structure.
+ * Generate output for this format from [w] and return it as
+ * the [json] representation of a nested Map structure.
*/
- String generateOutput(Writer w) {
+ generateOutput(Writer w) {
jsonify(w);
- return json.stringify(w.stateForReference(w._rootReferences().first));
+ var root = w._rootReferences().first;
+ if (root is Reference) root = w.stateForReference(root);
+ if (w.selfDescribing && storeRoundTripInfo) {
+ root = new Map()
+ ..[RULES] = w.serializedRules()
+ ..[DATA] = root;
+ }
+ return root;
}
/**
@@ -134,7 +144,7 @@ class SimpleJsonFormat extends Format {
if (storeRoundTripInfo) ruleData[i].add(rule.number);
} else if (each is Map) {
jsonifyEntry(each, w);
- if (storeRoundTripInfo) each[ruleIdentifier] = rule.number;
+ if (storeRoundTripInfo) each[RULE] = rule.number;
}
}
}
@@ -150,19 +160,29 @@ class SimpleJsonFormat extends Format {
}
/**
- * Read a [json] encoded string representing serialized data in this format
- * and return the Map representation that the reader expects, with top-level
+ * Read serialized data saved in this format, which should look like
+ * either a simple type, a List or a Map and return the Map
+ * representation that the reader expects, with top-level
* entries for "rules", "data", and "roots". Nested lists/maps will be
* converted into Reference objects. Note that if the data was not written
* with [storeRoundTripInfo] true this will fail.
*/
- Map<String, dynamic> read(String input, Reader r) {
- var data = json.parse(input);
- var result = {};
- result["rules"] = null;
- var ruleData =
- new List(r.serialization.rules.length).map((x) => []).toList();
- var top = recursivelyFixUp(data, r, ruleData);
+ Map<String, dynamic> read(data, Reader reader) {
+ var result = new Map();
+ // Check the case of having been written without additional data and
+ // read as if it had been written with storeRoundTripData set.
+ if (reader.selfDescribing && !(data.containsKey(DATA))) {
+ throw new SerializationException("Missing $DATA entry, "
+ "may mean this was written and read with different values "
+ "of selfDescribing.");
+ }
+ // If we are self-describing, we should have separate rule and data
+ // sections. If not, we assume that we have just the data at the top level.
+ var rules = reader.selfDescribing ? data[RULES] : null;
+ var actualData = reader.selfDescribing ? data[DATA] : data;
+ reader.readRules(rules);
+ var ruleData = new List(reader.rules.length).map((x) => []).toList();
+ var top = recursivelyFixUp(actualData, reader, ruleData);
result["data"] = ruleData;
result["roots"] = [top];
return result;
@@ -171,20 +191,28 @@ class SimpleJsonFormat extends Format {
/**
* Convert nested references in [data] into [Reference] objects.
*/
- recursivelyFixUp(data, Reader r, List result) {
+ recursivelyFixUp(input, Reader r, List result) {
+ var data = input;
if (isPrimitive(data)) {
result[r._primitiveRule().number].add(data);
return data;
}
var ruleNumber;
+ // If we've added the rule number on as the last item in a list we have
+ // to get rid of it or it will be interpreted as extra data. For a map
+ // the library will be ok, but we need to get rid of the extra key before
+ // the data is shown to the user, so we destructively modify.
if (data is List) {
- ruleNumber = data.removeLast();
+ ruleNumber = data.last;
+ data = data.take(data.length -1);
} else if (data is Map) {
- ruleNumber = data.remove(ruleIdentifier);
+ ruleNumber = data.remove(RULE);
} else {
throw new SerializationException("Invalid data format");
}
- var newData = mapValues(data, (x) => recursivelyFixUp(x, r, result));
+ // Do not use mappedBy or other lazy operations for this. They do not play
+ // well with a function that destructively modifies its arguments.
+ var newData = mapValues(data, (each) => recursivelyFixUp(each, r, result));
result[ruleNumber].add(newData);
return new Reference(r, ruleNumber, result[ruleNumber].length - 1);
}
« no previous file with comments | « pkg/serialization/lib/src/basic_rule.dart ('k') | pkg/serialization/lib/src/reader_writer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698