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