2e11de087380c6f7fe46436bd2f2c81395cd0e3b
[babeltrace.git] / bindings / python / bt2 / bt2 / event.py
1 # The MIT License (MIT)
2 #
3 # Copyright (c) 2016-2017 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
23 from bt2 import native_bt, object, utils
24 import bt2.clock_class
25 import bt2.packet
26 import bt2.stream
27 import bt2.fields
28 import numbers
29 import copy
30 import abc
31 import bt2
32
33
34 def _create_from_ptr(ptr):
35 # recreate the event class wrapper of this event's class (the
36 # identity could be different, but the underlying address should be
37 # the same)
38 event_class_ptr = native_bt.ctf_event_get_class(ptr)
39 utils._handle_ptr(event_class_ptr, "cannot get event object's class")
40 event_class = bt2.EventClass._create_from_ptr(event_class_ptr)
41 event = _Event._create_from_ptr(ptr)
42 event._event_class = event_class
43 return event
44
45
46 class _Event(object._Object):
47 @property
48 def event_class(self):
49 return self._event_class
50
51 @property
52 def name(self):
53 return self._event_class.name
54
55 @property
56 def id(self):
57 return self._event_class.id
58
59 @property
60 def packet(self):
61 packet_ptr = native_bt.ctf_event_get_packet(self._ptr)
62
63 if packet_ptr is None:
64 return packet_ptr
65
66 return bt2.packet._Packet._create_from_ptr(packet_ptr)
67
68 @packet.setter
69 def packet(self, packet):
70 utils._check_type(packet, bt2.packet._Packet)
71 ret = native_bt.ctf_event_set_packet(self._ptr, packet._ptr)
72 utils._handle_ret(ret, "cannot set event object's packet object")
73
74 @property
75 def stream(self):
76 stream_ptr = native_bt.ctf_event_get_stream(self._ptr)
77
78 if stream_ptr is None:
79 return stream_ptr
80
81 return bt2.stream._Stream._create_from_ptr(stream_ptr)
82
83 @property
84 def header_field(self):
85 field_ptr = native_bt.ctf_event_get_header(self._ptr)
86
87 if field_ptr is None:
88 return
89
90 return bt2.fields._create_from_ptr(field_ptr)
91
92 @header_field.setter
93 def header_field(self, header_field):
94 header_field_ptr = None
95
96 if header_field is not None:
97 utils._check_type(header_field, bt2.fields._Field)
98 header_field_ptr = header_field._ptr
99
100 ret = native_bt.ctf_event_set_header(self._ptr, header_field_ptr)
101 utils._handle_ret(ret, "cannot set event object's header field")
102
103 @property
104 def stream_event_context_field(self):
105 field_ptr = native_bt.ctf_event_get_stream_event_context(self._ptr)
106
107 if field_ptr is None:
108 return
109
110 return bt2.fields._create_from_ptr(field_ptr)
111
112 @stream_event_context_field.setter
113 def stream_event_context_field(self, stream_event_context):
114 stream_event_context_ptr = None
115
116 if stream_event_context is not None:
117 utils._check_type(stream_event_context, bt2.fields._Field)
118 stream_event_context_ptr = stream_event_context._ptr
119
120 ret = native_bt.ctf_event_set_stream_event_context(self._ptr,
121 stream_event_context_ptr)
122 utils._handle_ret(ret, "cannot set event object's stream event context field")
123
124 @property
125 def context_field(self):
126 field_ptr = native_bt.ctf_event_get_event_context(self._ptr)
127
128 if field_ptr is None:
129 return
130
131 return bt2.fields._create_from_ptr(field_ptr)
132
133 @context_field.setter
134 def context_field(self, context):
135 context_ptr = None
136
137 if context is not None:
138 utils._check_type(context, bt2.fields._Field)
139 context_ptr = context._ptr
140
141 ret = native_bt.ctf_event_set_event_context(self._ptr, context_ptr)
142 utils._handle_ret(ret, "cannot set event object's context field")
143
144 @property
145 def payload_field(self):
146 field_ptr = native_bt.ctf_event_get_event_payload(self._ptr)
147
148 if field_ptr is None:
149 return
150
151 return bt2.fields._create_from_ptr(field_ptr)
152
153 @payload_field.setter
154 def payload_field(self, payload):
155 payload_ptr = None
156
157 if payload is not None:
158 utils._check_type(payload, bt2.fields._Field)
159 payload_ptr = payload._ptr
160
161 ret = native_bt.ctf_event_set_event_payload(self._ptr, payload_ptr)
162 utils._handle_ret(ret, "cannot set event object's payload field")
163
164 def _get_clock_value_cycles(self, clock_class_ptr):
165 clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
166 clock_class_ptr)
167
168 if clock_value_ptr is None:
169 return
170
171 ret, cycles = native_bt.ctf_clock_value_get_value(clock_value_ptr)
172 native_bt.put(clock_value_ptr)
173 utils._handle_ret(ret, "cannot get clock value object's cycles")
174 return cycles
175
176 def clock_value(self, clock_class):
177 utils._check_type(clock_class, bt2.ClockClass)
178 clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
179 clock_class._ptr)
180
181 if clock_value_ptr is None:
182 return
183
184 clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
185 return clock_value
186
187 def add_clock_value(self, clock_value):
188 utils._check_type(clock_value, bt2.clock_class._ClockValue)
189 ret = native_bt.ctf_event_set_clock_value(self._ptr,
190 clock_value._ptr)
191 utils._handle_ret(ret, "cannot set event object's clock value")
192
193 def __getitem__(self, key):
194 utils._check_str(key)
195 payload_field = self.payload_field
196
197 if payload_field is not None and key in payload_field:
198 return payload_field[key]
199
200 context_field = self.context_field
201
202 if context_field is not None and key in context_field:
203 return context_field[key]
204
205 sec_field = self.stream_event_context_field
206
207 if sec_field is not None and key in sec_field:
208 return sec_field[key]
209
210 header_field = self.header_field
211
212 if header_field is not None and key in header_field:
213 return header_field[key]
214
215 packet = self.packet
216
217 if packet is None:
218 raise KeyError(key)
219
220 pkt_context_field = packet.context_field
221
222 if pkt_context_field is not None and key in pkt_context_field:
223 return pkt_context_field[key]
224
225 pkt_header_field = packet.header_field
226
227 if pkt_header_field is not None and key in pkt_header_field:
228 return pkt_header_field[key]
229
230 raise KeyError(key)
231
232 @property
233 def _clock_classes(self):
234 stream_class = self.event_class.stream_class
235
236 if stream_class is None:
237 return []
238
239 trace = stream_class.trace
240
241 if trace is None:
242 return []
243
244 clock_classes = []
245
246 for clock_class in trace.clock_classes.values():
247 clock_classes.append(clock_class)
248
249 return clock_classes
250
251 @property
252 def _clock_class_ptrs(self):
253 return [cc._ptr for cc in self._clock_classes]
254
255 def __eq__(self, other):
256 if type(other) is not type(self):
257 return False
258
259 if self.addr == other.addr:
260 return True
261
262 self_clock_values = {}
263 other_clock_values = {}
264
265 for clock_class_ptr in self._clock_class_ptrs:
266 self_clock_values[int(clock_class_ptr)] = self._get_clock_value_cycles(clock_class_ptr)
267
268 for clock_class_ptr in other._clock_class_ptrs:
269 other_clock_values[int(clock_class_ptr)] = self._get_clock_value_cycles(clock_class_ptr)
270
271 self_props = (
272 self.header_field,
273 self.stream_event_context_field,
274 self.context_field,
275 self.payload_field,
276 self_clock_values,
277 )
278 other_props = (
279 other.header_field,
280 other.stream_event_context_field,
281 other.context_field,
282 other.payload_field,
283 other_clock_values,
284 )
285 return self_props == other_props
286
287 def _copy(self, copy_func):
288 cpy = self.event_class()
289
290 # copy fields
291 cpy.header_field = copy_func(self.header_field)
292 cpy.stream_event_context_field = copy_func(self.stream_event_context_field)
293 cpy.context_field = copy_func(self.context_field)
294 cpy.payload_field = copy_func(self.payload_field)
295
296 # Copy known clock value references. It's not necessary to copy
297 # clock class or clock value objects because once a clock value
298 # is created from a clock class, the clock class is frozen.
299 # Thus even if we copy the clock class, the user cannot modify
300 # it, therefore it's useless to copy it.
301 for clock_class in self._clock_classes:
302 clock_value = self.clock_value(clock_class)
303
304 if clock_value is not None:
305 cpy.add_clock_value(clock_value)
306
307 return cpy
308
309 def __copy__(self):
310 return self._copy(copy.copy)
311
312 def __deepcopy__(self, memo):
313 cpy = self._copy(copy.deepcopy)
314 memo[id(self)] = cpy
315 return cpy
This page took 0.035897 seconds and 4 git commands to generate.