import struct from io import BytesIO class BCDataStream: def __init__(self, data=None): self.data = BytesIO(data) @property def is_at_beginning(self): return self.data.tell() == 0 def reset(self): self.data.seek(0) def get_bytes(self): return self.data.getvalue() def read(self, size): return self.data.read(size) def write(self, data): self.data.write(data) def write_many(self, many): self.data.writelines(many) def read_string(self): return self.read(self.read_compact_size()) def write_string(self, s): self.write_compact_size(len(s)) self.write(s) def read_compact_size(self): size = self.read_uint8() if size < 253: return size if size == 253: return self.read_uint16() elif size == 254: return self.read_uint32() elif size == 255: return self.read_uint64() def write_compact_size(self, size): if size < 253: self.write_uint8(size) elif size <= 0xFFFF: self.write_uint8(253) self.write_uint16(size) elif size <= 0xFFFFFFFF: self.write_uint8(254) self.write_uint32(size) else: self.write_uint8(255) self.write_uint64(size) def read_boolean(self): return self.read_uint8() != 0 def write_boolean(self, val): return self.write_uint8(1 if val else 0) int8 = struct.Struct('b') uint8 = struct.Struct('B') int16 = struct.Struct(' 0: return fmt.unpack(value)[0] def read_int8(self): return self._read_struct(self.int8) def read_uint8(self): return self._read_struct(self.uint8) def read_int16(self): return self._read_struct(self.int16) def read_uint16(self): return self._read_struct(self.uint16) def read_int32(self): return self._read_struct(self.int32) def read_uint32(self): return self._read_struct(self.uint32) def read_int64(self): return self._read_struct(self.int64) def read_uint64(self): return self._read_struct(self.uint64) def write_int8(self, val): self.write(self.int8.pack(val)) def write_uint8(self, val): self.write(self.uint8.pack(val)) def write_int16(self, val): self.write(self.int16.pack(val)) def write_uint16(self, val): self.write(self.uint16.pack(val)) def write_int32(self, val): self.write(self.int32.pack(val)) def write_uint32(self, val): self.write(self.uint32.pack(val)) def write_int64(self, val): self.write(self.int64.pack(val)) def write_uint64(self, val): self.write(self.uint64.pack(val))