from .message_coder import message_coder from .field_decoder import field_decoder from .message import message from .cutter import cutter class message_decoder(message_coder): def __init__(self, content: bytes) -> None: self.__content = content def extract_type(self) -> int: return int.from_bytes(self.__content[:self.type_size()]) def __check_crc(self, target: bytes, crc: bytes) -> bool: return self._get_hash(target) == crc def build(self, target: type) -> message: if not issubclass(target, message): raise RuntimeError("Target must be subclass of message.") result = target() self.fill(result) return result def fill(self, target: message) -> object: if self.extract_type() != target.get_type(): raise TypeError("Received message ID is not correct.") handler = cutter(self.__content) if target.encoder().size != handler.size: raise ValueError("Received content lenght is not correct") crc = handler.cut(self.hash_size()) if not self.__check_crc(handler.content, crc): raise ConnectionError("Message CRC checksum is not correct.") handler.trim(self.type_size()) for count in target.fields: field_bytes = handler.trim(count.size) count.decoder().load(field_bytes) return self