feat: Symbol Class
Signed-off-by: Philipp Le <philipp@philipple.de>
Change-Id: I906abce077026380ce52b9fd90d81b0f13c06416
diff --git a/dcs/utils/symbols.py b/dcs/utils/symbols.py
new file mode 100644
index 0000000..9d4c521
--- /dev/null
+++ b/dcs/utils/symbols.py
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from typing import List
+
+
+@dataclass
+class Symbols:
+ symbols: List[int]
+ bits_per_symbol: int
+
+ def reencode(self, new_bits_per_symbol: int) -> Symbols:
+ assert new_bits_per_symbol > 0, 'Number of bits must be at least 1'
+ mask = (1 << new_bits_per_symbol) - 1
+ tmp_word = 0
+ head = 0
+ new_symbols = []
+ for sym in self.symbols:
+ tmp_word |= (sym << head)
+ head += self.bits_per_symbol
+ while head >= new_bits_per_symbol:
+ new_symbols.append(tmp_word & mask)
+ tmp_word >>= new_bits_per_symbol
+ head -= new_bits_per_symbol
+ if head > 0:
+ new_symbols.append(tmp_word & mask)
+
+ return Symbols(
+ symbols=new_symbols,
+ bits_per_symbol=new_bits_per_symbol,
+ )
+
+ def to_bit_str(self) -> List[str]:
+ fmt = '{:0%db}' % self.bits_per_symbol
+ return [fmt.format(sym) for sym in self.symbols]
+
+ def __len__(self):
+ return len(self.symbols)
+
+
+class MessageBinarySerializer:
+ def __init__(self, message: str):
+ self.message = message
+ self.symbols = None
+
+ def to_symbols(self) -> Symbols:
+ if self.symbols is None:
+ ba = bytearray(self.message, 'utf-8')
+ self.symbols = Symbols(
+ symbols=[int(sym) for sym in ba],
+ bits_per_symbol=8,
+ )
+ return self.symbols