Add Babeltrace 2 Python bindings
[babeltrace.git] / bindings / python / bt2 / trace.py
CommitLineData
81447b5b
PP
1# The MIT License (MIT)
2#
3# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
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
24import bt2.field_types
25import collections.abc
26import bt2.values
27import copy
28import bt2
29
30
31class _StreamClassIterator(collections.abc.Iterator):
32 def __init__(self, trace):
33 self._trace = trace
34 self._at = 0
35
36 def __next__(self):
37 if self._at == len(self._trace):
38 raise StopIteration
39
40 sc_ptr = native_bt.ctf_trace_get_stream_class(self._trace._ptr,
41 self._at)
42 utils._handle_ptr(sc_ptr, "cannot get trace class object's stream class object")
43 id = native_bt.ctf_stream_class_get_id(sc_ptr)
44 native_bt.put(sc_ptr)
45
46 if utils._is_m1ull(id):
47 raise bt2.Error("cannot get stream class object's ID")
48
49 self._at += 1
50 return id
51
52
53class _TraceClockClassesIterator(collections.abc.Iterator):
54 def __init__(self, trace_clock_classes):
55 self._trace_clock_classes = trace_clock_classes
56 self._at = 0
57
58 def __next__(self):
59 if self._at == len(self._trace_clock_classes):
60 raise StopIteration
61
62 trace_ptr = self._trace_clock_classes._trace._ptr
63 cc_ptr = native_bt.ctf_trace_get_clock_class(trace_ptr, self._at)
64 utils._handle_ptr(cc_ptr, "cannot get trace class object's clock class")
65 name = native_bt.ctf_clock_class_get_name(cc_ptr)
66 native_bt.put(cc_ptr)
67 utils._handle_ptr(name, "cannot get clock class object's name")
68 self._at += 1
69 return name
70
71
72class _TraceClockClasses(collections.abc.Mapping):
73 def __init__(self, trace):
74 self._trace = trace
75
76 def __getitem__(self, key):
77 utils._check_str(key)
78 cc_ptr = native_bt.ctf_trace_get_clock_class_by_name(self._trace._ptr,
79 key)
80
81 if cc_ptr is None:
82 raise KeyError(key)
83
84 return bt2.ClockClass._create_from_ptr(cc_ptr)
85
86 def __len__(self):
87 count = native_bt.ctf_trace_get_clock_class_count(self._trace._ptr)
88 utils._handle_ret(count, "cannot get trace class object's clock class count")
89 return count
90
91 def __iter__(self):
92 return _TraceClockClassesIterator(self)
93
94
95class _TraceEnvIterator(collections.abc.Iterator):
96 def __init__(self, trace_env):
97 self._trace_env = trace_env
98 self._at = 0
99
100 def __next__(self):
101 if self._at == len(self._trace_env):
102 raise StopIteration
103
104 trace_ptr = self._trace_env._trace._ptr
105 entry_name = native_bt.ctf_trace_get_environment_field_name(trace_ptr,
106 self._at)
107 utils._handle_ptr(entry_name, "cannot get trace class object's environment entry name")
108 self._at += 1
109 return entry_name
110
111
112class _TraceEnv(collections.abc.MutableMapping):
113 def __init__(self, trace):
114 self._trace = trace
115
116 def __getitem__(self, key):
117 utils._check_str(key)
118 value_ptr = native_bt.ctf_trace_get_environment_field_value_by_name(self._trace._ptr,
119 key)
120
121 if value_ptr is None:
122 raise KeyError(key)
123
124 return bt2.values._create_from_ptr(value_ptr)
125
126 def __setitem__(self, key, value):
127 utils._check_str(key)
128 value = bt2.create_value(value)
129 ret = native_bt.ctf_trace_set_environment_field(self._trace._ptr,
130 key, value._ptr)
131 utils._handle_ret(ret, "cannot set trace class object's environment entry")
132
133 def __delitem__(self, key):
134 raise NotImplementedError
135
136 def __len__(self):
137 count = native_bt.ctf_trace_get_environment_field_count(self._trace._ptr)
138 utils._handle_ret(count, "cannot get trace class object's environment entry count")
139 return count
140
141 def __iter__(self):
142 return _TraceEnvIterator(self)
143
144
145class Trace(object._Object, collections.abc.Mapping):
146 def __init__(self, name=None, native_byte_order=None, env=None,
147 packet_header_field_type=None, clock_classes=None,
148 stream_classes=None):
149 ptr = native_bt.ctf_trace_create()
150
151 if ptr is None:
152 raise bt2.CreationError('cannot create trace class object')
153
154 super().__init__(ptr)
155
156 if name is not None:
157 self.name = name
158
159 if native_byte_order is not None:
160 self.native_byte_order = native_byte_order
161
162 if packet_header_field_type is not None:
163 self.packet_header_field_type = packet_header_field_type
164
165 if env is not None:
166 for key, value in env.items():
167 self.env[key] = value
168
169 if clock_classes is not None:
170 for clock_class in clock_classes:
171 self.add_clock_class(clock_class)
172
173 if stream_classes is not None:
174 for stream_class in stream_classes:
175 self.add_stream_class(stream_class)
176
177 def __getitem__(self, key):
178 utils._check_int64(key)
179 sc_ptr = native_bt.ctf_trace_get_stream_class_by_id(self._ptr, key)
180
181 if sc_ptr is None:
182 raise KeyError(key)
183
184 return bt2.StreamClass._create_from_ptr(sc_ptr)
185
186 def __len__(self):
187 count = native_bt.ctf_trace_get_stream_class_count(self._ptr)
188 utils._handle_ret(count, "cannot get trace class object's stream class count")
189 return count
190
191 def __iter__(self):
192 return _StreamClassIterator(self)
193
194 def add_stream_class(self, stream_class):
195 utils._check_type(stream_class, bt2.StreamClass)
196 ret = native_bt.ctf_trace_add_stream_class(self._ptr, stream_class._ptr)
197 utils._handle_ret(ret, "cannot add stream class object to trace class object")
198
199 @property
200 def name(self):
201 return native_bt.ctf_trace_get_name(self._ptr)
202
203 @name.setter
204 def name(self, name):
205 utils._check_str(name)
206 ret = native_bt.ctf_trace_set_name(self._ptr, name)
207 utils._handle_ret(ret, "cannot set trace class object's name")
208
209 @property
210 def native_byte_order(self):
211 bo = native_bt.ctf_trace_get_byte_order(self._ptr)
212 utils._handle_ret(bo, "cannot get trace class object's native byte order")
213 return bo
214
215 @native_byte_order.setter
216 def native_byte_order(self, native_byte_order):
217 utils._check_int(native_byte_order)
218 ret = native_bt.ctf_trace_set_byte_order(self._ptr, native_byte_order)
219 utils._handle_ret(ret, "cannot set trace class object's native byte order")
220
221 @property
222 def env(self):
223 return _TraceEnv(self)
224
225 @property
226 def clock_classes(self):
227 return _TraceClockClasses(self)
228
229 def add_clock_class(self, clock_class):
230 utils._check_type(clock_class, bt2.ClockClass)
231 ret = native_bt.ctf_trace_add_clock_class(self._ptr, clock_class._ptr)
232 utils._handle_ret(ret, "cannot add clock class object to trace class object")
233
234 @property
235 def packet_header_field_type(self):
236 ft_ptr = native_bt.ctf_trace_get_packet_header_type(self._ptr)
237
238 if ft_ptr is None:
239 return
240
241 return bt2.field_types._create_from_ptr(ft_ptr)
242
243 @packet_header_field_type.setter
244 def packet_header_field_type(self, packet_header_field_type):
245 packet_header_field_type_ptr = None
246
247 if packet_header_field_type is not None:
248 utils._check_type(packet_header_field_type, bt2.field_types._FieldType)
249 packet_header_field_type_ptr = packet_header_field_type._ptr
250
251 ret = native_bt.ctf_trace_set_packet_header_type(self._ptr,
252 packet_header_field_type_ptr)
253 utils._handle_ret(ret, "cannot set trace class object's packet header field type")
254
255 def __eq__(self, other):
256 if type(other) is not type(self):
257 # not comparing apples to apples
258 return False
259
260 if self.addr == other.addr:
261 return True
262
263 self_stream_classes = list(self.values())
264 self_clock_classes = list(self.clock_classes.values())
265 self_env = {key: val for key, val in self.env.items()}
266 other_stream_classes = list(other.values())
267 other_clock_classes = list(other.clock_classes.values())
268 other_env = {key: val for key, val in other.env.items()}
269 self_props = (
270 self_stream_classes,
271 self_clock_classes,
272 self_env,
273 self.name,
274 self.native_byte_order,
275 self.packet_header_field_type,
276 )
277 other_props = (
278 other_stream_classes,
279 other_clock_classes,
280 other_env,
281 other.name,
282 other.native_byte_order,
283 other.packet_header_field_type,
284 )
285 return self_props == other_props
286
287 def _copy(self, gen_copy_func, sc_copy_func):
288 cpy = Trace()
289
290 if self.name is not None:
291 cpy.name = self.name
292
293 cpy.packet_header_field_type = gen_copy_func(self.packet_header_field_type)
294
295 for key, val in self.env.items():
296 cpy.env[key] = gen_copy_func(val)
297
298 for clock_class in self.clock_classes.values():
299 cpy.add_clock_class(gen_copy_func(clock_class))
300
301 for stream_class in self.values():
302 cpy.add_stream_class(sc_copy_func(stream_class))
303
304 return cpy
305
306 def __copy__(self):
307 return self._copy(lambda obj: obj, copy.copy)
308
309 def __deepcopy__(self, memo):
310 cpy = self._copy(copy.deepcopy, copy.deepcopy)
311 memo[id(self)] = cpy
312 return cpy
This page took 0.034886 seconds and 4 git commands to generate.