import ctypes
import logging
from .vlrs import rawvlr, vlrlist, known
logger = logging.getLogger(__name__)
EVLR_HEADER_SIZE = ctypes.sizeof(EVLRHeader)
[docs]class RawEVLR:
def __init__(self):
self.header = EVLRHeader()
self._record_data = b""
@property
def record_data(self):
return self._record_data
@record_data.setter
def record_data(self, value):
self._record_data = value
self.header.record_length_after_header = len(value)
[docs] @classmethod
def read_from(cls, data_stream):
raw_evlr = cls()
raw_evlr.header = EVLRHeader.from_buffer(
bytearray(data_stream.read(EVLR_HEADER_SIZE))
)
raw_evlr.record_data = data_stream.read(
raw_evlr.header.record_length_after_header
)
return raw_evlr
[docs] def size_in_bytes(self):
return EVLR_HEADER_SIZE + self.header.record_length_after_header
[docs] def write_to(self, out):
out.write(bytes(self.header))
out.write(self.record_data)
def __repr__(self):
return "<RawEVLR(user_id: {}, record_id: {}, record_length_after_header: {})>".format(
self.header.user_id,
self.header.record_id,
self.header.record_length_after_header,
)
[docs]class EVLR(rawvlr.VLR):
pass
[docs]def evlr_factory(raw):
return known.vlr_factory(raw)
[docs]class RawEVLRList(vlrlist.RawVLRList):
[docs] @classmethod
def from_list(cls, vlrs):
raw_vlrs = cls()
for vlr in vlrs:
raw = RawEVLR()
raw.header.user_id = vlr.user_id.encode("utf8")
raw.header.description = vlr.description.encode("utf8")
raw.header.record_id = vlr.record_id
raw.record_data = vlr.record_data_bytes()
raw_vlrs.append(raw)
return raw_vlrs
[docs]class EVLRList(vlrlist.VLRList):
[docs] @classmethod
def read_from(cls, data_stream, num_to_read):
evlr_list = cls()
for _ in range(num_to_read):
raw = RawEVLR.read_from(data_stream)
try:
evlr_list.append(evlr_factory(raw))
except UnicodeDecodeError:
logger.error("Failed to decode VLR: {}".format(raw))
return evlr_list