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