| Index: mojo/public/python/mojo/bindings/descriptor.py
|
| diff --git a/mojo/public/python/mojo/bindings/descriptor.py b/mojo/public/python/mojo/bindings/descriptor.py
|
| index f190d2befcfd7f6108db3a2e867c4a74bf84b28f..0df0bd606df25371e356c0022c202feee63ea0cf 100644
|
| --- a/mojo/public/python/mojo/bindings/descriptor.py
|
| +++ b/mojo/public/python/mojo/bindings/descriptor.py
|
| @@ -72,7 +72,7 @@ class SerializableType(Type):
|
| """
|
| raise NotImplementedError()
|
|
|
| - def Deserialize(self, value, data, handles):
|
| + def Deserialize(self, value, context):
|
| """
|
| Deserialize a value of this type.
|
|
|
| @@ -106,7 +106,7 @@ class NumericType(SerializableType):
|
| def Serialize(self, value, data_offset, data, handle_offset):
|
| return (value, [])
|
|
|
| - def Deserialize(self, value, data, handles):
|
| + def Deserialize(self, value, context):
|
| return value
|
|
|
|
|
| @@ -161,21 +161,31 @@ class PointerType(SerializableType):
|
| return (0, [])
|
| return self.SerializePointer(value, data_offset, data, handle_offset)
|
|
|
| - def Deserialize(self, value, data, handles):
|
| + def Deserialize(self, value, context):
|
| if value == 0:
|
| if not self.nullable:
|
| raise serialization.DeserializationException(
|
| 'Trying to deserialize null for non nullable type.')
|
| return None
|
| - pointed_data = buffer(data, value)
|
| - (size, nb_elements) = serialization.HEADER_STRUCT.unpack_from(pointed_data)
|
| - return self.DeserializePointer(size, nb_elements, pointed_data, handles)
|
| + if value % 8 != 0:
|
| + raise serialization.DeserializationException(
|
| + 'Pointer alignment is incorrect.')
|
| + sub_context = context.GetSubContext(value)
|
| + if len(sub_context.data) < serialization.HEADER_STRUCT.size:
|
| + raise serialization.DeserializationException(
|
| + 'Available data too short to contain header.')
|
| + (size, nb_elements) = serialization.HEADER_STRUCT.unpack_from(
|
| + sub_context.data)
|
| + if len(sub_context.data) < size or size < serialization.HEADER_STRUCT.size:
|
| + raise serialization.DeserializationException('Header size is incorrect.')
|
| + sub_context.ClaimMemory(0, size)
|
| + return self.DeserializePointer(size, nb_elements, sub_context)
|
|
|
| def SerializePointer(self, value, data_offset, data, handle_offset):
|
| """Serialize the not null value."""
|
| raise NotImplementedError()
|
|
|
| - def DeserializePointer(self, size, nb_elements, data, handles):
|
| + def DeserializePointer(self, size, nb_elements, context):
|
| raise NotImplementedError()
|
|
|
|
|
| @@ -204,9 +214,8 @@ class StringType(PointerType):
|
| return self._array_type.SerializeArray(
|
| string_array, data_offset, data, handle_offset)
|
|
|
| - def DeserializePointer(self, size, nb_elements, data, handles):
|
| - string_array = self._array_type.DeserializeArray(
|
| - size, nb_elements, data, handles)
|
| + def DeserializePointer(self, size, nb_elements, context):
|
| + string_array = self._array_type.DeserializeArray(size, nb_elements, context)
|
| return unicode(string_array.tostring(), 'utf8')
|
|
|
|
|
| @@ -226,14 +235,13 @@ class BaseHandleType(SerializableType):
|
| return (-1, [])
|
| return (handle_offset, [handle])
|
|
|
| - def Deserialize(self, value, data, handles):
|
| + def Deserialize(self, value, context):
|
| if value == -1:
|
| if not self.nullable:
|
| raise serialization.DeserializationException(
|
| 'Trying to deserialize null for non nullable type.')
|
| return self.FromHandle(mojo.system.Handle())
|
| - # TODO(qsr) validate handle order
|
| - return self.FromHandle(handles[value])
|
| + return self.FromHandle(context.ClaimHandle(value))
|
|
|
| def FromHandle(self, handle):
|
| raise NotImplementedError()
|
| @@ -326,12 +334,18 @@ class BaseArrayType(PointerType):
|
| """Serialize the not null array."""
|
| raise NotImplementedError()
|
|
|
| - def DeserializePointer(self, size, nb_elements, data, handles):
|
| - if self.length != 0 and size != self.length:
|
| + def DeserializePointer(self, size, nb_elements, context):
|
| + if self.length != 0 and nb_elements != self.length:
|
| raise serialization.DeserializationException('Incorrect array size')
|
| - return self.DeserializeArray(size, nb_elements, data, handles)
|
| + if (size <
|
| + serialization.HEADER_STRUCT.size + self.SizeForLength(nb_elements)):
|
| + raise serialization.DeserializationException('Incorrect array size')
|
| + return self.DeserializeArray(size, nb_elements, context)
|
| +
|
| + def DeserializeArray(self, size, nb_elements, context):
|
| + raise NotImplementedError()
|
|
|
| - def DeserializeArray(self, size, nb_elements, data, handles):
|
| + def SizeForLength(self, nb_elements):
|
| raise NotImplementedError()
|
|
|
|
|
| @@ -351,9 +365,8 @@ class BooleanArrayType(BaseArrayType):
|
| converted = array.array('B', [_ConvertBooleansToByte(x) for x in groups])
|
| return _SerializeNativeArray(converted, data_offset, data, len(value))
|
|
|
| - def DeserializeArray(self, size, nb_elements, data, handles):
|
| - converted = self._array_type.DeserializeArray(
|
| - size, nb_elements, data, handles)
|
| + def DeserializeArray(self, size, nb_elements, context):
|
| + converted = self._array_type.DeserializeArray(size, nb_elements, context)
|
| elements = list(itertools.islice(
|
| itertools.chain.from_iterable(
|
| [_ConvertByteToBooleans(x, 8) for x in converted]),
|
| @@ -361,6 +374,9 @@ class BooleanArrayType(BaseArrayType):
|
| nb_elements))
|
| return elements
|
|
|
| + def SizeForLength(self, nb_elements):
|
| + return (nb_elements + 7) // 8
|
| +
|
|
|
| class GenericArrayType(BaseArrayType):
|
| """Type object for arrays of pointers."""
|
| @@ -400,18 +416,22 @@ class GenericArrayType(BaseArrayType):
|
| *to_pack)
|
| return (data_offset, returned_handles)
|
|
|
| - def DeserializeArray(self, size, nb_elements, data, handles):
|
| + def DeserializeArray(self, size, nb_elements, context):
|
| values = struct.unpack_from(
|
| '%d%s' % (nb_elements, self.sub_type.GetTypeCode()),
|
| - buffer(data, serialization.HEADER_STRUCT.size))
|
| + buffer(context.data, serialization.HEADER_STRUCT.size))
|
| result = []
|
| - position = serialization.HEADER_STRUCT.size
|
| + sub_context = context.GetSubContext(serialization.HEADER_STRUCT.size)
|
| for value in values:
|
| - result.append(
|
| - self.sub_type.Deserialize(value, buffer(data, position), handles))
|
| - position += self.sub_type.GetByteSize()
|
| + result.append(self.sub_type.Deserialize(
|
| + value,
|
| + sub_context))
|
| + sub_context = sub_context.GetSubContext(self.sub_type.GetByteSize())
|
| return result
|
|
|
| + def SizeForLength(self, nb_elements):
|
| + return nb_elements * self.sub_type.GetByteSize();
|
| +
|
|
|
| class NativeArrayType(BaseArrayType):
|
| """Type object for arrays of native types."""
|
| @@ -419,6 +439,7 @@ class NativeArrayType(BaseArrayType):
|
| def __init__(self, typecode, nullable=False, length=0):
|
| BaseArrayType.__init__(self, nullable, length)
|
| self.array_typecode = typecode
|
| + self.element_size = struct.calcsize('<%s' % self.array_typecode)
|
|
|
| def Convert(self, value):
|
| if value is None:
|
| @@ -431,13 +452,16 @@ class NativeArrayType(BaseArrayType):
|
| def SerializeArray(self, value, data_offset, data, handle_offset):
|
| return _SerializeNativeArray(value, data_offset, data, len(value))
|
|
|
| - def DeserializeArray(self, size, nb_elements, data, handles):
|
| + def DeserializeArray(self, size, nb_elements, context):
|
| result = array.array(self.array_typecode)
|
| - result.fromstring(buffer(data,
|
| + result.fromstring(buffer(context.data,
|
| serialization.HEADER_STRUCT.size,
|
| size - serialization.HEADER_STRUCT.size))
|
| return result
|
|
|
| + def SizeForLength(self, nb_elements):
|
| + return nb_elements * self.element_size
|
| +
|
|
|
| class StructType(PointerType):
|
| """Type object for structs."""
|
| @@ -469,8 +493,8 @@ class StructType(PointerType):
|
| data.extend(new_data)
|
| return (data_offset, new_handles)
|
|
|
| - def DeserializePointer(self, size, nb_elements, data, handles):
|
| - return self.struct_type.Deserialize(data, handles)
|
| + def DeserializePointer(self, size, nb_elements, context):
|
| + return self.struct_type.Deserialize(context)
|
|
|
|
|
| class MapType(SerializableType):
|
| @@ -511,8 +535,8 @@ class MapType(SerializableType):
|
| s = self.struct(keys=keys, values=values)
|
| return self.struct_type.Serialize(s, data_offset, data, handle_offset)
|
|
|
| - def Deserialize(self, value, data, handles):
|
| - s = self.struct_type.Deserialize(value, data, handles)
|
| + def Deserialize(self, value, context):
|
| + s = self.struct_type.Deserialize(value, context)
|
| if s:
|
| if len(s.keys) != len(s.values):
|
| raise serialization.DeserializationException(
|
| @@ -590,7 +614,7 @@ class FieldGroup(object):
|
| def Serialize(self, obj, data_offset, data, handle_offset):
|
| raise NotImplementedError()
|
|
|
| - def Deserialize(self, value, data, handles):
|
| + def Deserialize(self, value, context):
|
| raise NotImplementedError()
|
|
|
|
|
| @@ -615,8 +639,8 @@ class SingleFieldGroup(FieldGroup, FieldDescriptor):
|
| value = getattr(obj, self.name)
|
| return self.field_type.Serialize(value, data_offset, data, handle_offset)
|
|
|
| - def Deserialize(self, value, data, handles):
|
| - entity = self.field_type.Deserialize(value, data, handles)
|
| + def Deserialize(self, value, context):
|
| + entity = self.field_type.Deserialize(value, context)
|
| return { self.name: entity }
|
|
|
|
|
| @@ -640,7 +664,7 @@ class BooleanGroup(FieldGroup):
|
| [getattr(obj, field.name) for field in self.GetDescriptors()])
|
| return (value, [])
|
|
|
| - def Deserialize(self, value, data, handles):
|
| + def Deserialize(self, value, context):
|
| values = itertools.izip_longest([x.name for x in self.descriptors],
|
| _ConvertByteToBooleans(value),
|
| fillvalue=False)
|
| @@ -663,7 +687,7 @@ def _ConvertBooleansToByte(booleans):
|
|
|
|
|
| def _ConvertByteToBooleans(value, min_size=0):
|
| - "Unpack an integer into a list of booleans."""
|
| + """Unpack an integer into a list of booleans."""
|
| res = []
|
| while value:
|
| res.append(bool(value&1))
|
|
|