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