summaryrefslogtreecommitdiff
path: root/dart
diff options
context:
space:
mode:
authorIvan Dlugos <6349682+vaind@users.noreply.github.com>2021-07-19 20:27:01 +0200
committerGitHub <noreply@github.com>2021-07-19 11:27:01 -0700
commit65700441d3334aacbb141d29587a77876c2783e0 (patch)
treeeafce79c7c7289a08e9ea146027c5e8f9de38a95 /dart
parentdd5bb55cad8f75162a5a43dfb2eac8bcac3ccd55 (diff)
downloadflatbuffers-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.dart8
-rw-r--r--dart/lib/flat_buffers.dart48
-rw-r--r--dart/test/flat_buffers_test.dart22
-rw-r--r--dart/test/monster_test_my_game.example2_generated.dart4
-rw-r--r--dart/test/monster_test_my_game.example_generated.dart30
-rw-r--r--dart/test/monster_test_my_game_generated.dart4
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();
}