|
@@ -0,0 +1,264 @@
|
|
|
+import 'dart:typed_data';
|
|
|
+
|
|
|
+//Raised when data is not ready.
|
|
|
+class NotReadyException implements Exception {}
|
|
|
+
|
|
|
+class StreamErrorException implements Exception {
|
|
|
+ String _msg;
|
|
|
+
|
|
|
+ StreamErrorException(this._msg);
|
|
|
+
|
|
|
+ @override
|
|
|
+ String toString() {
|
|
|
+ return _msg;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class VidUsDataStreamReader {
|
|
|
+ late final List<int> _data = [];
|
|
|
+ late int _index;
|
|
|
+ late ByteBuffer _buffer;
|
|
|
+ late bool _error;
|
|
|
+ late String _errorMsg;
|
|
|
+
|
|
|
+ VidUsDataStreamReader(Stream<Uint8List> stream, [int offset = 0]) {
|
|
|
+ _buffer = Uint8List.fromList(_data).buffer;
|
|
|
+ stream.listen(onDataArrived, onError: onStreamError, onDone: onStreamDone);
|
|
|
+ _index = offset;
|
|
|
+ }
|
|
|
+
|
|
|
+ void onDataArrived(Uint8List data) {
|
|
|
+ _data.addAll(data);
|
|
|
+ _buffer = Uint8List.fromList(_data).buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ void onStreamError(String msg) {
|
|
|
+ _error = true;
|
|
|
+ _errorMsg = msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ void onStreamDone() {
|
|
|
+ //Update the last data into the buffer.
|
|
|
+ _buffer = Uint8List.fromList(_data).buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read int value from binary data(little endian),
|
|
|
+ int readInt([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 4) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var intData = _buffer.asByteData(_index, 4);
|
|
|
+ _index += 4;
|
|
|
+ return intData.getInt32(0, Endian.little);
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 4) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var intData = _buffer.asByteData(index, 4);
|
|
|
+ _index = index + 4;
|
|
|
+ return intData.getInt32(0, Endian.little);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read string from the binary data, the string format is utf-16, which is unicode in C#
|
|
|
+ String readString([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ int dataLength;
|
|
|
+ if (index == -1) {
|
|
|
+ dataLength = readInt();
|
|
|
+ if ((_buffer.lengthInBytes - _index) < dataLength) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ dataLength = readInt(index);
|
|
|
+ if ((_buffer.lengthInBytes - index) < dataLength) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var stringData = _buffer.asUint8List(_index, dataLength);
|
|
|
+ _index += dataLength;
|
|
|
+ var unicodeStringData = Uint8List.fromList(stringData.toList()).buffer.asUint16List();
|
|
|
+ return String.fromCharCodes(unicodeStringData);
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read int16 value from binary data(little endian)
|
|
|
+ int readInt16([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 2) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var intData = _buffer.asByteData(_index, 2);
|
|
|
+ _index += 2;
|
|
|
+ return intData.getInt16(0, Endian.little);
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 2) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var intData = _buffer.asByteData(index, 2);
|
|
|
+ _index = index + 2;
|
|
|
+ return intData.getInt16(0, Endian.little);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read int64 value from binary data(little endian)
|
|
|
+ ///this method is not support in web platform use readInt64V2 instead.
|
|
|
+ int readInt64([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 8) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var intData = _buffer.asByteData(_index, 8);
|
|
|
+ _index += 8;
|
|
|
+ return intData.getInt64(0, Endian.little);
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 8) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var intData = _buffer.asByteData(index, 8);
|
|
|
+ _index = index + 8;
|
|
|
+ return intData.getInt64(0, Endian.little);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read int64 value from binary data(little endian)
|
|
|
+ ///this method use two int32 to support read int64 on web platform
|
|
|
+ int readInt64V2([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 8) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ int low = readInt();
|
|
|
+ int high = readInt();
|
|
|
+ int value = high >> 32;
|
|
|
+ value |= low;
|
|
|
+ return value;
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 8) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ int low = readInt(index);
|
|
|
+ //Read the next int.
|
|
|
+ int high = readInt();
|
|
|
+ int value = high >> 32;
|
|
|
+ value |= low;
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read float value from binary data(little endian)
|
|
|
+ double readFloat([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 4) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var floatData = _buffer.asByteData(_index, 4);
|
|
|
+ _index += 4;
|
|
|
+ return floatData.getFloat32(0, Endian.little);
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 4) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var floatData = _buffer.asByteData(index, 4);
|
|
|
+ _index = index + 4;
|
|
|
+ return floatData.getFloat32(0, Endian.little);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read double value from binary data(little endian)
|
|
|
+ double readDouble([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 8) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var floatData = _buffer.asByteData(_index, 8);
|
|
|
+ _index += 8;
|
|
|
+ return floatData.getFloat64(0, Endian.little);
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 8) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var floatData = _buffer.asByteData(index, 8);
|
|
|
+ _index = index + 8;
|
|
|
+ return floatData.getFloat64(0, Endian.little);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read bool value from binary data
|
|
|
+ bool readBool([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 1) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var boolData = _buffer.asByteData(_index, 1);
|
|
|
+ _index++;
|
|
|
+ return boolData.getInt8(0) == 1;
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 1) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var boolData = _buffer.asByteData(index, 1);
|
|
|
+ _index = index + 1;
|
|
|
+ return boolData.getInt8(0) == 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read byte value from binary data
|
|
|
+ int readByte([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ if ((_buffer.lengthInBytes - _index) < 1) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var byteData = _buffer.asByteData(_index, 1);
|
|
|
+ _index++;
|
|
|
+ return byteData.getInt8(0);
|
|
|
+ } else {
|
|
|
+ if ((_buffer.lengthInBytes - index) < 1) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var byteData = _buffer.asByteData(index, 1);
|
|
|
+ _index = index + 1;
|
|
|
+ return byteData.getInt8(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Read bytes from the binary data.
|
|
|
+ Uint8List readBytes([int index = -1]) {
|
|
|
+ if (_error) {
|
|
|
+ throw StreamErrorException(_errorMsg);
|
|
|
+ }
|
|
|
+ var dataLength = readInt(index);
|
|
|
+ if ((_buffer.lengthInBytes - _index) < dataLength) {
|
|
|
+ throw NotReadyException();
|
|
|
+ }
|
|
|
+ var bytes = _buffer.asUint8List(_index, dataLength);
|
|
|
+ _index += dataLength;
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+}
|