summaryrefslogtreecommitdiff
path: root/dart
diff options
context:
space:
mode:
authorIvan Dlugos <6349682+vaind@users.noreply.github.com>2021-09-15 17:50:57 +0200
committerGitHub <noreply@github.com>2021-09-15 08:50:57 -0700
commit90baa1444b59af408e5363b284d4333d35835e8d (patch)
tree8c0fedda45c34da92dc1f64e16206d022cbba592 /dart
parent0a3b017f09db8723ab634706ae875af20686e1e3 (diff)
downloadflatbuffers-90baa1444b59af408e5363b284d4333d35835e8d.tar.gz
flatbuffers-90baa1444b59af408e5363b284d4333d35835e8d.tar.bz2
flatbuffers-90baa1444b59af408e5363b284d4333d35835e8d.zip
Dart: binary lists (typed_data) (#6839)
* Dart - add eager mode to Uint8ListReader * Dart - add Int8ListReader * Dart - use binary reader where useful * Dart - test binary list reader laziness * Dart - update generated code
Diffstat (limited to 'dart')
-rw-r--r--dart/lib/flat_buffers.dart72
-rw-r--r--dart/lib/src/reference.dart3
-rw-r--r--dart/test/flat_buffers_test.dart18
-rw-r--r--dart/test/monster_test_my_game.example_generated.dart20
4 files changed, 90 insertions, 23 deletions
diff --git a/dart/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart
index 215ee510..22bd788b 100644
--- a/dart/lib/flat_buffers.dart
+++ b/dart/lib/flat_buffers.dart
@@ -155,7 +155,8 @@ class Builder {
}
}
- /// Calculate the finished buffer size (aligned).@pragma('vm:prefer-inline')
+ /// Calculate the finished buffer size (aligned).
+ @pragma('vm:prefer-inline')
int size() => _tail + ((-_tail) & (_maxAlign - 1));
/// Add the [field] with the given boolean [value]. The field is not added if
@@ -1170,11 +1171,17 @@ class Uint16Reader extends Reader<int> {
int read(BufferContext bc, int offset) => bc._getUint16(offset);
}
-/// Reader of lists of unsigned 8-bit integer values.
-///
-/// The returned unmodifiable lists lazily read values on access.
+/// Reader of unmodifiable binary data (a list of unsigned 8-bit integers).
class Uint8ListReader extends Reader<List<int>> {
- const Uint8ListReader();
+ /// Enables lazy reading of the list
+ ///
+ /// If true, the returned unmodifiable list lazily reads bytes on access.
+ /// Therefore, the underlying buffer must not change while accessing the list.
+ ///
+ /// If false, reads the whole list immediately as an Uint8List.
+ final bool lazy;
+
+ const Uint8ListReader({this.lazy = true});
@override
@pragma('vm:prefer-inline')
@@ -1182,8 +1189,18 @@ class Uint8ListReader extends Reader<List<int>> {
@override
@pragma('vm:prefer-inline')
- List<int> read(BufferContext bc, int offset) =>
- _FbUint8List(bc, bc.derefObject(offset));
+ List<int> read(BufferContext bc, int offset) {
+ final listOffset = bc.derefObject(offset);
+ if (lazy) return _FbUint8List(bc, listOffset);
+
+ final length = bc._getUint32(listOffset);
+ final result = Uint8List(length);
+ var pos = listOffset + _sizeofUint32;
+ for (var i = 0; i < length; i++, pos++) {
+ result[i] = bc._getUint8(pos);
+ }
+ return result;
+ }
}
/// The reader of unsigned 8-bit integers.
@@ -1199,6 +1216,38 @@ class Uint8Reader extends Reader<int> {
int read(BufferContext bc, int offset) => bc._getUint8(offset);
}
+/// Reader of unmodifiable binary data (a list of signed 8-bit integers).
+class Int8ListReader extends Reader<List<int>> {
+ /// Enables lazy reading of the list
+ ///
+ /// If true, the returned unmodifiable list lazily reads bytes on access.
+ /// Therefore, the underlying buffer must not change while accessing the list.
+ ///
+ /// If false, reads the whole list immediately as an Uint8List.
+ final bool lazy;
+
+ const Int8ListReader({this.lazy = true});
+
+ @override
+ @pragma('vm:prefer-inline')
+ int get size => _sizeofUint32;
+
+ @override
+ @pragma('vm:prefer-inline')
+ List<int> read(BufferContext bc, int offset) {
+ final listOffset = bc.derefObject(offset);
+ if (lazy) return _FbUint8List(bc, listOffset);
+
+ final length = bc._getUint32(listOffset);
+ final result = Int8List(length);
+ var pos = listOffset + _sizeofUint32;
+ for (var i = 0; i < length; i++, pos++) {
+ result[i] = bc._getInt8(pos);
+ }
+ return result;
+ }
+}
+
/// The list backed by 64-bit values - Uint64 length and Float64.
class _FbFloat64List extends _FbList<double> {
_FbFloat64List(BufferContext bc, int offset) : super(bc, offset);
@@ -1286,6 +1335,15 @@ class _FbUint8List extends _FbList<int> {
int operator [](int i) => bc._getUint8(offset + 4 + i);
}
+/// List backed by 8-bit signed integers.
+class _FbInt8List extends _FbList<int> {
+ _FbInt8List(BufferContext bc, int offset) : super(bc, offset);
+
+ @override
+ @pragma('vm:prefer-inline')
+ int operator [](int i) => bc._getInt8(offset + 4 + i);
+}
+
/// List backed by 8-bit unsigned integers.
class _FbBoolList extends _FbList<bool> {
_FbBoolList(BufferContext bc, int offset) : super(bc, offset);
diff --git a/dart/lib/src/reference.dart b/dart/lib/src/reference.dart
index 89752fa0..e52d0b70 100644
--- a/dart/lib/src/reference.dart
+++ b/dart/lib/src/reference.dart
@@ -373,8 +373,7 @@ class Reference {
return null;
}
- int _diffKeys(
- List<int> input, int index, int indirectOffset, int byteWidth) {
+ int _diffKeys(List<int> input, int index, int indirectOffset, int byteWidth) {
final keyOffset = indirectOffset + index * byteWidth;
final keyIndirectOffset =
keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));
diff --git a/dart/test/flat_buffers_test.dart b/dart/test/flat_buffers_test.dart
index 55a3b6c1..b670b452 100644
--- a/dart/test/flat_buffers_test.dart
+++ b/dart/test/flat_buffers_test.dart
@@ -658,15 +658,25 @@ class BuilderTest {
List<int> byteList;
{
Builder builder = Builder(initialSize: 0);
- int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]);
+ int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A, 0xFA]);
builder.finish(offset);
byteList = builder.buffer;
}
// read and verify
BufferContext buf = BufferContext.fromBytes(byteList);
- List<int> items = const Uint8ListReader().read(buf, 0);
- expect(items, hasLength(5));
- expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
+ const buffOffset = 8; // 32-bit offset to the list, + 32-bit length
+ for (final lazy in [true, false]) {
+ List<int> items = Uint8ListReader(lazy: lazy).read(buf, 0);
+ expect(items, hasLength(6));
+ expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A, 0xFA]));
+
+ // overwrite the buffer to verify the laziness
+ buf.buffer.setUint8(buffOffset + 1, 99);
+ expect(items, orderedEquals(<int>[1, lazy ? 99 : 2, 3, 4, 0x9A, 0xFA]));
+
+ // restore the previous value for the next loop
+ buf.buffer.setUint8(buffOffset + 1, 2);
+ }
}
void test_reset() {
diff --git a/dart/test/monster_test_my_game.example_generated.dart b/dart/test/monster_test_my_game.example_generated.dart
index 69c918a2..869f1e6d 100644
--- a/dart/test/monster_test_my_game.example_generated.dart
+++ b/dart/test/monster_test_my_game.example_generated.dart
@@ -1039,7 +1039,7 @@ class Monster {
int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10);
- List<int>? get inventory => const fb.ListReader<int>(fb.Uint8Reader()).vTableGetNullable(_bc, _bcOffset, 14);
+ List<int>? get inventory => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 14);
Color get color => Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
AnyTypeId? get testType => AnyTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 18));
dynamic get test {
@@ -1056,7 +1056,7 @@ class Monster {
/// multiline too
List<Monster>? get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGetNullable(_bc, _bcOffset, 26);
Monster? get enemy => Monster.reader.vTableGetNullable(_bc, _bcOffset, 28);
- List<int>? get testnestedflatbuffer => const fb.ListReader<int>(fb.Uint8Reader()).vTableGetNullable(_bc, _bcOffset, 30);
+ List<int>? get testnestedflatbuffer => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 30);
Stat? get testempty => Stat.reader.vTableGetNullable(_bc, _bcOffset, 32);
bool get testbool => const fb.BoolReader().vTableGet(_bc, _bcOffset, 34, false);
int get testhashs32Fnv1 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 36, 0);
@@ -1073,7 +1073,7 @@ class Monster {
double get testf3 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 58, 0.0);
List<String>? get testarrayofstring2 => const fb.ListReader<String>(fb.StringReader()).vTableGetNullable(_bc, _bcOffset, 60);
List<Ability>? get testarrayofsortedstruct => const fb.ListReader<Ability>(Ability.reader).vTableGetNullable(_bc, _bcOffset, 62);
- List<int>? get flex => const fb.ListReader<int>(fb.Uint8Reader()).vTableGetNullable(_bc, _bcOffset, 64);
+ List<int>? get flex => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 64);
List<Test>? get test5 => const fb.ListReader<Test>(Test.reader).vTableGetNullable(_bc, _bcOffset, 66);
List<int>? get vectorOfLongs => const fb.ListReader<int>(fb.Int64Reader()).vTableGetNullable(_bc, _bcOffset, 68);
List<double>? get vectorOfDoubles => const fb.ListReader<double>(fb.Float64Reader()).vTableGetNullable(_bc, _bcOffset, 70);
@@ -1106,7 +1106,7 @@ class Monster {
}
List<Color>? get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGetNullable(_bc, _bcOffset, 98);
Race get signedEnum => Race.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 100, -1));
- List<int>? get testrequirednestedflatbuffer => const fb.ListReader<int>(fb.Uint8Reader()).vTableGetNullable(_bc, _bcOffset, 102);
+ List<int>? get testrequirednestedflatbuffer => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 102);
List<Stat>? get scalarKeySortedTables => const fb.ListReader<Stat>(Stat.reader).vTableGetNullable(_bc, _bcOffset, 104);
@override
@@ -1119,7 +1119,7 @@ class Monster {
mana: mana,
hp: hp,
name: name,
- inventory: const fb.ListReader<int>(fb.Uint8Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 14),
+ inventory: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 14),
color: color,
testType: testType,
test: test,
@@ -1127,7 +1127,7 @@ class Monster {
testarrayofstring: const fb.ListReader<String>(fb.StringReader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 24),
testarrayoftables: testarrayoftables?.map((e) => e.unpack()).toList(),
enemy: enemy?.unpack(),
- testnestedflatbuffer: const fb.ListReader<int>(fb.Uint8Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 30),
+ testnestedflatbuffer: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 30),
testempty: testempty?.unpack(),
testbool: testbool,
testhashs32Fnv1: testhashs32Fnv1,
@@ -1144,7 +1144,7 @@ class Monster {
testf3: testf3,
testarrayofstring2: const fb.ListReader<String>(fb.StringReader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 60),
testarrayofsortedstruct: testarrayofsortedstruct?.map((e) => e.unpack()).toList(),
- flex: const fb.ListReader<int>(fb.Uint8Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 64),
+ flex: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 64),
test5: test5?.map((e) => e.unpack()).toList(),
vectorOfLongs: const fb.ListReader<int>(fb.Int64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 68),
vectorOfDoubles: const fb.ListReader<double>(fb.Float64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 70),
@@ -1163,7 +1163,7 @@ class Monster {
anyAmbiguous: anyAmbiguous,
vectorOfEnums: const fb.ListReader<Color>(Color.reader, lazy: false).vTableGetNullable(_bc, _bcOffset, 98),
signedEnum: signedEnum,
- testrequirednestedflatbuffer: const fb.ListReader<int>(fb.Uint8Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 102),
+ testrequirednestedflatbuffer: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 102),
scalarKeySortedTables: scalarKeySortedTables?.map((e) => e.unpack()).toList());
static int pack(fb.Builder fbBuilder, MonsterT? object) {
@@ -1914,7 +1914,7 @@ class TypeAliases {
int get u64 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 18, 0);
double get f32 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 20, 0.0);
double get f64 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 22, 0.0);
- List<int>? get v8 => const fb.ListReader<int>(fb.Int8Reader()).vTableGetNullable(_bc, _bcOffset, 24);
+ List<int>? get v8 => const fb.Int8ListReader().vTableGetNullable(_bc, _bcOffset, 24);
List<double>? get vf64 => const fb.ListReader<double>(fb.Float64Reader()).vTableGetNullable(_bc, _bcOffset, 26);
@override
@@ -1933,7 +1933,7 @@ class TypeAliases {
u64: u64,
f32: f32,
f64: f64,
- v8: const fb.ListReader<int>(fb.Int8Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 24),
+ v8: const fb.Int8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 24),
vf64: const fb.ListReader<double>(fb.Float64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 26));
static int pack(fb.Builder fbBuilder, TypeAliasesT? object) {