lib: Make graph listeners return an error status
[babeltrace.git] / bindings / python / bt2 / bt2 / message.py
CommitLineData
81447b5b
PP
1# The MIT License (MIT)
2#
3# Copyright (c) 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
23from bt2 import native_bt, object, utils
4b552f8b 24import bt2.clock_snapshot
71fd6f52 25import collections
81447b5b
PP
26import bt2.packet
27import bt2.stream
28import bt2.event
811644b8 29import copy
81447b5b
PP
30import bt2
31
32
33def _create_from_ptr(ptr):
5602ef81 34 msg_type = native_bt.message_get_type(ptr)
81447b5b
PP
35 cls = None
36
5602ef81
SM
37 if msg_type not in _MESSAGE_TYPE_TO_CLS:
38 raise bt2.Error('unknown message type: {}'.format(msg_type))
81447b5b 39
5602ef81 40 return _MESSAGE_TYPE_TO_CLS[msg_type]._create_from_ptr(ptr)
81447b5b
PP
41
42
5602ef81
SM
43def _msg_types_from_msg_classes(message_types):
44 if message_types is None:
45 msg_types = None
dc43190b 46 else:
5602ef81
SM
47 for msg_cls in message_types:
48 if msg_cls not in _MESSAGE_TYPE_TO_CLS.values():
49 raise ValueError("'{}' is not a message class".format(msg_cls))
dc43190b 50
5602ef81 51 msg_types = [msg_cls._TYPE for msg_cls in message_types]
dc43190b 52
5602ef81 53 return msg_types
dc43190b
PP
54
55
78288f58 56class _Message(object._SharedObject):
2ae9f48c
SM
57 _get_ref = staticmethod(native_bt.message_get_ref)
58 _put_ref = staticmethod(native_bt.message_put_ref)
81447b5b
PP
59
60
5602ef81 61class _CopyableMessage(_Message):
811644b8
PP
62 def __copy__(self):
63 return self._copy(lambda obj: obj)
64
65 def __deepcopy__(self, memo):
66 cpy = self._copy(copy.deepcopy)
67 memo[id(self)] = cpy
68 return cpy
69
70
2ae9f48c 71class _EventMessage(_CopyableMessage):
88f3724d 72 _TYPE = native_bt.MESSAGE_TYPE_EVENT
811644b8 73
2ae9f48c
SM
74 @property
75 def event(self):
76 event_ptr = native_bt.message_event_borrow_event(self._ptr)
77 assert event_ptr is not None
78 return bt2.event._Event._create_from_ptr_and_get_ref(
79 event_ptr, self._ptr, self._get_ref, self._put_ref)
81447b5b 80
2ae9f48c
SM
81 @property
82 def default_clock_snapshot(self):
83 if self.event.event_class.stream_class.default_clock_class is None:
84 return None
81447b5b 85
2ae9f48c 86 snapshot_ptr = native_bt.message_event_borrow_default_clock_snapshot_const(self._ptr)
81447b5b 87
2ae9f48c
SM
88 return bt2.clock_snapshot._ClockSnapshot._create_from_ptr_and_get_ref(
89 snapshot_ptr, self._ptr, self._get_ref, self._put_ref)
81447b5b 90
811644b8
PP
91 @property
92 def clock_class_priority_map(self):
5602ef81 93 cc_prio_map_ptr = native_bt.message_event_get_clock_class_priority_map(self._ptr)
811644b8
PP
94 assert(cc_prio_map_ptr)
95 return bt2.clock_class_priority_map.ClockClassPriorityMap._create_from_ptr(cc_prio_map_ptr)
96
97 def __eq__(self, other):
98 if type(other) is not type(self):
99 return False
100
101 if self.addr == other.addr:
102 return True
103
104 self_props = (
105 self.event,
106 self.clock_class_priority_map,
107 )
108 other_props = (
109 other.event,
110 other.clock_class_priority_map,
111 )
112 return self_props == other_props
113
114 def _copy(self, copy_func):
115 # We can always use references here because those properties are
5602ef81
SM
116 # frozen anyway if they are part of a message. Since the
117 # user cannot modify them after copying the message, it's
811644b8 118 # useless to copy/deep-copy them.
5602ef81 119 return EventMessage(self.event, self.clock_class_priority_map)
811644b8
PP
120
121
2ae9f48c 122class _PacketBeginningMessage(_CopyableMessage):
88f3724d 123 _TYPE = native_bt.MESSAGE_TYPE_PACKET_BEGINNING
81447b5b 124
81447b5b
PP
125 @property
126 def packet(self):
5602ef81 127 packet_ptr = native_bt.message_packet_begin_get_packet(self._ptr)
811644b8 128 assert(packet_ptr)
81447b5b
PP
129 return bt2.packet._Packet._create_from_ptr(packet_ptr)
130
811644b8
PP
131 def __eq__(self, other):
132 if type(other) is not type(self):
133 return False
134
135 if self.addr == other.addr:
136 return True
137
138 return self.packet == other.packet
139
140 def _copy(self, copy_func):
141 # We can always use references here because those properties are
5602ef81
SM
142 # frozen anyway if they are part of a message. Since the
143 # user cannot modify them after copying the message, it's
811644b8 144 # useless to copy/deep-copy them.
5602ef81 145 return PacketBeginningMessage(self.packet)
811644b8
PP
146
147
5602ef81 148class PacketEndMessage(_CopyableMessage):
88f3724d 149 _TYPE = native_bt.MESSAGE_TYPE_PACKET_END
81447b5b 150
81447b5b
PP
151 def __init__(self, packet):
152 utils._check_type(packet, bt2.packet._Packet)
5602ef81 153 ptr = native_bt.message_packet_end_create(packet._ptr)
81447b5b
PP
154
155 if ptr is None:
5602ef81 156 raise bt2.CreationError('cannot create packet end message object')
81447b5b
PP
157
158 super().__init__(ptr)
159
160 @property
161 def packet(self):
5602ef81 162 packet_ptr = native_bt.message_packet_end_get_packet(self._ptr)
811644b8 163 assert(packet_ptr)
81447b5b
PP
164 return bt2.packet._Packet._create_from_ptr(packet_ptr)
165
811644b8
PP
166 def __eq__(self, other):
167 if type(other) is not type(self):
168 return False
169
170 if self.addr == other.addr:
171 return True
172
173 return self.packet == other.packet
174
175 def _copy(self, copy_func):
176 # We can always use references here because those properties are
5602ef81
SM
177 # frozen anyway if they are part of a message. Since the
178 # user cannot modify them after copying the message, it's
811644b8 179 # useless to copy/deep-copy them.
5602ef81 180 return PacketEndMessage(self.packet)
811644b8
PP
181
182
2ae9f48c 183class _StreamBeginningMessage(_CopyableMessage):
88f3724d 184 _TYPE = native_bt.MESSAGE_TYPE_STREAM_BEGINNING
81447b5b 185
81447b5b
PP
186 @property
187 def stream(self):
5602ef81 188 stream_ptr = native_bt.message_stream_begin_get_stream(self._ptr)
811644b8 189 assert(stream_ptr)
81447b5b
PP
190 return bt2.stream._create_from_ptr(stream_ptr)
191
811644b8
PP
192 def __eq__(self, other):
193 if type(other) is not type(self):
194 return False
195
196 if self.addr == other.addr:
197 return True
198
199 return self.stream == other.stream
200
201 def _copy(self, copy_func):
202 # We can always use references here because those properties are
5602ef81
SM
203 # frozen anyway if they are part of a message. Since the
204 # user cannot modify them after copying the message, it's
811644b8 205 # useless to copy/deep-copy them.
5602ef81 206 return StreamBeginningMessage(self.stream)
811644b8
PP
207
208
5602ef81 209class StreamEndMessage(_CopyableMessage):
88f3724d 210 _TYPE = native_bt.MESSAGE_TYPE_STREAM_END
81447b5b 211
811644b8
PP
212 def __init__(self, stream):
213 utils._check_type(stream, bt2.stream._Stream)
5602ef81 214 ptr = native_bt.message_stream_end_create(stream._ptr)
81447b5b
PP
215
216 if ptr is None:
5602ef81 217 raise bt2.CreationError('cannot create stream end message object')
81447b5b
PP
218
219 super().__init__(ptr)
220
221 @property
811644b8 222 def stream(self):
5602ef81 223 stream_ptr = native_bt.message_stream_end_get_stream(self._ptr)
811644b8
PP
224 assert(stream_ptr)
225 return bt2.stream._create_from_ptr(stream_ptr)
226
227 def __eq__(self, other):
228 if type(other) is not type(self):
229 return False
230
231 if self.addr == other.addr:
232 return True
233
234 return self.stream == other.stream
235
236 def _copy(self, copy_func):
237 # We can always use references here because those properties are
5602ef81
SM
238 # frozen anyway if they are part of a message. Since the
239 # user cannot modify them after copying the message, it's
811644b8 240 # useless to copy/deep-copy them.
5602ef81 241 return StreamEndMessage(self.stream)
811644b8
PP
242
243
4b552f8b
SM
244class _InactivityMessageClockSnapshotsIterator(collections.abc.Iterator):
245 def __init__(self, msg_clock_snapshots):
246 self._msg_clock_snapshots = msg_clock_snapshots
247 self._clock_classes = list(msg_clock_snapshots._msg.clock_class_priority_map)
71fd6f52
PP
248 self._at = 0
249
250 def __next__(self):
251 if self._at == len(self._clock_classes):
252 raise StopIteration
253
254 self._at += 1
255 return self._clock_classes[at]
256
257
4b552f8b 258class _InactivityMessageClockSnapshots(collections.abc.Mapping):
5602ef81
SM
259 def __init__(self, msg):
260 self._msg = msg
71fd6f52
PP
261
262 def __getitem__(self, clock_class):
263 utils._check_type(clock_class, bt2.ClockClass)
4b552f8b 264 clock_snapshot_ptr = native_bt.message_inactivity_get_clock_snapshot(self._msg._ptr,
71fd6f52
PP
265 clock_class._ptr)
266
4b552f8b 267 if clock_snapshot_ptr is None:
71fd6f52
PP
268 return
269
4b552f8b
SM
270 clock_snapshot = bt2.clock_snapshot._create_clock_snapshot_from_ptr(clock_snapshot_ptr)
271 return clock_snapshot
71fd6f52 272
4b552f8b
SM
273 def add(self, clock_snapshot):
274 utils._check_type(clock_snapshot, bt2.clock_snapshot._ClockSnapshot)
275 ret = native_bt.message_inactivity_set_clock_snapshot(self._msg._ptr,
276 clock_snapshot._ptr)
5602ef81 277 utils._handle_ret(ret, "cannot set inactivity message object's clock value")
71fd6f52
PP
278
279 def __len__(self):
5602ef81 280 return len(self._msg.clock_class_priority_map)
71fd6f52
PP
281
282 def __iter__(self):
4b552f8b 283 return _InactivityMessageClockSnapshotsIterator(self)
71fd6f52
PP
284
285
5602ef81 286class InactivityMessage(_CopyableMessage):
88f3724d 287 _TYPE = native_bt.MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY
81447b5b 288
811644b8
PP
289 def __init__(self, cc_prio_map=None):
290 if cc_prio_map is not None:
291 utils._check_type(cc_prio_map, bt2.clock_class_priority_map.ClockClassPriorityMap)
292 cc_prio_map_ptr = cc_prio_map._ptr
293 else:
294 cc_prio_map_ptr = None
81447b5b 295
5602ef81 296 ptr = native_bt.message_inactivity_create(cc_prio_map_ptr)
81447b5b
PP
297
298 if ptr is None:
5602ef81 299 raise bt2.CreationError('cannot create inactivity message object')
81447b5b
PP
300
301 super().__init__(ptr)
302
303 @property
811644b8 304 def clock_class_priority_map(self):
5602ef81 305 cc_prio_map_ptr = native_bt.message_inactivity_get_clock_class_priority_map(self._ptr)
811644b8
PP
306 assert(cc_prio_map_ptr)
307 return bt2.clock_class_priority_map.ClockClassPriorityMap._create_from_ptr(cc_prio_map_ptr)
308
71fd6f52 309 @property
4b552f8b
SM
310 def clock_snapshots(self):
311 return _InactivityMessageClockSnapshots(self)
811644b8 312
4b552f8b
SM
313 def _get_clock_snapshots(self):
314 clock_snapshots = {}
811644b8 315
4b552f8b
SM
316 for clock_class, clock_snapshot in self.clock_snapshots.items():
317 if clock_snapshot is None:
811644b8
PP
318 continue
319
4b552f8b 320 clock_snapshots[clock_class] = clock_snapshot
811644b8 321
4b552f8b 322 return clock_snapshots
811644b8
PP
323
324 def __eq__(self, other):
325 if type(other) is not type(self):
326 return False
327
328 if self.addr == other.addr:
329 return True
330
331 self_props = (
332 self.clock_class_priority_map,
4b552f8b 333 self._get_clock_snapshots(),
811644b8
PP
334 )
335 other_props = (
336 other.clock_class_priority_map,
4b552f8b 337 other._get_clock_snapshots(),
811644b8
PP
338 )
339 return self_props == other_props
340
341 def __copy__(self):
5602ef81 342 cpy = InactivityMessage(self.clock_class_priority_map)
811644b8 343
4b552f8b
SM
344 for clock_class, clock_snapshot in self.clock_snapshots.items():
345 if clock_snapshot is None:
811644b8
PP
346 continue
347
4b552f8b 348 cpy.clock_snapshots.add(clock_snapshot)
811644b8
PP
349
350 return cpy
351
352 def __deepcopy__(self, memo):
353 cc_prio_map_cpy = copy.deepcopy(self.clock_class_priority_map)
5602ef81 354 cpy = InactivityMessage(cc_prio_map_cpy)
811644b8
PP
355
356 # copy clock values
357 for orig_clock_class in self.clock_class_priority_map:
4b552f8b 358 orig_clock_snapshot = self.clock_snapshot(orig_clock_class)
811644b8 359
4b552f8b 360 if orig_clock_snapshot is None:
811644b8
PP
361 continue
362
363 # find equivalent, copied clock class in CC priority map copy
364 for cpy_clock_class in cc_prio_map_cpy:
365 if cpy_clock_class == orig_clock_class:
366 break
367
368 # create copy of clock value from copied clock class
4b552f8b 369 clock_snapshot_cpy = cpy_clock_class(orig_clock_snapshot.cycles)
811644b8 370
5602ef81 371 # set copied clock value in message copy
4b552f8b 372 cpy.clock_snapshots.add(clock_snapshot_cpy)
811644b8
PP
373
374 memo[id(self)] = cpy
375 return cpy
376
377
5602ef81 378class _DiscardedElementsMessage(_Message):
811644b8
PP
379 def __eq__(self, other):
380 if type(other) is not type(self):
381 return False
382
383 if self.addr == other.addr:
384 return True
385
386 self_props = (
387 self.count,
388 self.stream,
4b552f8b
SM
389 self.beginning_clock_snapshot,
390 self.end_clock_snapshot,
811644b8
PP
391 )
392 other_props = (
393 other.count,
394 other.stream,
4b552f8b
SM
395 other.beginning_clock_snapshot,
396 other.end_clock_snapshot,
811644b8
PP
397 )
398 return self_props == other_props
399
400
5602ef81 401class _DiscardedPacketsMessage(_DiscardedElementsMessage):
88f3724d 402 _TYPE = native_bt.MESSAGE_TYPE_DISCARDED_PACKETS
811644b8
PP
403
404 @property
405 def count(self):
5602ef81 406 count = native_bt.message_discarded_packets_get_count(self._ptr)
811644b8
PP
407 assert(count >= 0)
408 return count
409
410 @property
411 def stream(self):
5602ef81 412 stream_ptr = native_bt.message_discarded_packets_get_stream(self._ptr)
811644b8
PP
413 assert(stream_ptr)
414 return bt2.stream._create_from_ptr(stream_ptr)
415
416 @property
4b552f8b
SM
417 def beginning_clock_snapshot(self):
418 clock_snapshot_ptr = native_bt.message_discarded_packets_get_begin_clock_snapshot(self._ptr)
811644b8 419
4b552f8b 420 if clock_snapshot_ptr is None:
811644b8
PP
421 return
422
4b552f8b
SM
423 clock_snapshot = bt2.clock_snapshot._create_clock_snapshot_from_ptr(clock_snapshot_ptr)
424 return clock_snapshot
811644b8
PP
425
426 @property
4b552f8b
SM
427 def end_clock_snapshot(self):
428 clock_snapshot_ptr = native_bt.message_discarded_packets_get_end_clock_snapshot(self._ptr)
811644b8 429
4b552f8b 430 if clock_snapshot_ptr is None:
811644b8
PP
431 return
432
4b552f8b
SM
433 clock_snapshot = bt2.clock_snapshot._create_clock_snapshot_from_ptr(clock_snapshot_ptr)
434 return clock_snapshot
811644b8
PP
435
436
5602ef81 437class _DiscardedEventsMessage(_DiscardedElementsMessage):
88f3724d 438 _TYPE = native_bt.MESSAGE_TYPE_DISCARDED_EVENTS
811644b8
PP
439
440 @property
441 def count(self):
5602ef81 442 count = native_bt.message_discarded_events_get_count(self._ptr)
811644b8
PP
443 assert(count >= 0)
444 return count
445
446 @property
447 def stream(self):
5602ef81 448 stream_ptr = native_bt.message_discarded_events_get_stream(self._ptr)
811644b8
PP
449 assert(stream_ptr)
450 return bt2.stream._create_from_ptr(stream_ptr)
451
452 @property
4b552f8b
SM
453 def beginning_clock_snapshot(self):
454 clock_snapshot_ptr = native_bt.message_discarded_events_get_begin_clock_snapshot(self._ptr)
811644b8 455
4b552f8b 456 if clock_snapshot_ptr is None:
811644b8
PP
457 return
458
4b552f8b
SM
459 clock_snapshot = bt2.clock_snapshot._create_clock_snapshot_from_ptr(clock_snapshot_ptr)
460 return clock_snapshot
811644b8
PP
461
462 @property
4b552f8b
SM
463 def end_clock_snapshot(self):
464 clock_snapshot_ptr = native_bt.message_discarded_events_get_end_clock_snapshot(self._ptr)
811644b8 465
4b552f8b 466 if clock_snapshot_ptr is None:
811644b8
PP
467 return
468
4b552f8b
SM
469 clock_snapshot = bt2.clock_snapshot._create_clock_snapshot_from_ptr(clock_snapshot_ptr)
470 return clock_snapshot
81447b5b
PP
471
472
5602ef81 473_MESSAGE_TYPE_TO_CLS = {
2ae9f48c
SM
474 native_bt.MESSAGE_TYPE_EVENT: _EventMessage,
475 native_bt.MESSAGE_TYPE_PACKET_BEGINNING: _PacketBeginningMessage,
5602ef81 476 native_bt.MESSAGE_TYPE_PACKET_END: PacketEndMessage,
2ae9f48c 477 native_bt.MESSAGE_TYPE_STREAM_BEGINNING: _StreamBeginningMessage,
5602ef81
SM
478 native_bt.MESSAGE_TYPE_STREAM_END: StreamEndMessage,
479 native_bt.MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: InactivityMessage,
480 native_bt.MESSAGE_TYPE_DISCARDED_PACKETS: _DiscardedPacketsMessage,
481 native_bt.MESSAGE_TYPE_DISCARDED_EVENTS: _DiscardedEventsMessage,
81447b5b 482}
This page took 0.058975 seconds and 4 git commands to generate.