Commit | Line | Data |
---|---|---|
81447b5b PP |
1 | # The MIT License (MIT) |
2 | # | |
f6a5e476 | 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 | |
ae0bfae8 | 25 | import bt2.field |
c8820b76 | 26 | import bt2.field_path |
81447b5b PP |
27 | import bt2 |
28 | ||
29 | ||
060aee52 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 | ||
c8820b76 SM |
35 | class IntegerDisplayBase: |
36 | BINARY = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY | |
37 | OCTAL = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL | |
38 | DECIMAL = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL | |
39 | HEXADECIMAL = native_bt.FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL | |
81447b5b | 40 | |
81447b5b | 41 | |
c8820b76 SM |
42 | class _FieldClass(object._SharedObject): |
43 | _get_ref = staticmethod(native_bt.field_class_get_ref) | |
44 | _put_ref = staticmethod(native_bt.field_class_put_ref) | |
81447b5b PP |
45 | |
46 | def _check_create_status(self, ptr): | |
47 | if ptr is None: | |
32656995 | 48 | raise bt2.CreationError('cannot create {} field class object'.format(self._NAME.lower())) |
81447b5b | 49 | |
81447b5b | 50 | |
a728f6c3 | 51 | class _IntegerFieldClass(_FieldClass): |
81447b5b | 52 | @property |
c8820b76 SM |
53 | def field_value_range(self): |
54 | size = native_bt.field_class_integer_get_field_value_range(self._ptr) | |
f6a5e476 | 55 | assert(size >= 1) |
81447b5b PP |
56 | return size |
57 | ||
c8820b76 SM |
58 | def _field_value_range(self, size): |
59 | if size < 1 or size > 64: | |
60 | raise ValueError("Value is outside valid range [1, 64] ({})".format(size)) | |
61 | native_bt.field_class_integer_set_field_value_range(self._ptr, size) | |
81447b5b | 62 | |
c8820b76 | 63 | _field_value_range = property(fset=_field_value_range) |
81447b5b PP |
64 | |
65 | @property | |
c8820b76 SM |
66 | def preferred_display_base(self): |
67 | base = native_bt.field_class_integer_get_preferred_display_base( | |
68 | self._ptr) | |
f6a5e476 | 69 | assert(base >= 0) |
81447b5b PP |
70 | return base |
71 | ||
c8820b76 SM |
72 | def _preferred_display_base(self, base): |
73 | utils._check_uint64(base) | |
81447b5b | 74 | |
c8820b76 SM |
75 | if base not in (IntegerDisplayBase.BINARY, |
76 | IntegerDisplayBase.OCTAL, | |
77 | IntegerDisplayBase.DECIMAL, | |
78 | IntegerDisplayBase.HEXADECIMAL): | |
79 | raise ValueError("Display base is not a valid IntegerDisplayBase value") | |
81447b5b | 80 | |
c8820b76 SM |
81 | native_bt.field_class_integer_set_preferred_display_base( |
82 | self._ptr, base) | |
81447b5b | 83 | |
c8820b76 | 84 | _preferred_display_base = property(fset=_preferred_display_base) |
81447b5b PP |
85 | |
86 | ||
27d97a3f | 87 | class _UnsignedIntegerFieldClass(_IntegerFieldClass): |
c8820b76 | 88 | _NAME = 'Unsigned integer' |
27d97a3f SM |
89 | |
90 | ||
a728f6c3 | 91 | class _SignedIntegerFieldClass(_IntegerFieldClass): |
c8820b76 | 92 | _NAME = 'Signed integer' |
27d97a3f | 93 | |
a728f6c3 | 94 | |
c8820b76 | 95 | class _RealFieldClass(_FieldClass): |
27d97a3f | 96 | _NAME = 'Real' |
81447b5b | 97 | |
81447b5b | 98 | @property |
c8820b76 SM |
99 | def is_single_precision(self): |
100 | return native_bt.field_class_real_is_single_precision(self._ptr) | |
81447b5b | 101 | |
c8820b76 SM |
102 | def _is_single_precision(self, is_single_precision): |
103 | utils._check_bool(is_single_precision) | |
104 | native_bt.field_class_real_set_is_single_precision( | |
105 | self._ptr, is_single_precision) | |
81447b5b | 106 | |
c8820b76 | 107 | _is_single_precision = property(fset=_is_single_precision) |
81447b5b PP |
108 | |
109 | ||
c8820b76 SM |
110 | class _EnumerationFieldClassMappingRange: |
111 | def __init__(self, lower, upper): | |
81447b5b PP |
112 | self._lower = lower |
113 | self._upper = upper | |
114 | ||
81447b5b PP |
115 | @property |
116 | def lower(self): | |
117 | return self._lower | |
118 | ||
119 | @property | |
120 | def upper(self): | |
121 | return self._upper | |
122 | ||
123 | def __eq__(self, other): | |
c8820b76 | 124 | return self.lower == other.lower and self.upper == other.upper |
81447b5b | 125 | |
81447b5b | 126 | |
c8820b76 SM |
127 | class _EnumerationFieldClassMapping(collections.abc.Set): |
128 | def __init__(self, mapping_ptr): | |
129 | self._mapping_ptr = mapping_ptr | |
81447b5b PP |
130 | |
131 | @property | |
c8820b76 SM |
132 | def label(self): |
133 | mapping_ptr = self._as_enumeration_field_class_mapping_ptr(self._mapping_ptr) | |
134 | label = native_bt.field_class_enumeration_mapping_get_label(mapping_ptr) | |
135 | assert label is not None | |
136 | return label | |
81447b5b | 137 | |
c8820b76 SM |
138 | def __len__(self): |
139 | mapping_ptr = self._as_enumeration_field_class_mapping_ptr(self._mapping_ptr) | |
140 | return native_bt.field_class_enumeration_mapping_get_range_count(mapping_ptr) | |
81447b5b | 141 | |
c8820b76 SM |
142 | def __contains__(self, other_range): |
143 | for curr_range in self: | |
144 | if curr_range == other_range: | |
145 | return True | |
146 | return False | |
81447b5b | 147 | |
c8820b76 SM |
148 | def __iter__(self): |
149 | for idx in range(len(self)): | |
150 | lower, upper = self._get_range_by_index(self._mapping_ptr, idx) | |
151 | yield _EnumerationFieldClassMappingRange(lower, upper) | |
81447b5b | 152 | |
81447b5b | 153 | |
c8820b76 SM |
154 | class _UnsignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping): |
155 | _as_enumeration_field_class_mapping_ptr = staticmethod(native_bt.field_class_unsigned_enumeration_mapping_as_mapping_const) | |
156 | _get_range_by_index = staticmethod(native_bt.field_class_unsigned_enumeration_mapping_get_range_by_index) | |
81447b5b | 157 | |
81447b5b | 158 | |
c8820b76 SM |
159 | class _SignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping): |
160 | _as_enumeration_field_class_mapping_ptr = staticmethod(native_bt.field_class_signed_enumeration_mapping_as_mapping_const) | |
161 | _get_range_by_index = staticmethod(native_bt.field_class_signed_enumeration_mapping_get_range_by_index) | |
81447b5b | 162 | |
81447b5b | 163 | |
c8820b76 | 164 | class _EnumerationFieldClass(_IntegerFieldClass, collections.abc.Mapping): |
81447b5b | 165 | def __len__(self): |
32656995 | 166 | count = native_bt.field_class_enumeration_get_mapping_count(self._ptr) |
f6a5e476 | 167 | assert(count >= 0) |
81447b5b PP |
168 | return count |
169 | ||
c8820b76 SM |
170 | def map_range(self, label, lower, upper=None): |
171 | utils._check_str(label) | |
81447b5b | 172 | |
c8820b76 SM |
173 | if upper is None: |
174 | upper = lower | |
81447b5b | 175 | |
c8820b76 SM |
176 | ret = self._map_range(self._ptr, label, lower, upper) |
177 | utils._handle_ret(ret, "cannot add mapping to enumeration field class object") | |
81447b5b | 178 | |
c8820b76 SM |
179 | def labels_by_value(self, value): |
180 | ret, labels = self._get_mapping_labels_by_value(self._ptr, value) | |
181 | utils._handle_ret(ret, "cannot get mapping labels") | |
182 | return labels | |
81447b5b | 183 | |
c8820b76 SM |
184 | def __iter__(self): |
185 | for idx in range(len(self)): | |
186 | mapping = self._get_mapping_by_index(self._ptr, idx) | |
187 | yield mapping.label | |
81447b5b | 188 | |
c8820b76 SM |
189 | def __getitem__(self, key): |
190 | utils._check_str(key) | |
191 | for idx in range(len(self)): | |
192 | mapping = self._get_mapping_by_index(self._ptr, idx) | |
193 | if mapping.label == key: | |
194 | return mapping | |
81447b5b | 195 | |
c8820b76 | 196 | raise KeyError(key) |
81447b5b | 197 | |
c8820b76 SM |
198 | def __iadd__(self, mappings): |
199 | for mapping in mappings.values(): | |
200 | for range in mapping: | |
201 | self.map_range(mapping.label, range.lower, range.upper) | |
81447b5b | 202 | |
c8820b76 | 203 | return self |
81447b5b | 204 | |
81447b5b | 205 | |
c8820b76 SM |
206 | class _UnsignedEnumerationFieldClass(_EnumerationFieldClass, _UnsignedIntegerFieldClass): |
207 | _NAME = 'Unsigned enumeration' | |
81447b5b | 208 | |
c8820b76 SM |
209 | @staticmethod |
210 | def _get_mapping_by_index(enum_ptr, index): | |
211 | mapping_ptr = native_bt.field_class_unsigned_enumeration_borrow_mapping_by_index_const(enum_ptr, index) | |
212 | assert mapping_ptr is not None | |
213 | return _UnsignedEnumerationFieldClassMapping(mapping_ptr) | |
81447b5b | 214 | |
c8820b76 SM |
215 | @staticmethod |
216 | def _map_range(enum_ptr, label, lower, upper): | |
217 | utils._check_uint64(lower) | |
218 | utils._check_uint64(upper) | |
219 | return native_bt.field_class_unsigned_enumeration_map_range(enum_ptr, label, lower, upper) | |
81447b5b | 220 | |
c8820b76 SM |
221 | @staticmethod |
222 | def _get_mapping_labels_by_value(enum_ptr, value): | |
223 | utils._check_uint64(value) | |
224 | return native_bt.field_class_unsigned_enumeration_get_mapping_labels_by_value(enum_ptr, value) | |
81447b5b PP |
225 | |
226 | ||
c8820b76 SM |
227 | class _SignedEnumerationFieldClass(_EnumerationFieldClass, _SignedIntegerFieldClass): |
228 | _NAME = 'Signed enumeration' | |
81447b5b | 229 | |
c8820b76 SM |
230 | @staticmethod |
231 | def _get_mapping_by_index(enum_ptr, index): | |
232 | mapping_ptr = native_bt.field_class_signed_enumeration_borrow_mapping_by_index_const(enum_ptr, index) | |
233 | assert mapping_ptr is not None | |
234 | return _SignedEnumerationFieldClassMapping(mapping_ptr) | |
81447b5b | 235 | |
c8820b76 SM |
236 | @staticmethod |
237 | def _map_range(enum_ptr, label, lower, upper): | |
238 | utils._check_int64(lower) | |
239 | utils._check_int64(upper) | |
240 | return native_bt.field_class_signed_enumeration_map_range(enum_ptr, label, lower, upper) | |
81447b5b | 241 | |
c8820b76 SM |
242 | @staticmethod |
243 | def _get_mapping_labels_by_value(enum_ptr, value): | |
244 | utils._check_int64(value) | |
245 | return native_bt.field_class_signed_enumeration_get_mapping_labels_by_value(enum_ptr, value) | |
81447b5b | 246 | |
c8820b76 SM |
247 | |
248 | class _StringFieldClass(_FieldClass): | |
249 | _NAME = 'String' | |
81447b5b PP |
250 | |
251 | ||
252 | class _FieldContainer(collections.abc.Mapping): | |
253 | def __len__(self): | |
c8820b76 SM |
254 | count = self._get_element_count(self._ptr) |
255 | assert count >= 0 | |
81447b5b PP |
256 | return count |
257 | ||
258 | def __getitem__(self, key): | |
259 | if not isinstance(key, str): | |
c8820b76 | 260 | raise TypeError("key should be a 'str' object, got {}".format(key.__class__.__name__)) |
81447b5b | 261 | |
c8820b76 | 262 | ptr = self._borrow_field_class_ptr_by_name(key) |
81447b5b PP |
263 | |
264 | if ptr is None: | |
265 | raise KeyError(key) | |
266 | ||
c8820b76 SM |
267 | return _create_field_class_from_ptr_and_get_ref(ptr) |
268 | ||
269 | def _borrow_field_class_ptr_by_name(self, key): | |
270 | element_ptr = self._borrow_element_by_name(self._ptr, key) | |
271 | if element_ptr is None: | |
272 | return | |
273 | ||
274 | return self._element_borrow_field_class(element_ptr) | |
81447b5b PP |
275 | |
276 | def __iter__(self): | |
c8820b76 SM |
277 | for idx in range(len(self)): |
278 | element_ptr = self._borrow_element_by_index(self._ptr, idx) | |
279 | assert element_ptr is not None | |
81447b5b | 280 | |
c8820b76 SM |
281 | yield self._element_get_name(element_ptr) |
282 | ||
283 | def _append_element_common(self, name, field_class): | |
81447b5b | 284 | utils._check_str(name) |
32656995 | 285 | utils._check_type(field_class, _FieldClass) |
c8820b76 | 286 | ret = self._append_element(self._ptr, name, field_class._ptr) |
32656995 | 287 | utils._handle_ret(ret, "cannot add field to {} field class object".format(self._NAME.lower())) |
81447b5b PP |
288 | |
289 | def __iadd__(self, fields): | |
32656995 | 290 | for name, field_class in fields.items(): |
c8820b76 | 291 | self._append_element_common(name, field_class) |
81447b5b PP |
292 | |
293 | return self | |
294 | ||
c8820b76 | 295 | def _at_index(self, index): |
81447b5b | 296 | utils._check_uint64(index) |
81447b5b | 297 | |
f6a5e476 PP |
298 | if index < 0 or index >= len(self): |
299 | raise IndexError | |
300 | ||
c8820b76 SM |
301 | element_ptr = self._borrow_element_by_index(self._ptr, index) |
302 | assert element_ptr is not None | |
81447b5b | 303 | |
c8820b76 | 304 | field_class_ptr = self._element_borrow_field_class(element_ptr) |
81447b5b | 305 | |
c8820b76 | 306 | return _create_field_class_from_ptr_and_get_ref(field_class_ptr) |
81447b5b PP |
307 | |
308 | ||
c8820b76 SM |
309 | class _StructureFieldClass(_FieldClass, _FieldContainer): |
310 | _NAME = 'Structure' | |
311 | _borrow_element_by_index = staticmethod(native_bt.field_class_structure_borrow_member_by_index_const) | |
312 | _borrow_element_by_name = staticmethod(native_bt.field_class_structure_borrow_member_by_name_const) | |
313 | _element_get_name = staticmethod(native_bt.field_class_structure_member_get_name) | |
314 | _element_borrow_field_class = staticmethod(native_bt.field_class_structure_member_borrow_field_class_const) | |
315 | _get_element_count = staticmethod(native_bt.field_class_structure_get_member_count) | |
316 | _append_element = staticmethod(native_bt.field_class_structure_append_member) | |
81447b5b | 317 | |
c8820b76 SM |
318 | def append_member(self, name, field_class): |
319 | return self._append_element_common(name, field_class) | |
81447b5b | 320 | |
c8820b76 SM |
321 | def member_at_index(self, index): |
322 | return self._at_index(index) | |
81447b5b PP |
323 | |
324 | ||
c8820b76 | 325 | class _VariantFieldClass(_FieldClass, _FieldContainer): |
81447b5b | 326 | _NAME = 'Variant' |
c8820b76 SM |
327 | _borrow_element_by_index = staticmethod(native_bt.field_class_variant_borrow_option_by_index_const) |
328 | _borrow_element_by_name = staticmethod(native_bt.field_class_variant_borrow_option_by_name_const) | |
329 | _element_get_name = staticmethod(native_bt.field_class_variant_option_get_name) | |
330 | _element_borrow_field_class = staticmethod(native_bt.field_class_variant_option_borrow_field_class_const) | |
331 | _get_element_count = staticmethod(native_bt.field_class_variant_get_option_count) | |
332 | _append_element = staticmethod(native_bt.field_class_variant_append_option) | |
f6a5e476 | 333 | |
c8820b76 SM |
334 | def append_option(self, name, field_class): |
335 | return self._append_element_common(name, field_class) | |
f6a5e476 | 336 | |
c8820b76 SM |
337 | def option_at_index(self, index): |
338 | return self._at_index(index) | |
81447b5b PP |
339 | |
340 | @property | |
c8820b76 SM |
341 | def selector_field_path(self): |
342 | ptr = native_bt.field_class_variant_borrow_selector_field_path_const(self._ptr) | |
343 | if ptr is None: | |
f6a5e476 PP |
344 | return |
345 | ||
c8820b76 | 346 | return bt2.field_path._FieldPath._create_from_ptr_and_get_ref(ptr) |
81447b5b | 347 | |
c8820b76 SM |
348 | def _set_selector_field_class(self, selector_fc): |
349 | utils._check_type(selector_fc, bt2.field_class._EnumerationFieldClass) | |
350 | ret = native_bt.field_class_variant_set_selector_field_class(self._ptr, selector_fc._ptr) | |
351 | utils._handle_ret(ret, "cannot set variant selector field type") | |
81447b5b | 352 | |
c8820b76 | 353 | _selector_field_class = property(fset=_set_selector_field_class) |
f6a5e476 | 354 | |
81447b5b | 355 | |
c8820b76 SM |
356 | class _ArrayFieldClass(_FieldClass): |
357 | @property | |
358 | def element_field_class(self): | |
359 | elem_fc_ptr = native_bt.field_class_array_borrow_element_field_class_const(self._ptr) | |
360 | return _create_field_class_from_ptr_and_get_ref(elem_fc_ptr) | |
81447b5b | 361 | |
81447b5b | 362 | |
c8820b76 | 363 | class _StaticArrayFieldClass(_ArrayFieldClass): |
81447b5b PP |
364 | @property |
365 | def length(self): | |
c8820b76 | 366 | return native_bt.field_class_static_array_get_length(self._ptr) |
81447b5b PP |
367 | |
368 | ||
c8820b76 SM |
369 | class _DynamicArrayFieldClass(_ArrayFieldClass): |
370 | @property | |
371 | def length_field_path(self): | |
372 | ptr = native_bt.field_class_dynamic_array_borrow_length_field_path_const(self._ptr) | |
373 | if ptr is None: | |
374 | return | |
81447b5b | 375 | |
c8820b76 | 376 | return bt2.field_path._FieldPath._create_from_ptr_and_get_ref(ptr) |
81447b5b | 377 | |
c8820b76 SM |
378 | def _set_length_field_class(self, length_fc): |
379 | utils._check_type(length_fc, _UnsignedIntegerFieldClass) | |
380 | ret = native_bt.field_class_dynamic_array_set_length_field_class(self._ptr, length_fc._ptr) | |
381 | utils._handle_ret(ret, "cannot set dynamic array length field type") | |
81447b5b | 382 | |
c8820b76 | 383 | _length_field_class = property(fset=_set_length_field_class) |
81447b5b PP |
384 | |
385 | ||
060aee52 | 386 | _FIELD_CLASS_TYPE_TO_OBJ = { |
c8820b76 SM |
387 | native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerFieldClass, |
388 | native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerFieldClass, | |
389 | native_bt.FIELD_CLASS_TYPE_REAL: _RealFieldClass, | |
390 | native_bt.FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION: _UnsignedEnumerationFieldClass, | |
391 | native_bt.FIELD_CLASS_TYPE_SIGNED_ENUMERATION: _SignedEnumerationFieldClass, | |
392 | native_bt.FIELD_CLASS_TYPE_STRING: _StringFieldClass, | |
060aee52 | 393 | native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldClass, |
c8820b76 SM |
394 | native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldClass, |
395 | native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayFieldClass, | |
396 | native_bt.FIELD_CLASS_TYPE_VARIANT: _VariantFieldClass, | |
81447b5b | 397 | } |