diff --git a/chirp/drivers/icf.py b/chirp/drivers/icf.py index c0acbd668..843204dfe 100644 --- a/chirp/drivers/icf.py +++ b/chirp/drivers/icf.py @@ -1034,7 +1034,7 @@ def get_bank_model(self): return None -def warp_byte_size(inbytes, obw=8, ibw=8): +def warp_byte_size(inbytes, obw=8, ibw=8, iskip=0, opad=0): """Convert between "byte sizes". This will pack N-bit characters into a sequence of 8-bit bytes, @@ -1042,17 +1042,23 @@ def warp_byte_size(inbytes, obw=8, ibw=8): ibw (input bit width) is the width of the storage obw (output bit width) is the width of the characters to extract + iskip is the number of input padding bits to skip + opad is the number of output zero padding bits to add ibw=8,obw=7 will pull seven-bit characters from a sequence of bytes ibw=7,obw=8 will pack seven-bit characters into a sequence of bytes """ if isinstance(inbytes, str): inbytes = [ord(x) for x in inbytes] - outbit = 0 + outbit = opad tmp = 0 stripmask = 1 << (ibw - 1) for byte in inbytes: inbit = 0 + while iskip: + byte = (byte << 1) & 0xFF + inbit += 1 + iskip -= 1 for i in range(0, max(obw, ibw - inbit)): if inbit == ibw: # Move to next char diff --git a/tests/unit/test_icf.py b/tests/unit/test_icf.py index 08bd74d04..cc30ee23b 100644 --- a/tests/unit/test_icf.py +++ b/tests/unit/test_icf.py @@ -159,3 +159,32 @@ def test_pack(self): f = icf.IcfFrame(icf.ADDR_PC, icf.ADDR_RADIO, icf.CMD_CLONE_ID) f.payload = b'\x01\x02' self.assertEqual(b'\xfe\xfe\xee\xef\xe0\x01\x02\xfd', f.pack()) + + +class TestICFUtil(unittest.TestCase): + def test_warp_byte_size(self): + # 4-bit chars to 8-bit bytes + input = bytes([0x12, 0x34]) + output = bytes(icf.warp_byte_size(input, obw=4)) + self.assertEqual(b'\x01\x02\x03\x04', output) + + def test_warp_byte_size_skip(self): + # 4-bit chars to 8-bit bytes with 4 bits of padding ignored + input = bytes([0x12, 0x34]) + output = bytes(icf.warp_byte_size(input, obw=4, iskip=4)) + self.assertEqual(b'\x02\x03\x04', output) + + def test_warp_byte_size_pad(self): + # 8-bit bytes to 4-bit chars, with 4 bits of padding added + input = bytes([2, 3, 4]) + output = bytes(icf.warp_byte_size(input, ibw=4, opad=4)) + self.assertEqual(b'\x02\x34', output) + + def test_warp_byte_size_symmetric_padded(self): + # Make sure we can go from 8->4-> with padding and get back what we + # put in + ref = bytes([1, 2, 3, 4, 5, 6]) + stored = bytes(icf.warp_byte_size(bytes(ref), ibw=6, opad=4)) + self.assertEqual(5, len(bytes(stored))) + self.assertEqual(ref, + bytes(icf.warp_byte_size(stored, obw=6, iskip=4)))