| Index: third_party/mojo/src/mojo/public/dart/src/codec.dart
|
| diff --git a/third_party/mojo/src/mojo/public/dart/src/codec.dart b/third_party/mojo/src/mojo/public/dart/src/codec.dart
|
| index 268daee2a61fcec7b7f9e0686484c68057ef35b4..677dc10a7b33b1976f296db1939cc9f6c7faceb0 100644
|
| --- a/third_party/mojo/src/mojo/public/dart/src/codec.dart
|
| +++ b/third_party/mojo/src/mojo/public/dart/src/codec.dart
|
| @@ -9,7 +9,9 @@ int align(int size) => size + (kAlignment - (size % kAlignment)) % kAlignment;
|
| const int kAlignment = 8;
|
| const int kSerializedHandleSize = 4;
|
| const int kPointerSize = 8;
|
| -const DataHeader kMapStructHeader = const DataHeader(24, 2);
|
| +// TODO(yzshen): In order to work with other bindings which still interprets
|
| +// the |version| field as |num_fields|, set it to version 2 for now.
|
| +const StructDataHeader kMapStructHeader = const StructDataHeader(24, 2);
|
| const int kUnspecifiedArrayLength = -1;
|
| const int kNothingNullable = 0;
|
| const int kArrayNullable = (1 << 0);
|
| @@ -18,6 +20,30 @@ const int kElementNullable = (1 << 1);
|
| bool isArrayNullable(int nullability) => (nullability & kArrayNullable) > 0;
|
| bool isElementNullable(int nullability) => (nullability & kElementNullable) > 0;
|
|
|
| +class StructDataHeader {
|
| + static const int kHeaderSize = 8;
|
| + static const int kSizeOffset = 0;
|
| + static const int kVersionOffset = 4;
|
| + final int size;
|
| + final int version;
|
| +
|
| + const StructDataHeader(this.size, this.version);
|
| +
|
| + String toString() => "StructDataHeader($size, $version)";
|
| +}
|
| +
|
| +class ArrayDataHeader {
|
| + static const int kHeaderSize = 8;
|
| + static const int kSizeOffset = 0;
|
| + static const int kNumElementsOffset = 4;
|
| + final int size;
|
| + final int numElements;
|
| +
|
| + const ArrayDataHeader(this.size, this.numElements);
|
| +
|
| + String toString() => "ArrayDataHeader($size, $numElements)";
|
| +}
|
| +
|
| class MojoCodecError {
|
| final String message;
|
| MojoCodecError(this.message);
|
| @@ -64,18 +90,30 @@ class Encoder {
|
| _buffer = buffer,
|
| _base = buffer.extent;
|
|
|
| - Encoder getEncoderAtOffset(DataHeader dataHeader) {
|
| + Encoder getStructEncoderAtOffset(StructDataHeader dataHeader) {
|
| var result = new Encoder._fromBuffer(_buffer);
|
| - result.encodeDataHeader(dataHeader);
|
| + result.encodeStructDataHeader(dataHeader);
|
| + return result;
|
| + }
|
| +
|
| + Encoder getArrayEncoderAtOffset(ArrayDataHeader dataHeader) {
|
| + var result = new Encoder._fromBuffer(_buffer);
|
| + result.encodeArrayDataHeader(dataHeader);
|
| return result;
|
| }
|
|
|
| Message get message => new Message(_buffer.trimmed, _buffer.handles);
|
|
|
| - void encodeDataHeader(DataHeader dataHeader) {
|
| + void encodeStructDataHeader(StructDataHeader dataHeader) {
|
| _buffer.claimMemory(align(dataHeader.size));
|
| - encodeUint32(dataHeader.size, DataHeader.kSizeOffset);
|
| - encodeUint32(dataHeader.numFields, DataHeader.kNumFieldsOffset);
|
| + encodeUint32(dataHeader.size, StructDataHeader.kSizeOffset);
|
| + encodeUint32(dataHeader.version, StructDataHeader.kVersionOffset);
|
| + }
|
| +
|
| + void encodeArrayDataHeader(ArrayDataHeader dataHeader) {
|
| + _buffer.claimMemory(align(dataHeader.size));
|
| + encodeUint32(dataHeader.size, ArrayDataHeader.kSizeOffset);
|
| + encodeUint32(dataHeader.numElements, ArrayDataHeader.kNumElementsOffset);
|
| }
|
|
|
| static const String kErrorUnsigned =
|
| @@ -223,8 +261,8 @@ class Encoder {
|
|
|
| Encoder encoderForArrayByTotalSize(int size, int length, int offset) {
|
| encodePointerToNextUnclaimed(offset);
|
| - return getEncoderAtOffset(
|
| - new DataHeader(DataHeader.kHeaderSize + size, length));
|
| + return getArrayEncoderAtOffset(
|
| + new ArrayDataHeader(ArrayDataHeader.kHeaderSize + size, length));
|
| }
|
|
|
| void encodeBoolArray(
|
| @@ -329,7 +367,8 @@ class Encoder {
|
| var encoder = encoderForArray(
|
| kSerializedHandleSize, value.length, offset, expectedLength);
|
| for (int i = 0; i < value.length; ++i) {
|
| - int handleOffset = DataHeader.kHeaderSize + kSerializedHandleSize * i;
|
| + int handleOffset =
|
| + ArrayDataHeader.kHeaderSize + kSerializedHandleSize * i;
|
| elementEncoder(
|
| encoder, value[i], handleOffset, isElementNullable(nullability));
|
| }
|
| @@ -415,8 +454,8 @@ class Encoder {
|
|
|
| void appendBytes(Uint8List value) {
|
| _buffer.buffer.buffer.asUint8List().setRange(
|
| - _base + DataHeader.kHeaderSize,
|
| - _base + DataHeader.kHeaderSize + value.lengthInBytes,
|
| + _base + ArrayDataHeader.kHeaderSize,
|
| + _base + ArrayDataHeader.kHeaderSize + value.lengthInBytes,
|
| value);
|
| }
|
|
|
| @@ -452,7 +491,7 @@ class Encoder {
|
|
|
| Encoder encoderForMap(int offset) {
|
| encodePointerToNextUnclaimed(offset);
|
| - return getEncoderAtOffset(kMapStructHeader);
|
| + return getStructEncoderAtOffset(kMapStructHeader);
|
| }
|
| }
|
|
|
| @@ -588,31 +627,47 @@ class Decoder {
|
| return new Decoder.atOffset(this, newPosition, _validator);
|
| }
|
|
|
| - DataHeader decodeDataHeader() {
|
| - _validator.claimMemory(_base, _base + DataHeader.kHeaderSize);
|
| - int size = decodeUint32(DataHeader.kSizeOffset);
|
| - int numFields = decodeUint32(DataHeader.kNumFieldsOffset);
|
| + StructDataHeader decodeStructDataHeader() {
|
| + _validator.claimMemory(_base, _base + StructDataHeader.kHeaderSize);
|
| + int size = decodeUint32(StructDataHeader.kSizeOffset);
|
| + int version = decodeUint32(StructDataHeader.kVersionOffset);
|
| + if (size < 0) {
|
| + throw new MojoCodecError('Negative size.');
|
| + }
|
| + if (version < 0) {
|
| + throw new MojoCodecError('Negative version number.');
|
| + }
|
| + _validator.claimMemory(_base + StructDataHeader.kHeaderSize, _base + size);
|
| + return new StructDataHeader(size, version);
|
| + }
|
| +
|
| + ArrayDataHeader decodeArrayDataHeader() {
|
| + _validator.claimMemory(_base, _base + ArrayDataHeader.kHeaderSize);
|
| + int size = decodeUint32(ArrayDataHeader.kSizeOffset);
|
| + int numElements = decodeUint32(ArrayDataHeader.kNumElementsOffset);
|
| if (size < 0) {
|
| throw new MojoCodecError('Negative size.');
|
| }
|
| - if (numFields < 0) {
|
| - throw new MojoCodecError('Negative number of fields.');
|
| + if (numElements < 0) {
|
| + throw new MojoCodecError('Negative number of elements.');
|
| }
|
| - _validator.claimMemory(_base + DataHeader.kHeaderSize, _base + size);
|
| - return new DataHeader(size, numFields);
|
| + _validator.claimMemory(_base + ArrayDataHeader.kHeaderSize, _base + size);
|
| + return new ArrayDataHeader(size, numElements);
|
| }
|
|
|
| // Decode arrays.
|
| - DataHeader decodeDataHeaderForBoolArray(int expectedLength) {
|
| - var header = decodeDataHeader();
|
| - if (header.size < DataHeader.kHeaderSize + (header.numFields + 7) ~/ 8) {
|
| + ArrayDataHeader decodeDataHeaderForBoolArray(int expectedLength) {
|
| + var header = decodeArrayDataHeader();
|
| + var arrayByteCount =
|
| + ArrayDataHeader.kHeaderSize + (header.numElements + 7) ~/ 8;
|
| + if (header.size < arrayByteCount) {
|
| throw new MojoCodecError('Array header is incorrect');
|
| }
|
| if ((expectedLength != kUnspecifiedArrayLength) &&
|
| - (header.numFields != expectedLength)) {
|
| + (header.numElements != expectedLength)) {
|
| throw new MojoCodecError(
|
| 'Incorrect array length. Expected $expectedLength, but got '
|
| - '${header.numFields}.');
|
| + '${header.numElements}.');
|
| }
|
| return header;
|
| }
|
| @@ -625,9 +680,9 @@ class Decoder {
|
| var header = d.decodeDataHeaderForBoolArray(expectedLength);
|
| var bytes = new Uint8List.view(
|
| d._buffer.buffer,
|
| - d._buffer.offsetInBytes + d._base + DataHeader.kHeaderSize,
|
| - (header.numFields + 7) ~/ kAlignment);
|
| - var result = new List<bool>(header.numFields);
|
| + d._buffer.offsetInBytes + d._base + ArrayDataHeader.kHeaderSize,
|
| + (header.numElements + 7) ~/ kAlignment);
|
| + var result = new List<bool>(header.numElements);
|
| for (int i = 0; i < bytes.lengthInBytes; ++i) {
|
| for (int j = 0; j < kAlignment; ++j) {
|
| int boolIndex = i * kAlignment + j;
|
| @@ -639,22 +694,25 @@ class Decoder {
|
| return result;
|
| }
|
|
|
| - DataHeader decodeDataHeaderForArray(int elementSize, int expectedLength) {
|
| - var header = decodeDataHeader();
|
| - if (header.size < DataHeader.kHeaderSize + header.numFields * elementSize) {
|
| + ArrayDataHeader decodeDataHeaderForArray(int elementSize,
|
| + int expectedLength) {
|
| + var header = decodeArrayDataHeader();
|
| + var arrayByteCount =
|
| + ArrayDataHeader.kHeaderSize + header.numElements * elementSize;
|
| + if (header.size < arrayByteCount) {
|
| throw new MojoCodecError(
|
| 'Array header is incorrect: $header, elementSize = $elementSize');
|
| }
|
| if ((expectedLength != kUnspecifiedArrayLength) &&
|
| - (header.numFields != expectedLength)) {
|
| + (header.numElements != expectedLength)) {
|
| throw new MojoCodecError(
|
| 'Incorrect array length. Expected $expectedLength, but got '
|
| - '${header.numFields}');
|
| + '${header.numElements}');
|
| }
|
| return header;
|
| }
|
|
|
| - DataHeader decodeDataHeaderForPointerArray(int expectedLength) =>
|
| + ArrayDataHeader decodeDataHeaderForPointerArray(int expectedLength) =>
|
| decodeDataHeaderForArray(kPointerSize, expectedLength);
|
|
|
| List decodeArray(Function arrayViewer,
|
| @@ -669,8 +727,8 @@ class Decoder {
|
| var header = d.decodeDataHeaderForArray(elementSize, expectedLength);
|
| return arrayViewer(
|
| d._buffer.buffer,
|
| - d._buffer.offsetInBytes + d._base + DataHeader.kHeaderSize,
|
| - header.numFields);
|
| + d._buffer.offsetInBytes + d._base + ArrayDataHeader.kHeaderSize,
|
| + header.numElements);
|
| }
|
|
|
| List<int> decodeInt8Array(
|
| @@ -732,11 +790,11 @@ class Decoder {
|
| return null;
|
| }
|
| var header = d.decodeDataHeaderForArray(4, expectedLength);
|
| - var result = new List(header.numFields);
|
| + var result = new List(header.numElements);
|
| for (int i = 0; i < result.length; ++i) {
|
| result[i] = elementDecoder(
|
| d,
|
| - DataHeader.kHeaderSize + kSerializedHandleSize * i,
|
| + ArrayDataHeader.kHeaderSize + kSerializedHandleSize * i,
|
| isElementNullable(nullability));
|
| }
|
| return result;
|
| @@ -798,15 +856,15 @@ class Decoder {
|
| return _stringOfUtf8(bytes);
|
| }
|
|
|
| - DataHeader decodeDataHeaderForMap() {
|
| - var header = decodeDataHeader();
|
| + StructDataHeader decodeDataHeaderForMap() {
|
| + var header = decodeStructDataHeader();
|
| if (header.size != kMapStructHeader.size) {
|
| throw new MojoCodecError(
|
| 'Incorrect header for map. The size is incorrect.');
|
| }
|
| - if (header.numFields != kMapStructHeader.numFields) {
|
| + if (header.version != kMapStructHeader.version) {
|
| throw new MojoCodecError(
|
| - 'Incorrect header for map. The number of fields is incorrect.');
|
| + 'Incorrect header for map. The version is incorrect.');
|
| }
|
| return header;
|
| }
|
|
|