diff options
author | Ivan Dlugos <6349682+vaind@users.noreply.github.com> | 2021-07-09 20:45:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-09 11:45:45 -0700 |
commit | 92ae532e43950df1c0d96bf9ad6d33f2d529c919 (patch) | |
tree | 645c7272a2b8ee965fc865afcf21ac0661055ba2 /dart | |
parent | 7482b25f8b9000f9b5cf805a30b29e7578718714 (diff) | |
download | flatbuffers-92ae532e43950df1c0d96bf9ad6d33f2d529c919.tar.gz flatbuffers-92ae532e43950df1c0d96bf9ad6d33f2d529c919.tar.bz2 flatbuffers-92ae532e43950df1c0d96bf9ad6d33f2d529c919.zip |
Dart - finish/lowFinish/buffer changes (#6712)
* Dart - change Builder "lowFinish()" to "buffer" and "finish()" to not void return
Aligning the API with other languages, e.g. c++ and allowing custom use-cases to avoid creating a Uint8List
* Dart - change builder.buffer to check that finish() was already called
* Dart - builder - move !finished assertion to _prepare() which is run from all other functions
Diffstat (limited to 'dart')
-rw-r--r-- | dart/lib/flat_buffers.dart | 18 | ||||
-rw-r--r-- | dart/test/flat_buffers_test.dart | 100 | ||||
-rw-r--r-- | dart/test/monster_test_my_game.example2_generated.dart | 3 | ||||
-rw-r--r-- | dart/test/monster_test_my_game.example_generated.dart | 27 | ||||
-rw-r--r-- | dart/test/monster_test_my_game_generated.dart | 3 |
5 files changed, 98 insertions, 53 deletions
diff --git a/dart/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart index 8b31f21b..1ab410d3 100644 --- a/dart/lib/flat_buffers.dart +++ b/dart/lib/flat_buffers.dart @@ -103,6 +103,8 @@ abstract class ObjectBuilder { /// Class that helps building flat buffers. class Builder { + bool _finished = false; + final int initialSize; /// The list of existing VTable(s). @@ -336,11 +338,9 @@ class Builder { return tableTail; } - /// This method low level method can be used to return a raw piece of the - /// buffer after using the put* methods. - /// - /// Most clients should prefer calling [finish]. - Uint8List lowFinish() { + /// Returns the finished buffer. You must call [finish] before accessing this. + Uint8List get buffer { + assert(_finished); final finishedSize = size(); return _buf.buffer .asUint8List(_buf.lengthInBytes - finishedSize, finishedSize); @@ -351,7 +351,7 @@ class Builder { /// written object. If [fileIdentifier] is specified (and not `null`), it is /// interpreted as a 4-byte Latin-1 encoded string that should be placed at /// bytes 4-7 of the file. - Uint8List finish(int offset, [String? fileIdentifier]) { + void finish(int offset, [String? fileIdentifier]) { final sizeBeforePadding = size(); final requiredBytes = _sizeofUint32 * (fileIdentifier == null ? 1 : 2); _prepare(max(requiredBytes, _maxAlign), 1); @@ -370,9 +370,7 @@ class Builder { i++) { _setUint8AtTail(_buf, i, 0); } - - return _buf.buffer - .asUint8List(_buf.lengthInBytes - finishedSize, finishedSize); + _finished = true; } /// Writes a Float64 to the tail of the buffer after preparing space for it. @@ -457,6 +455,7 @@ class Builder { /// Reset the builder and make it ready for filling a new buffer. void reset() { + _finished = false; _maxAlign = 1; _tail = 0; _currentVTable = null; @@ -719,6 +718,7 @@ class Builder { /// Additionally allocate the specified `additionalBytes`. Update the current /// tail pointer to point at the allocated space. void _prepare(int size, int count, {int additionalBytes = 0}) { + assert(!_finished); // Update the alignment. if (_maxAlign < size) { _maxAlign = size; diff --git a/dart/test/flat_buffers_test.dart b/dart/test/flat_buffers_test.dart index ff77ff37..bfe7b181 100644 --- a/dart/test/flat_buffers_test.dart +++ b/dart/test/flat_buffers_test.dart @@ -136,12 +136,16 @@ class CheckOtherLangaugesData { /// Test a custom, fixed-memory allocator (no actual allocations performed) class CustomAllocator extends Allocator { final _memory = ByteData(10 * 1024); + int _used = 0; + + Uint8List buffer(int size) => _memory.buffer.asUint8List(_used - size, size); @override ByteData allocate(int size) { if (size > _memory.lengthInBytes) { throw UnsupportedError('Trying to allocate too much'); } + _used = size; return ByteData.sublistView(_memory, 0, size); } @@ -240,7 +244,8 @@ class BuilderTest { Builder builder = new Builder(initialSize: 0); builder.startTable(); int offset = builder.endTable(); - byteList = builder.finish(offset, 'Az~ÿ'); + builder.finish(offset, 'Az~ÿ'); + byteList = builder.buffer; } // Convert byteList to a ByteData so that we can read data from it. ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes); @@ -263,16 +268,29 @@ class BuilderTest { } void test_low() { - final builder = Builder(initialSize: 0, allocator: CustomAllocator()); - expect((builder..putUint8(1)).lowFinish(), [1]); - expect((builder..putUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]); - expect((builder..putUint8(3)).lowFinish(), - [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]); - expect((builder..putUint8(4)).lowFinish(), - [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); - expect((builder..putUint8(5)).lowFinish(), - [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); - expect((builder..putUint32(6)).lowFinish(), + final allocator = CustomAllocator(); + final builder = Builder(initialSize: 0, allocator: allocator); + + builder.putUint8(1); + expect(allocator.buffer(builder.size()), [1]); + + builder.putUint32(2); + expect(allocator.buffer(builder.size()), [2, 0, 0, 0, 0, 0, 0, 1]); + + builder.putUint8(3); + expect( + allocator.buffer(builder.size()), [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]); + + builder.putUint8(4); + expect( + allocator.buffer(builder.size()), [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); + + builder.putUint8(5); + expect( + allocator.buffer(builder.size()), [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); + + builder.putUint32(6); + expect(allocator.buffer(builder.size()), [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); } @@ -284,7 +302,8 @@ class BuilderTest { builder.addInt32(0, 10, 10); builder.addInt32(1, 20, 10); int offset = builder.endTable(); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; expect(builder.size(), byteList.length); } // read and verify @@ -310,7 +329,8 @@ class BuilderTest { builder.addInt32(0, 10); builder.addInt32(1, 20); builder.addInt32(2, 30); - byteList = builder.finish(builder.endTable()); + builder.finish(builder.endTable()); + byteList = builder.buffer; } // Convert byteList to a ByteData so that we can read data from it. ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes); @@ -346,7 +366,8 @@ class BuilderTest { builder.addOffset(0, latinStringOffset); builder.addOffset(1, unicodeStringOffset); int offset = builder.endTable(); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -375,7 +396,8 @@ class BuilderTest { builder.addUint32(5, 0x9ABCDEF0); builder.addUint8(6, 0x9A); int offset = builder.endTable(); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -417,7 +439,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListUint32(values); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -437,7 +460,8 @@ class BuilderTest { values[bit] = true; } int offset = builder.writeListBool(values); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -473,7 +497,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -489,7 +514,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListFloat64(values); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify @@ -509,7 +535,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListFloat32(values); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -542,7 +569,8 @@ class BuilderTest { } // write the list int offset = builder.writeList([object1, object2]); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -562,7 +590,8 @@ class BuilderTest { int? str1 = builder.writeString('12345'); int? str2 = builder.writeString('ABC'); int offset = builder.writeList([str1!, str2!]); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -582,7 +611,8 @@ class BuilderTest { builder.startTable(); builder.addOffset(0, listOffset); int offset = builder.endTable(); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -598,7 +628,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -612,7 +643,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListUint16(<int>[1, 2, 60000]); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -626,7 +658,8 @@ class BuilderTest { { Builder builder = new Builder(initialSize: 0); int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]); - byteList = builder.finish(offset); + builder.finish(offset); + byteList = builder.buffer; } // read and verify BufferContext buf = new BufferContext.fromBytes(byteList); @@ -706,8 +739,8 @@ class ObjectAPITest { void test_tableStat() { final object1 = example.StatT(count: 3, id: "foo", val: 4); final fbb = Builder(); - final data = fbb.finish(object1.pack(fbb)); - final object2 = example.Stat(data).unpack(); + fbb.finish(object1.pack(fbb)); + final object2 = example.Stat(fbb.buffer).unpack(); expect(object2.count, object1.count); expect(object2.id, object1.id); expect(object2.val, object1.val); @@ -750,7 +783,8 @@ class ObjectAPITest { final fbBuilder = Builder(); final offset = monster.pack(fbBuilder); expect(offset, isNonZero); - final data = fbBuilder.finish(offset); + fbBuilder.finish(offset); + final data = fbBuilder.buffer; // TODO currently broken because of struct builder issue, see #6688 // final monster2 = example.Monster(data); // Monster (reader) @@ -770,14 +804,14 @@ class ObjectAPITest { final fbb = Builder(); final object1 = example.TypeAliasesT(v8: [1, 2, 3], vf64: [5, 6]); - final data1 = fbb.finish(object1.pack(fbb)); - final object1Read = example.TypeAliases(data1).unpack(); + fbb.finish(object1.pack(fbb)); + final object1Read = example.TypeAliases(fbb.buffer).unpack(); // overwrite the original buffer by writing to the same builder fbb.reset(); final object2 = example.TypeAliasesT(v8: [7, 8, 9], vf64: [10, 11]); - final data2 = fbb.finish(object2.pack(fbb)); - final object2Read = example.TypeAliases(data2).unpack(); + fbb.finish(object2.pack(fbb)); + final object2Read = example.TypeAliases(fbb.buffer).unpack(); // this is fine even with lazy lists: expect(object2.toString(), object2Read.toString()); diff --git a/dart/test/monster_test_my_game.example2_generated.dart b/dart/test/monster_test_my_game.example2_generated.dart index 92d7c911..60ac656a 100644 --- a/dart/test/monster_test_my_game.example2_generated.dart +++ b/dart/test/monster_test_my_game.example2_generated.dart @@ -71,6 +71,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } diff --git a/dart/test/monster_test_my_game.example_generated.dart b/dart/test/monster_test_my_game.example_generated.dart index ca4efd1c..93814a5a 100644 --- a/dart/test/monster_test_my_game.example_generated.dart +++ b/dart/test/monster_test_my_game.example_generated.dart @@ -348,7 +348,8 @@ class TestObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class TestSimpleTableWithEnum { @@ -445,7 +446,8 @@ class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class Vec3 { @@ -591,7 +593,8 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class Ability { @@ -688,7 +691,8 @@ class AbilityObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class StructOfStructs { @@ -795,7 +799,8 @@ class StructOfStructsObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class Stat { @@ -920,7 +925,8 @@ class StatObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class Referrable { @@ -1017,7 +1023,8 @@ class ReferrableObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } /// an example documentation comment: "monster object" @@ -1922,7 +1929,8 @@ class MonsterObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } class TypeAliases { @@ -2174,6 +2182,7 @@ class TypeAliasesObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } diff --git a/dart/test/monster_test_my_game_generated.dart b/dart/test/monster_test_my_game_generated.dart index 146c4017..eef9e73d 100644 --- a/dart/test/monster_test_my_game_generated.dart +++ b/dart/test/monster_test_my_game_generated.dart @@ -71,6 +71,7 @@ class InParentNamespaceObjectBuilder extends fb.ObjectBuilder { Uint8List toBytes([String? fileIdentifier]) { fb.Builder fbBuilder = new fb.Builder(); int offset = finish(fbBuilder); - return fbBuilder.finish(offset, fileIdentifier); + fbBuilder.finish(offset, fileIdentifier); + return fbBuilder.buffer; } } |