1 # The MIT License (MIT)
3 # Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
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:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
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
23 from bt2
import native_bt
, object, utils
24 import bt2
.clock_class
28 import bt2
.clock_snapshot
36 def _create_from_ptr(ptr
):
37 # recreate the event class wrapper of this event's class (the
38 # identity could be different, but the underlying address should be
40 event_class_ptr
= native_bt
.event_get_class(ptr
)
41 utils
._handle
_ptr
(event_class_ptr
, "cannot get event object's class")
42 event_class
= bt2
.EventClass
._create
_from
_ptr
(event_class_ptr
)
43 event
= _Event
._create
_from
_ptr
(ptr
)
44 event
._event
_class
= event_class
48 class _EventClockSnapshotsIterator(collections
.abc
.Iterator
):
49 def __init__(self
, event_clock_snapshots
):
50 self
._event
_clock
_snapshots
= event_clock_snapshots
51 self
._clock
_classes
= event_clock_snapshots
._event
._clock
_classes
55 if self
._at
== len(self
._clock
_classes
):
59 return self
._clock
_classes
[at
]
62 class _EventClockSnapshots(collections
.abc
.Mapping
):
63 def __init__(self
, event
):
66 def __getitem__(self
, clock_class
):
67 utils
._check
_type
(clock_class
, bt2
.ClockClass
)
68 clock_snapshot_ptr
= native_bt
.event_get_clock_snapshot(self
._event
._ptr
,
71 if clock_snapshot_ptr
is None:
74 clock_snapshot
= bt2
.clock_snapshot
._create
_clock
_snapshot
_from
_ptr
(clock_snapshot_ptr
)
77 def add(self
, clock_snapshot
):
78 utils
._check
_type
(clock_snapshot
, bt2
.clock_snapshot
._ClockSnapshot
)
79 ret
= native_bt
.event_set_clock_snapshot(self
._ptr
,
81 utils
._handle
_ret
(ret
, "cannot set event object's clock value")
84 count
= len(self
._event
._clock
_classes
)
89 return _EventClockSnapshotsIterator(self
)
92 class _Event(object._Object
):
94 def event_class(self
):
95 return self
._event
_class
99 return self
._event
_class
.name
103 return self
._event
_class
.id
107 packet_ptr
= native_bt
.event_get_packet(self
._ptr
)
109 if packet_ptr
is None:
112 return bt2
.packet
._Packet
._create
_from
_ptr
(packet_ptr
)
115 def packet(self
, packet
):
116 utils
._check
_type
(packet
, bt2
.packet
._Packet
)
117 ret
= native_bt
.event_set_packet(self
._ptr
, packet
._ptr
)
118 utils
._handle
_ret
(ret
, "cannot set event object's packet object")
122 stream_ptr
= native_bt
.event_get_stream(self
._ptr
)
124 if stream_ptr
is None:
127 return bt2
.stream
._Stream
._create
_from
_ptr
(stream_ptr
)
130 def header_field(self
):
131 field_ptr
= native_bt
.event_get_header(self
._ptr
)
133 if field_ptr
is None:
136 return bt2
.fields
._create
_from
_ptr
(field_ptr
)
139 def header_field(self
, header_field
):
140 header_field_ptr
= None
142 if header_field
is not None:
143 utils
._check
_type
(header_field
, bt2
.fields
._Field
)
144 header_field_ptr
= header_field
._ptr
146 ret
= native_bt
.event_set_header(self
._ptr
, header_field_ptr
)
147 utils
._handle
_ret
(ret
, "cannot set event object's header field")
150 def stream_event_context_field(self
):
151 field_ptr
= native_bt
.event_get_stream_event_context(self
._ptr
)
153 if field_ptr
is None:
156 return bt2
.fields
._create
_from
_ptr
(field_ptr
)
158 @stream_event_context_field.setter
159 def stream_event_context_field(self
, stream_event_context
):
160 stream_event_context_ptr
= None
162 if stream_event_context
is not None:
163 utils
._check
_type
(stream_event_context
, bt2
.fields
._Field
)
164 stream_event_context_ptr
= stream_event_context
._ptr
166 ret
= native_bt
.event_set_stream_event_context(self
._ptr
,
167 stream_event_context_ptr
)
168 utils
._handle
_ret
(ret
, "cannot set event object's stream event context field")
171 def context_field(self
):
172 field_ptr
= native_bt
.event_get_event_context(self
._ptr
)
174 if field_ptr
is None:
177 return bt2
.fields
._create
_from
_ptr
(field_ptr
)
179 @context_field.setter
180 def context_field(self
, context
):
183 if context
is not None:
184 utils
._check
_type
(context
, bt2
.fields
._Field
)
185 context_ptr
= context
._ptr
187 ret
= native_bt
.event_set_event_context(self
._ptr
, context_ptr
)
188 utils
._handle
_ret
(ret
, "cannot set event object's context field")
191 def payload_field(self
):
192 field_ptr
= native_bt
.event_get_event_payload(self
._ptr
)
194 if field_ptr
is None:
197 return bt2
.fields
._create
_from
_ptr
(field_ptr
)
199 @payload_field.setter
200 def payload_field(self
, payload
):
203 if payload
is not None:
204 utils
._check
_type
(payload
, bt2
.fields
._Field
)
205 payload_ptr
= payload
._ptr
207 ret
= native_bt
.event_set_event_payload(self
._ptr
, payload_ptr
)
208 utils
._handle
_ret
(ret
, "cannot set event object's payload field")
210 def _get_clock_snapshot_cycles(self
, clock_class_ptr
):
211 clock_snapshot_ptr
= native_bt
.event_get_clock_snapshot(self
._ptr
,
214 if clock_snapshot_ptr
is None:
217 ret
, cycles
= native_bt
.clock_snapshot_get_value(clock_snapshot_ptr
)
218 native_bt
.put(clock_snapshot_ptr
)
219 utils
._handle
_ret
(ret
, "cannot get clock value object's cycles")
223 def clock_snapshots(self
):
224 return _EventClockSnapshots(self
)
226 def __getitem__(self
, key
):
227 utils
._check
_str
(key
)
228 payload_field
= self
.payload_field
230 if payload_field
is not None and key
in payload_field
:
231 return payload_field
[key
]
233 context_field
= self
.context_field
235 if context_field
is not None and key
in context_field
:
236 return context_field
[key
]
238 sec_field
= self
.stream_event_context_field
240 if sec_field
is not None and key
in sec_field
:
241 return sec_field
[key
]
243 header_field
= self
.header_field
245 if header_field
is not None and key
in header_field
:
246 return header_field
[key
]
253 pkt_context_field
= packet
.context_field
255 if pkt_context_field
is not None and key
in pkt_context_field
:
256 return pkt_context_field
[key
]
258 pkt_header_field
= packet
.header_field
260 if pkt_header_field
is not None and key
in pkt_header_field
:
261 return pkt_header_field
[key
]
266 def _clock_classes(self
):
267 stream_class
= self
.event_class
.stream_class
269 if stream_class
is None:
272 trace
= stream_class
.trace
279 for clock_class
in trace
.clock_classes
.values():
280 clock_classes
.append(clock_class
)
285 def _clock_class_ptrs(self
):
286 return [cc
._ptr
for cc
in self
._clock
_classes
]
288 def __eq__(self
, other
):
289 if type(other
) is not type(self
):
292 if self
.addr
== other
.addr
:
295 self_clock_snapshots
= {}
296 other_clock_snapshots
= {}
298 for clock_class_ptr
in self
._clock
_class
_ptrs
:
299 self_clock_snapshots
[int(clock_class_ptr
)] = self
._get
_clock
_snapshot
_cycles
(clock_class_ptr
)
301 for clock_class_ptr
in other
._clock
_class
_ptrs
:
302 other_clock_snapshots
[int(clock_class_ptr
)] = self
._get
_clock
_snapshot
_cycles
(clock_class_ptr
)
306 self
.stream_event_context_field
,
309 self_clock_snapshots
,
313 other
.stream_event_context_field
,
316 other_clock_snapshots
,
318 return self_props
== other_props
320 def _copy(self
, copy_func
):
321 cpy
= self
.event_class()
324 cpy
.header_field
= copy_func(self
.header_field
)
325 cpy
.stream_event_context_field
= copy_func(self
.stream_event_context_field
)
326 cpy
.context_field
= copy_func(self
.context_field
)
327 cpy
.payload_field
= copy_func(self
.payload_field
)
329 # Copy known clock value references. It's not necessary to copy
330 # clock class or clock value objects because once a clock value
331 # is created from a clock class, the clock class is frozen.
332 # Thus even if we copy the clock class, the user cannot modify
333 # it, therefore it's useless to copy it.
334 for clock_class
in self
._clock
_classes
:
335 clock_snapshot
= self
.clock_snapshots
[clock_class
]
337 if clock_snapshot
is not None:
338 cpy
.clock_snapshots
.add(clock_snapshot
)
343 return self
._copy
(copy
.copy
)
345 def __deepcopy__(self
, memo
):
346 cpy
= self
._copy
(copy
.deepcopy
)