X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bindings%2Fpython%2Fbt2%2Fbt2%2Fmessage.py;h=56b545daa98faf1c0220f424b5e2dd8f6cec7aec;hb=68b66a256a54d32992dfefeaad11eea88b7df234;hp=272443c1208744e14772af4717d082c8e0f1c3b9;hpb=5602ef8155de326402dcb33f40ee4c7d5d693ca5;p=babeltrace.git diff --git a/bindings/python/bt2/bt2/message.py b/bindings/python/bt2/bt2/message.py index 272443c1..56b545da 100644 --- a/bindings/python/bt2/bt2/message.py +++ b/bindings/python/bt2/bt2/message.py @@ -21,19 +21,15 @@ # THE SOFTWARE. from bt2 import native_bt, object, utils -import bt2.clock_class_priority_map -import bt2.clock_value -import collections +import bt2.clock_snapshot import bt2.packet import bt2.stream import bt2.event -import copy import bt2 def _create_from_ptr(ptr): msg_type = native_bt.message_get_type(ptr) - cls = None if msg_type not in _MESSAGE_TYPE_TO_CLS: raise bt2.Error('unknown message type: {}'.format(msg_type)) @@ -41,465 +37,200 @@ def _create_from_ptr(ptr): return _MESSAGE_TYPE_TO_CLS[msg_type]._create_from_ptr(ptr) -def _msg_types_from_msg_classes(message_types): - if message_types is None: - msg_types = None - else: - for msg_cls in message_types: - if msg_cls not in _MESSAGE_TYPE_TO_CLS.values(): - raise ValueError("'{}' is not a message class".format(msg_cls)) +class _Message(object._SharedObject): + _get_ref = staticmethod(native_bt.message_get_ref) + _put_ref = staticmethod(native_bt.message_put_ref) - msg_types = [msg_cls._TYPE for msg_cls in message_types] + @staticmethod + def _check_has_default_clock_class(clock_class): + if clock_class is None: + raise bt2.NonexistentClockSnapshot('cannot get default clock snapshot: stream class has no default clock class') - return msg_types +class _MessageWithDefaultClockSnapshot: + def _get_default_clock_snapshot(self, borrow_clock_snapshot_ptr): + snapshot_ptr = borrow_clock_snapshot_ptr(self._ptr) -class _Message(object._Object): - pass + return bt2.clock_snapshot._ClockSnapshot._create_from_ptr_and_get_ref( + snapshot_ptr, self._ptr, self._get_ref, self._put_ref) -class _CopyableMessage(_Message): - def __copy__(self): - return self._copy(lambda obj: obj) - - def __deepcopy__(self, memo): - cpy = self._copy(copy.deepcopy) - memo[id(self)] = cpy - return cpy - - -class EventMessage(_CopyableMessage): - _TYPE = native_bt.MESSAGE_TYPE_EVENT - - def __init__(self, event, cc_prio_map=None): - utils._check_type(event, bt2.event._Event) - - if cc_prio_map is not None: - utils._check_type(cc_prio_map, bt2.clock_class_priority_map.ClockClassPriorityMap) - cc_prio_map_ptr = cc_prio_map._ptr - else: - cc_prio_map_ptr = None - - ptr = native_bt.message_event_create(event._ptr, cc_prio_map_ptr) - - if ptr is None: - raise bt2.CreationError('cannot create event message object') - - super().__init__(ptr) +class _EventMessage(_Message, _MessageWithDefaultClockSnapshot): + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_event_borrow_default_clock_snapshot_const) @property - def event(self): - event_ptr = native_bt.message_event_get_event(self._ptr) - assert(event_ptr) - return bt2.event._create_from_ptr(event_ptr) + def default_clock_snapshot(self): + self._check_has_default_clock_class(self.event.packet.stream.cls.default_clock_class) + return self._get_default_clock_snapshot(self._borrow_default_clock_snapshot_ptr) @property - def clock_class_priority_map(self): - cc_prio_map_ptr = native_bt.message_event_get_clock_class_priority_map(self._ptr) - assert(cc_prio_map_ptr) - return bt2.clock_class_priority_map.ClockClassPriorityMap._create_from_ptr(cc_prio_map_ptr) - - def __eq__(self, other): - if type(other) is not type(self): - return False - - if self.addr == other.addr: - return True - - self_props = ( - self.event, - self.clock_class_priority_map, - ) - other_props = ( - other.event, - other.clock_class_priority_map, - ) - return self_props == other_props - - def _copy(self, copy_func): - # We can always use references here because those properties are - # frozen anyway if they are part of a message. Since the - # user cannot modify them after copying the message, it's - # useless to copy/deep-copy them. - return EventMessage(self.event, self.clock_class_priority_map) - - -class PacketBeginningMessage(_CopyableMessage): - _TYPE = native_bt.MESSAGE_TYPE_PACKET_BEGINNING - - def __init__(self, packet): - utils._check_type(packet, bt2.packet._Packet) - ptr = native_bt.message_packet_begin_create(packet._ptr) - - if ptr is None: - raise bt2.CreationError('cannot create packet beginning message object') + def event(self): + event_ptr = native_bt.message_event_borrow_event(self._ptr) + assert event_ptr is not None + return bt2.event._Event._create_from_ptr_and_get_ref( + event_ptr, self._ptr, self._get_ref, self._put_ref) - super().__init__(ptr) +class _PacketMessage(_Message, _MessageWithDefaultClockSnapshot): @property - def packet(self): - packet_ptr = native_bt.message_packet_begin_get_packet(self._ptr) - assert(packet_ptr) - return bt2.packet._Packet._create_from_ptr(packet_ptr) - - def __eq__(self, other): - if type(other) is not type(self): - return False - - if self.addr == other.addr: - return True - - return self.packet == other.packet - - def _copy(self, copy_func): - # We can always use references here because those properties are - # frozen anyway if they are part of a message. Since the - # user cannot modify them after copying the message, it's - # useless to copy/deep-copy them. - return PacketBeginningMessage(self.packet) - - -class PacketEndMessage(_CopyableMessage): - _TYPE = native_bt.MESSAGE_TYPE_PACKET_END - - def __init__(self, packet): - utils._check_type(packet, bt2.packet._Packet) - ptr = native_bt.message_packet_end_create(packet._ptr) - - if ptr is None: - raise bt2.CreationError('cannot create packet end message object') - - super().__init__(ptr) + def default_clock_snapshot(self): + self._check_has_default_clock_class(self.packet.stream.cls.default_clock_class) + return self._get_default_clock_snapshot(self._borrow_default_clock_snapshot_ptr) @property def packet(self): - packet_ptr = native_bt.message_packet_end_get_packet(self._ptr) - assert(packet_ptr) - return bt2.packet._Packet._create_from_ptr(packet_ptr) + packet_ptr = self._borrow_packet_ptr(self._ptr) + assert packet_ptr is not None + return bt2.packet._Packet._create_from_ptr_and_get_ref(packet_ptr) - def __eq__(self, other): - if type(other) is not type(self): - return False - if self.addr == other.addr: - return True +class _PacketBeginningMessage(_PacketMessage): + _borrow_packet_ptr = staticmethod(native_bt.message_packet_beginning_borrow_packet) + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_packet_beginning_borrow_default_clock_snapshot_const) - return self.packet == other.packet - def _copy(self, copy_func): - # We can always use references here because those properties are - # frozen anyway if they are part of a message. Since the - # user cannot modify them after copying the message, it's - # useless to copy/deep-copy them. - return PacketEndMessage(self.packet) +class _PacketEndMessage(_PacketMessage): + _borrow_packet_ptr = staticmethod(native_bt.message_packet_end_borrow_packet) + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_packet_end_borrow_default_clock_snapshot_const) -class StreamBeginningMessage(_CopyableMessage): - _TYPE = native_bt.MESSAGE_TYPE_STREAM_BEGINNING - - def __init__(self, stream): - utils._check_type(stream, bt2.stream._Stream) - ptr = native_bt.message_stream_begin_create(stream._ptr) - - if ptr is None: - raise bt2.CreationError('cannot create stream beginning message object') - - super().__init__(ptr) - +class _StreamMessage(_Message): @property def stream(self): - stream_ptr = native_bt.message_stream_begin_get_stream(self._ptr) - assert(stream_ptr) - return bt2.stream._create_from_ptr(stream_ptr) - - def __eq__(self, other): - if type(other) is not type(self): - return False - - if self.addr == other.addr: - return True + stream_ptr = self._borrow_stream_ptr(self._ptr) + assert stream_ptr + return bt2.stream._Stream._create_from_ptr_and_get_ref(stream_ptr) - return self.stream == other.stream - def _copy(self, copy_func): - # We can always use references here because those properties are - # frozen anyway if they are part of a message. Since the - # user cannot modify them after copying the message, it's - # useless to copy/deep-copy them. - return StreamBeginningMessage(self.stream) +class _StreamBeginningMessage(_StreamMessage): + _borrow_stream_ptr = staticmethod(native_bt.message_stream_beginning_borrow_stream) -class StreamEndMessage(_CopyableMessage): - _TYPE = native_bt.MESSAGE_TYPE_STREAM_END +class _StreamEndMessage(_StreamMessage): + _borrow_stream_ptr = staticmethod(native_bt.message_stream_end_borrow_stream) - def __init__(self, stream): - utils._check_type(stream, bt2.stream._Stream) - ptr = native_bt.message_stream_end_create(stream._ptr) - - if ptr is None: - raise bt2.CreationError('cannot create stream end message object') - - super().__init__(ptr) +class _StreamActivityMessage(_Message): @property - def stream(self): - stream_ptr = native_bt.message_stream_end_get_stream(self._ptr) - assert(stream_ptr) - return bt2.stream._create_from_ptr(stream_ptr) - - def __eq__(self, other): - if type(other) is not type(self): - return False - - if self.addr == other.addr: - return True - - return self.stream == other.stream - - def _copy(self, copy_func): - # We can always use references here because those properties are - # frozen anyway if they are part of a message. Since the - # user cannot modify them after copying the message, it's - # useless to copy/deep-copy them. - return StreamEndMessage(self.stream) - - -class _InactivityMessageClockValuesIterator(collections.abc.Iterator): - def __init__(self, msg_clock_values): - self._msg_clock_values = msg_clock_values - self._clock_classes = list(msg_clock_values._msg.clock_class_priority_map) - self._at = 0 - - def __next__(self): - if self._at == len(self._clock_classes): - raise StopIteration - - self._at += 1 - return self._clock_classes[at] + def default_clock_snapshot(self): + self._check_has_default_clock_class(self.stream.cls.default_clock_class) + status, snapshot_ptr = self._borrow_default_clock_snapshot_ptr(self._ptr) - -class _InactivityMessageClockValues(collections.abc.Mapping): - def __init__(self, msg): - self._msg = msg - - def __getitem__(self, clock_class): - utils._check_type(clock_class, bt2.ClockClass) - clock_value_ptr = native_bt.message_inactivity_get_clock_value(self._msg._ptr, - clock_class._ptr) - - if clock_value_ptr is None: - return - - clock_value = bt2.clock_value._create_clock_value_from_ptr(clock_value_ptr) - return clock_value - - def add(self, clock_value): - utils._check_type(clock_value, bt2.clock_value._ClockValue) - ret = native_bt.message_inactivity_set_clock_value(self._msg._ptr, - clock_value._ptr) - utils._handle_ret(ret, "cannot set inactivity message object's clock value") - - def __len__(self): - return len(self._msg.clock_class_priority_map) - - def __iter__(self): - return _InactivityMessageClockValuesIterator(self) - - -class InactivityMessage(_CopyableMessage): - _TYPE = native_bt.MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY - - def __init__(self, cc_prio_map=None): - if cc_prio_map is not None: - utils._check_type(cc_prio_map, bt2.clock_class_priority_map.ClockClassPriorityMap) - cc_prio_map_ptr = cc_prio_map._ptr + if status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: + snapshot_type = bt2.clock_snapshot._ClockSnapshot + elif status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: + snapshot_type = bt2.clock_snapshot._UnknownClockSnapshot + elif status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: + snapshot_type = bt2.clock_snapshot._InfiniteClockSnapshot else: - cc_prio_map_ptr = None + raise bt2.Error('cannot borrow default clock snapshot from message') - ptr = native_bt.message_inactivity_create(cc_prio_map_ptr) + assert snapshot_ptr is not None - if ptr is None: - raise bt2.CreationError('cannot create inactivity message object') + return snapshot_type._create_from_ptr_and_get_ref( + snapshot_ptr, self._ptr, self._get_ref, self._put_ref) - super().__init__(ptr) + def _default_clock_snapshot(self, value): + self._set_default_clock_snapshot_ptr(self._ptr, value) - @property - def clock_class_priority_map(self): - cc_prio_map_ptr = native_bt.message_inactivity_get_clock_class_priority_map(self._ptr) - assert(cc_prio_map_ptr) - return bt2.clock_class_priority_map.ClockClassPriorityMap._create_from_ptr(cc_prio_map_ptr) + _default_clock_snapshot = property(fset=_default_clock_snapshot) @property - def clock_values(self): - return _InactivityMessageClockValues(self) - - def _get_clock_values(self): - clock_values = {} - - for clock_class, clock_value in self.clock_values.items(): - if clock_value is None: - continue - - clock_values[clock_class] = clock_value - - return clock_values - - def __eq__(self, other): - if type(other) is not type(self): - return False - - if self.addr == other.addr: - return True - - self_props = ( - self.clock_class_priority_map, - self._get_clock_values(), - ) - other_props = ( - other.clock_class_priority_map, - other._get_clock_values(), - ) - return self_props == other_props - - def __copy__(self): - cpy = InactivityMessage(self.clock_class_priority_map) - - for clock_class, clock_value in self.clock_values.items(): - if clock_value is None: - continue - - cpy.clock_values.add(clock_value) - - return cpy - - def __deepcopy__(self, memo): - cc_prio_map_cpy = copy.deepcopy(self.clock_class_priority_map) - cpy = InactivityMessage(cc_prio_map_cpy) - - # copy clock values - for orig_clock_class in self.clock_class_priority_map: - orig_clock_value = self.clock_value(orig_clock_class) - - if orig_clock_value is None: - continue - - # find equivalent, copied clock class in CC priority map copy - for cpy_clock_class in cc_prio_map_cpy: - if cpy_clock_class == orig_clock_class: - break - - # create copy of clock value from copied clock class - clock_value_cpy = cpy_clock_class(orig_clock_value.cycles) - - # set copied clock value in message copy - cpy.clock_values.add(clock_value_cpy) - - memo[id(self)] = cpy - return cpy + def stream(self): + stream_ptr = self._borrow_stream_ptr(self._ptr) + assert stream_ptr + return bt2.stream._Stream._create_from_ptr_and_get_ref(stream_ptr) -class _DiscardedElementsMessage(_Message): - def __eq__(self, other): - if type(other) is not type(self): - return False +class _StreamActivityBeginningMessage(_StreamActivityMessage): + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_activity_beginning_borrow_default_clock_snapshot_const) + _set_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_activity_beginning_set_default_clock_snapshot) + _borrow_stream_ptr = staticmethod(native_bt.message_stream_activity_beginning_borrow_stream) - if self.addr == other.addr: - return True - self_props = ( - self.count, - self.stream, - self.beginning_clock_value, - self.end_clock_value, - ) - other_props = ( - other.count, - other.stream, - other.beginning_clock_value, - other.end_clock_value, - ) - return self_props == other_props +class _StreamActivityEndMessage(_StreamActivityMessage): + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_activity_end_borrow_default_clock_snapshot_const) + _set_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_activity_end_set_default_clock_snapshot) + _borrow_stream_ptr = staticmethod(native_bt.message_stream_activity_end_borrow_stream) -class _DiscardedPacketsMessage(_DiscardedElementsMessage): - _TYPE = native_bt.MESSAGE_TYPE_DISCARDED_PACKETS +class _MessageIteratorInactivityMessage(_Message, _MessageWithDefaultClockSnapshot): + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_message_iterator_inactivity_borrow_default_clock_snapshot_const) @property - def count(self): - count = native_bt.message_discarded_packets_get_count(self._ptr) - assert(count >= 0) - return count + def default_clock_snapshot(self): + # This kind of message always has a default clock class: no + # need to call self._check_has_default_clock_class() here. + return self._get_default_clock_snapshot(self._borrow_default_clock_snapshot_ptr) - @property - def stream(self): - stream_ptr = native_bt.message_discarded_packets_get_stream(self._ptr) - assert(stream_ptr) - return bt2.stream._create_from_ptr(stream_ptr) +class _DiscardedMessage(_Message, _MessageWithDefaultClockSnapshot): @property - def beginning_clock_value(self): - clock_value_ptr = native_bt.message_discarded_packets_get_begin_clock_value(self._ptr) - - if clock_value_ptr is None: - return - - clock_value = bt2.clock_value._create_clock_value_from_ptr(clock_value_ptr) - return clock_value + def stream(self): + stream_ptr = self._borrow_stream_ptr(self._ptr) + assert stream_ptr + return bt2.stream._Stream._create_from_ptr_and_get_ref(stream_ptr) @property - def end_clock_value(self): - clock_value_ptr = native_bt.message_discarded_packets_get_end_clock_value(self._ptr) - - if clock_value_ptr is None: - return + def count(self): + avail, count = self._get_count(self._ptr) + if avail is native_bt.PROPERTY_AVAILABILITY_AVAILABLE: + return count - clock_value = bt2.clock_value._create_clock_value_from_ptr(clock_value_ptr) - return clock_value + def _set_count(self, count): + utils._check_uint64(count) + self._set_count(self._ptr, count) + _count = property(fset=_set_count) -class _DiscardedEventsMessage(_DiscardedElementsMessage): - _TYPE = native_bt.MESSAGE_TYPE_DISCARDED_EVENTS + def _check_has_default_clock_snapshots(self): + if not self._has_default_clock_snapshots: + raise bt2.NonexistentClockSnapshot('cannot get default clock snapshot: such a message has no clock snapshots for this stream class') @property - def count(self): - count = native_bt.message_discarded_events_get_count(self._ptr) - assert(count >= 0) - return count + def beginning_default_clock_snapshot(self): + self._check_has_default_clock_snapshots() + return self._get_default_clock_snapshot(self._borrow_beginning_clock_snapshot_ptr) @property - def stream(self): - stream_ptr = native_bt.message_discarded_events_get_stream(self._ptr) - assert(stream_ptr) - return bt2.stream._create_from_ptr(stream_ptr) + def end_default_clock_snapshot(self): + self._check_has_default_clock_snapshots() + return self._get_default_clock_snapshot(self._borrow_end_clock_snapshot_ptr) - @property - def beginning_clock_value(self): - clock_value_ptr = native_bt.message_discarded_events_get_begin_clock_value(self._ptr) - if clock_value_ptr is None: - return - - clock_value = bt2.clock_value._create_clock_value_from_ptr(clock_value_ptr) - return clock_value +class _DiscardedEventsMessage(_DiscardedMessage): + _borrow_stream_ptr = staticmethod(native_bt.message_discarded_events_borrow_stream_const) + _get_count = staticmethod(native_bt.message_discarded_events_get_count) + _set_count = staticmethod(native_bt.message_discarded_events_set_count) + _borrow_beginning_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_events_borrow_beginning_default_clock_snapshot_const) + _borrow_end_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_events_borrow_end_default_clock_snapshot_const) @property - def end_clock_value(self): - clock_value_ptr = native_bt.message_discarded_events_get_end_clock_value(self._ptr) + def _has_default_clock_snapshots(self): + return self.stream.cls.discarded_events_have_default_clock_snapshots + - if clock_value_ptr is None: - return +class _DiscardedPacketsMessage(_DiscardedMessage): + _borrow_stream_ptr = staticmethod(native_bt.message_discarded_packets_borrow_stream_const) + _get_count = staticmethod(native_bt.message_discarded_packets_get_count) + _set_count = staticmethod(native_bt.message_discarded_packets_set_count) + _borrow_beginning_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_packets_borrow_beginning_default_clock_snapshot_const) + _borrow_end_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_packets_borrow_end_default_clock_snapshot_const) - clock_value = bt2.clock_value._create_clock_value_from_ptr(clock_value_ptr) - return clock_value + @property + def _has_default_clock_snapshots(self): + return self.stream.cls.discarded_packets_have_default_clock_snapshots _MESSAGE_TYPE_TO_CLS = { - native_bt.MESSAGE_TYPE_EVENT: EventMessage, - native_bt.MESSAGE_TYPE_PACKET_BEGINNING: PacketBeginningMessage, - native_bt.MESSAGE_TYPE_PACKET_END: PacketEndMessage, - native_bt.MESSAGE_TYPE_STREAM_BEGINNING: StreamBeginningMessage, - native_bt.MESSAGE_TYPE_STREAM_END: StreamEndMessage, - native_bt.MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: InactivityMessage, - native_bt.MESSAGE_TYPE_DISCARDED_PACKETS: _DiscardedPacketsMessage, + native_bt.MESSAGE_TYPE_EVENT: _EventMessage, + native_bt.MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: _MessageIteratorInactivityMessage, + native_bt.MESSAGE_TYPE_STREAM_BEGINNING: _StreamBeginningMessage, + native_bt.MESSAGE_TYPE_STREAM_END: _StreamEndMessage, + native_bt.MESSAGE_TYPE_PACKET_BEGINNING: _PacketBeginningMessage, + native_bt.MESSAGE_TYPE_PACKET_END: _PacketEndMessage, + native_bt.MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: _StreamActivityBeginningMessage, + native_bt.MESSAGE_TYPE_STREAM_ACTIVITY_END: _StreamActivityEndMessage, native_bt.MESSAGE_TYPE_DISCARDED_EVENTS: _DiscardedEventsMessage, + native_bt.MESSAGE_TYPE_DISCARDED_PACKETS: _DiscardedPacketsMessage, }