import enum
from restruct import Struct, Processed, parse
class BType(enum.Enum):
Dict = 1
Array = 2
Int = 4
String = 9
Null = 11
class BDictElem(Struct, generics={'T'}):
key: T
value: T
Byteswap = lambda x, n: Processed(x,
parse=lambda v: int.from_bytes(v.to_bytes(n, byteorder='big'), byteorder='little'),
emit= lambda v: int.from_bytes(v.to_bytes(n, byteorder='big'), byteorder='little'),
)
class BElem(Struct, partials={'T', 'SA', 'SI', 'SS'}, recursive=True):
size: Byteswap(Bits(24), 3) @ SA.count @ SI.bits @ SS.length
type: Enum(BType, Bits(7)) @ T.selector
last: Bool(Bits(1))
value: Switch(options={
BType.Dict: Arr(BDictElem[Self]) @ SA,
BType.Array: Arr(Self) @ SA,
BType.Int: UInt() @ SI,
BType.String: AlignTo(Str(type='raw') @ SS, 4),
}) @ T
class BList(Struct):
size: UInt(32)
root: BElem
print(parse(BList, bytes.fromhex("""
d3 00 00 00
04 00 00 81
06 00 00 09 47 6c 6f 62 61 6c 02 00
02 00 00 01
05 00 00 09 77 69 64 74 68 01 00 00
40 00 00 04 80 07 00 00 00 00 00 00
06 00 00 09 68 65 69 67 68 74 02 00
40 00 00 84 38 04 00 00 00 00 00 00
""")))