Bump black to version 23
[babeltrace.git] / src / bindings / python / bt2 / bt2 / trace_class.py
1 # SPDX-License-Identifier: MIT
2 #
3 # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
4 # Copyright (c) 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
5 # Copyright (c) 2019 Simon Marchi <simon.marchi@efficios.com>
6
7 from bt2 import native_bt, utils, object
8 from bt2 import stream_class as bt2_stream_class
9 from bt2 import field_class as bt2_field_class
10 from bt2 import integer_range_set as bt2_integer_range_set
11 from bt2 import trace as bt2_trace
12 from bt2 import value as bt2_value
13 import collections.abc
14 import functools
15 import bt2
16
17
18 def _trace_class_destruction_listener_from_native(
19 user_listener, handle, trace_class_ptr
20 ):
21 trace_class = _TraceClass._create_from_ptr_and_get_ref(trace_class_ptr)
22 user_listener(trace_class)
23 handle._invalidate()
24
25
26 class _TraceClassConst(object._SharedObject, collections.abc.Mapping):
27 @staticmethod
28 def _get_ref(ptr):
29 native_bt.trace_class_get_ref(ptr)
30
31 @staticmethod
32 def _put_ref(ptr):
33 native_bt.trace_class_put_ref(ptr)
34
35 _borrow_stream_class_ptr_by_index = staticmethod(
36 native_bt.trace_class_borrow_stream_class_by_index_const
37 )
38 _borrow_stream_class_ptr_by_id = staticmethod(
39 native_bt.trace_class_borrow_stream_class_by_id_const
40 )
41 _borrow_user_attributes_ptr = staticmethod(
42 native_bt.trace_class_borrow_user_attributes_const
43 )
44 _stream_class_pycls = bt2_stream_class._StreamClassConst
45 _create_value_from_ptr_and_get_ref = staticmethod(
46 bt2_value._create_from_const_ptr_and_get_ref
47 )
48
49 @property
50 def user_attributes(self):
51 ptr = self._borrow_user_attributes_ptr(self._ptr)
52 assert ptr is not None
53 return self._create_value_from_ptr_and_get_ref(ptr)
54
55 # Number of stream classes in this trace class.
56
57 def __len__(self):
58 count = native_bt.trace_class_get_stream_class_count(self._ptr)
59 assert count >= 0
60 return count
61
62 # Get a stream class by stream id.
63
64 def __getitem__(self, key):
65 utils._check_uint64(key)
66
67 sc_ptr = self._borrow_stream_class_ptr_by_id(self._ptr, key)
68 if sc_ptr is None:
69 raise KeyError(key)
70
71 return self._stream_class_pycls._create_from_ptr_and_get_ref(sc_ptr)
72
73 def __iter__(self):
74 for idx in range(len(self)):
75 sc_ptr = self._borrow_stream_class_ptr_by_index(self._ptr, idx)
76 assert sc_ptr is not None
77
78 id = native_bt.stream_class_get_id(sc_ptr)
79 assert id >= 0
80
81 yield id
82
83 @property
84 def assigns_automatic_stream_class_id(self):
85 return native_bt.trace_class_assigns_automatic_stream_class_id(self._ptr)
86
87 # Add a listener to be called when the trace class is destroyed.
88
89 def add_destruction_listener(self, listener):
90 if not callable(listener):
91 raise TypeError("'listener' parameter is not callable")
92
93 handle = utils._ListenerHandle(self.addr)
94
95 listener_from_native = functools.partial(
96 _trace_class_destruction_listener_from_native, listener, handle
97 )
98
99 fn = native_bt.bt2_trace_class_add_destruction_listener
100 status, listener_id = fn(self._ptr, listener_from_native)
101 utils._handle_func_status(
102 status, "cannot add destruction listener to trace class object"
103 )
104
105 handle._set_listener_id(listener_id)
106
107 return handle
108
109 def remove_destruction_listener(self, listener_handle):
110 utils._check_type(listener_handle, utils._ListenerHandle)
111
112 if listener_handle._addr != self.addr:
113 raise ValueError(
114 "This trace class destruction listener does not match the trace class object."
115 )
116
117 if listener_handle._listener_id is None:
118 raise ValueError(
119 "This trace class destruction listener was already removed."
120 )
121
122 status = native_bt.trace_class_remove_destruction_listener(
123 self._ptr, listener_handle._listener_id
124 )
125 utils._handle_func_status(status)
126 listener_handle._invalidate()
127
128
129 class _TraceClass(_TraceClassConst):
130 _borrow_stream_class_ptr_by_index = staticmethod(
131 native_bt.trace_class_borrow_stream_class_by_index
132 )
133 _borrow_stream_class_ptr_by_id = staticmethod(
134 native_bt.trace_class_borrow_stream_class_by_id
135 )
136 _borrow_user_attributes_ptr = staticmethod(
137 native_bt.trace_class_borrow_user_attributes
138 )
139 _stream_class_pycls = bt2_stream_class._StreamClass
140 _create_value_from_ptr_and_get_ref = staticmethod(
141 bt2_value._create_from_ptr_and_get_ref
142 )
143
144 # Instantiate a trace of this class.
145
146 def __call__(self, name=None, user_attributes=None, uuid=None, environment=None):
147 trace_ptr = native_bt.trace_create(self._ptr)
148
149 if trace_ptr is None:
150 raise bt2._MemoryError("cannot create trace class object")
151
152 trace = bt2_trace._Trace._create_from_ptr(trace_ptr)
153
154 if name is not None:
155 trace._name = name
156
157 if user_attributes is not None:
158 trace._user_attributes = user_attributes
159
160 if uuid is not None:
161 trace._uuid = uuid
162
163 if environment is not None:
164 for key, value in environment.items():
165 trace.environment[key] = value
166
167 return trace
168
169 def create_stream_class(
170 self,
171 id=None,
172 name=None,
173 user_attributes=None,
174 packet_context_field_class=None,
175 event_common_context_field_class=None,
176 default_clock_class=None,
177 assigns_automatic_event_class_id=True,
178 assigns_automatic_stream_id=True,
179 supports_packets=False,
180 packets_have_beginning_default_clock_snapshot=False,
181 packets_have_end_default_clock_snapshot=False,
182 supports_discarded_events=False,
183 discarded_events_have_default_clock_snapshots=False,
184 supports_discarded_packets=False,
185 discarded_packets_have_default_clock_snapshots=False,
186 ):
187 # Validate parameters before we create the object.
188 bt2_stream_class._StreamClass._validate_create_params(
189 name,
190 user_attributes,
191 packet_context_field_class,
192 event_common_context_field_class,
193 default_clock_class,
194 assigns_automatic_event_class_id,
195 assigns_automatic_stream_id,
196 supports_packets,
197 packets_have_beginning_default_clock_snapshot,
198 packets_have_end_default_clock_snapshot,
199 supports_discarded_events,
200 discarded_events_have_default_clock_snapshots,
201 supports_discarded_packets,
202 discarded_packets_have_default_clock_snapshots,
203 )
204
205 if self.assigns_automatic_stream_class_id:
206 if id is not None:
207 raise ValueError(
208 "id provided, but trace class assigns automatic stream class ids"
209 )
210
211 sc_ptr = native_bt.stream_class_create(self._ptr)
212 else:
213 if id is None:
214 raise ValueError(
215 "id not provided, but trace class does not assign automatic stream class ids"
216 )
217
218 utils._check_uint64(id)
219 sc_ptr = native_bt.stream_class_create_with_id(self._ptr, id)
220
221 sc = bt2_stream_class._StreamClass._create_from_ptr(sc_ptr)
222
223 if name is not None:
224 sc._name = name
225
226 if user_attributes is not None:
227 sc._user_attributes = user_attributes
228
229 if event_common_context_field_class is not None:
230 sc._event_common_context_field_class = event_common_context_field_class
231
232 if default_clock_class is not None:
233 sc._default_clock_class = default_clock_class
234
235 # call after `sc._default_clock_class` because, if
236 # `packets_have_beginning_default_clock_snapshot` or
237 # `packets_have_end_default_clock_snapshot` is true, then this
238 # stream class needs a default clock class already.
239 sc._set_supports_packets(
240 supports_packets,
241 packets_have_beginning_default_clock_snapshot,
242 packets_have_end_default_clock_snapshot,
243 )
244
245 # call after sc._set_supports_packets() because, if
246 # `packet_context_field_class` is not `None`, then this stream
247 # class needs to support packets already.
248 if packet_context_field_class is not None:
249 sc._packet_context_field_class = packet_context_field_class
250
251 sc._assigns_automatic_event_class_id = assigns_automatic_event_class_id
252 sc._assigns_automatic_stream_id = assigns_automatic_stream_id
253 sc._set_supports_discarded_events(
254 supports_discarded_events, discarded_events_have_default_clock_snapshots
255 )
256 sc._set_supports_discarded_packets(
257 supports_discarded_packets, discarded_packets_have_default_clock_snapshots
258 )
259 return sc
260
261 def _user_attributes(self, user_attributes):
262 value = bt2_value.create_value(user_attributes)
263 utils._check_type(value, bt2_value.MapValue)
264 native_bt.trace_class_set_user_attributes(self._ptr, value._ptr)
265
266 _user_attributes = property(fset=_user_attributes)
267
268 def _assigns_automatic_stream_class_id(self, auto_id):
269 utils._check_bool(auto_id)
270 return native_bt.trace_class_set_assigns_automatic_stream_class_id(
271 self._ptr, auto_id
272 )
273
274 _assigns_automatic_stream_class_id = property(
275 fset=_assigns_automatic_stream_class_id
276 )
277
278 # Field class creation methods.
279
280 def _check_field_class_create_status(self, ptr, type_name):
281 if ptr is None:
282 raise bt2._MemoryError("cannot create {} field class".format(type_name))
283
284 @staticmethod
285 def _set_field_class_user_attrs(fc, user_attributes):
286 if user_attributes is not None:
287 fc._user_attributes = user_attributes
288
289 def create_bool_field_class(self, user_attributes=None):
290 field_class_ptr = native_bt.field_class_bool_create(self._ptr)
291 self._check_field_class_create_status(field_class_ptr, "boolean")
292 fc = bt2_field_class._BoolFieldClass._create_from_ptr(field_class_ptr)
293 self._set_field_class_user_attrs(fc, user_attributes)
294 return fc
295
296 def create_bit_array_field_class(self, length, user_attributes=None):
297 utils._check_uint64(length)
298
299 if length < 1 or length > 64:
300 raise ValueError(
301 "invalid length {}: expecting a value in the [1, 64] range".format(
302 length
303 )
304 )
305
306 field_class_ptr = native_bt.field_class_bit_array_create(self._ptr, length)
307 self._check_field_class_create_status(field_class_ptr, "bit array")
308 fc = bt2_field_class._BitArrayFieldClass._create_from_ptr(field_class_ptr)
309 self._set_field_class_user_attrs(fc, user_attributes)
310 return fc
311
312 def _create_integer_field_class(
313 self,
314 create_func,
315 py_cls,
316 type_name,
317 field_value_range,
318 preferred_display_base,
319 user_attributes,
320 ):
321 field_class_ptr = create_func(self._ptr)
322 self._check_field_class_create_status(field_class_ptr, type_name)
323
324 field_class = py_cls._create_from_ptr(field_class_ptr)
325
326 if field_value_range is not None:
327 field_class._field_value_range = field_value_range
328
329 if preferred_display_base is not None:
330 field_class._preferred_display_base = preferred_display_base
331
332 self._set_field_class_user_attrs(field_class, user_attributes)
333 return field_class
334
335 def create_signed_integer_field_class(
336 self, field_value_range=None, preferred_display_base=None, user_attributes=None
337 ):
338 return self._create_integer_field_class(
339 native_bt.field_class_integer_signed_create,
340 bt2_field_class._SignedIntegerFieldClass,
341 "signed integer",
342 field_value_range,
343 preferred_display_base,
344 user_attributes,
345 )
346
347 def create_unsigned_integer_field_class(
348 self, field_value_range=None, preferred_display_base=None, user_attributes=None
349 ):
350 return self._create_integer_field_class(
351 native_bt.field_class_integer_unsigned_create,
352 bt2_field_class._UnsignedIntegerFieldClass,
353 "unsigned integer",
354 field_value_range,
355 preferred_display_base,
356 user_attributes,
357 )
358
359 def create_signed_enumeration_field_class(
360 self, field_value_range=None, preferred_display_base=None, user_attributes=None
361 ):
362 return self._create_integer_field_class(
363 native_bt.field_class_enumeration_signed_create,
364 bt2_field_class._SignedEnumerationFieldClass,
365 "signed enumeration",
366 field_value_range,
367 preferred_display_base,
368 user_attributes,
369 )
370
371 def create_unsigned_enumeration_field_class(
372 self, field_value_range=None, preferred_display_base=None, user_attributes=None
373 ):
374 return self._create_integer_field_class(
375 native_bt.field_class_enumeration_unsigned_create,
376 bt2_field_class._UnsignedEnumerationFieldClass,
377 "unsigned enumeration",
378 field_value_range,
379 preferred_display_base,
380 user_attributes,
381 )
382
383 def create_single_precision_real_field_class(self, user_attributes=None):
384 field_class_ptr = native_bt.field_class_real_single_precision_create(self._ptr)
385 self._check_field_class_create_status(field_class_ptr, "single-precision real")
386
387 field_class = bt2_field_class._SinglePrecisionRealFieldClass._create_from_ptr(
388 field_class_ptr
389 )
390
391 self._set_field_class_user_attrs(field_class, user_attributes)
392
393 return field_class
394
395 def create_double_precision_real_field_class(self, user_attributes=None):
396 field_class_ptr = native_bt.field_class_real_double_precision_create(self._ptr)
397 self._check_field_class_create_status(field_class_ptr, "double-precision real")
398
399 field_class = bt2_field_class._DoublePrecisionRealFieldClass._create_from_ptr(
400 field_class_ptr
401 )
402
403 self._set_field_class_user_attrs(field_class, user_attributes)
404
405 return field_class
406
407 def create_structure_field_class(self, user_attributes=None):
408 field_class_ptr = native_bt.field_class_structure_create(self._ptr)
409 self._check_field_class_create_status(field_class_ptr, "structure")
410 fc = bt2_field_class._StructureFieldClass._create_from_ptr(field_class_ptr)
411 self._set_field_class_user_attrs(fc, user_attributes)
412 return fc
413
414 def create_string_field_class(self, user_attributes=None):
415 field_class_ptr = native_bt.field_class_string_create(self._ptr)
416 self._check_field_class_create_status(field_class_ptr, "string")
417 fc = bt2_field_class._StringFieldClass._create_from_ptr(field_class_ptr)
418 self._set_field_class_user_attrs(fc, user_attributes)
419 return fc
420
421 def create_static_array_field_class(self, elem_fc, length, user_attributes=None):
422 utils._check_type(elem_fc, bt2_field_class._FieldClass)
423 utils._check_uint64(length)
424 ptr = native_bt.field_class_array_static_create(self._ptr, elem_fc._ptr, length)
425 self._check_field_class_create_status(ptr, "static array")
426 fc = bt2_field_class._StaticArrayFieldClass._create_from_ptr(ptr)
427 self._set_field_class_user_attrs(fc, user_attributes)
428 return fc
429
430 def create_dynamic_array_field_class(
431 self, elem_fc, length_fc=None, user_attributes=None
432 ):
433 utils._check_type(elem_fc, bt2_field_class._FieldClass)
434 length_fc_ptr = None
435
436 if length_fc is not None:
437 utils._check_type(length_fc, bt2_field_class._UnsignedIntegerFieldClass)
438 length_fc_ptr = length_fc._ptr
439
440 ptr = native_bt.field_class_array_dynamic_create(
441 self._ptr, elem_fc._ptr, length_fc_ptr
442 )
443 self._check_field_class_create_status(ptr, "dynamic array")
444 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
445 self._set_field_class_user_attrs(fc, user_attributes)
446 return fc
447
448 def create_option_without_selector_field_class(
449 self, content_fc, user_attributes=None
450 ):
451 utils._check_type(content_fc, bt2_field_class._FieldClass)
452 ptr = native_bt.field_class_option_without_selector_create(
453 self._ptr, content_fc._ptr
454 )
455 self._check_field_class_create_status(ptr, "option")
456 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
457 self._set_field_class_user_attrs(fc, user_attributes)
458 return fc
459
460 def create_option_with_bool_selector_field_class(
461 self, content_fc, selector_fc, selector_is_reversed=False, user_attributes=None
462 ):
463 utils._check_type(content_fc, bt2_field_class._FieldClass)
464 utils._check_bool(selector_is_reversed)
465 utils._check_type(selector_fc, bt2_field_class._BoolFieldClass)
466 ptr = native_bt.field_class_option_with_selector_field_bool_create(
467 self._ptr, content_fc._ptr, selector_fc._ptr
468 )
469 self._check_field_class_create_status(ptr, "option")
470 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
471 self._set_field_class_user_attrs(fc, user_attributes)
472 fc._selector_is_reversed = selector_is_reversed
473 return fc
474
475 def create_option_with_integer_selector_field_class(
476 self, content_fc, selector_fc, ranges, user_attributes=None
477 ):
478 utils._check_type(content_fc, bt2_field_class._FieldClass)
479 utils._check_type(selector_fc, bt2_field_class._IntegerFieldClass)
480
481 if len(ranges) == 0:
482 raise ValueError("integer range set is empty")
483
484 if isinstance(selector_fc, bt2_field_class._UnsignedIntegerFieldClass):
485 utils._check_type(ranges, bt2_integer_range_set.UnsignedIntegerRangeSet)
486 ptr = native_bt.field_class_option_with_selector_field_integer_unsigned_create(
487 self._ptr, content_fc._ptr, selector_fc._ptr, ranges._ptr
488 )
489 else:
490 utils._check_type(ranges, bt2_integer_range_set.SignedIntegerRangeSet)
491 ptr = (
492 native_bt.field_class_option_with_selector_field_integer_signed_create(
493 self._ptr, content_fc._ptr, selector_fc._ptr, ranges._ptr
494 )
495 )
496
497 self._check_field_class_create_status(ptr, "option")
498 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
499 self._set_field_class_user_attrs(fc, user_attributes)
500 return fc
501
502 def create_variant_field_class(self, selector_fc=None, user_attributes=None):
503 selector_fc_ptr = None
504
505 if selector_fc is not None:
506 utils._check_type(selector_fc, bt2_field_class._IntegerFieldClass)
507 selector_fc_ptr = selector_fc._ptr
508
509 ptr = native_bt.field_class_variant_create(self._ptr, selector_fc_ptr)
510 self._check_field_class_create_status(ptr, "variant")
511 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
512 self._set_field_class_user_attrs(fc, user_attributes)
513 return fc
This page took 0.042409 seconds and 4 git commands to generate.