diff --git a/dart/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart index 4956286e5c4..32397fd27a3 100644 --- a/dart/lib/flat_buffers.dart +++ b/dart/lib/flat_buffers.dart @@ -41,7 +41,7 @@ class BufferContext { @pragma('vm:prefer-inline') Uint8List _asUint8List(int offset, int length) => _buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length); - + @pragma('vm:prefer-inline') Int8List _asInt8List(int offset, int length) => _buffer.buffer.asInt8List(_buffer.offsetInBytes + offset, length); @@ -58,6 +58,20 @@ class BufferContext { return _buffer.buffer.asUint32List(_buffer.offsetInBytes + offset, length); } + @pragma('vm:prefer-inline') + Float32List _asFloat32List(int offset, int length) { + assert(Endian.host == Endian.little); + return _buffer.buffer + .asFloat32List(_buffer.offsetInBytes + offset, length); + } + + @pragma('vm:prefer-inline') + Float64List _asFloat64List(int offset, int length) { + assert(Endian.host == Endian.little); + return _buffer.buffer + .asFloat64List(_buffer.offsetInBytes + offset, length); + } + @pragma('vm:prefer-inline') double _getFloat64(int offset) => _buffer.getFloat64(offset, Endian.little); @@ -540,7 +554,8 @@ class Builder { /// Write the given list of 64-bit float [values]. int writeListFloat64(List values) { assert(!_inVTable); - _prepare(_sizeofFloat64, values.length, additionalBytes: _sizeofUint32); + _prepare(_sizeofUint32, 1, + additionalBytes: values.length * _sizeofFloat64); final result = _tail; var tail = _tail; _setUint32AtTail(tail, values.length); @@ -555,7 +570,8 @@ class Builder { /// Write the given list of 32-bit float [values]. int writeListFloat32(List values) { assert(!_inVTable); - _prepare(_sizeofFloat32, 1 + values.length); + _prepare(_sizeofUint32, 1, + additionalBytes: values.length * _sizeofFloat32); final result = _tail; var tail = _tail; _setUint32AtTail(tail, values.length); @@ -894,8 +910,6 @@ class BoolReader extends Reader { /// The reader of lists of 64-bit float values. /// /// The returned unmodifiable lists lazily read values on access. -/// -/// TODO: Return dart:typed_data Float64List type on LE systems class Float64ListReader extends Reader> { const Float64ListReader(); @@ -905,15 +919,20 @@ class Float64ListReader extends Reader> { @override @pragma('vm:prefer-inline') - List read(BufferContext bc, int offset) => - _FbFloat64List(bc, bc.derefObject(offset)); + List read(BufferContext bc, int offset) { + if (Endian.host == Endian.little) { + final listOffset = bc.derefObject(offset); + final length = bc._getUint32(listOffset); + return bc._asFloat64List(listOffset + _sizeofUint32, length); + } else { + return _FbFloat64List(bc, bc.derefObject(offset)); + } + } } /// The reader of lists of 32-bit float values. /// /// The returned unmodifiable lists lazily read values on access. -/// -/// TODO: Return dart:typed_data Float32List type on LE systems class Float32ListReader extends Reader> { const Float32ListReader(); @@ -923,8 +942,15 @@ class Float32ListReader extends Reader> { @override @pragma('vm:prefer-inline') - List read(BufferContext bc, int offset) => - _FbFloat32List(bc, bc.derefObject(offset)); + List read(BufferContext bc, int offset) { + if (Endian.host == Endian.little) { + final listOffset = bc.derefObject(offset); + final length = bc._getUint32(listOffset); + return bc._asFloat32List(listOffset + _sizeofUint32, length); + } else { + return _FbFloat32List(bc, bc.derefObject(offset)); + } + } } class Float64Reader extends Reader { @@ -1146,14 +1172,13 @@ class Uint32ListReader extends Reader> { @pragma('vm:prefer-inline') List read(BufferContext bc, int offset) { if (Endian.host == Endian.little) { - final listOffset = bc.derefObject(offset); - final length = bc._getUint32(listOffset); - return bc._asUint32List(listOffset + _sizeofUint32, length); - } else { - return _FbUint32List(bc, bc.derefObject(offset)); - } - } - + final listOffset = bc.derefObject(offset); + final length = bc._getUint32(listOffset); + return bc._asUint32List(listOffset + _sizeofUint32, length); + } else { + return _FbUint32List(bc, bc.derefObject(offset)); + } + } } /// The reader of unsigned 64-bit integers. @@ -1198,12 +1223,12 @@ class Uint16ListReader extends Reader> { @pragma('vm:prefer-inline') List read(BufferContext bc, int offset) { if (Endian.host == Endian.little) { - final listOffset = bc.derefObject(offset); - final length = bc._getUint32(listOffset); - return bc._asUint16List(listOffset + _sizeofUint32, length); - } else { - return _FbUint16List(bc, bc.derefObject(offset)); - } + final listOffset = bc.derefObject(offset); + final length = bc._getUint32(listOffset); + return bc._asUint16List(listOffset + _sizeofUint32, length); + } else { + return _FbUint16List(bc, bc.derefObject(offset)); + } } } diff --git a/dart/test/flat_buffers_test.dart b/dart/test/flat_buffers_test.dart index 9f0048c4d5a..41aefeaba9f 100644 --- a/dart/test/flat_buffers_test.dart +++ b/dart/test/flat_buffers_test.dart @@ -542,9 +542,19 @@ class BuilderTest { byteList = builder.buffer; } + // verify alignment + ByteData byteData = ByteData.view(Uint8List.fromList(byteList).buffer); + int vectorOffset = byteData.getUint32(0, Endian.little); + expect(vectorOffset, 8); + int length = byteData.getUint32(vectorOffset, Endian.little); + expect(length, values.length); + int floatDataOffset = vectorOffset + 4; + expect(floatDataOffset % 8, 0); + // read and verify BufferContext buf = BufferContext.fromBytes(byteList); List items = const Float64ListReader().read(buf, 0); + expect(items is Float64List, Endian.host == Endian.little); expect(items, hasLength(values.length)); for (int i = 0; i < values.length; i++) { expect(values[i], closeTo(items[i], .001)); @@ -561,10 +571,21 @@ class BuilderTest { builder.finish(offset); byteList = builder.buffer; } + + // verify alignment + ByteData byteData = ByteData.view(Uint8List.fromList(byteList).buffer); + int vectorOffset = byteData.getUint32(0, Endian.little); + expect(vectorOffset, 4); + int length = byteData.getUint32(vectorOffset, Endian.little); + expect(length, values.length); + int floatDataOffset = vectorOffset + 4; + expect(floatDataOffset % 4, 0); + // read and verify BufferContext buf = BufferContext.fromBytes(byteList); List items = const Float32ListReader().read(buf, 0); - expect(items, hasLength(5)); + expect(items is Float32List, Endian.host == Endian.little); + expect(items, hasLength(values.length)); for (int i = 0; i < values.length; i++) { expect(values[i], closeTo(items[i], .001)); }