Files
pilipala/lib/utils/binary_writer.dart
2024-08-18 23:30:51 +08:00

118 lines
2.9 KiB
Dart

import 'dart:typed_data';
class BinaryWriter {
List<int> buffer;
int position = 0;
BinaryWriter(this.buffer);
int get length => buffer.length;
void writeBytes(List<int> list) {
buffer.addAll(list);
position += list.length;
}
void writeInt(int value, int len, {Endian endian = Endian.big}) {
var bytes = _createByteData(len);
switch (len) {
case 1:
bytes.setUint8(0, value.toUnsigned(8));
break;
case 2:
bytes.setInt16(0, value, endian);
break;
case 4:
bytes.setInt32(0, value, endian);
break;
case 8:
bytes.setInt64(0, value, endian);
break;
default:
throw ArgumentError('Invalid length for writeInt: $len');
}
_addBytesToBuffer(bytes, len);
}
void writeDouble(double value, int len, {Endian endian = Endian.big}) {
var bytes = _createByteData(len);
switch (len) {
case 4:
bytes.setFloat32(0, value, endian);
break;
case 8:
bytes.setFloat64(0, value, endian);
break;
default:
throw ArgumentError('Invalid length for writeDouble: $len');
}
_addBytesToBuffer(bytes, len);
}
ByteData _createByteData(int len) {
var b = Uint8List(len).buffer;
return ByteData.view(b);
}
void _addBytesToBuffer(ByteData bytes, int len) {
buffer.addAll(bytes.buffer.asUint8List());
position += len;
}
}
class BinaryReader {
Uint8List buffer;
int position = 0;
BinaryReader(this.buffer);
int get length => buffer.length;
int read() {
return buffer[position++];
}
int readInt(int len, {Endian endian = Endian.big}) {
var bytes = _getBytes(len);
var data = ByteData.view(bytes.buffer);
switch (len) {
case 1:
return data.getUint8(0);
case 2:
return data.getInt16(0, endian);
case 4:
return data.getInt32(0, endian);
case 8:
return data.getInt64(0, endian);
default:
throw ArgumentError('Invalid length for readInt: $len');
}
}
int readByte({Endian endian = Endian.big}) => readInt(1, endian: endian);
int readShort({Endian endian = Endian.big}) => readInt(2, endian: endian);
int readInt32({Endian endian = Endian.big}) => readInt(4, endian: endian);
int readLong({Endian endian = Endian.big}) => readInt(8, endian: endian);
Uint8List readBytes(int len) {
var bytes = _getBytes(len);
return bytes;
}
double readFloat(int len, {Endian endian = Endian.big}) {
var bytes = _getBytes(len);
var data = ByteData.view(bytes.buffer);
switch (len) {
case 4:
return data.getFloat32(0, endian);
case 8:
return data.getFloat64(0, endian);
default:
throw ArgumentError('Invalid length for readFloat: $len');
}
}
Uint8List _getBytes(int len) {
var bytes =
Uint8List.fromList(buffer.getRange(position, position + len).toList());
position += len;
return bytes;
}
}