// 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;

int align(int size) => size + (kAlignment - (size % kAlignment)) % kAlignment;

const int kAlignment = 8;
const int kSerializedHandleSize = 4;
const int kPointerSize = 8;
// 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);
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);
  String toString() => message;
}

class _EncoderBuffer {
  ByteData buffer;
  List<core.MojoHandle> handles;
  int extent;

  static const int kInitialBufferSize = 1024;

  _EncoderBuffer([int size = -1]) :
      buffer = new ByteData(size > 0 ? size : kInitialBufferSize),
      handles = [],
      extent = 0;

  void _grow(int newSize) {
    Uint8List newBuffer = new Uint8List(newSize);
    newBuffer.setRange(0, buffer.lengthInBytes, buffer.buffer.asUint8List());
    buffer = newBuffer.buffer.asByteData();
  }

  void claimMemory(int claimSize) {
    extent += claimSize;
    if (extent > buffer.lengthInBytes) {
      int newSize = buffer.lengthInBytes + claimSize;
      newSize += newSize ~/ 2;
      _grow(newSize);
    }
  }

  ByteData get trimmed => new ByteData.view(buffer.buffer, 0, extent);
}

class Encoder {
  _EncoderBuffer _buffer;
  int _base;

  Encoder([int size = -1]) : _buffer = new _EncoderBuffer(size), _base = 0;

  Encoder._fromBuffer(_EncoderBuffer buffer) :
      _buffer = buffer,
      _base = buffer.extent;

  Encoder getStructEncoderAtOffset(StructDataHeader dataHeader) {
    var result = new Encoder._fromBuffer(_buffer);
    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 encodeStructDataHeader(StructDataHeader dataHeader) {
    _buffer.claimMemory(align(dataHeader.size));
    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 =
      'Passing negative value to unsigned encoder';

  void encodeBool(bool value, int offset, int bit) {
    if (value) {
      int encodedValue = _buffer.buffer.getUint8(_base + offset);
      encodedValue |= (1 << bit);
      _buffer.buffer.setUint8(_base + offset, encodedValue);
    }
  }

  void encodeInt8(int value, int offset) =>
      _buffer.buffer.setInt8(_base + offset, value);

  void encodeUint8(int value, int offset) {
    if (value < 0) {
      throw new MojoCodecError('$kErrorUnsigned: $val');
    }
    _buffer.buffer.setUint8(_base + offset, value);
  }

  void encodeInt16(int value, int offset) =>
      _buffer.buffer.setInt16(_base + offset, value, Endianness.LITTLE_ENDIAN);

  void encodeUint16(int value, int offset) {
    if (value < 0) {
      throw new MojoCodecError('$kErrorUnsigned: $val');
    }
    _buffer.buffer.setUint16(_base + offset, value, Endianness.LITTLE_ENDIAN);
  }

  void encodeInt32(int value, int offset) =>
      _buffer.buffer.setInt32(_base + offset, value, Endianness.LITTLE_ENDIAN);

  void encodeUint32(int value, int offset) {
    if (value < 0) {
      throw new MojoCodecError('$kErrorUnsigned: $val');
    }
    _buffer.buffer.setUint32(_base + offset, value, Endianness.LITTLE_ENDIAN);
  }

  void encodeInt64(int value, int offset) =>
      _buffer.buffer.setInt64(_base + offset, value, Endianness.LITTLE_ENDIAN);

  void encodeUint64(int value, int offset) {
    if (value < 0) {
      throw new MojoCodecError('$kErrorUnsigned: $val');
    }
    _buffer.buffer.setUint64(_base + offset, value, Endianness.LITTLE_ENDIAN);
  }

  void encodeFloat(double value, int offset) =>
    _buffer.buffer.setFloat32(_base + offset, value, Endianness.LITTLE_ENDIAN);

  void encodeDouble(double value, int offset) =>
    _buffer.buffer.setFloat64(_base + offset, value, Endianness.LITTLE_ENDIAN);

  void encodeHandle(core.MojoHandle value, int offset, bool nullable) {
    if ((value == null) || !value.isValid) {
      encodeInvalideHandle(offset, nullable);
    } else {
      encodeUint32(_buffer.handles.length, offset);
      _buffer.handles.add(value);
    }
  }

  void encodeMessagePipeHandle(
      core.MojoMessagePipeEndpoint value, int offset, bool nullable) =>
      encodeHandle(value != null ? value.handle : null, offset, nullable);

  void encodeConsumerHandle(
      core.MojoDataPipeConsumer value, int offset, bool nullable) =>
      encodeHandle(value != null ? value.handle : null, offset, nullable);

  void encodeProducerHandle(
      core.MojoDataPipeProducer value, int offset, bool nullable) =>
      encodeHandle(value != null ? value.handle : null, offset, nullable);

  void encodeSharedBufferHandle(
      core.MojoSharedBuffer value, int offset, bool nullable) =>
      encodeHandle(value != null ? value.handle : null, offset, nullable);

  void encodeInterface(Stub interface, int offset, bool nullable) {
    if (interface == null) {
      encodeInvalideHandle(offset, nullable);
      return;
    }
    var pipe = new core.MojoMessagePipe();
    interface.bind(pipe.endpoints[0]);
    encodeMessagePipeHandle(pipe.endpoints[1], offset, nullable);
  }

  void encodeInterfaceRequest(Proxy client, int offset, bool nullable) {
    if (client == null) {
      encodeInvalideHandle(offset, nullable);
      return;
    }
    var pipe = new core.MojoMessagePipe();
    client.bind(pipe.endpoints[0]);
    encodeMessagePipeHandle(pipe.endpoints[1], offset, nullable);
  }

  void encodeNullPointer(int offset, bool nullable) {
    if (!nullable) {
      throw new MojoCodecError(
          'Trying to encode a null pointer for a non-nullable type');
    }
    _buffer.buffer.setUint64(_base + offset, 0, Endianness.LITTLE_ENDIAN);
  }

  void encodeInvalideHandle(int offset, bool nullable) {
    if (!nullable) {
      throw new MojoCodecError(
          'Trying to encode a null pointer for a non-nullable type');
    }
    _buffer.buffer.setInt32(_base + offset, -1, Endianness.LITTLE_ENDIAN);
  }

  void encodePointerToNextUnclaimed(int offset) =>
      encodeUint64(_buffer.extent - (_base + offset), offset);

  void encodeStruct(Struct value, int offset, bool nullable) {
    if (value == null) {
      encodeNullPointer(offset, nullable);
      return;
    }
    encodePointerToNextUnclaimed(offset);
    value.encode(this);
  }

  Encoder encodePointerArray(int length, int offset, int expectedLength) =>
      encoderForArray(kPointerSize, length, offset, expectedLength);

  Encoder encoderForArray(
      int elementSize, int length, int offset, int expectedLength) {
    if ((expectedLength != kUnspecifiedArrayLength) &&
        (expectedLength != length)) {
      throw new MojoCodecError(
          'Trying to encode a fixed array of incorrect length');
    }
    return encoderForArrayByTotalSize(length * elementSize, length, offset);
  }

  Encoder encoderForArrayByTotalSize(int size, int length, int offset) {
    encodePointerToNextUnclaimed(offset);
    return getArrayEncoderAtOffset(
        new ArrayDataHeader(ArrayDataHeader.kHeaderSize + size, length));
  }

  void encodeBoolArray(
      List<bool> value, int offset, int nullability, int expectedLength) {
    if (value == null) {
      encodeNullPointer(offset, isArrayNullable(nullability));
      return;
    }
    if ((expectedLength != kUnspecifiedArrayLength) &&
        (expectedLength != value.length)) {
      throw new MojoCodecError(
          'Trying to encode a fixed array of incorrect size.');
    }
    var bytes = new Uint8List((value.length + 7) ~/ kAlignment);
    for (int i = 0; i < bytes.length; ++i) {
      for (int j = 0; j < kAlignment; ++j) {
        int boolIndex = kAlignment * i + j;
        if ((boolIndex < value.length) && value[boolIndex]) {
          bytes[i] |= (1 << j);
        }
      }
    }
    var encoder = encoderForArrayByTotalSize(
        bytes.length, value.length, offset);
    encoder.appendUint8Array(bytes);
  }

  void encodeArray(Function arrayAppend,
                   int elementBytes,
                   List<int> value,
                   int offset,
                   int nullability,
                   int expectedLength) {
    if (value == null) {
      encodeNullPointer(offset, isArrayNullable(nullability));
      return;
    }
    var encoder = encoderForArray(
        elementBytes, value.length, offset, expectedLength);
    arrayAppend(encoder, value);
  }

  void encodeInt8Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendInt8Array(v),
                  1, value, offset, nullability, expectedLength);

  void encodeUint8Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendUint8Array(v),
                  1, value, offset, nullability, expectedLength);

  void encodeInt16Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendInt16Array(v),
                  2, value, offset, nullability, expectedLength);

  void encodeUint16Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendUint16Array(v),
                  2, value, offset, nullability, expectedLength);

  void encodeInt32Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendInt32Array(v),
                  4, value, offset, nullability, expectedLength);

  void encodeUint32Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendUint32Array(v),
                  4, value, offset, nullability, expectedLength);

  void encodeInt64Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendInt64Array(v),
                  8, value, offset, nullability, expectedLength);

  void encodeUint64Array(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendUint64Array(v),
                  8, value, offset, nullability, expectedLength);

  void encodeFloatArray(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendFloatArray(v),
                  4, value, offset, nullability, expectedLength);

  void encodeDoubleArray(
      List<int> value, int offset, int nullability, int expectedLength) =>
      encodeArray((e, v) => e.appendDoubleArray(v),
                  8, value, offset, nullability, expectedLength);

  void _handleArrayEncodeHelper(Function elementEncoder,
                                List value,
                                int offset,
                                int nullability,
                                int expectedLength) {
    if (value == null) {
      encodeNullPointer(offset, isArrayNullable(nullability));
      return;
    }
    var encoder = encoderForArray(
        kSerializedHandleSize, value.length, offset, expectedLength);
    for (int i = 0; i < value.length; ++i) {
      int handleOffset =
          ArrayDataHeader.kHeaderSize + kSerializedHandleSize * i;
      elementEncoder(
          encoder, value[i], handleOffset, isElementNullable(nullability));
    }
  }

  void encodeHandleArray(
      List<core.MojoHandle> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeHandle(v, o, n),
          value, offset, nullability, expectedLength);

  void encodeMessagePipeHandleArray(
      List<core.MojoMessagePipeEndpoint> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeMessagePipeHandle(v, o, n),
          value, offset, nullability, expectedLength);

  void encodeConsumerHandleArray(
      List<core.MojoDataPipeConsumer> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeConsumerHandle(v, o, n),
          value, offset, nullability, expectedLength);

  void encodeProducerHandleArray(
      List<core.MojoDataPipeProducer> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeProducerHandle(v, o, n),
          value, offset, nullability, expectedLength);

  void encodeSharedBufferHandleArray(
      List<core.MojoSharedBuffer> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeSharedBufferHandle(v, o, n),
          value, offset, nullability, expectedLength);

  void encodeInterfaceRequestArray(
      List<Proxy> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeInterfaceRequest(v, o, n),
          value, offset, nullability, expectedLength);

  void encodeInterfaceArray(
      List<Stub> value,
      int offset,
      int nullability,
      int expectedLength) =>
      _handleArrayEncodeHelper(
          (e, v, o, n) => e.encodeInterface(v, o, n),
          value, offset, nullability, expectedLength);

  static Uint8List _utf8OfString(String s) =>
      (new Uint8List.fromList((const Utf8Encoder()).convert(s)));

  void encodeString(String value, int offset, bool nullable) {
    if (value == null) {
      encodeNullPointer(offset, nullable);
      return;
    }
    int nullability = nullable ? kArrayNullable : kNothingNullable;
    encodeUint8Array(_utf8OfString(value),
                     offset,
                     nullability,
                     kUnspecifiedArrayLength);
  }

  void appendBytes(Uint8List value) {
    _buffer.buffer.buffer.asUint8List().setRange(
        _base + ArrayDataHeader.kHeaderSize,
        _base + ArrayDataHeader.kHeaderSize + value.lengthInBytes,
        value);
  }

  void appendInt8Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Int8List.fromList(value).buffer));

  void appendUint8Array(List<int> value) =>
      appendBytes(new Uint8List.fromList(value));

  void appendInt16Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Int16List.fromList(value).buffer));

  void appendUint16Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Uint16List.fromList(value).buffer));

  void appendInt32Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Int32List.fromList(value).buffer));

  void appendUint32Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Uint32List.fromList(value).buffer));

  void appendInt64Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Int64List.fromList(value).buffer));

  void appendUint64Array(List<int> value) =>
      appendBytes(new Uint8List.view(new Uint64List.fromList(value).buffer));

  void appendFloatArray(List<int> value) =>
      appendBytes(new Uint8List.view(new Float32List.fromList(value).buffer));

  void appendDoubleArray(List<int> value) =>
      appendBytes(new Uint8List.view(new Float64List.fromList(value).buffer));

  Encoder encoderForMap(int offset) {
    encodePointerToNextUnclaimed(offset);
    return getStructEncoderAtOffset(kMapStructHeader);
  }
}


class _Validator {
  final int _maxMemory;
  final int _numberOfHandles;
  int _minNextClaimedHandle = 0;
  int _minNextMemory = 0;

  _Validator(this._maxMemory, this._numberOfHandles);

  void claimHandle(int handle) {
    if (handle < _minNextClaimedHandle) {
      throw new MojoCodecError('Trying to access handle out of order.');
    }
    if (handle >= _numberOfHandles) {
      throw new MojoCodecError('Trying to access non present handle.');
    }
    _minNextClaimedHandle = handle + 1;
  }

  void claimMemory(int start, int end) {
    if ((start % kAlignment) != 0) {
      throw new MojoCodecError('Incorrect starting alignment: $start.');
    }
    if (start < _minNextMemory) {
      throw new MojoCodecError('Trying to access memory out of order.');
    }
    if (end < start) {
      throw new MojoCodecError('Incorrect memory range.');
    }
    if (end > _maxMemory) {
      throw new MojoCodecError('Trying to access out of range memory.');
    }
    _minNextMemory = align(end);
  }
}


class Decoder {
  _Validator _validator;
  Message _message;
  int _base = 0;

  Decoder(this._message, [this._base = 0, this._validator = null]) {
    if (_validator == null) {
      _validator = new _Validator(
          _message.buffer.lengthInBytes, _message.handles.length);
    }
  }

  Decoder getDecoderAtPosition(int offset) =>
      new Decoder(_message, offset, _validator);

  factory Decoder.atOffset(Decoder d, int offset, _Validator validator) =>
      new Decoder(d._message, offset, validator);

  ByteData get _buffer => _message.buffer;
  List<core.MojoHandle> get _handles => _message.handles;

  int decodeInt8(int offset) => _buffer.getInt8(_base + offset);
  int decodeUint8(int offset) => _buffer.getUint8(_base + offset);
  int decodeInt16(int offset) =>
      _buffer.getInt16(_base + offset, Endianness.LITTLE_ENDIAN);
  int decodeUint16(int offset) =>
      _buffer.getUint16(_base + offset, Endianness.LITTLE_ENDIAN);
  int decodeInt32(int offset) =>
      _buffer.getInt32(_base + offset, Endianness.LITTLE_ENDIAN);
  int decodeUint32(int offset) =>
      _buffer.getUint32(_base + offset, Endianness.LITTLE_ENDIAN);
  int decodeInt64(int offset) =>
      _buffer.getInt64(_base + offset, Endianness.LITTLE_ENDIAN);
  int decodeUint64(int offset) =>
      _buffer.getUint64(_base + offset,Endianness.LITTLE_ENDIAN);
  double decodeFloat(int offset) =>
      _buffer.getFloat32(_base + offset, Endianness.LITTLE_ENDIAN);
  double decodeDouble(int offset) =>
      _buffer.getFloat64(_base + offset, Endianness.LITTLE_ENDIAN);

  bool decodeBool(int offset, int bit) =>
      (decodeUint8(offset) & (1 << bit)) != 0;

  core.MojoHandle decodeHandle(int offset, bool nullable) {
    int index = decodeInt32(offset);
    if (index == -1) {
      if (!nullable) {
        throw new MojoCodecError(
            'Trying to decode an invalid handle from a non-nullable type.');
      }
      return new core.MojoHandle(core.MojoHandle.INVALID);
    }
    _validator.claimHandle(index);
    return _handles[index];
  }

  core.MojoMessagePipeEndpoint decodeMessagePipeHandle(
      int offset, bool nullable) =>
      new core.MojoMessagePipeEndpoint(decodeHandle(offset, nullable));

  core.MojoDataPipeConsumer decodeConsumerHandle(int offset, bool nullable) =>
      new core.MojoDataPipeConsumer(decodeHandle(offset, nullable));

  core.MojoDataPipeProducer decodeProducerHandle(int offset, bool nullable) =>
      new core.MojoDataPipeProducer(decodeHandle(offset, nullable));

  core.MojoSharedBuffer decodeSharedBufferHandle(int offset, bool nullable) =>
      new core.MojoSharedBuffer(decodeHandle(offset, nullable));

  Proxy decodeServiceInterface(
      int offset, bool nullable, Function clientFactory) {
    var endpoint = decodeMessagePipeHandle(offset, nullable);
    return endpoint.handle.isValid ? clientFactory(endpoint) : null;
  }

  Stub decodeInterfaceRequest(
      int offset, bool nullable, Function interfaceFactory) {
    var endpoint = decodeMessagePipeHandle(offset, nullable);
    return endpoint.handle.isValid ? interfaceFactory(endpoint) : null;
  }

  Decoder decodePointer(int offset, bool nullable) {
    int basePosition = _base + offset;
    int pointerOffset = decodeUint64(offset);
    if (pointerOffset == 0) {
      if (!nullable) {
        throw new MojoCodecError(
            'Trying to decode a null pointer for a non-nullable type');
      }
      return null;
    }
    int newPosition = (basePosition + pointerOffset);
    return new Decoder.atOffset(this, newPosition, _validator);
  }

  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 (numElements < 0) {
      throw new MojoCodecError('Negative number of elements.');
    }
    _validator.claimMemory(_base + ArrayDataHeader.kHeaderSize, _base + size);
    return new ArrayDataHeader(size, numElements);
  }

  // Decode arrays.
  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.numElements != expectedLength)) {
      throw new MojoCodecError(
          'Incorrect array length. Expected $expectedLength, but got '
          '${header.numElements}.');
    }
    return header;
  }

  List<bool> decodeBoolArray(int offset, int nullability, int expectedLength) {
    Decoder d = decodePointer(offset, isArrayNullable(nullability));
    if (d == null) {
      return null;
    }
    var header = d.decodeDataHeaderForBoolArray(expectedLength);
    var bytes = new Uint8List.view(
        d._buffer.buffer,
        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;
        if (boolIndex < result.length) {
          result[boolIndex] = (bytes[i] & (1 << j)) != 0;
        }
      }
    }
    return result;
  }

  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.numElements != expectedLength)) {
      throw new MojoCodecError(
          'Incorrect array length. Expected $expectedLength, but got '
          '${header.numElements}');
    }
    return header;
  }

  ArrayDataHeader decodeDataHeaderForPointerArray(int expectedLength) =>
      decodeDataHeaderForArray(kPointerSize, expectedLength);

  List decodeArray(Function arrayViewer,
                   int elementSize,
                   int offset,
                   int nullability,
                   int expectedLength) {
    Decoder d = decodePointer(offset, isArrayNullable(nullability));
    if (d == null) {
      return null;
    }
    var header = d.decodeDataHeaderForArray(elementSize, expectedLength);
    return arrayViewer(
        d._buffer.buffer,
        d._buffer.offsetInBytes + d._base + ArrayDataHeader.kHeaderSize,
        header.numElements);
  }

  List<int> decodeInt8Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Int8List.view(b, s, l),
                  1, offset, nullability, expectedLength);

  List<int> decodeUint8Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Uint8List.view(b, s, l),
                  1, offset, nullability, expectedLength);

  List<int> decodeInt16Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Int16List.view(b, s, l),
                  2, offset, nullability, expectedLength);

  List<int> decodeUint16Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Uint16List.view(b, s, l),
                  2, offset, nullability, expectedLength);

  List<int> decodeInt32Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Int32List.view(b, s, l),
                  4, offset, nullability, expectedLength);

  List<int> decodeUint32Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Uint32List.view(b, s, l),
                  4, offset, nullability, expectedLength);

  List<int> decodeInt64Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Int64List.view(b, s, l),
                  8, offset, nullability, expectedLength);

  List<int> decodeUint64Array(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Uint64List.view(b, s, l),
                  8, offset, nullability, expectedLength);

  List<double> decodeFloatArray(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Float32List.view(b, s, l),
                  4, offset, nullability, expectedLength);

  List<double> decodeDoubleArray(
      int offset, int nullability, int expectedLength) =>
      decodeArray((b, s, l) => new Float64List.view(b, s, l),
                  8, offset, nullability, expectedLength);

  List _handleArrayDecodeHelper(Function elementDecoder,
                                int offset,
                                int nullability,
                                int expectedLength) {
    Decoder d = decodePointer(offset, isArrayNullable(nullability));
    if (d == null) {
      return null;
    }
    var header = d.decodeDataHeaderForArray(4, expectedLength);
    var result = new List(header.numElements);
    for (int i = 0; i < result.length; ++i) {
      result[i] = elementDecoder(
          d,
          ArrayDataHeader.kHeaderSize + kSerializedHandleSize * i,
          isElementNullable(nullability));
    }
    return result;

  }

  List<core.MojoHandle> decodeHandleArray(
      int offset, int nullability, int expectedLength) =>
      _handleArrayDecodeHelper((d, o, n) => d.decodeHandle(o, n),
                               offset, nullability, expectedLength);

  List<core.MojoDataPipeConsumer> decodeConsumerHandleArray(
      int offset, int nullability, int expectedLength) =>
      _handleArrayDecodeHelper((d, o, n) => d.decodeConsumerHandle(o, n),
                               offset, nullability, expectedLength);

  List<core.MojoDataPipeProducer> decodeProducerHandleArray(
      int offset, int nullability, int expectedLength) =>
      _handleArrayDecodeHelper((d, o, n) => d.decodeProducerHandle(o, n),
                               offset, nullability, expectedLength);

  List<core.MojoMessagePipeEndpoint> decodeMessagePipeHandleArray(
      int offset, int nullability, int expectedLength) =>
      _handleArrayDecodeHelper((d, o, n) => d.decodeMessagePipeHandle(o, n),
                               offset, nullability, expectedLength);

  List<core.MojoSharedBuffer> decodeSharedBufferHandleArray(
      int offset, int nullability, int expectedLength) =>
      _handleArrayDecodeHelper((d, o, n) => d.decodeSharedBufferHandle(o, n),
                               offset, nullability, expectedLength);

  List<Stub> decodeInterfaceRequestArray(
      int offset,
      int nullability,
      int expectedLength,
      Function interfaceFactory) =>
      _handleArrayDecodeHelper(
          (d, o, n) => d.decodeInterfaceRequest(o, n, interfaceFactory),
          offset, nullability, expectedLength);

  List<Proxy> decodeServiceInterfaceArray(
      int offset,
      int nullability,
      int expectedLength,
      Function clientFactory) =>
      _handleArrayDecodeHelper(
          (d, o, n) => d.decodeServiceInterface(o, n, clientFactory),
          offset, nullability, expectedLength);

  static String _stringOfUtf8(Uint8List bytes) =>
      (const Utf8Decoder()).convert(bytes.toList());

  String decodeString(int offset, bool nullable) {
    int nullability = nullable ? kArrayNullable : 0;
    var bytes = decodeUint8Array(offset, nullability, kUnspecifiedArrayLength);
    if (bytes == null) {
      return null;
    }
    return _stringOfUtf8(bytes);
  }

  StructDataHeader decodeDataHeaderForMap() {
    var header = decodeStructDataHeader();
    if (header.size != kMapStructHeader.size) {
      throw new MojoCodecError(
          'Incorrect header for map. The size is incorrect.');
    }
    if (header.version != kMapStructHeader.version) {
      throw new MojoCodecError(
          'Incorrect header for map. The version is incorrect.');
    }
    return header;
  }
}
