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

Side by Side Diff: pkg/serialization/lib/src/serialization_rule.dart

Issue 11783009: Big merge from experimental to bleeding edge. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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
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 serialization; 5 part of serialization;
6 6
7 // TODO(alanknight): We should have an example and tests for subclassing 7 // TODO(alanknight): We should have an example and tests for subclassing
8 // serialization rule rather than using the hard-coded ClosureToMap rule. And 8 // serialization rule rather than using the hard-coded ClosureToMap rule. And
9 // possibly an abstract superclass that's designed to be subclassed that way. 9 // possibly an abstract superclass that's designed to be subclassed that way.
10 /** 10 /**
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 * the flat format. Return false if the results are fixed length. 143 * the flat format. Return false if the results are fixed length.
144 */ 144 */
145 // TODO(alanknight): This should probably go away with more general formats. 145 // TODO(alanknight): This should probably go away with more general formats.
146 bool get writeLengthInFlatFormat => false; 146 bool get writeLengthInFlatFormat => false;
147 147
148 /** 148 /**
149 * The inverse of dumpStateInto, this reads the rule's state from an 149 * The inverse of dumpStateInto, this reads the rule's state from an
150 * iterator in a flat format. 150 * iterator in a flat format.
151 */ 151 */
152 pullStateFrom(Iterator stream) { 152 pullStateFrom(Iterator stream) {
153 var numberOfEntries = stream.next(); 153 stream.moveNext();
154 var numberOfEntries = stream.current;
154 var ruleData = new List(); 155 var ruleData = new List();
155 for (var i = 0; i < numberOfEntries; i++) { 156 for (var i = 0; i < numberOfEntries; i++) {
156 var subLength = dataLengthIn(stream); 157 var subLength = dataLengthIn(stream);
157 var subList = []; 158 var subList = [];
158 ruleData.add(subList); 159 ruleData.add(subList);
159 for (var j = 0; j < subLength; j++) { 160 for (var j = 0; j < subLength; j++) {
160 var a = stream.next(); 161 stream.moveNext();
161 var b = stream.next(); 162 var a = stream.current;
162 if (!(a is int)) { 163 stream.moveNext();
164 var b = stream.current;
165 if (a is! int) {
163 // This wasn't a reference, just use the first object as a literal. 166 // This wasn't a reference, just use the first object as a literal.
164 // particularly used for the case of null. 167 // particularly used for the case of null.
165 subList.add(a); 168 subList.add(a);
166 } else { 169 } else {
167 subList.add(new Reference(this, a, b)); 170 subList.add(new Reference(this, a, b));
168 } 171 }
169 } 172 }
170 } 173 }
171 return ruleData; 174 return ruleData;
172 } 175 }
173 176
174 /** 177 /**
175 * Return the length of the list of data we expect to see on a particular 178 * Return the length of the list of data we expect to see on a particular
176 * iterator in a flat format. This may have been encoded in the stream if we 179 * iterator in a flat format. This may have been encoded in the stream if we
177 * are variable length, or it may be constant. Note that this is expressed in 180 * are variable length, or it may be constant. Returns null if the [Iterator]
178 * 181 * is empty.
179 */ 182 */
180 dataLengthIn(Iterator stream) => 183 dataLengthIn(Iterator stream) =>
181 writeLengthInFlatFormat ? stream.next() : dataLength; 184 writeLengthInFlatFormat ? (stream..moveNext()).current : dataLength;
182 185
183 /** 186 /**
184 * If the data is fixed length, return it here. Unused in the non-flat 187 * If the data is fixed length, return it here. Unused in the non-flat
185 * format, or if the data is variable length. 188 * format, or if the data is variable length.
186 */ 189 */
187 int get dataLength => 0; 190 int get dataLength => 0;
188 } 191 }
189 192
190 /** 193 /**
191 * This rule handles things that implement List. It will recreate them as 194 * This rule handles things that implement List. It will recreate them as
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 * When reading from a flat format we are given [stream] and need to pull as 227 * When reading from a flat format we are given [stream] and need to pull as
225 * much data from it as we need. Our format is that we have an integer N 228 * much data from it as we need. Our format is that we have an integer N
226 * indicating the number of objects and then for each object a length M, 229 * indicating the number of objects and then for each object a length M,
227 * and then M references, where a reference is stored in the stream as two 230 * and then M references, where a reference is stored in the stream as two
228 * integers. Or, in the special case of null, two nulls. 231 * integers. Or, in the special case of null, two nulls.
229 */ 232 */
230 pullStateFrom(Iterator stream) { 233 pullStateFrom(Iterator stream) {
231 // TODO(alanknight): This is much too close to the basicRule implementation, 234 // TODO(alanknight): This is much too close to the basicRule implementation,
232 // and I'd refactor them if I didn't think this whole mechanism needed to 235 // and I'd refactor them if I didn't think this whole mechanism needed to
233 // change soon. 236 // change soon.
234 var length = stream.next(); 237 stream.moveNext();
238 var length = stream.current;
235 var ruleData = new List(); 239 var ruleData = new List();
236 for (var i = 0; i < length; i++) { 240 for (var i = 0; i < length; i++) {
237 var subLength = stream.next(); 241 stream.moveNext();
242 var subLength = stream.current;
238 var subList = new List(); 243 var subList = new List();
239 ruleData.add(subList); 244 ruleData.add(subList);
240 for (var j = 0; j < subLength; j++) { 245 for (var j = 0; j < subLength; j++) {
241 var a = stream.next(); 246 stream.moveNext();
242 var b = stream.next(); 247 var a = stream.current;
248 stream.moveNext();
249 var b = stream.current;
243 if (!(a is int)) { 250 if (!(a is int)) {
244 // This wasn't a reference, just use the first object as a literal. 251 // This wasn't a reference, just use the first object as a literal.
245 // particularly used for the case of null. 252 // particularly used for the case of null.
246 subList.add(a); 253 subList.add(a);
247 } else { 254 } else {
248 subList.add(new Reference(this, a, b)); 255 subList.add(new Reference(this, a, b));
249 } 256 }
250 } 257 }
251 } 258 }
252 return ruleData; 259 return ruleData;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 void dumpStateInto(List ruleData, List target) { 320 void dumpStateInto(List ruleData, List target) {
314 target.addAll(ruleData); 321 target.addAll(ruleData);
315 } 322 }
316 323
317 /** 324 /**
318 * When reading from a flat format we are given [stream] and need to pull as 325 * When reading from a flat format we are given [stream] and need to pull as
319 * much data from it as we need. Our format is that we have an integer N 326 * much data from it as we need. Our format is that we have an integer N
320 * indicating the number of objects and then N simple objects. 327 * indicating the number of objects and then N simple objects.
321 */ 328 */
322 pullStateFrom(Iterator stream) { 329 pullStateFrom(Iterator stream) {
323 var length = stream.next(); 330 stream.moveNext();
331 var length = stream.current;
324 var ruleData = new List(); 332 var ruleData = new List();
325 for (var i = 0; i < length; i++) { 333 for (var i = 0; i < length; i++) {
326 ruleData.add(stream.next()); 334 stream.moveNext();
335 ruleData.add(stream.current);
327 } 336 }
328 return ruleData; 337 return ruleData;
329 } 338 }
330 } 339 }
331 340
332 /** Typedef for the object construction closure used in ClosureRule. */ 341 /** Typedef for the object construction closure used in ClosureRule. */
333 typedef ConstructType(Map m); 342 typedef ConstructType(Map m);
334 343
335 /** Typedef for the state-getting closure used in ClosureToMapRule. */ 344 /** Typedef for the state-getting closure used in ClosureToMapRule. */
336 typedef Map<String, dynamic> GetStateType(object); 345 typedef Map<String, dynamic> GetStateType(object);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 setState(object, _lazy(state, r)); 489 setState(object, _lazy(state, r));
481 490
482 // We don't want to have to make the end user tell us how long the list is 491 // We don't want to have to make the end user tell us how long the list is
483 // separately, so write it out for each object, even though they're all 492 // separately, so write it out for each object, even though they're all
484 // expected to be the same length. 493 // expected to be the same length.
485 get writeLengthInFlatFormat => true; 494 get writeLengthInFlatFormat => true;
486 } 495 }
487 496
488 /** Create a lazy list/map that will inflate its items on demand in [r]. */ 497 /** Create a lazy list/map that will inflate its items on demand in [r]. */
489 _lazy(l, Reader r) { 498 _lazy(l, Reader r) {
490 if (l is List) return new _LazyList(l, r); 499 if (l is List) return l.mappedBy(r.inflateReference);
491 if (l is Map) return new _LazyMap(l, r); 500 if (l is Map) return new _LazyMap(l, r);
492 throw new SerializationException("Invalid type: must be Map or List - $l"); 501 throw new SerializationException("Invalid type: must be Map or List - $l");
493 } 502 }
494 503
495 /** 504 /**
496 * This provides an implementation of Map that wraps a list which may 505 * This provides an implementation of Map that wraps a list which may
497 * contain references to (potentially) non-inflated objects. If these 506 * contain references to (potentially) non-inflated objects. If these
498 * are accessed it will inflate them. This allows us to pass something that 507 * are accessed it will inflate them. This allows us to pass something that
499 * looks like it's just a list of objects to a [CustomRule] without needing 508 * looks like it's just a list of objects to a [CustomRule] without needing
500 * to inflate all the references in advance. 509 * to inflate all the references in advance.
501 */ 510 */
502 class _LazyMap implements Map { 511 class _LazyMap implements Map {
503 _LazyMap(this._raw, this._reader); 512 _LazyMap(this._raw, this._reader);
504 513
505 Map _raw; 514 Map _raw;
506 Reader _reader; 515 Reader _reader;
507 516
508 // This is the only operation that really matters. 517 // This is the only operation that really matters.
509 operator [](x) => _reader.inflateReference(_raw[x]); 518 operator [](x) => _reader.inflateReference(_raw[x]);
510 519
511 int get length => _raw.length; 520 int get length => _raw.length;
512 bool get isEmpty => _raw.isEmpty; 521 bool get isEmpty => _raw.isEmpty;
513 List get keys => _raw.keys; 522 Iterable get keys => _raw.keys;
514 bool containsKey(x) => _raw.containsKey(x); 523 bool containsKey(x) => _raw.containsKey(x);
515 524
516 // These operations will work, but may be expensive, and are probably 525 // These operations will work, but may be expensive, and are probably
517 // best avoided. 526 // best avoided.
518 get _inflated => keysAndValues(_raw).map(_reader.inflateReference); 527 get _inflated => keysAndValues(_raw).map(_reader.inflateReference);
519 bool containsValue(x) => _inflated.containsValue(x); 528 bool containsValue(x) => _inflated.containsValue(x);
520 List get values => _inflated.values; 529 Iterable get values => _inflated.values;
521 void forEach(f) => _inflated.forEach(f); 530 void forEach(f) => _inflated.forEach(f);
522 531
523 // These operations are all invalid 532 // These operations are all invalid
524 _throw() => throw new UnsupportedError("Not modifiable"); 533 _throw() => throw new UnsupportedError("Not modifiable");
525 operator []=(x, y) => _throw(); 534 operator []=(x, y) => _throw();
526 putIfAbsent(x, y) => _throw(); 535 putIfAbsent(x, y) => _throw();
527 remove(x) => _throw(); 536 remove(x) => _throw();
528 clear() => _throw(); 537 clear() => _throw();
529 } 538 }
530
531 /**
532 * This provides an implementation of List that wraps a list which may
533 * contain references to (potentially) non-inflated objects. If these
534 * are accessed it will inflate them. This allows us to pass something that
535 * looks like it's just a list of objects to a [CustomRule] without needing
536 * to inflate all the references in advance.
537 */
538 class _LazyList implements List {
539 _LazyList(this._raw, this._reader);
540
541 List _raw;
542 Reader _reader;
543
544 // This is the only operation that really matters.
545 operator [](x) => _reader.inflateReference(_raw[x]);
546
547 int get length => _raw.length;
548 bool get isEmpty => _raw.isEmpty;
549 get first => _reader.inflateReference(_raw.first);
550 get last => _reader.inflateReference(_raw.last);
551
552 // These operations will work, but may be expensive, and are probably
553 // best avoided.
554 get _inflated => _raw.map(_reader.inflateReference);
555 map(f) => _inflated.map(f);
556 filter(f) => _inflated.filter(f);
557 bool contains(element) => _inflated.filter(element);
558 forEach(f) => _inflated.forEach(f);
559 reduce(x, f) => _inflated.reduce(x, f);
560 every(f) => _inflated(f);
561 some(f) => _inflated(f);
562 iterator() => _inflated.iterator();
563 indexOf(x, [pos = 0]) => _inflated.indexOf(x);
564 lastIndexOf(x, [pos]) => _inflated.lastIndexOf(x);
565
566 // These operations are all invalid
567 _throw() => throw new UnsupportedError("Not modifiable");
568 operator []=(x, y) => _throw();
569 add(x) => _throw();
570 addLast(x) => _throw();
571 addAll(x) => _throw();
572 sort([f]) => _throw();
573 clear() => _throw();
574 removeAt(x) => _throw();
575 removeLast() => _throw();
576 getRange(x, y) => _throw();
577 setRange(x, y, z, [a]) => _throw();
578 removeRange(x, y) => _throw();
579 insertRange(x, y, [z]) => _throw();
580 void set length(x) => _throw();
581 }
OLDNEW
« no previous file with comments | « pkg/serialization/lib/src/serialization_helpers.dart ('k') | pkg/serialization/test/serialization_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698