Commit | Line | Data |
---|---|---|
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 | ||
23 | from bt2 import native_bt, object, utils | |
24 | import collections.abc | |
3fb99a22 PP |
25 | from bt2 import field_path as bt2_field_path |
26 | from bt2 import integer_range_set as bt2_integer_range_set | |
5783664e | 27 | from bt2 import value as bt2_value |
81447b5b PP |
28 | import bt2 |
29 | ||
30 | ||
3cdfbaea SM |
31 | def _create_field_class_from_ptr_and_get_ref(ptr): |
32 | typeid = native_bt.field_class_get_type(ptr) | |
33 | return _FIELD_CLASS_TYPE_TO_OBJ[typeid]._create_from_ptr_and_get_ref(ptr) | |
81447b5b PP |
34 | |
35 | ||
d47b87ac SM |
36 | class IntegerDisplayBase: |
37 | BINARY = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY | |
38 | OCTAL = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL | |
39 | DECIMAL = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL | |
40 | HEXADECIMAL = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL | |
81447b5b | 41 | |
81447b5b | 42 | |
d47b87ac SM |
43 | class _FieldClass(object._SharedObject): |
44 | _get_ref = staticmethod(native_bt.field_class_get_ref) | |
45 | _put_ref = staticmethod(native_bt.field_class_put_ref) | |
81447b5b PP |
46 | |
47 | def _check_create_status(self, ptr): | |
48 | if ptr is None: | |
694c792b | 49 | raise bt2._MemoryError( |
cfbd7cf3 FD |
50 | 'cannot create {} field class object'.format(self._NAME.lower()) |
51 | ) | |
81447b5b | 52 | |
5783664e PP |
53 | @property |
54 | def user_attributes(self): | |
55 | ptr = native_bt.field_class_borrow_user_attributes(self._ptr) | |
56 | assert ptr is not None | |
57 | return bt2_value._create_from_ptr_and_get_ref(ptr) | |
58 | ||
59 | def _user_attributes(self, user_attributes): | |
60 | value = bt2_value.create_value(user_attributes) | |
61 | utils._check_type(value, bt2_value.MapValue) | |
62 | native_bt.field_class_set_user_attributes(self._ptr, value._ptr) | |
63 | ||
64 | _user_attributes = property(fset=_user_attributes) | |
65 | ||
81447b5b | 66 | |
aae30e61 PP |
67 | class _BoolFieldClass(_FieldClass): |
68 | _NAME = 'Boolean' | |
69 | ||
70 | ||
ead8c3d4 PP |
71 | class _BitArrayFieldClass(_FieldClass): |
72 | _NAME = 'Bit array' | |
73 | ||
74 | @property | |
75 | def length(self): | |
76 | length = native_bt.field_class_bit_array_get_length(self._ptr) | |
77 | assert length >= 1 | |
78 | return length | |
79 | ||
80 | ||
af4bbfc7 | 81 | class _IntegerFieldClass(_FieldClass): |
81447b5b | 82 | @property |
d47b87ac SM |
83 | def field_value_range(self): |
84 | size = native_bt.field_class_integer_get_field_value_range(self._ptr) | |
cfbd7cf3 | 85 | assert size >= 1 |
81447b5b PP |
86 | return size |
87 | ||
d47b87ac SM |
88 | def _field_value_range(self, size): |
89 | if size < 1 or size > 64: | |
90 | raise ValueError("Value is outside valid range [1, 64] ({})".format(size)) | |
91 | native_bt.field_class_integer_set_field_value_range(self._ptr, size) | |
81447b5b | 92 | |
d47b87ac | 93 | _field_value_range = property(fset=_field_value_range) |
81447b5b PP |
94 | |
95 | @property | |
d47b87ac | 96 | def preferred_display_base(self): |
cfbd7cf3 FD |
97 | base = native_bt.field_class_integer_get_preferred_display_base(self._ptr) |
98 | assert base >= 0 | |
81447b5b PP |
99 | return base |
100 | ||
d47b87ac SM |
101 | def _preferred_display_base(self, base): |
102 | utils._check_uint64(base) | |
81447b5b | 103 | |
cfbd7cf3 FD |
104 | if base not in ( |
105 | IntegerDisplayBase.BINARY, | |
106 | IntegerDisplayBase.OCTAL, | |
107 | IntegerDisplayBase.DECIMAL, | |
108 | IntegerDisplayBase.HEXADECIMAL, | |
109 | ): | |
d47b87ac | 110 | raise ValueError("Display base is not a valid IntegerDisplayBase value") |
81447b5b | 111 | |
cfbd7cf3 | 112 | native_bt.field_class_integer_set_preferred_display_base(self._ptr, base) |
81447b5b | 113 | |
d47b87ac | 114 | _preferred_display_base = property(fset=_preferred_display_base) |
81447b5b PP |
115 | |
116 | ||
2ae9f48c | 117 | class _UnsignedIntegerFieldClass(_IntegerFieldClass): |
d47b87ac | 118 | _NAME = 'Unsigned integer' |
2ae9f48c SM |
119 | |
120 | ||
af4bbfc7 | 121 | class _SignedIntegerFieldClass(_IntegerFieldClass): |
d47b87ac | 122 | _NAME = 'Signed integer' |
2ae9f48c | 123 | |
af4bbfc7 | 124 | |
d47b87ac | 125 | class _RealFieldClass(_FieldClass): |
2ae9f48c | 126 | _NAME = 'Real' |
81447b5b | 127 | |
81447b5b | 128 | @property |
d47b87ac SM |
129 | def is_single_precision(self): |
130 | return native_bt.field_class_real_is_single_precision(self._ptr) | |
81447b5b | 131 | |
d47b87ac SM |
132 | def _is_single_precision(self, is_single_precision): |
133 | utils._check_bool(is_single_precision) | |
134 | native_bt.field_class_real_set_is_single_precision( | |
cfbd7cf3 FD |
135 | self._ptr, is_single_precision |
136 | ) | |
81447b5b | 137 | |
d47b87ac | 138 | _is_single_precision = property(fset=_is_single_precision) |
81447b5b PP |
139 | |
140 | ||
45c51519 PP |
141 | # an enumeration field class mapping does not have a reference count, so |
142 | # we copy the properties here to avoid eventual memory access errors. | |
143 | class _EnumerationFieldClassMapping: | |
d47b87ac | 144 | def __init__(self, mapping_ptr): |
45c51519 | 145 | base_mapping_ptr = self._as_enumeration_field_class_mapping_ptr(mapping_ptr) |
cfbd7cf3 FD |
146 | self._label = native_bt.field_class_enumeration_mapping_get_label( |
147 | base_mapping_ptr | |
148 | ) | |
45c51519 PP |
149 | assert self._label is not None |
150 | ranges_ptr = self._mapping_borrow_ranges_ptr(mapping_ptr) | |
151 | assert ranges_ptr is not None | |
152 | self._ranges = self._ranges_type._create_from_ptr_and_get_ref(ranges_ptr) | |
81447b5b PP |
153 | |
154 | @property | |
d47b87ac | 155 | def label(self): |
45c51519 | 156 | return self._label |
81447b5b | 157 | |
45c51519 PP |
158 | @property |
159 | def ranges(self): | |
160 | return self._ranges | |
81447b5b | 161 | |
81447b5b | 162 | |
d47b87ac | 163 | class _UnsignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping): |
3fb99a22 | 164 | _ranges_type = bt2_integer_range_set.UnsignedIntegerRangeSet |
cfbd7cf3 | 165 | _as_enumeration_field_class_mapping_ptr = staticmethod( |
9c08c816 | 166 | native_bt.field_class_enumeration_unsigned_mapping_as_mapping_const |
cfbd7cf3 FD |
167 | ) |
168 | _mapping_borrow_ranges_ptr = staticmethod( | |
9c08c816 | 169 | native_bt.field_class_enumeration_unsigned_mapping_borrow_ranges_const |
cfbd7cf3 | 170 | ) |
81447b5b | 171 | |
81447b5b | 172 | |
d47b87ac | 173 | class _SignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping): |
3fb99a22 | 174 | _ranges_type = bt2_integer_range_set.SignedIntegerRangeSet |
cfbd7cf3 | 175 | _as_enumeration_field_class_mapping_ptr = staticmethod( |
9c08c816 | 176 | native_bt.field_class_enumeration_signed_mapping_as_mapping_const |
cfbd7cf3 FD |
177 | ) |
178 | _mapping_borrow_ranges_ptr = staticmethod( | |
9c08c816 | 179 | native_bt.field_class_enumeration_signed_mapping_borrow_ranges_const |
cfbd7cf3 | 180 | ) |
81447b5b | 181 | |
81447b5b | 182 | |
d47b87ac | 183 | class _EnumerationFieldClass(_IntegerFieldClass, collections.abc.Mapping): |
81447b5b | 184 | def __len__(self): |
b4f45851 | 185 | count = native_bt.field_class_enumeration_get_mapping_count(self._ptr) |
45c51519 | 186 | assert count >= 0 |
81447b5b PP |
187 | return count |
188 | ||
45c51519 | 189 | def add_mapping(self, label, ranges): |
d47b87ac | 190 | utils._check_str(label) |
45c51519 | 191 | utils._check_type(ranges, self._range_set_type) |
81447b5b | 192 | |
45c51519 | 193 | if label in self: |
ce4923b0 | 194 | raise ValueError("duplicate mapping label '{}'".format(label)) |
81447b5b | 195 | |
45c51519 | 196 | status = self._add_mapping(self._ptr, label, ranges._ptr) |
cfbd7cf3 FD |
197 | utils._handle_func_status( |
198 | status, 'cannot add mapping to enumeration field class object' | |
199 | ) | |
81447b5b | 200 | |
45c51519 | 201 | def mappings_for_value(self, value): |
185ecf64 | 202 | status, labels = self._get_mapping_labels_for_value(self._ptr, value) |
cfbd7cf3 FD |
203 | utils._handle_func_status( |
204 | status, 'cannot get mapping labels for value {}'.format(value) | |
205 | ) | |
45c51519 | 206 | return [self[label] for label in labels] |
81447b5b | 207 | |
d47b87ac SM |
208 | def __iter__(self): |
209 | for idx in range(len(self)): | |
210 | mapping = self._get_mapping_by_index(self._ptr, idx) | |
211 | yield mapping.label | |
81447b5b | 212 | |
45c51519 PP |
213 | def __getitem__(self, label): |
214 | utils._check_str(label) | |
215 | mapping = self._get_mapping_by_label(self._ptr, label) | |
81447b5b | 216 | |
45c51519 PP |
217 | if mapping is None: |
218 | raise KeyError(label) | |
219 | ||
220 | return mapping | |
81447b5b | 221 | |
d47b87ac | 222 | def __iadd__(self, mappings): |
45c51519 PP |
223 | for label, ranges in mappings: |
224 | self.add_mapping(label, ranges) | |
81447b5b | 225 | |
d47b87ac | 226 | return self |
81447b5b | 227 | |
81447b5b | 228 | |
cfbd7cf3 FD |
229 | class _UnsignedEnumerationFieldClass( |
230 | _EnumerationFieldClass, _UnsignedIntegerFieldClass | |
231 | ): | |
d47b87ac | 232 | _NAME = 'Unsigned enumeration' |
3fb99a22 | 233 | _range_set_type = bt2_integer_range_set.UnsignedIntegerRangeSet |
9c08c816 | 234 | _add_mapping = staticmethod(native_bt.field_class_enumeration_unsigned_add_mapping) |
81447b5b | 235 | |
d47b87ac SM |
236 | @staticmethod |
237 | def _get_mapping_by_index(enum_ptr, index): | |
9c08c816 | 238 | mapping_ptr = native_bt.field_class_enumeration_unsigned_borrow_mapping_by_index_const( |
cfbd7cf3 FD |
239 | enum_ptr, index |
240 | ) | |
d47b87ac SM |
241 | assert mapping_ptr is not None |
242 | return _UnsignedEnumerationFieldClassMapping(mapping_ptr) | |
81447b5b | 243 | |
d47b87ac | 244 | @staticmethod |
45c51519 | 245 | def _get_mapping_by_label(enum_ptr, label): |
9c08c816 | 246 | mapping_ptr = native_bt.field_class_enumeration_unsigned_borrow_mapping_by_label_const( |
cfbd7cf3 FD |
247 | enum_ptr, label |
248 | ) | |
45c51519 PP |
249 | |
250 | if mapping_ptr is None: | |
251 | return | |
252 | ||
253 | return _UnsignedEnumerationFieldClassMapping(mapping_ptr) | |
81447b5b | 254 | |
d47b87ac | 255 | @staticmethod |
185ecf64 | 256 | def _get_mapping_labels_for_value(enum_ptr, value): |
d47b87ac | 257 | utils._check_uint64(value) |
9c08c816 | 258 | return native_bt.field_class_enumeration_unsigned_get_mapping_labels_for_value( |
cfbd7cf3 FD |
259 | enum_ptr, value |
260 | ) | |
81447b5b PP |
261 | |
262 | ||
d47b87ac SM |
263 | class _SignedEnumerationFieldClass(_EnumerationFieldClass, _SignedIntegerFieldClass): |
264 | _NAME = 'Signed enumeration' | |
3fb99a22 | 265 | _range_set_type = bt2_integer_range_set.SignedIntegerRangeSet |
9c08c816 | 266 | _add_mapping = staticmethod(native_bt.field_class_enumeration_signed_add_mapping) |
81447b5b | 267 | |
d47b87ac SM |
268 | @staticmethod |
269 | def _get_mapping_by_index(enum_ptr, index): | |
9c08c816 | 270 | mapping_ptr = native_bt.field_class_enumeration_signed_borrow_mapping_by_index_const( |
cfbd7cf3 FD |
271 | enum_ptr, index |
272 | ) | |
d47b87ac SM |
273 | assert mapping_ptr is not None |
274 | return _SignedEnumerationFieldClassMapping(mapping_ptr) | |
81447b5b | 275 | |
d47b87ac | 276 | @staticmethod |
45c51519 | 277 | def _get_mapping_by_label(enum_ptr, label): |
9c08c816 | 278 | mapping_ptr = native_bt.field_class_enumeration_signed_borrow_mapping_by_label_const( |
cfbd7cf3 FD |
279 | enum_ptr, label |
280 | ) | |
45c51519 PP |
281 | |
282 | if mapping_ptr is None: | |
283 | return | |
284 | ||
285 | return _SignedEnumerationFieldClassMapping(mapping_ptr) | |
81447b5b | 286 | |
d47b87ac | 287 | @staticmethod |
185ecf64 | 288 | def _get_mapping_labels_for_value(enum_ptr, value): |
d47b87ac | 289 | utils._check_int64(value) |
9c08c816 | 290 | return native_bt.field_class_enumeration_signed_get_mapping_labels_for_value( |
cfbd7cf3 FD |
291 | enum_ptr, value |
292 | ) | |
81447b5b | 293 | |
d47b87ac SM |
294 | |
295 | class _StringFieldClass(_FieldClass): | |
296 | _NAME = 'String' | |
81447b5b PP |
297 | |
298 | ||
45c51519 | 299 | class _StructureFieldClassMember: |
5783664e PP |
300 | def __init__(self, owning_struct_fc, member_ptr): |
301 | # this field class owns the member; keeping it here maintains | |
302 | # the member alive as members are not shared objects | |
303 | self._owning_struct_fc = owning_struct_fc | |
304 | self._ptr = member_ptr | |
45c51519 PP |
305 | |
306 | @property | |
307 | def name(self): | |
5783664e PP |
308 | name = native_bt.field_class_structure_member_get_name(self._ptr) |
309 | assert name is not None | |
310 | return name | |
45c51519 PP |
311 | |
312 | @property | |
313 | def field_class(self): | |
5783664e PP |
314 | fc_ptr = native_bt.field_class_structure_member_borrow_field_class_const( |
315 | self._ptr | |
316 | ) | |
317 | assert fc_ptr is not None | |
318 | return _create_field_class_from_ptr_and_get_ref(fc_ptr) | |
319 | ||
320 | @property | |
321 | def user_attributes(self): | |
322 | ptr = native_bt.field_class_structure_member_borrow_user_attributes(self._ptr) | |
323 | assert ptr is not None | |
324 | return bt2_value._create_from_ptr_and_get_ref(ptr) | |
325 | ||
326 | def _user_attributes(self, user_attributes): | |
327 | value = bt2_value.create_value(user_attributes) | |
328 | utils._check_type(value, bt2_value.MapValue) | |
329 | native_bt.field_class_structure_member_set_user_attributes( | |
330 | self._ptr, value._ptr | |
331 | ) | |
332 | ||
333 | _user_attributes = property(fset=_user_attributes) | |
45c51519 PP |
334 | |
335 | ||
336 | class _StructureFieldClass(_FieldClass, collections.abc.Mapping): | |
337 | _NAME = 'Structure' | |
338 | ||
5783664e | 339 | def append_member(self, name, field_class, user_attributes=None): |
45c51519 PP |
340 | utils._check_str(name) |
341 | utils._check_type(field_class, _FieldClass) | |
342 | ||
343 | if name in self: | |
ce4923b0 | 344 | raise ValueError("duplicate member name '{}'".format(name)) |
45c51519 | 345 | |
5783664e PP |
346 | user_attributes_value = None |
347 | ||
348 | if user_attributes is not None: | |
349 | # check now that user attributes are valid | |
350 | user_attributes_value = bt2.create_value(user_attributes) | |
351 | ||
cfbd7cf3 FD |
352 | status = native_bt.field_class_structure_append_member( |
353 | self._ptr, name, field_class._ptr | |
354 | ) | |
355 | utils._handle_func_status( | |
356 | status, 'cannot append member to structure field class object' | |
357 | ) | |
45c51519 | 358 | |
5783664e PP |
359 | if user_attributes is not None: |
360 | self[name]._user_attributes = user_attributes_value | |
361 | ||
81447b5b | 362 | def __len__(self): |
45c51519 | 363 | count = native_bt.field_class_structure_get_member_count(self._ptr) |
d47b87ac | 364 | assert count >= 0 |
81447b5b PP |
365 | return count |
366 | ||
5783664e PP |
367 | def _create_member_from_ptr(self, member_ptr): |
368 | return _StructureFieldClassMember(self, member_ptr) | |
45c51519 | 369 | |
81447b5b PP |
370 | def __getitem__(self, key): |
371 | if not isinstance(key, str): | |
cfbd7cf3 FD |
372 | raise TypeError( |
373 | "key must be a 'str' object, got '{}'".format(key.__class__.__name__) | |
374 | ) | |
81447b5b | 375 | |
cfbd7cf3 FD |
376 | member_ptr = native_bt.field_class_structure_borrow_member_by_name_const( |
377 | self._ptr, key | |
378 | ) | |
81447b5b | 379 | |
45c51519 | 380 | if member_ptr is None: |
81447b5b PP |
381 | raise KeyError(key) |
382 | ||
45c51519 | 383 | return self._create_member_from_ptr(member_ptr) |
81447b5b PP |
384 | |
385 | def __iter__(self): | |
d47b87ac | 386 | for idx in range(len(self)): |
cfbd7cf3 FD |
387 | member_ptr = native_bt.field_class_structure_borrow_member_by_index_const( |
388 | self._ptr, idx | |
389 | ) | |
45c51519 PP |
390 | assert member_ptr is not None |
391 | yield native_bt.field_class_structure_member_get_name(member_ptr) | |
81447b5b | 392 | |
45c51519 PP |
393 | def __iadd__(self, members): |
394 | for name, field_class in members: | |
395 | self.append_member(name, field_class) | |
81447b5b PP |
396 | |
397 | return self | |
398 | ||
45c51519 | 399 | def member_at_index(self, index): |
81447b5b | 400 | utils._check_uint64(index) |
81447b5b | 401 | |
45c51519 | 402 | if index >= len(self): |
811644b8 PP |
403 | raise IndexError |
404 | ||
cfbd7cf3 FD |
405 | member_ptr = native_bt.field_class_structure_borrow_member_by_index_const( |
406 | self._ptr, index | |
407 | ) | |
45c51519 PP |
408 | assert member_ptr is not None |
409 | return self._create_member_from_ptr(member_ptr) | |
410 | ||
81447b5b | 411 | |
cec0261d PP |
412 | class _OptionFieldClass(_FieldClass): |
413 | @property | |
414 | def field_class(self): | |
415 | elem_fc_ptr = native_bt.field_class_option_borrow_field_class_const(self._ptr) | |
416 | return _create_field_class_from_ptr_and_get_ref(elem_fc_ptr) | |
417 | ||
418 | @property | |
419 | def selector_field_path(self): | |
420 | ptr = native_bt.field_class_option_borrow_selector_field_path_const(self._ptr) | |
421 | if ptr is None: | |
422 | return | |
423 | ||
424 | return bt2_field_path._FieldPath._create_from_ptr_and_get_ref(ptr) | |
425 | ||
426 | ||
45c51519 | 427 | class _VariantFieldClassOption: |
5783664e PP |
428 | def __init__(self, owning_var_fc, option_ptr): |
429 | # this field class owns the option; keeping it here maintains | |
430 | # the option alive as options are not shared objects | |
431 | self._owning_var_fc = owning_var_fc | |
432 | self._ptr = option_ptr | |
81447b5b | 433 | |
45c51519 PP |
434 | @property |
435 | def name(self): | |
5783664e PP |
436 | name = native_bt.field_class_variant_option_get_name(self._ptr) |
437 | assert name is not None | |
438 | return name | |
81447b5b | 439 | |
45c51519 PP |
440 | @property |
441 | def field_class(self): | |
5783664e PP |
442 | fc_ptr = native_bt.field_class_variant_option_borrow_field_class_const( |
443 | self._ptr | |
444 | ) | |
445 | assert fc_ptr is not None | |
446 | return _create_field_class_from_ptr_and_get_ref(fc_ptr) | |
81447b5b | 447 | |
5783664e PP |
448 | @property |
449 | def user_attributes(self): | |
450 | ptr = native_bt.field_class_variant_option_borrow_user_attributes(self._ptr) | |
451 | assert ptr is not None | |
452 | return bt2_value._create_from_ptr_and_get_ref(ptr) | |
81447b5b | 453 | |
5783664e PP |
454 | def _user_attributes(self, user_attributes): |
455 | value = bt2_value.create_value(user_attributes) | |
456 | utils._check_type(value, bt2_value.MapValue) | |
457 | native_bt.field_class_variant_option_set_user_attributes(self._ptr, value._ptr) | |
81447b5b | 458 | |
5783664e | 459 | _user_attributes = property(fset=_user_attributes) |
81447b5b PP |
460 | |
461 | ||
45c51519 | 462 | class _VariantFieldClass(_FieldClass, collections.abc.Mapping): |
81447b5b | 463 | _NAME = 'Variant' |
cfbd7cf3 FD |
464 | _borrow_option_by_name_ptr = staticmethod( |
465 | native_bt.field_class_variant_borrow_option_by_name_const | |
466 | ) | |
467 | _borrow_member_by_index_ptr = staticmethod( | |
468 | native_bt.field_class_variant_borrow_option_by_index_const | |
469 | ) | |
811644b8 | 470 | |
45c51519 PP |
471 | @staticmethod |
472 | def _as_option_ptr(opt_ptr): | |
473 | return opt_ptr | |
474 | ||
475 | def _create_option_from_ptr(self, opt_ptr): | |
5783664e | 476 | return _VariantFieldClassOption(self, opt_ptr) |
45c51519 PP |
477 | |
478 | def __len__(self): | |
479 | count = native_bt.field_class_variant_get_option_count(self._ptr) | |
480 | assert count >= 0 | |
481 | return count | |
482 | ||
483 | def __getitem__(self, key): | |
484 | if not isinstance(key, str): | |
cfbd7cf3 FD |
485 | raise TypeError( |
486 | "key must be a 'str' object, got '{}'".format(key.__class__.__name__) | |
487 | ) | |
45c51519 PP |
488 | |
489 | opt_ptr = self._borrow_option_by_name_ptr(self._ptr, key) | |
490 | ||
491 | if opt_ptr is None: | |
492 | raise KeyError(key) | |
493 | ||
494 | return self._create_option_from_ptr(opt_ptr) | |
495 | ||
496 | def __iter__(self): | |
497 | for idx in range(len(self)): | |
498 | opt_ptr = self._borrow_member_by_index_ptr(self._ptr, idx) | |
499 | assert opt_ptr is not None | |
500 | base_opt_ptr = self._as_option_ptr(opt_ptr) | |
501 | yield native_bt.field_class_variant_option_get_name(base_opt_ptr) | |
811644b8 | 502 | |
d47b87ac | 503 | def option_at_index(self, index): |
45c51519 PP |
504 | utils._check_uint64(index) |
505 | ||
506 | if index >= len(self): | |
507 | raise IndexError | |
508 | ||
509 | opt_ptr = self._borrow_member_by_index_ptr(self._ptr, index) | |
510 | assert opt_ptr is not None | |
511 | return self._create_option_from_ptr(opt_ptr) | |
512 | ||
513 | ||
514 | class _VariantFieldClassWithoutSelector(_VariantFieldClass): | |
515 | _NAME = 'Variant (without selector)' | |
516 | ||
5783664e | 517 | def append_option(self, name, field_class, user_attributes=None): |
45c51519 PP |
518 | utils._check_str(name) |
519 | utils._check_type(field_class, _FieldClass) | |
520 | ||
521 | if name in self: | |
ce4923b0 | 522 | raise ValueError("duplicate option name '{}'".format(name)) |
45c51519 | 523 | |
5783664e PP |
524 | user_attributes_value = None |
525 | ||
526 | if user_attributes is not None: | |
527 | # check now that user attributes are valid | |
528 | user_attributes_value = bt2.create_value(user_attributes) | |
529 | ||
cfbd7cf3 FD |
530 | status = native_bt.field_class_variant_without_selector_append_option( |
531 | self._ptr, name, field_class._ptr | |
532 | ) | |
533 | utils._handle_func_status( | |
534 | status, 'cannot append option to variant field class object' | |
535 | ) | |
45c51519 | 536 | |
5783664e PP |
537 | if user_attributes is not None: |
538 | self[name]._user_attributes = user_attributes_value | |
539 | ||
45c51519 PP |
540 | def __iadd__(self, options): |
541 | for name, field_class in options: | |
542 | self.append_option(name, field_class) | |
543 | ||
544 | return self | |
545 | ||
546 | ||
5783664e PP |
547 | class _VariantFieldClassWithSelectorOption(_VariantFieldClassOption): |
548 | def __init__(self, owning_var_fc, spec_opt_ptr): | |
549 | self._spec_ptr = spec_opt_ptr | |
550 | super().__init__(owning_var_fc, self._as_option_ptr(spec_opt_ptr)) | |
551 | ||
552 | @property | |
553 | def ranges(self): | |
554 | range_set_ptr = self._borrow_ranges_ptr(self._spec_ptr) | |
555 | assert range_set_ptr is not None | |
556 | return self._range_set_type._create_from_ptr_and_get_ref(range_set_ptr) | |
557 | ||
558 | ||
559 | class _VariantFieldClassWithSignedSelectorOption(_VariantFieldClassWithSelectorOption): | |
560 | _as_option_ptr = staticmethod( | |
561 | native_bt.field_class_variant_with_selector_signed_option_as_option_const | |
562 | ) | |
563 | _borrow_ranges_ptr = staticmethod( | |
564 | native_bt.field_class_variant_with_selector_signed_option_borrow_ranges_const | |
565 | ) | |
566 | _range_set_type = bt2_integer_range_set.SignedIntegerRangeSet | |
567 | ||
568 | ||
569 | class _VariantFieldClassWithUnsignedSelectorOption( | |
570 | _VariantFieldClassWithSelectorOption | |
571 | ): | |
572 | _as_option_ptr = staticmethod( | |
573 | native_bt.field_class_variant_with_selector_unsigned_option_as_option_const | |
574 | ) | |
575 | _borrow_ranges_ptr = staticmethod( | |
576 | native_bt.field_class_variant_with_selector_unsigned_option_borrow_ranges_const | |
577 | ) | |
578 | _range_set_type = bt2_integer_range_set.UnsignedIntegerRangeSet | |
579 | ||
580 | ||
45c51519 PP |
581 | class _VariantFieldClassWithSelector(_VariantFieldClass): |
582 | _NAME = 'Variant (with selector)' | |
583 | ||
584 | def _create_option_from_ptr(self, opt_ptr): | |
5783664e | 585 | return self._option_type(self, opt_ptr) |
81447b5b PP |
586 | |
587 | @property | |
d47b87ac | 588 | def selector_field_path(self): |
cfbd7cf3 FD |
589 | ptr = native_bt.field_class_variant_with_selector_borrow_selector_field_path_const( |
590 | self._ptr | |
591 | ) | |
45c51519 | 592 | |
d47b87ac | 593 | if ptr is None: |
811644b8 PP |
594 | return |
595 | ||
3fb99a22 | 596 | return bt2_field_path._FieldPath._create_from_ptr_and_get_ref(ptr) |
81447b5b | 597 | |
5783664e | 598 | def append_option(self, name, field_class, ranges, user_attributes=None): |
45c51519 PP |
599 | utils._check_str(name) |
600 | utils._check_type(field_class, _FieldClass) | |
5783664e | 601 | utils._check_type(ranges, self._option_type._range_set_type) |
45c51519 PP |
602 | |
603 | if name in self: | |
ce4923b0 | 604 | raise ValueError("duplicate option name '{}'".format(name)) |
45c51519 PP |
605 | |
606 | if len(ranges) == 0: | |
607 | raise ValueError('range set is empty') | |
608 | ||
5783664e PP |
609 | user_attributes_value = None |
610 | ||
611 | if user_attributes is not None: | |
612 | # check now that user attributes are valid | |
613 | user_attributes_value = bt2.create_value(user_attributes) | |
614 | ||
45c51519 PP |
615 | # TODO: check overlaps (precondition of self._append_option()) |
616 | ||
617 | status = self._append_option(self._ptr, name, field_class._ptr, ranges._ptr) | |
cfbd7cf3 FD |
618 | utils._handle_func_status( |
619 | status, 'cannot append option to variant field class object' | |
620 | ) | |
45c51519 | 621 | |
5783664e PP |
622 | if user_attributes is not None: |
623 | self[name]._user_attributes = user_attributes_value | |
624 | ||
45c51519 PP |
625 | def __iadd__(self, options): |
626 | for name, field_class, ranges in options: | |
627 | self.append_option(name, field_class, ranges) | |
628 | ||
629 | return self | |
630 | ||
631 | ||
632 | class _VariantFieldClassWithUnsignedSelector(_VariantFieldClassWithSelector): | |
633 | _NAME = 'Variant (with unsigned selector)' | |
cfbd7cf3 | 634 | _borrow_option_by_name_ptr = staticmethod( |
9c08c816 | 635 | native_bt.field_class_variant_with_selector_unsigned_borrow_option_by_name_const |
cfbd7cf3 FD |
636 | ) |
637 | _borrow_member_by_index_ptr = staticmethod( | |
9c08c816 | 638 | native_bt.field_class_variant_with_selector_unsigned_borrow_option_by_index_const |
cfbd7cf3 | 639 | ) |
cfbd7cf3 | 640 | _append_option = staticmethod( |
9c08c816 | 641 | native_bt.field_class_variant_with_selector_unsigned_append_option |
cfbd7cf3 | 642 | ) |
5783664e PP |
643 | _option_type = _VariantFieldClassWithUnsignedSelectorOption |
644 | _as_option_ptr = staticmethod(_option_type._as_option_ptr) | |
45c51519 | 645 | |
81447b5b | 646 | |
45c51519 PP |
647 | class _VariantFieldClassWithSignedSelector(_VariantFieldClassWithSelector): |
648 | _NAME = 'Variant (with signed selector)' | |
cfbd7cf3 | 649 | _borrow_option_by_name_ptr = staticmethod( |
9c08c816 | 650 | native_bt.field_class_variant_with_selector_signed_borrow_option_by_name_const |
cfbd7cf3 FD |
651 | ) |
652 | _borrow_member_by_index_ptr = staticmethod( | |
9c08c816 | 653 | native_bt.field_class_variant_with_selector_signed_borrow_option_by_index_const |
cfbd7cf3 | 654 | ) |
cfbd7cf3 | 655 | _append_option = staticmethod( |
9c08c816 | 656 | native_bt.field_class_variant_with_selector_signed_append_option |
cfbd7cf3 | 657 | ) |
5783664e PP |
658 | _option_type = _VariantFieldClassWithSignedSelectorOption |
659 | _as_option_ptr = staticmethod(_option_type._as_option_ptr) | |
811644b8 | 660 | |
81447b5b | 661 | |
d47b87ac SM |
662 | class _ArrayFieldClass(_FieldClass): |
663 | @property | |
664 | def element_field_class(self): | |
cfbd7cf3 FD |
665 | elem_fc_ptr = native_bt.field_class_array_borrow_element_field_class_const( |
666 | self._ptr | |
667 | ) | |
d47b87ac | 668 | return _create_field_class_from_ptr_and_get_ref(elem_fc_ptr) |
81447b5b | 669 | |
81447b5b | 670 | |
d47b87ac | 671 | class _StaticArrayFieldClass(_ArrayFieldClass): |
81447b5b PP |
672 | @property |
673 | def length(self): | |
9c08c816 | 674 | return native_bt.field_class_array_static_get_length(self._ptr) |
81447b5b PP |
675 | |
676 | ||
d47b87ac SM |
677 | class _DynamicArrayFieldClass(_ArrayFieldClass): |
678 | @property | |
679 | def length_field_path(self): | |
9c08c816 | 680 | ptr = native_bt.field_class_array_dynamic_borrow_length_field_path_const( |
cfbd7cf3 FD |
681 | self._ptr |
682 | ) | |
d47b87ac SM |
683 | if ptr is None: |
684 | return | |
81447b5b | 685 | |
3fb99a22 | 686 | return bt2_field_path._FieldPath._create_from_ptr_and_get_ref(ptr) |
81447b5b | 687 | |
81447b5b | 688 | |
3cdfbaea | 689 | _FIELD_CLASS_TYPE_TO_OBJ = { |
aae30e61 | 690 | native_bt.FIELD_CLASS_TYPE_BOOL: _BoolFieldClass, |
ead8c3d4 | 691 | native_bt.FIELD_CLASS_TYPE_BIT_ARRAY: _BitArrayFieldClass, |
d47b87ac SM |
692 | native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerFieldClass, |
693 | native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerFieldClass, | |
694 | native_bt.FIELD_CLASS_TYPE_REAL: _RealFieldClass, | |
695 | native_bt.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: _UnsignedEnumerationFieldClass, | |
696 | native_bt.FIELD_CLASS_TYPE_SIGNED_ENUMERATION: _SignedEnumerationFieldClass, | |
697 | native_bt.FIELD_CLASS_TYPE_STRING: _StringFieldClass, | |
3cdfbaea | 698 | native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldClass, |
d47b87ac SM |
699 | native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldClass, |
700 | native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayFieldClass, | |
cec0261d | 701 | native_bt.FIELD_CLASS_TYPE_OPTION: _OptionFieldClass, |
45c51519 PP |
702 | native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: _VariantFieldClassWithoutSelector, |
703 | native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: _VariantFieldClassWithUnsignedSelector, | |
704 | native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: _VariantFieldClassWithSignedSelector, | |
81447b5b | 705 | } |