bt2: prepend `_` prefix to names of classes that the user cannot create
[babeltrace.git] / 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
2c6f8520 25__all__ = ['_TraceClass']
fbbe9302
SM
26
27import bt2
28from bt2 import native_bt, utils, object
2c6f8520 29import bt2.stream_class
fbbe9302
SM
30import uuid as uuidp
31import collections.abc
32import functools
33
34
35class _TraceClassEnv(collections.abc.MutableMapping):
36 def __init__(self, trace_class):
37 self._trace_class = trace_class
38
39 def __getitem__(self, key):
40 utils._check_str(key)
41
42 borrow_entry_fn = native_bt.trace_class_borrow_environment_entry_value_by_name_const
43 value_ptr = borrow_entry_fn(self._trace_class._ptr, key)
44
45 if value_ptr is None:
46 raise KeyError(key)
47
48 return bt2.value._create_from_ptr_and_get_ref(value_ptr)
49
50 def __setitem__(self, key, value):
51 if isinstance(value, str):
52 set_env_entry_fn = native_bt.trace_class_set_environment_entry_string
53 elif isinstance(value, int):
54 set_env_entry_fn = native_bt.trace_class_set_environment_entry_integer
55 else:
56 raise TypeError('expected str or int, got {}'.format(type(value)))
57
58 ret = set_env_entry_fn(self._trace_class._ptr, key, value)
59
60 utils._handle_ret(ret, "cannot set trace class object's environment entry")
61
62 def __delitem__(self, key):
63 raise NotImplementedError
64
65 def __len__(self):
66 count = native_bt.trace_class_get_environment_entry_count(self._trace_class._ptr)
67 assert count >= 0
68 return count
69
70 def __iter__(self):
71 trace_class_ptr = self._trace_class_env._trace_class._ptr
72
73 for idx in range(len(self)):
74 borrow_entry_fn = native_bt.trace_class_borrow_environment_entry_by_index_const
75 entry_name, _ = borrow_entry_fn(trace_class_ptr, idx)
76 assert entry_name is not None
77 yield entry_name
78
79
80class _StreamClassIterator(collections.abc.Iterator):
81 def __init__(self, trace_class):
82 self._trace_class = trace_class
83 self._at = 0
84
85 def __next__(self):
86 if self._at == len(self._trace_class):
87 raise StopIteration
88
89 borrow_stream_class_fn = native_bt.trace_class_borrow_stream_class_by_index_const
90 sc_ptr = borrow_stream_class_fn(self._trace_class._ptr, self._at)
91 assert sc_ptr
92 id = native_bt.stream_class_get_id(sc_ptr)
93 assert id >= 0
94 self._at += 1
95 return id
96
97
98def _trace_class_destruction_listener_from_native(user_listener, trace_class_ptr):
2c6f8520 99 trace_class = bt2.trace_class._TraceClass._create_from_ptr_and_get_ref(trace_class_ptr)
fbbe9302
SM
100 user_listener(trace_class)
101
102
2c6f8520 103class _TraceClass(object._SharedObject, collections.abc.Mapping):
fbbe9302
SM
104 _get_ref = staticmethod(native_bt.trace_class_get_ref)
105 _put_ref = staticmethod(native_bt.trace_class_put_ref)
106
107 @property
108 def uuid(self):
109 uuid_bytes = native_bt.trace_class_get_uuid(self._ptr)
110 if uuid_bytes is None:
111 return
112
113 return uuidp.UUID(bytes=uuid_bytes)
114
115 def _uuid(self, uuid):
116 utils._check_type(uuid, uuidp.UUID)
117 native_bt.trace_class_set_uuid(self._ptr, uuid.bytes)
118
119 _uuid = property(fset=_uuid)
120
8c2367b8
SM
121 # Instantiate a trace of this class.
122
123 def __call__(self, name=None):
124 trace_ptr = native_bt.trace_create(self._ptr)
125
126 if trace_ptr is None:
127 raise bt2.CreationError('cannot create trace class object')
128
2c6f8520 129 trace = bt2.trace._Trace._create_from_ptr(trace_ptr)
8c2367b8
SM
130
131 if name is not None:
132 trace._name = name
133
134 return trace
135
fbbe9302
SM
136 # Number of stream classes in this trace class.
137
138 def __len__(self):
139 count = native_bt.trace_class_get_stream_class_count(self._ptr)
140 assert count >= 0
141 return count
142
143 # Get a stream class by stream id.
144
145 def __getitem__(self, key):
146 utils._check_uint64(key)
147
148 sc_ptr = native_bt.trace_class_borrow_stream_class_by_id_const(self._ptr, key)
149 if sc_ptr is None:
150 raise KeyError(key)
151
2c6f8520 152 return bt2.stream_class._StreamClass._create_from_ptr_and_get_ref(sc_ptr)
fbbe9302
SM
153
154 def __iter__(self):
155 for idx in range(len(self)):
156 sc_ptr = native_bt.trace_class_borrow_stream_class_by_index_const(self._ptr, idx)
157 assert sc_ptr is not None
158
159 id = native_bt.stream_class_get_id(sc_ptr)
160 assert id >= 0
161
162 yield id
163
164 @property
165 def env(self):
166 return _TraceClassEnv(self)
167
8c2367b8 168 def create_stream_class(self, id=None,
3cdfbaea
SM
169 name=None,
170 packet_context_field_class=None,
171 event_common_context_field_class=None,
172 default_clock_class=None,
173 assigns_automatic_event_class_id=True,
174 assigns_automatic_stream_id=True,
9b24b6aa
PP
175 packets_have_beginning_default_clock_snapshot=False,
176 packets_have_end_default_clock_snapshot=False,
2e90378a
PP
177 supports_discarded_events=False,
178 discarded_events_have_default_clock_snapshots=False,
179 supports_discarded_packets=False,
180 discarded_packets_have_default_clock_snapshots=False):
fbbe9302
SM
181
182 if self.assigns_automatic_stream_class_id:
183 if id is not None:
4430bc80 184 raise ValueError('id provided, but trace class assigns automatic stream class ids')
fbbe9302
SM
185
186 sc_ptr = native_bt.stream_class_create(self._ptr)
187 else:
188 if id is None:
4430bc80 189 raise ValueError('id not provided, but trace class does not assign automatic stream class ids')
fbbe9302
SM
190
191 utils._check_uint64(id)
192 sc_ptr = native_bt.stream_class_create_with_id(self._ptr, id)
193
2c6f8520 194 sc = bt2.stream_class._StreamClass._create_from_ptr(sc_ptr)
8c2367b8 195
3cdfbaea
SM
196 if name is not None:
197 sc._name = name
198
199 if packet_context_field_class is not None:
200 sc._packet_context_field_class = packet_context_field_class
201
202 if event_common_context_field_class is not None:
203 sc._event_common_context_field_class = event_common_context_field_class
204
205 if default_clock_class is not None:
206 sc._default_clock_class = default_clock_class
207
208 sc._assigns_automatic_event_class_id = assigns_automatic_event_class_id
8c2367b8 209 sc._assigns_automatic_stream_id = assigns_automatic_stream_id
9b24b6aa
PP
210 sc._packets_have_beginning_default_clock_snapshot = packets_have_beginning_default_clock_snapshot
211 sc._packets_have_end_default_clock_snapshot = packets_have_end_default_clock_snapshot
2e90378a
PP
212 sc._set_supports_discarded_events(supports_discarded_events,
213 discarded_events_have_default_clock_snapshots)
214 sc._set_supports_discarded_packets(supports_discarded_packets,
215 discarded_packets_have_default_clock_snapshots)
8c2367b8 216 return sc
fbbe9302
SM
217
218 @property
219 def assigns_automatic_stream_class_id(self):
220 return native_bt.trace_class_assigns_automatic_stream_class_id(self._ptr)
221
222 def _assigns_automatic_stream_class_id(self, auto_id):
223 utils._check_bool(auto_id)
224 return native_bt.trace_class_set_assigns_automatic_stream_class_id(self._ptr, auto_id)
225
226 _assigns_automatic_stream_class_id = property(fset=_assigns_automatic_stream_class_id)
227
3cdfbaea
SM
228 # Field class creation methods.
229
230 def _check_create_status(self, ptr, type_name):
231 if ptr is None:
232 raise bt2.CreationError(
233 'cannot create {} field class'.format(type_name))
234
d47b87ac 235 def _create_integer_field_class(self, create_func, py_cls, type_name, field_value_range, preferred_display_base):
af4bbfc7
SM
236 field_class_ptr = create_func(self._ptr)
237 self._check_create_status(field_class_ptr, type_name)
238
239 field_class = py_cls._create_from_ptr(field_class_ptr)
240
d47b87ac
SM
241 if field_value_range is not None:
242 field_class._field_value_range = field_value_range
af4bbfc7 243
d47b87ac
SM
244 if preferred_display_base is not None:
245 field_class._preferred_display_base = preferred_display_base
af4bbfc7
SM
246
247 return field_class
248
d47b87ac 249 def create_signed_integer_field_class(self, field_value_range=None, preferred_display_base=None):
af4bbfc7 250 return self._create_integer_field_class(native_bt.field_class_signed_integer_create,
d47b87ac
SM
251 bt2.field_class._SignedIntegerFieldClass,
252 'signed integer', field_value_range, preferred_display_base)
af4bbfc7 253
d47b87ac 254 def create_unsigned_integer_field_class(self, field_value_range=None, preferred_display_base=None):
2ae9f48c 255 return self._create_integer_field_class(native_bt.field_class_unsigned_integer_create,
d47b87ac
SM
256 bt2.field_class._UnsignedIntegerFieldClass,
257 'unsigned integer', field_value_range, preferred_display_base)
258
259 def create_signed_enumeration_field_class(self, field_value_range=None, preferred_display_base=None):
260 return self._create_integer_field_class(native_bt.field_class_signed_enumeration_create,
261 bt2.field_class._SignedEnumerationFieldClass,
262 'signed enumeration', field_value_range, preferred_display_base)
263
264 def create_unsigned_enumeration_field_class(self, field_value_range=None, preferred_display_base=None):
265 return self._create_integer_field_class(native_bt.field_class_unsigned_enumeration_create,
266 bt2.field_class._UnsignedEnumerationFieldClass,
267 'unsigned enumeration', field_value_range, preferred_display_base)
2ae9f48c
SM
268
269 def create_real_field_class(self, is_single_precision=False):
270 field_class_ptr = native_bt.field_class_real_create(self._ptr)
271 self._check_create_status(field_class_ptr, 'real')
272
d47b87ac 273 field_class = bt2.field_class._RealFieldClass._create_from_ptr(field_class_ptr)
2ae9f48c 274
d47b87ac 275 field_class._is_single_precision = is_single_precision
2ae9f48c
SM
276
277 return field_class
278
3cdfbaea
SM
279 def create_structure_field_class(self):
280 field_class_ptr = native_bt.field_class_structure_create(self._ptr)
281 self._check_create_status(field_class_ptr, 'structure')
282
283 return bt2.field_class._StructureFieldClass._create_from_ptr(field_class_ptr)
284
285 def create_string_field_class(self):
286 field_class_ptr = native_bt.field_class_string_create(self._ptr)
287 self._check_create_status(field_class_ptr, 'string')
288
d47b87ac
SM
289 return bt2.field_class._StringFieldClass._create_from_ptr(field_class_ptr)
290
291 def create_static_array_field_class(self, elem_fc, length):
292 utils._check_type(elem_fc, bt2.field_class._FieldClass)
293 utils._check_uint64(length)
294 ptr = native_bt.field_class_static_array_create(self._ptr, elem_fc._ptr, length)
295 self._check_create_status(ptr, 'static array')
296
297 return bt2.field_class._StaticArrayFieldClass._create_from_ptr_and_get_ref(ptr)
298
299 def create_dynamic_array_field_class(self, elem_fc, length_fc=None):
300 utils._check_type(elem_fc, bt2.field_class._FieldClass)
301 ptr = native_bt.field_class_dynamic_array_create(self._ptr, elem_fc._ptr)
302 self._check_create_status(ptr, 'dynamic array')
303 obj = bt2.field_class._DynamicArrayFieldClass._create_from_ptr(ptr)
304
305 if length_fc is not None:
306 obj._length_field_class = length_fc
307
308 return obj
309
310 def create_variant_field_class(self, selector_fc=None):
311 ptr = native_bt.field_class_variant_create(self._ptr)
312 self._check_create_status(ptr, 'variant')
313 obj = bt2.field_class._VariantFieldClass._create_from_ptr(ptr)
314
315 if selector_fc is not None:
316 obj._selector_field_class = selector_fc
317
318 return obj
3cdfbaea 319
fbbe9302
SM
320 # Add a listener to be called when the trace class is destroyed.
321
322 def add_destruction_listener(self, listener):
323
324 if not callable(listener):
325 raise TypeError("'listener' parameter is not callable")
326
327 fn = native_bt.py3_trace_class_add_destruction_listener
328 listener_from_native = functools.partial(_trace_class_destruction_listener_from_native,
329 listener)
330
331 listener_id = fn(self._ptr, listener_from_native)
332 if listener_id is None:
333 utils._raise_bt2_error('cannot add destruction listener to trace class object')
334
335 return bt2._ListenerHandle(listener_id, self)
This page took 0.036108 seconds and 4 git commands to generate.