Chromium Code Reviews| Index: pkg/serialization/lib/src/format.dart |
| diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart |
| index 4ab20d43f5343f9d4800f4d560cee1ac2a9b5ab5..357c8c1f30680dcde5d58636bfd5d9de86aefac1 100644 |
| --- a/pkg/serialization/lib/src/format.dart |
| +++ b/pkg/serialization/lib/src/format.dart |
| @@ -157,7 +157,7 @@ class SimpleJsonFormat extends Format { |
| result["rules"] = null; |
| var ruleData = |
| new List(r.serialization.rules.length).mappedBy((x) => []).toList(); |
| - var rootRule = data["__rule"]; |
| + var rootRule = (data is Map) ? data["__rule"] : data.last; |
|
Jennifer Messerly
2013/01/25 01:19:59
hmmm. Do we know for sure "data" is an Iterable or
Alan Knight
2013/01/26 01:33:38
Done.
|
| var top = recursivelyFixUp(data, r, ruleData); |
| result["data"] = ruleData; |
| result["roots"] = [top]; |
| @@ -176,8 +176,12 @@ class SimpleJsonFormat extends Format { |
| (data is List) ? data.removeLast() : data.remove("__rule"); |
| var newData = values(data).mappedBy( |
| (x) => recursivelyFixUp(x, r, result)); |
| + // TODO(alanknight): Ugh. Get rid of this if we can resolve bug 7982/7940. |
|
Jennifer Messerly
2013/01/25 01:19:59
or http://dartbug.com/8113 :)
|
| + if (newData is MappedList) { |
| + newData = newData.toList(); |
| + } |
| result[ruleNumber].add(newData); |
| - return new Reference(this, ruleNumber, result[ruleNumber].length - 1); |
| + return new Reference(r, ruleNumber, result[ruleNumber].length - 1); |
| } |
| } |
| @@ -225,12 +229,14 @@ class SimpleFlatFormat extends Format { |
| void writeStateInto(SerializationRule rule, List ruleData, List target) { |
| if (!ruleData.isEmpty) { |
| var sample = ruleData.first; |
| - if (sample is List) { |
| + if (rule.storesStateAsLists || sample is List) { |
| writeLists(rule, ruleData, target); |
| - } else if (sample is Map) { |
| + } else if (rule.storesStateAsMaps || sample is Map) { |
| writeMaps(rule, ruleData, target); |
| - } else { |
| + } else if (rule.storesStateAsPrimitives || isPrimitive(sample)) { |
| writeObjects(ruleData, target); |
| + } else { |
| + throw new SerializationException("Invalid data format"); |
| } |
| } else { |
| // If there is no data, write a zero for the length. |
| @@ -271,13 +277,8 @@ class SimpleFlatFormat extends Format { |
| if (rule.hasVariableLengthEntries) { |
| target.add(eachEntry.length); |
| } |
| - // We take advantage of this being only a semi-flat format, and expecting |
| - // that the keys here are field names, i.e. strings. So we write |
| - // the keys as literals and the values as references. This duplicates the |
| - // keys, so is quite inefficient. But generating maps rather than lists is |
| - // not very efficient in the first place. |
| eachEntry.forEach((key, value) { |
| - target.add(key); |
| + writeReference(key, target); |
| writeReference(value, target); |
| }); |
| } |
| @@ -289,6 +290,9 @@ class SimpleFlatFormat extends Format { |
| */ |
| writeObjects(List entries, List target) { |
| target.add(STORED_AS_PRIMITIVE); |
| + for (var each in entries) { |
| + if (!isPrimitive(each)) throw new SerializationException("Invalid data"); |
| + } |
| target.addAll(entries); |
| } |
| @@ -312,6 +316,9 @@ class SimpleFlatFormat extends Format { |
| * format. |
| */ |
| Map<String, dynamic> read(List rawInput, Reader r) { |
| + // TODO(alanknight): It's annoying to have to pass the reader around so |
| + // much, consider having the format be specific to a particular |
| + // serialization operation along with the reader and having it as a field. |
|
Jennifer Messerly
2013/01/25 01:19:59
yeah, it is kind of nice how Format is independent
Alan Knight
2013/01/26 01:33:38
For the moment I'll go with not worrying about it.
|
| var input = {}; |
| input["rules"] = rawInput[0]; |
| r.readRules(input["rules"]); |
| @@ -320,14 +327,14 @@ class SimpleFlatFormat extends Format { |
| var stream = flatData.iterator; |
| var tempData = new List(r.rules.length); |
| for (var eachRule in r.rules) { |
| - tempData[eachRule.number] = readRuleDataFrom(stream, eachRule); |
| + tempData[eachRule.number] = readRuleDataFrom(stream, eachRule, r); |
| } |
| input["data"] = tempData; |
| var roots = []; |
| var rootsAsInts = rawInput[2].iterator; |
| do { |
| - roots.add(nextReferenceFrom(rootsAsInts)); |
| + roots.add(nextReferenceFrom(rootsAsInts, r)); |
| } while (rootsAsInts.current != null); |
| input["roots"] = roots; |
| @@ -337,14 +344,14 @@ class SimpleFlatFormat extends Format { |
| /** |
| * Read the data for [rule] from [input] and return it. |
| */ |
| - readRuleDataFrom(Iterator input, SerializationRule rule) { |
| + readRuleDataFrom(Iterator input, SerializationRule rule, Reader r) { |
| var numberOfEntries = _next(input); |
| var entryType = _next(input); |
| if (entryType == STORED_AS_LIST) { |
| - return readLists(input, rule, numberOfEntries); |
| + return readLists(input, rule, numberOfEntries, r); |
| } |
| if (entryType == STORED_AS_MAP) { |
| - return readMaps(input, rule, numberOfEntries); |
| + return readMaps(input, rule, numberOfEntries, r); |
| } |
| if (entryType == STORED_AS_PRIMITIVE) { |
| return readPrimitives(input, rule, numberOfEntries); |
| @@ -360,7 +367,7 @@ class SimpleFlatFormat extends Format { |
| * Read data for [rule] from [input] with [length] number of entries, |
| * creating lists from the results. |
| */ |
| - readLists(Iterator input, SerializationRule rule, int length) { |
| + readLists(Iterator input, SerializationRule rule, int length, Reader r) { |
| var ruleData = []; |
| for (var i = 0; i < length; i++) { |
| var subLength = |
| @@ -368,7 +375,7 @@ class SimpleFlatFormat extends Format { |
| var subList = []; |
| ruleData.add(subList); |
| for (var j = 0; j < subLength; j++) { |
| - subList.add(nextReferenceFrom(input)); |
| + subList.add(nextReferenceFrom(input, r)); |
| } |
| } |
| return ruleData; |
| @@ -378,15 +385,17 @@ class SimpleFlatFormat extends Format { |
| * Read data for [rule] from [input] with [length] number of entries, |
| * creating maps from the results. |
| */ |
| - readMaps(Iterator input, SerializationRule rule, int length) { |
| + readMaps(Iterator input, SerializationRule rule, int length, Reader r) { |
| var ruleData = []; |
| for (var i = 0; i < length; i++) { |
| var subLength = |
| rule.hasVariableLengthEntries ? _next(input) : rule.dataLength; |
| - var map = {}; |
| + var map = new Map(); |
| ruleData.add(map); |
| for (var j = 0; j < subLength; j++) { |
| - map[_next(input)] = nextReferenceFrom(input); |
| + var key = nextReferenceFrom(input, r); |
| + var value = nextReferenceFrom(input, r); |
| + map[key] = value; |
| } |
| } |
| return ruleData; |
| @@ -405,13 +414,13 @@ class SimpleFlatFormat extends Format { |
| } |
| /** Read the next Reference from the input. */ |
| - nextReferenceFrom(Iterator input) { |
| + nextReferenceFrom(Iterator input, Reader r) { |
| var a = _next(input); |
| var b = _next(input); |
| if (a == null) { |
| return null; |
| } else { |
| - return new Reference(this, a, b); |
| + return new Reference(r, a, b); |
| } |
| } |