blob: df29f580d33f6ba05c38f56fbb0fbdce16921839 [file] [log] [blame]
// 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";
}
}