Binary object serialization
[sandbox] / serial / serial / binary.py
index d19a221..444db4f 100644 (file)
@@ -61,6 +61,27 @@ def _serialize_list(to):
 
     return struct.pack(fmt, tags.LIST, list_tag, len(payload)) + payload
 
+def _serialize_object(to):
+    assert isinstance(to.instance, list)
+
+    # TODO Actually handle this case somehow
+    assert len(to.instance) > 0
+
+    # TODO Do this a better way
+    serialized_kvps = [(serialize(k), serialize(v)) for k,v in to.instance]
+    key_type_tag = serialized_kvps[0][0][0]
+
+    def check_and_strip_prefix(b):
+        item_tag = b[0]
+        assert key_type_tag == item_tag
+        return b[1:]
+
+    payload = b''.join(check_and_strip_prefix(k) + v for k,v in serialized_kvps)
+
+    fmt = '!BBI'
+
+    return struct.pack(fmt, tags.OBJECT, key_type_tag, len(payload)) + payload
+
 _TAGS_TO_SERIALIZERS = {
     tags.NULL: _make_tag_only_serializer(tags.NULL, None),
     tags.TRUE: _make_tag_only_serializer(tags.TRUE, True),
@@ -79,6 +100,7 @@ _TAGS_TO_SERIALIZERS = {
     tags.UTF32: _make_string_serializer(lambda s: s.encode('utf-32')),
     tags.TUPLE: _serialize_tuple,
     tags.LIST: _serialize_list,
+    tags.OBJECT: _serialize_object,
 }
 
 def serialize(to):
@@ -160,6 +182,9 @@ def _deserialize_list(b):
     # TODO Return tags = (tags.LIST, list_tag) to function like a generic type
     return bytes_read, tags.TaggedObject(tag = tags.LIST, instance = instance)
 
+def _deserialize_object(b):
+    raise Exception('Not implemented')
+
 _TAGS_TO_PARSERS = {
     tags.NULL: _make_tag_only_parser(tags.NULL, None),
     tags.TRUE: _make_tag_only_parser(tags.TRUE, True),
@@ -178,6 +203,7 @@ _TAGS_TO_PARSERS = {
     tags.UTF32: _make_string_deserializer(tags.UTF32, lambda b: b.decode('utf-32')),
     tags.TUPLE: _deserialize_tuple,
     tags.LIST: _deserialize_list,
+    tags.OBJECT: _deserialize_object,
 }
 
 def _deserialize_partial(b):