Commit d4a62b87 authored by erg's avatar erg Committed by Commit bot

Revert of mojo: Add deserialization to python structs. (patchset #3 id:40001...

Revert of mojo: Add deserialization to python structs. (patchset #3 id:40001 of https://codereview.chromium.org/578263003/)

Reason for revert:
New unit tests fail.

https://build.chromium.org/p/chromium.linux/builders/Linux%20Tests/builds/13695

Original issue's description:
> mojo: Add deserialization to python structs.
>
> BUG=415491
> R=sdefresne@chromium.org,cmasone@chromium.org
>
> Committed: https://crrev.com/ea8a6ef576c314506c4b3ee25544f6bcaa895fe1
> Cr-Commit-Position: refs/heads/master@{#295478}

TBR=cmasone@chromium.org,sdefresne@chromium.org,qsr@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=415491

Review URL: https://codereview.chromium.org/579383002

Cr-Commit-Position: refs/heads/master@{#295522}
parent 53f608b5
......@@ -7,7 +7,6 @@ The descriptors used to define generated elements of the mojo python bindings.
"""
import array
import itertools
import struct
# pylint: disable=F0401
......@@ -56,7 +55,7 @@ class SerializableType(Type):
def Serialize(self, value, data_offset, data, handle_offset):
"""
Serialize a value of this type.
Serialize an value of this type.
Args:
value: the value to serialize.
......@@ -70,21 +69,6 @@ class SerializableType(Type):
"""
raise NotImplementedError()
def Deserialize(self, value, data, handles):
"""
Deserialize a value of this type.
Args:
value: the base value for this type. This is always a numeric type, and
corresponds to the first element in the tuple returned by
Serialize.
data: the bytearray to retrieve additional data from.
handles: the array of handles contained in the message to deserialize.
Returns the deserialized value.
"""
raise NotImplementedError()
class BooleanType(Type):
"""Type object for booleans"""
......@@ -104,9 +88,6 @@ class NumericType(SerializableType):
def Serialize(self, value, data_offset, data, handle_offset):
return (value, [])
def Deserialize(self, value, data, handles):
return value
class IntegerType(NumericType):
"""Type object for integer types."""
......@@ -154,28 +135,15 @@ class PointerType(SerializableType):
def Serialize(self, value, data_offset, data, handle_offset):
if value is None and not self.nullable:
raise serialization.SerializationException(
'Trying to serialize null for non nullable type.')
"Trying to serialize null for non nullable type.")
if value is None:
return (0, [])
return self.SerializePointer(value, data_offset, data, handle_offset)
def Deserialize(self, value, data, handles):
if value == 0:
if not self.nullable:
raise serialization.DeserializationException(
'Trying to deserialize null for non nullable type.')
return None
pointed_data = data[value:]
(size, nb_elements) = serialization.HEADER_STRUCT.unpack_from(pointed_data)
return self.DeserializePointer(size, nb_elements, pointed_data, handles)
def SerializePointer(self, value, data_offset, data, handle_offset):
"""Serialize the not null value."""
raise NotImplementedError()
def DeserializePointer(self, size, nb_elements, data, handles):
raise NotImplementedError()
class StringType(PointerType):
"""
......@@ -202,11 +170,6 @@ 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)
return unicode(string_array.tostring(), 'utf8')
class HandleType(SerializableType):
"""Type object for handles."""
......@@ -225,20 +188,11 @@ class HandleType(SerializableType):
def Serialize(self, value, data_offset, data, handle_offset):
if not value.IsValid() and not self.nullable:
raise serialization.SerializationException(
'Trying to serialize null for non nullable type.')
"Trying to serialize null for non nullable type.")
if not value.IsValid():
return (-1, [])
return (handle_offset, [value])
def Deserialize(self, value, data, handles):
if value == -1:
if not self.nullable:
raise serialization.DeserializationException(
'Trying to deserialize null for non nullable type.')
return mojo.system.Handle()
# TODO(qsr) validate handle order
return handles[value]
class BaseArrayType(PointerType):
"""Abstract Type object for arrays."""
......@@ -249,22 +203,13 @@ class BaseArrayType(PointerType):
def SerializePointer(self, value, data_offset, data, handle_offset):
if self.length != 0 and len(value) != self.length:
raise serialization.SerializationException('Incorrect array size')
raise serialization.SerializationException("Incorrect array size")
return self.SerializeArray(value, data_offset, data, handle_offset)
def SerializeArray(self, value, data_offset, data, handle_offset):
"""Serialize the not null array."""
raise NotImplementedError()
def DeserializePointer(self, size, nb_elements, data, handles):
if self.length != 0 and size != self.length:
raise serialization.DeserializationException('Incorrect array size')
return self.DeserializeArray(size, nb_elements, data, handles)
def DeserializeArray(self, size, nb_elements, data, handles):
raise NotImplementedError()
class BooleanArrayType(BaseArrayType):
def __init__(self, nullable=False, length=0):
......@@ -279,17 +224,8 @@ class BooleanArrayType(BaseArrayType):
def SerializeArray(self, value, data_offset, data, handle_offset):
groups = [value[i:i+8] for i in range(0, len(value), 8)]
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)
elements = list(itertools.islice(
itertools.chain.from_iterable(
[_ConvertByteToBooleans(x, 8) for x in converted]),
0,
nb_elements))
return elements
return self._array_type.SerializeArray(
converted, data_offset, data, handle_offset)
class GenericArrayType(BaseArrayType):
......@@ -309,11 +245,12 @@ class GenericArrayType(BaseArrayType):
size = (serialization.HEADER_STRUCT.size +
self.sub_type.GetByteSize() * len(value))
data_end = len(data)
position = len(data) + serialization.HEADER_STRUCT.size
position = len(data) - data_offset
data.extend(bytearray(size +
serialization.NeededPaddingForAlignment(size)))
returned_handles = []
to_pack = []
position = position + 2
for item in value:
(new_data, new_handles) = self.sub_type.Serialize(
item,
......@@ -324,23 +261,12 @@ class GenericArrayType(BaseArrayType):
returned_handles.extend(new_handles)
position = position + self.sub_type.GetByteSize()
serialization.HEADER_STRUCT.pack_into(data, data_end, size, len(value))
struct.pack_into('%d%s' % (len(value), self.sub_type.GetTypeCode()),
struct.pack_into("%d%s" % (len(value), self.sub_type.GetTypeCode()),
data,
data_end + serialization.HEADER_STRUCT.size,
*to_pack)
return (data_offset, returned_handles)
def DeserializeArray(self, size, nb_elements, data, handles):
values = struct.unpack_from(
'%d%s' % (nb_elements, self.sub_type.GetTypeCode()),
data[serialization.HEADER_STRUCT.size:])
result = []
position = serialization.HEADER_STRUCT.size
for value in values:
result.append(self.sub_type.Deserialize(value, data[position:], handles))
position += self.sub_type.GetByteSize()
return result
class NativeArrayType(BaseArrayType):
"""Type object for arrays of native types."""
......@@ -358,12 +284,15 @@ class NativeArrayType(BaseArrayType):
return array.array(self.array_typecode, value)
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):
result = array.array(self.array_typecode)
result.fromstring(data[serialization.HEADER_STRUCT.size:size].tobytes())
return result
data_size = len(data)
data.extend(bytearray(serialization.HEADER_STRUCT.size))
data.extend(value.tostring())
data_length = len(data) - data_size
data.extend(bytearray(
serialization.NeededPaddingForAlignment(data_length)))
serialization.HEADER_STRUCT.pack_into(
data, data_size, data_length, len(value))
return (data_offset, [])
class StructType(PointerType):
......@@ -389,9 +318,6 @@ 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)
class NoneType(SerializableType):
"""Placeholder type, used temporarily until all mojo types are handled."""
......@@ -405,9 +331,6 @@ class NoneType(SerializableType):
def Serialize(self, value, data_offset, data, handle_offset):
return (0, [])
def Deserialize(self, value, data, handles):
return None
TYPE_NONE = NoneType()
......@@ -469,9 +392,6 @@ class FieldGroup(object):
def Serialize(self, obj, data_offset, data, handle_offset):
raise NotImplementedError()
def Deserialize(self, value, data, handles):
raise NotImplementedError()
class SingleFieldGroup(FieldGroup, FieldDescriptor):
"""A FieldGroup that contains a single FieldDescriptor."""
......@@ -494,10 +414,6 @@ 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)
return { self.name: entity }
class BooleanGroup(FieldGroup):
"""A FieldGroup to pack booleans."""
......@@ -506,7 +422,7 @@ class BooleanGroup(FieldGroup):
self.version = min([descriptor.field_number for descriptor in descriptors])
def GetTypeCode(self):
return 'B'
return "B"
def GetByteSize(self):
return 1
......@@ -519,33 +435,7 @@ class BooleanGroup(FieldGroup):
[getattr(obj, field.name) for field in self.GetDescriptors()])
return (value, [])
def Deserialize(self, value, data, handles):
values = itertools.izip_longest([x.name for x in self.descriptors],
_ConvertByteToBooleans(value),
fillvalue=False)
return dict(values)
def _SerializeNativeArray(value, data_offset, data, length):
data_size = len(data)
data.extend(bytearray(serialization.HEADER_STRUCT.size))
data.extend(value.tostring())
data_length = len(data) - data_size
data.extend(bytearray(serialization.NeededPaddingForAlignment(data_length)))
serialization.HEADER_STRUCT.pack_into(data, data_size, data_length, length)
return (data_offset, [])
def _ConvertBooleansToByte(booleans):
"""Pack a list of booleans into an integer."""
return reduce(lambda x, y: x * 2 + y, reversed(booleans), 0)
def _ConvertByteToBooleans(value, min_size=0):
"Unpack an integer into a list of booleans."""
res = []
while value:
res.append(bool(value&1))
value = value / 2
res.extend([False] * (min_size - len(res)))
return res
......@@ -107,14 +107,6 @@ class MojoStructType(type):
return serialization_object.Serialize(self, handle_offset)
dictionary['Serialize'] = Serialize
def Deserialize(cls, data, handles):
result = cls.__new__(cls)
fields = {}
serialization_object.Deserialize(fields, data, handles)
result._fields = fields
return result
dictionary['Deserialize'] = classmethod(Deserialize)
return type.__new__(mcs, name, bases, dictionary)
# Prevent adding new attributes, or mutating constants.
......
......@@ -16,42 +16,28 @@ 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.version = _GetVersion(groups)
self._groups = groups
self.version = _GetVersion(groups)
main_struct = _GetStruct(groups)
self.size = HEADER_STRUCT.size + main_struct.size
self._struct_per_version = {
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 version greater than the last known.
# If asking for a greater ver
version = min(version, self.version)
if version not in self._struct_per_version:
self._struct_per_version[version] = _GetStruct(self._GetGroups(version))
self._struct_per_version[version] = _GetStruct(_FilterGroups(self._groups,
version))
return self._struct_per_version[version]
def Serialize(self, obj, handle_offset):
......@@ -78,18 +64,6 @@ 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."""
......@@ -103,7 +77,7 @@ def _GetVersion(groups):
def _FilterGroups(groups, version):
return [group for group in groups if group.GetVersion() < version]
return [group for group in groups if group.version < version]
def _GetStruct(groups):
......
......@@ -2,67 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import math
import unittest
# pylint: disable=F0401
import mojo.bindings.reflection as reflection
import mojo.system
# Generated files
# pylint: disable=F0401
import sample_import_mojom
import sample_import2_mojom
import sample_service_mojom
def _NewHandle():
return mojo.system.MessagePipe().handle0
def _TestEquality(x, y):
if x == y:
return True
if type(x) != type(y):
print '\n%r != %r. Element are not of the same type.' % (x, y)
return False
if isinstance(x, float) and math.isnan(x) and math.isnan(y):
return True
if hasattr(x, '__len__'):
if len(x) != len(y):
print '\n%r != %r. Iterables are not of the same size.' % (x, y)
return False
for (x1, y1) in zip(x, y):
if not _TestEquality(x1, y1):
return False
return True
if (hasattr(x, '__metaclass__') and
x.__metaclass__ == reflection.MojoStructType):
properties = [p for p in dir(x) if not p.startswith('_')]
for p in properties:
p1 = getattr(x, p)
p2 = getattr(y, p)
if not hasattr(p1, '__call__') and not _TestEquality(p1, p2):
print '\n%r != %r. Not equal for property %r.' % (x, y, p)
return False
return True
return False
def _NewBar():
bar_instance = sample_service_mojom.Bar()
bar_instance.alpha = 22
bar_instance.beta = 87
bar_instance.gamma = 122
bar_instance.type = sample_service_mojom.Bar.Type.BOTH
return bar_instance
def _NewFoo():
foo_instance = sample_service_mojom.Foo()
foo_instance.name = "Foo.name"
......@@ -71,10 +23,10 @@ def _NewFoo():
foo_instance.a = False
foo_instance.b = True
foo_instance.c = True
foo_instance.bar = _NewBar()
foo_instance.bar = sample_service_mojom.Bar()
foo_instance.extra_bars = [
_NewBar(),
_NewBar(),
sample_service_mojom.Bar(),
sample_service_mojom.Bar()
]
foo_instance.data = 'Hello world'
foo_instance.source = _NewHandle()
......@@ -89,43 +41,12 @@ def _NewFoo():
],
[],
]
foo_instance.array_of_bools = [ True, 0, 1, 2, 0, 0, 0, 0, 0, True ]
foo_instance.array_of_bools = [ True, 0, 1, 2, 0 ]
return foo_instance
class SerializationDeserializationTest(unittest.TestCase):
def testTestEquality(self):
self.assertFalse(_TestEquality(1, 2))
def testFooSerialization(self):
(data, _) = _NewFoo().Serialize()
self.assertTrue(len(data))
self.assertEquals(len(data) % 8, 0)
def testFooDeserialization(self):
(data, handles) = _NewFoo().Serialize()
self.assertTrue(
sample_service_mojom.Foo.Deserialize(memoryview(data), handles))
def testFooSerializationDeserialization(self):
foo1 = _NewFoo()
(data, handles) = foo1.Serialize()
foo2 = sample_service_mojom.Foo.Deserialize(memoryview(data), handles)
self.assertTrue(_TestEquality(foo1, foo2))
def testDefaultsTestSerializationDeserialization(self):
v1 = sample_service_mojom.DefaultsTest()
v1.a18 = []
v1.a19 = ""
v1.a21 = sample_import_mojom.Point()
v1.a22.location = sample_import_mojom.Point()
v1.a22.size = sample_import2_mojom.Size()
(data, handles) = v1.Serialize()
v2 = sample_service_mojom.DefaultsTest.Deserialize(memoryview(data),
handles)
self.assertTrue(_TestEquality(v1, v2))
def testFooDeserializationError(self):
with self.assertRaises(Exception):
sample_service_mojom.Foo.Deserialize("", [])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment