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 | |
c4239792 | 25 | import bt2.field |
81447b5b PP |
26 | import abc |
27 | import bt2 | |
28 | ||
29 | ||
3cdfbaea SM |
30 | def _create_field_class_from_ptr_and_get_ref(ptr): |
31 | typeid = native_bt.field_class_get_type(ptr) | |
32 | return _FIELD_CLASS_TYPE_TO_OBJ[typeid]._create_from_ptr_and_get_ref(ptr) | |
81447b5b PP |
33 | |
34 | ||
78288f58 | 35 | class _FieldClass(object._SharedObject, metaclass=abc.ABCMeta): |
3cdfbaea SM |
36 | _get_ref = staticmethod(native_bt.field_class_get_ref) |
37 | _put_ref = staticmethod(native_bt.field_class_put_ref) | |
38 | ||
81447b5b PP |
39 | def __init__(self, ptr): |
40 | super().__init__(ptr) | |
41 | ||
42 | def __eq__(self, other): | |
43 | if not isinstance(other, self.__class__): | |
44 | # not comparing apples to apples | |
45 | return False | |
46 | ||
47 | if self.addr == other.addr: | |
48 | return True | |
49 | ||
b4f45851 SM |
50 | ret = native_bt.field_class_compare(self._ptr, other._ptr) |
51 | utils._handle_ret(ret, "cannot compare field classes") | |
81447b5b PP |
52 | return ret == 0 |
53 | ||
54 | def _check_create_status(self, ptr): | |
55 | if ptr is None: | |
b4f45851 | 56 | raise bt2.CreationError('cannot create {} field class object'.format(self._NAME.lower())) |
81447b5b PP |
57 | |
58 | def __copy__(self): | |
b4f45851 SM |
59 | ptr = native_bt.field_class_copy(self._ptr) |
60 | utils._handle_ptr(ptr, 'cannot copy {} field class object'.format(self._NAME.lower())) | |
81447b5b PP |
61 | return _create_from_ptr(ptr) |
62 | ||
63 | def __deepcopy__(self, memo): | |
64 | cpy = self.__copy__() | |
65 | memo[id(self)] = cpy | |
66 | return cpy | |
67 | ||
68 | def __call__(self, value=None): | |
50842bdc | 69 | field_ptr = native_bt.field_create(self._ptr) |
81447b5b PP |
70 | |
71 | if field_ptr is None: | |
72 | raise bt2.CreationError('cannot create {} field object'.format(self._NAME.lower())) | |
73 | ||
c4239792 | 74 | field = bt2.field._create_from_ptr(field_ptr) |
81447b5b PP |
75 | |
76 | if value is not None: | |
c4239792 | 77 | if not isinstance(field, (bt2.field._IntegerField, bt2.field._FloatingPointNumberField, bt2.field._StringField)): |
81447b5b PP |
78 | raise bt2.Error('cannot assign an initial value to a {} field object'.format(field._NAME)) |
79 | ||
80 | field.value = value | |
81 | ||
82 | return field | |
83 | ||
84 | ||
81447b5b PP |
85 | class _AlignmentProp: |
86 | @property | |
87 | def alignment(self): | |
b4f45851 | 88 | alignment = native_bt.field_class_get_alignment(self._ptr) |
811644b8 | 89 | assert(alignment >= 0) |
81447b5b PP |
90 | return alignment |
91 | ||
92 | @alignment.setter | |
93 | def alignment(self, alignment): | |
94 | utils._check_alignment(alignment) | |
b4f45851 SM |
95 | ret = native_bt.field_class_set_alignment(self._ptr, alignment) |
96 | utils._handle_ret(ret, "cannot set field class object's alignment") | |
81447b5b PP |
97 | |
98 | ||
99 | class _ByteOrderProp: | |
100 | @property | |
101 | def byte_order(self): | |
b4f45851 | 102 | bo = native_bt.field_class_get_byte_order(self._ptr) |
811644b8 | 103 | assert(bo >= 0) |
81447b5b PP |
104 | return bo |
105 | ||
106 | @byte_order.setter | |
107 | def byte_order(self, byte_order): | |
108 | utils._check_int(byte_order) | |
b4f45851 SM |
109 | ret = native_bt.field_class_set_byte_order(self._ptr, byte_order) |
110 | utils._handle_ret(ret, "cannot set field class object's byte order") | |
81447b5b PP |
111 | |
112 | ||
b4f45851 | 113 | class IntegerFieldClass(_FieldClass, _AlignmentProp, _ByteOrderProp): |
81447b5b PP |
114 | _NAME = 'Integer' |
115 | ||
116 | def __init__(self, size, alignment=None, byte_order=None, is_signed=None, | |
117 | base=None, encoding=None, mapped_clock_class=None): | |
118 | utils._check_uint64(size) | |
119 | ||
120 | if size == 0: | |
121 | raise ValueError('size is 0 bits') | |
122 | ||
b4f45851 | 123 | ptr = native_bt.field_class_integer_create(size) |
81447b5b PP |
124 | self._check_create_status(ptr) |
125 | super().__init__(ptr) | |
126 | ||
127 | if alignment is not None: | |
128 | self.alignment = alignment | |
129 | ||
130 | if byte_order is not None: | |
131 | self.byte_order = byte_order | |
132 | ||
133 | if is_signed is not None: | |
134 | self.is_signed = is_signed | |
135 | ||
136 | if base is not None: | |
137 | self.base = base | |
138 | ||
139 | if encoding is not None: | |
140 | self.encoding = encoding | |
141 | ||
142 | if mapped_clock_class is not None: | |
143 | self.mapped_clock_class = mapped_clock_class | |
144 | ||
145 | @property | |
146 | def size(self): | |
b4f45851 | 147 | size = native_bt.field_class_integer_get_size(self._ptr) |
811644b8 | 148 | assert(size >= 1) |
81447b5b PP |
149 | return size |
150 | ||
151 | @property | |
152 | def is_signed(self): | |
b4f45851 | 153 | is_signed = native_bt.field_class_integer_is_signed(self._ptr) |
811644b8 | 154 | assert(is_signed >= 0) |
81447b5b PP |
155 | return is_signed > 0 |
156 | ||
157 | @is_signed.setter | |
158 | def is_signed(self, is_signed): | |
159 | utils._check_bool(is_signed) | |
b4f45851 SM |
160 | ret = native_bt.field_class_integer_set_is_signed(self._ptr, int(is_signed)) |
161 | utils._handle_ret(ret, "cannot set integer field class object's signedness") | |
81447b5b PP |
162 | |
163 | @property | |
164 | def base(self): | |
b4f45851 | 165 | base = native_bt.field_class_integer_get_base(self._ptr) |
811644b8 | 166 | assert(base >= 0) |
81447b5b PP |
167 | return base |
168 | ||
169 | @base.setter | |
170 | def base(self, base): | |
171 | utils._check_int(base) | |
b4f45851 SM |
172 | ret = native_bt.field_class_integer_set_base(self._ptr, base) |
173 | utils._handle_ret(ret, "cannot set integer field class object's base") | |
81447b5b PP |
174 | |
175 | @property | |
176 | def encoding(self): | |
b4f45851 | 177 | encoding = native_bt.field_class_integer_get_encoding(self._ptr) |
811644b8 | 178 | assert(encoding >= 0) |
81447b5b PP |
179 | return encoding |
180 | ||
181 | @encoding.setter | |
182 | def encoding(self, encoding): | |
183 | utils._check_int(encoding) | |
b4f45851 SM |
184 | ret = native_bt.field_class_integer_set_encoding(self._ptr, encoding) |
185 | utils._handle_ret(ret, "cannot set integer field class object's encoding") | |
81447b5b PP |
186 | |
187 | @property | |
188 | def mapped_clock_class(self): | |
b4f45851 | 189 | ptr = native_bt.field_class_integer_get_mapped_clock_class(self._ptr) |
811644b8 PP |
190 | |
191 | if ptr is None: | |
192 | return | |
193 | ||
81447b5b PP |
194 | return bt2.ClockClass._create_from_ptr(ptr) |
195 | ||
196 | @mapped_clock_class.setter | |
197 | def mapped_clock_class(self, clock_class): | |
198 | utils._check_type(clock_class, bt2.ClockClass) | |
b4f45851 SM |
199 | ret = native_bt.field_class_integer_set_mapped_clock_class(self._ptr, clock_class._ptr) |
200 | utils._handle_ret(ret, "cannot set integer field class object's mapped clock class") | |
81447b5b PP |
201 | |
202 | ||
b4f45851 | 203 | class FloatingPointNumberFieldClass(_FieldClass, _AlignmentProp, _ByteOrderProp): |
81447b5b PP |
204 | _NAME = 'Floating point number' |
205 | ||
206 | def __init__(self, alignment=None, byte_order=None, exponent_size=None, | |
207 | mantissa_size=None): | |
b4f45851 | 208 | ptr = native_bt.field_class_floating_point_create() |
81447b5b PP |
209 | self._check_create_status(ptr) |
210 | super().__init__(ptr) | |
211 | ||
212 | if alignment is not None: | |
213 | self.alignment = alignment | |
214 | ||
215 | if byte_order is not None: | |
216 | self.byte_order = byte_order | |
217 | ||
218 | if exponent_size is not None: | |
219 | self.exponent_size = exponent_size | |
220 | ||
221 | if mantissa_size is not None: | |
222 | self.mantissa_size = mantissa_size | |
223 | ||
224 | @property | |
225 | def exponent_size(self): | |
b4f45851 | 226 | exp_size = native_bt.field_class_floating_point_get_exponent_digits(self._ptr) |
811644b8 | 227 | assert(exp_size >= 0) |
81447b5b PP |
228 | return exp_size |
229 | ||
230 | @exponent_size.setter | |
231 | def exponent_size(self, exponent_size): | |
232 | utils._check_uint64(exponent_size) | |
b4f45851 SM |
233 | ret = native_bt.field_class_floating_point_set_exponent_digits(self._ptr, exponent_size) |
234 | utils._handle_ret(ret, "cannot set floating point number field class object's exponent size") | |
81447b5b PP |
235 | |
236 | @property | |
237 | def mantissa_size(self): | |
b4f45851 | 238 | mant_size = native_bt.field_class_floating_point_get_mantissa_digits(self._ptr) |
811644b8 PP |
239 | assert(mant_size >= 0) |
240 | return mant_size | |
81447b5b PP |
241 | |
242 | @mantissa_size.setter | |
243 | def mantissa_size(self, mantissa_size): | |
244 | utils._check_uint64(mantissa_size) | |
b4f45851 SM |
245 | ret = native_bt.field_class_floating_point_set_mantissa_digits(self._ptr, mantissa_size) |
246 | utils._handle_ret(ret, "cannot set floating point number field class object's mantissa size") | |
81447b5b PP |
247 | |
248 | ||
b4f45851 | 249 | class _EnumerationFieldClassMapping: |
81447b5b PP |
250 | def __init__(self, name, lower, upper): |
251 | self._name = name | |
252 | self._lower = lower | |
253 | self._upper = upper | |
254 | ||
255 | @property | |
256 | def name(self): | |
257 | return self._name | |
258 | ||
259 | @property | |
260 | def lower(self): | |
261 | return self._lower | |
262 | ||
263 | @property | |
264 | def upper(self): | |
265 | return self._upper | |
266 | ||
267 | def __eq__(self, other): | |
268 | if type(other) is not self.__class__: | |
269 | return False | |
270 | ||
271 | return (self.name, self.lower, self.upper) == (other.name, other.lower, other.upper) | |
272 | ||
273 | ||
78288f58 SM |
274 | class _EnumerationFieldClassMappingIterator(object._SharedObject, |
275 | collections.abc.Iterator): | |
81447b5b PP |
276 | def __init__(self, iter_ptr, is_signed): |
277 | super().__init__(iter_ptr) | |
278 | self._is_signed = is_signed | |
279 | self._done = (iter_ptr is None) | |
280 | ||
281 | def __next__(self): | |
282 | if self._done: | |
283 | raise StopIteration | |
284 | ||
b4f45851 | 285 | ret = native_bt.field_class_enumeration_mapping_iterator_next(self._ptr) |
74fb0452 JG |
286 | if ret < 0: |
287 | self._done = True | |
288 | raise StopIteration | |
289 | ||
81447b5b | 290 | if self._is_signed: |
b4f45851 | 291 | ret, name, lower, upper = native_bt.field_class_enumeration_mapping_iterator_get_signed(self._ptr) |
81447b5b | 292 | else: |
b4f45851 | 293 | ret, name, lower, upper = native_bt.field_class_enumeration_mapping_iterator_get_unsigned(self._ptr) |
81447b5b | 294 | |
811644b8 | 295 | assert(ret == 0) |
b4f45851 | 296 | mapping = _EnumerationFieldClassMapping(name, lower, upper) |
81447b5b PP |
297 | |
298 | return mapping | |
299 | ||
300 | ||
b4f45851 | 301 | class EnumerationFieldClass(IntegerFieldClass, collections.abc.Sequence): |
81447b5b PP |
302 | _NAME = 'Enumeration' |
303 | ||
b4f45851 | 304 | def __init__(self, int_field_class=None, size=None, alignment=None, |
81447b5b PP |
305 | byte_order=None, is_signed=None, base=None, encoding=None, |
306 | mapped_clock_class=None): | |
b4f45851 SM |
307 | if int_field_class is None: |
308 | int_field_class = IntegerFieldClass(size=size, alignment=alignment, | |
81447b5b PP |
309 | byte_order=byte_order, |
310 | is_signed=is_signed, base=base, | |
311 | encoding=encoding, | |
312 | mapped_clock_class=mapped_clock_class) | |
313 | ||
b4f45851 SM |
314 | utils._check_type(int_field_class, IntegerFieldClass) |
315 | ptr = native_bt.field_class_enumeration_create(int_field_class._ptr) | |
81447b5b | 316 | self._check_create_status(ptr) |
b4f45851 | 317 | _FieldClass.__init__(self, ptr) |
81447b5b PP |
318 | |
319 | @property | |
b4f45851 SM |
320 | def integer_field_class(self): |
321 | ptr = native_bt.field_class_enumeration_get_container_type(self._ptr) | |
811644b8 | 322 | assert(ptr) |
81447b5b PP |
323 | return _create_from_ptr(ptr) |
324 | ||
325 | @property | |
326 | def size(self): | |
b4f45851 | 327 | return self.integer_field_class.size |
81447b5b PP |
328 | |
329 | @property | |
330 | def alignment(self): | |
b4f45851 | 331 | return self.integer_field_class.alignment |
81447b5b PP |
332 | |
333 | @alignment.setter | |
334 | def alignment(self, alignment): | |
b4f45851 | 335 | self.integer_field_class.alignment = alignment |
81447b5b PP |
336 | |
337 | @property | |
338 | def byte_order(self): | |
b4f45851 | 339 | return self.integer_field_class.byte_order |
81447b5b PP |
340 | |
341 | @byte_order.setter | |
342 | def byte_order(self, byte_order): | |
b4f45851 | 343 | self.integer_field_class.byte_order = byte_order |
81447b5b PP |
344 | |
345 | @property | |
346 | def is_signed(self): | |
b4f45851 | 347 | return self.integer_field_class.is_signed |
81447b5b PP |
348 | |
349 | @is_signed.setter | |
350 | def is_signed(self, is_signed): | |
b4f45851 | 351 | self.integer_field_class.is_signed = is_signed |
81447b5b PP |
352 | |
353 | @property | |
354 | def base(self): | |
b4f45851 | 355 | return self.integer_field_class.base |
81447b5b PP |
356 | |
357 | @base.setter | |
358 | def base(self, base): | |
b4f45851 | 359 | self.integer_field_class.base = base |
81447b5b PP |
360 | |
361 | @property | |
362 | def encoding(self): | |
b4f45851 | 363 | return self.integer_field_class.encoding |
81447b5b PP |
364 | |
365 | @encoding.setter | |
366 | def encoding(self, encoding): | |
b4f45851 | 367 | self.integer_field_class.encoding = encoding |
81447b5b PP |
368 | |
369 | @property | |
370 | def mapped_clock_class(self): | |
b4f45851 | 371 | return self.integer_field_class.mapped_clock_class |
81447b5b PP |
372 | |
373 | @mapped_clock_class.setter | |
374 | def mapped_clock_class(self, mapped_clock_class): | |
b4f45851 | 375 | self.integer_field_class.mapped_clock_class = mapped_clock_class |
81447b5b PP |
376 | |
377 | def __len__(self): | |
b4f45851 | 378 | count = native_bt.field_class_enumeration_get_mapping_count(self._ptr) |
811644b8 | 379 | assert(count >= 0) |
81447b5b PP |
380 | return count |
381 | ||
382 | def __getitem__(self, index): | |
383 | utils._check_uint64(index) | |
384 | ||
385 | if index >= len(self): | |
386 | raise IndexError | |
387 | ||
388 | if self.is_signed: | |
b4f45851 | 389 | get_fn = native_bt.field_class_enumeration_get_mapping_signed |
81447b5b | 390 | else: |
b4f45851 | 391 | get_fn = native_bt.field_class_enumeration_get_mapping_unsigned |
81447b5b PP |
392 | |
393 | ret, name, lower, upper = get_fn(self._ptr, index) | |
811644b8 | 394 | assert(ret == 0) |
b4f45851 | 395 | return _EnumerationFieldClassMapping(name, lower, upper) |
81447b5b PP |
396 | |
397 | def _get_mapping_iter(self, iter_ptr): | |
b4f45851 | 398 | return _EnumerationFieldClassMappingIterator(iter_ptr, self.is_signed) |
81447b5b PP |
399 | |
400 | def mappings_by_name(self, name): | |
401 | utils._check_str(name) | |
b4f45851 | 402 | iter_ptr = native_bt.field_class_enumeration_find_mappings_by_name(self._ptr, name) |
74fb0452 | 403 | print('iter_ptr', iter_ptr) |
81447b5b PP |
404 | return self._get_mapping_iter(iter_ptr) |
405 | ||
406 | def mappings_by_value(self, value): | |
407 | if self.is_signed: | |
408 | utils._check_int64(value) | |
b4f45851 | 409 | iter_ptr = native_bt.field_class_enumeration_find_mappings_by_signed_value(self._ptr, value) |
81447b5b PP |
410 | else: |
411 | utils._check_uint64(value) | |
b4f45851 | 412 | iter_ptr = native_bt.field_class_enumeration_find_mappings_by_unsigned_value(self._ptr, value) |
81447b5b PP |
413 | |
414 | return self._get_mapping_iter(iter_ptr) | |
415 | ||
e4d04867 | 416 | def add_mapping(self, name, lower, upper=None): |
81447b5b PP |
417 | utils._check_str(name) |
418 | ||
419 | if upper is None: | |
420 | upper = lower | |
421 | ||
422 | if self.is_signed: | |
b4f45851 | 423 | add_fn = native_bt.field_class_enumeration_add_mapping_signed |
81447b5b PP |
424 | utils._check_int64(lower) |
425 | utils._check_int64(upper) | |
426 | else: | |
b4f45851 | 427 | add_fn = native_bt.field_class_enumeration_add_mapping_unsigned |
81447b5b PP |
428 | utils._check_uint64(lower) |
429 | utils._check_uint64(upper) | |
430 | ||
431 | ret = add_fn(self._ptr, name, lower, upper) | |
b4f45851 | 432 | utils._handle_ret(ret, "cannot add mapping to enumeration field class object") |
81447b5b PP |
433 | |
434 | def __iadd__(self, mappings): | |
435 | for mapping in mappings: | |
e4d04867 | 436 | self.add_mapping(mapping.name, mapping.lower, mapping.upper) |
81447b5b PP |
437 | |
438 | return self | |
439 | ||
440 | ||
b4f45851 | 441 | class StringFieldClass(_FieldClass): |
81447b5b PP |
442 | _NAME = 'String' |
443 | ||
444 | def __init__(self, encoding=None): | |
b4f45851 | 445 | ptr = native_bt.field_class_string_create() |
81447b5b PP |
446 | self._check_create_status(ptr) |
447 | super().__init__(ptr) | |
448 | ||
449 | if encoding is not None: | |
450 | self.encoding = encoding | |
451 | ||
452 | @property | |
453 | def encoding(self): | |
b4f45851 | 454 | encoding = native_bt.field_class_string_get_encoding(self._ptr) |
811644b8 | 455 | assert(encoding >= 0) |
81447b5b PP |
456 | return encoding |
457 | ||
458 | @encoding.setter | |
459 | def encoding(self, encoding): | |
460 | utils._check_int(encoding) | |
b4f45851 SM |
461 | ret = native_bt.field_class_string_set_encoding(self._ptr, encoding) |
462 | utils._handle_ret(ret, "cannot set string field class object's encoding") | |
81447b5b PP |
463 | |
464 | ||
465 | class _FieldContainer(collections.abc.Mapping): | |
466 | def __len__(self): | |
467 | count = self._count() | |
811644b8 | 468 | assert(count >= 0) |
81447b5b PP |
469 | return count |
470 | ||
471 | def __getitem__(self, key): | |
472 | if not isinstance(key, str): | |
473 | raise TypeError("'{}' is not a 'str' object".format(key.__class__.__name__)) | |
474 | ||
475 | ptr = self._get_field_by_name(key) | |
476 | ||
477 | if ptr is None: | |
478 | raise KeyError(key) | |
479 | ||
480 | return _create_from_ptr(ptr) | |
481 | ||
482 | def __iter__(self): | |
483 | return self._ITER_CLS(self) | |
484 | ||
b4f45851 | 485 | def append_field(self, name, field_class): |
81447b5b | 486 | utils._check_str(name) |
b4f45851 SM |
487 | utils._check_type(field_class, _FieldClass) |
488 | ret = self._add_field(field_class._ptr, name) | |
489 | utils._handle_ret(ret, "cannot add field to {} field class object".format(self._NAME.lower())) | |
81447b5b PP |
490 | |
491 | def __iadd__(self, fields): | |
b4f45851 SM |
492 | for name, field_class in fields.items(): |
493 | self.append_field(name, field_class) | |
81447b5b PP |
494 | |
495 | return self | |
496 | ||
497 | def at_index(self, index): | |
498 | utils._check_uint64(index) | |
499 | return self._at(index) | |
500 | ||
501 | ||
b4f45851 SM |
502 | class _StructureFieldClassFieldIterator(collections.abc.Iterator): |
503 | def __init__(self, struct_field_class): | |
504 | self._struct_field_class = struct_field_class | |
81447b5b PP |
505 | self._at = 0 |
506 | ||
507 | def __next__(self): | |
b4f45851 | 508 | if self._at == len(self._struct_field_class): |
81447b5b PP |
509 | raise StopIteration |
510 | ||
b4f45851 SM |
511 | get_fc_by_index = native_bt.field_class_structure_get_field_by_index |
512 | ret, name, field_class_ptr = get_fc_by_index(self._struct_field_class._ptr, | |
811644b8 PP |
513 | self._at) |
514 | assert(ret == 0) | |
b4f45851 | 515 | native_bt.put(field_class_ptr) |
81447b5b PP |
516 | self._at += 1 |
517 | return name | |
518 | ||
519 | ||
3cdfbaea | 520 | class _StructureFieldClass(_FieldClass, _FieldContainer, _AlignmentProp): |
81447b5b | 521 | _NAME = 'Structure' |
b4f45851 | 522 | _ITER_CLS = _StructureFieldClassFieldIterator |
81447b5b PP |
523 | |
524 | def __init__(self, min_alignment=None): | |
b4f45851 | 525 | ptr = native_bt.field_class_structure_create() |
81447b5b PP |
526 | self._check_create_status(ptr) |
527 | super().__init__(ptr) | |
528 | ||
529 | if min_alignment is not None: | |
530 | self.min_alignment = min_alignment | |
531 | ||
532 | def _count(self): | |
b4f45851 | 533 | return native_bt.field_class_structure_get_field_count(self._ptr) |
81447b5b PP |
534 | |
535 | def _get_field_by_name(self, key): | |
b4f45851 | 536 | return native_bt.field_class_structure_get_field_class_by_name(self._ptr, key) |
81447b5b PP |
537 | |
538 | def _add_field(self, ptr, name): | |
b4f45851 | 539 | return native_bt.field_class_structure_add_field(self._ptr, ptr, |
0b03f63e | 540 | name) |
81447b5b PP |
541 | |
542 | def _at(self, index): | |
811644b8 PP |
543 | if index < 0 or index >= len(self): |
544 | raise IndexError | |
545 | ||
b4f45851 | 546 | ret, name, field_class_ptr = native_bt.field_class_structure_get_field_by_index(self._ptr, index) |
811644b8 | 547 | assert(ret == 0) |
b4f45851 | 548 | return _create_from_ptr(field_class_ptr) |
81447b5b PP |
549 | |
550 | ||
3cdfbaea SM |
551 | _StructureFieldClass.min_alignment = property(fset=_StructureFieldClass.alignment.fset) |
552 | _StructureFieldClass.alignment = property(fget=_StructureFieldClass.alignment.fget) | |
81447b5b PP |
553 | |
554 | ||
b4f45851 SM |
555 | class _VariantFieldClassFieldIterator(collections.abc.Iterator): |
556 | def __init__(self, variant_field_class): | |
557 | self._variant_field_class = variant_field_class | |
81447b5b PP |
558 | self._at = 0 |
559 | ||
560 | def __next__(self): | |
b4f45851 | 561 | if self._at == len(self._variant_field_class): |
81447b5b PP |
562 | raise StopIteration |
563 | ||
b4f45851 | 564 | ret, name, field_class_ptr = native_bt.field_class_variant_get_field_by_index(self._variant_field_class._ptr, |
0b03f63e | 565 | self._at) |
811644b8 | 566 | assert(ret == 0) |
b4f45851 | 567 | native_bt.put(field_class_ptr) |
81447b5b PP |
568 | self._at += 1 |
569 | return name | |
570 | ||
571 | ||
b4f45851 | 572 | class VariantFieldClass(_FieldClass, _FieldContainer, _AlignmentProp): |
81447b5b | 573 | _NAME = 'Variant' |
b4f45851 | 574 | _ITER_CLS = _VariantFieldClassFieldIterator |
81447b5b | 575 | |
b4f45851 | 576 | def __init__(self, tag_name, tag_field_class=None): |
81447b5b | 577 | utils._check_str(tag_name) |
811644b8 | 578 | |
b4f45851 SM |
579 | if tag_field_class is None: |
580 | tag_fc_ptr = None | |
811644b8 | 581 | else: |
b4f45851 SM |
582 | utils._check_type(tag_field_class, EnumerationFieldClass) |
583 | tag_fc_ptr = tag_field_class._ptr | |
811644b8 | 584 | |
b4f45851 | 585 | ptr = native_bt.field_class_variant_create(tag_fc_ptr, |
0b03f63e | 586 | tag_name) |
81447b5b PP |
587 | self._check_create_status(ptr) |
588 | super().__init__(ptr) | |
589 | ||
590 | @property | |
591 | def tag_name(self): | |
b4f45851 | 592 | tag_name = native_bt.field_class_variant_get_tag_name(self._ptr) |
811644b8 | 593 | assert(tag_name is not None) |
81447b5b PP |
594 | return tag_name |
595 | ||
596 | @tag_name.setter | |
597 | def tag_name(self, tag_name): | |
598 | utils._check_str(tag_name) | |
b4f45851 SM |
599 | ret = native_bt.field_class_variant_set_tag_name(self._ptr, tag_name) |
600 | utils._handle_ret(ret, "cannot set variant field class object's tag name") | |
81447b5b | 601 | |
811644b8 | 602 | @property |
b4f45851 SM |
603 | def tag_field_class(self): |
604 | fc_ptr = native_bt.field_class_variant_get_tag_type(self._ptr) | |
811644b8 | 605 | |
b4f45851 | 606 | if fc_ptr is None: |
811644b8 PP |
607 | return |
608 | ||
b4f45851 | 609 | return _create_from_ptr(fc_ptr) |
811644b8 | 610 | |
81447b5b | 611 | def _count(self): |
b4f45851 | 612 | return native_bt.field_class_variant_get_field_count(self._ptr) |
81447b5b PP |
613 | |
614 | def _get_field_by_name(self, key): | |
b4f45851 | 615 | return native_bt.field_class_variant_get_field_class_by_name(self._ptr, key) |
81447b5b PP |
616 | |
617 | def _add_field(self, ptr, name): | |
b4f45851 | 618 | return native_bt.field_class_variant_add_field(self._ptr, ptr, name) |
81447b5b PP |
619 | |
620 | def _at(self, index): | |
811644b8 PP |
621 | if index < 0 or index >= len(self): |
622 | raise IndexError | |
623 | ||
b4f45851 | 624 | ret, name, field_class_ptr = native_bt.field_class_variant_get_field_by_index(self._ptr, index) |
811644b8 | 625 | assert(ret == 0) |
b4f45851 | 626 | return _create_from_ptr(field_class_ptr) |
81447b5b PP |
627 | |
628 | ||
b4f45851 | 629 | class ArrayFieldClass(_FieldClass): |
81447b5b PP |
630 | _NAME = 'Array' |
631 | ||
b4f45851 SM |
632 | def __init__(self, element_field_class, length): |
633 | utils._check_type(element_field_class, _FieldClass) | |
81447b5b | 634 | utils._check_uint64(length) |
b4f45851 | 635 | ptr = native_bt.field_class_array_create(element_field_class._ptr, length) |
81447b5b PP |
636 | self._check_create_status(ptr) |
637 | super().__init__(ptr) | |
638 | ||
639 | @property | |
640 | def length(self): | |
b4f45851 | 641 | length = native_bt.field_class_array_get_length(self._ptr) |
811644b8 | 642 | assert(length >= 0) |
81447b5b PP |
643 | return length |
644 | ||
645 | @property | |
b4f45851 SM |
646 | def element_field_class(self): |
647 | ptr = native_bt.field_class_array_get_element_type(self._ptr) | |
811644b8 | 648 | assert(ptr) |
81447b5b PP |
649 | return _create_from_ptr(ptr) |
650 | ||
651 | ||
b4f45851 | 652 | class SequenceFieldClass(_FieldClass): |
81447b5b PP |
653 | _NAME = 'Sequence' |
654 | ||
b4f45851 SM |
655 | def __init__(self, element_field_class, length_name): |
656 | utils._check_type(element_field_class, _FieldClass) | |
81447b5b | 657 | utils._check_str(length_name) |
b4f45851 | 658 | ptr = native_bt.field_class_sequence_create(element_field_class._ptr, |
0b03f63e | 659 | length_name) |
81447b5b PP |
660 | self._check_create_status(ptr) |
661 | super().__init__(ptr) | |
662 | ||
663 | @property | |
664 | def length_name(self): | |
b4f45851 | 665 | length_name = native_bt.field_class_sequence_get_length_field_name(self._ptr) |
811644b8 | 666 | assert(length_name is not None) |
81447b5b PP |
667 | return length_name |
668 | ||
669 | @property | |
b4f45851 SM |
670 | def element_field_class(self): |
671 | ptr = native_bt.field_class_sequence_get_element_type(self._ptr) | |
811644b8 | 672 | assert(ptr) |
81447b5b PP |
673 | return _create_from_ptr(ptr) |
674 | ||
675 | ||
3cdfbaea SM |
676 | _FIELD_CLASS_TYPE_TO_OBJ = { |
677 | native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldClass, | |
81447b5b | 678 | } |