X-Git-Url: https://code.kerkeslager.com/?p=sandbox;a=blobdiff_plain;f=serial%2Fserial%2Fbinary.py;fp=serial%2Fserial%2Fbinary.py;h=d19a2211071dadeb96ed915944e80830616fae1c;hp=960acef8bd02243ed01beabaa2c551eec5b9a1dd;hb=4689baa84252ba845bfba1dd6faea9ab3f103051;hpb=6cb74967b5b52c7b072c0477aa19e52f30b67d7a diff --git a/serial/serial/binary.py b/serial/serial/binary.py index 960acef..d19a221 100644 --- a/serial/serial/binary.py +++ b/serial/serial/binary.py @@ -40,6 +40,26 @@ def _serialize_tuple(to): return struct.pack('!BI', tags.TUPLE, len(payload)) + payload +def _serialize_list(to): + assert isinstance(to.instance, list) + + # TODO Actually handle this case somehow + assert len(to.instance) > 0 + + # TODO Do this a better way + serialized_items = [serialize(i) for i in to.instance] + list_tag = serialized_items[0][0] + + def check_and_strip_prefix(b): + item_tag = b[0] + assert list_tag == item_tag + return b[1:] + + payload = b''.join(check_and_strip_prefix(si) for si in serialized_items) + + fmt = '!BBI' + + return struct.pack(fmt, tags.LIST, list_tag, len(payload)) + payload _TAGS_TO_SERIALIZERS = { tags.NULL: _make_tag_only_serializer(tags.NULL, None), @@ -58,6 +78,7 @@ _TAGS_TO_SERIALIZERS = { tags.UTF16: _make_string_serializer(lambda s: s.encode('utf-16')), tags.UTF32: _make_string_serializer(lambda s: s.encode('utf-32')), tags.TUPLE: _serialize_tuple, + tags.LIST: _serialize_list, } def serialize(to): @@ -119,6 +140,26 @@ def _deserialize_tuple(b): return bytes_read, tags.TaggedObject(tag = tags.TUPLE, instance = tuple(instance)) +def _deserialize_list(b): + list_tag_bytes = b.read(1) + assert len(list_tag_bytes) == 1 + list_tag = list_tag_bytes[0] + + bytes_read, payload = _read_length_then_payload(b) + + payload_stream = io.BytesIO(payload) + + total_bytes_read = 0 + instance = [] + + while total_bytes_read < len(payload): + partial_bytes_read, item = _TAGS_TO_PARSERS[list_tag](payload_stream) + total_bytes_read += partial_bytes_read + instance.append(item) + + # TODO Return tags = (tags.LIST, list_tag) to function like a generic type + return bytes_read, tags.TaggedObject(tag = tags.LIST, instance = instance) + _TAGS_TO_PARSERS = { tags.NULL: _make_tag_only_parser(tags.NULL, None), tags.TRUE: _make_tag_only_parser(tags.TRUE, True), @@ -136,6 +177,7 @@ _TAGS_TO_PARSERS = { tags.UTF16: _make_string_deserializer(tags.UTF16, lambda b: b.decode('utf-16')), tags.UTF32: _make_string_deserializer(tags.UTF32, lambda b: b.decode('utf-32')), tags.TUPLE: _deserialize_tuple, + tags.LIST: _deserialize_list, } def _deserialize_partial(b):