Loading files
"""
Tinymovr Codecs Module
Copyright Ioannis Chatzikonstantinou 2020-2023
Implements codecs for various datatypes.
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
"""
from typing import Dict, List
import struct
from avlos.datatypes import DataType
class Codec:
"""
Generic codec base class
"""
def serialize(self, value) -> bytes:
raise NotImplementedError()
def deserialize(self, buffer: bytes):
raise NotImplementedError()
class StructCodec(Codec):
def __init__(self, struct_format, target_type: type):
self._struct_format = struct_format
self._target_type = target_type
def serialize(self, value) -> bytes:
value = self._target_type(value)
return struct.pack(self._struct_format, value)
def deserialize(self, buffer: bytes):
size = struct.calcsize(self._struct_format)
trimmed_buffer: bytes = buffer[: size]
value = struct.unpack(self._struct_format, trimmed_buffer)
value = value[0] if len(value) == 1 else value
return self._target_type(value), size
class StringCodec:
def serialize(self, value) -> bytes:
value += '\x00'
value = self._target_type(value)
return struct.pack(self._struct_format, value)
def deserialize(self, buffer: bytes):
# Use the length of the buffer directly for unpacking
size = len(buffer)
value = struct.unpack(f"{size}s", buffer)
value = value[0] if len(value) == 1 else value
return value.rstrip(b'\x00').decode('utf-8'), size
codecs: Dict[DataType, StructCodec] = {
DataType.BOOL: StructCodec("<?", bool),
DataType.INT8: StructCodec("<b", int),
DataType.UINT8: StructCodec("<B", int),
DataType.INT16: StructCodec("<h", int),
DataType.UINT16: StructCodec("<H", int),
DataType.INT32: StructCodec("<i", int),
DataType.UINT32: StructCodec("<I", int),
DataType.FLOAT: StructCodec("<f", float),
DataType.STR: StringCodec(),
}
class MultibyteCodec(Codec):
def serialize(self, values, *args) -> bytearray:
"""
Serialize a series of variables to a bytes array
"""
buffer = bytearray()
assert len(values) == len(args)
for value, dtype in zip(values, args):
buffer.extend(codecs[dtype].serialize(value))
return buffer
def deserialize(self, data, *args) -> List:
"""
Deserialize a bytes array to a tuple of values
"""
index: int = 0
values = []
for dtype in args:
value, size = codecs[dtype].deserialize(data[index:])
values.append(value)
index += size
return values
e258911dbThis file is pinned to the selected release. Download the original to open it in your design tool.