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