| // 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. |
| |
| // Patch file for the dart:isolate library. |
| |
| part of html; |
| |
| /******************************************************** |
| Inserted from lib/isolate/serialization.dart |
| ********************************************************/ |
| |
| class _MessageTraverserVisitedMap { |
| |
| operator[](var object) => null; |
| void operator[]=(var object, var info) { } |
| |
| void reset() { } |
| void cleanup() { } |
| |
| } |
| |
| /** Abstract visitor for dart objects that can be sent as isolate messages. */ |
| abstract class _MessageTraverser { |
| |
| _MessageTraverserVisitedMap _visited; |
| _MessageTraverser() : _visited = new _MessageTraverserVisitedMap(); |
| |
| /** Visitor's entry point. */ |
| traverse(var x) { |
| if (isPrimitive(x)) return visitPrimitive(x); |
| _visited.reset(); |
| var result; |
| try { |
| result = _dispatch(x); |
| } finally { |
| _visited.cleanup(); |
| } |
| return result; |
| } |
| |
| _dispatch(var x) { |
| if (isPrimitive(x)) return visitPrimitive(x); |
| if (x is List) return visitList(x); |
| if (x is Map) return visitMap(x); |
| if (x is SendPort) return visitSendPort(x); |
| if (x is SendPortSync) return visitSendPortSync(x); |
| |
| // Overridable fallback. |
| return visitObject(x); |
| } |
| |
| visitPrimitive(x); |
| visitList(List x); |
| visitMap(Map x); |
| visitSendPort(SendPort x); |
| visitSendPortSync(SendPortSync x); |
| |
| visitObject(Object x) { |
| // TODO(floitsch): make this a real exception. (which one)? |
| throw "Message serialization: Illegal value $x passed"; |
| } |
| |
| static bool isPrimitive(x) { |
| return (x == null) || (x is String) || (x is num) || (x is bool); |
| } |
| } |
| |
| |
| /** Visitor that serializes a message as a JSON array. */ |
| abstract class _Serializer extends _MessageTraverser { |
| int _nextFreeRefId = 0; |
| |
| visitPrimitive(x) => x; |
| |
| visitList(List list) { |
| int copyId = _visited[list]; |
| if (copyId != null) return ['ref', copyId]; |
| |
| int id = _nextFreeRefId++; |
| _visited[list] = id; |
| var jsArray = _serializeList(list); |
| // TODO(floitsch): we are losing the generic type. |
| return ['list', id, jsArray]; |
| } |
| |
| visitMap(Map map) { |
| int copyId = _visited[map]; |
| if (copyId != null) return ['ref', copyId]; |
| |
| int id = _nextFreeRefId++; |
| _visited[map] = id; |
| var keys = _serializeList(map.keys.toList()); |
| var values = _serializeList(map.values.toList()); |
| // TODO(floitsch): we are losing the generic type. |
| return ['map', id, keys, values]; |
| } |
| |
| _serializeList(List list) { |
| int len = list.length; |
| var result = new List(len); |
| for (int i = 0; i < len; i++) { |
| result[i] = _dispatch(list[i]); |
| } |
| return result; |
| } |
| } |
| |
| /** Deserializes arrays created with [_Serializer]. */ |
| abstract class _Deserializer { |
| Map<int, dynamic> _deserialized; |
| |
| _Deserializer(); |
| |
| static bool isPrimitive(x) { |
| return (x == null) || (x is String) || (x is num) || (x is bool); |
| } |
| |
| deserialize(x) { |
| if (isPrimitive(x)) return x; |
| // TODO(floitsch): this should be new HashMap<int, dynamic>() |
| _deserialized = new HashMap(); |
| return _deserializeHelper(x); |
| } |
| |
| _deserializeHelper(x) { |
| if (isPrimitive(x)) return x; |
| assert(x is List); |
| switch (x[0]) { |
| case 'ref': return _deserializeRef(x); |
| case 'list': return _deserializeList(x); |
| case 'map': return _deserializeMap(x); |
| case 'sendport': return deserializeSendPort(x); |
| default: return deserializeObject(x); |
| } |
| } |
| |
| _deserializeRef(List x) { |
| int id = x[1]; |
| var result = _deserialized[id]; |
| assert(result != null); |
| return result; |
| } |
| |
| List _deserializeList(List x) { |
| int id = x[1]; |
| // We rely on the fact that Dart-lists are directly mapped to Js-arrays. |
| List dartList = x[2]; |
| _deserialized[id] = dartList; |
| int len = dartList.length; |
| for (int i = 0; i < len; i++) { |
| dartList[i] = _deserializeHelper(dartList[i]); |
| } |
| return dartList; |
| } |
| |
| Map _deserializeMap(List x) { |
| Map result = new Map(); |
| int id = x[1]; |
| _deserialized[id] = result; |
| List keys = x[2]; |
| List values = x[3]; |
| int len = keys.length; |
| assert(len == values.length); |
| for (int i = 0; i < len; i++) { |
| var key = _deserializeHelper(keys[i]); |
| var value = _deserializeHelper(values[i]); |
| result[key] = value; |
| } |
| return result; |
| } |
| |
| deserializeSendPort(List x); |
| |
| deserializeObject(List x) { |
| // TODO(floitsch): Use real exception (which one?). |
| throw "Unexpected serialized object"; |
| } |
| } |
| |