bt2: Add bindings for trace classes
[babeltrace.git] / bindings / python / bt2 / bt2 / trace.py
CommitLineData
81447b5b
PP
1# The MIT License (MIT)
2#
811644b8 3# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
81447b5b
PP
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy
6# of this software and associated documentation files (the "Software"), to deal
7# in the Software without restriction, including without limitation the rights
8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9# copies of the Software, and to permit persons to whom the Software is
10# furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in
13# all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21# THE SOFTWARE.
22
23from bt2 import native_bt, object, utils
b4f45851 24import bt2.field_class
81447b5b 25import collections.abc
c4239792 26import bt2.value
811644b8 27import bt2.stream
81447b5b
PP
28import copy
29import bt2
30
31
32class _StreamClassIterator(collections.abc.Iterator):
33 def __init__(self, trace):
34 self._trace = trace
35 self._at = 0
36
37 def __next__(self):
38 if self._at == len(self._trace):
39 raise StopIteration
40
50842bdc 41 sc_ptr = native_bt.trace_get_stream_class_by_index(self._trace._ptr,
0b03f63e 42 self._at)
811644b8 43 assert(sc_ptr)
50842bdc 44 id = native_bt.stream_class_get_id(sc_ptr)
81447b5b 45 native_bt.put(sc_ptr)
811644b8 46 assert(id >= 0)
81447b5b
PP
47 self._at += 1
48 return id
49
50
811644b8
PP
51class _TraceStreams(collections.abc.Sequence):
52 def __init__(self, trace):
53 self._trace = trace
54
55 def __len__(self):
50842bdc 56 count = native_bt.trace_get_stream_count(self._trace._ptr)
811644b8
PP
57 assert(count >= 0)
58 return count
59
60 def __getitem__(self, index):
61 utils._check_uint64(index)
62
63 if index >= len(self):
64 raise IndexError
65
50842bdc 66 stream_ptr = native_bt.trace_get_stream_by_index(self._trace._ptr,
0b03f63e 67 index)
811644b8
PP
68 assert(stream_ptr)
69 return bt2.stream._create_from_ptr(stream_ptr)
70
71
81447b5b
PP
72class _TraceClockClassesIterator(collections.abc.Iterator):
73 def __init__(self, trace_clock_classes):
74 self._trace_clock_classes = trace_clock_classes
75 self._at = 0
76
77 def __next__(self):
78 if self._at == len(self._trace_clock_classes):
79 raise StopIteration
80
81 trace_ptr = self._trace_clock_classes._trace._ptr
50842bdc 82 cc_ptr = native_bt.trace_get_clock_class_by_index(trace_ptr, self._at)
811644b8 83 assert(cc_ptr)
50842bdc 84 name = native_bt.clock_class_get_name(cc_ptr)
81447b5b 85 native_bt.put(cc_ptr)
811644b8 86 assert(name is not None)
81447b5b
PP
87 self._at += 1
88 return name
89
90
91class _TraceClockClasses(collections.abc.Mapping):
92 def __init__(self, trace):
93 self._trace = trace
94
95 def __getitem__(self, key):
96 utils._check_str(key)
0b03f63e 97 cc_ptr = native_bt.trace_get_clock_class_by_name(self._trace._ptr, key)
81447b5b
PP
98
99 if cc_ptr is None:
100 raise KeyError(key)
101
102 return bt2.ClockClass._create_from_ptr(cc_ptr)
103
104 def __len__(self):
50842bdc 105 count = native_bt.trace_get_clock_class_count(self._trace._ptr)
811644b8 106 assert(count >= 0)
81447b5b
PP
107 return count
108
109 def __iter__(self):
110 return _TraceClockClassesIterator(self)
111
112
113class _TraceEnvIterator(collections.abc.Iterator):
114 def __init__(self, trace_env):
115 self._trace_env = trace_env
116 self._at = 0
117
118 def __next__(self):
119 if self._at == len(self._trace_env):
120 raise StopIteration
121
122 trace_ptr = self._trace_env._trace._ptr
50842bdc 123 entry_name = native_bt.trace_get_environment_field_name_by_index(trace_ptr,
0b03f63e 124 self._at)
811644b8 125 assert(entry_name is not None)
81447b5b
PP
126 self._at += 1
127 return entry_name
128
129
130class _TraceEnv(collections.abc.MutableMapping):
131 def __init__(self, trace):
132 self._trace = trace
133
134 def __getitem__(self, key):
135 utils._check_str(key)
50842bdc 136 value_ptr = native_bt.trace_get_environment_field_value_by_name(self._trace._ptr,
0b03f63e 137 key)
81447b5b
PP
138
139 if value_ptr is None:
140 raise KeyError(key)
141
c4239792 142 return bt2.value._create_from_ptr(value_ptr)
81447b5b
PP
143
144 def __setitem__(self, key, value):
145 utils._check_str(key)
146 value = bt2.create_value(value)
50842bdc 147 ret = native_bt.trace_set_environment_field(self._trace._ptr,
0b03f63e 148 key, value._ptr)
81447b5b
PP
149 utils._handle_ret(ret, "cannot set trace class object's environment entry")
150
151 def __delitem__(self, key):
152 raise NotImplementedError
153
154 def __len__(self):
50842bdc 155 count = native_bt.trace_get_environment_field_count(self._trace._ptr)
811644b8 156 assert(count >= 0)
81447b5b
PP
157 return count
158
159 def __iter__(self):
160 return _TraceEnvIterator(self)
161
162
78288f58 163class Trace(object._SharedObject, collections.abc.Mapping):
81447b5b 164 def __init__(self, name=None, native_byte_order=None, env=None,
b4f45851 165 packet_header_field_class=None, clock_classes=None,
81447b5b 166 stream_classes=None):
50842bdc 167 ptr = native_bt.trace_create()
81447b5b
PP
168
169 if ptr is None:
170 raise bt2.CreationError('cannot create trace class object')
171
172 super().__init__(ptr)
173
174 if name is not None:
175 self.name = name
176
177 if native_byte_order is not None:
178 self.native_byte_order = native_byte_order
179
b4f45851
SM
180 if packet_header_field_class is not None:
181 self.packet_header_field_class = packet_header_field_class
81447b5b
PP
182
183 if env is not None:
184 for key, value in env.items():
185 self.env[key] = value
186
187 if clock_classes is not None:
188 for clock_class in clock_classes:
189 self.add_clock_class(clock_class)
190
191 if stream_classes is not None:
192 for stream_class in stream_classes:
193 self.add_stream_class(stream_class)
194
195 def __getitem__(self, key):
196 utils._check_int64(key)
50842bdc 197 sc_ptr = native_bt.trace_get_stream_class_by_id(self._ptr, key)
81447b5b
PP
198
199 if sc_ptr is None:
200 raise KeyError(key)
201
202 return bt2.StreamClass._create_from_ptr(sc_ptr)
203
204 def __len__(self):
50842bdc 205 count = native_bt.trace_get_stream_class_count(self._ptr)
811644b8 206 assert(count >= 0)
81447b5b
PP
207 return count
208
209 def __iter__(self):
210 return _StreamClassIterator(self)
211
212 def add_stream_class(self, stream_class):
213 utils._check_type(stream_class, bt2.StreamClass)
50842bdc 214 ret = native_bt.trace_add_stream_class(self._ptr, stream_class._ptr)
81447b5b
PP
215 utils._handle_ret(ret, "cannot add stream class object to trace class object")
216
217 @property
218 def name(self):
50842bdc 219 return native_bt.trace_get_name(self._ptr)
81447b5b
PP
220
221 @name.setter
222 def name(self, name):
223 utils._check_str(name)
50842bdc 224 ret = native_bt.trace_set_name(self._ptr, name)
81447b5b
PP
225 utils._handle_ret(ret, "cannot set trace class object's name")
226
227 @property
228 def native_byte_order(self):
50842bdc 229 bo = native_bt.trace_get_native_byte_order(self._ptr)
811644b8 230 assert(bo >= 0)
81447b5b
PP
231 return bo
232
233 @native_byte_order.setter
234 def native_byte_order(self, native_byte_order):
235 utils._check_int(native_byte_order)
50842bdc 236 ret = native_bt.trace_set_native_byte_order(self._ptr, native_byte_order)
81447b5b
PP
237 utils._handle_ret(ret, "cannot set trace class object's native byte order")
238
811644b8
PP
239 @property
240 def is_static(self):
50842bdc 241 is_static = native_bt.trace_is_static(self._ptr)
811644b8
PP
242 return is_static > 0
243
244 def set_is_static(self):
50842bdc 245 ret = native_bt.trace_set_is_static(self._ptr)
811644b8
PP
246 utils._handle_ret(ret, "cannot set trace object as static")
247
81447b5b
PP
248 @property
249 def env(self):
250 return _TraceEnv(self)
251
252 @property
253 def clock_classes(self):
254 return _TraceClockClasses(self)
255
256 def add_clock_class(self, clock_class):
257 utils._check_type(clock_class, bt2.ClockClass)
50842bdc 258 ret = native_bt.trace_add_clock_class(self._ptr, clock_class._ptr)
81447b5b
PP
259 utils._handle_ret(ret, "cannot add clock class object to trace class object")
260
811644b8
PP
261 @property
262 def streams(self):
263 return _TraceStreams(self)
264
81447b5b 265 @property
b4f45851
SM
266 def packet_header_field_class(self):
267 fc_ptr = native_bt.trace_get_packet_header_type(self._ptr)
81447b5b 268
b4f45851 269 if fc_ptr is None:
81447b5b
PP
270 return
271
b4f45851 272 return bt2.field_class._create_from_ptr(fc_ptr)
81447b5b 273
b4f45851
SM
274 @packet_header_field_class.setter
275 def packet_header_field_class(self, packet_header_field_class):
276 packet_header_field_class_ptr = None
81447b5b 277
b4f45851
SM
278 if packet_header_field_class is not None:
279 utils._check_type(packet_header_field_class, bt2.field_class._FieldClass)
280 packet_header_field_class_ptr = packet_header_field_class._ptr
81447b5b 281
50842bdc 282 ret = native_bt.trace_set_packet_header_type(self._ptr,
b4f45851
SM
283 packet_header_field_class_ptr)
284 utils._handle_ret(ret, "cannot set trace class object's packet header field class")
81447b5b
PP
285
286 def __eq__(self, other):
287 if type(other) is not type(self):
288 # not comparing apples to apples
289 return False
290
291 if self.addr == other.addr:
292 return True
293
294 self_stream_classes = list(self.values())
295 self_clock_classes = list(self.clock_classes.values())
296 self_env = {key: val for key, val in self.env.items()}
297 other_stream_classes = list(other.values())
298 other_clock_classes = list(other.clock_classes.values())
299 other_env = {key: val for key, val in other.env.items()}
300 self_props = (
301 self_stream_classes,
302 self_clock_classes,
303 self_env,
304 self.name,
305 self.native_byte_order,
b4f45851 306 self.packet_header_field_class,
81447b5b
PP
307 )
308 other_props = (
309 other_stream_classes,
310 other_clock_classes,
311 other_env,
312 other.name,
313 other.native_byte_order,
b4f45851 314 other.packet_header_field_class,
81447b5b
PP
315 )
316 return self_props == other_props
317
318 def _copy(self, gen_copy_func, sc_copy_func):
319 cpy = Trace()
320
321 if self.name is not None:
322 cpy.name = self.name
323
b4f45851 324 cpy.packet_header_field_class = gen_copy_func(self.packet_header_field_class)
81447b5b
PP
325
326 for key, val in self.env.items():
327 cpy.env[key] = gen_copy_func(val)
328
329 for clock_class in self.clock_classes.values():
330 cpy.add_clock_class(gen_copy_func(clock_class))
331
332 for stream_class in self.values():
333 cpy.add_stream_class(sc_copy_func(stream_class))
334
335 return cpy
336
337 def __copy__(self):
338 return self._copy(lambda obj: obj, copy.copy)
339
340 def __deepcopy__(self, memo):
341 cpy = self._copy(copy.deepcopy, copy.deepcopy)
342 memo[id(self)] = cpy
343 return cpy
This page took 0.049637 seconds and 4 git commands to generate.