summaryrefslogtreecommitdiffstats
path: root/mojo/public/python/mojo_bindings
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/public/python/mojo_bindings')
-rw-r--r--mojo/public/python/mojo_bindings/__init__.py3
-rw-r--r--mojo/public/python/mojo_bindings/descriptor.py696
-rw-r--r--mojo/public/python/mojo_bindings/messaging.py407
-rw-r--r--mojo/public/python/mojo_bindings/promise.py196
-rw-r--r--mojo/public/python/mojo_bindings/reflection.py569
-rw-r--r--mojo/public/python/mojo_bindings/serialization.py193
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))