Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Unified Diff: mojo/public/python/mojo_bindings/serialization.py

Issue 1218023006: Implement python mojo bindings unions. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/public/python/mojo_bindings/serialization.py
diff --git a/mojo/public/python/mojo_bindings/serialization.py b/mojo/public/python/mojo_bindings/serialization.py
index 32f60f066dbad9a320b08fb40b81d59532f60433..b84bfc1124bef6e4991669942f3d6e2254e02d8c 100644
--- a/mojo/public/python/mojo_bindings/serialization.py
+++ b/mojo/public/python/mojo_bindings/serialization.py
@@ -7,9 +7,12 @@
import struct
-# Format of a header for a struct or an array.
+# Format of a header for a struct, array or union.
HEADER_STRUCT = struct.Struct("<II")
+# Format for a pointer.
+POINTER_STRUCT = struct.Struct("<Q")
+
def Flatten(value):
"""Flattens nested lists/tuples into an one-level list. If value is not a
@@ -218,3 +221,69 @@ def _GetStruct(groups):
if alignment_needed:
codes.append('x' * alignment_needed)
return struct.Struct(''.join(codes))
+
+
+class UnionSerializer(object):
qsr 2015/07/17 10:53:58 This code needs comments. I find it really hard to
azani 2015/07/17 20:38:15 I have added some comments. Let me know if they pr
+ """
+ Helper class to serialize/deserialize a union.
+ """
+ def __init__(self, fields):
+ self._fields = {field.index: field for field in fields}
+
+ def SerializeInline(self, union, handle_offset):
+ data = bytearray()
+ field = self._fields[union.tag]
+
+ (entry, handles) = field.field_type.Serialize(
+ union.data, 8, data, handle_offset)
+
+ if hasattr(field.field_type, 'union_type'):
qsr 2015/07/17 10:53:58 If you cannot do usual instanceof calls, then adds
azani 2015/07/17 20:38:15 Done.
+ nested_union = bytearray(16)
+ HEADER_STRUCT.pack_into(nested_union, 0, entry[0], entry[1])
+ POINTER_STRUCT.pack_into(nested_union, 8, entry[2])
+
+ data = nested_union + data
+ entry = 8
+
+ return (16, union.tag, entry, data), handles
qsr 2015/07/17 10:53:58 I am clearly missing something. Let say that you
azani 2015/07/17 20:38:16 In your exampled Serialize is PointerType.Serializ
+
+ def Serialize(self, union, handle_offset):
+ (size, tag, entry, extra_data), handles = self.SerializeInline(
+ union, handle_offset)
+ data = bytearray(16)
+ data.extend(extra_data)
+
+ field = self._fields[union.tag]
+
+ HEADER_STRUCT.pack_into(data, 0, size, tag)
+ typecode = field.GetTypeCode()
+ if hasattr(field.field_type, 'union_type'):
+ typecode = 'Q'
+
+ struct.pack_into('<%s' % typecode, data, 8, entry)
+ return data, handles
+
+ def Deserialize(self, context, union_class):
+ if len(context.data) < HEADER_STRUCT.size:
+ raise DeserializationException(
+ 'Available data too short to contain header.')
+ (size, tag) = HEADER_STRUCT.unpack_from(context.data)
+ if size == 0:
+ return None
+
+ if size != 16:
+ raise DeserializationException('Invalid union size %s' % size)
+
+ field = self._fields[tag]
+ if hasattr(field.field_type, 'union_type'):
+ ptr = POINTER_STRUCT.unpack_from(context.data, 8)[0]
+ value = field.field_type.Deserialize(ptr, context.GetSubContext(ptr+8))
+ else:
+ raw_value = struct.unpack_from(
+ field.GetTypeCode(), context.data, 8)[0]
+ value = field.field_type.Deserialize(raw_value, context.GetSubContext(8))
+
+ union = union_class.__new__(union_class)
+ union._tag = tag
+ union._data = value
+ return union

Powered by Google App Engine
This is Rietveld 408576698