2022-07-10 15:39:48 +00:00
|
|
|
import struct
|
|
|
|
from .binary import decode_int, decode_varint
|
|
|
|
|
|
|
|
def dissect_items(body, position=0):
|
|
|
|
result = []
|
|
|
|
while body:
|
|
|
|
(count, i) = decode_varint(body)
|
|
|
|
chunk = body[i:i+count]
|
|
|
|
body = body[i+count:]
|
2022-07-12 14:47:16 +00:00
|
|
|
result.append(_dissect(chunk, position + i))
|
2022-07-10 15:39:48 +00:00
|
|
|
position = position + i+count
|
|
|
|
return result
|
|
|
|
|
2022-07-12 14:47:16 +00:00
|
|
|
def dissect(bs):
|
|
|
|
if not isinstance(bs, memoryview):
|
|
|
|
bs = memoryview(bs)
|
|
|
|
return _dissect(bs, 0)
|
|
|
|
|
|
|
|
def _dissect(bs, position):
|
2022-07-10 15:39:48 +00:00
|
|
|
tag = bs[0]
|
|
|
|
body = bs[1:]
|
|
|
|
info = None
|
|
|
|
kids = None
|
|
|
|
|
|
|
|
if tag == 0xAA:
|
|
|
|
kids = dissect_items(body, position+1)
|
|
|
|
kids = [kids[i:i+2] for i in range(0, len(kids), 2)]
|
|
|
|
elif tag in [0xA7, 0xA8, 0xA9, 0xBF]:
|
|
|
|
kids = dissect_items(body, position+1)
|
|
|
|
elif tag == 0xAB:
|
2022-07-12 14:47:16 +00:00
|
|
|
kids = [_dissect(body, position+1)]
|
2022-07-10 15:39:48 +00:00
|
|
|
elif tag == 0xA2:
|
|
|
|
if len(body) == 4: info = struct.unpack('>f', body)[0]
|
|
|
|
if len(body) == 8: info = struct.unpack('>d', body)[0]
|
|
|
|
elif tag == 0xA3:
|
|
|
|
info = decode_int(body)
|
|
|
|
elif tag == 0xA4:
|
2022-07-12 14:47:16 +00:00
|
|
|
info = bytes(body[:-1]).decode('utf-8')
|
2022-07-10 15:39:48 +00:00
|
|
|
elif tag == 0xA6:
|
2022-07-12 14:47:16 +00:00
|
|
|
info = bytes(body).decode('utf-8')
|
2022-07-10 15:39:48 +00:00
|
|
|
|
|
|
|
if kids is not None:
|
|
|
|
return ((position, len(bs), tag), kids)
|
|
|
|
elif info is not None:
|
2022-07-12 14:47:16 +00:00
|
|
|
return ((position, len(bs), tag), bytes(body), info)
|
2022-07-10 15:39:48 +00:00
|
|
|
else:
|
2022-07-12 14:47:16 +00:00
|
|
|
return ((position, len(bs), tag), bytes(body))
|
2022-07-10 15:39:48 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
import sys
|
|
|
|
from pprint import pprint
|
|
|
|
pprint(dissect(sys.stdin.buffer.read()))
|