def decode(cls, data): "Decodes the PDU from the given data bytes" new_pdu = cls() idx = 0 for member in cls._orderedKeys: if not member.startswith("__") and not callable(getattr(cls, member)): M = getattr(cls, member) if Integer == type(M): # in [Integer, CString, String, TLV] s = data[idx:idx+M.length] idx = idx + M.length setattr(new_pdu, member, Integer.decode(s)) elif CString == type(M): # Need to find the next NULL character which is the string's end try: nidx = data.index(b'\x00', idx) s = data[idx:nidx+1] idx = nidx + 1 setattr(new_pdu, member, CString.decode(s)) except: raise RuntimeError("Cannot find end for CString type") elif String == type(M): # TODO: Since string fields can either be fixed length or have a corresponding # length field specifying their length, decoding this requires some info to # be passed from within the PDU class. pass elif TLV == type(M): pass return new_pdu
def test_04_cstring_decode(): "Test to check CString decoding" assert b"Hello" == CString.decode(b'Hello\x00').value assert b"123456789" == CString.decode(b'123456789\x00').value assert b"A2F5ED278FC" == CString.decode(b'A2F5ED278FC\x00').value