Bump black to version 23
[babeltrace.git] / src / bindings / python / bt2 / bt2 / trace_class.py
CommitLineData
0235b0db 1# SPDX-License-Identifier: MIT
fbbe9302
SM
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>
fbbe9302 6
fbbe9302 7from bt2 import native_bt, utils, object
3fb99a22
PP
8from bt2 import stream_class as bt2_stream_class
9from bt2 import field_class as bt2_field_class
0aa006b7 10from bt2 import integer_range_set as bt2_integer_range_set
3fb99a22 11from bt2 import trace as bt2_trace
5783664e 12from bt2 import value as bt2_value
fbbe9302
SM
13import collections.abc
14import functools
f0a42b33 15import bt2
fbbe9302
SM
16
17
67de22ba
SM
18def _trace_class_destruction_listener_from_native(
19 user_listener, handle, trace_class_ptr
20):
f0a42b33 21 trace_class = _TraceClass._create_from_ptr_and_get_ref(trace_class_ptr)
fbbe9302 22 user_listener(trace_class)
67de22ba 23 handle._invalidate()
fbbe9302
SM
24
25
f0a42b33 26class _TraceClassConst(object._SharedObject, collections.abc.Mapping):
9dee90bd
SM
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
f0a42b33
FD
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 )
2550c437
SM
41 _borrow_user_attributes_ptr = staticmethod(
42 native_bt.trace_class_borrow_user_attributes_const
43 )
f0a42b33
FD
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 )
fbbe9302 48
f0a42b33
FD
49 @property
50 def user_attributes(self):
2550c437 51 ptr = self._borrow_user_attributes_ptr(self._ptr)
f0a42b33
FD
52 assert ptr is not None
53 return self._create_value_from_ptr_and_get_ref(ptr)
8c2367b8 54
fbbe9302
SM
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
f0a42b33 67 sc_ptr = self._borrow_stream_class_ptr_by_id(self._ptr, key)
fbbe9302
SM
68 if sc_ptr is None:
69 raise KeyError(key)
70
f0a42b33 71 return self._stream_class_pycls._create_from_ptr_and_get_ref(sc_ptr)
fbbe9302
SM
72
73 def __iter__(self):
74 for idx in range(len(self)):
f0a42b33 75 sc_ptr = self._borrow_stream_class_ptr_by_index(self._ptr, idx)
fbbe9302
SM
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
f0a42b33
FD
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):
f0a42b33
FD
90 if not callable(listener):
91 raise TypeError("'listener' parameter is not callable")
92
67de22ba
SM
93 handle = utils._ListenerHandle(self.addr)
94
f0a42b33 95 listener_from_native = functools.partial(
67de22ba 96 _trace_class_destruction_listener_from_native, listener, handle
f0a42b33
FD
97 )
98
67de22ba 99 fn = native_bt.bt2_trace_class_add_destruction_listener
f0a42b33
FD
100 status, listener_id = fn(self._ptr, listener_from_native)
101 utils._handle_func_status(
f5567ea8 102 status, "cannot add destruction listener to trace class object"
f0a42b33
FD
103 )
104
67de22ba
SM
105 handle._set_listener_id(listener_id)
106
107 return handle
f0a42b33 108
1114a7d5
SM
109 def remove_destruction_listener(self, listener_handle):
110 utils._check_type(listener_handle, utils._ListenerHandle)
111
67de22ba 112 if listener_handle._addr != self.addr:
1114a7d5 113 raise ValueError(
f5567ea8 114 "This trace class destruction listener does not match the trace class object."
1114a7d5
SM
115 )
116
117 if listener_handle._listener_id is None:
118 raise ValueError(
f5567ea8 119 "This trace class destruction listener was already removed."
1114a7d5
SM
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)
67de22ba 126 listener_handle._invalidate()
1114a7d5 127
f0a42b33
FD
128
129class _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 )
2550c437
SM
136 _borrow_user_attributes_ptr = staticmethod(
137 native_bt.trace_class_borrow_user_attributes
138 )
f0a42b33
FD
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:
f5567ea8 150 raise bt2._MemoryError("cannot create trace class object")
f0a42b33
FD
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
cfbd7cf3
FD
169 def create_stream_class(
170 self,
171 id=None,
172 name=None,
5783664e 173 user_attributes=None,
cfbd7cf3
FD
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 ):
d3bf1370
SM
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 )
fbbe9302
SM
204
205 if self.assigns_automatic_stream_class_id:
206 if id is not None:
cfbd7cf3 207 raise ValueError(
f5567ea8 208 "id provided, but trace class assigns automatic stream class ids"
cfbd7cf3 209 )
fbbe9302
SM
210
211 sc_ptr = native_bt.stream_class_create(self._ptr)
212 else:
213 if id is None:
cfbd7cf3 214 raise ValueError(
f5567ea8 215 "id not provided, but trace class does not assign automatic stream class ids"
cfbd7cf3 216 )
fbbe9302
SM
217
218 utils._check_uint64(id)
219 sc_ptr = native_bt.stream_class_create_with_id(self._ptr, id)
220
3fb99a22 221 sc = bt2_stream_class._StreamClass._create_from_ptr(sc_ptr)
8c2367b8 222
3cdfbaea
SM
223 if name is not None:
224 sc._name = name
225
5783664e
PP
226 if user_attributes is not None:
227 sc._user_attributes = user_attributes
228
3cdfbaea
SM
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
26fc5aed
PP
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.
cfbd7cf3
FD
239 sc._set_supports_packets(
240 supports_packets,
241 packets_have_beginning_default_clock_snapshot,
242 packets_have_end_default_clock_snapshot,
243 )
26fc5aed
PP
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
3cdfbaea 251 sc._assigns_automatic_event_class_id = assigns_automatic_event_class_id
8c2367b8 252 sc._assigns_automatic_stream_id = assigns_automatic_stream_id
cfbd7cf3
FD
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 )
8c2367b8 259 return sc
fbbe9302 260
5783664e
PP
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
fbbe9302
SM
268 def _assigns_automatic_stream_class_id(self, auto_id):
269 utils._check_bool(auto_id)
cfbd7cf3
FD
270 return native_bt.trace_class_set_assigns_automatic_stream_class_id(
271 self._ptr, auto_id
272 )
fbbe9302 273
cfbd7cf3
FD
274 _assigns_automatic_stream_class_id = property(
275 fset=_assigns_automatic_stream_class_id
276 )
fbbe9302 277
3cdfbaea
SM
278 # Field class creation methods.
279
aae30e61 280 def _check_field_class_create_status(self, ptr, type_name):
3cdfbaea 281 if ptr is None:
f5567ea8 282 raise bt2._MemoryError("cannot create {} field class".format(type_name))
3cdfbaea 283
5783664e
PP
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):
aae30e61 290 field_class_ptr = native_bt.field_class_bool_create(self._ptr)
f5567ea8 291 self._check_field_class_create_status(field_class_ptr, "boolean")
5783664e
PP
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
aae30e61 295
5783664e 296 def create_bit_array_field_class(self, length, user_attributes=None):
ead8c3d4
PP
297 utils._check_uint64(length)
298
299 if length < 1 or length > 64:
300 raise ValueError(
f5567ea8 301 "invalid length {}: expecting a value in the [1, 64] range".format(
ead8c3d4
PP
302 length
303 )
304 )
305
306 field_class_ptr = native_bt.field_class_bit_array_create(self._ptr, length)
f5567ea8 307 self._check_field_class_create_status(field_class_ptr, "bit array")
5783664e
PP
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
ead8c3d4 311
cfbd7cf3 312 def _create_integer_field_class(
5783664e
PP
313 self,
314 create_func,
315 py_cls,
316 type_name,
317 field_value_range,
318 preferred_display_base,
319 user_attributes,
cfbd7cf3 320 ):
af4bbfc7 321 field_class_ptr = create_func(self._ptr)
aae30e61 322 self._check_field_class_create_status(field_class_ptr, type_name)
af4bbfc7
SM
323
324 field_class = py_cls._create_from_ptr(field_class_ptr)
325
d47b87ac
SM
326 if field_value_range is not None:
327 field_class._field_value_range = field_value_range
af4bbfc7 328
d47b87ac
SM
329 if preferred_display_base is not None:
330 field_class._preferred_display_base = preferred_display_base
af4bbfc7 331
5783664e 332 self._set_field_class_user_attrs(field_class, user_attributes)
af4bbfc7
SM
333 return field_class
334
cfbd7cf3 335 def create_signed_integer_field_class(
5783664e 336 self, field_value_range=None, preferred_display_base=None, user_attributes=None
cfbd7cf3
FD
337 ):
338 return self._create_integer_field_class(
9c08c816 339 native_bt.field_class_integer_signed_create,
3fb99a22 340 bt2_field_class._SignedIntegerFieldClass,
f5567ea8 341 "signed integer",
cfbd7cf3
FD
342 field_value_range,
343 preferred_display_base,
5783664e 344 user_attributes,
cfbd7cf3
FD
345 )
346
347 def create_unsigned_integer_field_class(
5783664e 348 self, field_value_range=None, preferred_display_base=None, user_attributes=None
cfbd7cf3
FD
349 ):
350 return self._create_integer_field_class(
9c08c816 351 native_bt.field_class_integer_unsigned_create,
3fb99a22 352 bt2_field_class._UnsignedIntegerFieldClass,
f5567ea8 353 "unsigned integer",
cfbd7cf3
FD
354 field_value_range,
355 preferred_display_base,
5783664e 356 user_attributes,
cfbd7cf3
FD
357 )
358
359 def create_signed_enumeration_field_class(
5783664e 360 self, field_value_range=None, preferred_display_base=None, user_attributes=None
cfbd7cf3
FD
361 ):
362 return self._create_integer_field_class(
9c08c816 363 native_bt.field_class_enumeration_signed_create,
3fb99a22 364 bt2_field_class._SignedEnumerationFieldClass,
f5567ea8 365 "signed enumeration",
cfbd7cf3
FD
366 field_value_range,
367 preferred_display_base,
5783664e 368 user_attributes,
cfbd7cf3
FD
369 )
370
371 def create_unsigned_enumeration_field_class(
5783664e 372 self, field_value_range=None, preferred_display_base=None, user_attributes=None
cfbd7cf3
FD
373 ):
374 return self._create_integer_field_class(
9c08c816 375 native_bt.field_class_enumeration_unsigned_create,
3fb99a22 376 bt2_field_class._UnsignedEnumerationFieldClass,
f5567ea8 377 "unsigned enumeration",
cfbd7cf3
FD
378 field_value_range,
379 preferred_display_base,
5783664e 380 user_attributes,
cfbd7cf3 381 )
2ae9f48c 382
fe4df857
FD
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)
f5567ea8 385 self._check_field_class_create_status(field_class_ptr, "single-precision real")
2ae9f48c 386
fe4df857
FD
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)
f5567ea8 397 self._check_field_class_create_status(field_class_ptr, "double-precision real")
fe4df857
FD
398
399 field_class = bt2_field_class._DoublePrecisionRealFieldClass._create_from_ptr(
400 field_class_ptr
401 )
2ae9f48c 402
5783664e 403 self._set_field_class_user_attrs(field_class, user_attributes)
2ae9f48c
SM
404
405 return field_class
406
5783664e 407 def create_structure_field_class(self, user_attributes=None):
3cdfbaea 408 field_class_ptr = native_bt.field_class_structure_create(self._ptr)
f5567ea8 409 self._check_field_class_create_status(field_class_ptr, "structure")
5783664e
PP
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
3cdfbaea 413
5783664e 414 def create_string_field_class(self, user_attributes=None):
3cdfbaea 415 field_class_ptr = native_bt.field_class_string_create(self._ptr)
f5567ea8 416 self._check_field_class_create_status(field_class_ptr, "string")
5783664e
PP
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
3cdfbaea 420
5783664e 421 def create_static_array_field_class(self, elem_fc, length, user_attributes=None):
3fb99a22 422 utils._check_type(elem_fc, bt2_field_class._FieldClass)
d47b87ac 423 utils._check_uint64(length)
9c08c816 424 ptr = native_bt.field_class_array_static_create(self._ptr, elem_fc._ptr, length)
f5567ea8 425 self._check_field_class_create_status(ptr, "static array")
2bebdd7f 426 fc = bt2_field_class._StaticArrayFieldClass._create_from_ptr(ptr)
5783664e
PP
427 self._set_field_class_user_attrs(fc, user_attributes)
428 return fc
d47b87ac 429
5783664e
PP
430 def create_dynamic_array_field_class(
431 self, elem_fc, length_fc=None, user_attributes=None
432 ):
3fb99a22 433 utils._check_type(elem_fc, bt2_field_class._FieldClass)
1367bc7c 434 length_fc_ptr = None
d47b87ac
SM
435
436 if length_fc is not None:
3fb99a22 437 utils._check_type(length_fc, bt2_field_class._UnsignedIntegerFieldClass)
1367bc7c 438 length_fc_ptr = length_fc._ptr
d47b87ac 439
9c08c816 440 ptr = native_bt.field_class_array_dynamic_create(
cfbd7cf3
FD
441 self._ptr, elem_fc._ptr, length_fc_ptr
442 )
f5567ea8 443 self._check_field_class_create_status(ptr, "dynamic array")
2bebdd7f 444 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
5783664e
PP
445 self._set_field_class_user_attrs(fc, user_attributes)
446 return fc
d47b87ac 447
0aa006b7
PP
448 def create_option_without_selector_field_class(
449 self, content_fc, user_attributes=None
5783664e 450 ):
cec0261d 451 utils._check_type(content_fc, bt2_field_class._FieldClass)
0aa006b7
PP
452 ptr = native_bt.field_class_option_without_selector_create(
453 self._ptr, content_fc._ptr
454 )
f5567ea8 455 self._check_field_class_create_status(ptr, "option")
2bebdd7f 456 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
0aa006b7
PP
457 self._set_field_class_user_attrs(fc, user_attributes)
458 return fc
cec0261d 459
0aa006b7
PP
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)
de821fe5 466 ptr = native_bt.field_class_option_with_selector_field_bool_create(
0aa006b7
PP
467 self._ptr, content_fc._ptr, selector_fc._ptr
468 )
f5567ea8 469 self._check_field_class_create_status(ptr, "option")
2bebdd7f 470 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
0aa006b7
PP
471 self._set_field_class_user_attrs(fc, user_attributes)
472 fc._selector_is_reversed = selector_is_reversed
473 return fc
cec0261d 474
0aa006b7
PP
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:
f5567ea8 482 raise ValueError("integer range set is empty")
0aa006b7
PP
483
484 if isinstance(selector_fc, bt2_field_class._UnsignedIntegerFieldClass):
485 utils._check_type(ranges, bt2_integer_range_set.UnsignedIntegerRangeSet)
de821fe5 486 ptr = native_bt.field_class_option_with_selector_field_integer_unsigned_create(
0aa006b7
PP
487 self._ptr, content_fc._ptr, selector_fc._ptr, ranges._ptr
488 )
489 else:
490 utils._check_type(ranges, bt2_integer_range_set.SignedIntegerRangeSet)
776a2a25
PP
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 )
0aa006b7 495 )
cec0261d 496
f5567ea8 497 self._check_field_class_create_status(ptr, "option")
2bebdd7f 498 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
5783664e
PP
499 self._set_field_class_user_attrs(fc, user_attributes)
500 return fc
cec0261d 501
5783664e 502 def create_variant_field_class(self, selector_fc=None, user_attributes=None):
45c51519 503 selector_fc_ptr = None
d47b87ac
SM
504
505 if selector_fc is not None:
3fb99a22 506 utils._check_type(selector_fc, bt2_field_class._IntegerFieldClass)
45c51519 507 selector_fc_ptr = selector_fc._ptr
d47b87ac 508
45c51519 509 ptr = native_bt.field_class_variant_create(self._ptr, selector_fc_ptr)
f5567ea8 510 self._check_field_class_create_status(ptr, "variant")
2bebdd7f 511 fc = bt2_field_class._obj_type_from_field_class_ptr(ptr)._create_from_ptr(ptr)
5783664e
PP
512 self._set_field_class_user_attrs(fc, user_attributes)
513 return fc
This page took 0.091382 seconds and 4 git commands to generate.