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