mirror of
https://git.ugnet.gay/CrossTalk/azul.git
synced 2026-05-27 22:59:49 +00:00
55 lines
1.0 KiB
Python
55 lines
1.0 KiB
Python
from . import buffer # because of circular imports, would've prefered to do `from .buffer import ...` but oh well
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class TLV:
|
|
__slots__ = ('type', 'data')
|
|
|
|
type: int
|
|
data: bytes
|
|
|
|
def __init__(self, type: int, data: bytes | str = b''):
|
|
self.type = type
|
|
|
|
if isinstance(data, str):
|
|
self.data = data.encode()
|
|
else:
|
|
self.data = data
|
|
|
|
def marshal(self) -> bytes:
|
|
buf = buffer.Buffer()
|
|
buf.write_u16(self.type)
|
|
buf.write_u16(len(self.data))
|
|
buf.write_bytes(self.data)
|
|
|
|
return buf.data
|
|
|
|
|
|
def marshal_tlvs(tlvs: list[TLV]) -> bytes:
|
|
return b''.join([tlv.marshal() for tlv in tlvs])
|
|
|
|
|
|
def unmarshal_tlvs(data: bytes) -> list[TLV]:
|
|
buf = buffer.Buffer(data)
|
|
tlvs = []
|
|
|
|
while len(buf) > 4:
|
|
type = buf.read_u16()
|
|
length = buf.read_u16()
|
|
value = buf.read_bytes(length)
|
|
|
|
tlvs.append(TLV(type, value))
|
|
|
|
return tlvs
|
|
|
|
|
|
def find_tlv(tlvs: list[TLV], type: int) -> Optional[TLV]:
|
|
for tlv in tlvs:
|
|
if tlv.type == type:
|
|
return tlv
|
|
|
|
return None
|