def test_chars_invalid_length(self): u = Fields() u.add(CH(5, 'string')) with pytest.raises(ValueError): u.unpack(bytearray.fromhex('31 32')) # Too few bytes with pytest.raises(ValueError): u.unpack(bytearray.fromhex('31 32 33 34')) # Too few bytes
def test_basic_unpack(self): u = Fields() u.add(CH(4, 'string')) u.unpack(bytearray.fromhex('41 42 43 44')) assert u.string == 'ABCD'
def test_chars_invalid_unicode(self): u = Fields() u.add(CH(2, 'string')) with pytest.raises(ValueError): u.unpack(bytearray.fromhex('d8 00')) # UTF16 reserved code point
def test_chars_trailing_zeroes_removed(self): u = Fields() u.add(CH(10, 'string')) u.unpack(bytearray.fromhex('41 42 43 44 45 00 00 00 00 00')) assert u.string == 'ABCDE'
class UbxFrame(object): CID = UbxCID(0, 0) NAME = 'UBX' SYNC_1 = 0xb5 SYNC_2 = 0x62 @classmethod def construct(cls, data): obj = cls() obj.data = data obj.unpack() return obj @classmethod def MATCHES(cls, cid): return cls.CID == cid def __init__(self): super().__init__() self.data = bytearray() # TODO: Do we need checksum as member? self.checksum = Checksum() self.f = Fields() def to_bytes(self): self._calc_checksum() msg = bytearray([UbxFrame.SYNC_1, UbxFrame.SYNC_2]) msg.append(self.CID.cls) msg.append(self.CID.id) length = len(self.data) msg.append((length >> 0) % 0xFF) msg.append((length >> 8) % 0xFF) msg += self.data msg.append(self.cka) msg.append(self.ckb) return msg def get(self, name): return self.f.get(name) def pack(self): self.data = self.f.pack() def unpack(self): self.f.unpack(self.data) def _calc_checksum(self): self.checksum.reset() self.checksum.add(self.CID.cls) self.checksum.add(self.CID.id) length = len(self.data) self.checksum.add((length >> 0) & 0xFF) self.checksum.add((length >> 8) & 0xFF) for d in self.data: self.checksum.add(d) self.cka, self.ckb = self.checksum.value() def __str__(self): res = f'{self.NAME} {self.CID}' res += str(self.f) return res