bt2: Add `_Clock*Const` classes and adapt tests
[babeltrace.git] / src / bindings / python / bt2 / bt2 / trace_class.py
CommitLineData
0bee8ea9
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
78668ecd 25__all__ = ['_TraceClass']
0bee8ea9
SM
26
27import bt2
28from bt2 import native_bt, utils, object
c946c9de
PP
29from bt2 import stream_class as bt2_stream_class
30from bt2 import field_class as bt2_field_class
31from bt2 import trace as bt2_trace
32from bt2 import trace_class as bt2_trace_class
b2df5780 33from bt2 import value as bt2_value
0bee8ea9
SM
34import collections.abc
35import functools
36
37
0bee8ea9 38def _trace_class_destruction_listener_from_native(user_listener, trace_class_ptr):
c946c9de 39 trace_class = bt2_trace_class._TraceClass._create_from_ptr_and_get_ref(
61d96b89
FD
40 trace_class_ptr
41 )
0bee8ea9
SM
42 user_listener(trace_class)
43
44
78668ecd 45class _TraceClass(object._SharedObject, collections.abc.Mapping):
0bee8ea9
SM
46 _get_ref = staticmethod(native_bt.trace_class_get_ref)
47 _put_ref = staticmethod(native_bt.trace_class_put_ref)
48
f377a958
SM
49 # Instantiate a trace of this class.
50
3f1a6e26 51 def __call__(self, name=None, user_attributes=None, uuid=None, environment=None):
f377a958
SM
52 trace_ptr = native_bt.trace_create(self._ptr)
53
54 if trace_ptr is None:
614743a5 55 raise bt2._MemoryError('cannot create trace class object')
f377a958 56
c946c9de 57 trace = bt2_trace._Trace._create_from_ptr(trace_ptr)
f377a958
SM
58
59 if name is not None:
60 trace._name = name
61
b2df5780
PP
62 if user_attributes is not None:
63 trace._user_attributes = user_attributes
64
cd03c43c
PP
65 if uuid is not None:
66 trace._uuid = uuid
67
3f1a6e26
PP
68 if environment is not None:
69 for key, value in environment.items():
70 trace.environment[key] = value
cd03c43c 71
f377a958
SM
72 return trace
73
0bee8ea9
SM
74 # Number of stream classes in this trace class.
75
76 def __len__(self):
77 count = native_bt.trace_class_get_stream_class_count(self._ptr)
78 assert count >= 0
79 return count
80
81 # Get a stream class by stream id.
82
83 def __getitem__(self, key):
84 utils._check_uint64(key)
85
86 sc_ptr = native_bt.trace_class_borrow_stream_class_by_id_const(self._ptr, key)
87 if sc_ptr is None:
88 raise KeyError(key)
89
c946c9de 90 return bt2_stream_class._StreamClass._create_from_ptr_and_get_ref(sc_ptr)
0bee8ea9
SM
91
92 def __iter__(self):
93 for idx in range(len(self)):
61d96b89
FD
94 sc_ptr = native_bt.trace_class_borrow_stream_class_by_index_const(
95 self._ptr, idx
96 )
0bee8ea9
SM
97 assert sc_ptr is not None
98
99 id = native_bt.stream_class_get_id(sc_ptr)
100 assert id >= 0
101
102 yield id
103
61d96b89
FD
104 def create_stream_class(
105 self,
106 id=None,
107 name=None,
b2df5780 108 user_attributes=None,
61d96b89
FD
109 packet_context_field_class=None,
110 event_common_context_field_class=None,
111 default_clock_class=None,
112 assigns_automatic_event_class_id=True,
113 assigns_automatic_stream_id=True,
114 supports_packets=False,
115 packets_have_beginning_default_clock_snapshot=False,
116 packets_have_end_default_clock_snapshot=False,
117 supports_discarded_events=False,
118 discarded_events_have_default_clock_snapshots=False,
119 supports_discarded_packets=False,
120 discarded_packets_have_default_clock_snapshots=False,
121 ):
0bee8ea9
SM
122
123 if self.assigns_automatic_stream_class_id:
124 if id is not None:
61d96b89
FD
125 raise ValueError(
126 'id provided, but trace class assigns automatic stream class ids'
127 )
0bee8ea9
SM
128
129 sc_ptr = native_bt.stream_class_create(self._ptr)
130 else:
131 if id is None:
61d96b89
FD
132 raise ValueError(
133 'id not provided, but trace class does not assign automatic stream class ids'
134 )
0bee8ea9
SM
135
136 utils._check_uint64(id)
137 sc_ptr = native_bt.stream_class_create_with_id(self._ptr, id)
138
c946c9de 139 sc = bt2_stream_class._StreamClass._create_from_ptr(sc_ptr)
f377a958 140
060aee52
SM
141 if name is not None:
142 sc._name = name
143
b2df5780
PP
144 if user_attributes is not None:
145 sc._user_attributes = user_attributes
146
060aee52
SM
147 if event_common_context_field_class is not None:
148 sc._event_common_context_field_class = event_common_context_field_class
149
150 if default_clock_class is not None:
151 sc._default_clock_class = default_clock_class
152
37a93d41
PP
153 # call after `sc._default_clock_class` because, if
154 # `packets_have_beginning_default_clock_snapshot` or
155 # `packets_have_end_default_clock_snapshot` is true, then this
156 # stream class needs a default clock class already.
61d96b89
FD
157 sc._set_supports_packets(
158 supports_packets,
159 packets_have_beginning_default_clock_snapshot,
160 packets_have_end_default_clock_snapshot,
161 )
37a93d41
PP
162
163 # call after sc._set_supports_packets() because, if
164 # `packet_context_field_class` is not `None`, then this stream
165 # class needs to support packets already.
166 if packet_context_field_class is not None:
167 sc._packet_context_field_class = packet_context_field_class
168
060aee52 169 sc._assigns_automatic_event_class_id = assigns_automatic_event_class_id
f377a958 170 sc._assigns_automatic_stream_id = assigns_automatic_stream_id
61d96b89
FD
171 sc._set_supports_discarded_events(
172 supports_discarded_events, discarded_events_have_default_clock_snapshots
173 )
174 sc._set_supports_discarded_packets(
175 supports_discarded_packets, discarded_packets_have_default_clock_snapshots
176 )
f377a958 177 return sc
0bee8ea9 178
b2df5780
PP
179 @property
180 def user_attributes(self):
181 ptr = native_bt.trace_class_borrow_user_attributes(self._ptr)
182 assert ptr is not None
183 return bt2_value._create_from_ptr_and_get_ref(ptr)
184
185 def _user_attributes(self, user_attributes):
186 value = bt2_value.create_value(user_attributes)
187 utils._check_type(value, bt2_value.MapValue)
188 native_bt.trace_class_set_user_attributes(self._ptr, value._ptr)
189
190 _user_attributes = property(fset=_user_attributes)
191
0bee8ea9
SM
192 @property
193 def assigns_automatic_stream_class_id(self):
194 return native_bt.trace_class_assigns_automatic_stream_class_id(self._ptr)
195
196 def _assigns_automatic_stream_class_id(self, auto_id):
197 utils._check_bool(auto_id)
61d96b89
FD
198 return native_bt.trace_class_set_assigns_automatic_stream_class_id(
199 self._ptr, auto_id
200 )
0bee8ea9 201
61d96b89
FD
202 _assigns_automatic_stream_class_id = property(
203 fset=_assigns_automatic_stream_class_id
204 )
0bee8ea9 205
060aee52
SM
206 # Field class creation methods.
207
a07f15cb 208 def _check_field_class_create_status(self, ptr, type_name):
060aee52 209 if ptr is None:
614743a5 210 raise bt2._MemoryError('cannot create {} field class'.format(type_name))
060aee52 211
b2df5780
PP
212 @staticmethod
213 def _set_field_class_user_attrs(fc, user_attributes):
214 if user_attributes is not None:
215 fc._user_attributes = user_attributes
216
217 def create_bool_field_class(self, user_attributes=None):
a07f15cb
PP
218 field_class_ptr = native_bt.field_class_bool_create(self._ptr)
219 self._check_field_class_create_status(field_class_ptr, 'boolean')
b2df5780
PP
220 fc = bt2_field_class._BoolFieldClass._create_from_ptr(field_class_ptr)
221 self._set_field_class_user_attrs(fc, user_attributes)
222 return fc
a07f15cb 223
b2df5780 224 def create_bit_array_field_class(self, length, user_attributes=None):
6b29f2d4
PP
225 utils._check_uint64(length)
226
227 if length < 1 or length > 64:
228 raise ValueError(
229 'invalid length {}: expecting a value in the [1, 64] range'.format(
230 length
231 )
232 )
233
234 field_class_ptr = native_bt.field_class_bit_array_create(self._ptr, length)
235 self._check_field_class_create_status(field_class_ptr, 'bit array')
b2df5780
PP
236 fc = bt2_field_class._BitArrayFieldClass._create_from_ptr(field_class_ptr)
237 self._set_field_class_user_attrs(fc, user_attributes)
238 return fc
6b29f2d4 239
61d96b89 240 def _create_integer_field_class(
b2df5780
PP
241 self,
242 create_func,
243 py_cls,
244 type_name,
245 field_value_range,
246 preferred_display_base,
247 user_attributes,
61d96b89 248 ):
a728f6c3 249 field_class_ptr = create_func(self._ptr)
a07f15cb 250 self._check_field_class_create_status(field_class_ptr, type_name)
a728f6c3
SM
251
252 field_class = py_cls._create_from_ptr(field_class_ptr)
253
c8820b76
SM
254 if field_value_range is not None:
255 field_class._field_value_range = field_value_range
a728f6c3 256
c8820b76
SM
257 if preferred_display_base is not None:
258 field_class._preferred_display_base = preferred_display_base
a728f6c3 259
b2df5780 260 self._set_field_class_user_attrs(field_class, user_attributes)
a728f6c3
SM
261 return field_class
262
61d96b89 263 def create_signed_integer_field_class(
b2df5780 264 self, field_value_range=None, preferred_display_base=None, user_attributes=None
61d96b89
FD
265 ):
266 return self._create_integer_field_class(
60bbfc7c 267 native_bt.field_class_integer_signed_create,
c946c9de 268 bt2_field_class._SignedIntegerFieldClass,
61d96b89
FD
269 'signed integer',
270 field_value_range,
271 preferred_display_base,
b2df5780 272 user_attributes,
61d96b89
FD
273 )
274
275 def create_unsigned_integer_field_class(
b2df5780 276 self, field_value_range=None, preferred_display_base=None, user_attributes=None
61d96b89
FD
277 ):
278 return self._create_integer_field_class(
60bbfc7c 279 native_bt.field_class_integer_unsigned_create,
c946c9de 280 bt2_field_class._UnsignedIntegerFieldClass,
61d96b89
FD
281 'unsigned integer',
282 field_value_range,
283 preferred_display_base,
b2df5780 284 user_attributes,
61d96b89
FD
285 )
286
287 def create_signed_enumeration_field_class(
b2df5780 288 self, field_value_range=None, preferred_display_base=None, user_attributes=None
61d96b89
FD
289 ):
290 return self._create_integer_field_class(
60bbfc7c 291 native_bt.field_class_enumeration_signed_create,
c946c9de 292 bt2_field_class._SignedEnumerationFieldClass,
61d96b89
FD
293 'signed enumeration',
294 field_value_range,
295 preferred_display_base,
b2df5780 296 user_attributes,
61d96b89
FD
297 )
298
299 def create_unsigned_enumeration_field_class(
b2df5780 300 self, field_value_range=None, preferred_display_base=None, user_attributes=None
61d96b89
FD
301 ):
302 return self._create_integer_field_class(
60bbfc7c 303 native_bt.field_class_enumeration_unsigned_create,
c946c9de 304 bt2_field_class._UnsignedEnumerationFieldClass,
61d96b89
FD
305 'unsigned enumeration',
306 field_value_range,
307 preferred_display_base,
b2df5780 308 user_attributes,
61d96b89 309 )
27d97a3f 310
b2df5780 311 def create_real_field_class(self, is_single_precision=False, user_attributes=None):
27d97a3f 312 field_class_ptr = native_bt.field_class_real_create(self._ptr)
a07f15cb 313 self._check_field_class_create_status(field_class_ptr, 'real')
27d97a3f 314
c946c9de 315 field_class = bt2_field_class._RealFieldClass._create_from_ptr(field_class_ptr)
27d97a3f 316
c8820b76 317 field_class._is_single_precision = is_single_precision
b2df5780 318 self._set_field_class_user_attrs(field_class, user_attributes)
27d97a3f
SM
319
320 return field_class
321
b2df5780 322 def create_structure_field_class(self, user_attributes=None):
060aee52 323 field_class_ptr = native_bt.field_class_structure_create(self._ptr)
a07f15cb 324 self._check_field_class_create_status(field_class_ptr, 'structure')
b2df5780
PP
325 fc = bt2_field_class._StructureFieldClass._create_from_ptr(field_class_ptr)
326 self._set_field_class_user_attrs(fc, user_attributes)
327 return fc
060aee52 328
b2df5780 329 def create_string_field_class(self, user_attributes=None):
060aee52 330 field_class_ptr = native_bt.field_class_string_create(self._ptr)
a07f15cb 331 self._check_field_class_create_status(field_class_ptr, 'string')
b2df5780
PP
332 fc = bt2_field_class._StringFieldClass._create_from_ptr(field_class_ptr)
333 self._set_field_class_user_attrs(fc, user_attributes)
334 return fc
060aee52 335
b2df5780 336 def create_static_array_field_class(self, elem_fc, length, user_attributes=None):
c946c9de 337 utils._check_type(elem_fc, bt2_field_class._FieldClass)
c8820b76 338 utils._check_uint64(length)
60bbfc7c 339 ptr = native_bt.field_class_array_static_create(self._ptr, elem_fc._ptr, length)
a07f15cb 340 self._check_field_class_create_status(ptr, 'static array')
b2df5780
PP
341 fc = bt2_field_class._StaticArrayFieldClass._create_from_ptr_and_get_ref(ptr)
342 self._set_field_class_user_attrs(fc, user_attributes)
343 return fc
c8820b76 344
b2df5780
PP
345 def create_dynamic_array_field_class(
346 self, elem_fc, length_fc=None, user_attributes=None
347 ):
c946c9de 348 utils._check_type(elem_fc, bt2_field_class._FieldClass)
93d7d5d1 349 length_fc_ptr = None
c8820b76
SM
350
351 if length_fc is not None:
c946c9de 352 utils._check_type(length_fc, bt2_field_class._UnsignedIntegerFieldClass)
93d7d5d1 353 length_fc_ptr = length_fc._ptr
c8820b76 354
60bbfc7c 355 ptr = native_bt.field_class_array_dynamic_create(
61d96b89
FD
356 self._ptr, elem_fc._ptr, length_fc_ptr
357 )
a07f15cb 358 self._check_field_class_create_status(ptr, 'dynamic array')
b2df5780
PP
359 fc = bt2_field_class._DynamicArrayFieldClass._create_from_ptr(ptr)
360 self._set_field_class_user_attrs(fc, user_attributes)
361 return fc
c8820b76 362
b2df5780
PP
363 def create_option_field_class(
364 self, content_fc, selector_fc=None, user_attributes=None
365 ):
84eba0d9
PP
366 utils._check_type(content_fc, bt2_field_class._FieldClass)
367
368 selector_fc_ptr = None
369
370 if selector_fc is not None:
371 utils._check_type(selector_fc, bt2_field_class._BoolFieldClass)
372 selector_fc_ptr = selector_fc._ptr
373
374 ptr = native_bt.field_class_option_create(
375 self._ptr, content_fc._ptr, selector_fc_ptr
376 )
377 self._check_field_class_create_status(ptr, 'option')
b2df5780
PP
378 fc = bt2_field_class._create_field_class_from_ptr_and_get_ref(ptr)
379 self._set_field_class_user_attrs(fc, user_attributes)
380 return fc
84eba0d9 381
b2df5780 382 def create_variant_field_class(self, selector_fc=None, user_attributes=None):
02b61fe0 383 selector_fc_ptr = None
c8820b76
SM
384
385 if selector_fc is not None:
c946c9de 386 utils._check_type(selector_fc, bt2_field_class._IntegerFieldClass)
02b61fe0 387 selector_fc_ptr = selector_fc._ptr
c8820b76 388
02b61fe0 389 ptr = native_bt.field_class_variant_create(self._ptr, selector_fc_ptr)
a07f15cb 390 self._check_field_class_create_status(ptr, 'variant')
b2df5780
PP
391 fc = bt2_field_class._create_field_class_from_ptr_and_get_ref(ptr)
392 self._set_field_class_user_attrs(fc, user_attributes)
393 return fc
060aee52 394
0bee8ea9
SM
395 # Add a listener to be called when the trace class is destroyed.
396
397 def add_destruction_listener(self, listener):
398
399 if not callable(listener):
400 raise TypeError("'listener' parameter is not callable")
401
fb25b9e3 402 fn = native_bt.bt2_trace_class_add_destruction_listener
61d96b89
FD
403 listener_from_native = functools.partial(
404 _trace_class_destruction_listener_from_native, listener
405 )
0bee8ea9 406
48e95b3d
SM
407 status, listener_id = fn(self._ptr, listener_from_native)
408 utils._handle_func_status(
409 status, 'cannot add destruction listener to trace class object'
410 )
0bee8ea9 411
c946c9de 412 return utils._ListenerHandle(listener_id, self)
This page took 0.05283 seconds and 4 git commands to generate.