mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-01 00:51:36 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user