lbry-sdk/torba/bcd_data_stream.py

127 lines
3 KiB
Python
Raw Normal View History

2018-05-25 08:03:25 +02:00
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('<h')
uint16 = struct.Struct('<H')
int32 = struct.Struct('<i')
uint32 = struct.Struct('<I')
int64 = struct.Struct('<q')
uint64 = struct.Struct('<Q')
def _read_struct(self, fmt):
value = self.read(fmt.size)
if len(value) > 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))