diff options
Diffstat (limited to 'mojo/public/python/mojo_bindings')
-rw-r--r-- | mojo/public/python/mojo_bindings/__init__.py | 3 | ||||
-rw-r--r-- | mojo/public/python/mojo_bindings/descriptor.py | 696 | ||||
-rw-r--r-- | mojo/public/python/mojo_bindings/messaging.py | 407 | ||||
-rw-r--r-- | mojo/public/python/mojo_bindings/promise.py | 196 | ||||
-rw-r--r-- | mojo/public/python/mojo_bindings/reflection.py | 569 | ||||
-rw-r--r-- | mojo/public/python/mojo_bindings/serialization.py | 193 |
6 files changed, 0 insertions, 2064 deletions
diff --git a/mojo/public/python/mojo_bindings/__init__.py b/mojo/public/python/mojo_bindings/__init__.py deleted file mode 100644 index 4d6aabb..0000000 --- a/mojo/public/python/mojo_bindings/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. diff --git a/mojo/public/python/mojo_bindings/descriptor.py b/mojo/public/python/mojo_bindings/descriptor.py deleted file mode 100644 index 45e073f..0000000 --- a/mojo/public/python/mojo_bindings/descriptor.py +++ /dev/null @@ -1,696 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -The descriptors used to define generated elements of the mojo python bindings. -""" - -import array -import itertools -import struct - -import mojo_bindings.reflection as reflection -import mojo_bindings.serialization as serialization - -# pylint: disable=E0611,F0401 -import mojo_system - - -class Type(object): - """Describes the type of a struct field or a method parameter,""" - - def Convert(self, value): # pylint: disable=R0201 - """ - Convert the given value into its canonical representation, raising an - exception if the value cannot be converted. - """ - return value - - def GetDefaultValue(self, value): - """ - Returns the default value for this type associated with the given value. - This method must be able to correcly handle value being None. - """ - return self.Convert(value) - - -class SerializableType(Type): - """Describe a type that can be serialized by itself.""" - - def __init__(self, typecode): - Type.__init__(self) - self.typecode = typecode - self.byte_size = struct.calcsize('<%s' % self.GetTypeCode()) - - def GetTypeCode(self): - """ - Returns the type code (as defined by the struct module) used to encode - this type. - """ - return self.typecode - - def GetByteSize(self): - """ - Returns the size of the encoding of this type. - """ - return self.byte_size - - def Serialize(self, value, data_offset, data, handle_offset): - """ - Serialize a value of this type. - - Args: - value: the value to serialize. - data_offset: the offset to the end of the data bytearray. Used to encode - pointers. - data: the bytearray to append additional data to. - handle_offset: the offset to use to encode handles. - - Returns a a tuple where the first element is the value to encode, and the - second is the array of handles to add to the message. - """ - raise NotImplementedError() - - def Deserialize(self, value, context): - """ - 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""" - - def Convert(self, value): - return bool(value) - - -class NumericType(SerializableType): - """Base Type object for all numeric types""" - - def GetDefaultValue(self, value): - if value is None: - return self.Convert(0) - return self.Convert(value) - - def Serialize(self, value, data_offset, data, handle_offset): - return (value, []) - - def Deserialize(self, value, context): - return value - - -class IntegerType(NumericType): - """Type object for integer types.""" - - def __init__(self, typecode): - NumericType.__init__(self, typecode) - size = 8 * self.byte_size - signed = typecode.islower() - if signed: - self._min_value = -(1 << (size - 1)) - self._max_value = (1 << (size - 1)) - 1 - else: - self._min_value = 0 - self._max_value = (1 << size) - 1 - - def Convert(self, value): - if value is None: - raise TypeError('None is not an integer.') - if not isinstance(value, (int, long)): - raise TypeError('%r is not an integer type' % value) - if value < self._min_value or value > self._max_value: - raise OverflowError('%r is not in the range [%d, %d]' % - (value, self._min_value, self._max_value)) - return value - - -class FloatType(NumericType): - """Type object for floating point number types.""" - - def Convert(self, value): - if value is None: - raise TypeError('None is not an floating point number.') - if not isinstance(value, (int, long, float)): - raise TypeError('%r is not a numeric type' % value) - return float(value) - - -class PointerType(SerializableType): - """Base Type object for pointers.""" - - def __init__(self, nullable=False): - SerializableType.__init__(self, 'Q') - self.nullable = nullable - - 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.') - if value is None: - return (0, []) - return self.SerializePointer(value, data_offset, data, handle_offset) - - 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 - 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, context): - raise NotImplementedError() - - -class StringType(PointerType): - """ - Type object for strings. - - Strings are represented as unicode, and the conversion is done using the - default encoding if a string instance is used. - """ - - def __init__(self, nullable=False): - PointerType.__init__(self, nullable) - self._array_type = NativeArrayType('B', nullable) - - def Convert(self, value): - if value is None or isinstance(value, unicode): - return value - if isinstance(value, str): - return unicode(value) - raise TypeError('%r is not a string' % value) - - def SerializePointer(self, value, data_offset, data, handle_offset): - string_array = array.array('b') - string_array.fromstring(value.encode('utf8')) - return self._array_type.SerializeArray( - string_array, data_offset, data, handle_offset) - - def DeserializePointer(self, size, nb_elements, context): - string_array = self._array_type.DeserializeArray(size, nb_elements, context) - return unicode(string_array.tostring(), 'utf8') - - -class BaseHandleType(SerializableType): - """Type object for handles.""" - - def __init__(self, nullable=False): - SerializableType.__init__(self, 'i') - self.nullable = nullable - - def Serialize(self, value, data_offset, data, handle_offset): - handle = self.ToHandle(value) - if not handle.IsValid() and not self.nullable: - raise serialization.SerializationException( - 'Trying to serialize null for non nullable type.') - if not handle.IsValid(): - return (-1, []) - return (handle_offset, [handle]) - - 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()) - return self.FromHandle(context.ClaimHandle(value)) - - def FromHandle(self, handle): - raise NotImplementedError() - - def ToHandle(self, value): - raise NotImplementedError() - - -class HandleType(BaseHandleType): - """Type object for handles.""" - - def Convert(self, value): - if value is None: - return mojo_system.Handle() - if not isinstance(value, mojo_system.Handle): - raise TypeError('%r is not a handle' % value) - return value - - def FromHandle(self, handle): - return handle - - def ToHandle(self, value): - return value - - -class InterfaceRequestType(BaseHandleType): - """Type object for interface requests.""" - - def Convert(self, value): - if value is None: - return reflection.InterfaceRequest(mojo_system.Handle()) - if not isinstance(value, reflection.InterfaceRequest): - raise TypeError('%r is not an interface request' % value) - return value - - def FromHandle(self, handle): - return reflection.InterfaceRequest(handle) - - def ToHandle(self, value): - return value.PassMessagePipe() - - -class InterfaceType(BaseHandleType): - """Type object for interfaces.""" - - def __init__(self, interface_getter, nullable=False): - BaseHandleType.__init__(self, nullable) - self._interface_getter = interface_getter - self._interface = None - - def Convert(self, value): - if value is None or isinstance(value, self.interface): - return value - raise TypeError('%r is not an instance of ' % self.interface) - - @property - def interface(self): - if not self._interface: - self._interface = self._interface_getter() - return self._interface - - def FromHandle(self, handle): - if handle.IsValid(): - return self.interface.manager.Proxy(handle) - return None - - def ToHandle(self, value): - if not value: - return mojo_system.Handle() - if isinstance(value, reflection.InterfaceProxy): - return value.manager.PassMessagePipe() - pipe = mojo_system.MessagePipe() - self.interface.manager.Bind(value, pipe.handle0) - return pipe.handle1 - - -class BaseArrayType(PointerType): - """Abstract Type object for arrays.""" - - def __init__(self, nullable=False, length=0): - PointerType.__init__(self, nullable) - self.length = length - - def SerializePointer(self, value, data_offset, data, handle_offset): - if self.length != 0 and len(value) != self.length: - 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, context): - if self.length != 0 and nb_elements != self.length: - raise serialization.DeserializationException('Incorrect array size') - 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 SizeForLength(self, nb_elements): - raise NotImplementedError() - - -class BooleanArrayType(BaseArrayType): - - def __init__(self, nullable=False, length=0): - BaseArrayType.__init__(self, nullable, length) - self._array_type = NativeArrayType('B', nullable) - - def Convert(self, value): - if value is None: - return value - return [TYPE_BOOL.Convert(x) for x in value] - - 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, 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]), - 0, - nb_elements)) - return elements - - def SizeForLength(self, nb_elements): - return (nb_elements + 7) // 8 - - -class GenericArrayType(BaseArrayType): - """Type object for arrays of pointers.""" - - def __init__(self, sub_type, nullable=False, length=0): - BaseArrayType.__init__(self, nullable, length) - assert isinstance(sub_type, SerializableType) - self.sub_type = sub_type - - def Convert(self, value): - if value is None: - return value - return [self.sub_type.Convert(x) for x in value] - - def SerializeArray(self, value, data_offset, data, handle_offset): - size = (serialization.HEADER_STRUCT.size + - self.sub_type.GetByteSize() * len(value)) - data_end = len(data) - position = len(data) + serialization.HEADER_STRUCT.size - data.extend(bytearray(size + - serialization.NeededPaddingForAlignment(size))) - returned_handles = [] - to_pack = [] - for item in value: - (new_data, new_handles) = self.sub_type.Serialize( - item, - len(data) - position, - data, - handle_offset + len(returned_handles)) - to_pack.append(new_data) - 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()), - data, - data_end + serialization.HEADER_STRUCT.size, - *to_pack) - return (data_offset, returned_handles) - - def DeserializeArray(self, size, nb_elements, context): - values = struct.unpack_from( - '%d%s' % (nb_elements, self.sub_type.GetTypeCode()), - buffer(context.data, serialization.HEADER_STRUCT.size)) - result = [] - sub_context = context.GetSubContext(serialization.HEADER_STRUCT.size) - for value in values: - 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.""" - - 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: - return value - if (isinstance(value, array.array) and - value.array_typecode == self.array_typecode): - return value - 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, context): - result = array.array(self.array_typecode) - 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.""" - - def __init__(self, struct_type_getter, nullable=False): - PointerType.__init__(self) - self._struct_type_getter = struct_type_getter - self._struct_type = None - self.nullable = nullable - - @property - def struct_type(self): - if not self._struct_type: - self._struct_type = self._struct_type_getter() - return self._struct_type - - def Convert(self, value): - if value is None or isinstance(value, self.struct_type): - return value - raise TypeError('%r is not an instance of %r' % (value, self.struct_type)) - - def GetDefaultValue(self, value): - if value: - return self.struct_type() - return None - - def SerializePointer(self, value, data_offset, data, handle_offset): - (new_data, new_handles) = value.Serialize(handle_offset) - data.extend(new_data) - return (data_offset, new_handles) - - def DeserializePointer(self, size, nb_elements, context): - return self.struct_type.Deserialize(context) - - -class MapType(SerializableType): - """Type objects for maps.""" - - def __init__(self, key_type, value_type, nullable=False): - self._key_type = key_type - self._value_type = value_type - dictionary = { - '__metaclass__': reflection.MojoStructType, - '__module__': __name__, - 'DESCRIPTOR': { - 'fields': [ - SingleFieldGroup('keys', MapType._GetArrayType(key_type), 0, 0), - SingleFieldGroup('values', MapType._GetArrayType(value_type), 1, 1), - ], - } - } - self.struct = reflection.MojoStructType('MapStruct', (object,), dictionary) - self.struct_type = StructType(lambda: self.struct, nullable) - SerializableType.__init__(self, self.struct_type.typecode) - - def Convert(self, value): - if value is None: - return value - if isinstance(value, dict): - return dict([(self._key_type.Convert(x), self._value_type.Convert(y)) for - x, y in value.iteritems()]) - raise TypeError('%r is not a dictionary.') - - def Serialize(self, value, data_offset, data, handle_offset): - s = None - if value: - keys, values = [], [] - for key, value in value.iteritems(): - keys.append(key) - values.append(value) - s = self.struct(keys=keys, values=values) - return self.struct_type.Serialize(s, data_offset, data, handle_offset) - - def Deserialize(self, value, context): - s = self.struct_type.Deserialize(value, context) - if s: - if len(s.keys) != len(s.values): - raise serialization.DeserializationException( - 'keys and values do not have the same length.') - return dict(zip(s.keys, s.values)) - return None - - @staticmethod - def _GetArrayType(t): - if t == TYPE_BOOL: - return BooleanArrayType() - else: - return GenericArrayType(t) - - -TYPE_BOOL = BooleanType() - -TYPE_INT8 = IntegerType('b') -TYPE_INT16 = IntegerType('h') -TYPE_INT32 = IntegerType('i') -TYPE_INT64 = IntegerType('q') - -TYPE_UINT8 = IntegerType('B') -TYPE_UINT16 = IntegerType('H') -TYPE_UINT32 = IntegerType('I') -TYPE_UINT64 = IntegerType('Q') - -TYPE_FLOAT = FloatType('f') -TYPE_DOUBLE = FloatType('d') - -TYPE_STRING = StringType() -TYPE_NULLABLE_STRING = StringType(True) - -TYPE_HANDLE = HandleType() -TYPE_NULLABLE_HANDLE = HandleType(True) - -TYPE_INTERFACE_REQUEST = InterfaceRequestType() -TYPE_NULLABLE_INTERFACE_REQUEST = InterfaceRequestType(True) - - -class FieldDescriptor(object): - """Describes a field in a generated struct.""" - - def __init__(self, name, field_type, index, version, default_value=None): - self.name = name - self.field_type = field_type - self.version = version - self.index = index - self._default_value = default_value - - def GetDefaultValue(self): - return self.field_type.GetDefaultValue(self._default_value) - - -class FieldGroup(object): - """ - Describe a list of field in the generated struct that must be - serialized/deserialized together. - """ - def __init__(self, descriptors): - self.descriptors = descriptors - - def GetDescriptors(self): - return self.descriptors - - def GetTypeCode(self): - raise NotImplementedError() - - def GetByteSize(self): - raise NotImplementedError() - - def GetVersion(self): - raise NotImplementedError() - - def Serialize(self, obj, data_offset, data, handle_offset): - raise NotImplementedError() - - def Deserialize(self, value, context): - raise NotImplementedError() - - -class SingleFieldGroup(FieldGroup, FieldDescriptor): - """A FieldGroup that contains a single FieldDescriptor.""" - - def __init__(self, name, field_type, index, version, default_value=None): - FieldDescriptor.__init__( - self, name, field_type, index, version, default_value) - FieldGroup.__init__(self, [self]) - - def GetTypeCode(self): - return self.field_type.GetTypeCode() - - def GetByteSize(self): - return self.field_type.GetByteSize() - - def GetVersion(self): - return self.version - - def Serialize(self, obj, data_offset, data, handle_offset): - value = getattr(obj, self.name) - return self.field_type.Serialize(value, data_offset, data, handle_offset) - - def Deserialize(self, value, context): - entity = self.field_type.Deserialize(value, context) - return { self.name: entity } - - -class BooleanGroup(FieldGroup): - """A FieldGroup to pack booleans.""" - def __init__(self, descriptors): - FieldGroup.__init__(self, descriptors) - self.version = min([descriptor.version for descriptor in descriptors]) - - def GetTypeCode(self): - return 'B' - - def GetByteSize(self): - return 1 - - def GetVersion(self): - return self.version - - def Serialize(self, obj, data_offset, data, handle_offset): - value = _ConvertBooleansToByte( - [getattr(obj, field.name) for field in self.GetDescriptors()]) - return (value, []) - - def Deserialize(self, value, context): - 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(buffer(value)) - 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 diff --git a/mojo/public/python/mojo_bindings/messaging.py b/mojo/public/python/mojo_bindings/messaging.py deleted file mode 100644 index 385a080..0000000 --- a/mojo/public/python/mojo_bindings/messaging.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Utility classes to handle sending and receiving messages.""" - - -import struct -import sys -import weakref - -import mojo_bindings.serialization as serialization - -# pylint: disable=E0611,F0401 -import mojo_system as system - - -# The flag values for a message header. -NO_FLAG = 0 -MESSAGE_EXPECTS_RESPONSE_FLAG = 1 << 0 -MESSAGE_IS_RESPONSE_FLAG = 1 << 1 - - -class MessagingException(Exception): - def __init__(self, *args, **kwargs): - Exception.__init__(self, *args, **kwargs) - self.__traceback__ = sys.exc_info()[2] - - -class MessageHeader(object): - """The header of a mojo message.""" - - _SIMPLE_MESSAGE_NUM_FIELDS = 2 - _SIMPLE_MESSAGE_STRUCT = struct.Struct("<IIII") - - _REQUEST_ID_STRUCT = struct.Struct("<Q") - _REQUEST_ID_OFFSET = _SIMPLE_MESSAGE_STRUCT.size - - _MESSAGE_WITH_REQUEST_ID_NUM_FIELDS = 3 - _MESSAGE_WITH_REQUEST_ID_SIZE = ( - _SIMPLE_MESSAGE_STRUCT.size + _REQUEST_ID_STRUCT.size) - - def __init__(self, message_type, flags, request_id=0, data=None): - self._message_type = message_type - self._flags = flags - self._request_id = request_id - self._data = data - - @classmethod - def Deserialize(cls, data): - buf = buffer(data) - if len(data) < cls._SIMPLE_MESSAGE_STRUCT.size: - raise serialization.DeserializationException('Header is too short.') - (size, version, message_type, flags) = ( - cls._SIMPLE_MESSAGE_STRUCT.unpack_from(buf)) - if (version < cls._SIMPLE_MESSAGE_NUM_FIELDS): - raise serialization.DeserializationException('Incorrect version.') - request_id = 0 - if _HasRequestId(flags): - if version < cls._MESSAGE_WITH_REQUEST_ID_NUM_FIELDS: - raise serialization.DeserializationException('Incorrect version.') - if (size < cls._MESSAGE_WITH_REQUEST_ID_SIZE or - len(data) < cls._MESSAGE_WITH_REQUEST_ID_SIZE): - raise serialization.DeserializationException('Header is too short.') - (request_id, ) = cls._REQUEST_ID_STRUCT.unpack_from( - buf, cls._REQUEST_ID_OFFSET) - return MessageHeader(message_type, flags, request_id, data) - - @property - def message_type(self): - return self._message_type - - # pylint: disable=E0202 - @property - def request_id(self): - assert self.has_request_id - return self._request_id - - # pylint: disable=E0202 - @request_id.setter - def request_id(self, request_id): - assert self.has_request_id - self._request_id = request_id - self._REQUEST_ID_STRUCT.pack_into(self._data, self._REQUEST_ID_OFFSET, - request_id) - - @property - def has_request_id(self): - return _HasRequestId(self._flags) - - @property - def expects_response(self): - return self._HasFlag(MESSAGE_EXPECTS_RESPONSE_FLAG) - - @property - def is_response(self): - return self._HasFlag(MESSAGE_IS_RESPONSE_FLAG) - - @property - def size(self): - if self.has_request_id: - return self._MESSAGE_WITH_REQUEST_ID_SIZE - return self._SIMPLE_MESSAGE_STRUCT.size - - def Serialize(self): - if not self._data: - self._data = bytearray(self.size) - version = self._SIMPLE_MESSAGE_NUM_FIELDS - size = self._SIMPLE_MESSAGE_STRUCT.size - if self.has_request_id: - version = self._MESSAGE_WITH_REQUEST_ID_NUM_FIELDS - size = self._MESSAGE_WITH_REQUEST_ID_SIZE - self._SIMPLE_MESSAGE_STRUCT.pack_into(self._data, 0, size, version, - self._message_type, self._flags) - if self.has_request_id: - self._REQUEST_ID_STRUCT.pack_into(self._data, self._REQUEST_ID_OFFSET, - self._request_id) - return self._data - - def _HasFlag(self, flag): - return self._flags & flag != 0 - - -class Message(object): - """A message for a message pipe. This contains data and handles.""" - - def __init__(self, data=None, handles=None, header=None): - self.data = data - self.handles = handles - self._header = header - self._payload = None - - @property - def header(self): - if self._header is None: - self._header = MessageHeader.Deserialize(self.data) - return self._header - - @property - def payload(self): - if self._payload is None: - self._payload = Message(self.data[self.header.size:], self.handles) - return self._payload - - def SetRequestId(self, request_id): - header = self.header - header.request_id = request_id - (data, _) = header.Serialize() - self.data[:header.Size] = data[:header.Size] - - -class MessageReceiver(object): - """A class which implements this interface can receive Message objects.""" - - def Accept(self, message): - """ - Receive a Message. The MessageReceiver is allowed to mutate the message. - - Args: - message: the received message. - - Returns: - True if the message has been handled, False otherwise. - """ - raise NotImplementedError() - - -class MessageReceiverWithResponder(MessageReceiver): - """ - A MessageReceiver that can also handle the response message generated from the - given message. - """ - - def AcceptWithResponder(self, message, responder): - """ - A variant on Accept that registers a MessageReceiver (known as the - responder) to handle the response message generated from the given message. - The responder's Accept method may be called as part of the call to - AcceptWithResponder, or some time after its return. - - Args: - message: the received message. - responder: the responder that will receive the response. - - Returns: - True if the message has been handled, False otherwise. - """ - raise NotImplementedError() - - -class ConnectionErrorHandler(object): - """ - A ConnectionErrorHandler is notified of an error happening while using the - bindings over message pipes. - """ - - def OnError(self, result): - raise NotImplementedError() - - -class Connector(MessageReceiver): - """ - A Connector owns a message pipe and will send any received messages to the - registered MessageReceiver. It also acts as a MessageReceiver and will send - any message through the handle. - - The method Start must be called before the Connector will start listening to - incoming messages. - """ - - def __init__(self, handle): - MessageReceiver.__init__(self) - self._handle = handle - self._cancellable = None - self._incoming_message_receiver = None - self._error_handler = None - - def __del__(self): - if self._cancellable: - self._cancellable() - - def SetIncomingMessageReceiver(self, message_receiver): - """ - Set the MessageReceiver that will receive message from the owned message - pipe. - """ - self._incoming_message_receiver = message_receiver - - def SetErrorHandler(self, error_handler): - """ - Set the ConnectionErrorHandler that will be notified of errors on the owned - message pipe. - """ - self._error_handler = error_handler - - def Start(self): - assert not self._cancellable - self._RegisterAsyncWaiterForRead() - - def Accept(self, message): - result = self._handle.WriteMessage(message.data, message.handles) - return result == system.RESULT_OK - - def Close(self): - if self._cancellable: - self._cancellable() - self._cancellable = None - self._handle.Close() - - def PassMessagePipe(self): - if self._cancellable: - self._cancellable() - self._cancellable = None - result = self._handle - self._handle = system.Handle() - return result - - def _OnAsyncWaiterResult(self, result): - self._cancellable = None - if result == system.RESULT_OK: - self._ReadOutstandingMessages() - else: - self._OnError(result) - - def _OnError(self, result): - assert not self._cancellable - if self._error_handler: - self._error_handler.OnError(result) - self._handle.Close() - - def _RegisterAsyncWaiterForRead(self) : - assert not self._cancellable - self._cancellable = self._handle.AsyncWait( - system.HANDLE_SIGNAL_READABLE, - system.DEADLINE_INDEFINITE, - _WeakCallback(self._OnAsyncWaiterResult)) - - def _ReadOutstandingMessages(self): - result = system.RESULT_OK - while result == system.RESULT_OK: - result = _ReadAndDispatchMessage(self._handle, - self._incoming_message_receiver) - if result == system.RESULT_SHOULD_WAIT: - self._RegisterAsyncWaiterForRead() - return - self._OnError(result) - - -class Router(MessageReceiverWithResponder): - """ - A Router will handle mojo message and forward those to a Connector. It deals - with parsing of headers and adding of request ids in order to be able to match - a response to a request. - """ - - def __init__(self, handle): - MessageReceiverWithResponder.__init__(self) - self._incoming_message_receiver = None - self._next_request_id = 1 - self._responders = {} - self._connector = Connector(handle) - self._connector.SetIncomingMessageReceiver( - ForwardingMessageReceiver(_WeakCallback(self._HandleIncomingMessage))) - - def Start(self): - self._connector.Start() - - def SetIncomingMessageReceiver(self, message_receiver): - """ - Set the MessageReceiver that will receive message from the owned message - pipe. - """ - self._incoming_message_receiver = message_receiver - - def SetErrorHandler(self, error_handler): - """ - Set the ConnectionErrorHandler that will be notified of errors on the owned - message pipe. - """ - self._connector.SetErrorHandler(error_handler) - - def Accept(self, message): - # A message without responder is directly forwarded to the connector. - return self._connector.Accept(message) - - def AcceptWithResponder(self, message, responder): - # The message must have a header. - header = message.header - assert header.expects_response - request_id = self._NextRequestId() - header.request_id = request_id - if not self._connector.Accept(message): - return False - self._responders[request_id] = responder - return True - - def Close(self): - self._connector.Close() - - def PassMessagePipe(self): - return self._connector.PassMessagePipe() - - def _HandleIncomingMessage(self, message): - header = message.header - if header.expects_response: - if self._incoming_message_receiver: - return self._incoming_message_receiver.AcceptWithResponder( - message, self) - # If we receive a request expecting a response when the client is not - # listening, then we have no choice but to tear down the pipe. - self.Close() - return False - if header.is_response: - request_id = header.request_id - responder = self._responders.pop(request_id, None) - if responder is None: - return False - return responder.Accept(message) - if self._incoming_message_receiver: - return self._incoming_message_receiver.Accept(message) - # Ok to drop the message - return False - - def _NextRequestId(self): - request_id = self._next_request_id - while request_id == 0 or request_id in self._responders: - request_id = (request_id + 1) % (1 << 64) - self._next_request_id = (request_id + 1) % (1 << 64) - return request_id - -class ForwardingMessageReceiver(MessageReceiver): - """A MessageReceiver that forward calls to |Accept| to a callable.""" - - def __init__(self, callback): - MessageReceiver.__init__(self) - self._callback = callback - - def Accept(self, message): - return self._callback(message) - - -def _WeakCallback(callback): - func = callback.im_func - self = callback.im_self - if not self: - return callback - weak_self = weakref.ref(self) - def Callback(*args, **kwargs): - self = weak_self() - if self: - return func(self, *args, **kwargs) - return Callback - - -def _ReadAndDispatchMessage(handle, message_receiver): - (result, _, sizes) = handle.ReadMessage() - if result == system.RESULT_OK and message_receiver: - message_receiver.Accept(Message(bytearray(), [])) - if result != system.RESULT_RESOURCE_EXHAUSTED: - return result - (result, data, _) = handle.ReadMessage(bytearray(sizes[0]), sizes[1]) - if result == system.RESULT_OK and message_receiver: - message_receiver.Accept(Message(data[0], data[1])) - return result - -def _HasRequestId(flags): - return flags & (MESSAGE_EXPECTS_RESPONSE_FLAG|MESSAGE_IS_RESPONSE_FLAG) != 0 diff --git a/mojo/public/python/mojo_bindings/promise.py b/mojo/public/python/mojo_bindings/promise.py deleted file mode 100644 index ebf6f85..0000000 --- a/mojo/public/python/mojo_bindings/promise.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -Promise used by the python bindings. - -The API is following the ECMAScript 6 API for promises. -""" - -import sys - - -class Promise(object): - """The promise object.""" - - STATE_PENDING = 0 - STATE_FULLFILLED = 1 - STATE_REJECTED = 2 - STATE_BOUND = 3 - - def __init__(self, generator_function): - """ - Constructor. - - Args: - generator_function: A function taking 2 arguments: resolve and reject. - When |resolve| is called, the promise is fullfilled with the given value. - When |reject| is called, the promise is rejected with the given value. - A promise can only be resolved or rejected once, all following calls will - have no effect. - """ - self._onCatched = [] - self._onFulfilled = [] - self._onRejected = [] - self._state = Promise.STATE_PENDING - self._result = None - try: - generator_function(self._Resolve, self._Reject) - except Exception as e: - # Adding traceback similarly to python 3.0 (pep-3134) - e.__traceback__ = sys.exc_info()[2] - self._Reject(e) - - @staticmethod - def Resolve(value): - """ - If value is a promise, make a promise that have the same behavior as value, - otherwise make a promise that fulfills to value. - """ - if isinstance(value, Promise): - return value - return Promise(lambda x, y: x(value)) - - @staticmethod - def Reject(reason): - "Make a promise that rejects to reason.""" - return Promise(lambda x, y: y(reason)) - - @staticmethod - def All(*iterable): - """ - Make a promise that fulfills when every item in the array fulfills, and - rejects if (and when) any item rejects. Each array item is passed to - Promise.resolve, so the array can be a mixture of promise-like objects and - other objects. The fulfillment value is an array (in order) of fulfillment - values. The rejection value is the first rejection value. - """ - def GeneratorFunction(resolve, reject): - state = { - 'rejected': False, - 'nb_resolved': 0, - } - promises = [Promise.Resolve(x) for x in iterable] - results = [None for x in promises] - def OnFullfilled(i): - def OnFullfilled(res): - if state['rejected']: - return - results[i] = res - state['nb_resolved'] = state['nb_resolved'] + 1 - if state['nb_resolved'] == len(results): - resolve(results) - return OnFullfilled - def OnRejected(reason): - if state['rejected']: - return - state['rejected'] = True - reject(reason) - - for (i, promise) in enumerate(promises): - promise.Then(OnFullfilled(i), OnRejected) - return Promise(GeneratorFunction) - - @staticmethod - def Race(*iterable): - """ - Make a Promise that fulfills as soon as any item fulfills, or rejects as - soon as any item rejects, whichever happens first. - """ - def GeneratorFunction(resolve, reject): - state = { - 'ended': False - } - def OnEvent(callback): - def OnEvent(res): - if state['ended']: - return - state['ended'] = True - callback(res) - return OnEvent - for promise in [Promise.Resolve(x) for x in iterable]: - promise.Then(OnEvent(resolve), OnEvent(reject)) - return Promise(GeneratorFunction) - - @property - def state(self): - if isinstance(self._result, Promise): - return self._result.state - return self._state - - def Then(self, onFullfilled=None, onRejected=None): - """ - onFulfilled is called when/if this promise resolves. onRejected is called - when/if this promise rejects. Both are optional, if either/both are omitted - the next onFulfilled/onRejected in the chain is called. Both callbacks have - a single parameter, the fulfillment value or rejection reason. |Then| - returns a new promise equivalent to the value you return from - onFulfilled/onRejected after being passed through Resolve. If an - error is thrown in the callback, the returned promise rejects with that - error. - """ - if isinstance(self._result, Promise): - return self._result.Then(onFullfilled, onRejected) - def GeneratorFunction(resolve, reject): - if self._state == Promise.STATE_PENDING: - self._onFulfilled.append(_Delegate(resolve, reject, onFullfilled)) - self._onRejected.append(_Delegate(reject, reject, onRejected)) - if self._state == self.STATE_FULLFILLED: - _Delegate(resolve, reject, onFullfilled)(self._result) - if self._state == self.STATE_REJECTED: - recover = reject - if onRejected: - recover = resolve - _Delegate(recover, reject, onRejected)(self._result) - return Promise(GeneratorFunction) - - def Catch(self, onCatched): - """Equivalent to |Then(None, onCatched)|""" - return self.Then(None, onCatched) - - def _Resolve(self, value): - if self.state != Promise.STATE_PENDING: - return - self._result = value - if isinstance(value, Promise): - self._state = Promise.STATE_BOUND - self._result.Then(_IterateAction(self._onFulfilled), - _IterateAction(self._onRejected)) - return - self._state = Promise.STATE_FULLFILLED - for f in self._onFulfilled: - f(value) - self._onFulfilled = None - self._onRejected = None - - def _Reject(self, reason): - if self.state != Promise.STATE_PENDING: - return - self._result = reason - self._state = Promise.STATE_REJECTED - for f in self._onRejected: - f(reason) - self._onFulfilled = None - self._onRejected = None - - -def _IterateAction(iterable): - def _Run(x): - for f in iterable: - f(x) - return _Run - - -def _Delegate(resolve, reject, action): - def _Run(x): - try: - if action: - resolve(action(x)) - else: - resolve(x) - except Exception as e: - # Adding traceback similarly to python 3.0 (pep-3134) - e.__traceback__ = sys.exc_info()[2] - reject(e) - return _Run diff --git a/mojo/public/python/mojo_bindings/reflection.py b/mojo/public/python/mojo_bindings/reflection.py deleted file mode 100644 index 5432691..0000000 --- a/mojo/public/python/mojo_bindings/reflection.py +++ /dev/null @@ -1,569 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""The metaclasses used by the mojo python bindings.""" - -import itertools -import logging -import sys - -# pylint: disable=F0401 -import mojo_bindings.messaging as messaging -import mojo_bindings.promise as promise -import mojo_bindings.serialization as serialization - - -class MojoEnumType(type): - """Meta class for enumerations. - - Usage: - class MyEnum(object): - __metaclass__ = MojoEnumType - VALUES = [ - ('A', 0), - 'B', - ('C', 5), - ] - - This will define a enum with 3 values, 'A' = 0, 'B' = 1 and 'C' = 5. - """ - - def __new__(mcs, name, bases, dictionary): - dictionary['__slots__'] = () - dictionary['__new__'] = None - for value in dictionary.pop('VALUES', []): - if not isinstance(value, tuple): - raise ValueError('incorrect value: %r' % value) - key, enum_value = value - if isinstance(key, str) and isinstance(enum_value, int): - dictionary[key] = enum_value - else: - raise ValueError('incorrect value: %r' % value) - return type.__new__(mcs, name, bases, dictionary) - - def __setattr__(cls, key, value): - raise AttributeError('can\'t set attribute') - - def __delattr__(cls, key): - raise AttributeError('can\'t delete attribute') - - -class MojoStructType(type): - """Meta class for structs. - - Usage: - class MyStruct(object): - __metaclass__ = MojoStructType - DESCRIPTOR = { - 'constants': { - 'C1': 1, - 'C2': 2, - }, - 'enums': { - 'ENUM1': [ - ('V1', 1), - 'V2', - ], - 'ENUM2': [ - ('V1', 1), - 'V2', - ], - }, - 'fields': [ - SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), - ], - } - - This will define an struct, with: - - 2 constants 'C1' and 'C2'; - - 2 enums 'ENUM1' and 'ENUM2', each of those having 2 values, 'V1' and - 'V2'; - - 1 int32 field named 'x'. - """ - - def __new__(mcs, name, bases, dictionary): - dictionary['__slots__'] = ('_fields') - descriptor = dictionary.pop('DESCRIPTOR', {}) - - # Add constants - dictionary.update(descriptor.get('constants', {})) - - # Add enums - enums = descriptor.get('enums', {}) - for key in enums: - dictionary[key] = MojoEnumType(key, (object,), { 'VALUES': enums[key] }) - - # Add fields - groups = descriptor.get('fields', []) - - fields = list( - itertools.chain.from_iterable([group.descriptors for group in groups])) - fields.sort(key=lambda f: f.index) - for field in fields: - dictionary[field.name] = _BuildProperty(field) - - # Add init - dictionary['__init__'] = _StructInit(fields) - - # Add serialization method - serialization_object = serialization.Serialization(groups) - def Serialize(self, handle_offset=0): - return serialization_object.Serialize(self, handle_offset) - dictionary['Serialize'] = Serialize - - # pylint: disable=W0212 - def AsDict(self): - return self._fields - dictionary['AsDict'] = AsDict - - def Deserialize(cls, context): - result = cls.__new__(cls) - fields = {} - serialization_object.Deserialize(fields, context) - result._fields = fields - return result - dictionary['Deserialize'] = classmethod(Deserialize) - - dictionary['__eq__'] = _StructEq(fields) - dictionary['__ne__'] = _StructNe - - return type.__new__(mcs, name, bases, dictionary) - - # Prevent adding new attributes, or mutating constants. - def __setattr__(cls, key, value): - raise AttributeError('can\'t set attribute') - - # Prevent deleting constants. - def __delattr__(cls, key): - raise AttributeError('can\'t delete attribute') - - -class MojoInterfaceType(type): - """Meta class for interfaces. - - Usage: - class MyInterface(object): - __metaclass__ = MojoInterfaceType - DESCRIPTOR = { - 'client': MyInterfaceClient, - 'methods': [ - { - 'name': 'FireAndForget', - 'ordinal': 0, - 'parameters': [ - SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), - ] - }, - { - 'name': 'Ping', - 'ordinal': 1, - 'parameters': [ - SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), - ], - 'responses': [ - SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), - ], - }, - ], - } - """ - - def __new__(mcs, name, bases, dictionary): - # If one of the base class is already an interface type, do not edit the - # class. - for base in bases: - if isinstance(base, mcs): - return type.__new__(mcs, name, bases, dictionary) - - descriptor = dictionary.pop('DESCRIPTOR', {}) - - methods = [_MethodDescriptor(x) for x in descriptor.get('methods', [])] - for method in methods: - dictionary[method.name] = _NotImplemented - client_class_getter = descriptor.get('client', None) - - interface_manager = InterfaceManager(name, methods, client_class_getter) - dictionary.update({ - 'client': None, - 'manager': None, - '_interface_manager': interface_manager, - }) - - interface_class = type.__new__(mcs, name, bases, dictionary) - interface_manager.interface_class = interface_class - return interface_class - - @property - def manager(cls): - return cls._interface_manager - - # Prevent adding new attributes, or mutating constants. - def __setattr__(cls, key, value): - raise AttributeError('can\'t set attribute') - - # Prevent deleting constants. - def __delattr__(cls, key): - raise AttributeError('can\'t delete attribute') - - -class InterfaceProxy(object): - """ - A proxy allows to access a remote interface through a message pipe. - """ - pass - - -class InterfaceRequest(object): - """ - An interface request allows to send a request for an interface to a remote - object and start using it immediately. - """ - - def __init__(self, handle): - self._handle = handle - - def IsPending(self): - return self._handle.IsValid() - - def PassMessagePipe(self): - result = self._handle - self._handle = None - return result - - -class InterfaceManager(object): - """ - Manager for an interface class. The manager contains the operation that allows - to bind an implementation to a pipe, or to generate a proxy for an interface - over a pipe. - """ - - def __init__(self, name, methods, client_class_getter): - self.name = name - self.methods = methods - self.interface_class = None - self._client_class_getter = client_class_getter - self._client_manager = None - self._client_manager_computed = False - self._proxy_class = None - self._stub_class = None - - @property - def client_manager(self): - if not self._client_manager_computed: - self._client_manager_computed = True - if self._client_class_getter: - self._client_manager = self._client_class_getter().manager - return self._client_manager - - def Proxy(self, handle): - router = messaging.Router(handle) - error_handler = _ProxyErrorHandler() - router.SetErrorHandler(error_handler) - router.Start() - return self._InternalProxy(router, error_handler) - - # pylint: disable=W0212 - def Bind(self, impl, handle): - router = messaging.Router(handle) - router.SetIncomingMessageReceiver(self._Stub(impl)) - error_handler = _ProxyErrorHandler() - router.SetErrorHandler(error_handler) - - # Retain the router, until an error happen. - retainer = _Retainer(router) - def Cleanup(_): - retainer.release() - error_handler.AddCallback(Cleanup) - - if self.client_manager: - impl.client = self.client_manager._InternalProxy(router, error_handler) - - # Give an instance manager to the implementation to allow it to close - # the connection. - impl.manager = InstanceManager(router) - - router.Start() - - def _InternalProxy(self, router, error_handler): - if not self._proxy_class: - dictionary = { - '__module__': __name__, - '__init__': _ProxyInit, - } - if self.client_manager: - dictionary['client'] = property(_ProxyGetClient, _ProxySetClient) - dictionary['manager'] = None - dictionary['_client_manager'] = self.client_manager - for method in self.methods: - dictionary[method.name] = _ProxyMethodCall(method) - self._proxy_class = type('%sProxy' % self.name, - (self.interface_class, InterfaceProxy), - dictionary) - - proxy = self._proxy_class(router, error_handler) - # Give an instance manager to the proxy to allow to close the connection. - proxy.manager = InstanceManager(router) - return proxy - - def _Stub(self, impl): - if not self._stub_class: - accept_method = _StubAccept(self.methods) - dictionary = { - '__module__': __name__, - '__init__': _StubInit, - 'Accept': accept_method, - 'AcceptWithResponder': accept_method, - } - self._stub_class = type('%sStub' % self.name, - (messaging.MessageReceiverWithResponder,), - dictionary) - return self._stub_class(impl) - - -class InstanceManager(object): - """ - Manager for the implementation of an interface or a proxy. The manager allows - to control the connection over the pipe. - """ - def __init__(self, router): - self.router = router - - def Close(self): - self.router.Close() - - def PassMessagePipe(self): - return self.router.PassMessagePipe() - - -class _MethodDescriptor(object): - def __init__(self, descriptor): - self.name = descriptor['name'] - self.ordinal = descriptor['ordinal'] - self.parameters_struct = _ConstructParameterStruct( - descriptor['parameters'], self.name, "Parameters") - self.response_struct = _ConstructParameterStruct( - descriptor.get('responses'), self.name, "Responses") - - -def _ConstructParameterStruct(descriptor, name, suffix): - if descriptor is None: - return None - parameter_dictionary = { - '__metaclass__': MojoStructType, - '__module__': __name__, - 'DESCRIPTOR': descriptor, - } - return MojoStructType( - '%s%s' % (name, suffix), - (object,), - parameter_dictionary) - - -class _ProxyErrorHandler(messaging.ConnectionErrorHandler): - def __init__(self): - messaging.ConnectionErrorHandler.__init__(self) - self._callbacks = set() - - def OnError(self, result): - exception = messaging.MessagingException('Mojo error: %d' % result) - for callback in list(self._callbacks): - callback(exception) - self._callbacks = None - - def AddCallback(self, callback): - if self._callbacks is not None: - self._callbacks.add(callback) - - def RemoveCallback(self, callback): - if self._callbacks: - self._callbacks.remove(callback) - - -class _Retainer(object): - - # Set to force instances to be retained. - _RETAINED = set() - - def __init__(self, retained): - self._retained = retained - _Retainer._RETAINED.add(self) - - def release(self): - self._retained = None - _Retainer._RETAINED.remove(self) - - -def _StructInit(fields): - def _Init(self, *args, **kwargs): - if len(args) + len(kwargs) > len(fields): - raise TypeError('__init__() takes %d argument (%d given)' % - (len(fields), len(args) + len(kwargs))) - self._fields = {} - for f, a in zip(fields, args): - self.__setattr__(f.name, a) - remaining_fields = set(x.name for x in fields[len(args):]) - for name in kwargs: - if not name in remaining_fields: - if name in (x.name for x in fields[:len(args)]): - raise TypeError( - '__init__() got multiple values for keyword argument %r' % name) - raise TypeError('__init__() got an unexpected keyword argument %r' % - name) - self.__setattr__(name, kwargs[name]) - return _Init - - -def _BuildProperty(field): - """Build the property for the given field.""" - - # pylint: disable=W0212 - def Get(self): - if field.name not in self._fields: - self._fields[field.name] = field.GetDefaultValue() - return self._fields[field.name] - - # pylint: disable=W0212 - def Set(self, value): - self._fields[field.name] = field.field_type.Convert(value) - - return property(Get, Set) - - -def _StructEq(fields): - def _Eq(self, other): - if type(self) is not type(other): - return False - for field in fields: - if getattr(self, field.name) != getattr(other, field.name): - return False - return True - return _Eq - -def _StructNe(self, other): - return not self.__eq__(other) - - -def _ProxyInit(self, router, error_handler): - self._router = router - self._error_handler = error_handler - self._client = None - - -# pylint: disable=W0212 -def _ProxyGetClient(self): - return self._client - - -# pylint: disable=W0212 -def _ProxySetClient(self, client): - self._client = client - stub = self._client_manager._Stub(client) - self._router.SetIncomingMessageReceiver(stub) - - -# pylint: disable=W0212 -def _ProxyMethodCall(method): - flags = messaging.NO_FLAG - if method.response_struct: - flags = messaging.MESSAGE_EXPECTS_RESPONSE_FLAG - def _Call(self, *args, **kwargs): - def GenerationMethod(resolve, reject): - message = _GetMessage(method, flags, *args, **kwargs) - if method.response_struct: - def Accept(message): - try: - assert message.header.message_type == method.ordinal - payload = message.payload - response = method.response_struct.Deserialize( - serialization.RootDeserializationContext(payload.data, - payload.handles)) - as_dict = response.AsDict() - if len(as_dict) == 1: - value = as_dict.values()[0] - if not isinstance(value, dict): - response = value - resolve(response) - return True - except Exception as e: - # Adding traceback similarly to python 3.0 (pep-3134) - e.__traceback__ = sys.exc_info()[2] - reject(e) - return False - finally: - self._error_handler.RemoveCallback(reject) - - self._error_handler.AddCallback(reject) - if not self._router.AcceptWithResponder( - message, messaging.ForwardingMessageReceiver(Accept)): - self._error_handler.RemoveCallback(reject) - reject(messaging.MessagingException("Unable to send message.")) - else: - if (self._router.Accept(message)): - resolve(None) - else: - reject(messaging.MessagingException("Unable to send message.")) - return promise.Promise(GenerationMethod) - return _Call - - -def _GetMessage(method, flags, *args, **kwargs): - if flags == messaging.MESSAGE_IS_RESPONSE_FLAG: - struct = method.response_struct(*args, **kwargs) - else: - struct = method.parameters_struct(*args, **kwargs) - header = messaging.MessageHeader(method.ordinal, flags) - data = header.Serialize() - (payload, handles) = struct.Serialize() - data.extend(payload) - return messaging.Message(data, handles, header) - - -def _StubInit(self, impl): - self.impl = impl - - -def _StubAccept(methods): - methods_by_ordinal = dict((m.ordinal, m) for m in methods) - def Accept(self, message, responder=None): - try: - header = message.header - assert header.expects_response == bool(responder) - assert header.message_type in methods_by_ordinal - method = methods_by_ordinal[header.message_type] - payload = message.payload - parameters = method.parameters_struct.Deserialize( - serialization.RootDeserializationContext( - payload.data, payload.handles)).AsDict() - response = getattr(self.impl, method.name)(**parameters) - if header.expects_response: - def SendResponse(response): - if isinstance(response, dict): - response_message = _GetMessage(method, - messaging.MESSAGE_IS_RESPONSE_FLAG, - **response) - else: - response_message = _GetMessage(method, - messaging.MESSAGE_IS_RESPONSE_FLAG, - response) - response_message.header.request_id = header.request_id - responder.Accept(response_message) - p = promise.Promise.Resolve(response).Then(SendResponse) - if self.impl.manager: - # Close the connection in case of error. - p.Catch(lambda _: self.impl.manager.Close()) - return True - # pylint: disable=W0702 - except: - # Close the connection in case of error. - logging.warning( - 'Error occured in accept method. Connection will be closed.') - if self.impl.manager: - self.impl.manager.Close() - return False - return Accept - - -def _NotImplemented(*_1, **_2): - raise NotImplementedError() diff --git a/mojo/public/python/mojo_bindings/serialization.py b/mojo/public/python/mojo_bindings/serialization.py deleted file mode 100644 index b5ea1bd..0000000 --- a/mojo/public/python/mojo_bindings/serialization.py +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Utility classes for serialization""" - -import struct - - -# Format of a header for a struct or an array. -HEADER_STRUCT = struct.Struct("<II") - - -class SerializationException(Exception): - """Error when strying to serialize a struct.""" - pass - - -class DeserializationException(Exception): - """Error when strying to deserialize a struct.""" - 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. - """ - def __init__(self, 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._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. - version = min(version, self.version) - if version not in self._struct_per_version: - self._struct_per_version[version] = _GetStruct(self._GetGroups(version)) - return self._struct_per_version[version] - - def Serialize(self, obj, handle_offset): - """ - Serialize the given obj. handle_offset is the the first value to use when - encoding handles. - """ - handles = [] - data = bytearray(self.size) - HEADER_STRUCT.pack_into(data, 0, self.size, self.version) - position = HEADER_STRUCT.size - to_pack = [] - for group in self._groups: - position = position + NeededPaddingForAlignment(position, - group.GetByteSize()) - (entry, new_handles) = group.Serialize( - obj, - len(data) - position, - data, - handle_offset + len(handles)) - to_pack.append(entry) - handles.extend(new_handles) - position = position + group.GetByteSize() - self._GetMainStruct().pack_into(data, HEADER_STRUCT.size, *to_pack) - return (data, handles) - - 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(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, context.GetSubContext(position))) - position += group.GetByteSize() - - -def NeededPaddingForAlignment(value, alignment=8): - """Returns the padding necessary to align value with the given alignment.""" - if value % alignment: - return alignment - (value % alignment) - return 0 - - -def _GetVersion(groups): - return sum([len(x.descriptors) for x in groups]) - - -def _FilterGroups(groups, version): - return [group for group in groups if group.GetVersion() < version] - - -def _GetStruct(groups): - index = 0 - codes = [ '<' ] - for group in groups: - code = group.GetTypeCode() - size = group.GetByteSize() - needed_padding = NeededPaddingForAlignment(index, size) - if needed_padding: - codes.append('x' * needed_padding) - index = index + needed_padding - codes.append(code) - index = index + size - alignment_needed = NeededPaddingForAlignment(index) - if alignment_needed: - codes.append('x' * alignment_needed) - return struct.Struct(''.join(codes)) |