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