X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=src%2Fbindings%2Fpython%2Fbt2%2Fbt2%2Ffield.py;h=7229318dbc6be3b85a35c53bd294d2826d3fc8b3;hp=0f3e5e7ee32eb11b797f370723f52de5145ca098;hb=7e0b3e015929f15319fb72095429216a9aa5090b;hpb=fb25b9e364c8eab9fe5e37947831e233086c7218 diff --git a/src/bindings/python/bt2/bt2/field.py b/src/bindings/python/bt2/bt2/field.py index 0f3e5e7e..7229318d 100644 --- a/src/bindings/python/bt2/bt2/field.py +++ b/src/bindings/python/bt2/bt2/field.py @@ -21,44 +21,69 @@ # THE SOFTWARE. from bt2 import native_bt, object, utils -import bt2.field_class +from bt2 import field_class as bt2_field_class import collections.abc import functools import numbers import math -import bt2 -def _create_field_from_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref): +def _create_field_from_ptr_template( + object_map, ptr, owner_ptr, owner_get_ref, owner_put_ref +): + field_class_ptr = native_bt.field_borrow_class_const(ptr) - utils._handle_ptr(field_class_ptr, "cannot get field object's class") typeid = native_bt.field_class_get_type(field_class_ptr) - field = _TYPE_ID_TO_OBJ[typeid]._create_from_ptr_and_get_ref( - ptr, owner_ptr, owner_get_ref, owner_put_ref) + field = object_map[typeid]._create_from_ptr_and_get_ref( + ptr, owner_ptr, owner_get_ref, owner_put_ref + ) return field -# Get the "effective" field of `field`. If `field` is a variant, return the -# currently selected field. If `field` is of any other type, return `field` +def _create_field_from_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref): + return _create_field_from_ptr_template( + _TYPE_ID_TO_OBJ, ptr, owner_ptr, owner_get_ref, owner_put_ref + ) + + +def _create_field_from_const_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref): + return _create_field_from_ptr_template( + _TYPE_ID_TO_CONST_OBJ, ptr, owner_ptr, owner_get_ref, owner_put_ref + ) + + +# Get the "effective" field of `field`. If `field` is a variant, return +# the currently selected field. If `field` is an option, return the +# content field. If `field` is of any other type, return `field` # directly. + def _get_leaf_field(field): - if not isinstance(field, _VariantField): - return field + if isinstance(field, _VariantFieldConst): + return _get_leaf_field(field.selected_option) - return _get_leaf_field(field.selected_option) + if isinstance(field, _OptionFieldConst): + return _get_leaf_field(field.field) + + return field -class _Field(object._UniqueObject): +class _FieldConst(object._UniqueObject): + _create_field_from_ptr = staticmethod(_create_field_from_const_ptr) + _create_field_class_from_ptr_and_get_ref = staticmethod( + bt2_field_class._create_field_class_from_const_ptr_and_get_ref + ) + _borrow_class_ptr = staticmethod(native_bt.field_borrow_class_const) + def __eq__(self, other): other = _get_leaf_field(other) return self._spec_eq(other) @property - def field_class(self): - field_class_ptr = native_bt.field_borrow_class_const(self._ptr) + def cls(self): + field_class_ptr = self._borrow_class_ptr(self._ptr) assert field_class_ptr is not None - return bt2.field_class._create_field_class_from_ptr_and_get_ref(field_class_ptr) + return self._create_field_class_from_ptr_and_get_ref(field_class_ptr) def _repr(self): raise NotImplementedError @@ -67,12 +92,55 @@ class _Field(object._UniqueObject): return self._repr() +class _Field(_FieldConst): + _create_field_from_ptr = staticmethod(_create_field_from_ptr) + _create_field_class_from_ptr_and_get_ref = staticmethod( + bt2_field_class._create_field_class_from_ptr_and_get_ref + ) + _borrow_class_ptr = staticmethod(native_bt.field_borrow_class) + + +class _BitArrayFieldConst(_FieldConst): + _NAME = 'Const bit array' + + @property + def value_as_integer(self): + return native_bt.field_bit_array_get_value_as_integer(self._ptr) + + def _spec_eq(self, other): + if type(other) is not type(self): + return False + + return self.value_as_integer == other.value_as_integer + + def _repr(self): + return repr(self.value_as_integer) + + def __str__(self): + return str(self.value_as_integer) + + def __len__(self): + return self.cls.length + + +class _BitArrayField(_BitArrayFieldConst, _Field): + _NAME = 'Bit array' + + def _value_as_integer(self, value): + utils._check_uint64(value) + native_bt.field_bit_array_set_value_as_integer(self._ptr, value) + + value_as_integer = property( + fget=_BitArrayFieldConst.value_as_integer.fget, fset=_value_as_integer + ) + + @functools.total_ordering -class _NumericField(_Field): +class _NumericFieldConst(_FieldConst): @staticmethod def _extract_value(other): - if isinstance(other, bool): - return other + if isinstance(other, _BoolFieldConst) or isinstance(other, bool): + return bool(other) if isinstance(other, numbers.Integral): return int(other) @@ -83,7 +151,9 @@ class _NumericField(_Field): if isinstance(other, numbers.Complex): return complex(other) - raise TypeError("'{}' object is not a number object".format(other.__class__.__name__)) + raise TypeError( + "'{}' object is not a number object".format(other.__class__.__name__) + ) def __int__(self): return int(self._value) @@ -96,17 +166,23 @@ class _NumericField(_Field): def __lt__(self, other): if not isinstance(other, numbers.Number): - raise TypeError('unorderable types: {}() < {}()'.format(self.__class__.__name__, - other.__class__.__name__)) + raise TypeError( + 'unorderable types: {}() < {}()'.format( + self.__class__.__name__, other.__class__.__name__ + ) + ) return self._value < self._extract_value(other) def _spec_eq(self, other): try: return self._value == self._extract_value(other) - except: + except Exception: return False + def __hash__(self): + return hash(self._value) + def __rmod__(self, other): return self._extract_value(other) % self._value @@ -168,7 +244,14 @@ class _NumericField(_Field): return self._extract_value(base) ** self._value -class _IntegralField(_NumericField, numbers.Integral): +class _NumericField(_NumericFieldConst, _Field): + def __hash__(self): + # Non const field are not hashable as their value may be modified + # without changing the underlying Python object. + raise TypeError('unhashable type: \'{}\''.format(self._NAME)) + + +class _IntegralFieldConst(_NumericFieldConst, numbers.Integral): def __lshift__(self, other): return self._value << self._extract_value(other) @@ -203,106 +286,234 @@ class _IntegralField(_NumericField, numbers.Integral): return ~self._value -class _IntegerField(_IntegralField, _Field): +class _IntegralField(_IntegralFieldConst, _NumericField): pass -class _UnsignedIntegerField(_IntegerField, _Field): - _NAME = 'Unsigned integer' +class _BoolFieldConst(_IntegralFieldConst, _FieldConst): + _NAME = 'Const boolean' - def _value_to_int(self, value): - if not isinstance(value, numbers.Integral): - raise TypeError('expecting an integral number object') + def __bool__(self): + return self._value - value = int(value) - utils._check_uint64(value) + @classmethod + def _value_to_bool(cls, value): + if isinstance(value, _BoolFieldConst): + value = value._value + + if not isinstance(value, bool): + raise TypeError( + "'{}' object is not a 'bool', '_BoolFieldConst', or '_BoolField' object".format( + value.__class__ + ) + ) return value @property def _value(self): - return native_bt.field_unsigned_integer_get_value(self._ptr) + return bool(native_bt.field_bool_get_value(self._ptr)) + + +class _BoolField(_BoolFieldConst, _IntegralField, _Field): + _NAME = 'Boolean' def _set_value(self, value): - value = self._value_to_int(value) - native_bt.field_unsigned_integer_set_value(self._ptr, value) + value = self._value_to_bool(value) + native_bt.field_bool_set_value(self._ptr, value) value = property(fset=_set_value) -class _SignedIntegerField(_IntegerField, _Field): - _NAME = 'Signed integer' +class _IntegerFieldConst(_IntegralFieldConst, _FieldConst): + pass - def _value_to_int(self, value): + +class _IntegerField(_IntegerFieldConst, _IntegralField, _Field): + def _check_range(self, value): + if not (value >= self._lower_bound and value <= self._upper_bound): + raise ValueError( + "Value {} is outside valid range [{}, {}]".format( + value, self._lower_bound, self._upper_bound + ) + ) + + +class _UnsignedIntegerFieldConst(_IntegerFieldConst, _FieldConst): + _NAME = 'Const unsigned integer' + + @classmethod + def _value_to_int(cls, value): if not isinstance(value, numbers.Integral): raise TypeError('expecting an integral number object') - value = int(value) - utils._check_int64(value) + return int(value) - return value + @property + def _value(self): + return native_bt.field_integer_unsigned_get_value(self._ptr) + + +class _UnsignedIntegerField(_UnsignedIntegerFieldConst, _IntegerField, _Field): + _NAME = 'Unsigned integer' + + def _set_value(self, value): + value = self._value_to_int(value) + + self._check_range(value) + + native_bt.field_integer_unsigned_set_value(self._ptr, value) + + value = property(fset=_set_value) + + @property + def _lower_bound(self): + return 0 + + @property + def _upper_bound(self): + return (2 ** self.cls.field_value_range) - 1 + + +class _SignedIntegerFieldConst(_IntegerFieldConst, _FieldConst): + _NAME = 'Const signed integer' + + @classmethod + def _value_to_int(cls, value): + if not isinstance(value, numbers.Integral): + raise TypeError('expecting an integral number object') + + return int(value) @property def _value(self): - return native_bt.field_signed_integer_get_value(self._ptr) + return native_bt.field_integer_signed_get_value(self._ptr) + + +class _SignedIntegerField(_SignedIntegerFieldConst, _IntegerField, _Field): + _NAME = 'Signed integer' def _set_value(self, value): value = self._value_to_int(value) - native_bt.field_signed_integer_set_value(self._ptr, value) + + self._check_range(value) + + native_bt.field_integer_signed_set_value(self._ptr, value) value = property(fset=_set_value) + @property + def _lower_bound(self): + return -1 * (2 ** (self.cls.field_value_range - 1)) + + @property + def _upper_bound(self): + return (2 ** (self.cls.field_value_range - 1)) - 1 -class _RealField(_NumericField, numbers.Real): - _NAME = 'Real' - def _value_to_float(self, value): +class _RealFieldConst(_NumericFieldConst, numbers.Real): + _NAME = 'Const real' + + @classmethod + def _value_to_float(cls, value): if not isinstance(value, numbers.Real): raise TypeError("expecting a real number object") return float(value) + +class _SinglePrecisionRealFieldConst(_RealFieldConst): + _NAME = 'Const single-precision real' + @property def _value(self): - return native_bt.field_real_get_value(self._ptr) + return native_bt.field_real_single_precision_get_value(self._ptr) + + +class _DoublePrecisionRealFieldConst(_RealFieldConst): + _NAME = 'Const double-precision real' + + @property + def _value(self): + return native_bt.field_real_double_precision_get_value(self._ptr) + + +class _RealField(_RealFieldConst, _NumericField): + _NAME = 'Real' + + +class _SinglePrecisionRealField(_SinglePrecisionRealFieldConst, _RealField): + _NAME = 'Single-precision real' + + def _set_value(self, value): + value = self._value_to_float(value) + native_bt.field_real_single_precision_set_value(self._ptr, value) + + value = property(fset=_set_value) + + +class _DoublePrecisionRealField(_DoublePrecisionRealFieldConst, _RealField): + _NAME = 'Double-precision real' def _set_value(self, value): value = self._value_to_float(value) - native_bt.field_real_set_value(self._ptr, value) + native_bt.field_real_double_precision_set_value(self._ptr, value) value = property(fset=_set_value) -class _EnumerationField(_IntegerField): +class _EnumerationFieldConst(_IntegerFieldConst): def _repr(self): return '{} ({})'.format(self._value, ', '.join(self.labels)) @property def labels(self): status, labels = self._get_mapping_labels(self._ptr) - utils._handle_func_status(status, - "cannot get label for enumeration field") + utils._handle_func_status(status, "cannot get label for enumeration field") assert labels is not None return labels -class _UnsignedEnumerationField(_EnumerationField, _UnsignedIntegerField): - _NAME = 'Unsigned Enumeration' - _get_mapping_labels = staticmethod(native_bt.field_unsigned_enumeration_get_mapping_labels) +class _EnumerationField(_EnumerationFieldConst, _IntegerField): + pass + + +class _UnsignedEnumerationFieldConst( + _EnumerationFieldConst, _UnsignedIntegerFieldConst +): + _NAME = 'Const unsigned Enumeration' + _get_mapping_labels = staticmethod( + native_bt.field_enumeration_unsigned_get_mapping_labels + ) + + +class _UnsignedEnumerationField( + _UnsignedEnumerationFieldConst, _EnumerationField, _UnsignedIntegerField +): + _NAME = 'Unsigned enumeration' -class _SignedEnumerationField(_EnumerationField, _SignedIntegerField): - _NAME = 'Signed Enumeration' - _get_mapping_labels = staticmethod(native_bt.field_signed_enumeration_get_mapping_labels) +class _SignedEnumerationFieldConst(_EnumerationFieldConst, _SignedIntegerFieldConst): + _NAME = 'Const signed Enumeration' + _get_mapping_labels = staticmethod( + native_bt.field_enumeration_signed_get_mapping_labels + ) + + +class _SignedEnumerationField( + _SignedEnumerationFieldConst, _EnumerationField, _SignedIntegerField +): + _NAME = 'Signed enumeration' @functools.total_ordering -class _StringField(_Field): - _NAME = 'String' +class _StringFieldConst(_FieldConst): + _NAME = 'Const string' - def _value_to_str(self, value): - if isinstance(value, self.__class__): + @classmethod + def _value_to_str(cls, value): + if isinstance(value, _StringFieldConst): value = value._value if not isinstance(value, str): @@ -314,16 +525,10 @@ class _StringField(_Field): def _value(self): return native_bt.field_string_get_value(self._ptr) - def _set_value(self, value): - value = self._value_to_str(value) - native_bt.field_string_set_value(self._ptr, value) - - value = property(fset=_set_value) - def _spec_eq(self, other): try: return self._value == self._value_to_str(other) - except: + except Exception: return False def __lt__(self, other): @@ -332,6 +537,9 @@ class _StringField(_Field): def __bool__(self): return bool(self._value) + def __hash__(self): + return hash(self._value) + def _repr(self): return repr(self._value) @@ -344,18 +552,37 @@ class _StringField(_Field): def __len__(self): return native_bt.field_string_get_length(self._ptr) + +class _StringField(_StringFieldConst, _Field): + _NAME = 'String' + + def _set_value(self, value): + value = self._value_to_str(value) + native_bt.field_string_set_value(self._ptr, value) + + value = property(fset=_set_value) + def __iadd__(self, value): value = self._value_to_str(value) status = native_bt.field_string_append(self._ptr, value) - utils._handle_func_status(status, - "cannot append to string field object's value") + utils._handle_func_status( + status, "cannot append to string field object's value" + ) return self + def __hash__(self): + # Non const field are not hashable as their value may be modified + # without changing the underlying Python object. + raise TypeError('unhashable type: \'{}\''.format(self._NAME)) + -class _ContainerField(_Field): +class _ContainerFieldConst(_FieldConst): def __bool__(self): return len(self) != 0 + def _count(self): + return len(self.cls) + def __len__(self): count = self._count() assert count >= 0 @@ -364,24 +591,31 @@ class _ContainerField(_Field): def __delitem__(self, index): raise NotImplementedError + def __setitem__(self, index, value): + raise TypeError( + '\'{}\' object does not support item assignment'.format(self.__class__) + ) -class _StructureField(_ContainerField, collections.abc.MutableMapping): - _NAME = 'Structure' - def _count(self): - return len(self.field_class) +class _ContainerField(_ContainerFieldConst, _Field): + pass - def __setitem__(self, key, value): - # raises if key is somehow invalid - field = self[key] - # the field's property does the appropriate conversion or raises - # the appropriate exception - field.value = value +class _StructureFieldConst(_ContainerFieldConst, collections.abc.Mapping): + _NAME = 'Const structure' + _borrow_member_field_ptr_by_index = staticmethod( + native_bt.field_structure_borrow_member_field_by_index_const + ) + _borrow_member_field_ptr_by_name = staticmethod( + native_bt.field_structure_borrow_member_field_by_name_const + ) + + def _count(self): + return len(self.cls) def __iter__(self): # same name iterator - return iter(self.field_class) + return iter(self.cls) def _spec_eq(self, other): if not isinstance(other, collections.abc.Mapping): @@ -400,62 +634,136 @@ class _StructureField(_ContainerField, collections.abc.MutableMapping): return True - def _set_value(self, values): - try: - for key, value in values.items(): - self[key].value = value - except Exception: - raise - - value = property(fset=_set_value) - def _repr(self): items = ['{}: {}'.format(repr(k), repr(v)) for k, v in self.items()] return '{{{}}}'.format(', '.join(items)) def __getitem__(self, key): utils._check_str(key) - field_ptr = native_bt.field_structure_borrow_member_field_by_name(self._ptr, key) + field_ptr = self._borrow_member_field_ptr_by_name(self._ptr, key) if field_ptr is None: raise KeyError(key) - return _create_field_from_ptr(field_ptr, self._owner_ptr, - self._owner_get_ref, - self._owner_put_ref) + return self._create_field_from_ptr( + field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref + ) def member_at_index(self, index): utils._check_uint64(index) if index >= len(self): raise IndexError - - field_ptr = native_bt.field_structure_borrow_member_field_by_index(self._ptr, index) + field_ptr = self._borrow_member_field_ptr_by_index(self._ptr, index) assert field_ptr is not None - return _create_field_from_ptr(field_ptr, self._owner_ptr, - self._owner_get_ref, - self._owner_put_ref) + return self._create_field_from_ptr( + field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref + ) -class _VariantField(_ContainerField, _Field): - _NAME = 'Variant' +class _StructureField( + _StructureFieldConst, _ContainerField, collections.abc.MutableMapping +): + _NAME = 'Structure' + _borrow_member_field_ptr_by_index = staticmethod( + native_bt.field_structure_borrow_member_field_by_index + ) + _borrow_member_field_ptr_by_name = staticmethod( + native_bt.field_structure_borrow_member_field_by_name + ) + + def __setitem__(self, key, value): + # raises if key is somehow invalid + field = self[key] + + # the field's property does the appropriate conversion or raises + # the appropriate exception + field.value = value + + def _set_value(self, values): + try: + for key, value in values.items(): + self[key].value = value + except Exception: + raise + + value = property(fset=_set_value) + + +class _OptionFieldConst(_FieldConst): + _NAME = 'Const option' + _borrow_field_ptr = staticmethod(native_bt.field_option_borrow_field_const) @property - def selected_option_index(self): - return native_bt.field_variant_get_selected_option_field_index(self._ptr) + def field(self): + field_ptr = self._borrow_field_ptr(self._ptr) + + if field_ptr is None: + return + + return self._create_field_from_ptr( + field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref + ) + + @property + def has_field(self): + return self.field is not None + + def _spec_eq(self, other): + return _get_leaf_field(self) == other + + def __bool__(self): + return self.has_field - @selected_option_index.setter - def selected_option_index(self, index): - native_bt.field_variant_select_option_field(self._ptr, index) + def __str__(self): + return str(self.field) + + def _repr(self): + return repr(self.field) + + +class _OptionField(_OptionFieldConst, _Field): + _NAME = 'Option' + _borrow_field_ptr = staticmethod(native_bt.field_option_borrow_field) + + def _has_field(self, value): + utils._check_bool(value) + native_bt.field_option_set_has_field(self._ptr, value) + + has_field = property(fget=_OptionFieldConst.has_field.fget, fset=_has_field) + + def _set_value(self, value): + self.has_field = True + field = self.field + assert field is not None + field.value = value + + value = property(fset=_set_value) + + +class _VariantFieldConst(_ContainerFieldConst, _FieldConst): + _NAME = 'Const variant' + _borrow_selected_option_field_ptr = staticmethod( + native_bt.field_variant_borrow_selected_option_field_const + ) + + def _count(self): + return len(self.cls) + + @property + def selected_option_index(self): + return native_bt.field_variant_get_selected_option_index(self._ptr) @property def selected_option(self): - field_ptr = native_bt.field_variant_borrow_selected_option_field(self._ptr) - utils._handle_ptr(field_ptr, "cannot get variant field's selected option") + # TODO: Is there a way to check if the variant field has a selected_option, + # so we can raise an exception instead of hitting a pre-condition check? + # If there is something, that check should be added to selected_option_index too. + field_ptr = self._borrow_selected_option_field_ptr(self._ptr) - return _create_field_from_ptr(field_ptr, self._owner_ptr, - self._owner_get_ref, - self._owner_put_ref) + return self._create_field_from_ptr( + field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref + ) def _spec_eq(self, other): return _get_leaf_field(self) == other @@ -469,13 +777,34 @@ class _VariantField(_ContainerField, _Field): def _repr(self): return repr(self.selected_option) + +class _VariantField(_VariantFieldConst, _ContainerField, _Field): + _NAME = 'Variant' + _borrow_selected_option_field_ptr = staticmethod( + native_bt.field_variant_borrow_selected_option_field + ) + + def _selected_option_index(self, index): + if index < 0 or index >= len(self): + raise IndexError('{} field object index is out of range'.format(self._NAME)) + + native_bt.field_variant_select_option_by_index(self._ptr, index) + + selected_option_index = property( + fget=_VariantFieldConst.selected_option_index.fget, fset=_selected_option_index + ) + def _set_value(self, value): self.selected_option.value = value value = property(fset=_set_value) -class _ArrayField(_ContainerField, _Field, collections.abc.MutableSequence): +class _ArrayFieldConst(_ContainerFieldConst, _FieldConst, collections.abc.Sequence): + _borrow_element_field_ptr_by_index = staticmethod( + native_bt.field_array_borrow_element_field_by_index_const + ) + def _get_length(self): return native_bt.field_array_get_length(self._ptr) @@ -483,29 +812,22 @@ class _ArrayField(_ContainerField, _Field, collections.abc.MutableSequence): def __getitem__(self, index): if not isinstance(index, numbers.Integral): - raise TypeError("'{}' is not an integral number object: invalid index".format(index.__class__.__name__)) + raise TypeError( + "'{}' is not an integral number object: invalid index".format( + index.__class__.__name__ + ) + ) index = int(index) if index < 0 or index >= len(self): raise IndexError('{} field object index is out of range'.format(self._NAME)) - field_ptr = native_bt.field_array_borrow_element_field_by_index(self._ptr, index) - assert(field_ptr) - return _create_field_from_ptr(field_ptr, self._owner_ptr, - self._owner_get_ref, - self._owner_put_ref) - - def __setitem__(self, index, value): - # raises if index is somehow invalid - field = self[index] - - if not isinstance(field, (_NumericField, _StringField)): - raise TypeError('can only set the value of a number or string field') - - # the field's property does the appropriate conversion or raises - # the appropriate exception - field.value = value + field_ptr = self._borrow_element_field_ptr_by_index(self._ptr, index) + assert field_ptr + return self._create_field_from_ptr( + field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref + ) def insert(self, index, value): raise NotImplementedError @@ -528,16 +850,42 @@ class _ArrayField(_ContainerField, _Field, collections.abc.MutableSequence): return '[{}]'.format(', '.join([repr(v) for v in self])) -class _StaticArrayField(_ArrayField, _Field): - _NAME = 'Static array' +class _ArrayField( + _ArrayFieldConst, _ContainerField, _Field, collections.abc.MutableSequence +): + _borrow_element_field_ptr_by_index = staticmethod( + native_bt.field_array_borrow_element_field_by_index + ) + + def __setitem__(self, index, value): + # raises if index is somehow invalid + field = self[index] + + if not isinstance(field, (_NumericField, _StringField)): + raise TypeError('can only set the value of a number or string field') + + # the field's property does the appropriate conversion or raises + # the appropriate exception + field.value = value + + +class _StaticArrayFieldConst(_ArrayFieldConst, _FieldConst): + _NAME = 'Const static array' def _count(self): return native_bt.field_array_get_length(self._ptr) + +class _StaticArrayField(_StaticArrayFieldConst, _ArrayField, _Field): + _NAME = 'Static array' + def _set_value(self, values): if len(self) != len(values): raise ValueError( - 'expected length of value and array field to match') + 'expected length of value ({}) and array field ({}) to match'.format( + len(values), len(self) + ) + ) for index, value in enumerate(values): if value is not None: @@ -546,15 +894,19 @@ class _StaticArrayField(_ArrayField, _Field): value = property(fset=_set_value) -class _DynamicArrayField(_ArrayField, _Field): - _NAME = 'Dynamic array' +class _DynamicArrayFieldConst(_ArrayFieldConst, _FieldConst): + _NAME = 'Const dynamic array' def _count(self): return self.length + +class _DynamicArrayField(_DynamicArrayFieldConst, _ArrayField, _Field): + _NAME = 'Dynamic array' + def _set_length(self, length): utils._check_uint64(length) - status = native_bt.field_dynamic_array_set_length(self._ptr, length) + status = native_bt.field_array_dynamic_set_length(self._ptr, length) utils._handle_func_status(status, "cannot set dynamic array length") length = property(fget=_ArrayField._get_length, fset=_set_length) @@ -570,15 +922,48 @@ class _DynamicArrayField(_ArrayField, _Field): value = property(fset=_set_value) +_TYPE_ID_TO_CONST_OBJ = { + native_bt.FIELD_CLASS_TYPE_BOOL: _BoolFieldConst, + native_bt.FIELD_CLASS_TYPE_BIT_ARRAY: _BitArrayFieldConst, + native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerFieldConst, + native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerFieldConst, + native_bt.FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL: _SinglePrecisionRealFieldConst, + native_bt.FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL: _DoublePrecisionRealFieldConst, + native_bt.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: _UnsignedEnumerationFieldConst, + native_bt.FIELD_CLASS_TYPE_SIGNED_ENUMERATION: _SignedEnumerationFieldConst, + native_bt.FIELD_CLASS_TYPE_STRING: _StringFieldConst, + native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldConst, + native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldConst, + native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: _DynamicArrayFieldConst, + native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: _DynamicArrayFieldConst, + native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: _OptionFieldConst, + native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: _OptionFieldConst, + native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _OptionFieldConst, + native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _OptionFieldConst, + native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: _VariantFieldConst, + native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _VariantFieldConst, + native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _VariantFieldConst, +} + _TYPE_ID_TO_OBJ = { + native_bt.FIELD_CLASS_TYPE_BOOL: _BoolField, + native_bt.FIELD_CLASS_TYPE_BIT_ARRAY: _BitArrayField, native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerField, native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerField, - native_bt.FIELD_CLASS_TYPE_REAL: _RealField, + native_bt.FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL: _SinglePrecisionRealField, + native_bt.FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL: _DoublePrecisionRealField, native_bt.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: _UnsignedEnumerationField, native_bt.FIELD_CLASS_TYPE_SIGNED_ENUMERATION: _SignedEnumerationField, native_bt.FIELD_CLASS_TYPE_STRING: _StringField, native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureField, native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayField, - native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayField, - native_bt.FIELD_CLASS_TYPE_VARIANT: _VariantField, + native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: _DynamicArrayField, + native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: _DynamicArrayField, + native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: _OptionField, + native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: _OptionField, + native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _OptionField, + native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _OptionField, + native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: _VariantField, + native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _VariantField, + native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _VariantField, }