1 # The MIT License (MIT)
3 # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 from bt2
import native_bt
, object, utils
24 import collections
.abc
30 def _create_field_class_from_ptr_and_get_ref(ptr
):
31 typeid
= native_bt
.field_class_get_type(ptr
)
32 return _FIELD_CLASS_TYPE_TO_OBJ
[typeid
]._create
_from
_ptr
_and
_get
_ref
(ptr
)
35 class IntegerDisplayBase
:
36 BINARY
= native_bt
.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY
37 OCTAL
= native_bt
.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL
38 DECIMAL
= native_bt
.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
39 HEXADECIMAL
= native_bt
.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL
42 class _FieldClass(object._SharedObject
):
43 _get_ref
= staticmethod(native_bt
.field_class_get_ref
)
44 _put_ref
= staticmethod(native_bt
.field_class_put_ref
)
46 def _check_create_status(self
, ptr
):
48 raise bt2
.CreationError('cannot create {} field class object'.format(self
._NAME
.lower()))
51 class _IntegerFieldClass(_FieldClass
):
53 def field_value_range(self
):
54 size
= native_bt
.field_class_integer_get_field_value_range(self
._ptr
)
58 def _field_value_range(self
, size
):
59 if size
< 1 or size
> 64:
60 raise ValueError("Value is outside valid range [1, 64] ({})".format(size
))
61 native_bt
.field_class_integer_set_field_value_range(self
._ptr
, size
)
63 _field_value_range
= property(fset
=_field_value_range
)
66 def preferred_display_base(self
):
67 base
= native_bt
.field_class_integer_get_preferred_display_base(
72 def _preferred_display_base(self
, base
):
73 utils
._check
_uint
64(base
)
75 if base
not in (IntegerDisplayBase
.BINARY
,
76 IntegerDisplayBase
.OCTAL
,
77 IntegerDisplayBase
.DECIMAL
,
78 IntegerDisplayBase
.HEXADECIMAL
):
79 raise ValueError("Display base is not a valid IntegerDisplayBase value")
81 native_bt
.field_class_integer_set_preferred_display_base(
84 _preferred_display_base
= property(fset
=_preferred_display_base
)
87 class _UnsignedIntegerFieldClass(_IntegerFieldClass
):
88 _NAME
= 'Unsigned integer'
91 class _SignedIntegerFieldClass(_IntegerFieldClass
):
92 _NAME
= 'Signed integer'
95 class _RealFieldClass(_FieldClass
):
99 def is_single_precision(self
):
100 return native_bt
.field_class_real_is_single_precision(self
._ptr
)
102 def _is_single_precision(self
, is_single_precision
):
103 utils
._check
_bool
(is_single_precision
)
104 native_bt
.field_class_real_set_is_single_precision(
105 self
._ptr
, is_single_precision
)
107 _is_single_precision
= property(fset
=_is_single_precision
)
110 class _EnumerationFieldClassMappingRange
:
111 def __init__(self
, lower
, upper
):
123 def __eq__(self
, other
):
124 return self
.lower
== other
.lower
and self
.upper
== other
.upper
127 class _EnumerationFieldClassMapping(collections
.abc
.Set
):
128 def __init__(self
, mapping_ptr
):
129 self
._mapping
_ptr
= mapping_ptr
133 mapping_ptr
= self
._as
_enumeration
_field
_class
_mapping
_ptr
(self
._mapping
_ptr
)
134 label
= native_bt
.field_class_enumeration_mapping_get_label(mapping_ptr
)
135 assert label
is not None
139 mapping_ptr
= self
._as
_enumeration
_field
_class
_mapping
_ptr
(self
._mapping
_ptr
)
140 return native_bt
.field_class_enumeration_mapping_get_range_count(mapping_ptr
)
142 def __contains__(self
, other_range
):
143 for curr_range
in self
:
144 if curr_range
== other_range
:
149 for idx
in range(len(self
)):
150 lower
, upper
= self
._get
_range
_by
_index
(self
._mapping
_ptr
, idx
)
151 yield _EnumerationFieldClassMappingRange(lower
, upper
)
154 class _UnsignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping
):
155 _as_enumeration_field_class_mapping_ptr
= staticmethod(native_bt
.field_class_unsigned_enumeration_mapping_as_mapping_const
)
156 _get_range_by_index
= staticmethod(native_bt
.field_class_unsigned_enumeration_mapping_get_range_by_index
)
159 class _SignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping
):
160 _as_enumeration_field_class_mapping_ptr
= staticmethod(native_bt
.field_class_signed_enumeration_mapping_as_mapping_const
)
161 _get_range_by_index
= staticmethod(native_bt
.field_class_signed_enumeration_mapping_get_range_by_index
)
164 class _EnumerationFieldClass(_IntegerFieldClass
, collections
.abc
.Mapping
):
166 count
= native_bt
.field_class_enumeration_get_mapping_count(self
._ptr
)
170 def map_range(self
, label
, lower
, upper
=None):
171 utils
._check
_str
(label
)
176 ret
= self
._map
_range
(self
._ptr
, label
, lower
, upper
)
177 utils
._handle
_ret
(ret
, "cannot add mapping to enumeration field class object")
179 def labels_by_value(self
, value
):
180 ret
, labels
= self
._get
_mapping
_labels
_by
_value
(self
._ptr
, value
)
181 utils
._handle
_ret
(ret
, "cannot get mapping labels")
185 for idx
in range(len(self
)):
186 mapping
= self
._get
_mapping
_by
_index
(self
._ptr
, idx
)
189 def __getitem__(self
, key
):
190 utils
._check
_str
(key
)
191 for idx
in range(len(self
)):
192 mapping
= self
._get
_mapping
_by
_index
(self
._ptr
, idx
)
193 if mapping
.label
== key
:
198 def __iadd__(self
, mappings
):
199 for mapping
in mappings
.values():
200 for range in mapping
:
201 self
.map_range(mapping
.label
, range.lower
, range.upper
)
206 class _UnsignedEnumerationFieldClass(_EnumerationFieldClass
, _UnsignedIntegerFieldClass
):
207 _NAME
= 'Unsigned enumeration'
210 def _get_mapping_by_index(enum_ptr
, index
):
211 mapping_ptr
= native_bt
.field_class_unsigned_enumeration_borrow_mapping_by_index_const(enum_ptr
, index
)
212 assert mapping_ptr
is not None
213 return _UnsignedEnumerationFieldClassMapping(mapping_ptr
)
216 def _map_range(enum_ptr
, label
, lower
, upper
):
217 utils
._check
_uint
64(lower
)
218 utils
._check
_uint
64(upper
)
219 return native_bt
.field_class_unsigned_enumeration_map_range(enum_ptr
, label
, lower
, upper
)
222 def _get_mapping_labels_by_value(enum_ptr
, value
):
223 utils
._check
_uint
64(value
)
224 return native_bt
.field_class_unsigned_enumeration_get_mapping_labels_by_value(enum_ptr
, value
)
227 class _SignedEnumerationFieldClass(_EnumerationFieldClass
, _SignedIntegerFieldClass
):
228 _NAME
= 'Signed enumeration'
231 def _get_mapping_by_index(enum_ptr
, index
):
232 mapping_ptr
= native_bt
.field_class_signed_enumeration_borrow_mapping_by_index_const(enum_ptr
, index
)
233 assert mapping_ptr
is not None
234 return _SignedEnumerationFieldClassMapping(mapping_ptr
)
237 def _map_range(enum_ptr
, label
, lower
, upper
):
238 utils
._check
_int
64(lower
)
239 utils
._check
_int
64(upper
)
240 return native_bt
.field_class_signed_enumeration_map_range(enum_ptr
, label
, lower
, upper
)
243 def _get_mapping_labels_by_value(enum_ptr
, value
):
244 utils
._check
_int
64(value
)
245 return native_bt
.field_class_signed_enumeration_get_mapping_labels_by_value(enum_ptr
, value
)
248 class _StringFieldClass(_FieldClass
):
252 class _FieldContainer(collections
.abc
.Mapping
):
254 count
= self
._get
_element
_count
(self
._ptr
)
258 def __getitem__(self
, key
):
259 if not isinstance(key
, str):
260 raise TypeError("key should be a 'str' object, got {}".format(key
.__class
__.__name
__))
262 ptr
= self
._borrow
_field
_class
_ptr
_by
_name
(key
)
267 return _create_field_class_from_ptr_and_get_ref(ptr
)
269 def _borrow_field_class_ptr_by_name(self
, key
):
270 element_ptr
= self
._borrow
_element
_by
_name
(self
._ptr
, key
)
271 if element_ptr
is None:
274 return self
._element
_borrow
_field
_class
(element_ptr
)
277 for idx
in range(len(self
)):
278 element_ptr
= self
._borrow
_element
_by
_index
(self
._ptr
, idx
)
279 assert element_ptr
is not None
281 yield self
._element
_get
_name
(element_ptr
)
283 def _append_element_common(self
, name
, field_class
):
284 utils
._check
_str
(name
)
285 utils
._check
_type
(field_class
, _FieldClass
)
286 ret
= self
._append
_element
(self
._ptr
, name
, field_class
._ptr
)
287 utils
._handle
_ret
(ret
, "cannot add field to {} field class object".format(self
._NAME
.lower()))
289 def __iadd__(self
, fields
):
290 for name
, field_class
in fields
.items():
291 self
._append
_element
_common
(name
, field_class
)
295 def _at_index(self
, index
):
296 utils
._check
_uint
64(index
)
298 if index
< 0 or index
>= len(self
):
301 element_ptr
= self
._borrow
_element
_by
_index
(self
._ptr
, index
)
302 assert element_ptr
is not None
304 field_class_ptr
= self
._element
_borrow
_field
_class
(element_ptr
)
306 return _create_field_class_from_ptr_and_get_ref(field_class_ptr
)
309 class _StructureFieldClass(_FieldClass
, _FieldContainer
):
311 _borrow_element_by_index
= staticmethod(native_bt
.field_class_structure_borrow_member_by_index_const
)
312 _borrow_element_by_name
= staticmethod(native_bt
.field_class_structure_borrow_member_by_name_const
)
313 _element_get_name
= staticmethod(native_bt
.field_class_structure_member_get_name
)
314 _element_borrow_field_class
= staticmethod(native_bt
.field_class_structure_member_borrow_field_class_const
)
315 _get_element_count
= staticmethod(native_bt
.field_class_structure_get_member_count
)
316 _append_element
= staticmethod(native_bt
.field_class_structure_append_member
)
318 def append_member(self
, name
, field_class
):
319 return self
._append
_element
_common
(name
, field_class
)
321 def member_at_index(self
, index
):
322 return self
._at
_index
(index
)
325 class _VariantFieldClass(_FieldClass
, _FieldContainer
):
327 _borrow_element_by_index
= staticmethod(native_bt
.field_class_variant_borrow_option_by_index_const
)
328 _borrow_element_by_name
= staticmethod(native_bt
.field_class_variant_borrow_option_by_name_const
)
329 _element_get_name
= staticmethod(native_bt
.field_class_variant_option_get_name
)
330 _element_borrow_field_class
= staticmethod(native_bt
.field_class_variant_option_borrow_field_class_const
)
331 _get_element_count
= staticmethod(native_bt
.field_class_variant_get_option_count
)
332 _append_element
= staticmethod(native_bt
.field_class_variant_append_option
)
334 def append_option(self
, name
, field_class
):
335 return self
._append
_element
_common
(name
, field_class
)
337 def option_at_index(self
, index
):
338 return self
._at
_index
(index
)
341 def selector_field_path(self
):
342 ptr
= native_bt
.field_class_variant_borrow_selector_field_path_const(self
._ptr
)
346 return bt2
.field_path
._FieldPath
._create
_from
_ptr
_and
_get
_ref
(ptr
)
348 def _set_selector_field_class(self
, selector_fc
):
349 utils
._check
_type
(selector_fc
, bt2
.field_class
._EnumerationFieldClass
)
350 ret
= native_bt
.field_class_variant_set_selector_field_class(self
._ptr
, selector_fc
._ptr
)
351 utils
._handle
_ret
(ret
, "cannot set variant selector field type")
353 _selector_field_class
= property(fset
=_set_selector_field_class
)
356 class _ArrayFieldClass(_FieldClass
):
358 def element_field_class(self
):
359 elem_fc_ptr
= native_bt
.field_class_array_borrow_element_field_class_const(self
._ptr
)
360 return _create_field_class_from_ptr_and_get_ref(elem_fc_ptr
)
363 class _StaticArrayFieldClass(_ArrayFieldClass
):
366 return native_bt
.field_class_static_array_get_length(self
._ptr
)
369 class _DynamicArrayFieldClass(_ArrayFieldClass
):
371 def length_field_path(self
):
372 ptr
= native_bt
.field_class_dynamic_array_borrow_length_field_path_const(self
._ptr
)
376 return bt2
.field_path
._FieldPath
._create
_from
_ptr
_and
_get
_ref
(ptr
)
378 def _set_length_field_class(self
, length_fc
):
379 utils
._check
_type
(length_fc
, _UnsignedIntegerFieldClass
)
380 ret
= native_bt
.field_class_dynamic_array_set_length_field_class(self
._ptr
, length_fc
._ptr
)
381 utils
._handle
_ret
(ret
, "cannot set dynamic array length field type")
383 _length_field_class
= property(fset
=_set_length_field_class
)
386 _FIELD_CLASS_TYPE_TO_OBJ
= {
387 native_bt
.FIELD_CLASS_TYPE_UNSIGNED_INTEGER
: _UnsignedIntegerFieldClass
,
388 native_bt
.FIELD_CLASS_TYPE_SIGNED_INTEGER
: _SignedIntegerFieldClass
,
389 native_bt
.FIELD_CLASS_TYPE_REAL
: _RealFieldClass
,
390 native_bt
.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
: _UnsignedEnumerationFieldClass
,
391 native_bt
.FIELD_CLASS_TYPE_SIGNED_ENUMERATION
: _SignedEnumerationFieldClass
,
392 native_bt
.FIELD_CLASS_TYPE_STRING
: _StringFieldClass
,
393 native_bt
.FIELD_CLASS_TYPE_STRUCTURE
: _StructureFieldClass
,
394 native_bt
.FIELD_CLASS_TYPE_STATIC_ARRAY
: _StaticArrayFieldClass
,
395 native_bt
.FIELD_CLASS_TYPE_DYNAMIC_ARRAY
: _DynamicArrayFieldClass
,
396 native_bt
.FIELD_CLASS_TYPE_VARIANT
: _VariantFieldClass
,