| 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 2c0478f0408bee09094ecd8d51ed1b9ca472ce58..b5ea1bd8a9f3d2e420c3c3db023d4889fd441cb6 100644
|
| --- a/mojo/public/python/mojo/bindings/serialization.py
|
| +++ b/mojo/public/python/mojo/bindings/serialization.py
|
| @@ -21,6 +21,68 @@ class DeserializationException(Exception):
|
| pass
|
|
|
|
|
| +class DeserializationContext(object):
|
| +
|
| + def ClaimHandle(self, handle):
|
| + raise NotImplementedError()
|
| +
|
| + def ClaimMemory(self, start, size):
|
| + raise NotImplementedError()
|
| +
|
| + def GetSubContext(self, offset):
|
| + raise NotImplementedError()
|
| +
|
| + def IsInitialContext(self):
|
| + raise NotImplementedError()
|
| +
|
| +
|
| +class RootDeserializationContext(DeserializationContext):
|
| + def __init__(self, data, handles):
|
| + if isinstance(data, buffer):
|
| + self.data = data
|
| + else:
|
| + self.data = buffer(data)
|
| + self._handles = handles
|
| + self._next_handle = 0;
|
| + self._next_memory = 0;
|
| +
|
| + def ClaimHandle(self, handle):
|
| + if handle < self._next_handle:
|
| + raise DeserializationException('Accessing handles out of order.')
|
| + self._next_handle = handle + 1
|
| + return self._handles[handle]
|
| +
|
| + def ClaimMemory(self, start, size):
|
| + if start < self._next_memory:
|
| + raise DeserializationException('Accessing buffer out of order.')
|
| + self._next_memory = start + size
|
| +
|
| + def GetSubContext(self, offset):
|
| + return _ChildDeserializationContext(self, offset)
|
| +
|
| + def IsInitialContext(self):
|
| + return True
|
| +
|
| +
|
| +class _ChildDeserializationContext(DeserializationContext):
|
| + def __init__(self, parent, offset):
|
| + self._parent = parent
|
| + self._offset = offset
|
| + self.data = buffer(parent.data, offset)
|
| +
|
| + def ClaimHandle(self, handle):
|
| + return self._parent.ClaimHandle(handle)
|
| +
|
| + def ClaimMemory(self, start, size):
|
| + return self._parent.ClaimMemory(self._offset + start, size)
|
| +
|
| + def GetSubContext(self, offset):
|
| + return self._parent.GetSubContext(self._offset + offset)
|
| +
|
| + def IsInitialContext(self):
|
| + return False
|
| +
|
| +
|
| class Serialization(object):
|
| """
|
| Helper class to serialize/deserialize a struct.
|
| @@ -78,18 +140,23 @@ 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):
|
| - data = buffer(data)
|
| - (_, version) = HEADER_STRUCT.unpack_from(data)
|
| + def Deserialize(self, fields, context):
|
| + if len(context.data) < HEADER_STRUCT.size:
|
| + raise DeserializationException(
|
| + 'Available data too short to contain header.')
|
| + (size, version) = HEADER_STRUCT.unpack_from(context.data)
|
| + if len(context.data) < size or size < HEADER_STRUCT.size:
|
| + raise DeserializationException('Header size is incorrect.')
|
| + if context.IsInitialContext():
|
| + context.ClaimMemory(0, size)
|
| version_struct = self._GetStruct(version)
|
| - entitities = version_struct.unpack_from(data, HEADER_STRUCT.size)
|
| + entitities = version_struct.unpack_from(context.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))
|
| + fields.update(group.Deserialize(value, context.GetSubContext(position)))
|
| position += group.GetByteSize()
|
|
|
|
|
|
|