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

Unified Diff: mojo/public/dart/src/codec.dart

Issue 703273002: Update mojo sdk to rev 04a510fb37db10642e156957f9b2c11c2f6442ac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix content/child -> mojo/common linking Created 6 years, 1 month 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 | « mojo/public/dart/bindings.dart ('k') | mojo/public/js/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/dart/src/codec.dart
diff --git a/mojo/public/dart/src/codec.dart b/mojo/public/dart/src/codec.dart
new file mode 100644
index 0000000000000000000000000000000000000000..003fcc1d26aeedb3f3ac8b6fa8460ef814c03c30
--- /dev/null
+++ b/mojo/public/dart/src/codec.dart
@@ -0,0 +1,745 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+part of bindings;
+
+const int kAlignment = 8;
+const int kArrayHeaderSize = 8;
+const int kStructHeaderSize = 8;
+const int kMessageHeaderSize = 16;
+const int kMessageWithRequestIDHeaderSize = 24;
+const int kMapStructPayloadSize = 16;
+const int kStructHeaderNumBytesOffset = 0;
+const int kStructHeaderNumFieldsOffset = 4;
+const int kEncodedInvalidHandleValue = 0xffffffff;
+const String kErrorUnsigned = "Passing negative value to unsigned encoder";
+
+
+int align(int size) => size + (kAlignment - (size % kAlignment)) % kAlignment;
+bool isAligned(offset) => (offset >= 0) && ((offset % kAlignment) == 0);
+
+
+Uint8List utf8OfString(String s) =>
+ (new Uint8List.fromList((const Utf8Encoder()).convert(s)));
+
+
+String stringOfUtf8(Uint8List bytes) =>
+ (const Utf8Decoder()).convert(bytes.toList());
+
+
+// Given an argument that is either a Type or an instance:
+// Invoke the static method "decode" of the Type, or the instance method
+// "decode" of the instance, on the MojoDecoder.
+Object _callDecode(Object typeOrInstance, MojoDecoder decoder) {
+ if (typeOrInstance is Type) {
+ return reflectClass(typeOrInstance).invoke(#decode, [decoder]).reflectee;
+ } else {
+ return typeOrInstance.decode(decoder);
+ }
+}
+
+
+// Given an argument that is either a Type or an instance:
+// Invoke the static method "encode" of the Type, or the instance method
+// "encode" of the instance, on the MojoEncoder and value to be encoded.
+void _callEncode(Object typeOrInstance, MojoEncoder encoder, Object val) {
+ if (typeOrInstance is Type) {
+ reflectClass(typeOrInstance).invoke(#encode, [encoder, val]);
+ } else {
+ typeOrInstance.encode(encoder, val);
+ }
+}
+
+
+// Given an argument that is either a Type or an instance:
+// Invoke the static getter "encodedSize" of the Type, or the instance getter
+// "encodedSize" of the instance, and return the result.
+int getEncodedSize(Object typeOrInstance) {
+ if (typeOrInstance is Type) {
+ return reflectClass(typeOrInstance).getField(#encodedSize).reflectee;
+ } else {
+ return typeOrInstance.encodedSize;
+ }
+}
+
+
+class MojoDecoder {
+ ByteData buffer;
+ List<int> handles;
+ int base;
+ int next;
+
+ MojoDecoder(this.buffer, this.handles, this.base) {
+ next = base;
+ }
+
+ void skip(int offset) {
+ next += offset;
+ }
+
+ int readInt8() {
+ int result = buffer.getInt8(next);
+ next += 1;
+ return result;
+ }
+
+ int readUint8() {
+ int result = buffer.getUint8(next);
+ next += 1;
+ return result;
+ }
+
+ int readInt16() {
+ int result = buffer.getInt16(next, Endianness.LITTLE_ENDIAN);
+ next += 2;
+ return result;
+ }
+
+ int readUint16() {
+ int result = buffer.getUint16(next, Endianness.LITTLE_ENDIAN);
+ next += 2;
+ return result;
+ }
+
+ int readInt32() {
+ int result = buffer.getInt32(next, Endianness.LITTLE_ENDIAN);
+ next += 4;
+ return result;
+ }
+
+ int readUint32() {
+ int result = buffer.getUint32(next, Endianness.LITTLE_ENDIAN);
+ next += 4;
+ return result;
+ }
+
+ int readInt64() {
+ int result = buffer.getInt64(next, Endianness.LITTLE_ENDIAN);
+ next += 8;
+ return result;
+ }
+
+ int readUint64() {
+ int result = buffer.getUint64(next, Endianness.LITTLE_ENDIAN);
+ next += 8;
+ return result;
+ }
+
+ double readFloat() {
+ double result = buffer.getFloat32(next,Endianness.LITTLE_ENDIAN);
+ next += 4;
+ return result;
+ }
+
+ double readDouble() {
+ double result = buffer.getFloat64(next, Endianness.LITTLE_ENDIAN);
+ next += 8;
+ return result;
+ }
+
+ int decodePointer() {
+ int offsetPointer = next;
+ int offset = readUint64();
+ if (offset == 0) {
+ return 0;
+ }
+ return offsetPointer + offset;
+ }
+
+ MojoDecoder decodeAndCreateDecoder(int offset) {
+ return new MojoDecoder(buffer, handles, offset);
+ }
+
+ int decodeHandle() {
+ return handles[readUint32()];
+ }
+
+ String decodeString() {
+ int numBytes = readUint32();
+ int numElements = readUint32();
+ int base = next;
+ next += numElements;
+ return stringOfUtf8(buffer.buffer.asUint8List(base, numElements));
+ }
+
+ List decodeArray(Object type) {
+ int numBytes = readUint32();
+ int numElements = readUint32();
+ if (type == PackedBool) {
+ int b;
+ List<bool> result = new List<bool>(numElements);
+ for (int i = 0; i < numElements; i++) {
+ if ((i % 8) == 0) {
+ b = readUint8();
+ }
+ result[i] = ((b & (1 << (i % 8)) != 0) ? true : false);
+ }
+ return result;
+ } else {
+ List result = new List(numElements);
+ for (int i = 0; i < numElements; i++) {
+ result[i] = _callDecode(type, this);
+ }
+ return result;
+ }
+ }
+
+ Object decodeStruct(Object t) {
+ return _callDecode(t, this);
+ }
+
+ Object decodeStructPointer(Object t) {
+ int pointer = decodePointer();
+ if (pointer == 0) {
+ return null;
+ }
+ return _callDecode(t, decodeAndCreateDecoder(pointer));
+ }
+
+ List decodeArrayPointer(Object type) {
+ int pointer = decodePointer();
+ if (pointer == 0) {
+ return null;
+ }
+ return decodeAndCreateDecoder(pointer).decodeArray(type);
+ }
+
+ String decodeStringPointer() {
+ int pointer = decodePointer();
+ if (pointer == 0) {
+ return null;
+ }
+ return decodeAndCreateDecoder(pointer).decodeString();
+ }
+
+ Map decodeMap(Object keyType, Object valType) {
+ skip(4); // number of bytes.
+ skip(4); // number of fields.
+ List keys = decodeArrayPointer(keyType);
+ List values = decodeArrayPointer(valType);
+ return new Map.fromIterables(keys, values);
+ }
+
+ Map decodeMapPointer(Object keyType, Object valType) {
+ int pointer = this.decodePointer();
+ if (pointer == 0) {
+ return null;
+ }
+ MojoDecoder decoder = decodeAndCreateDecoder(pointer);
+ return decoder.decodeMap(keyType, valType);
+ }
+}
+
+
+class MojoEncoder {
+ ByteData buffer;
+ List<int> handles;
+ int base;
+ int next;
+ int extent;
+
+ MojoEncoder(this.buffer, this.handles, this.base, this.extent) {
+ next = base;
+ }
+
+ void skip(int offset) {
+ next += offset;
+ }
+
+ void writeInt8(int val) {
+ buffer.setInt8(next, val);
+ next += 1;
+ }
+
+ void writeUint8(int val) {
+ if (val < 0) {
+ throw new ArgumentError("$kErrorUnsigned: $val");
+ }
+ buffer.setUint8(next, val);
+ next += 1;
+ }
+
+ void writeInt16(int val) {
+ buffer.setInt16(next, val, Endianness.LITTLE_ENDIAN);
+ next += 2;
+ }
+
+ void writeUint16(int val) {
+ if (val < 0) {
+ throw new ArgumentError("$kErrorUnsigned: $val");
+ }
+ buffer.setUint16(next, val, Endianness.LITTLE_ENDIAN);
+ next += 2;
+ }
+
+ void writeInt32(int val) {
+ buffer.setInt32(next, val, Endianness.LITTLE_ENDIAN);
+ next += 4;
+ }
+
+ void writeUint32(int val) {
+ if (val < 0) {
+ throw new ArgumentError("$kErrorUnsigned: $val");
+ }
+ buffer.setUint32(next, val, Endianness.LITTLE_ENDIAN);
+ next += 4;
+ }
+
+ void writeInt64(int val) {
+ buffer.setInt64(next, val, Endianness.LITTLE_ENDIAN);
+ next += 8;
+ }
+
+ void writeUint64(int val) {
+ if (val < 0) {
+ throw new ArgumentError("$kErrorUnsigned: $val");
+ }
+ buffer.setUint64(next, val, Endianness.LITTLE_ENDIAN);
+ next += 8;
+ }
+
+ void writeFloat(double val) {
+ buffer.setFloat32(next, val, Endianness.LITTLE_ENDIAN);
+ next += 4;
+ }
+
+ void writeDouble(double val) {
+ buffer.setFloat64(next, val, Endianness.LITTLE_ENDIAN);
+ next += 8;
+ }
+
+ void encodePointer(int pointer) {
+ if (pointer == null) {
+ writeUint64(0);
+ return;
+ }
+ int offset = pointer - next;
+ writeUint64(offset);
+ }
+
+ void grow(int new_size) {
+ Uint8List new_buffer = new Uint8List(new_size);
+ new_buffer.setRange(0, next, buffer.buffer.asUint8List());
+ buffer = new_buffer.buffer.asByteData();
+ }
+
+ int alloc(int size_request) {
+ int pointer = extent;
+ extent += size_request;
+ if (extent > buffer.lengthInBytes) {
+ int new_size = buffer.lengthInBytes + size_request;
+ new_size += new_size ~/ 2;
+ grow(new_size);
+ }
+ return pointer;
+ }
+
+ MojoEncoder createAndEncodeEncoder(int size) {
+ int pointer = alloc(align(size));
+ encodePointer(pointer);
+ return new MojoEncoder(buffer, handles, pointer, extent);
+ }
+
+ void encodeHandle(int handle) {
+ handles.add(handle);
+ writeUint32(handles.length - 1);
+ }
+
+ void encodeString(String val) {
+ Uint8List utf8string = utf8OfString(val);
+ int numElements = utf8string.lengthInBytes;
+ int numBytes = kArrayHeaderSize + numElements;
+ writeUint32(numBytes);
+ writeUint32(numElements);
+ buffer.buffer.asUint8List().setRange(next, next + numElements, utf8string);
+ next += numElements;
+ }
+
+ void encodeArray(Object t, List val, [int numElements, int encodedSize]) {
+ if (numElements == null) {
+ numElements = val.length;
+ }
+ if (encodedSize == null) {
+ encodedSize = kArrayHeaderSize + (getEncodedSize(t) * numElements);
+ }
+
+ writeUint32(encodedSize);
+ writeUint32(numElements);
+
+ if (t == PackedBool) {
+ int b = 0;
+ for (int i = 0; i < numElements; i++) {
+ if (val[i]) {
+ b |= (1 << (i % 8));
+ }
+ if (((i % 8) == 7) || (i == (numElements - 1))) {
+ Uint8.encode(this, b);
+ }
+ }
+ } else {
+ for (int i = 0; i < numElements; i++) {
+ _callEncode(t, this, val[i]);
+ }
+ }
+ }
+
+ void encodeStruct(Object t, Object val) {
+ _callEncode(t, this, val);
+ }
+
+ void encodeStructPointer(Object t, Object val) {
+ if (val == null) {
+ encodePointer(val);
+ return;
+ }
+ MojoEncoder encoder = createAndEncodeEncoder(getEncodedSize(t));
+ _callEncode(t, encoder, val);
+ extent = encoder.extent;
+ buffer = encoder.buffer;
+ }
+
+ void encodeArrayPointer(Object t, List val) {
+ if (val == null) {
+ encodePointer(val);
+ return;
+ }
+ int numElements = val.length;
+ int encodedSize = kArrayHeaderSize + ((t == PackedBool) ?
+ (numElements / 8).ceil() : (getEncodedSize(t) * numElements));
+ MojoEncoder encoder = createAndEncodeEncoder(encodedSize);
+ encoder.encodeArray(t, val, numElements, encodedSize);
+ extent = encoder.extent;
+ buffer = encoder.buffer;
+ }
+
+ void encodeStringPointer(String val) {
+ if (val == null) {
+ encodePointer(val);
+ return;
+ }
+ int encodedSize = kArrayHeaderSize + utf8OfString(val).lengthInBytes;
+ MojoEncoder encoder = createAndEncodeEncoder(encodedSize);
+ encoder.encodeString(val);
+ extent = encoder.extent;
+ buffer = encoder.buffer;
+ }
+
+ void encodeMap(Object keyType, Object valType, Map val) {
+ List keys = val.keys;
+ List vals = val.values;
+ writeUint32(kStructHeaderSize + kMapStructPayloadSize);
+ writeUint32(2);
+ encodeArrayPointer(keyType, keys);
+ encodeArrayPointer(valType, vals);
+ }
+
+ void encodeMapPointer(Object keyTYpe, Object valType, Map val) {
+ if (val == null) {
+ encodePointer(val);
+ return;
+ }
+ int encodedSize = kStructHeaderSize + kMapStructPayloadSize;
+ MojoEncoder encoder = createAndEncodeEncoder(encodedSize);
+ encoder.encodeMap(keyType, valType, val);
+ extent = encoder.extent;
+ buffer = encoder.buffer;
+ }
+}
+
+
+const int kMessageNameOffset = kStructHeaderSize;
+const int kMessageFlagsOffset = kMessageNameOffset + 4;
+const int kMessageRequestIDOffset = kMessageFlagsOffset + 4;
+const int kMessageExpectsResponse = 1 << 0;
+const int kMessageIsResponse = 1 << 1;
+
+class Message {
+ ByteData buffer;
+ List<int> handles;
+
+ Message(this.buffer, this.handles);
+
+ int getHeaderNumBytes() => buffer.getUint32(kStructHeaderNumBytesOffset);
+ int getHeaderNumFields() => buffer.getUint32(kStructHeaderNumFieldsOffset);
+ int getName() => buffer.getUint32(kMessageNameOffset);
+ int getFlags() => buffer.getUint32(kMessageFlagsOffset);
+ bool isResponse() => (getFlags() & kMessageIsResponse) != 0;
+ bool expectsResponse() => (getFlags() & kMessageExpectsResponse) != 0;
+
+ void setRequestID(int id) {
+ buffer.setUint64(kMessageRequestIDOffset, id);
+ }
+}
+
+
+class MessageBuilder {
+ MojoEncoder encoder;
+ List<int> handles;
+
+ MessageBuilder(int name, int payloadSize) {
+ int numBytes = kMessageHeaderSize + payloadSize;
+ var buffer = new ByteData(numBytes);
+ handles = [];
+
+ encoder = new MojoEncoder(buffer, handles, 0, kMessageHeaderSize);
+ encoder.writeUint32(kMessageHeaderSize);
+ encoder.writeUint32(2); // num_fields;
+ encoder.writeUint32(name);
+ encoder.writeUint32(0); // flags.
+ }
+
+ MojoEncoder createEncoder(int size) {
+ encoder = new MojoEncoder(encoder.buffer,
+ handles,
+ encoder.next,
+ encoder.next + size);
+ return encoder;
+ }
+
+ void encodeStruct(Object t, Object val) {
+ encoder = createEncoder(getEncodedSize(t));
+ _callEncode(t, encoder, val);
+ }
+
+ ByteData _trimBuffer() {
+ return new ByteData.view(encoder.buffer.buffer, 0, encoder.extent);
+ }
+
+ Message finish() {
+ Message message = new Message(_trimBuffer(), handles);
+ encoder = null;
+ handles = null;
+ return message;
+ }
+}
+
+
+class MessageWithRequestIDBuilder extends MessageBuilder {
+ MessageWithRequestIDBuilder(
+ int name, int payloadSize, int flags, int requestID) {
+ int numBytes = kMessageWithRequestIDHeaderSize + payloadSize;
+ buffer = new ByteData(numBytes);
+ handles = [];
+ base = 0;
+
+ encoder = createEncoder(0, kMessageWithRequestIDHeaderSize);
+ encoder.writeUint32(kMessageWithRequestIDHeaderSize);
+ encoder.writeUint32(3); // num_fields.
+ encoder.writeUint32(name);
+ encoder.writeUint32(flags);
+ encoder.writeUint64(requestID);
+ base = encoder.next;
+ buffer = encoder.buffer;
+ }
+}
+
+
+class MessageReader {
+ MojoDecoder decoder;
+ int payloadSize;
+ int name;
+ int flags;
+ int requestID;
+
+ MessageReader(Message message) {
+ decoder = new MojoDecoder(message.buffer, message.handles, 0);
+
+ int messageHeaderSize = decoder.readUint32();
+ payloadSize = message.buffer.lengthInBytes - messageHeaderSize;
+
+ int num_fields = decoder.readUint32();
+ name = decoder.readUint32();
+ flags = decoder.readUint32();
+
+ if (num_fields >= 3) {
+ requestID = decoder.readUint64();
+ }
+ decoder.skip(messageHeaderSize - decoder.next);
+ }
+
+ Object decodeStruct(Object t) => _callDecode(t, decoder);
+}
+
+
+abstract class MojoType<T> {
+ static const int encodedSize = 0;
+ static T decode(MojoDecoder decoder) { return null }
+ static void encode(MojoEncoder encoder, T val) {}
+}
+
+
+class PackedBool {}
+
+
+class Int8 implements MojoType<int> {
+ static const int encodedSize = 1;
+ static int decode(MojoDecoder decoder) => decoder.readInt8();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeInt8(val);
+ }
+}
+
+
+class Uint8 implements MojoType<int> {
+ static const int encodedSize = 1;
+ static int decode(MojoDecoder decoder) => decoder.readUint8();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeUint8(val);
+ }
+}
+
+
+class Int16 implements MojoType<int> {
+ static const int encodedSize = 2;
+ static int decode(MojoDecoder decoder) => decoder.readInt16();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeInt16(val);
+ }
+}
+
+
+class Uint16 implements MojoType<int> {
+ static const int encodedSize = 2;
+ static int decode(MojoDecoder decoder) => decoder.readUint16();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeUint16(val);
+ }
+}
+
+
+class Int32 implements MojoType<int> {
+ static const int encodedSize = 4;
+ static int decode(MojoDecoder decoder) => decoder.readInt32();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeInt32(val);
+ }
+}
+
+
+class Uint32 implements MojoType<int> {
+ static const int encodedSize = 4;
+ static int decode(MojoDecoder decoder) => decoder.readUint32();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeUint32(val);
+ }
+}
+
+
+class Int64 implements MojoType<int> {
+ static const int encodedSize = 8;
+ static int decode(MojoDecoder decoder) => decoder.readInt64();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeInt64(val);
+ }
+}
+
+
+class Uint64 implements MojoType<int> {
+ static const int encodedSize = 8;
+ static int decode(MojoDecoder decoder) => decoder.readUint64();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.writeUint64(val);
+ }
+}
+
+
+class MojoString implements MojoType<String> {
+ static const int encodedSize = 8;
+ static String decode(MojoDecoder decoder) => decoder.decodeStringPointer();
+ static void encode(MojoEncoder encoder, String val) {
+ encoder.encodeStringPointer(val);
+ }
+}
+
+
+class NullableMojoString implements MojoType<String> {
+ static const int encodedSize = MojoString.encodedSize;
+ static var decode = MojoString.decode;
+ static var encode = MojoString.encode;
+}
+
+
+class Float implements MojoType<double> {
+ static const int encodedSize = 4;
+ static double decode(MojoDecoder decoder) => decoder.readFloat();
+ static void encode(MojoEncoder encoder, double val) {
+ encoder.writeFloat(val);
+ }
+}
+
+
+class Double implements MojoType<double> {
+ static const int encodedSize = 8;
+ static double decode(MojoDecoder decoder) => decoder.readDouble();
+ static void encode(MojoEncoder encoder, double val) {
+ encoder.writeDouble(val);
+ }
+}
+
+
+class PointerTo {
+ Object val;
+
+ PointerTo(this.val);
+
+ int encodedSize = 8;
+ Object decode(MojoDecoder decoder) {
+ int pointer = decoder.decodePointer();
+ if (pointer == 0) {
+ return null;
+ }
+ return _callDecode(val, decoder.decodeAndCreateDecoder(pointer));
+ }
+ void encode(MojoEncoder encoder, Object val) {
+ if (val == null) {
+ encoder.encodePointer(val);
+ return;
+ }
+ MojoEncoder obj_encoder =
+ encoder.createAndEncodeEncoder(getEncodedSize(this.val));
+ _callEncode(this.val, obj_encoder, val);
+ }
+}
+
+
+class NullablePointerTo extends PointerTo {
+ static const int encodedSize = PointerTo.encodedSize;
+}
+
+
+class ArrayOf {
+ Object val;
+ int length;
+
+ ArrayOf(this.val, [this.length = 0]);
+
+ int dimensions() => [length].addAll((val is ArrayOf) ? val.dimensions() : []);
+
+ int encodedSize = 8;
+ List decode(MojoDecoder decoder) => decoder.decodeArrayPointer(val);
+ void encode(MojoEncoder encoder, List val) {
+ encoder.encodeArrayPointer(this.val, val);
+ }
+}
+
+
+class NullableArrayOf extends ArrayOf {
+ static const int encodedSize = ArrayOf.encodedSize;
+}
+
+
+class Handle implements MojoType<int> {
+ static const int encodedSize = 4;
+ static int decode(MojoDecoder decoder) => decoder.decodeHandle();
+ static void encode(MojoEncoder encoder, int val) {
+ encoder.encodeHandle(val);
+ }
+}
+
+
+class NullableHandle implements MojoType<int> {
+ static const int encodedSize = Handle.encodedSize;
+ static const decode = Handle.decode;
+ static const encode = Handle.encode;
+}
« no previous file with comments | « mojo/public/dart/bindings.dart ('k') | mojo/public/js/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698