Chromium Code Reviews| Index: mojo/public/python/mojo/bindings/descriptor.py |
| diff --git a/mojo/public/python/mojo/bindings/descriptor.py b/mojo/public/python/mojo/bindings/descriptor.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b102843fdd277eaa6ba92aa1d9de987d6c3ae6e4 |
| --- /dev/null |
| +++ b/mojo/public/python/mojo/bindings/descriptor.py |
| @@ -0,0 +1,193 @@ |
| +# 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. |
| +""" |
| + |
| +# pylint: disable=F0401 |
| +from mojo.system import Handle |
| + |
| +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 BooleanType(Type): |
| + """Type object for booleans""" |
| + |
| + def Convert(self, value): |
| + return bool(value) |
| + |
| + |
| +class NumericType(Type): |
| + """Base Type object for all numeric types""" |
| + |
| + def GetDefaultValue(self, value): |
| + if value is None: |
| + return 0 |
|
sdefresne
2014/09/09 09:24:45
I think you want to do "value = 0" here, otherwise
qsr
2014/09/09 09:56:09
BooleanType doesn't apply. It is not a numeric typ
|
| + return self.Convert(value) |
| + |
| + |
| +class IntegerType(NumericType): |
| + """Type object for integer types.""" |
| + |
| + def __init__(self, size, signed): |
| + NumericType.__init__(self) |
| + self.size = size |
| + self.signed = signed |
| + if self.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 ValueError('None is not an integer.') |
| + if not isinstance(value, (int, long)): |
| + raise ValueError('%r is not an integer type' % value) |
| + if value < self._min_value or value > self._max_value: |
| + raise ValueError('%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 __init__(self, size): |
| + NumericType.__init__(self) |
| + self.size = size |
| + |
| + def Convert(self, value): |
| + if value is None: |
| + raise ValueError('None is not an floating point number.') |
| + if not isinstance(value, (int, long, float)): |
| + raise ValueError('%r is not a numeric type' % value) |
| + return float(value) |
| + |
| + |
| +class StringType(Type): |
| + """Type object for strings.""" |
| + |
| + def __init__(self, nullable=False): |
| + Type.__init__(self) |
| + self.nullable = nullable |
| + |
| + def Convert(self, value): |
| + if value is None or isinstance(value, unicode): |
| + return value |
| + if isinstance(value, str): |
| + return unicode(value) |
|
sdefresne
2014/09/09 09:24:44
By default, if no encoding is specified, "unicode(
qsr
2014/09/09 09:56:09
There is only one (two if you caount the nullable)
sdefresne
2014/09/09 12:22:48
SGTM. Maybe document that StringType store the val
qsr
2014/09/09 12:44:26
Done.
|
| + raise ValueError('%r is not a string' % value) |
| + |
| + |
| +class HandleType(Type): |
| + """Type object for handles.""" |
| + |
| + def __init__(self, nullable=False): |
| + Type.__init__(self) |
| + self.nullable = nullable |
| + |
| + def Convert(self, value): |
| + if value is None: |
| + return Handle() |
| + if not isinstance(value, Handle): |
| + raise ValueError('%r is not a handle' % value) |
| + return value |
| + |
| + |
| +class ArrayType(Type): |
| + """Type object for arrays.""" |
| + |
| + def __init__(self, sub_type, nullable=False, length=0): |
| + Type.__init__(self) |
| + self.sub_type = sub_type |
| + self.nullable = nullable |
| + self.length = length |
| + |
| + def Convert(self, value): |
| + if value is None: |
| + return value |
| + return [self.sub_type.Convert(x) for x in value] |
| + |
| + |
| +class StructType(Type): |
| + """Type object for structs.""" |
| + |
| + def __init__(self, struct_type, nullable=False): |
| + Type.__init__(self) |
| + self.struct_type = struct_type |
| + self.nullable = nullable |
| + |
| + def Convert(self, value): |
| + if value is None or isinstance(value, self.struct_type): |
| + return value |
| + raise ValueError('%r is not an instance of %r' % (value, self.struct_type)) |
| + |
| + def GetDefaultValue(self, value): |
| + if value: |
| + return self.struct_type() |
| + return None |
| + |
| + |
| +class NoneType(Type): |
| + """Placeholder type, used temporarly until all mojo types are handled.""" |
|
sdefresne
2014/09/09 09:24:44
nit: temporarily
qsr
2014/09/09 09:56:09
Done.
|
| + |
| + def Convert(self, value): |
| + return None |
| + |
| + |
| +TYPE_NONE = NoneType() |
| + |
| +TYPE_BOOL = BooleanType() |
| + |
| +TYPE_INT8 = IntegerType(8, True) |
| +TYPE_INT16 = IntegerType(16, True) |
| +TYPE_INT32 = IntegerType(32, True) |
| +TYPE_INT64 = IntegerType(64, True) |
| + |
| +TYPE_UINT8 = IntegerType(8, False) |
| +TYPE_UINT16 = IntegerType(16, False) |
| +TYPE_UINT32 = IntegerType(32, False) |
| +TYPE_UINT64 = IntegerType(64, False) |
| + |
| +TYPE_FLOAT = FloatType(4) |
| +TYPE_DOUBLE = FloatType(8) |
| + |
| +TYPE_STRING = StringType() |
| +TYPE_NULLABLE_STRING = StringType(True) |
| + |
| +TYPE_HANDLE = HandleType() |
| +TYPE_NULLABLE_HANDLE = HandleType(True) |
| + |
| + |
| +class FieldDescriptor(object): |
| + """Describes a field in a generated struct.""" |
| + |
| + def __init__(self, name, field_type, offset, |
| + bit_offset=None, default_value=None): |
| + self.name = name |
| + self.field_type = field_type |
| + self.offset = offset |
| + self.bit_offset = bit_offset |
| + self._default_value = default_value |
| + |
| + def GetDefaultValue(self): |
| + return self.field_type.GetDefaultValue(self._default_value) |