diff options
author | Ivan Dlugos <6349682+vaind@users.noreply.github.com> | 2021-07-19 20:27:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-19 11:27:01 -0700 |
commit | 65700441d3334aacbb141d29587a77876c2783e0 (patch) | |
tree | eafce79c7c7289a08e9ea146027c5e8f9de38a95 /dart | |
parent | dd5bb55cad8f75162a5a43dfb2eac8bcac3ccd55 (diff) | |
download | flatbuffers-65700441d3334aacbb141d29587a77876c2783e0.tar.gz flatbuffers-65700441d3334aacbb141d29587a77876c2783e0.tar.bz2 flatbuffers-65700441d3334aacbb141d29587a77876c2783e0.zip |
Dart - make vTable fixed size (expect the number of fields when creating) (#6735)
Diffstat (limited to 'dart')
-rw-r--r-- | dart/example/monster_my_game.sample_generated.dart | 8 | ||||
-rw-r--r-- | dart/lib/flat_buffers.dart | 48 | ||||
-rw-r--r-- | dart/test/flat_buffers_test.dart | 22 | ||||
-rw-r--r-- | dart/test/monster_test_my_game.example2_generated.dart | 4 | ||||
-rw-r--r-- | dart/test/monster_test_my_game.example_generated.dart | 30 | ||||
-rw-r--r-- | dart/test/monster_test_my_game_generated.dart | 4 |
6 files changed, 65 insertions, 51 deletions
diff --git a/dart/example/monster_my_game.sample_generated.dart b/dart/example/monster_my_game.sample_generated.dart index eae52b61..57c3d6b3 100644 --- a/dart/example/monster_my_game.sample_generated.dart +++ b/dart/example/monster_my_game.sample_generated.dart @@ -220,7 +220,7 @@ class MonsterBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(10); } int addPos(int offset) { @@ -315,7 +315,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder { final int? equippedOffset = _equipped?.getOrCreateOffset(fbBuilder); final int? pathOffset = _path == null ? null : fbBuilder.writeListOfStructs(_path!); - fbBuilder.startTable(); + fbBuilder.startTable(10); if (_pos != null) { fbBuilder.addStruct(0, _pos!.finish(fbBuilder)); } @@ -375,7 +375,7 @@ class WeaponBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(2); } int addNameOffset(int? offset) { @@ -407,7 +407,7 @@ class WeaponObjectBuilder extends fb.ObjectBuilder { @override int finish(fb.Builder fbBuilder) { final int? nameOffset = fbBuilder.writeString(_name); - fbBuilder.startTable(); + fbBuilder.startTable(2); fbBuilder.addOffset(0, nameOffset); fbBuilder.addInt16(1, _damage); return fbBuilder.endTable(); diff --git a/dart/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart index ca635feb..55b825a0 100644 --- a/dart/lib/flat_buffers.dart +++ b/dart/lib/flat_buffers.dart @@ -472,12 +472,12 @@ class Builder { } } - /// Start a new table. Must be finished with [endTable] invocation. - void startTable() { + /// Start a new table. Must be finished with [endTable] invocation. + void startTable(int numFields) { if (_currentVTable != null) { throw new StateError('Inline tables are not supported.'); } - _currentVTable = new _VTable(); + _currentVTable = new _VTable(numFields); _currentTableEndTail = _tail; } @@ -1229,8 +1229,14 @@ class _FbBoolList extends _FbList<bool> { class _VTable { static const int _metadataLength = 4; - final fieldTails = <int?>[]; - final fieldOffsets = <int>[]; + final int numFields; + + // Note: fieldOffsets start as "tail offsets" and are then transformed by + // [computeFieldOffsets()] to actual offsets when a table is finished. + final Uint32List fieldOffsets; + bool offsetsComputed = false; + + _VTable(this.numFields) : fieldOffsets = Uint32List(numFields); /// The size of the table that uses this VTable. int tableSize = 0; @@ -1241,17 +1247,20 @@ class _VTable { int get _vTableSize => numOfUint16 * _sizeofUint16; - int get numOfUint16 => 1 + 1 + fieldTails.length; + int get numOfUint16 => 1 + 1 + numFields; + @pragma('vm:prefer-inline') void addField(int field, int offset) { - while (fieldTails.length <= field) { - fieldTails.add(null); - } - fieldTails[field] = offset; + assert(!offsetsComputed); + assert(offset > 0); // it's impossible for field to start at the buffer end + assert(offset <= 4294967295); // uint32 max + fieldOffsets[field] = offset; } + @pragma('vm:prefer-inline') bool _offsetsMatch(int vt2Start, ByteData buf) { - for (int i = 0; i < fieldOffsets.length; i++) { + assert(offsetsComputed); + for (int i = 0; i < numFields; i++) { if (fieldOffsets[i] != buf.getUint16(vt2Start + _metadataLength + (2 * i), Endian.little)) { return false; @@ -1261,17 +1270,22 @@ class _VTable { } /// Fill the [fieldOffsets] field. + @pragma('vm:prefer-inline') void computeFieldOffsets(int tableTail) { - assert(fieldOffsets.isEmpty); - for (int? fieldTail in fieldTails) { - int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail; - fieldOffsets.add(fieldOffset); + assert(!offsetsComputed); + offsetsComputed = true; + for (var i = 0; i < numFields; i++) { + if (fieldOffsets[i] != 0) { + fieldOffsets[i] = tableTail - fieldOffsets[i]; + } } } /// Outputs this VTable to [buf], which is is expected to be aligned to 16-bit /// and have at least [numOfUint16] 16-bit words available. + @pragma('vm:prefer-inline') void output(ByteData buf, int bufOffset) { + assert(offsetsComputed); // VTable size. buf.setUint16(bufOffset, numOfUint16 * 2, Endian.little); bufOffset += 2; @@ -1279,8 +1293,8 @@ class _VTable { buf.setUint16(bufOffset, tableSize, Endian.little); bufOffset += 2; // Field offsets. - for (int fieldOffset in fieldOffsets) { - buf.setUint16(bufOffset, fieldOffset, Endian.little); + for (int i = 0; i < numFields; i++) { + buf.setUint16(bufOffset, fieldOffsets[i], Endian.little); bufOffset += 2; } } diff --git a/dart/test/flat_buffers_test.dart b/dart/test/flat_buffers_test.dart index 6df4b306..783f9fc0 100644 --- a/dart/test/flat_buffers_test.dart +++ b/dart/test/flat_buffers_test.dart @@ -224,15 +224,15 @@ class BuilderTest { void test_error_startTable_duringTable() { Builder builder = new Builder(); - builder.startTable(); + builder.startTable(0); expect(() { - builder.startTable(); + builder.startTable(0); }, throwsStateError); } void test_error_writeString_duringTable() { Builder builder = new Builder(); - builder.startTable(); + builder.startTable(1); expect(() { builder.writeString('12345'); }, throwsStateError); @@ -242,7 +242,7 @@ class BuilderTest { Uint8List byteList; { Builder builder = new Builder(initialSize: 0); - builder.startTable(); + builder.startTable(0); int offset = builder.endTable(); builder.finish(offset, 'Az~ΓΏ'); byteList = builder.buffer; @@ -298,7 +298,7 @@ class BuilderTest { List<int> byteList; { final builder = Builder(initialSize: 0, allocator: CustomAllocator()); - builder.startTable(); + builder.startTable(2); builder.addInt32(0, 10, 10); builder.addInt32(1, 20, 10); int offset = builder.endTable(); @@ -325,7 +325,7 @@ class BuilderTest { Uint8List byteList; { builder ??= new Builder(initialSize: 0); - builder.startTable(); + builder.startTable(3); builder.addInt32(0, 10); builder.addInt32(1, 20); builder.addInt32(2, 30); @@ -362,7 +362,7 @@ class BuilderTest { Builder builder = new Builder(initialSize: 0); int? latinStringOffset = builder.writeString(latinString); int? unicodeStringOffset = builder.writeString(unicodeString); - builder.startTable(); + builder.startTable(2); builder.addOffset(0, latinStringOffset); builder.addOffset(1, unicodeStringOffset); int offset = builder.endTable(); @@ -387,7 +387,7 @@ class BuilderTest { { builder ??= new Builder(initialSize: 0); int? stringOffset = builder.writeString('12345'); - builder.startTable(); + builder.startTable(7); builder.addBool(0, true); builder.addInt8(1, 10); builder.addInt32(2, 20); @@ -554,7 +554,7 @@ class BuilderTest { // write the object #1 int object1; { - builder.startTable(); + builder.startTable(2); builder.addInt32(0, 10); builder.addInt32(1, 20); object1 = builder.endTable(); @@ -562,7 +562,7 @@ class BuilderTest { // write the object #1 int object2; { - builder.startTable(); + builder.startTable(2); builder.addInt32(0, 100); builder.addInt32(1, 200); object2 = builder.endTable(); @@ -608,7 +608,7 @@ class BuilderTest { builder ??= new Builder(initialSize: 0); int listOffset = builder.writeList( [builder.writeString('12345')!, builder.writeString('ABC')!]); - builder.startTable(); + builder.startTable(1); builder.addOffset(0, listOffset); int offset = builder.endTable(); builder.finish(offset); diff --git a/dart/test/monster_test_my_game.example2_generated.dart b/dart/test/monster_test_my_game.example2_generated.dart index 82c3f4ba..723572c5 100644 --- a/dart/test/monster_test_my_game.example2_generated.dart +++ b/dart/test/monster_test_my_game.example2_generated.dart @@ -37,7 +37,7 @@ class Monster { class MonsterT { int pack(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(0); return fbBuilder.endTable(); } @@ -62,7 +62,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder { /// Finish building, and store into the [fbBuilder]. @override int finish(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(0); return fbBuilder.endTable(); } diff --git a/dart/test/monster_test_my_game.example_generated.dart b/dart/test/monster_test_my_game.example_generated.dart index 5d11bb71..8e0fc0b4 100644 --- a/dart/test/monster_test_my_game.example_generated.dart +++ b/dart/test/monster_test_my_game.example_generated.dart @@ -387,7 +387,7 @@ class TestSimpleTableWithEnumT { this.color = Color.Green}); int pack(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(1); fbBuilder.addUint8(0, color.value); return fbBuilder.endTable(); } @@ -412,7 +412,7 @@ class TestSimpleTableWithEnumBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(1); } int addColor(Color? color) { @@ -436,7 +436,7 @@ class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder { /// Finish building, and store into the [fbBuilder]. @override int finish(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(1); fbBuilder.addUint8(0, _color?.value); return fbBuilder.endTable(); } @@ -847,7 +847,7 @@ class StatT { int pack(fb.Builder fbBuilder) { final int? idOffset = fbBuilder.writeString(id); - fbBuilder.startTable(); + fbBuilder.startTable(3); fbBuilder.addOffset(0, idOffset); fbBuilder.addInt64(1, val); fbBuilder.addUint16(2, count); @@ -874,7 +874,7 @@ class StatBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(3); } int addIdOffset(int? offset) { @@ -913,7 +913,7 @@ class StatObjectBuilder extends fb.ObjectBuilder { @override int finish(fb.Builder fbBuilder) { final int? idOffset = fbBuilder.writeString(_id); - fbBuilder.startTable(); + fbBuilder.startTable(3); fbBuilder.addOffset(0, idOffset); fbBuilder.addInt64(1, _val); fbBuilder.addUint16(2, _count); @@ -964,7 +964,7 @@ class ReferrableT { this.id = 0}); int pack(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(1); fbBuilder.addUint64(0, id); return fbBuilder.endTable(); } @@ -989,7 +989,7 @@ class ReferrableBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(1); } int addId(int? id) { @@ -1013,7 +1013,7 @@ class ReferrableObjectBuilder extends fb.ObjectBuilder { /// Finish building, and store into the [fbBuilder]. @override int finish(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(1); fbBuilder.addUint64(0, _id); return fbBuilder.endTable(); } @@ -1341,7 +1341,7 @@ class MonsterT { : fbBuilder.writeListUint8(testrequirednestedflatbuffer!); final int? scalarKeySortedTablesOffset = scalarKeySortedTables == null ? null : fbBuilder.writeList(scalarKeySortedTables!.map((b) => b.pack(fbBuilder)).toList()); - fbBuilder.startTable(); + fbBuilder.startTable(50); if (pos != null) { fbBuilder.addStruct(0, pos!.pack(fbBuilder)); } @@ -1417,7 +1417,7 @@ class MonsterBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(50); } int addPos(int offset) { @@ -1831,7 +1831,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder { : fbBuilder.writeListUint8(_testrequirednestedflatbuffer!); final int? scalarKeySortedTablesOffset = _scalarKeySortedTables == null ? null : fbBuilder.writeList(_scalarKeySortedTables!.map((b) => b.getOrCreateOffset(fbBuilder)).toList()); - fbBuilder.startTable(); + fbBuilder.startTable(50); if (_pos != null) { fbBuilder.addStruct(0, _pos!.finish(fbBuilder)); } @@ -1979,7 +1979,7 @@ class TypeAliasesT { : fbBuilder.writeListInt8(v8!); final int? vf64Offset = vf64 == null ? null : fbBuilder.writeListFloat64(vf64!); - fbBuilder.startTable(); + fbBuilder.startTable(12); fbBuilder.addInt8(0, i8); fbBuilder.addUint8(1, u8); fbBuilder.addInt16(2, i16); @@ -2015,7 +2015,7 @@ class TypeAliasesBuilder { final fb.Builder fbBuilder; void begin() { - fbBuilder.startTable(); + fbBuilder.startTable(12); } int addI8(int? i8) { @@ -2120,7 +2120,7 @@ class TypeAliasesObjectBuilder extends fb.ObjectBuilder { : fbBuilder.writeListInt8(_v8!); final int? vf64Offset = _vf64 == null ? null : fbBuilder.writeListFloat64(_vf64!); - fbBuilder.startTable(); + fbBuilder.startTable(12); fbBuilder.addInt8(0, _i8); fbBuilder.addUint8(1, _u8); fbBuilder.addInt16(2, _i16); diff --git a/dart/test/monster_test_my_game_generated.dart b/dart/test/monster_test_my_game_generated.dart index 7f0fcda5..07618f6c 100644 --- a/dart/test/monster_test_my_game_generated.dart +++ b/dart/test/monster_test_my_game_generated.dart @@ -37,7 +37,7 @@ class InParentNamespace { class InParentNamespaceT { int pack(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(0); return fbBuilder.endTable(); } @@ -62,7 +62,7 @@ class InParentNamespaceObjectBuilder extends fb.ObjectBuilder { /// Finish building, and store into the [fbBuilder]. @override int finish(fb.Builder fbBuilder) { - fbBuilder.startTable(); + fbBuilder.startTable(0); return fbBuilder.endTable(); } |