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 cb68d4a2d2429817614af124c59e4ecb7d3bf573..dd14a7db45bcb8744c0bb39c438653cdffae0857 100644 |
--- a/mojo/public/python/mojo/bindings/serialization.py |
+++ b/mojo/public/python/mojo/bindings/serialization.py |
@@ -16,28 +16,42 @@ class SerializationException(Exception): |
pass |
+class DeserializationException(Exception): |
+ """Error when strying to deserialize a struct.""" |
+ pass |
+ |
+ |
class Serialization(object): |
""" |
Helper class to serialize/deserialize a struct. |
""" |
def __init__(self, groups): |
- self._groups = groups |
self.version = _GetVersion(groups) |
+ self._groups = groups |
main_struct = _GetStruct(groups) |
self.size = HEADER_STRUCT.size + main_struct.size |
self._struct_per_version = { |
- self.version: main_struct, |
+ self.version: main_struct, |
+ } |
+ self._groups_per_version = { |
+ self.version: groups, |
} |
def _GetMainStruct(self): |
return self._GetStruct(self.version) |
+ def _GetGroups(self, version): |
+ # If asking for a version greater than the last known. |
+ version = min(version, self.version) |
+ if version not in self._groups_per_version: |
+ self._groups_per_version[version] = _FilterGroups(self._groups, version) |
+ return self._groups_per_version[version] |
+ |
def _GetStruct(self, version): |
- # If asking for a greater ver |
+ # If asking for a version greater than the last known. |
version = min(version, self.version) |
if version not in self._struct_per_version: |
- self._struct_per_version[version] = _GetStruct(_FilterGroups(self._groups, |
- version)) |
+ self._struct_per_version[version] = _GetStruct(self._GetGroups(version)) |
return self._struct_per_version[version] |
def Serialize(self, obj, handle_offset): |
@@ -64,6 +78,18 @@ class Serialization(object): |
self._GetMainStruct().pack_into(data, HEADER_STRUCT.size, *to_pack) |
return (data, handles) |
+ def Deserialize(self, fields, data, handles): |
+ (_, version) = HEADER_STRUCT.unpack_from(data) |
+ version_struct = self._GetStruct(version) |
+ entitities = version_struct.unpack_from(data, HEADER_STRUCT.size) |
+ filtered_groups = self._GetGroups(version) |
+ position = HEADER_STRUCT.size |
+ for (group, value) in zip(filtered_groups, entitities): |
+ position = position + NeededPaddingForAlignment(position, |
+ group.GetByteSize()) |
+ fields.update(group.Deserialize(value, data[position:], handles)) |
+ position += group.GetByteSize() |
+ |
def NeededPaddingForAlignment(value, alignment=8): |
"""Returns the padding necessary to align value with the given alignment.""" |
@@ -77,7 +103,7 @@ def _GetVersion(groups): |
def _FilterGroups(groups, version): |
- return [group for group in groups if group.version < version] |
+ return [group for group in groups if group.GetVersion() < version] |
def _GetStruct(groups): |