Dart null safety (#6696)

* Dart null-safety - prepare migration annotations in library files

* Dart null-safety - apply migration

* Dart null-safety - update flatc to generate valid code

* Dart null-safety - fix flatc generated code and adjust tests

* Dart null-safety - update example and the generated code in the tests folder

* Dart null safety - minor review changes

* Dart - apply `dartfmt -w .`
This commit is contained in:
Ivan Dlugos
2021-06-22 17:54:57 +02:00
committed by GitHub
parent 71d43f3be9
commit a6ee335574
23 changed files with 3352 additions and 2649 deletions

View File

@@ -28,13 +28,17 @@ typedef void StructBuilder();
class BufferContext {
final ByteData _buffer;
ByteData get buffer => _buffer;
/// Create from a FlatBuffer represented by a list of bytes (uint8).
factory BufferContext.fromBytes(List<int> byteList) {
Uint8List uint8List = _asUint8List(byteList);
ByteData buf = new ByteData.view(uint8List.buffer, uint8List.offsetInBytes);
return new BufferContext._(buf);
return BufferContext(buf);
}
BufferContext._(this._buffer);
/// Create from a FlatBuffer represented by ByteData.
BufferContext(this._buffer);
int derefObject(int offset) {
return offset + _getUint32(offset);
@@ -43,31 +47,23 @@ class BufferContext {
Uint8List _asUint8LIst(int offset, int length) =>
_buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);
double _getFloat64(int offset) =>
_buffer.getFloat64(offset, Endian.little);
double _getFloat64(int offset) => _buffer.getFloat64(offset, Endian.little);
double _getFloat32(int offset) =>
_buffer.getFloat32(offset, Endian.little);
double _getFloat32(int offset) => _buffer.getFloat32(offset, Endian.little);
int _getInt64(int offset) =>
_buffer.getInt64(offset, Endian.little);
int _getInt64(int offset) => _buffer.getInt64(offset, Endian.little);
int _getInt32(int offset) =>
_buffer.getInt32(offset, Endian.little);
int _getInt32(int offset) => _buffer.getInt32(offset, Endian.little);
int _getInt16(int offset) =>
_buffer.getInt16(offset, Endian.little);
int _getInt16(int offset) => _buffer.getInt16(offset, Endian.little);
int _getInt8(int offset) => _buffer.getInt8(offset);
int _getUint64(int offset) =>
_buffer.getUint64(offset, Endian.little);
int _getUint64(int offset) => _buffer.getUint64(offset, Endian.little);
int _getUint32(int offset) =>
_buffer.getUint32(offset, Endian.little);
int _getUint32(int offset) => _buffer.getUint32(offset, Endian.little);
int _getUint16(int offset) =>
_buffer.getUint16(offset, Endian.little);
int _getUint16(int offset) => _buffer.getUint16(offset, Endian.little);
int _getUint8(int offset) => _buffer.getUint8(offset);
@@ -84,7 +80,7 @@ class BufferContext {
/// Class implemented by typed builders generated by flatc.
abstract class ObjectBuilder {
int _firstOffset;
int? _firstOffset;
/// Can be used to write the data represented by this builder to the [Builder]
/// and reuse the offset created in multiple tables.
@@ -94,7 +90,7 @@ abstract class ObjectBuilder {
/// first call to this method.
int getOrCreateOffset(Builder fbBuilder) {
_firstOffset ??= finish(fbBuilder);
return _firstOffset;
return _firstOffset!;
}
/// Writes the data in this helper to the [Builder].
@@ -110,8 +106,8 @@ class Builder {
final int initialSize;
/// The list of existing VTable(s).
//final List<_VTable> _vTables = <_VTable>[];
final List<int> _vTables = <int>[];
final List<int> _vTables = List<int>.filled(16, 0, growable: true)
..length = 0;
ByteData _buf;
@@ -125,16 +121,16 @@ class Builder {
int _tail = 0;
/// The location of the end of the current table, measured in bytes from the
/// end of [_buf], or `null` if a table is not currently being built.
int _currentTableEndTail;
/// end of [_buf].
int _currentTableEndTail = 0;
_VTable _currentVTable;
_VTable? _currentVTable;
/// Map containing all strings that have been written so far. This allows us
/// to avoid duplicating strings.
///
/// Allocated only if `internStrings` is set to true on the constructor.
Map<String, int> _strings;
Map<String, int>? _strings;
/// Creates a new FlatBuffers Builder.
///
@@ -155,7 +151,7 @@ class Builder {
/// Add the [field] with the given boolean [value]. The field is not added if
/// the [value] is equal to [def]. Booleans are stored as 8-bit fields with
/// `0` for `false` and `1` for `true`.
void addBool(int field, bool value, [bool def]) {
void addBool(int field, bool? value, [bool? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofUint8, 1);
@@ -166,7 +162,7 @@ class Builder {
/// Add the [field] with the given 32-bit signed integer [value]. The field is
/// not added if the [value] is equal to [def].
void addInt32(int field, int value, [int def]) {
void addInt32(int field, int? value, [int? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofInt32, 1);
@@ -177,7 +173,7 @@ class Builder {
/// Add the [field] with the given 32-bit signed integer [value]. The field is
/// not added if the [value] is equal to [def].
void addInt16(int field, int value, [int def]) {
void addInt16(int field, int? value, [int? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofInt16, 1);
@@ -188,7 +184,7 @@ class Builder {
/// Add the [field] with the given 8-bit signed integer [value]. The field is
/// not added if the [value] is equal to [def].
void addInt8(int field, int value, [int def]) {
void addInt8(int field, int? value, [int? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofInt8, 1);
@@ -200,11 +196,11 @@ class Builder {
void addStruct(int field, int offset) {
_ensureCurrentVTable();
_trackField(field);
_currentVTable.addField(field, offset);
_currentVTable!.addField(field, offset);
}
/// Add the [field] referencing an object with the given [offset].
void addOffset(int field, int offset) {
void addOffset(int field, int? offset) {
_ensureCurrentVTable();
if (offset != null) {
_prepare(_sizeofUint32, 1);
@@ -215,7 +211,7 @@ class Builder {
/// Add the [field] with the given 32-bit unsigned integer [value]. The field
/// is not added if the [value] is equal to [def].
void addUint32(int field, int value, [int def]) {
void addUint32(int field, int? value, [int? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofUint32, 1);
@@ -226,7 +222,7 @@ class Builder {
/// Add the [field] with the given 32-bit unsigned integer [value]. The field
/// is not added if the [value] is equal to [def].
void addUint16(int field, int value, [int def]) {
void addUint16(int field, int? value, [int? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofUint16, 1);
@@ -237,7 +233,7 @@ class Builder {
/// Add the [field] with the given 8-bit unsigned integer [value]. The field
/// is not added if the [value] is equal to [def].
void addUint8(int field, int value, [int def]) {
void addUint8(int field, int? value, [int? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofUint8, 1);
@@ -248,7 +244,7 @@ class Builder {
/// Add the [field] with the given 32-bit float [value]. The field
/// is not added if the [value] is equal to [def].
void addFloat32(int field, double value, [double def]) {
void addFloat32(int field, double? value, [double? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofFloat32, 1);
@@ -259,7 +255,7 @@ class Builder {
/// Add the [field] with the given 64-bit double [value]. The field
/// is not added if the [value] is equal to [def].
void addFloat64(int field, double value, [double def]) {
void addFloat64(int field, double? value, [double? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofFloat64, 1);
@@ -270,7 +266,7 @@ class Builder {
/// Add the [field] with the given 64-bit unsigned integer [value]. The field
/// is not added if the [value] is equal to [def].
void addUint64(int field, int value, [double def]) {
void addUint64(int field, int? value, [double? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofUint64, 1);
@@ -281,7 +277,7 @@ class Builder {
/// Add the [field] with the given 64-bit unsigned integer [value]. The field
/// is not added if the [value] is equal to [def].
void addInt64(int field, int value, [double def]) {
void addInt64(int field, int? value, [double? def]) {
_ensureCurrentVTable();
if (value != null && value != def) {
_prepare(_sizeofInt64, 1);
@@ -299,11 +295,12 @@ class Builder {
_prepare(_sizeofInt32, 1);
int tableTail = _tail;
// Prepare the size of the current table.
_currentVTable.tableSize = tableTail - _currentTableEndTail;
final currentVTable = _currentVTable!;
currentVTable.tableSize = tableTail - _currentTableEndTail;
// Prepare the VTable to use for the current table.
int vTableTail;
int? vTableTail;
{
_currentVTable.computeFieldOffsets(tableTail);
currentVTable.computeFieldOffsets(tableTail);
// Try to find an existing compatible VTable.
// Search backward - more likely to have recently used one
for (int i = _vTables.length - 1; i >= 0; i--) {
@@ -311,19 +308,19 @@ class Builder {
final int vt2Start = _buf.lengthInBytes - vt2Offset;
final int vt2Size = _buf.getUint16(vt2Start, Endian.little);
if (_currentVTable._vTableSize == vt2Size &&
_currentVTable._offsetsMatch(vt2Start, _buf)) {
if (currentVTable._vTableSize == vt2Size &&
currentVTable._offsetsMatch(vt2Start, _buf)) {
vTableTail = vt2Offset;
break;
}
}
// Write a new VTable.
if (vTableTail == null) {
_prepare(_sizeofUint16, _currentVTable.numOfUint16);
_prepare(_sizeofUint16, _currentVTable!.numOfUint16);
vTableTail = _tail;
_currentVTable.tail = vTableTail;
_currentVTable.output(_buf, _buf.lengthInBytes - _tail);
_vTables.add(_currentVTable.tail);
currentVTable.tail = vTableTail;
currentVTable.output(_buf, _buf.lengthInBytes - _tail);
_vTables.add(currentVTable.tail);
}
}
// Set the VTable offset.
@@ -346,7 +343,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]) {
Uint8List finish(int offset, [String? fileIdentifier]) {
_prepare(max(_sizeofUint32, _maxAlign), fileIdentifier == null ? 1 : 2);
final finishedSize = size();
_setUint32AtTail(_buf, finishedSize, finishedSize - offset);
@@ -444,7 +441,7 @@ class Builder {
_maxAlign = 1;
_tail = 0;
_currentVTable = null;
_vTables.clear();
_vTables.length = 0;
if (_strings != null) {
_strings = new Map<String, int>();
}
@@ -613,7 +610,7 @@ class Builder {
/// Write the given list of bools as unsigend 8-bit integer [values].
int writeListBool(List<bool> values) {
return writeListUint8(values?.map((b) => b ? 1 : 0)?.toList());
return writeListUint8(values.map((b) => b ? 1 : 0).toList());
}
/// Write the given list of signed 8-bit integer [values].
@@ -648,11 +645,11 @@ class Builder {
/// Write the given string [value] and return its offset, or `null` if
/// the [value] is `null`.
int writeString(String value) {
int? writeString(String? value) {
_ensureNoVTable();
if (value != null) {
if (_strings != null) {
return _strings.putIfAbsent(value, () => _writeString(value));
return _strings!.putIfAbsent(value, () => _writeString(value));
} else {
return _writeString(value);
}
@@ -732,7 +729,7 @@ class Builder {
/// Record the offset of the given [field].
void _trackField(int field) {
_currentVTable.addField(field, _tail);
_currentVTable!.addField(field, _tail);
}
static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
@@ -848,6 +845,7 @@ class Float32Reader extends Reader<double> {
class Int64Reader extends Reader<int> {
const Int64Reader() : super();
@override
int get size => _sizeofInt64;
@@ -915,19 +913,23 @@ abstract class Reader<T> {
T read(BufferContext bc, int offset);
/// Read the value of the given [field] in the given [object].
T vTableGet(BufferContext object, int offset, int field, [T defaultValue]) {
T vTableGet(BufferContext object, int offset, int field, T defaultValue) {
int fieldOffset = _vTableFieldOffset(object, offset, field);
return fieldOffset == 0 ? defaultValue : read(object, offset + fieldOffset);
}
/// Read the value of the given [field] in the given [object].
T? vTableGetNullable(BufferContext object, int offset, int field) {
int fieldOffset = _vTableFieldOffset(object, offset, field);
return fieldOffset == 0 ? null : read(object, offset + fieldOffset);
}
int _vTableFieldOffset(BufferContext object, int offset, int field) {
int vTableSOffset = object._getInt32(offset);
int vTableOffset = offset - vTableSOffset;
int vTableSize = object._getUint16(vTableOffset);
int vTableFieldOffset = field;
if (vTableFieldOffset < vTableSize) {
int fieldOffsetInObject =
object._getUint16(vTableOffset + vTableFieldOffset);
if (fieldOffsetInObject != 0) {
return read(object, offset + fieldOffsetInObject);
}
}
return defaultValue;
if (field >= vTableSize) return 0;
return object._getUint16(vTableOffset + field);
}
}
@@ -1101,20 +1103,20 @@ class _FbFloat32List extends _FbList<double> {
class _FbGenericList<E> extends _FbList<E> {
final Reader<E> elementReader;
List<E> _items;
List<E?>? _items;
_FbGenericList(this.elementReader, BufferContext bp, int offset)
: super(bp, offset);
@override
E operator [](int i) {
_items ??= new List<E>(length);
E item = _items[i];
_items ??= List<E?>.filled(length, null);
E? item = _items![i];
if (item == null) {
item = elementReader.read(bc, offset + 4 + elementReader.size * i);
_items[i] = item;
_items![i] = item;
}
return item;
return item!;
}
}
@@ -1122,14 +1124,14 @@ class _FbGenericList<E> extends _FbList<E> {
abstract class _FbList<E> extends Object with ListMixin<E> implements List<E> {
final BufferContext bc;
final int offset;
int _length;
int? _length;
_FbList(this.bc, this.offset);
@override
int get length {
_length ??= bc._getUint32(offset);
return _length;
return _length!;
}
@override
@@ -1185,15 +1187,15 @@ class _FbBoolList extends _FbList<bool> {
class _VTable {
static const int _metadataLength = 4;
final List<int> fieldTails = <int>[];
final List<int> fieldOffsets = <int>[];
final fieldTails = <int?>[];
final fieldOffsets = <int>[];
/// The size of the table that uses this VTable.
int tableSize;
int tableSize = 0;
/// The tail of this VTable. It is used to share the same VTable between
/// The tail of this VTable. It is used to share the same VTable between
/// multiple tables of identical structure.
int tail;
int tail = 0;
int get _vTableSize => numOfUint16 * _sizeofUint16;
@@ -1209,8 +1211,7 @@ class _VTable {
bool _offsetsMatch(int vt2Start, ByteData buf) {
for (int i = 0; i < fieldOffsets.length; i++) {
if (fieldOffsets[i] !=
buf.getUint16(
vt2Start + _metadataLength + (2 * i), Endian.little)) {
buf.getUint16(vt2Start + _metadataLength + (2 * i), Endian.little)) {
return false;
}
}
@@ -1220,7 +1221,7 @@ class _VTable {
/// Fill the [fieldOffsets] field.
void computeFieldOffsets(int tableTail) {
assert(fieldOffsets.isEmpty);
for (int fieldTail in fieldTails) {
for (int? fieldTail in fieldTails) {
int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail;
fieldOffsets.add(fieldOffset);
}

View File

@@ -6,37 +6,26 @@ import 'types.dart';
/// The main builder class for creation of a FlexBuffer.
class Builder {
ByteData _buffer;
List<_StackValue> _stack;
List<_StackPointer> _stackPointers;
int _offset;
bool _finished;
Map<String, _StackValue> _stringCache;
Map<String, _StackValue> _keyCache;
Map<_KeysHash, _StackValue> _keyVectorCache;
Map<int, _StackValue> _indirectIntCache;
Map<double, _StackValue> _indirectDoubleCache;
List<_StackValue> _stack = [];
List<_StackPointer> _stackPointers = [];
int _offset = 0;
bool _finished = false;
Map<String, _StackValue> _stringCache = {};
Map<String, _StackValue> _keyCache = {};
Map<_KeysHash, _StackValue> _keyVectorCache = {};
Map<int, _StackValue> _indirectIntCache = {};
Map<double, _StackValue> _indirectDoubleCache = {};
/// Instantiate the builder if you intent to gradually build up the buffer by calling
/// add... methods and calling [finish] to receive the the resulting byte array.
///
/// The default size of internal buffer is set to 2048. Provide a different value in order to avoid buffer copies.
Builder({int size = 2048}) {
_buffer = ByteData(size);
_stack = [];
_stackPointers = [];
_offset = 0;
_finished = false;
_stringCache = {};
_keyCache = {};
_keyVectorCache = {};
_indirectIntCache = {};
_indirectDoubleCache = {};
}
Builder({int size = 2048}) : _buffer = ByteData(size) {}
/// Use this method in order to turn an object into a FlexBuffer directly.
///
/// Use the manual instantiation of the [Builder] and gradual addition of values, if performance is more important than convenience.
static ByteBuffer buildFromObject(Object value) {
static ByteBuffer buildFromObject(Object? value) {
final builder = Builder();
builder._add(value);
final buffer = builder.finish();
@@ -45,7 +34,7 @@ class Builder {
return byteData.buffer;
}
void _add(Object value) {
void _add(Object? value) {
if (value == null) {
addNull();
} else if (value is bool) {
@@ -106,7 +95,7 @@ class Builder {
void addString(String value) {
_integrityCheckOnValueAddition();
if (_stringCache.containsKey(value)) {
_stack.add(_stringCache[value]);
_stack.add(_stringCache[value]!);
return;
}
final utf8String = utf8.encode(value);
@@ -118,7 +107,8 @@ class Builder {
final newOffset = _newOffset(length + 1);
_pushBuffer(utf8String);
_offset = newOffset;
final stackValue = _StackValue.WithOffset(stringOffset, ValueType.String, bitWidth);
final stackValue =
_StackValue.WithOffset(stringOffset, ValueType.String, bitWidth);
_stack.add(stackValue);
_stringCache[value] = stackValue;
}
@@ -129,7 +119,7 @@ class Builder {
void addKey(String value) {
_integrityCheckOnKeyAddition();
if (_keyCache.containsKey(value)) {
_stack.add(_keyCache[value]);
_stack.add(_keyCache[value]!);
return;
}
final utf8String = utf8.encode(value);
@@ -138,7 +128,8 @@ class Builder {
final newOffset = _newOffset(length + 1);
_pushBuffer(utf8String);
_offset = newOffset;
final stackValue = _StackValue.WithOffset(keyOffset, ValueType.Key, BitWidth.width8);
final stackValue =
_StackValue.WithOffset(keyOffset, ValueType.Key, BitWidth.width8);
_stack.add(stackValue);
_keyCache[value] = stackValue;
}
@@ -156,7 +147,8 @@ class Builder {
final newOffset = _newOffset(length);
_pushBuffer(value.asUint8List());
_offset = newOffset;
final stackValue = _StackValue.WithOffset(blobOffset, ValueType.Blob, bitWidth);
final stackValue =
_StackValue.WithOffset(blobOffset, ValueType.Blob, bitWidth);
_stack.add(stackValue);
}
@@ -169,7 +161,7 @@ class Builder {
void addIntIndirectly(int value, {bool cache = false}) {
_integrityCheckOnValueAddition();
if (_indirectIntCache.containsKey(value)) {
_stack.add(_indirectIntCache[value]);
_stack.add(_indirectIntCache[value]!);
return;
}
final stackValue = _StackValue.WithInt(value);
@@ -177,7 +169,8 @@ class Builder {
final newOffset = _newOffset(byteWidth);
final valueOffset = _offset;
_pushBuffer(stackValue.asU8List(stackValue.width));
final stackOffset = _StackValue.WithOffset(valueOffset, ValueType.IndirectInt, stackValue.width);
final stackOffset = _StackValue.WithOffset(
valueOffset, ValueType.IndirectInt, stackValue.width);
_stack.add(stackOffset);
_offset = newOffset;
if (cache) {
@@ -193,7 +186,7 @@ class Builder {
void addDoubleIndirectly(double value, {bool cache = false}) {
_integrityCheckOnValueAddition();
if (cache && _indirectDoubleCache.containsKey(value)) {
_stack.add(_indirectDoubleCache[value]);
_stack.add(_indirectDoubleCache[value]!);
return;
}
final stackValue = _StackValue.WithDouble(value);
@@ -201,7 +194,8 @@ class Builder {
final newOffset = _newOffset(byteWidth);
final valueOffset = _offset;
_pushBuffer(stackValue.asU8List(stackValue.width));
final stackOffset = _StackValue.WithOffset(valueOffset, ValueType.IndirectFloat, stackValue.width);
final stackOffset = _StackValue.WithOffset(
valueOffset, ValueType.IndirectFloat, stackValue.width);
_stack.add(stackOffset);
_offset = newOffset;
if (cache) {
@@ -258,8 +252,10 @@ class Builder {
tmp._offset = _offset;
tmp._stack = List.from(_stack);
tmp._stackPointers = List.from(_stackPointers);
tmp._buffer.buffer.asUint8List().setAll(0, _buffer.buffer.asUint8List(0, _offset));
for (var i = 0; i < tmp._stackPointers.length; i++){
tmp._buffer.buffer
.asUint8List()
.setAll(0, _buffer.buffer.asUint8List(0, _offset));
for (var i = 0; i < tmp._stackPointers.length; i++) {
tmp.end();
}
final buffer = tmp.finish();
@@ -267,14 +263,15 @@ class Builder {
bd.buffer.asUint8List().setAll(0, buffer);
return bd.buffer;
}
void _integrityCheckOnValueAddition() {
if (_finished) {
throw StateError('Adding values after finish is prohibited');
}
if (_stackPointers.isNotEmpty && _stackPointers.last.isVector == false) {
if (_stack.last.type != ValueType.Key) {
throw StateError('Adding value to a map before adding a key is prohibited');
throw StateError(
'Adding value to a map before adding a key is prohibited');
}
}
}
@@ -290,7 +287,8 @@ class Builder {
void _finish() {
if (_stack.length != 1) {
throw StateError('Stack has to be exactly 1, but is ${_stack.length}. You have to end all started vectors and maps, before calling [finish]');
throw StateError(
'Stack has to be exactly 1, but is ${_stack.length}. You have to end all started vectors and maps, before calling [finish]');
}
final value = _stack[0];
final byteWidth = _align(value.elementWidth(_offset, 0));
@@ -299,8 +297,9 @@ class Builder {
_writeUInt(byteWidth, 1);
_finished = true;
}
_StackValue _createVector(int start, int vecLength, int step, [_StackValue keys]) {
_StackValue _createVector(int start, int vecLength, int step,
[_StackValue? keys]) {
var bitWidth = BitWidthUtil.uwidth(vecLength);
var prefixElements = 1;
if (keys != null) {
@@ -327,7 +326,9 @@ class Builder {
}
}
final byteWidth = _align(bitWidth);
final fix = typed & ValueTypeUtils.isNumber(vectorType) && vecLength >= 2 && vecLength <= 4;
final fix = typed & ValueTypeUtils.isNumber(vectorType) &&
vecLength >= 2 &&
vecLength <= 4;
if (keys != null) {
_writeStackValue(keys, byteWidth);
_writeUInt(1 << keys.width.index, byteWidth);
@@ -348,7 +349,8 @@ class Builder {
return _StackValue.WithOffset(vecOffset, ValueType.Map, bitWidth);
}
if (typed) {
final vType = ValueTypeUtils.toTypedVector(vectorType, fix ? vecLength : 0);
final vType =
ValueTypeUtils.toTypedVector(vectorType, fix ? vecLength : 0);
return _StackValue.WithOffset(vecOffset, vType, bitWidth);
}
return _StackValue.WithOffset(vecOffset, ValueType.Vector, bitWidth);
@@ -363,12 +365,13 @@ class Builder {
void _sortKeysAndEndMap(_StackPointer pointer) {
if (((_stack.length - pointer.stackPosition) & 1) == 1) {
throw StateError('The stack needs to hold key value pairs (even number of elements). Check if you combined [addKey] with add... method calls properly.');
throw StateError(
'The stack needs to hold key value pairs (even number of elements). Check if you combined [addKey] with add... method calls properly.');
}
var sorted = true;
for (var i = pointer.stackPosition; i < _stack.length - 2; i += 2) {
if (_shouldFlip(_stack[i], _stack[i+2])) {
if (_shouldFlip(_stack[i], _stack[i + 2])) {
sorted = false;
break;
}
@@ -394,12 +397,12 @@ class Builder {
}
_endMap(pointer);
}
void _endMap(_StackPointer pointer) {
final vecLength = (_stack.length - pointer.stackPosition) >> 1;
final offsets = <int>[];
for (var i = pointer.stackPosition; i < _stack.length; i += 2) {
offsets.add(_stack[i].offset);
offsets.add(_stack[i].offset!);
}
final keysHash = _KeysHash(offsets);
var keysStackValue;
@@ -409,21 +412,23 @@ class Builder {
keysStackValue = _createVector(pointer.stackPosition, vecLength, 2);
_keyVectorCache[keysHash] = keysStackValue;
}
final vec = _createVector(pointer.stackPosition + 1, vecLength, 2, keysStackValue);
final vec =
_createVector(pointer.stackPosition + 1, vecLength, 2, keysStackValue);
_stack.removeRange(pointer.stackPosition, _stack.length);
_stack.add(vec);
}
bool _shouldFlip(_StackValue v1, _StackValue v2) {
if (v1.type != ValueType.Key || v2.type != ValueType.Key) {
throw StateError('Stack values are not keys $v1 | $v2. Check if you combined [addKey] with add... method calls properly.');
throw StateError(
'Stack values are not keys $v1 | $v2. Check if you combined [addKey] with add... method calls properly.');
}
var c1, c2;
var index = 0;
do {
c1 = _buffer.getUint8(v1.offset + index);
c2 = _buffer.getUint8(v2.offset + index);
c1 = _buffer.getUint8(v1.offset! + index);
c2 = _buffer.getUint8(v2.offset! + index);
if (c2 < c1) return true;
if (c1 < c2) return false;
index += 1;
@@ -440,11 +445,12 @@ class Builder {
void _writeStackValue(_StackValue value, int byteWidth) {
final newOffset = _newOffset(byteWidth);
if (value.isOffset) {
final relativeOffset = _offset - value.offset;
final relativeOffset = _offset - value.offset!;
if (byteWidth == 8 || relativeOffset < (1 << (byteWidth * 8))) {
_writeUInt(relativeOffset, byteWidth);
} else {
throw StateError('Unexpected size $byteWidth. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new');
throw StateError(
'Unexpected size $byteWidth. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new');
}
} else {
_pushBuffer(value.asU8List(BitWidthUtil.fromByteWidth(byteWidth)));
@@ -467,16 +473,13 @@ class Builder {
}
if (prevSize < size) {
final newBuf = ByteData(size);
newBuf.buffer
.asUint8List()
.setAll(0, _buffer.buffer.asUint8List());
newBuf.buffer.asUint8List().setAll(0, _buffer.buffer.asUint8List());
}
return newOffset;
}
void _pushInt(int value, BitWidth width) {
switch (width) {
case BitWidth.width8:
_buffer.setInt8(_offset, value);
break;
@@ -494,7 +497,6 @@ class Builder {
void _pushUInt(int value, BitWidth width) {
switch (width) {
case BitWidth.width8:
_buffer.setUint8(_offset, value);
break;
@@ -516,37 +518,39 @@ class Builder {
}
class _StackValue {
Object _value;
int _offset;
late Object _value;
int? _offset;
ValueType _type;
BitWidth _width;
_StackValue.WithNull() {
_type = ValueType.Null;
_width = BitWidth.width8;
}
_StackValue.WithInt(int value) {
_type = value != null ? ValueType.Int : ValueType.Null;
_width = BitWidthUtil.width(value);
_value = value;
}
_StackValue.WithBool(bool value) {
_type = value != null ? ValueType.Bool : ValueType.Null;
_width = BitWidth.width8;
_value = value;
}
_StackValue.WithDouble(double value) {
_type = value != null ? ValueType.Float : ValueType.Null;
_width = BitWidthUtil.width(value);
_value = value;
}
_StackValue.WithOffset(int value, ValueType type, BitWidth width) {
_offset = value;
_type = type;
_width = width;
}
_StackValue.WithNull()
: _type = ValueType.Null,
_width = BitWidth.width8 {}
_StackValue.WithInt(int value)
: _type = ValueType.Int,
_width = BitWidthUtil.width(value),
_value = value {}
_StackValue.WithBool(bool value)
: _type = ValueType.Bool,
_width = BitWidth.width8,
_value = value {}
_StackValue.WithDouble(double value)
: _type = ValueType.Float,
_width = BitWidthUtil.width(value),
_value = value {}
_StackValue.WithOffset(int value, ValueType type, BitWidth width)
: _offset = value,
_type = type,
_width = width {}
BitWidth storedWidth({BitWidth width = BitWidth.width8}) {
return ValueTypeUtils.isInline(_type) ? BitWidthUtil.max(_width, width) : _width;
return ValueTypeUtils.isInline(_type)
? BitWidthUtil.max(_width, width)
: _width;
}
int storedPackedType({BitWidth width = BitWidth.width8}) {
@@ -555,16 +559,18 @@ class _StackValue {
BitWidth elementWidth(int size, int index) {
if (ValueTypeUtils.isInline(_type)) return _width;
for(var i = 0; i < 4; i++) {
final offset = offsetLoc - _offset!;
for (var i = 0; i < 4; i++) {
final width = 1 << i;
final offsetLoc = size + BitWidthUtil.paddingSize(size, width) + index * width;
final offset = offsetLoc - _offset;
final offsetLoc =
size + BitWidthUtil.paddingSize(size, width) + index * width;
final bitWidth = BitWidthUtil.uwidth(offset);
if (1 << bitWidth.index == width) {
return bitWidth;
}
}
throw StateError('Element is of unknown. Size: $size at index: $index. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new');
throw StateError(
'Element is of unknown. Size: $size at index: $index. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new');
}
List<int> asU8List(BitWidth width) {
@@ -572,30 +578,30 @@ class _StackValue {
if (_type == ValueType.Float) {
if (width == BitWidth.width32) {
final result = ByteData(4);
result.setFloat32(0, _value, Endian.little);
result.setFloat32(0, _value as double, Endian.little);
return result.buffer.asUint8List();
} else {
final result = ByteData(8);
result.setFloat64(0, _value, Endian.little);
result.setFloat64(0, _value as double, Endian.little);
return result.buffer.asUint8List();
}
} else {
switch(width) {
switch (width) {
case BitWidth.width8:
final result = ByteData(1);
result.setInt8(0, _value);
result.setInt8(0, _value as int);
return result.buffer.asUint8List();
case BitWidth.width16:
final result = ByteData(2);
result.setInt16(0, _value, Endian.little);
result.setInt16(0, _value as int, Endian.little);
return result.buffer.asUint8List();
case BitWidth.width32:
final result = ByteData(4);
result.setInt32(0, _value, Endian.little);
result.setInt32(0, _value as int, Endian.little);
return result.buffer.asUint8List();
case BitWidth.width64:
final result = ByteData(8);
result.setInt64(0, _value, Endian.little);
result.setInt64(0, _value as int, Endian.little);
return result.buffer.asUint8List();
}
}
@@ -607,11 +613,12 @@ class _StackValue {
}
if (_type == ValueType.Bool) {
final result = ByteData(1);
result.setInt8(0, _value ? 1 : 0);
result.setInt8(0, _value as bool ? 1 : 0);
return result.buffer.asUint8List();
}
throw StateError('Unexpected type: $_type. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new');
throw StateError(
'Unexpected type: $_type. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new');
}
ValueType get type {
@@ -625,7 +632,8 @@ class _StackValue {
bool get isOffset {
return !ValueTypeUtils.isInline(_type);
}
int get offset => _offset;
int? get offset => _offset;
bool get isFloat32 {
return _type == ValueType.Float && _width == BitWidth.width32;

View File

@@ -11,14 +11,15 @@ class Reference {
final int _offset;
final BitWidth _parentWidth;
final String _path;
int _byteWidth;
ValueType _valueType;
int _length;
final int _byteWidth;
final ValueType _valueType;
int? _length;
Reference._(this._buffer, this._offset, this._parentWidth, int packedType, this._path) {
_byteWidth = 1 << (packedType & 3);
_valueType = ValueTypeUtils.fromInt(packedType >> 2);
}
Reference._(
this._buffer, this._offset, this._parentWidth, int packedType, this._path,
[int? byteWidth, ValueType? valueType])
: _byteWidth = byteWidth ?? 1 << (packedType & 3),
_valueType = valueType ?? ValueTypeUtils.fromInt(packedType >> 2) {}
/// Use this method to access the root value of a FlexBuffer.
static Reference fromBuffer(ByteBuffer buffer) {
@@ -30,31 +31,44 @@ class Reference {
final byteWidth = byteData.getUint8(len - 1);
final packedType = byteData.getUint8(len - 2);
final offset = len - byteWidth - 2;
return Reference._(ByteData.view(buffer), offset, BitWidthUtil.fromByteWidth(byteWidth), packedType, "/");
return Reference._(ByteData.view(buffer), offset,
BitWidthUtil.fromByteWidth(byteWidth), packedType, "/");
}
/// Returns true if the underlying value is null.
bool get isNull => _valueType == ValueType.Null;
/// Returns true if the underlying value can be represented as [num].
bool get isNum => ValueTypeUtils.isNumber(_valueType) || ValueTypeUtils.isIndirectNumber(_valueType);
bool get isNum =>
ValueTypeUtils.isNumber(_valueType) ||
ValueTypeUtils.isIndirectNumber(_valueType);
/// Returns true if the underlying value was encoded as a float (direct or indirect).
bool get isDouble => _valueType == ValueType.Float || _valueType == ValueType.IndirectFloat;
bool get isDouble =>
_valueType == ValueType.Float || _valueType == ValueType.IndirectFloat;
/// Returns true if the underlying value was encoded as an int or uint (direct or indirect).
bool get isInt => isNum && !isDouble;
/// Returns true if the underlying value was encoded as a string or a key.
bool get isString => _valueType == ValueType.String || _valueType == ValueType.Key;
bool get isString =>
_valueType == ValueType.String || _valueType == ValueType.Key;
/// Returns true if the underlying value was encoded as a bool.
bool get isBool => _valueType == ValueType.Bool;
/// Returns true if the underlying value was encoded as a blob.
bool get isBlob => _valueType == ValueType.Blob;
/// Returns true if the underlying value points to a vector.
bool get isVector => ValueTypeUtils.isAVector(_valueType);
/// Returns true if the underlying value points to a map.
bool get isMap => _valueType == ValueType.Map;
/// If this [isBool], returns the bool value. Otherwise, returns null.
bool get boolValue {
if(_valueType == ValueType.Bool) {
bool? get boolValue {
if (_valueType == ValueType.Bool) {
return _readInt(_offset, _parentWidth) != 0;
}
return null;
@@ -63,7 +77,7 @@ class Reference {
/// Returns an [int], if the underlying value can be represented as an int.
///
/// Otherwise returns [null].
int get intValue {
int? get intValue {
if (_valueType == ValueType.Int) {
return _readInt(_offset, _parentWidth);
}
@@ -82,7 +96,7 @@ class Reference {
/// Returns [double], if the underlying value [isDouble].
///
/// Otherwise returns [null].
double get doubleValue {
double? get doubleValue {
if (_valueType == ValueType.Float) {
return _readFloat(_offset, _parentWidth);
}
@@ -95,12 +109,12 @@ class Reference {
/// Returns [num], if the underlying value is numeric, be it int uint, or float (direct or indirect).
///
/// Otherwise returns [null].
num get numValue => doubleValue ?? intValue;
num? get numValue => doubleValue ?? intValue;
/// Returns [String] value or null otherwise.
///
/// This method performers a utf8 decoding, as FlexBuffers format stores strings in utf8 encoding.
String get stringValue {
///
/// This method performers a utf8 decoding, as FlexBuffers format stores strings in utf8 encoding.
String? get stringValue {
if (_valueType == ValueType.String || _valueType == ValueType.Key) {
return utf8.decode(_buffer.buffer.asUint8List(_indirect, length));
}
@@ -108,7 +122,7 @@ class Reference {
}
/// Returns [Uint8List] value or null otherwise.
Uint8List get blobValue {
Uint8List? get blobValue {
if (_valueType == ValueType.Blob) {
return _buffer.buffer.asUint8List(_indirect, length);
}
@@ -122,22 +136,31 @@ class Reference {
Reference operator [](Object key) {
if (key is int && ValueTypeUtils.isAVector(_valueType)) {
final index = key;
if(index >= length || index < 0) {
throw ArgumentError('Key: [$key] is not applicable on: $_path of: $_valueType length: $length');
if (index >= length || index < 0) {
throw ArgumentError(
'Key: [$key] is not applicable on: $_path of: $_valueType length: $length');
}
final elementOffset = _indirect + index * _byteWidth;
final reference = Reference._(_buffer, elementOffset, BitWidthUtil.fromByteWidth(_byteWidth), 0, "$_path[$index]");
reference._byteWidth = 1;
int packedType = 0;
int? byteWidth;
ValueType? valueType;
if (ValueTypeUtils.isTypedVector(_valueType)) {
reference._valueType = ValueTypeUtils.typedVectorElementType(_valueType);
return reference;
byteWidth = 1;
valueType = ValueTypeUtils.typedVectorElementType(_valueType);
} else if (ValueTypeUtils.isFixedTypedVector(_valueType)) {
byteWidth = 1;
valueType = ValueTypeUtils.fixedTypedVectorElementType(_valueType);
} else {
packedType = _buffer.getUint8(_indirect + length * _byteWidth + index);
}
if(ValueTypeUtils.isFixedTypedVector(_valueType)) {
reference._valueType = ValueTypeUtils.fixedTypedVectorElementType(_valueType);
return reference;
}
final packedType = _buffer.getUint8(_indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path[$index]");
return Reference._(
_buffer,
elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth),
packedType,
"$_path[$index]",
byteWidth,
valueType);
}
if (key is String && _valueType == ValueType.Map) {
final index = _keyIndex(key);
@@ -145,13 +168,14 @@ class Reference {
return _valueForIndexWithKey(index, key);
}
}
throw ArgumentError('Key: [$key] is not applicable on: $_path of: $_valueType');
throw ArgumentError(
'Key: [$key] is not applicable on: $_path of: $_valueType');
}
/// Get an iterable if the underlying flexBuffer value is a vector.
/// Otherwise throws an exception.
Iterable<Reference> get vectorIterable {
if(isVector == false) {
if (isVector == false) {
throw UnsupportedError('Value is not a vector. It is: $_valueType');
}
return _VectorIterator(this);
@@ -160,7 +184,7 @@ class Reference {
/// Get an iterable for keys if the underlying flexBuffer value is a map.
/// Otherwise throws an exception.
Iterable<String> get mapKeyIterable {
if(isMap == false) {
if (isMap == false) {
throw UnsupportedError('Value is not a map. It is: $_valueType');
}
return _MapKeyIterator(this);
@@ -169,7 +193,7 @@ class Reference {
/// Get an iterable for values if the underlying flexBuffer value is a map.
/// Otherwise throws an exception.
Iterable<Reference> get mapValueIterable {
if(isMap == false) {
if (isMap == false) {
throw UnsupportedError('Value is not a map. It is: $_valueType');
}
return _MapValueIterator(this);
@@ -181,59 +205,62 @@ class Reference {
/// If the underlying value is a vector, or map, the length reflects number of elements / element pairs.
/// If the values is a string or a blob, the length reflects a number of bytes the value occupies (strings are encoded in utf8 format).
int get length {
if (_length != null) {
return _length;
}
// needs to be checked before more generic isAVector
if(ValueTypeUtils.isFixedTypedVector(_valueType)) {
_length = ValueTypeUtils.fixedTypedVectorElementSize(_valueType);
} else if(_valueType == ValueType.Blob || ValueTypeUtils.isAVector(_valueType) || _valueType == ValueType.Map){
_length = _readUInt(_indirect - _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth));
} else if (_valueType == ValueType.Null) {
_length = 0;
} else if (_valueType == ValueType.String) {
final indirect = _indirect;
var size_byte_width = _byteWidth;
var size = _readUInt(indirect - size_byte_width, BitWidthUtil.fromByteWidth(size_byte_width));
while (_buffer.getInt8(indirect + size) != 0) {
size_byte_width <<= 1;
size = _readUInt(indirect - size_byte_width, BitWidthUtil.fromByteWidth(size_byte_width));
if (_length == null) {
// needs to be checked before more generic isAVector
if (ValueTypeUtils.isFixedTypedVector(_valueType)) {
_length = ValueTypeUtils.fixedTypedVectorElementSize(_valueType);
} else if (_valueType == ValueType.Blob ||
ValueTypeUtils.isAVector(_valueType) ||
_valueType == ValueType.Map) {
_length = _readUInt(
_indirect - _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth));
} else if (_valueType == ValueType.Null) {
_length = 0;
} else if (_valueType == ValueType.String) {
final indirect = _indirect;
var size_byte_width = _byteWidth;
var size = _readUInt(indirect - size_byte_width,
BitWidthUtil.fromByteWidth(size_byte_width));
while (_buffer.getInt8(indirect + size) != 0) {
size_byte_width <<= 1;
size = _readUInt(indirect - size_byte_width,
BitWidthUtil.fromByteWidth(size_byte_width));
}
_length = size;
} else if (_valueType == ValueType.Key) {
final indirect = _indirect;
var size = 1;
while (_buffer.getInt8(indirect + size) != 0) {
size += 1;
}
_length = size;
} else {
_length = 1;
}
_length = size;
} else if (_valueType == ValueType.Key) {
final indirect = _indirect;
var size = 1;
while (_buffer.getInt8(indirect + size) != 0) {
size += 1;
}
_length = size;
} else {
_length = 1;
}
return _length;
return _length!;
}
/// Returns a minified JSON representation of the underlying FlexBuffer value.
///
/// This method involves materializing the entire object tree, which may be
/// expensive. It is more efficient to work with [Reference] and access only the needed data.
/// Blob values are represented as base64 encoded string.
String get json {
if(_valueType == ValueType.Bool) {
return boolValue ? 'true' : 'false';
if (_valueType == ValueType.Bool) {
return boolValue! ? 'true' : 'false';
}
if (_valueType == ValueType.Null) {
return 'null';
}
if(ValueTypeUtils.isNumber(_valueType)) {
if (ValueTypeUtils.isNumber(_valueType)) {
return jsonEncode(numValue);
}
if (_valueType == ValueType.String) {
return jsonEncode(stringValue);
}
if (_valueType == ValueType.Blob) {
return jsonEncode(base64Encode(blobValue));
return jsonEncode(base64Encode(blobValue!));
}
if (ValueTypeUtils.isAVector(_valueType)) {
final result = StringBuffer();
@@ -261,7 +288,8 @@ class Reference {
result.write('}');
return result.toString();
}
throw UnsupportedError('Type: $_valueType is not supported for JSON conversion');
throw UnsupportedError(
'Type: $_valueType is not supported for JSON conversion');
}
/// Computes the indirect offset of the value.
@@ -316,16 +344,20 @@ class Reference {
}
void _validateOffset(int offset, BitWidth width) {
if (_offset < 0 || _buffer.lengthInBytes <= offset + width.index || offset & (BitWidthUtil.toByteWidth(width) - 1) != 0) {
if (_offset < 0 ||
_buffer.lengthInBytes <= offset + width.index ||
offset & (BitWidthUtil.toByteWidth(width) - 1) != 0) {
throw StateError('Bad offset: $offset, width: $width');
}
}
int _keyIndex(String key) {
int? _keyIndex(String key) {
final input = utf8.encode(key);
final keysVectorOffset = _indirect - _byteWidth * 3;
final indirectOffset = keysVectorOffset - _readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt(keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth));
final indirectOffset = keysVectorOffset -
_readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt(
keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth));
var low = 0;
var high = length - 1;
while (low <= high) {
@@ -341,9 +373,11 @@ class Reference {
return null;
}
int _diffKeys(List<int> input, int index, int indirect_offset, int byteWidth) {
int _diffKeys(
List<int> input, int index, int indirect_offset, int byteWidth) {
final keyOffset = indirect_offset + index * byteWidth;
final keyIndirectOffset = keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));
final keyIndirectOffset =
keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));
for (var i = 0; i < input.length; i++) {
final dif = input[i] - _buffer.getUint8(keyIndirectOffset + i);
if (dif != 0) {
@@ -357,38 +391,42 @@ class Reference {
final indirect = _indirect;
final elementOffset = indirect + index * _byteWidth;
final packedType = _buffer.getUint8(indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/$key");
return Reference._(_buffer, elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/$key");
}
Reference _valueForIndex(int index) {
final indirect = _indirect;
final elementOffset = indirect + index * _byteWidth;
final packedType = _buffer.getUint8(indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/[$index]");
return Reference._(_buffer, elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/[$index]");
}
String _keyForIndex(int index) {
final keysVectorOffset = _indirect - _byteWidth * 3;
final indirectOffset = keysVectorOffset - _readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt(keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth));
final indirectOffset = keysVectorOffset -
_readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt(
keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth));
final keyOffset = indirectOffset + index * byteWidth;
final keyIndirectOffset = keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));
final keyIndirectOffset =
keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));
var length = 0;
while (_buffer.getUint8(keyIndirectOffset + length) != 0) {
length += 1;
}
return utf8.decode(_buffer.buffer.asUint8List(keyIndirectOffset, length));
}
}
class _VectorIterator with IterableMixin<Reference> implements Iterator<Reference> {
class _VectorIterator
with IterableMixin<Reference>
implements Iterator<Reference> {
final Reference _vector;
int index;
int index = -1;
_VectorIterator(this._vector) {
index = -1;
}
_VectorIterator(this._vector);
@override
Reference get current => _vector[index];
@@ -405,11 +443,9 @@ class _VectorIterator with IterableMixin<Reference> implements Iterator<Referenc
class _MapKeyIterator with IterableMixin<String> implements Iterator<String> {
final Reference _map;
int index;
int index = -1;
_MapKeyIterator(this._map) {
index = -1;
}
_MapKeyIterator(this._map);
@override
String get current => _map._keyForIndex(index);
@@ -424,13 +460,13 @@ class _MapKeyIterator with IterableMixin<String> implements Iterator<String> {
Iterator<String> get iterator => this;
}
class _MapValueIterator with IterableMixin<Reference> implements Iterator<Reference> {
class _MapValueIterator
with IterableMixin<Reference>
implements Iterator<Reference> {
final Reference _map;
int index;
int index = -1;
_MapValueIterator(this._map) {
index = -1;
}
_MapValueIterator(this._map);
@override
Reference get current => _map._valueForIndex(index);

View File

@@ -1,17 +1,13 @@
import 'dart:typed_data';
/// Represents the number of bits a value occupies.
enum BitWidth {
width8,
width16,
width32,
width64
}
enum BitWidth { width8, width16, width32, width64 }
class BitWidthUtil {
static int toByteWidth(BitWidth self) {
return 1 << self.index;
}
static BitWidth width(num value) {
if (value.toInt() == value) {
var v = value.toInt().abs();
@@ -20,8 +16,11 @@ class BitWidthUtil {
if (v >> 31 == 0) return BitWidth.width32;
return BitWidth.width64;
}
return value == _toF32(value) ? BitWidth.width32 : BitWidth.width64;
return value == _toF32(value as double)
? BitWidth.width32
: BitWidth.width64;
}
static BitWidth uwidth(num value) {
if (value.toInt() == value) {
var v = value.toInt().abs();
@@ -30,8 +29,11 @@ class BitWidthUtil {
if (v >> 32 == 0) return BitWidth.width32;
return BitWidth.width64;
}
return value == _toF32(value) ? BitWidth.width32 : BitWidth.width64;
return value == _toF32(value as double)
? BitWidth.width32
: BitWidth.width64;
}
static BitWidth fromByteWidth(int value) {
if (value == 1) {
return BitWidth.width8;
@@ -47,9 +49,11 @@ class BitWidthUtil {
}
throw Exception('Unexpected value ${value}');
}
static int paddingSize(int bufSize, int scalarSize) {
return (~bufSize + 1) & (scalarSize - 1);
}
static double _toF32(double value) {
var bdata = ByteData(4);
bdata.setFloat32(0, value);
@@ -66,15 +70,36 @@ class BitWidthUtil {
/// Represents all internal FlexBuffer types.
enum ValueType {
Null, Int, UInt, Float,
Key, String, IndirectInt, IndirectUInt, IndirectFloat,
Map, Vector, VectorInt, VectorUInt, VectorFloat, VectorKey,
@Deprecated('VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)')
Null,
Int,
UInt,
Float,
Key,
String,
IndirectInt,
IndirectUInt,
IndirectFloat,
Map,
Vector,
VectorInt,
VectorUInt,
VectorFloat,
VectorKey,
@Deprecated(
'VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)')
VectorString,
VectorInt2, VectorUInt2, VectorFloat2,
VectorInt3, VectorUInt3, VectorFloat3,
VectorInt4, VectorUInt4, VectorFloat4,
Blob, Bool, VectorBool
VectorInt2,
VectorUInt2,
VectorFloat2,
VectorInt3,
VectorUInt3,
VectorFloat3,
VectorInt4,
VectorUInt4,
VectorFloat4,
Blob,
Bool,
VectorBool
}
class ValueTypeUtils {
@@ -89,71 +114,70 @@ class ValueTypeUtils {
}
static bool isInline(ValueType self) {
return self == ValueType.Bool
|| toInt(self) <= toInt(ValueType.Float);
return self == ValueType.Bool || toInt(self) <= toInt(ValueType.Float);
}
static bool isNumber(ValueType self) {
return toInt(self) >= toInt(ValueType.Int)
&& toInt(self) <= toInt(ValueType.Float);
return toInt(self) >= toInt(ValueType.Int) &&
toInt(self) <= toInt(ValueType.Float);
}
static bool isIndirectNumber(ValueType self) {
return toInt(self) >= toInt(ValueType.IndirectInt)
&& toInt(self) <= toInt(ValueType.IndirectFloat);
return toInt(self) >= toInt(ValueType.IndirectInt) &&
toInt(self) <= toInt(ValueType.IndirectFloat);
}
static bool isTypedVectorElement(ValueType self) {
return self == ValueType.Bool ||
(
toInt(self) >= toInt(ValueType.Int)
&& toInt(self) <= toInt(ValueType.String)
);
(toInt(self) >= toInt(ValueType.Int) &&
toInt(self) <= toInt(ValueType.String));
}
static bool isTypedVector(ValueType self) {
return self == ValueType.VectorBool ||
(
toInt(self) >= toInt(ValueType.VectorInt)
&& toInt(self) <= toInt(ValueType.VectorString)
);
(toInt(self) >= toInt(ValueType.VectorInt) &&
toInt(self) <= toInt(ValueType.VectorString));
}
static bool isFixedTypedVector(ValueType self) {
return (
toInt(self) >= toInt(ValueType.VectorInt2)
&& toInt(self) <= toInt(ValueType.VectorFloat4)
);
return (toInt(self) >= toInt(ValueType.VectorInt2) &&
toInt(self) <= toInt(ValueType.VectorFloat4));
}
static bool isAVector(ValueType self) {
return (
isTypedVector(self) || isFixedTypedVector(self) || self == ValueType.Vector
);
return (isTypedVector(self) ||
isFixedTypedVector(self) ||
self == ValueType.Vector);
}
static ValueType toTypedVector(ValueType self, int length) {
if (length == 0) {
return ValueTypeUtils.fromInt(toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt));
return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt));
}
if (length == 2) {
return ValueTypeUtils.fromInt(toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2));
return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2));
}
if (length == 3) {
return ValueTypeUtils.fromInt(toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3));
return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3));
}
if (length == 4) {
return ValueTypeUtils.fromInt(toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4));
return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4));
}
throw Exception('unexpected length ' + length.toString());
}
static ValueType typedVectorElementType(ValueType self) {
return ValueTypeUtils.fromInt(toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int));
return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int));
}
static ValueType fixedTypedVectorElementType(ValueType self) {
return ValueTypeUtils.fromInt((toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int));
return ValueTypeUtils.fromInt(
(toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int));
}
static int fixedTypedVectorElementSize(ValueType self) {