Chromium Code Reviews| 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..9a4b6a9bafbd781e70d47a14a540dc69de1ff4f5 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,20 @@ class Serialization(object): |
| self._GetMainStruct().pack_into(data, HEADER_STRUCT.size, *to_pack) |
| return (data, handles) |
| + def Deserialize(self, fields, data, handles): |
| + if not isinstance(data, buffer): |
|
sdefresne
2014/09/19 15:18:30
Why not simply "data = buffer(data)"? I've tested,
qsr
2014/09/19 15:45:27
Just to prevent creating some more object for no g
|
| + data = buffer(data) |
| + (_, 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, buffer(data, position), handles)) |
| + position += group.GetByteSize() |
| + |
| def NeededPaddingForAlignment(value, alignment=8): |
| """Returns the padding necessary to align value with the given alignment.""" |
| @@ -77,7 +105,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): |