mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-01 22:03:57 +00:00
Dart - make vTable fixed size (expect the number of fields when creating) (#6735)
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user