mirror of
https://github.com/flutter/flutter
synced 2024-09-13 21:32:11 +00:00
[framework] use Uint8List for SMC (#100582)
This commit is contained in:
parent
015732c732
commit
32c021bd33
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:math' as math;
|
||||
import 'dart:typed_data';
|
||||
|
||||
/// Write-only buffer for incrementally building a [ByteData] instance.
|
||||
|
@ -13,30 +14,59 @@ import 'dart:typed_data';
|
|||
class WriteBuffer {
|
||||
/// Creates an interface for incrementally building a [ByteData] instance.
|
||||
factory WriteBuffer() {
|
||||
final List<int> buffer = <int>[];
|
||||
final ByteData eightBytes = ByteData(8);
|
||||
final Uint8List eightBytesAsList = eightBytes.buffer.asUint8List();
|
||||
return WriteBuffer._(buffer, eightBytes, eightBytesAsList);
|
||||
return WriteBuffer._(Uint8List(8), eightBytes, eightBytesAsList);
|
||||
}
|
||||
|
||||
WriteBuffer._(this._buffer, this._eightBytes, this._eightBytesAsList);
|
||||
|
||||
List<int> _buffer;
|
||||
Uint8List _buffer;
|
||||
int _currentSize = 0;
|
||||
bool _isDone = false;
|
||||
final ByteData _eightBytes;
|
||||
final Uint8List _eightBytesAsList;
|
||||
static final Uint8List _zeroBuffer = Uint8List(8);
|
||||
|
||||
void _addAll(Uint8List data, [int start = 0, int? end]) {
|
||||
for (int i = start; i < (end ?? _eightBytesAsList.length); i++) {
|
||||
_buffer.add(data[i]);
|
||||
void _add(int byte) {
|
||||
if (_currentSize == _buffer.length) {
|
||||
_resize();
|
||||
}
|
||||
_buffer[_currentSize] = byte;
|
||||
_currentSize += 1;
|
||||
}
|
||||
|
||||
void _append(Uint8List other) {
|
||||
final int newSize = _currentSize + other.length;
|
||||
if (newSize >= _buffer.length) {
|
||||
_resize(newSize);
|
||||
}
|
||||
_buffer.setRange(_currentSize, newSize, other);
|
||||
_currentSize += other.length;
|
||||
}
|
||||
|
||||
void _addAll(Uint8List data, [int start = 0, int? end]) {
|
||||
final int newEnd = end ?? _eightBytesAsList.length;
|
||||
final int newSize = _currentSize + (newEnd - start);
|
||||
if (newSize >= _buffer.length) {
|
||||
_resize(newSize);
|
||||
}
|
||||
_buffer.setRange(_currentSize, newSize, data);
|
||||
_currentSize = newSize;
|
||||
}
|
||||
|
||||
void _resize([int? requiredLength]) {
|
||||
final int doubleLength = _buffer.length * 2;
|
||||
final int newLength = math.max(requiredLength ?? 0, doubleLength);
|
||||
final Uint8List newBuffer = Uint8List(newLength);
|
||||
newBuffer.setRange(0, _buffer.length, _buffer);
|
||||
_buffer = newBuffer;
|
||||
}
|
||||
|
||||
/// Write a Uint8 into the buffer.
|
||||
void putUint8(int byte) {
|
||||
assert(!_isDone);
|
||||
_buffer.add(byte);
|
||||
_add(byte);
|
||||
}
|
||||
|
||||
/// Write a Uint16 into the buffer.
|
||||
|
@ -78,40 +108,40 @@ class WriteBuffer {
|
|||
/// Write all the values from a [Uint8List] into the buffer.
|
||||
void putUint8List(Uint8List list) {
|
||||
assert(!_isDone);
|
||||
_buffer.addAll(list);
|
||||
_append(list);
|
||||
}
|
||||
|
||||
/// Write all the values from an [Int32List] into the buffer.
|
||||
void putInt32List(Int32List list) {
|
||||
assert(!_isDone);
|
||||
_alignTo(4);
|
||||
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length));
|
||||
_append(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length));
|
||||
}
|
||||
|
||||
/// Write all the values from an [Int64List] into the buffer.
|
||||
void putInt64List(Int64List list) {
|
||||
assert(!_isDone);
|
||||
_alignTo(8);
|
||||
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
|
||||
_append(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
|
||||
}
|
||||
|
||||
/// Write all the values from a [Float32List] into the buffer.
|
||||
void putFloat32List(Float32List list) {
|
||||
assert(!_isDone);
|
||||
_alignTo(4);
|
||||
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length));
|
||||
_append(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length));
|
||||
}
|
||||
|
||||
/// Write all the values from a [Float64List] into the buffer.
|
||||
void putFloat64List(Float64List list) {
|
||||
assert(!_isDone);
|
||||
_alignTo(8);
|
||||
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
|
||||
_append(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
|
||||
}
|
||||
|
||||
void _alignTo(int alignment) {
|
||||
assert(!_isDone);
|
||||
final int mod = _buffer.length % alignment;
|
||||
final int mod = _currentSize % alignment;
|
||||
if (mod != 0) {
|
||||
_addAll(_zeroBuffer, 0, alignment - mod);
|
||||
}
|
||||
|
@ -122,8 +152,8 @@ class WriteBuffer {
|
|||
if (_isDone) {
|
||||
throw StateError('done() must not be called more than once on the same $runtimeType.');
|
||||
}
|
||||
final ByteData result = Uint8List.fromList(_buffer).buffer.asByteData();
|
||||
_buffer = <int>[];
|
||||
final ByteData result = _buffer.buffer.asByteData(0, _currentSize);
|
||||
_buffer = Uint8List(0);
|
||||
_isDone = true;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,12 @@ import 'package:flutter_test/flutter_test.dart';
|
|||
|
||||
void main() {
|
||||
group('Write and read buffer round-trip', () {
|
||||
test('of empty buffer', () {
|
||||
final WriteBuffer write = WriteBuffer();
|
||||
final ByteData written = write.done();
|
||||
|
||||
expect(written.lengthInBytes, 0);
|
||||
});
|
||||
test('of single byte', () {
|
||||
final WriteBuffer write = WriteBuffer();
|
||||
write.putUint8(201);
|
||||
|
|
Loading…
Reference in a new issue