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