b1f2f9d5c82f1a77dccf4cd75bbc2d0b9bfa2e3e
[babeltrace.git] / src / bindings / python / bt2 / bt2 / field.py
1 # SPDX-License-Identifier: MIT
2 #
3 # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
4
5 from bt2 import native_bt
6 from bt2 import object as bt2_object
7 from bt2 import utils as bt2_utils
8 from bt2 import field_class as bt2_field_class
9 import collections.abc
10 import functools
11 import numbers
12 import math
13
14
15 def _create_field_from_ptr_template(
16 object_map, ptr, owner_ptr, owner_get_ref, owner_put_ref
17 ):
18 field_class_ptr = native_bt.field_borrow_class_const(ptr)
19 typeid = native_bt.field_class_get_type(field_class_ptr)
20 field = object_map[typeid]._create_from_ptr_and_get_ref(
21 ptr, owner_ptr, owner_get_ref, owner_put_ref
22 )
23 return field
24
25
26 def _create_field_from_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref):
27 return _create_field_from_ptr_template(
28 _TYPE_ID_TO_OBJ, ptr, owner_ptr, owner_get_ref, owner_put_ref
29 )
30
31
32 def _create_field_from_const_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref):
33 return _create_field_from_ptr_template(
34 _TYPE_ID_TO_CONST_OBJ, ptr, owner_ptr, owner_get_ref, owner_put_ref
35 )
36
37
38 # Get the "effective" field of `field`. If `field` is a variant, return
39 # the currently selected field. If `field` is an option, return the
40 # content field. If `field` is of any other type, return `field`
41 # directly.
42
43
44 def _get_leaf_field(field):
45 if isinstance(field, _VariantFieldConst):
46 return _get_leaf_field(field.selected_option)
47
48 if isinstance(field, _OptionFieldConst):
49 return _get_leaf_field(field.field)
50
51 return field
52
53
54 class _FieldConst(bt2_object._UniqueObject):
55 _create_field_from_ptr = staticmethod(_create_field_from_const_ptr)
56 _create_field_class_from_ptr_and_get_ref = staticmethod(
57 bt2_field_class._create_field_class_from_const_ptr_and_get_ref
58 )
59 _borrow_class_ptr = staticmethod(native_bt.field_borrow_class_const)
60
61 def __eq__(self, other):
62 other = _get_leaf_field(other)
63 return self._spec_eq(other)
64
65 @property
66 def cls(self):
67 field_class_ptr = self._borrow_class_ptr(self._ptr)
68 assert field_class_ptr is not None
69 return self._create_field_class_from_ptr_and_get_ref(field_class_ptr)
70
71 def _repr(self):
72 raise NotImplementedError
73
74 def __repr__(self):
75 return self._repr()
76
77
78 class _Field(_FieldConst):
79 _create_field_from_ptr = staticmethod(_create_field_from_ptr)
80 _create_field_class_from_ptr_and_get_ref = staticmethod(
81 bt2_field_class._create_field_class_from_ptr_and_get_ref
82 )
83 _borrow_class_ptr = staticmethod(native_bt.field_borrow_class)
84
85
86 class _BitArrayFieldConst(_FieldConst):
87 _NAME = "Const bit array"
88
89 @property
90 def value_as_integer(self):
91 return native_bt.field_bit_array_get_value_as_integer(self._ptr)
92
93 def _spec_eq(self, other):
94 if type(other) is not type(self):
95 return False
96
97 return self.value_as_integer == other.value_as_integer
98
99 def _repr(self):
100 return repr(self.value_as_integer)
101
102 def __str__(self):
103 return str(self.value_as_integer)
104
105 def __len__(self):
106 return self.cls.length
107
108
109 class _BitArrayField(_BitArrayFieldConst, _Field):
110 _NAME = "Bit array"
111
112 def _value_as_integer(self, value):
113 bt2_utils._check_uint64(value)
114 native_bt.field_bit_array_set_value_as_integer(self._ptr, value)
115
116 value_as_integer = property(
117 fget=_BitArrayFieldConst.value_as_integer.fget, fset=_value_as_integer
118 )
119
120
121 @functools.total_ordering
122 class _NumericFieldConst(_FieldConst):
123 @staticmethod
124 def _extract_value(other):
125 if isinstance(other, _BoolFieldConst) or isinstance(other, bool):
126 return bool(other)
127
128 if isinstance(other, numbers.Integral):
129 return int(other)
130
131 if isinstance(other, numbers.Real):
132 return float(other)
133
134 if isinstance(other, numbers.Complex):
135 return complex(other)
136
137 raise TypeError(
138 "'{}' object is not a number object".format(other.__class__.__name__)
139 )
140
141 def __int__(self):
142 return int(self._value)
143
144 def __float__(self):
145 return float(self._value)
146
147 def _repr(self):
148 return repr(self._value)
149
150 def __lt__(self, other):
151 if not isinstance(other, numbers.Number):
152 raise TypeError(
153 "unorderable types: {}() < {}()".format(
154 self.__class__.__name__, other.__class__.__name__
155 )
156 )
157
158 return self._value < self._extract_value(other)
159
160 def _spec_eq(self, other):
161 try:
162 return self._value == self._extract_value(other)
163 except Exception:
164 return False
165
166 def __hash__(self):
167 return hash(self._value)
168
169 def __rmod__(self, other):
170 return self._extract_value(other) % self._value
171
172 def __mod__(self, other):
173 return self._value % self._extract_value(other)
174
175 def __rfloordiv__(self, other):
176 return self._extract_value(other) // self._value
177
178 def __floordiv__(self, other):
179 return self._value // self._extract_value(other)
180
181 def __round__(self, ndigits=None):
182 if ndigits is None:
183 return round(self._value)
184 else:
185 return round(self._value, ndigits)
186
187 def __ceil__(self):
188 return math.ceil(self._value)
189
190 def __floor__(self):
191 return math.floor(self._value)
192
193 def __trunc__(self):
194 return int(self._value)
195
196 def __abs__(self):
197 return abs(self._value)
198
199 def __add__(self, other):
200 return self._value + self._extract_value(other)
201
202 def __radd__(self, other):
203 return self.__add__(other)
204
205 def __neg__(self):
206 return -self._value
207
208 def __pos__(self):
209 return +self._value
210
211 def __mul__(self, other):
212 return self._value * self._extract_value(other)
213
214 def __rmul__(self, other):
215 return self.__mul__(other)
216
217 def __truediv__(self, other):
218 return self._value / self._extract_value(other)
219
220 def __rtruediv__(self, other):
221 return self._extract_value(other) / self._value
222
223 def __pow__(self, exponent):
224 return self._value ** self._extract_value(exponent)
225
226 def __rpow__(self, base):
227 return self._extract_value(base) ** self._value
228
229
230 class _NumericField(_NumericFieldConst, _Field):
231 def __hash__(self):
232 # Non const field are not hashable as their value may be modified
233 # without changing the underlying Python object.
234 raise TypeError("unhashable type: '{}'".format(self._NAME))
235
236
237 class _IntegralFieldConst(_NumericFieldConst, numbers.Integral):
238 def __lshift__(self, other):
239 return self._value << self._extract_value(other)
240
241 def __rlshift__(self, other):
242 return self._extract_value(other) << self._value
243
244 def __rshift__(self, other):
245 return self._value >> self._extract_value(other)
246
247 def __rrshift__(self, other):
248 return self._extract_value(other) >> self._value
249
250 def __and__(self, other):
251 return self._value & self._extract_value(other)
252
253 def __rand__(self, other):
254 return self._extract_value(other) & self._value
255
256 def __xor__(self, other):
257 return self._value ^ self._extract_value(other)
258
259 def __rxor__(self, other):
260 return self._extract_value(other) ^ self._value
261
262 def __or__(self, other):
263 return self._value | self._extract_value(other)
264
265 def __ror__(self, other):
266 return self._extract_value(other) | self._value
267
268 def __invert__(self):
269 return ~self._value
270
271
272 class _IntegralField(_IntegralFieldConst, _NumericField):
273 pass
274
275
276 class _BoolFieldConst(_IntegralFieldConst, _FieldConst):
277 _NAME = "Const boolean"
278
279 def __bool__(self):
280 return self._value
281
282 @classmethod
283 def _value_to_bool(cls, value):
284 if isinstance(value, _BoolFieldConst):
285 value = value._value
286
287 if not isinstance(value, bool):
288 raise TypeError(
289 "'{}' object is not a 'bool', '_BoolFieldConst', or '_BoolField' object".format(
290 value.__class__
291 )
292 )
293
294 return value
295
296 @property
297 def _value(self):
298 return bool(native_bt.field_bool_get_value(self._ptr))
299
300
301 class _BoolField(_BoolFieldConst, _IntegralField, _Field):
302 _NAME = "Boolean"
303
304 def _set_value(self, value):
305 value = self._value_to_bool(value)
306 native_bt.field_bool_set_value(self._ptr, value)
307
308 value = property(fset=_set_value)
309
310
311 class _IntegerFieldConst(_IntegralFieldConst, _FieldConst):
312 pass
313
314
315 class _IntegerField(_IntegerFieldConst, _IntegralField, _Field):
316 def _check_range(self, value):
317 if not (value >= self._lower_bound and value <= self._upper_bound):
318 raise ValueError(
319 "Value {} is outside valid range [{}, {}]".format(
320 value, self._lower_bound, self._upper_bound
321 )
322 )
323
324
325 class _UnsignedIntegerFieldConst(_IntegerFieldConst, _FieldConst):
326 _NAME = "Const unsigned integer"
327
328 @classmethod
329 def _value_to_int(cls, value):
330 if not isinstance(value, numbers.Integral):
331 raise TypeError("expecting an integral number object")
332
333 return int(value)
334
335 @property
336 def _value(self):
337 return native_bt.field_integer_unsigned_get_value(self._ptr)
338
339
340 class _UnsignedIntegerField(_UnsignedIntegerFieldConst, _IntegerField, _Field):
341 _NAME = "Unsigned integer"
342
343 def _set_value(self, value):
344 value = self._value_to_int(value)
345
346 self._check_range(value)
347
348 native_bt.field_integer_unsigned_set_value(self._ptr, value)
349
350 value = property(fset=_set_value)
351
352 @property
353 def _lower_bound(self):
354 return 0
355
356 @property
357 def _upper_bound(self):
358 return (2**self.cls.field_value_range) - 1
359
360
361 class _SignedIntegerFieldConst(_IntegerFieldConst, _FieldConst):
362 _NAME = "Const signed integer"
363
364 @classmethod
365 def _value_to_int(cls, value):
366 if not isinstance(value, numbers.Integral):
367 raise TypeError("expecting an integral number object")
368
369 return int(value)
370
371 @property
372 def _value(self):
373 return native_bt.field_integer_signed_get_value(self._ptr)
374
375
376 class _SignedIntegerField(_SignedIntegerFieldConst, _IntegerField, _Field):
377 _NAME = "Signed integer"
378
379 def _set_value(self, value):
380 value = self._value_to_int(value)
381
382 self._check_range(value)
383
384 native_bt.field_integer_signed_set_value(self._ptr, value)
385
386 value = property(fset=_set_value)
387
388 @property
389 def _lower_bound(self):
390 return -1 * (2 ** (self.cls.field_value_range - 1))
391
392 @property
393 def _upper_bound(self):
394 return (2 ** (self.cls.field_value_range - 1)) - 1
395
396
397 class _RealFieldConst(_NumericFieldConst, numbers.Real):
398 _NAME = "Const real"
399
400 @classmethod
401 def _value_to_float(cls, value):
402 if not isinstance(value, numbers.Real):
403 raise TypeError("expecting a real number object")
404
405 return float(value)
406
407
408 class _SinglePrecisionRealFieldConst(_RealFieldConst):
409 _NAME = "Const single-precision real"
410
411 @property
412 def _value(self):
413 return native_bt.field_real_single_precision_get_value(self._ptr)
414
415
416 class _DoublePrecisionRealFieldConst(_RealFieldConst):
417 _NAME = "Const double-precision real"
418
419 @property
420 def _value(self):
421 return native_bt.field_real_double_precision_get_value(self._ptr)
422
423
424 class _RealField(_RealFieldConst, _NumericField):
425 _NAME = "Real"
426
427
428 class _SinglePrecisionRealField(_SinglePrecisionRealFieldConst, _RealField):
429 _NAME = "Single-precision real"
430
431 def _set_value(self, value):
432 value = self._value_to_float(value)
433 native_bt.field_real_single_precision_set_value(self._ptr, value)
434
435 value = property(fset=_set_value)
436
437
438 class _DoublePrecisionRealField(_DoublePrecisionRealFieldConst, _RealField):
439 _NAME = "Double-precision real"
440
441 def _set_value(self, value):
442 value = self._value_to_float(value)
443 native_bt.field_real_double_precision_set_value(self._ptr, value)
444
445 value = property(fset=_set_value)
446
447
448 class _EnumerationFieldConst(_IntegerFieldConst):
449 def _repr(self):
450 return "{} ({})".format(self._value, ", ".join(self.labels))
451
452 @property
453 def labels(self):
454 status, labels = self._get_mapping_labels(self._ptr)
455 bt2_utils._handle_func_status(status, "cannot get label for enumeration field")
456
457 assert labels is not None
458 return labels
459
460
461 class _EnumerationField(_EnumerationFieldConst, _IntegerField):
462 pass
463
464
465 class _UnsignedEnumerationFieldConst(
466 _EnumerationFieldConst, _UnsignedIntegerFieldConst
467 ):
468 _NAME = "Const unsigned Enumeration"
469 _get_mapping_labels = staticmethod(
470 native_bt.field_enumeration_unsigned_get_mapping_labels
471 )
472
473
474 class _UnsignedEnumerationField(
475 _UnsignedEnumerationFieldConst, _EnumerationField, _UnsignedIntegerField
476 ):
477 _NAME = "Unsigned enumeration"
478
479
480 class _SignedEnumerationFieldConst(_EnumerationFieldConst, _SignedIntegerFieldConst):
481 _NAME = "Const signed Enumeration"
482 _get_mapping_labels = staticmethod(
483 native_bt.field_enumeration_signed_get_mapping_labels
484 )
485
486
487 class _SignedEnumerationField(
488 _SignedEnumerationFieldConst, _EnumerationField, _SignedIntegerField
489 ):
490 _NAME = "Signed enumeration"
491
492
493 @functools.total_ordering
494 class _StringFieldConst(_FieldConst):
495 _NAME = "Const string"
496
497 @classmethod
498 def _value_to_str(cls, value):
499 if isinstance(value, _StringFieldConst):
500 value = value._value
501
502 if not isinstance(value, str):
503 raise TypeError("expecting a 'str' object")
504
505 return value
506
507 @property
508 def _value(self):
509 return native_bt.field_string_get_value(self._ptr)
510
511 def _spec_eq(self, other):
512 try:
513 return self._value == self._value_to_str(other)
514 except Exception:
515 return False
516
517 def __lt__(self, other):
518 return self._value < self._value_to_str(other)
519
520 def __bool__(self):
521 return bool(self._value)
522
523 def __hash__(self):
524 return hash(self._value)
525
526 def _repr(self):
527 return repr(self._value)
528
529 def __str__(self):
530 return str(self._value)
531
532 def __getitem__(self, index):
533 return self._value[index]
534
535 def __len__(self):
536 return native_bt.field_string_get_length(self._ptr)
537
538
539 class _StringField(_StringFieldConst, _Field):
540 _NAME = "String"
541
542 def _set_value(self, value):
543 value = self._value_to_str(value)
544 native_bt.field_string_set_value(self._ptr, value)
545
546 value = property(fset=_set_value)
547
548 def __iadd__(self, value):
549 value = self._value_to_str(value)
550 status = native_bt.field_string_append(self._ptr, value)
551 bt2_utils._handle_func_status(
552 status, "cannot append to string field object's value"
553 )
554 return self
555
556 def __hash__(self):
557 # Non const field are not hashable as their value may be modified
558 # without changing the underlying Python object.
559 raise TypeError("unhashable type: '{}'".format(self._NAME))
560
561
562 class _ContainerFieldConst(_FieldConst):
563 def __bool__(self):
564 return len(self) != 0
565
566 def _count(self):
567 return len(self.cls)
568
569 def __len__(self):
570 count = self._count()
571 assert count >= 0
572 return count
573
574 def __delitem__(self, index):
575 raise NotImplementedError
576
577 def __setitem__(self, index, value):
578 raise TypeError(
579 "'{}' object does not support item assignment".format(self.__class__)
580 )
581
582
583 class _ContainerField(_ContainerFieldConst, _Field):
584 pass
585
586
587 class _StructureFieldConst(_ContainerFieldConst, collections.abc.Mapping):
588 _NAME = "Const structure"
589 _borrow_member_field_ptr_by_index = staticmethod(
590 native_bt.field_structure_borrow_member_field_by_index_const
591 )
592 _borrow_member_field_ptr_by_name = staticmethod(
593 native_bt.field_structure_borrow_member_field_by_name_const
594 )
595
596 def _count(self):
597 return len(self.cls)
598
599 def __iter__(self):
600 # same name iterator
601 return iter(self.cls)
602
603 def _spec_eq(self, other):
604 if not isinstance(other, collections.abc.Mapping):
605 return False
606
607 if len(self) != len(other):
608 # early mismatch
609 return False
610
611 for self_key in self:
612 if self_key not in other:
613 return False
614
615 if self[self_key] != other[self_key]:
616 return False
617
618 return True
619
620 def _repr(self):
621 items = ["{}: {}".format(repr(k), repr(v)) for k, v in self.items()]
622 return "{{{}}}".format(", ".join(items))
623
624 def __getitem__(self, key):
625 bt2_utils._check_str(key)
626 field_ptr = self._borrow_member_field_ptr_by_name(self._ptr, key)
627
628 if field_ptr is None:
629 raise KeyError(key)
630
631 return self._create_field_from_ptr(
632 field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
633 )
634
635 def member_at_index(self, index):
636 bt2_utils._check_uint64(index)
637
638 if index >= len(self):
639 raise IndexError
640 field_ptr = self._borrow_member_field_ptr_by_index(self._ptr, index)
641 assert field_ptr is not None
642 return self._create_field_from_ptr(
643 field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
644 )
645
646
647 class _StructureField(
648 _StructureFieldConst, _ContainerField, collections.abc.MutableMapping
649 ):
650 _NAME = "Structure"
651 _borrow_member_field_ptr_by_index = staticmethod(
652 native_bt.field_structure_borrow_member_field_by_index
653 )
654 _borrow_member_field_ptr_by_name = staticmethod(
655 native_bt.field_structure_borrow_member_field_by_name
656 )
657
658 def __setitem__(self, key, value):
659 # raises if key is somehow invalid
660 field = self[key]
661
662 # the field's property does the appropriate conversion or raises
663 # the appropriate exception
664 field.value = value
665
666 def _set_value(self, values):
667 try:
668 for key, value in values.items():
669 self[key].value = value
670 except Exception:
671 raise
672
673 value = property(fset=_set_value)
674
675
676 class _OptionFieldConst(_FieldConst):
677 _NAME = "Const option"
678 _borrow_field_ptr = staticmethod(native_bt.field_option_borrow_field_const)
679
680 @property
681 def field(self):
682 field_ptr = self._borrow_field_ptr(self._ptr)
683
684 if field_ptr is None:
685 return
686
687 return self._create_field_from_ptr(
688 field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
689 )
690
691 @property
692 def has_field(self):
693 return self.field is not None
694
695 def _spec_eq(self, other):
696 return _get_leaf_field(self) == other
697
698 def __bool__(self):
699 return self.has_field
700
701 def __str__(self):
702 return str(self.field)
703
704 def _repr(self):
705 return repr(self.field)
706
707
708 class _OptionField(_OptionFieldConst, _Field):
709 _NAME = "Option"
710 _borrow_field_ptr = staticmethod(native_bt.field_option_borrow_field)
711
712 def _has_field(self, value):
713 bt2_utils._check_bool(value)
714 native_bt.field_option_set_has_field(self._ptr, value)
715
716 has_field = property(fget=_OptionFieldConst.has_field.fget, fset=_has_field)
717
718 def _set_value(self, value):
719 self.has_field = True
720 field = self.field
721 assert field is not None
722 field.value = value
723
724 value = property(fset=_set_value)
725
726
727 class _VariantFieldConst(_ContainerFieldConst, _FieldConst):
728 _NAME = "Const variant"
729 _borrow_selected_option_field_ptr = staticmethod(
730 native_bt.field_variant_borrow_selected_option_field_const
731 )
732
733 def _count(self):
734 return len(self.cls)
735
736 @property
737 def selected_option_index(self):
738 return native_bt.field_variant_get_selected_option_index(self._ptr)
739
740 @property
741 def selected_option(self):
742 # TODO: Is there a way to check if the variant field has a selected_option,
743 # so we can raise an exception instead of hitting a pre-condition check?
744 # If there is something, that check should be added to selected_option_index too.
745 field_ptr = self._borrow_selected_option_field_ptr(self._ptr)
746
747 return self._create_field_from_ptr(
748 field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
749 )
750
751 def _spec_eq(self, other):
752 return _get_leaf_field(self) == other
753
754 def __bool__(self):
755 raise NotImplementedError
756
757 def __str__(self):
758 return str(self.selected_option)
759
760 def _repr(self):
761 return repr(self.selected_option)
762
763
764 class _VariantField(_VariantFieldConst, _ContainerField, _Field):
765 _NAME = "Variant"
766 _borrow_selected_option_field_ptr = staticmethod(
767 native_bt.field_variant_borrow_selected_option_field
768 )
769
770 def _selected_option_index(self, index):
771 if index < 0 or index >= len(self):
772 raise IndexError("{} field object index is out of range".format(self._NAME))
773
774 native_bt.field_variant_select_option_by_index(self._ptr, index)
775
776 selected_option_index = property(
777 fget=_VariantFieldConst.selected_option_index.fget, fset=_selected_option_index
778 )
779
780 def _set_value(self, value):
781 self.selected_option.value = value
782
783 value = property(fset=_set_value)
784
785
786 class _ArrayFieldConst(_ContainerFieldConst, _FieldConst, collections.abc.Sequence):
787 _borrow_element_field_ptr_by_index = staticmethod(
788 native_bt.field_array_borrow_element_field_by_index_const
789 )
790
791 def _get_length(self):
792 return native_bt.field_array_get_length(self._ptr)
793
794 length = property(fget=_get_length)
795
796 def __getitem__(self, index):
797 if not isinstance(index, numbers.Integral):
798 raise TypeError(
799 "'{}' is not an integral number object: invalid index".format(
800 index.__class__.__name__
801 )
802 )
803
804 index = int(index)
805
806 if index < 0 or index >= len(self):
807 raise IndexError("{} field object index is out of range".format(self._NAME))
808
809 field_ptr = self._borrow_element_field_ptr_by_index(self._ptr, index)
810 assert field_ptr
811 return self._create_field_from_ptr(
812 field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
813 )
814
815 def insert(self, index, value):
816 raise NotImplementedError
817
818 def _spec_eq(self, other):
819 if not isinstance(other, collections.abc.Sequence):
820 return False
821
822 if len(self) != len(other):
823 # early mismatch
824 return False
825
826 for self_elem, other_elem in zip(self, other):
827 if self_elem != other_elem:
828 return False
829
830 return True
831
832 def _repr(self):
833 return "[{}]".format(", ".join([repr(v) for v in self]))
834
835
836 class _ArrayField(
837 _ArrayFieldConst, _ContainerField, _Field, collections.abc.MutableSequence
838 ):
839 _borrow_element_field_ptr_by_index = staticmethod(
840 native_bt.field_array_borrow_element_field_by_index
841 )
842
843 def __setitem__(self, index, value):
844 # raises if index is somehow invalid
845 field = self[index]
846
847 if not isinstance(field, (_NumericField, _StringField)):
848 raise TypeError("can only set the value of a number or string field")
849
850 # the field's property does the appropriate conversion or raises
851 # the appropriate exception
852 field.value = value
853
854
855 class _StaticArrayFieldConst(_ArrayFieldConst, _FieldConst):
856 _NAME = "Const static array"
857
858 def _count(self):
859 return native_bt.field_array_get_length(self._ptr)
860
861
862 class _StaticArrayField(_StaticArrayFieldConst, _ArrayField, _Field):
863 _NAME = "Static array"
864
865 def _set_value(self, values):
866 if len(self) != len(values):
867 raise ValueError(
868 "expected length of value ({}) and array field ({}) to match".format(
869 len(values), len(self)
870 )
871 )
872
873 for index, value in enumerate(values):
874 if value is not None:
875 self[index].value = value
876
877 value = property(fset=_set_value)
878
879
880 class _DynamicArrayFieldConst(_ArrayFieldConst, _FieldConst):
881 _NAME = "Const dynamic array"
882
883 def _count(self):
884 return self.length
885
886
887 class _DynamicArrayField(_DynamicArrayFieldConst, _ArrayField, _Field):
888 _NAME = "Dynamic array"
889
890 def _set_length(self, length):
891 bt2_utils._check_uint64(length)
892 status = native_bt.field_array_dynamic_set_length(self._ptr, length)
893 bt2_utils._handle_func_status(status, "cannot set dynamic array length")
894
895 length = property(fget=_ArrayField._get_length, fset=_set_length)
896
897 def _set_value(self, values):
898 if len(values) != self.length:
899 self.length = len(values)
900
901 for index, value in enumerate(values):
902 if value is not None:
903 self[index].value = value
904
905 value = property(fset=_set_value)
906
907
908 _TYPE_ID_TO_CONST_OBJ = {
909 native_bt.FIELD_CLASS_TYPE_BOOL: _BoolFieldConst,
910 native_bt.FIELD_CLASS_TYPE_BIT_ARRAY: _BitArrayFieldConst,
911 native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerFieldConst,
912 native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerFieldConst,
913 native_bt.FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL: _SinglePrecisionRealFieldConst,
914 native_bt.FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL: _DoublePrecisionRealFieldConst,
915 native_bt.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: _UnsignedEnumerationFieldConst,
916 native_bt.FIELD_CLASS_TYPE_SIGNED_ENUMERATION: _SignedEnumerationFieldConst,
917 native_bt.FIELD_CLASS_TYPE_STRING: _StringFieldConst,
918 native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldConst,
919 native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldConst,
920 native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: _DynamicArrayFieldConst,
921 native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: _DynamicArrayFieldConst,
922 native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: _OptionFieldConst,
923 native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: _OptionFieldConst,
924 native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _OptionFieldConst,
925 native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _OptionFieldConst,
926 native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: _VariantFieldConst,
927 native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _VariantFieldConst,
928 native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _VariantFieldConst,
929 }
930
931 _TYPE_ID_TO_OBJ = {
932 native_bt.FIELD_CLASS_TYPE_BOOL: _BoolField,
933 native_bt.FIELD_CLASS_TYPE_BIT_ARRAY: _BitArrayField,
934 native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerField,
935 native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerField,
936 native_bt.FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL: _SinglePrecisionRealField,
937 native_bt.FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL: _DoublePrecisionRealField,
938 native_bt.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: _UnsignedEnumerationField,
939 native_bt.FIELD_CLASS_TYPE_SIGNED_ENUMERATION: _SignedEnumerationField,
940 native_bt.FIELD_CLASS_TYPE_STRING: _StringField,
941 native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureField,
942 native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayField,
943 native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD: _DynamicArrayField,
944 native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD: _DynamicArrayField,
945 native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD: _OptionField,
946 native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD: _OptionField,
947 native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _OptionField,
948 native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _OptionField,
949 native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD: _VariantField,
950 native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD: _VariantField,
951 native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD: _VariantField,
952 }
This page took 0.047555 seconds and 3 git commands to generate.