-__init__.py
-native_bt.py
-native_bt_wrap.c
+bt2/__init__.py
+bt2/native_bt.py
+bt2/native_bt_wrap.c
+build
+build-python-bindings.stamp
+installed_files.txt
+setup.py
-# native module name (without `.i` extension)
-NATIVE_MODULE = native_bt
+# Since the shared object used by the python bindings is not built with
+# libtool, we need to add the directory containing libbabeltrace to the
+# linker path.
+AM_LDFLAGS=-L$(top_builddir)/lib/.libs
-# interface dependencies (without `native_bt` prefix and `.i` extension)
-NATIVE_MODULE_DEPS = \
- ccpriomap \
- clockclass \
- component \
- componentclass \
- connection \
- ctfwriter \
- event \
- eventclass \
- fields \
- ft \
- graph \
- logging \
- notification \
- notifiter \
- packet \
- plugin \
- port \
- ref \
- stream \
- streamclass \
- trace \
- values \
- version
+INSTALLED_FILES=$(builddir)/installed_files.txt
-# Python modules (without `.py` extension)
-EXTRA_MODULES = \
- clock_class \
- clock_class_priority_map \
- component \
- connection \
- ctf_writer \
- event \
- event_class \
- field_types \
- fields \
- graph \
- logging \
- notification \
- notification_iterator \
- object \
- packet \
- plugin \
- port \
- py_plugin \
- stream \
- stream_class \
- trace \
- utils \
- values
+STATIC_BINDINGS_DEPS = \
+ bt2/logging.c \
+ bt2/logging.h \
+ bt2/native_btccpriomap.i \
+ bt2/native_btclockclass.i \
+ bt2/native_btcomponentclass.i \
+ bt2/native_btcomponent.i \
+ bt2/native_btconnection.i \
+ bt2/native_btctfwriter.i \
+ bt2/native_bteventclass.i \
+ bt2/native_btevent.i \
+ bt2/native_btfields.i \
+ bt2/native_btft.i \
+ bt2/native_btgraph.i \
+ bt2/native_bt.i \
+ bt2/native_btlogging.i \
+ bt2/native_btnotification.i \
+ bt2/native_btnotifiter.i \
+ bt2/native_btpacket.i \
+ bt2/native_btplugin.i \
+ bt2/native_btport.i \
+ bt2/native_btref.i \
+ bt2/native_btstreamclass.i \
+ bt2/native_btstream.i \
+ bt2/native_bttrace.i \
+ bt2/native_btvalues.i \
+ bt2/native_btversion.i \
+ bt2/clock_class_priority_map.py \
+ bt2/clock_class.py \
+ bt2/component.py \
+ bt2/connection.py \
+ bt2/ctf_writer.py \
+ bt2/event_class.py \
+ bt2/event.py \
+ bt2/fields.py \
+ bt2/field_types.py \
+ bt2/graph.py \
+ bt2/logging.py \
+ bt2/notification_iterator.py \
+ bt2/notification.py \
+ bt2/object.py \
+ bt2/packet.py \
+ bt2/plugin.py \
+ bt2/port.py \
+ bt2/py_plugin.py \
+ bt2/stream_class.py \
+ bt2/stream.py \
+ bt2/trace.py \
+ bt2/utils.py \
+ bt2/values.py
-# automatically generated file lists
-EXTRA_MODULES_PY = $(addprefix $(srcdir)/,$(addsuffix .py,$(EXTRA_MODULES)))
-NATIVE_MODULE_I = $(srcdir)/$(NATIVE_MODULE).i
-NATIVE_MODULE_PY = $(NATIVE_MODULE).py
-NATIVE_MODULE_C = $(NATIVE_MODULE)_wrap.c
-NATIVE_MODULE_DEPS_I = $(addprefix $(srcdir)/native_bt,$(addsuffix .i,$(NATIVE_MODULE_DEPS)))
+GENERATED_BINDINGS_DEPS = \
+ bt2/__init__.py \
+ setup.py
-# installed Python package
-nodist_bt2package_PYTHON = __init__.py $(EXTRA_MODULES_PY) $(NATIVE_MODULE_PY)
+BUILD_FLAGS=CC="$(CC)" \
+ CFLAGS="$(GLIB_CFLAGS) $(AM_CFLAGS) $(CFLAGS)" \
+ CPPFLAGS="$(AM_CPPFLAGS) $(CPPFLAGS)" \
+ LDFLAGS="$(AM_LDFLAGS) $(LDFLAGS) $(GLIB_LIBS) $(LIBS)"
-# native libraries to build
-nativelibs_LTLIBRARIES = _native_bt.la
+all-local: build-python-bindings.stamp
-# installation directory for the `bt2` package
-bt2packagedir = $(pythondir)/bt2
-nativelibsdir = $(bt2packagedir)
+build-python-bindings.stamp: $(STATIC_BINDINGS_DEPS) $(GENERATED_BINDINGS_DEPS)
+ $(BUILD_FLAGS) $(PYTHON) $(builddir)/setup.py build_ext
+ $(BUILD_FLAGS) $(PYTHON) $(builddir)/setup.py build
+ touch $@
-# SWIG to C wrapper (and Python file)
-$(NATIVE_MODULE_C): $(NATIVE_MODULE_I) $(NATIVE_MODULE_DEPS_I)
- $(SWIG) -python -Wall -I$(srcdir) -I$(top_srcdir)/include -module $(NATIVE_MODULE) -outcurrentdir $(NATIVE_MODULE_I)
+install-exec-local: build-python-bindings.stamp
+ @opts="--prefix=$(prefix) --record $(INSTALLED_FILES) --verbose --no-compile $(DISTSETUPOPTS)"; \
+ if [ "$(DESTDIR)" != "" ]; then \
+ opts="$$opts --root=$(DESTDIR)"; \
+ fi; \
+ $(PYTHON) $(builddir)/setup.py install $$opts;
-# native_bt module
-_native_bt_la_SOURCES = logging.h logging.c
-nodist__native_bt_la_SOURCES = native_bt_wrap.c
-_native_bt_la_LDFLAGS = -module
-_native_bt_la_CFLAGS = $(PYTHON_INCLUDE) -I$(srcdir) $(AM_CFLAGS)
-_native_bt_la_LIBADD = \
- $(top_builddir)/lib/libbabeltrace.la \
- $(top_builddir)/logging/libbabeltrace-logging.la \
- $(top_builddir)/common/libbabeltrace-common.la
-
-# extra module sources -> build directory
-all-local:
- @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
- for file in $(EXTRA_MODULES_PY); do \
- cp -f "$(srcdir)/$$file" "$(builddir)"; \
- done; \
- fi
-
-# clean extra module sources in build directory
clean-local:
- @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
- for file in $(EXTRA_MODULES_PY); do \
- rm -f "$(srcdir)/$$file" "$(builddir)"; \
- done; \
+ rm -rf $(builddir)/build
+
+# Distutils' setup.py does not include an uninstall target, we thus need to do
+# it manually. We save the path of the files that were installed during the install target
+# and delete them during the uninstallation.
+uninstall-local:
+ if [ "$(DESTDIR)" != "" ]; then \
+ $(SED) -i "s|^|$(DESTDIR)/|g" $(INSTALLED_FILES); \
fi
+ cat $(INSTALLED_FILES) | xargs rm -rf || true
+ $(GREP) "__init__.py" $(INSTALLED_FILES) | xargs dirname | xargs rm -rf || true
+ rm -f $(INSTALLED_FILES)
# distribute: extra Python modules and SWIG interface files
-EXTRA_DIST = __init__.py.in $(EXTRA_MODULES_PY) $(NATIVE_MODULE_I) $(NATIVE_MODULE_DEPS_I)
+EXTRA_DIST = $(STATIC_BINDINGS_DEPS)
# clean: generated C and Python files (by SWIG)
-CLEANFILES = $(NATIVE_MODULE_PY) $(NATIVE_MODULE_C)
+CLEANFILES = bt2/native_bt.py bt2/native_bt_wrap.c build-python-bindings.stamp
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-__version__ = '@PACKAGE_VERSION@'
-
-
-from bt2.clock_class import *
-from bt2.clock_class import _ClockValue
-from bt2.clock_class_priority_map import *
-from bt2.component import *
-from bt2.component import _FilterComponent
-from bt2.component import _GenericFilterComponentClass
-from bt2.component import _GenericSinkComponentClass
-from bt2.component import _GenericSourceComponentClass
-from bt2.component import _SinkComponent
-from bt2.component import _SourceComponent
-from bt2.component import _UserFilterComponent
-from bt2.component import _UserSinkComponent
-from bt2.component import _UserSourceComponent
-from bt2.connection import *
-from bt2.connection import _Connection
-from bt2.connection import _PrivateConnection
-from bt2.ctf_writer import *
-from bt2.ctf_writer import _CtfWriterStream
-from bt2.event import _Event
-from bt2.event_class import *
-from bt2.field_types import *
-from bt2.field_types import _FieldType
-from bt2.fields import *
-from bt2.fields import _ArrayField
-from bt2.fields import _EnumerationField
-from bt2.fields import _Field
-from bt2.fields import _FloatingPointNumberField
-from bt2.fields import _IntegerField
-from bt2.fields import _SequenceField
-from bt2.fields import _StringField
-from bt2.fields import _StructureField
-from bt2.fields import _VariantField
-from bt2.graph import *
-from bt2.logging import *
-from bt2.notification import *
-from bt2.notification import _DiscardedEventsNotification
-from bt2.notification import _DiscardedPacketsNotification
-from bt2.notification_iterator import *
-from bt2.notification_iterator import _UserNotificationIterator
-from bt2.packet import _Packet
-from bt2.plugin import *
-from bt2.port import *
-from bt2.port import _InputPort
-from bt2.port import _OutputPort
-from bt2.port import _Port
-from bt2.port import _PrivateInputPort
-from bt2.port import _PrivateOutputPort
-from bt2.port import _PrivatePort
-from bt2.py_plugin import *
-from bt2.stream import _Stream
-from bt2.stream_class import *
-from bt2.trace import *
-from bt2.values import *
-from bt2.values import _Value
-
-
-class Error(Exception):
- pass
-
-
-class CreationError(Error):
- pass
-
-
-class Frozen(Error):
- pass
-
-
-class NoSuchPlugin(Error):
- pass
-
-
-class UnsupportedFeature(Exception):
- pass
-
-
-class NoSinkComponent(Exception):
- pass
-
-
-class TryAgain(Exception):
- pass
-
-
-class Stop(StopIteration):
- pass
-
-
-class PortConnectionRefused(Exception):
- pass
-
-
-class IncompleteUserClass(Error):
- pass
-
-
-class GraphCanceled(Exception):
- pass
-
-
-class NotificationIteratorCanceled(Exception):
- pass
-
-
-class ConnectionEnded(Exception):
- pass
-
-
-class _ListenerHandle:
- def __init__(self, listener_id, obj):
- self._listener_id = listener_id
- self._obj = obj
-
-
-import bt2.native_bt as _native_bt
-import atexit
-
-atexit.register(_native_bt.py3_cc_exit_handler)
-version = (_native_bt.version_get_major(), _native_bt.version_get_minor(),
- _native_bt.version_get_patch(), _native_bt.version_get_extra())
-_native_bt.py3_cc_init_from_bt2()
-del _native_bt
-
-try:
- del native_bt
-except:
- pass
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+__version__ = '@PACKAGE_VERSION@'
+
+
+from bt2.clock_class import *
+from bt2.clock_class import _ClockValue
+from bt2.clock_class_priority_map import *
+from bt2.component import *
+from bt2.component import _FilterComponent
+from bt2.component import _GenericFilterComponentClass
+from bt2.component import _GenericSinkComponentClass
+from bt2.component import _GenericSourceComponentClass
+from bt2.component import _SinkComponent
+from bt2.component import _SourceComponent
+from bt2.component import _UserFilterComponent
+from bt2.component import _UserSinkComponent
+from bt2.component import _UserSourceComponent
+from bt2.connection import *
+from bt2.connection import _Connection
+from bt2.connection import _PrivateConnection
+from bt2.ctf_writer import *
+from bt2.ctf_writer import _CtfWriterStream
+from bt2.event import _Event
+from bt2.event_class import *
+from bt2.field_types import *
+from bt2.field_types import _FieldType
+from bt2.fields import *
+from bt2.fields import _ArrayField
+from bt2.fields import _EnumerationField
+from bt2.fields import _Field
+from bt2.fields import _FloatingPointNumberField
+from bt2.fields import _IntegerField
+from bt2.fields import _SequenceField
+from bt2.fields import _StringField
+from bt2.fields import _StructureField
+from bt2.fields import _VariantField
+from bt2.graph import *
+from bt2.logging import *
+from bt2.notification import *
+from bt2.notification import _DiscardedEventsNotification
+from bt2.notification import _DiscardedPacketsNotification
+from bt2.notification_iterator import *
+from bt2.notification_iterator import _UserNotificationIterator
+from bt2.packet import _Packet
+from bt2.plugin import *
+from bt2.port import *
+from bt2.port import _InputPort
+from bt2.port import _OutputPort
+from bt2.port import _Port
+from bt2.port import _PrivateInputPort
+from bt2.port import _PrivateOutputPort
+from bt2.port import _PrivatePort
+from bt2.py_plugin import *
+from bt2.stream import _Stream
+from bt2.stream_class import *
+from bt2.trace import *
+from bt2.values import *
+from bt2.values import _Value
+
+
+class Error(Exception):
+ pass
+
+
+class CreationError(Error):
+ pass
+
+
+class Frozen(Error):
+ pass
+
+
+class NoSuchPlugin(Error):
+ pass
+
+
+class UnsupportedFeature(Exception):
+ pass
+
+
+class NoSinkComponent(Exception):
+ pass
+
+
+class TryAgain(Exception):
+ pass
+
+
+class Stop(StopIteration):
+ pass
+
+
+class PortConnectionRefused(Exception):
+ pass
+
+
+class IncompleteUserClass(Error):
+ pass
+
+
+class GraphCanceled(Exception):
+ pass
+
+
+class NotificationIteratorCanceled(Exception):
+ pass
+
+
+class ConnectionEnded(Exception):
+ pass
+
+
+class _ListenerHandle:
+ def __init__(self, listener_id, obj):
+ self._listener_id = listener_id
+ self._obj = obj
+
+
+import bt2.native_bt as _native_bt
+import atexit
+
+atexit.register(_native_bt.py3_cc_exit_handler)
+version = (_native_bt.version_get_major(), _native_bt.version_get_minor(),
+ _native_bt.version_get_patch(), _native_bt.version_get_extra())
+_native_bt.py3_cc_init_from_bt2()
+del _native_bt
+
+try:
+ del native_bt
+except:
+ pass
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import uuid as uuidp
+import numbers
+import bt2
+
+
+class ClockClassOffset:
+ def __init__(self, seconds=0, cycles=0):
+ utils._check_int64(seconds)
+ utils._check_int64(cycles)
+ self._seconds = seconds
+ self._cycles = cycles
+
+ @property
+ def seconds(self):
+ return self._seconds
+
+ @property
+ def cycles(self):
+ return self._cycles
+
+ def __hash__(self):
+ return hash((self.seconds, self.cycles))
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ # not comparing apples to apples
+ return False
+
+ return (self.seconds, self.cycles) == (other.seconds, other.cycles)
+
+
+class ClockClass(object._Object):
+ def __init__(self, name, frequency, description=None, precision=None,
+ offset=None, is_absolute=None, uuid=None):
+ utils._check_str(name)
+ utils._check_uint64(frequency)
+ ptr = native_bt.ctf_clock_class_create(name, frequency)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create clock class object')
+
+ super().__init__(ptr)
+
+ if description is not None:
+ self.description = description
+
+ if frequency is not None:
+ self.frequency = frequency
+
+ if precision is not None:
+ self.precision = precision
+
+ if offset is not None:
+ self.offset = offset
+
+ if is_absolute is not None:
+ self.is_absolute = is_absolute
+
+ if uuid is not None:
+ self.uuid = uuid
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ # not comparing apples to apples
+ return False
+
+ self_props = (
+ self.name,
+ self.description,
+ self.frequency,
+ self.precision,
+ self.offset,
+ self.is_absolute,
+ self.uuid
+ )
+ other_props = (
+ other.name,
+ other.description,
+ other.frequency,
+ other.precision,
+ other.offset,
+ other.is_absolute,
+ other.uuid
+ )
+ return self_props == other_props
+
+ def __copy__(self):
+ return ClockClass(name=self.name, description=self.description,
+ frequency=self.frequency, precision=self.precision,
+ offset=self.offset, is_absolute=self.is_absolute,
+ uuid=self.uuid)
+
+ def __deepcopy__(self, memo):
+ cpy = self.__copy__()
+ memo[id(self)] = cpy
+ return cpy
+
+ def __hash__(self):
+ return hash((
+ self.name,
+ self.description,
+ self.frequency,
+ self.precision,
+ self.offset.seconds,
+ self.offset.cycles,
+ self.is_absolute,
+ self.uuid))
+
+ @property
+ def name(self):
+ name = native_bt.ctf_clock_class_get_name(self._ptr)
+ assert(name is not None)
+ return name
+
+ @name.setter
+ def name(self, name):
+ utils._check_str(name)
+ ret = native_bt.ctf_clock_class_set_name(self._ptr, name)
+ utils._handle_ret(ret, "cannot set clock class object's name")
+
+ @property
+ def description(self):
+ return native_bt.ctf_clock_class_get_description(self._ptr)
+
+ @description.setter
+ def description(self, description):
+ utils._check_str(description)
+ ret = native_bt.ctf_clock_class_set_description(self._ptr, description)
+ utils._handle_ret(ret, "cannot set clock class object's description")
+
+ @property
+ def frequency(self):
+ frequency = native_bt.ctf_clock_class_get_frequency(self._ptr)
+ assert(frequency >= 1)
+ return frequency
+
+ @frequency.setter
+ def frequency(self, frequency):
+ utils._check_uint64(frequency)
+ ret = native_bt.ctf_clock_class_set_frequency(self._ptr, frequency)
+ utils._handle_ret(ret, "cannot set clock class object's frequency")
+
+ @property
+ def precision(self):
+ precision = native_bt.ctf_clock_class_get_precision(self._ptr)
+ assert(precision >= 0)
+ return precision
+
+ @precision.setter
+ def precision(self, precision):
+ utils._check_uint64(precision)
+ ret = native_bt.ctf_clock_class_set_precision(self._ptr, precision)
+ utils._handle_ret(ret, "cannot set clock class object's precision")
+
+ @property
+ def offset(self):
+ ret, offset_s = native_bt.ctf_clock_class_get_offset_s(self._ptr)
+ assert(ret == 0)
+ ret, offset_cycles = native_bt.ctf_clock_class_get_offset_cycles(self._ptr)
+ assert(ret == 0)
+ return ClockClassOffset(offset_s, offset_cycles)
+
+ @offset.setter
+ def offset(self, offset):
+ utils._check_type(offset, ClockClassOffset)
+ ret = native_bt.ctf_clock_class_set_offset_s(self._ptr, offset.seconds)
+ utils._handle_ret(ret, "cannot set clock class object's offset (seconds)")
+ ret = native_bt.ctf_clock_class_set_offset_cycles(self._ptr, offset.cycles)
+ utils._handle_ret(ret, "cannot set clock class object's offset (cycles)")
+
+ @property
+ def is_absolute(self):
+ is_absolute = native_bt.ctf_clock_class_is_absolute(self._ptr)
+ assert(is_absolute >= 0)
+ return is_absolute > 0
+
+ @is_absolute.setter
+ def is_absolute(self, is_absolute):
+ utils._check_bool(is_absolute)
+ ret = native_bt.ctf_clock_class_set_is_absolute(self._ptr, int(is_absolute))
+ utils._handle_ret(ret, "cannot set clock class object's absoluteness")
+
+ @property
+ def uuid(self):
+ uuid_bytes = native_bt.ctf_clock_class_get_uuid(self._ptr)
+
+ if uuid_bytes is None:
+ return
+
+ return uuidp.UUID(bytes=uuid_bytes)
+
+ @uuid.setter
+ def uuid(self, uuid):
+ utils._check_type(uuid, uuidp.UUID)
+ ret = native_bt.ctf_clock_class_set_uuid(self._ptr, uuid.bytes)
+ utils._handle_ret(ret, "cannot set clock class object's UUID")
+
+ def __call__(self, cycles):
+ return _ClockValue(self._ptr, cycles)
+
+
+def _create_clock_value_from_ptr(ptr):
+ clock_value = _ClockValue._create_from_ptr(ptr)
+ return clock_value
+
+
+class _ClockValue(object._Object):
+ def __init__(self, clock_class_ptr, cycles):
+ utils._check_uint64(cycles)
+ ptr = native_bt.ctf_clock_value_create(clock_class_ptr, cycles)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create clock value object')
+
+ super().__init__(ptr)
+
+ @property
+ def clock_class(self):
+ ptr = native_bt.ctf_clock_value_get_class(self._ptr)
+ assert(ptr)
+ return ClockClass._create_from_ptr(ptr)
+
+ @property
+ def cycles(self):
+ ret, cycles = native_bt.ctf_clock_value_get_value(self._ptr)
+ assert(ret == 0)
+ return cycles
+
+ @property
+ def ns_from_epoch(self):
+ ret, ns = native_bt.ctf_clock_value_get_value_ns_from_epoch(self._ptr)
+ utils._handle_ret(ret, "cannot get clock value object's nanoseconds from Epoch")
+ return ns
+
+ def __eq__(self, other):
+ if isinstance(other, numbers.Integral):
+ return int(other) == self.cycles
+
+ if not isinstance(other, self.__class__):
+ # not comparing apples to apples
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = self.clock_class, self.cycles
+ other_props = other.clock_class, other.cycles
+ return self_props == other_props
+
+ def __copy__(self):
+ return self.clock_class(self.cycles)
+
+ def __deepcopy__(self, memo):
+ cpy = self.__copy__()
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import bt2.clock_class
+import copy
+import bt2
+
+
+class _ClockClassIterator(collections.abc.Iterator):
+ def __init__(self, cc_prio_map):
+ self._cc_prio_map = cc_prio_map
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._cc_prio_map):
+ raise StopIteration
+
+ cc_ptr = native_bt.clock_class_priority_map_get_clock_class_by_index(self._cc_prio_map._ptr,
+ self._at)
+ assert(cc_ptr)
+ clock_class = bt2.ClockClass._create_from_ptr(cc_ptr)
+ self._at += 1
+ return clock_class
+
+
+class ClockClassPriorityMap(object._Object, collections.abc.MutableMapping):
+ def __init__(self, clock_class_priorities=None):
+ ptr = native_bt.clock_class_priority_map_create()
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create clock class priority map object')
+
+ super().__init__(ptr)
+
+ if clock_class_priorities is not None:
+ for clock_class, priority in clock_class_priorities.items():
+ self[clock_class] = priority
+
+ def __getitem__(self, key):
+ utils._check_type(key, bt2.ClockClass)
+ ret, prio = native_bt.clock_class_priority_map_get_clock_class_priority(self._ptr,
+ key._ptr)
+
+ if ret != 0:
+ raise KeyError(key)
+
+ return prio
+
+ def __len__(self):
+ count = native_bt.clock_class_priority_map_get_clock_class_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ def __delitem__(self):
+ raise NotImplementedError
+
+ def __setitem__(self, key, value):
+ utils._check_type(key, bt2.ClockClass)
+ utils._check_uint64(value)
+ ret = native_bt.clock_class_priority_map_add_clock_class(self._ptr,
+ key._ptr,
+ value)
+ utils._handle_ret(ret, "cannot set clock class's priority in clock class priority map object")
+
+ def __iter__(self):
+ return _ClockClassIterator(self)
+
+ @property
+ def highest_priority_clock_class(self):
+ cc_ptr = native_bt.clock_class_priority_map_get_highest_priority_clock_class(self._ptr)
+
+ if cc_ptr is None:
+ return
+
+ return bt2.ClockClass._create_from_ptr(cc_ptr)
+
+ def _get_prios(self):
+ prios = {}
+
+ for clock_class, prio in self.items():
+ prios[clock_class] = prio
+
+ return prios
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self._get_prios() == other._get_prios()
+
+ def _copy(self, cc_copy_func):
+ cpy = ClockClassPriorityMap()
+
+ for clock_class, prio in self.items():
+ cpy[cc_copy_func(clock_class)] = prio
+
+ return cpy
+
+ def __copy__(self):
+ return self._copy(lambda obj: obj)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.notification_iterator
+import collections.abc
+import bt2.values
+import traceback
+import bt2.port
+import sys
+import bt2
+import os
+
+
+_env_var = os.environ.get('BABELTRACE_PYTHON_BT2_NO_TRACEBACK')
+_NO_PRINT_TRACEBACK = _env_var == '1'
+
+
+# This class wraps a component class pointer. This component class could
+# have been created by Python code, but since we only have the pointer,
+# we can only wrap it in a generic way and lose the original Python
+# class.
+class _GenericComponentClass(object._Object):
+ @property
+ def name(self):
+ name = native_bt.component_class_get_name(self._ptr)
+ assert(name is not None)
+ return name
+
+ @property
+ def description(self):
+ return native_bt.component_class_get_description(self._ptr)
+
+ @property
+ def help(self):
+ return native_bt.component_class_get_help(self._ptr)
+
+ def query(self, obj, params=None):
+ return _query(self._ptr, obj, params)
+
+ def __eq__(self, other):
+ if not isinstance(other, _GenericComponentClass):
+ try:
+ if not issubclass(other, _UserComponent):
+ return False
+ except TypeError:
+ return False
+
+ return self.addr == other.addr
+
+
+class _GenericSourceComponentClass(_GenericComponentClass):
+ pass
+
+
+class _GenericFilterComponentClass(_GenericComponentClass):
+ pass
+
+
+class _GenericSinkComponentClass(_GenericComponentClass):
+ pass
+
+
+def _handle_component_status(status, gen_error_msg):
+ if status == native_bt.COMPONENT_STATUS_END:
+ raise bt2.Stop
+ elif status == native_bt.COMPONENT_STATUS_AGAIN:
+ raise bt2.TryAgain
+ elif status == native_bt.COMPONENT_STATUS_UNSUPPORTED:
+ raise bt2.UnsupportedFeature
+ elif status == native_bt.COMPONENT_STATUS_REFUSE_PORT_CONNECTION:
+ raise bt2.PortConnectionRefused
+ elif status == native_bt.COMPONENT_STATUS_GRAPH_IS_CANCELED:
+ raise bt2.GraphCanceled
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+
+class _PortIterator(collections.abc.Iterator):
+ def __init__(self, comp_ports):
+ self._comp_ports = comp_ports
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._comp_ports):
+ raise StopIteration
+
+ comp_ports = self._comp_ports
+ comp_ptr = comp_ports._component._ptr
+ port_ptr = comp_ports._get_port_at_index_fn(comp_ptr, self._at)
+ assert(port_ptr)
+
+ if comp_ports._is_private:
+ port_pub_ptr = native_bt.port_from_private_port(port_ptr)
+ name = native_bt.port_get_name(port_pub_ptr)
+ native_bt.put(port_pub_ptr)
+ else:
+ name = native_bt.port_get_name(port_ptr)
+
+ assert(name is not None)
+ native_bt.put(port_ptr)
+ self._at += 1
+ return name
+
+
+class _ComponentPorts(collections.abc.Mapping):
+ def __init__(self, is_private, component,
+ get_port_by_name_fn, get_port_at_index_fn,
+ get_port_count_fn):
+ self._is_private = is_private
+ self._component = component
+ self._get_port_by_name_fn = get_port_by_name_fn
+ self._get_port_at_index_fn = get_port_at_index_fn
+ self._get_port_count_fn = get_port_count_fn
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ port_ptr = self._get_port_by_name_fn(self._component._ptr, key)
+
+ if port_ptr is None:
+ raise KeyError(key)
+
+ if self._is_private:
+ return bt2.port._create_private_from_ptr(port_ptr)
+ else:
+ return bt2.port._create_from_ptr(port_ptr)
+
+ def __len__(self):
+ if self._is_private:
+ pub_ptr = native_bt.component_from_private_component(self._component._ptr)
+ count = self._get_port_count_fn(pub_ptr)
+ native_bt.put(pub_ptr)
+ else:
+ count = self._get_port_count_fn(self._component._ptr)
+
+ assert(count >= 0)
+ return count
+
+ def __iter__(self):
+ return _PortIterator(self)
+
+
+# This class holds the methods which are common to both generic
+# component objects and Python user component objects. They use the
+# internal native _ptr, however it was set, to call native API
+# functions.
+class _Component:
+ @property
+ def name(self):
+ name = native_bt.component_get_name(self._ptr)
+ assert(name is not None)
+ return name
+
+ @property
+ def graph(self):
+ ptr = native_bt.component_get_graph(self._ptr)
+ assert(ptr)
+ return bt2.Graph._create_from_ptr(ptr)
+
+ @property
+ def component_class(self):
+ cc_ptr = native_bt.component_get_class(self._ptr)
+ assert(cc_ptr)
+ return _create_generic_component_class_from_ptr(cc_ptr)
+
+ def __eq__(self, other):
+ if not hasattr(other, 'addr'):
+ return False
+
+ return self.addr == other.addr
+
+
+class _SourceComponent(_Component):
+ pass
+
+
+class _FilterComponent(_Component):
+ pass
+
+
+class _SinkComponent(_Component):
+ pass
+
+
+# This is analogous to _GenericSourceComponentClass, but for source
+# component objects.
+class _GenericSourceComponent(object._Object, _SourceComponent):
+ @property
+ def output_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_source_get_output_port_by_name,
+ native_bt.component_source_get_output_port_by_index,
+ native_bt.component_source_get_output_port_count)
+
+
+# This is analogous to _GenericFilterComponentClass, but for filter
+# component objects.
+class _GenericFilterComponent(object._Object, _FilterComponent):
+ @property
+ def output_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_filter_get_output_port_by_name,
+ native_bt.component_filter_get_output_port_by_index,
+ native_bt.component_filter_get_output_port_count)
+
+ @property
+ def input_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_filter_get_input_port_by_name,
+ native_bt.component_filter_get_input_port_by_index,
+ native_bt.component_filter_get_input_port_count)
+
+
+# This is analogous to _GenericSinkComponentClass, but for sink
+# component objects.
+class _GenericSinkComponent(object._Object, _SinkComponent):
+ @property
+ def input_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_sink_get_input_port_by_name,
+ native_bt.component_sink_get_input_port_by_index,
+ native_bt.component_sink_get_input_port_count)
+
+
+_COMP_CLS_TYPE_TO_GENERIC_COMP_PYCLS = {
+ native_bt.COMPONENT_CLASS_TYPE_SOURCE: _GenericSourceComponent,
+ native_bt.COMPONENT_CLASS_TYPE_FILTER: _GenericFilterComponent,
+ native_bt.COMPONENT_CLASS_TYPE_SINK: _GenericSinkComponent,
+}
+
+
+_COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_PYCLS = {
+ native_bt.COMPONENT_CLASS_TYPE_SOURCE: _GenericSourceComponentClass,
+ native_bt.COMPONENT_CLASS_TYPE_FILTER: _GenericFilterComponentClass,
+ native_bt.COMPONENT_CLASS_TYPE_SINK: _GenericSinkComponentClass,
+}
+
+
+def _create_generic_component_from_ptr(ptr):
+ comp_cls_type = native_bt.component_get_class_type(ptr)
+ return _COMP_CLS_TYPE_TO_GENERIC_COMP_PYCLS[comp_cls_type]._create_from_ptr(ptr)
+
+
+def _create_generic_component_class_from_ptr(ptr):
+ comp_cls_type = native_bt.component_class_get_type(ptr)
+ return _COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_PYCLS[comp_cls_type]._create_from_ptr(ptr)
+
+
+def _trim_docstring(docstring):
+ lines = docstring.expandtabs().splitlines()
+ indent = sys.maxsize
+
+ for line in lines[1:]:
+ stripped = line.lstrip()
+
+ if stripped:
+ indent = min(indent, len(line) - len(stripped))
+
+ trimmed = [lines[0].strip()]
+
+ if indent < sys.maxsize:
+ for line in lines[1:]:
+ trimmed.append(line[indent:].rstrip())
+
+ while trimmed and not trimmed[-1]:
+ trimmed.pop()
+
+ while trimmed and not trimmed[0]:
+ trimmed.pop(0)
+
+ return '\n'.join(trimmed)
+
+
+def _query(comp_cls_ptr, obj, params):
+ utils._check_str(obj)
+
+ if params is None:
+ params_ptr = native_bt.value_null
+ else:
+ params = bt2.create_value(params)
+ params_ptr = params._ptr
+
+ results_ptr = native_bt.component_class_query(comp_cls_ptr, obj,
+ params_ptr)
+
+ if results_ptr is None:
+ raise bt2.Error('cannot query info with object "{}"'.format(obj))
+
+ return bt2.values._create_from_ptr(results_ptr)
+
+
+# Metaclass for component classes defined by Python code.
+#
+# The Python user can create a standard Python class which inherits one
+# of the three base classes (_UserSourceComponent, _UserFilterComponent,
+# or _UserSinkComponent). Those base classes set this class
+# (_UserComponentType) as their metaclass.
+#
+# Once the body of a user-defined component class is executed, this
+# metaclass is used to create and initialize the class. The metaclass
+# creates a native BT component class of the corresponding type and
+# associates it with this user-defined class. The metaclass also defines
+# class methods like the `name` and `description` properties to match
+# the _GenericComponentClass interface.
+#
+# The component class name which is used is either:
+#
+# * The `name` parameter of the class:
+#
+# class MySink(bt2.SinkComponent, name='my-custom-sink'):
+# ...
+#
+# * If the `name` class parameter is not used: the name of the class
+# itself (`MySink` in the example above).
+#
+# The component class description which is used is the user-defined
+# class's docstring:
+#
+# class MySink(bt2.SinkComponent):
+# 'Description goes here'
+# ...
+#
+# A user-defined Python component class can have an __init__() method
+# which must at least accept the `params` and `name` arguments:
+#
+# def __init__(self, params, name, something_else):
+# ...
+#
+# The user-defined component class can also have a _finalize() method
+# (do NOT use __del__()) to be notified when the component object is
+# finalized.
+#
+# User-defined source and filter component classes must use the
+# `notification_iterator_class` class parameter to specify the
+# notification iterator class to use for this component class:
+#
+# class MyNotificationIterator(bt2._UserNotificationIterator):
+# ...
+#
+# class MySource(bt2._UserSourceComponent,
+# notification_iterator_class=MyNotificationIterator):
+# ...
+#
+# This notification iterator class must inherit
+# bt2._UserNotificationIterator, and it must define the _get() and
+# _next() methods. The notification iterator class can also define an
+# __init__() method: this method has access to the original Python
+# component object which was used to create it as the `component`
+# property. The notification iterator class can also define a
+# _finalize() method (again, do NOT use __del__()): this is called when
+# the notification iterator is (really) destroyed.
+#
+# When the user-defined class is destroyed, this metaclass's __del__()
+# method is called: the native BT component class pointer is put (not
+# needed anymore, at least not by any Python code since all references
+# are dropped for __del__() to be called).
+class _UserComponentType(type):
+ # __new__() is used to catch custom class parameters
+ def __new__(meta_cls, class_name, bases, attrs, **kwargs):
+ return super().__new__(meta_cls, class_name, bases, attrs)
+
+ def __init__(cls, class_name, bases, namespace, **kwargs):
+ super().__init__(class_name, bases, namespace)
+
+ # skip our own bases; they are never directly instantiated by the user
+ own_bases = (
+ '_UserComponent',
+ '_UserFilterSinkComponent',
+ '_UserSourceComponent',
+ '_UserFilterComponent',
+ '_UserSinkComponent',
+ )
+
+ if class_name in own_bases:
+ return
+
+ comp_cls_name = kwargs.get('name', class_name)
+ utils._check_str(comp_cls_name)
+ comp_cls_descr = None
+ comp_cls_help = None
+
+ if hasattr(cls, '__doc__') and cls.__doc__ is not None:
+ utils._check_str(cls.__doc__)
+ docstring = _trim_docstring(cls.__doc__)
+ lines = docstring.splitlines()
+
+ if len(lines) >= 1:
+ comp_cls_descr = lines[0]
+
+ if len(lines) >= 3:
+ comp_cls_help = '\n'.join(lines[2:])
+
+ iter_cls = kwargs.get('notification_iterator_class')
+
+ if _UserSourceComponent in bases:
+ _UserComponentType._set_iterator_class(cls, iter_cls)
+ cc_ptr = native_bt.py3_component_class_source_create(cls,
+ comp_cls_name,
+ comp_cls_descr,
+ comp_cls_help)
+ elif _UserFilterComponent in bases:
+ _UserComponentType._set_iterator_class(cls, iter_cls)
+ cc_ptr = native_bt.py3_component_class_filter_create(cls,
+ comp_cls_name,
+ comp_cls_descr,
+ comp_cls_help)
+ elif _UserSinkComponent in bases:
+ if not hasattr(cls, '_consume'):
+ raise bt2.IncompleteUserClass("cannot create component class '{}': missing a _consume() method".format(class_name))
+
+ cc_ptr = native_bt.py3_component_class_sink_create(cls,
+ comp_cls_name,
+ comp_cls_descr,
+ comp_cls_help)
+ else:
+ raise bt2.IncompleteUserClass("cannot find a known component class base in the bases of '{}'".format(class_name))
+
+ if cc_ptr is None:
+ raise bt2.CreationError("cannot create component class '{}'".format(class_name))
+
+ cls._cc_ptr = cc_ptr
+
+ def _init_from_native(cls, comp_ptr, params_ptr):
+ # create instance, not user-initialized yet
+ self = cls.__new__(cls)
+
+ # pointer to native private component object (weak/borrowed)
+ self._ptr = comp_ptr
+
+ # call user's __init__() method
+ if params_ptr is not None:
+ native_bt.get(params_ptr)
+ params = bt2.values._create_from_ptr(params_ptr)
+ else:
+ params = None
+
+ self.__init__(params)
+ return self
+
+ def __call__(cls, *args, **kwargs):
+ raise bt2.Error('cannot directly instantiate a user component from a Python module')
+
+ @staticmethod
+ def _set_iterator_class(cls, iter_cls):
+ if iter_cls is None:
+ raise bt2.IncompleteUserClass("cannot create component class '{}': missing notification iterator class".format(cls.__name__))
+
+ if not issubclass(iter_cls, bt2.notification_iterator._UserNotificationIterator):
+ raise bt2.IncompleteUserClass("cannot create component class '{}': notification iterator class does not inherit bt2._UserNotificationIterator".format(cls.__name__))
+
+ if not hasattr(iter_cls, '__next__'):
+ raise bt2.IncompleteUserClass("cannot create component class '{}': notification iterator class is missing a __next__() method".format(cls.__name__))
+
+ cls._iter_cls = iter_cls
+
+ @property
+ def name(cls):
+ return native_bt.component_class_get_name(cls._cc_ptr)
+
+ @property
+ def description(cls):
+ return native_bt.component_class_get_description(cls._cc_ptr)
+
+ @property
+ def help(cls):
+ return native_bt.component_class_get_help(cls._cc_ptr)
+
+ @property
+ def addr(cls):
+ return int(cls._cc_ptr)
+
+ def query(cls, obj, params=None):
+ return _query(cls._cc_ptr, obj, params)
+
+ def _query_from_native(cls, obj, params_ptr):
+ # this can raise, in which case the native call to
+ # bt_component_class_query() returns NULL
+ if params_ptr is not None:
+ native_bt.get(params_ptr)
+ params = bt2.values._create_from_ptr(params_ptr)
+ else:
+ params = None
+
+ try:
+ results = cls._query(obj, params)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
+
+ return
+
+ if results is NotImplemented:
+ return results
+
+ try:
+ results = bt2.create_value(results)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
+
+ return
+
+ if results is None:
+ results_addr = int(native_bt.value_null)
+ else:
+ # return new reference
+ results._get()
+ results_addr = int(results._ptr)
+
+ return results_addr
+
+ @classmethod
+ def _query(cls, obj, params):
+ # BT catches this and returns NULL to the user
+ return NotImplemented
+
+ def __eq__(self, other):
+ if not hasattr(other, 'addr'):
+ return False
+
+ return self.addr == other.addr
+
+ def __del__(cls):
+ if hasattr(cls, '_cc_ptr'):
+ native_bt.put(cls._cc_ptr)
+
+
+class _UserComponent(metaclass=_UserComponentType):
+ @property
+ def name(self):
+ pub_ptr = native_bt.component_from_private_component(self._ptr)
+ name = native_bt.component_get_name(pub_ptr)
+ native_bt.put(pub_ptr)
+ assert(name is not None)
+ return name
+
+ @property
+ def graph(self):
+ pub_ptr = native_bt.component_from_private_component(self._ptr)
+ ptr = native_bt.component_get_graph(pub_ptr)
+ native_bt.put(pub_ptr)
+ assert(ptr)
+ return bt2.Graph._create_from_ptr(ptr)
+
+ @property
+ def component_class(self):
+ pub_ptr = native_bt.component_from_private_component(self._ptr)
+ cc_ptr = native_bt.component_get_class(pub_ptr)
+ native_bt.put(pub_ptr)
+ assert(cc_ptr)
+ return _create_generic_component_class_from_ptr(cc_ptr)
+
+ @property
+ def addr(self):
+ return int(self._ptr)
+
+ def __init__(self, params=None):
+ pass
+
+ def _finalize(self):
+ pass
+
+ def _accept_port_connection(self, port, other_port):
+ return True
+
+ def _accept_port_connection_from_native(self, port_ptr, other_port_ptr):
+ native_bt.get(port_ptr)
+ native_bt.get(other_port_ptr)
+ port = bt2.port._create_private_from_ptr(port_ptr)
+ other_port = bt2.port._create_from_ptr(other_port_ptr)
+ res = self._accept_port_connection(port, other_port_ptr)
+
+ if type(res) is not bool:
+ raise TypeError("'{}' is not a 'bool' object")
+
+ return res
+
+ def _port_connected(self, port, other_port):
+ pass
+
+ def _port_connected_from_native(self, port_ptr, other_port_ptr):
+ native_bt.get(port_ptr)
+ native_bt.get(other_port_ptr)
+ port = bt2.port._create_private_from_ptr(port_ptr)
+ other_port = bt2.port._create_from_ptr(other_port_ptr)
+
+ try:
+ self._port_connected(port, other_port_ptr)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
+
+ def _port_disconnected(self, port):
+ pass
+
+ def _port_disconnected_from_native(self, port_ptr):
+ native_bt.get(port_ptr)
+ port = bt2.port._create_private_from_ptr(port_ptr)
+
+ try:
+ self._port_disconnected(port)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
+
+
+class _UserSourceComponent(_UserComponent, _SourceComponent):
+ @property
+ def _output_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_source_get_output_private_port_by_name,
+ native_bt.private_component_source_get_output_private_port_by_index,
+ native_bt.component_source_get_output_port_count)
+
+ def _add_output_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_source_add_output_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add output port to source component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
+
+
+class _UserFilterComponent(_UserComponent, _FilterComponent):
+ @property
+ def _output_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_filter_get_output_private_port_by_name,
+ native_bt.private_component_filter_get_output_private_port_by_index,
+ native_bt.component_filter_get_output_port_count)
+
+ @property
+ def _input_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_filter_get_input_private_port_by_name,
+ native_bt.private_component_filter_get_input_private_port_by_index,
+ native_bt.component_filter_get_input_port_count)
+
+ def _add_output_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_filter_add_output_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add output port to filter component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
+
+ def _add_input_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_filter_add_input_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add input port to filter component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
+
+
+class _UserSinkComponent(_UserComponent, _SinkComponent):
+ @property
+ def _input_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_sink_get_input_private_port_by_name,
+ native_bt.private_component_sink_get_input_private_port_by_index,
+ native_bt.component_sink_get_input_port_count)
+
+ def _add_input_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_sink_add_input_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add input port to sink component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.notification_iterator
+import collections.abc
+import bt2.port
+import copy
+import bt2
+
+
+def _handle_status(status, gen_error_msg):
+ if status == native_bt.CONNECTION_STATUS_GRAPH_IS_CANCELED:
+ raise bt2.GraphCanceled
+ elif status == native_bt.CONNECTION_STATUS_IS_ENDED:
+ raise bt2.ConnectionEnded
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+
+def _create_private_from_ptr(ptr):
+ obj = _PrivateConnection._create_from_ptr(ptr)
+ obj._pub_ptr = native_bt.connection_from_private_connection(ptr)
+ assert(obj._pub_ptr)
+ return obj
+
+
+class _Connection(object._Object):
+ @staticmethod
+ def _downstream_port(ptr):
+ port_ptr = native_bt.connection_get_downstream_port(ptr)
+ utils._handle_ptr(port_ptr, "cannot get connection object's downstream port object")
+ return bt2.port._create_from_ptr(port_ptr)
+
+ @staticmethod
+ def _upstream_port(ptr):
+ port_ptr = native_bt.connection_get_upstream_port(ptr)
+ utils._handle_ptr(port_ptr, "cannot get connection object's upstream port object")
+ return bt2.port._create_from_ptr(port_ptr)
+
+ @property
+ def downstream_port(self):
+ return self._downstream_port(self._ptr)
+
+ @property
+ def upstream_port(self):
+ return self._upstream_port(self._ptr)
+
+ @staticmethod
+ def _is_ended(ptr):
+ return native_bt.connection_is_ended(ptr) == 1
+
+ @property
+ def is_ended(self):
+ return self._is_ended(self._ptr)
+
+ def __eq__(self, other):
+ if type(other) not in (_Connection, _PrivateConnection):
+ return False
+
+ return self.addr == other.addr
+
+
+class _PrivateConnection(object._PrivateObject, _Connection):
+ def create_notification_iterator(self, notification_types=None):
+ if notification_types is None:
+ notif_types = None
+ else:
+ for notif_cls in notification_types:
+ if notif_cls not in bt2.notification._NOTIF_TYPE_TO_CLS.values():
+ raise ValueError("'{}' is not a notification class".format(notif_cls))
+
+ notif_types = [notif_cls._TYPE for notif_cls in notification_types]
+
+ status, notif_iter_ptr = native_bt.py3_create_notif_iter(int(self._ptr),
+ notif_types)
+ _handle_status(status, 'cannot create notification iterator object')
+ assert(notif_iter_ptr)
+ return bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(notif_iter_ptr)
+
+ @property
+ def is_ended(self):
+ return self._is_ended(self._pub_ptr)
+
+ @property
+ def downstream_port(self):
+ return self._downstream_port(self._pub_ptr)
+
+ @property
+ def upstream_port(self):
+ return self._upstream_port(self._pub_ptr)
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, stream, utils
+import uuid as uuidp
+import bt2.event
+import abc
+import bt2
+
+
+class CtfWriterClock(object._Object):
+ def __init__(self, name, description=None, frequency=None, precision=None,
+ offset=None, is_absolute=None, uuid=None):
+ utils._check_str(name)
+ ptr = native_bt.ctf_clock_create(name)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create CTF writer clock object')
+
+ super().__init__(ptr)
+
+ if description is not None:
+ self.description = description
+
+ if frequency is not None:
+ self.frequency = frequency
+
+ if precision is not None:
+ self.precision = precision
+
+ if offset is not None:
+ self.offset = offset
+
+ if is_absolute is not None:
+ self.is_absolute = is_absolute
+
+ if uuid is not None:
+ self.uuid = uuid
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ # not comparing apples to apples
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = (
+ self.name,
+ self.description,
+ self.frequency,
+ self.precision,
+ self.offset,
+ self.is_absolute,
+ self.uuid
+ )
+ other_props = (
+ other.name,
+ other.description,
+ other.frequency,
+ other.precision,
+ other.offset,
+ other.is_absolute,
+ other.uuid
+ )
+ return self_props == other_props
+
+ def __copy__(self):
+ return CtfWriterClock(name=self.name, description=self.description,
+ frequency=self.frequency,
+ precision=self.precision, offset=self.offset,
+ is_absolute=self.is_absolute, uuid=self.uuid)
+
+ def __deepcopy__(self, memo):
+ cpy = self.__copy__()
+ memo[id(self)] = cpy
+ return cpy
+
+ @property
+ def name(self):
+ name = native_bt.ctf_clock_get_name(self._ptr)
+ assert(name is not None)
+ return name
+
+ @property
+ def description(self):
+ description = native_bt.ctf_clock_get_description(self._ptr)
+ return description
+
+ @description.setter
+ def description(self, description):
+ utils._check_str(description)
+ ret = native_bt.ctf_clock_set_description(self._ptr, description)
+ utils._handle_ret(ret, "cannot set CTF writer clock object's description")
+
+ @property
+ def frequency(self):
+ frequency = native_bt.ctf_clock_get_frequency(self._ptr)
+ assert(frequency >= 1)
+ return frequency
+
+ @frequency.setter
+ def frequency(self, frequency):
+ utils._check_uint64(frequency)
+ ret = native_bt.ctf_clock_set_frequency(self._ptr, frequency)
+ utils._handle_ret(ret, "cannot set CTF writer clock object's frequency")
+
+ @property
+ def precision(self):
+ precision = native_bt.ctf_clock_get_precision(self._ptr)
+ assert(precision >= 0)
+ return precision
+
+ @precision.setter
+ def precision(self, precision):
+ utils._check_uint64(precision)
+ ret = native_bt.ctf_clock_set_precision(self._ptr, precision)
+ utils._handle_ret(ret, "cannot set CTF writer clock object's precision")
+
+ @property
+ def offset(self):
+ ret, offset_s = native_bt.ctf_clock_get_offset_s(self._ptr)
+ assert(ret == 0)
+ ret, offset_cycles = native_bt.ctf_clock_get_offset(self._ptr)
+ assert(ret == 0)
+ return bt2.ClockClassOffset(offset_s, offset_cycles)
+
+ @offset.setter
+ def offset(self, offset):
+ utils._check_type(offset, bt2.ClockClassOffset)
+ ret = native_bt.ctf_clock_set_offset_s(self._ptr, offset.seconds)
+ utils._handle_ret(ret, "cannot set CTF writer clock object's offset (seconds)")
+ ret = native_bt.ctf_clock_set_offset(self._ptr, offset.cycles)
+ utils._handle_ret(ret, "cannot set CTF writer clock object's offset (cycles)")
+
+ @property
+ def is_absolute(self):
+ is_absolute = native_bt.ctf_clock_get_is_absolute(self._ptr)
+ assert(is_absolute >= 0)
+ return is_absolute > 0
+
+ @is_absolute.setter
+ def is_absolute(self, is_absolute):
+ utils._check_bool(is_absolute)
+ ret = native_bt.ctf_clock_set_is_absolute(self._ptr, int(is_absolute))
+ utils._handle_ret(ret, "cannot set CTF writer clock object's absoluteness")
+
+ @property
+ def uuid(self):
+ uuid_bytes = native_bt.ctf_clock_get_uuid(self._ptr)
+ assert(uuid_bytes is not None)
+ return uuidp.UUID(bytes=uuid_bytes)
+
+ @uuid.setter
+ def uuid(self, uuid):
+ utils._check_type(uuid, uuidp.UUID)
+ ret = native_bt.ctf_clock_set_uuid(self._ptr, uuid.bytes)
+ utils._handle_ret(ret, "cannot set CTF writer clock object's UUID")
+
+ def _time(self, time):
+ utils._check_int64(time)
+ ret = native_bt.ctf_clock_set_time(self._ptr, time)
+
+ time = property(fset=_time)
+
+
+class _CtfWriterStream(stream._StreamBase):
+ @property
+ def discarded_events_count(self):
+ ret, count = native_bt.ctf_stream_get_discarded_events_count(self._ptr)
+ utils._handle_ret(ret, "cannot get CTF writer stream object's discarded events count")
+ return count
+
+ def append_discarded_events(self, count):
+ utils._check_uint64(count)
+ native_bt.ctf_stream_append_discarded_events(self._ptr, count)
+
+ def append_event(self, event):
+ utils._check_type(event, bt2.event._Event)
+ ret = native_bt.ctf_stream_append_event(self._ptr, event._ptr)
+ utils._handle_ret(ret, 'cannot append event object to CTF writer stream object')
+
+ def flush(self):
+ ret = native_bt.ctf_stream_flush(self._ptr)
+ utils._handle_ret(ret, 'cannot cannot flush CTF writer stream object')
+
+ @property
+ def packet_header_field(self):
+ field_ptr = native_bt.ctf_stream_get_packet_header(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return fields._create_from_ptr(field_ptr)
+
+ @packet_header_field.setter
+ def packet_header_field(self, packet_header_field):
+ packet_header_field_ptr = None
+
+ if packet_header_field is not None:
+ utils._check_type(packet_header_field, fields._Field)
+ packet_header_field_ptr = packet_header_field._ptr
+
+ ret = native_bt.ctf_stream_set_packet_header(self._ptr,
+ packet_header_field_ptr)
+ utils._handle_ret(ret, "cannot set CTF writer stream object's packet header field")
+
+ @property
+ def packet_context_field(self):
+ field_ptr = native_bt.ctf_stream_get_packet_context(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return fields._create_from_ptr(field_ptr)
+
+ @packet_context_field.setter
+ def packet_context_field(self, packet_context_field):
+ packet_context_field_ptr = None
+
+ if packet_context_field is not None:
+ utils._check_type(packet_context_field, fields._Field)
+ packet_context_field_ptr = packet_context_field._ptr
+
+ ret = native_bt.ctf_stream_set_packet_context(self._ptr,
+ packet_context_field_ptr)
+ utils._handle_ret(ret, "cannot set CTF writer stream object's packet context field")
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ if not _StreamBase.__eq__(self, other):
+ return False
+
+ self_props = (
+ self.discarded_events_count,
+ self.packet_header_field,
+ self.packet_context_field,
+ )
+ other_props = (
+ other.discarded_events_count,
+ other.packet_header_field,
+ other.packet_context_field,
+ )
+ return self_props == other_props
+
+ def _copy(self, copy_func):
+ cpy = self.stream_class(self.name)
+ cpy.append_discarded_events(self.discarded_events_count)
+ cpy.packet_header_field = copy_func(self.packet_header_field)
+ cpy.packet_context_field = copy_func(self.packet_context_field)
+ return cpy
+
+ def __copy__(self):
+ return self._copy(copy.copy)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
+
+
+class CtfWriter(object._Object):
+ def __init__(self, path):
+ utils._check_str(path)
+ ptr = native_bt.ctf_writer_create(path)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create CTF writer object')
+
+ super().__init__(ptr)
+
+ @property
+ def trace(self):
+ trace_ptr = native_bt.ctf_writer_get_trace(self._ptr)
+ assert(trace_ptr)
+ return bt2.Trace._create_from_ptr(trace_ptr)
+
+ @property
+ def metadata_string(self):
+ metadata_string = native_bt.ctf_writer_get_metadata_string(self._ptr)
+ assert(metadata_string is not None)
+ return metadata_string
+
+ def flush_metadata(self):
+ native_bt.ctf_writer_flush_metadata(self._ptr)
+
+ def add_clock(self, clock):
+ utils._check_type(clock, CtfWriterClock)
+ ret = native_bt.ctf_writer_add_clock(self._ptr, clock._ptr)
+ utils._handle_ret(ret, 'cannot add CTF writer clock object to CTF writer object')
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.clock_class
+import bt2.packet
+import bt2.stream
+import bt2.fields
+import numbers
+import copy
+import abc
+import bt2
+
+
+def _create_from_ptr(ptr):
+ # recreate the event class wrapper of this event's class (the
+ # identity could be different, but the underlying address should be
+ # the same)
+ event_class_ptr = native_bt.ctf_event_get_class(ptr)
+ utils._handle_ptr(event_class_ptr, "cannot get event object's class")
+ event_class = bt2.EventClass._create_from_ptr(event_class_ptr)
+ event = _Event._create_from_ptr(ptr)
+ event._event_class = event_class
+ return event
+
+
+class _Event(object._Object):
+ @property
+ def event_class(self):
+ return self._event_class
+
+ @property
+ def name(self):
+ return self._event_class.name
+
+ @property
+ def id(self):
+ return self._event_class.id
+
+ @property
+ def packet(self):
+ packet_ptr = native_bt.ctf_event_get_packet(self._ptr)
+
+ if packet_ptr is None:
+ return packet_ptr
+
+ return bt2.packet._Packet._create_from_ptr(packet_ptr)
+
+ @packet.setter
+ def packet(self, packet):
+ utils._check_type(packet, bt2.packet._Packet)
+ ret = native_bt.ctf_event_set_packet(self._ptr, packet._ptr)
+ utils._handle_ret(ret, "cannot set event object's packet object")
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.ctf_event_get_stream(self._ptr)
+
+ if stream_ptr is None:
+ return stream_ptr
+
+ return bt2.stream._Stream._create_from_ptr(stream_ptr)
+
+ @property
+ def header_field(self):
+ field_ptr = native_bt.ctf_event_get_header(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return bt2.fields._create_from_ptr(field_ptr)
+
+ @header_field.setter
+ def header_field(self, header_field):
+ header_field_ptr = None
+
+ if header_field is not None:
+ utils._check_type(header_field, bt2.fields._Field)
+ header_field_ptr = header_field._ptr
+
+ ret = native_bt.ctf_event_set_header(self._ptr, header_field_ptr)
+ utils._handle_ret(ret, "cannot set event object's header field")
+
+ @property
+ def stream_event_context_field(self):
+ field_ptr = native_bt.ctf_event_get_stream_event_context(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return bt2.fields._create_from_ptr(field_ptr)
+
+ @stream_event_context_field.setter
+ def stream_event_context_field(self, stream_event_context):
+ stream_event_context_ptr = None
+
+ if stream_event_context is not None:
+ utils._check_type(stream_event_context, bt2.fields._Field)
+ stream_event_context_ptr = stream_event_context._ptr
+
+ ret = native_bt.ctf_event_set_stream_event_context(self._ptr,
+ stream_event_context_ptr)
+ utils._handle_ret(ret, "cannot set event object's stream event context field")
+
+ @property
+ def context_field(self):
+ field_ptr = native_bt.ctf_event_get_event_context(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return bt2.fields._create_from_ptr(field_ptr)
+
+ @context_field.setter
+ def context_field(self, context):
+ context_ptr = None
+
+ if context is not None:
+ utils._check_type(context, bt2.fields._Field)
+ context_ptr = context._ptr
+
+ ret = native_bt.ctf_event_set_event_context(self._ptr, context_ptr)
+ utils._handle_ret(ret, "cannot set event object's context field")
+
+ @property
+ def payload_field(self):
+ field_ptr = native_bt.ctf_event_get_event_payload(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return bt2.fields._create_from_ptr(field_ptr)
+
+ @payload_field.setter
+ def payload_field(self, payload):
+ payload_ptr = None
+
+ if payload is not None:
+ utils._check_type(payload, bt2.fields._Field)
+ payload_ptr = payload._ptr
+
+ ret = native_bt.ctf_event_set_event_payload(self._ptr, payload_ptr)
+ utils._handle_ret(ret, "cannot set event object's payload field")
+
+ def _get_clock_value_cycles(self, clock_class_ptr):
+ clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
+ clock_class_ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ ret, cycles = native_bt.ctf_clock_value_get_value(clock_value_ptr)
+ native_bt.put(clock_value_ptr)
+ utils._handle_ret(ret, "cannot get clock value object's cycles")
+ return cycles
+
+ def clock_value(self, clock_class):
+ utils._check_type(clock_class, bt2.ClockClass)
+ clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
+ clock_class._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ def add_clock_value(self, clock_value):
+ utils._check_type(clock_value, bt2.clock_class._ClockValue)
+ ret = native_bt.ctf_event_set_clock_value(self._ptr,
+ clock_value._ptr)
+ utils._handle_ret(ret, "cannot set event object's clock value")
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ payload_field = self.payload_field
+
+ if payload_field is not None and key in payload_field:
+ return payload_field[key]
+
+ context_field = self.context_field
+
+ if context_field is not None and key in context_field:
+ return context_field[key]
+
+ sec_field = self.stream_event_context_field
+
+ if sec_field is not None and key in sec_field:
+ return sec_field[key]
+
+ header_field = self.header_field
+
+ if header_field is not None and key in header_field:
+ return header_field[key]
+
+ packet = self.packet
+
+ if packet is None:
+ raise KeyError(key)
+
+ pkt_context_field = packet.context_field
+
+ if pkt_context_field is not None and key in pkt_context_field:
+ return pkt_context_field[key]
+
+ pkt_header_field = packet.header_field
+
+ if pkt_header_field is not None and key in pkt_header_field:
+ return pkt_header_field[key]
+
+ raise KeyError(key)
+
+ @property
+ def _clock_classes(self):
+ stream_class = self.event_class.stream_class
+
+ if stream_class is None:
+ return []
+
+ trace = stream_class.trace
+
+ if trace is None:
+ return []
+
+ clock_classes = []
+
+ for clock_class in trace.clock_classes.values():
+ clock_classes.append(clock_class)
+
+ return clock_classes
+
+ @property
+ def _clock_class_ptrs(self):
+ return [cc._ptr for cc in self._clock_classes]
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_clock_values = {}
+ other_clock_values = {}
+
+ for clock_class_ptr in self._clock_class_ptrs:
+ self_clock_values[int(clock_class_ptr)] = self._get_clock_value_cycles(clock_class_ptr)
+
+ for clock_class_ptr in other._clock_class_ptrs:
+ other_clock_values[int(clock_class_ptr)] = self._get_clock_value_cycles(clock_class_ptr)
+
+ self_props = (
+ self.header_field,
+ self.stream_event_context_field,
+ self.context_field,
+ self.payload_field,
+ self_clock_values,
+ )
+ other_props = (
+ other.header_field,
+ other.stream_event_context_field,
+ other.context_field,
+ other.payload_field,
+ other_clock_values,
+ )
+ return self_props == other_props
+
+ def _copy(self, copy_func):
+ cpy = self.event_class()
+
+ # copy fields
+ cpy.header_field = copy_func(self.header_field)
+ cpy.stream_event_context_field = copy_func(self.stream_event_context_field)
+ cpy.context_field = copy_func(self.context_field)
+ cpy.payload_field = copy_func(self.payload_field)
+
+ # Copy known clock value references. It's not necessary to copy
+ # clock class or clock value objects because once a clock value
+ # is created from a clock class, the clock class is frozen.
+ # Thus even if we copy the clock class, the user cannot modify
+ # it, therefore it's useless to copy it.
+ for clock_class in self._clock_classes:
+ clock_value = self.clock_value(clock_class)
+
+ if clock_value is not None:
+ cpy.add_clock_value(clock_value)
+
+ return cpy
+
+ def __copy__(self):
+ return self._copy(copy.copy)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.field_types
+import collections.abc
+import bt2.values
+import bt2.event
+import copy
+import bt2
+
+
+class EventClassLogLevel:
+ UNKNOWN = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN
+ UNSPECIFIED = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
+ EMERGENCY = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY
+ ALERT = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_ALERT
+ CRITICAL = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL
+ ERROR = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_ERROR
+ WARNING = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_WARNING
+ NOTICE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_NOTICE
+ INFO = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_INFO
+ DEBUG_SYSTEM = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
+ DEBUG_PROGRAM = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
+ DEBUG_PROCESS = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
+ DEBUG_MODULE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
+ DEBUG_UNIT = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
+ DEBUG_FUNCTION = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
+ DEBUG_LINE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
+ DEBUG = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG
+
+
+class EventClass(object._Object):
+ def __init__(self, name, id=None, log_level=None, emf_uri=None,
+ context_field_type=None, payload_field_type=None):
+ utils._check_str(name)
+ ptr = native_bt.ctf_event_class_create(name)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create event class object')
+
+ super().__init__(ptr)
+
+ if id is not None:
+ self.id = id
+
+ if log_level is not None:
+ self.log_level = log_level
+
+ if emf_uri is not None:
+ self.emf_uri = emf_uri
+
+ if context_field_type is not None:
+ self.context_field_type = context_field_type
+
+ if payload_field_type is not None:
+ self.payload_field_type = payload_field_type
+
+ @property
+ def stream_class(self):
+ sc_ptr = native_bt.ctf_event_class_get_stream_class(self._ptr)
+
+ if sc_ptr is not None:
+ return bt2.StreamClass._create_from_ptr(sc_ptr)
+
+ @property
+ def name(self):
+ return native_bt.ctf_event_class_get_name(self._ptr)
+
+ @property
+ def id(self):
+ id = native_bt.ctf_event_class_get_id(self._ptr)
+ return id if id >= 0 else None
+
+ @id.setter
+ def id(self, id):
+ utils._check_int64(id)
+ ret = native_bt.ctf_event_class_set_id(self._ptr, id)
+ utils._handle_ret(ret, "cannot set event class object's ID")
+
+ @property
+ def log_level(self):
+ log_level = native_bt.ctf_event_class_get_log_level(self._ptr)
+ return log_level if log_level >= 0 else None
+
+ @log_level.setter
+ def log_level(self, log_level):
+ log_levels = (
+ EventClassLogLevel.UNSPECIFIED,
+ EventClassLogLevel.EMERGENCY,
+ EventClassLogLevel.ALERT,
+ EventClassLogLevel.CRITICAL,
+ EventClassLogLevel.ERROR,
+ EventClassLogLevel.WARNING,
+ EventClassLogLevel.NOTICE,
+ EventClassLogLevel.INFO,
+ EventClassLogLevel.DEBUG_SYSTEM,
+ EventClassLogLevel.DEBUG_PROGRAM,
+ EventClassLogLevel.DEBUG_PROCESS,
+ EventClassLogLevel.DEBUG_MODULE,
+ EventClassLogLevel.DEBUG_UNIT,
+ EventClassLogLevel.DEBUG_FUNCTION,
+ EventClassLogLevel.DEBUG_LINE,
+ EventClassLogLevel.DEBUG,
+ )
+
+ if log_level not in log_levels:
+ raise ValueError("'{}' is not a valid log level".format(log_level))
+
+ ret = native_bt.ctf_event_class_set_log_level(self._ptr, log_level)
+ utils._handle_ret(ret, "cannot set event class object's log level")
+
+ @property
+ def emf_uri(self):
+ return native_bt.ctf_event_class_get_emf_uri(self._ptr)
+
+ @emf_uri.setter
+ def emf_uri(self, emf_uri):
+ utils._check_str(emf_uri)
+ ret = native_bt.ctf_event_class_set_emf_uri(self._ptr, emf_uri)
+ utils._handle_ret(ret, "cannot set event class object's EMF URI")
+
+ @property
+ def context_field_type(self):
+ ft_ptr = native_bt.ctf_event_class_get_context_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return bt2.field_types._create_from_ptr(ft_ptr)
+
+ @context_field_type.setter
+ def context_field_type(self, context_field_type):
+ context_field_type_ptr = None
+
+ if context_field_type is not None:
+ utils._check_type(context_field_type, bt2.field_types._FieldType)
+ context_field_type_ptr = context_field_type._ptr
+
+ ret = native_bt.ctf_event_class_set_context_type(self._ptr, context_field_type_ptr)
+ utils._handle_ret(ret, "cannot set event class object's context field type")
+
+ @property
+ def payload_field_type(self):
+ ft_ptr = native_bt.ctf_event_class_get_payload_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return bt2.field_types._create_from_ptr(ft_ptr)
+
+ @payload_field_type.setter
+ def payload_field_type(self, payload_field_type):
+ payload_field_type_ptr = None
+
+ if payload_field_type is not None:
+ utils._check_type(payload_field_type, bt2.field_types._FieldType)
+ payload_field_type_ptr = payload_field_type._ptr
+
+ ret = native_bt.ctf_event_class_set_payload_type(self._ptr, payload_field_type_ptr)
+ utils._handle_ret(ret, "cannot set event class object's payload field type")
+
+ def __call__(self):
+ event_ptr = native_bt.ctf_event_create(self._ptr)
+
+ if event_ptr is None:
+ raise bt2.CreationError('cannot create event field object')
+
+ return bt2.event._create_from_ptr(event_ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = (
+ self.name,
+ self.id,
+ self.log_level,
+ self.emf_uri,
+ self.context_field_type,
+ self.payload_field_type
+ )
+ other_props = (
+ other.name,
+ other.id,
+ other.log_level,
+ other.emf_uri,
+ other.context_field_type,
+ other.payload_field_type
+ )
+ return self_props == other_props
+
+ def _copy(self, ft_copy_func):
+ cpy = EventClass(self.name)
+ cpy.id = self.id
+
+ if self.log_level is not None:
+ cpy.log_level = self.log_level
+
+ if self.emf_uri is not None:
+ cpy.emf_uri = self.emf_uri
+
+ cpy.context_field_type = ft_copy_func(self.context_field_type)
+ cpy.payload_field_type = ft_copy_func(self.payload_field_type)
+ return cpy
+
+ def __copy__(self):
+ return self._copy(lambda ft: ft)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import bt2.fields
+import abc
+import bt2
+
+
+def _create_from_ptr(ptr):
+ typeid = native_bt.ctf_field_type_get_type_id(ptr)
+ return _TYPE_ID_TO_OBJ[typeid]._create_from_ptr(ptr)
+
+
+class _FieldType(object._Object, metaclass=abc.ABCMeta):
+ def __init__(self, ptr):
+ super().__init__(ptr)
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ # not comparing apples to apples
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ ret = native_bt.ctf_field_type_compare(self._ptr, other._ptr)
+ utils._handle_ret(ret, "cannot compare field types")
+ return ret == 0
+
+ def _check_create_status(self, ptr):
+ if ptr is None:
+ raise bt2.CreationError('cannot create {} field type object'.format(self._NAME.lower()))
+
+ def __copy__(self):
+ ptr = native_bt.ctf_field_type_copy(self._ptr)
+ utils._handle_ptr(ptr, 'cannot copy {} field type object'.format(self._NAME.lower()))
+ return _create_from_ptr(ptr)
+
+ def __deepcopy__(self, memo):
+ cpy = self.__copy__()
+ memo[id(self)] = cpy
+ return cpy
+
+ def __call__(self, value=None):
+ field_ptr = native_bt.ctf_field_create(self._ptr)
+
+ if field_ptr is None:
+ raise bt2.CreationError('cannot create {} field object'.format(self._NAME.lower()))
+
+ field = bt2.fields._create_from_ptr(field_ptr)
+
+ if value is not None:
+ if not isinstance(field, (bt2.fields._IntegerField, bt2.fields._FloatingPointNumberField, bt2.fields._StringField)):
+ raise bt2.Error('cannot assign an initial value to a {} field object'.format(field._NAME))
+
+ field.value = value
+
+ return field
+
+
+class ByteOrder:
+ NATIVE = native_bt.CTF_BYTE_ORDER_NATIVE
+ LITTLE_ENDIAN = native_bt.CTF_BYTE_ORDER_LITTLE_ENDIAN
+ BIG_ENDIAN = native_bt.CTF_BYTE_ORDER_BIG_ENDIAN
+ NETWORK = native_bt.CTF_BYTE_ORDER_NETWORK
+
+
+class Encoding:
+ NONE = native_bt.CTF_STRING_ENCODING_NONE
+ UTF8 = native_bt.CTF_STRING_ENCODING_UTF8
+ ASCII = native_bt.CTF_STRING_ENCODING_ASCII
+
+
+class Base:
+ BINARY = native_bt.CTF_INTEGER_BASE_BINARY
+ OCTAL = native_bt.CTF_INTEGER_BASE_OCTAL
+ DECIMAL = native_bt.CTF_INTEGER_BASE_DECIMAL
+ HEXADECIMAL = native_bt.CTF_INTEGER_BASE_HEXADECIMAL
+
+
+class _AlignmentProp:
+ @property
+ def alignment(self):
+ alignment = native_bt.ctf_field_type_get_alignment(self._ptr)
+ assert(alignment >= 0)
+ return alignment
+
+ @alignment.setter
+ def alignment(self, alignment):
+ utils._check_alignment(alignment)
+ ret = native_bt.ctf_field_type_set_alignment(self._ptr, alignment)
+ utils._handle_ret(ret, "cannot set field type object's alignment")
+
+
+class _ByteOrderProp:
+ @property
+ def byte_order(self):
+ bo = native_bt.ctf_field_type_get_byte_order(self._ptr)
+ assert(bo >= 0)
+ return bo
+
+ @byte_order.setter
+ def byte_order(self, byte_order):
+ utils._check_int(byte_order)
+ ret = native_bt.ctf_field_type_set_byte_order(self._ptr, byte_order)
+ utils._handle_ret(ret, "cannot set field type object's byte order")
+
+
+class IntegerFieldType(_FieldType, _AlignmentProp, _ByteOrderProp):
+ _NAME = 'Integer'
+
+ def __init__(self, size, alignment=None, byte_order=None, is_signed=None,
+ base=None, encoding=None, mapped_clock_class=None):
+ utils._check_uint64(size)
+
+ if size == 0:
+ raise ValueError('size is 0 bits')
+
+ ptr = native_bt.ctf_field_type_integer_create(size)
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ if alignment is not None:
+ self.alignment = alignment
+
+ if byte_order is not None:
+ self.byte_order = byte_order
+
+ if is_signed is not None:
+ self.is_signed = is_signed
+
+ if base is not None:
+ self.base = base
+
+ if encoding is not None:
+ self.encoding = encoding
+
+ if mapped_clock_class is not None:
+ self.mapped_clock_class = mapped_clock_class
+
+ @property
+ def size(self):
+ size = native_bt.ctf_field_type_integer_get_size(self._ptr)
+ assert(size >= 1)
+ return size
+
+ @property
+ def is_signed(self):
+ is_signed = native_bt.ctf_field_type_integer_is_signed(self._ptr)
+ assert(is_signed >= 0)
+ return is_signed > 0
+
+ @is_signed.setter
+ def is_signed(self, is_signed):
+ utils._check_bool(is_signed)
+ ret = native_bt.ctf_field_type_integer_set_is_signed(self._ptr, int(is_signed))
+ utils._handle_ret(ret, "cannot set integer field type object's signedness")
+
+ @property
+ def base(self):
+ base = native_bt.ctf_field_type_integer_get_base(self._ptr)
+ assert(base >= 0)
+ return base
+
+ @base.setter
+ def base(self, base):
+ utils._check_int(base)
+ ret = native_bt.ctf_field_type_integer_set_base(self._ptr, base)
+ utils._handle_ret(ret, "cannot set integer field type object's base")
+
+ @property
+ def encoding(self):
+ encoding = native_bt.ctf_field_type_integer_get_encoding(self._ptr)
+ assert(encoding >= 0)
+ return encoding
+
+ @encoding.setter
+ def encoding(self, encoding):
+ utils._check_int(encoding)
+ ret = native_bt.ctf_field_type_integer_set_encoding(self._ptr, encoding)
+ utils._handle_ret(ret, "cannot set integer field type object's encoding")
+
+ @property
+ def mapped_clock_class(self):
+ ptr = native_bt.ctf_field_type_integer_get_mapped_clock_class(self._ptr)
+
+ if ptr is None:
+ return
+
+ return bt2.ClockClass._create_from_ptr(ptr)
+
+ @mapped_clock_class.setter
+ def mapped_clock_class(self, clock_class):
+ utils._check_type(clock_class, bt2.ClockClass)
+ ret = native_bt.ctf_field_type_integer_set_mapped_clock_class(self._ptr, clock_class._ptr)
+ utils._handle_ret(ret, "cannot set integer field type object's mapped clock class")
+
+
+class FloatingPointNumberFieldType(_FieldType, _AlignmentProp, _ByteOrderProp):
+ _NAME = 'Floating point number'
+
+ def __init__(self, alignment=None, byte_order=None, exponent_size=None,
+ mantissa_size=None):
+ ptr = native_bt.ctf_field_type_floating_point_create()
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ if alignment is not None:
+ self.alignment = alignment
+
+ if byte_order is not None:
+ self.byte_order = byte_order
+
+ if exponent_size is not None:
+ self.exponent_size = exponent_size
+
+ if mantissa_size is not None:
+ self.mantissa_size = mantissa_size
+
+ @property
+ def exponent_size(self):
+ exp_size = native_bt.ctf_field_type_floating_point_get_exponent_digits(self._ptr)
+ assert(exp_size >= 0)
+ return exp_size
+
+ @exponent_size.setter
+ def exponent_size(self, exponent_size):
+ utils._check_uint64(exponent_size)
+ ret = native_bt.ctf_field_type_floating_point_set_exponent_digits(self._ptr, exponent_size)
+ utils._handle_ret(ret, "cannot set floating point number field type object's exponent size")
+
+ @property
+ def mantissa_size(self):
+ mant_size = native_bt.ctf_field_type_floating_point_get_mantissa_digits(self._ptr)
+ assert(mant_size >= 0)
+ return mant_size
+
+ @mantissa_size.setter
+ def mantissa_size(self, mantissa_size):
+ utils._check_uint64(mantissa_size)
+ ret = native_bt.ctf_field_type_floating_point_set_mantissa_digits(self._ptr, mantissa_size)
+ utils._handle_ret(ret, "cannot set floating point number field type object's mantissa size")
+
+
+class _EnumerationFieldTypeMapping:
+ def __init__(self, name, lower, upper):
+ self._name = name
+ self._lower = lower
+ self._upper = upper
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def lower(self):
+ return self._lower
+
+ @property
+ def upper(self):
+ return self._upper
+
+ def __eq__(self, other):
+ if type(other) is not self.__class__:
+ return False
+
+ return (self.name, self.lower, self.upper) == (other.name, other.lower, other.upper)
+
+
+class _EnumerationFieldTypeMappingIterator(object._Object,
+ collections.abc.Iterator):
+ def __init__(self, iter_ptr, is_signed):
+ super().__init__(iter_ptr)
+ self._is_signed = is_signed
+ self._done = (iter_ptr is None)
+
+ def __next__(self):
+ if self._done:
+ raise StopIteration
+
+ if self._is_signed:
+ ret, name, lower, upper = native_bt.ctf_field_type_enumeration_mapping_iterator_get_signed(self._ptr)
+ else:
+ ret, name, lower, upper = native_bt.ctf_field_type_enumeration_mapping_iterator_get_unsigned(self._ptr)
+
+ assert(ret == 0)
+ mapping = _EnumerationFieldTypeMapping(name, lower, upper)
+ ret = native_bt.ctf_field_type_enumeration_mapping_iterator_next(self._ptr)
+
+ if ret < 0:
+ self._done = True
+
+ return mapping
+
+
+class EnumerationFieldType(IntegerFieldType, collections.abc.Sequence):
+ _NAME = 'Enumeration'
+
+ def __init__(self, int_field_type=None, size=None, alignment=None,
+ byte_order=None, is_signed=None, base=None, encoding=None,
+ mapped_clock_class=None):
+ if int_field_type is None:
+ int_field_type = IntegerFieldType(size=size, alignment=alignment,
+ byte_order=byte_order,
+ is_signed=is_signed, base=base,
+ encoding=encoding,
+ mapped_clock_class=mapped_clock_class)
+
+ utils._check_type(int_field_type, IntegerFieldType)
+ ptr = native_bt.ctf_field_type_enumeration_create(int_field_type._ptr)
+ self._check_create_status(ptr)
+ _FieldType.__init__(self, ptr)
+
+ @property
+ def integer_field_type(self):
+ ptr = native_bt.ctf_field_type_enumeration_get_container_type(self._ptr)
+ assert(ptr)
+ return _create_from_ptr(ptr)
+
+ @property
+ def size(self):
+ return self.integer_field_type.size
+
+ @property
+ def alignment(self):
+ return self.integer_field_type.alignment
+
+ @alignment.setter
+ def alignment(self, alignment):
+ self.integer_field_type.alignment = alignment
+
+ @property
+ def byte_order(self):
+ return self.integer_field_type.byte_order
+
+ @byte_order.setter
+ def byte_order(self, byte_order):
+ self.integer_field_type.byte_order = byte_order
+
+ @property
+ def is_signed(self):
+ return self.integer_field_type.is_signed
+
+ @is_signed.setter
+ def is_signed(self, is_signed):
+ self.integer_field_type.is_signed = is_signed
+
+ @property
+ def base(self):
+ return self.integer_field_type.base
+
+ @base.setter
+ def base(self, base):
+ self.integer_field_type.base = base
+
+ @property
+ def encoding(self):
+ return self.integer_field_type.encoding
+
+ @encoding.setter
+ def encoding(self, encoding):
+ self.integer_field_type.encoding = encoding
+
+ @property
+ def mapped_clock_class(self):
+ return self.integer_field_type.mapped_clock_class
+
+ @mapped_clock_class.setter
+ def mapped_clock_class(self, mapped_clock_class):
+ self.integer_field_type.mapped_clock_class = mapped_clock_class
+
+ def __len__(self):
+ count = native_bt.ctf_field_type_enumeration_get_mapping_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ def __getitem__(self, index):
+ utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
+ if self.is_signed:
+ get_fn = native_bt.ctf_field_type_enumeration_get_mapping_signed
+ else:
+ get_fn = native_bt.ctf_field_type_enumeration_get_mapping_unsigned
+
+ ret, name, lower, upper = get_fn(self._ptr, index)
+ assert(ret == 0)
+ return _EnumerationFieldTypeMapping(name, lower, upper)
+
+ def _get_mapping_iter(self, iter_ptr):
+ return _EnumerationFieldTypeMappingIterator(iter_ptr, self.is_signed)
+
+ def mappings_by_name(self, name):
+ utils._check_str(name)
+ iter_ptr = native_bt.ctf_field_type_enumeration_find_mappings_by_name(self._ptr, name)
+ return self._get_mapping_iter(iter_ptr)
+
+ def mappings_by_value(self, value):
+ if self.is_signed:
+ utils._check_int64(value)
+ iter_ptr = native_bt.ctf_field_type_enumeration_find_mappings_by_signed_value(self._ptr, value)
+ else:
+ utils._check_uint64(value)
+ iter_ptr = native_bt.ctf_field_type_enumeration_find_mappings_by_unsigned_value(self._ptr, value)
+
+ return self._get_mapping_iter(iter_ptr)
+
+ def append_mapping(self, name, lower, upper=None):
+ utils._check_str(name)
+
+ if upper is None:
+ upper = lower
+
+ if self.is_signed:
+ add_fn = native_bt.ctf_field_type_enumeration_add_mapping_signed
+ utils._check_int64(lower)
+ utils._check_int64(upper)
+ else:
+ add_fn = native_bt.ctf_field_type_enumeration_add_mapping_unsigned
+ utils._check_uint64(lower)
+ utils._check_uint64(upper)
+
+ ret = add_fn(self._ptr, name, lower, upper)
+ utils._handle_ret(ret, "cannot add mapping to enumeration field type object")
+
+ def __iadd__(self, mappings):
+ for mapping in mappings:
+ self.append_mapping(mapping.name, mapping.lower, mapping.upper)
+
+ return self
+
+
+class StringFieldType(_FieldType):
+ _NAME = 'String'
+
+ def __init__(self, encoding=None):
+ ptr = native_bt.ctf_field_type_string_create()
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ if encoding is not None:
+ self.encoding = encoding
+
+ @property
+ def encoding(self):
+ encoding = native_bt.ctf_field_type_string_get_encoding(self._ptr)
+ assert(encoding >= 0)
+ return encoding
+
+ @encoding.setter
+ def encoding(self, encoding):
+ utils._check_int(encoding)
+ ret = native_bt.ctf_field_type_string_set_encoding(self._ptr, encoding)
+ utils._handle_ret(ret, "cannot set string field type object's encoding")
+
+
+class _FieldContainer(collections.abc.Mapping):
+ def __len__(self):
+ count = self._count()
+ assert(count >= 0)
+ return count
+
+ def __getitem__(self, key):
+ if not isinstance(key, str):
+ raise TypeError("'{}' is not a 'str' object".format(key.__class__.__name__))
+
+ ptr = self._get_field_by_name(key)
+
+ if ptr is None:
+ raise KeyError(key)
+
+ return _create_from_ptr(ptr)
+
+ def __iter__(self):
+ return self._ITER_CLS(self)
+
+ def append_field(self, name, field_type):
+ utils._check_str(name)
+ utils._check_type(field_type, _FieldType)
+ ret = self._add_field(field_type._ptr, name)
+ utils._handle_ret(ret, "cannot add field to {} field type object".format(self._NAME.lower()))
+
+ def __iadd__(self, fields):
+ for name, field_type in fields.items():
+ self.append_field(name, field_type)
+
+ return self
+
+ def at_index(self, index):
+ utils._check_uint64(index)
+ return self._at(index)
+
+
+class _StructureFieldTypeFieldIterator(collections.abc.Iterator):
+ def __init__(self, struct_field_type):
+ self._struct_field_type = struct_field_type
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._struct_field_type):
+ raise StopIteration
+
+ get_ft_by_index = native_bt.ctf_field_type_structure_get_field_by_index
+ ret, name, field_type_ptr = get_ft_by_index(self._struct_field_type._ptr,
+ self._at)
+ assert(ret == 0)
+ native_bt.put(field_type_ptr)
+ self._at += 1
+ return name
+
+
+class StructureFieldType(_FieldType, _FieldContainer, _AlignmentProp):
+ _NAME = 'Structure'
+ _ITER_CLS = _StructureFieldTypeFieldIterator
+
+ def __init__(self, min_alignment=None):
+ ptr = native_bt.ctf_field_type_structure_create()
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ if min_alignment is not None:
+ self.min_alignment = min_alignment
+
+ def _count(self):
+ return native_bt.ctf_field_type_structure_get_field_count(self._ptr)
+
+ def _get_field_by_name(self, key):
+ return native_bt.ctf_field_type_structure_get_field_type_by_name(self._ptr, key)
+
+ def _add_field(self, ptr, name):
+ return native_bt.ctf_field_type_structure_add_field(self._ptr, ptr,
+ name)
+
+ def _at(self, index):
+ if index < 0 or index >= len(self):
+ raise IndexError
+
+ ret, name, field_type_ptr = native_bt.ctf_field_type_structure_get_field_by_index(self._ptr, index)
+ assert(ret == 0)
+ return _create_from_ptr(field_type_ptr)
+
+
+StructureFieldType.min_alignment = property(fset=StructureFieldType.alignment.fset)
+StructureFieldType.alignment = property(fget=StructureFieldType.alignment.fget)
+
+
+class _VariantFieldTypeFieldIterator(collections.abc.Iterator):
+ def __init__(self, variant_field_type):
+ self._variant_field_type = variant_field_type
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._variant_field_type):
+ raise StopIteration
+
+ ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field_by_index(self._variant_field_type._ptr,
+ self._at)
+ assert(ret == 0)
+ native_bt.put(field_type_ptr)
+ self._at += 1
+ return name
+
+
+class VariantFieldType(_FieldType, _FieldContainer, _AlignmentProp):
+ _NAME = 'Variant'
+ _ITER_CLS = _VariantFieldTypeFieldIterator
+
+ def __init__(self, tag_name, tag_field_type=None):
+ utils._check_str(tag_name)
+
+ if tag_field_type is None:
+ tag_ft_ptr = None
+ else:
+ utils._check_type(tag_field_type, EnumerationFieldType)
+ tag_ft_ptr = tag_field_type._ptr
+
+ ptr = native_bt.ctf_field_type_variant_create(tag_ft_ptr,
+ tag_name)
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ @property
+ def tag_name(self):
+ tag_name = native_bt.ctf_field_type_variant_get_tag_name(self._ptr)
+ assert(tag_name is not None)
+ return tag_name
+
+ @tag_name.setter
+ def tag_name(self, tag_name):
+ utils._check_str(tag_name)
+ ret = native_bt.ctf_field_type_variant_set_tag_name(self._ptr, tag_name)
+ utils._handle_ret(ret, "cannot set variant field type object's tag name")
+
+ @property
+ def tag_field_type(self):
+ ft_ptr = native_bt.ctf_field_type_variant_get_tag_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return _create_from_ptr(ft_ptr)
+
+ def _count(self):
+ return native_bt.ctf_field_type_variant_get_field_count(self._ptr)
+
+ def _get_field_by_name(self, key):
+ return native_bt.ctf_field_type_variant_get_field_type_by_name(self._ptr, key)
+
+ def _add_field(self, ptr, name):
+ return native_bt.ctf_field_type_variant_add_field(self._ptr, ptr, name)
+
+ def _at(self, index):
+ if index < 0 or index >= len(self):
+ raise IndexError
+
+ ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field_by_index(self._ptr, index)
+ assert(ret == 0)
+ return _create_from_ptr(field_type_ptr)
+
+
+class ArrayFieldType(_FieldType):
+ _NAME = 'Array'
+
+ def __init__(self, element_field_type, length):
+ utils._check_type(element_field_type, _FieldType)
+ utils._check_uint64(length)
+ ptr = native_bt.ctf_field_type_array_create(element_field_type._ptr, length)
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ @property
+ def length(self):
+ length = native_bt.ctf_field_type_array_get_length(self._ptr)
+ assert(length >= 0)
+ return length
+
+ @property
+ def element_field_type(self):
+ ptr = native_bt.ctf_field_type_array_get_element_type(self._ptr)
+ assert(ptr)
+ return _create_from_ptr(ptr)
+
+
+class SequenceFieldType(_FieldType):
+ _NAME = 'Sequence'
+
+ def __init__(self, element_field_type, length_name):
+ utils._check_type(element_field_type, _FieldType)
+ utils._check_str(length_name)
+ ptr = native_bt.ctf_field_type_sequence_create(element_field_type._ptr,
+ length_name)
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ @property
+ def length_name(self):
+ length_name = native_bt.ctf_field_type_sequence_get_length_field_name(self._ptr)
+ assert(length_name is not None)
+ return length_name
+
+ @property
+ def element_field_type(self):
+ ptr = native_bt.ctf_field_type_sequence_get_element_type(self._ptr)
+ assert(ptr)
+ return _create_from_ptr(ptr)
+
+
+_TYPE_ID_TO_OBJ = {
+ native_bt.CTF_FIELD_TYPE_ID_INTEGER: IntegerFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_FLOAT: FloatingPointNumberFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_ENUM: EnumerationFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_STRING: StringFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_STRUCT: StructureFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_ARRAY: ArrayFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_SEQUENCE: SequenceFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_VARIANT: VariantFieldType,
+}
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.field_types
+import collections.abc
+import functools
+import numbers
+import math
+import abc
+import bt2
+
+
+def _create_from_ptr(ptr):
+ # recreate the field type wrapper of this field's type (the identity
+ # could be different, but the underlying address should be the
+ # same)
+ field_type_ptr = native_bt.ctf_field_get_type(ptr)
+ utils._handle_ptr(field_type_ptr, "cannot get field object's type")
+ field_type = bt2.field_types._create_from_ptr(field_type_ptr)
+ typeid = native_bt.ctf_field_type_get_type_id(field_type._ptr)
+ field = _TYPE_ID_TO_OBJ[typeid]._create_from_ptr(ptr)
+ field._field_type = field_type
+ return field
+
+
+class _Field(object._Object, metaclass=abc.ABCMeta):
+ def __copy__(self):
+ ptr = native_bt.ctf_field_copy(self._ptr)
+ utils._handle_ptr(ptr, 'cannot copy {} field object'.format(self._NAME.lower()))
+ return _create_from_ptr(ptr)
+
+ def __deepcopy__(self, memo):
+ cpy = self.__copy__()
+ memo[id(self)] = cpy
+ return cpy
+
+ @property
+ def field_type(self):
+ return self._field_type
+
+
+@functools.total_ordering
+class _NumericField(_Field):
+ @staticmethod
+ def _extract_value(other):
+ if other is True or other is False:
+ return other
+
+ if isinstance(other, numbers.Integral):
+ return int(other)
+
+ if isinstance(other, numbers.Real):
+ return float(other)
+
+ if isinstance(other, numbers.Complex):
+ return complex(other)
+
+ raise TypeError("'{}' object is not a number object".format(other.__class__.__name__))
+
+ def __int__(self):
+ return int(self.value)
+
+ def __float__(self):
+ return float(self.value)
+
+ def __str__(self):
+ return str(self.value)
+
+ def __lt__(self, other):
+ if not isinstance(other, numbers.Number):
+ raise TypeError('unorderable types: {}() < {}()'.format(self.__class__.__name__,
+ other.__class__.__name__))
+
+ return self.value < float(other)
+
+ def __le__(self, other):
+ if not isinstance(other, numbers.Number):
+ raise TypeError('unorderable types: {}() <= {}()'.format(self.__class__.__name__,
+ other.__class__.__name__))
+
+ return self.value <= float(other)
+
+ def __eq__(self, other):
+ if not isinstance(other, numbers.Number):
+ return False
+
+ return self.value == complex(other)
+
+ def __rmod__(self, other):
+ return self._extract_value(other) % self.value
+
+ def __mod__(self, other):
+ return self.value % self._extract_value(other)
+
+ def __rfloordiv__(self, other):
+ return self._extract_value(other) // self.value
+
+ def __floordiv__(self, other):
+ return self.value // self._extract_value(other)
+
+ def __round__(self, ndigits=None):
+ if ndigits is None:
+ return round(self.value)
+ else:
+ return round(self.value, ndigits)
+
+ def __ceil__(self):
+ return math.ceil(self.value)
+
+ def __floor__(self):
+ return math.floor(self.value)
+
+ def __trunc__(self):
+ return int(self.value)
+
+ def __abs__(self):
+ return abs(self.value)
+
+ def __add__(self, other):
+ return self.value + self._extract_value(other)
+
+ def __radd__(self, other):
+ return self.__add__(other)
+
+ def __neg__(self):
+ return -self.value
+
+ def __pos__(self):
+ return +self.value
+
+ def __mul__(self, other):
+ return self.value * self._extract_value(other)
+
+ def __rmul__(self, other):
+ return self.__mul__(other)
+
+ def __truediv__(self, other):
+ return self.value / self._extract_value(other)
+
+ def __rtruediv__(self, other):
+ return self._extract_value(other) / self.value
+
+ def __pow__(self, exponent):
+ return self.value ** self._extract_value(exponent)
+
+ def __rpow__(self, base):
+ return self._extract_value(base) ** self.value
+
+ def __iadd__(self, other):
+ self.value = self + other
+ return self
+
+ def __isub__(self, other):
+ self.value = self - other
+ return self
+
+ def __imul__(self, other):
+ self.value = self * other
+ return self
+
+ def __itruediv__(self, other):
+ self.value = self / other
+ return self
+
+ def __ifloordiv__(self, other):
+ self.value = self // other
+ return self
+
+ def __imod__(self, other):
+ self.value = self % other
+ return self
+
+ def __ipow__(self, other):
+ self.value = self ** other
+ return self
+
+
+class _IntegralField(_NumericField, numbers.Integral):
+ def __lshift__(self, other):
+ return self.value << self._extract_value(other)
+
+ def __rlshift__(self, other):
+ return self._extract_value(other) << self.value
+
+ def __rshift__(self, other):
+ return self.value >> self._extract_value(other)
+
+ def __rrshift__(self, other):
+ return self._extract_value(other) >> self.value
+
+ def __and__(self, other):
+ return self.value & self._extract_value(other)
+
+ def __rand__(self, other):
+ return self._extract_value(other) & self.value
+
+ def __xor__(self, other):
+ return self.value ^ self._extract_value(other)
+
+ def __rxor__(self, other):
+ return self._extract_value(other) ^ self.value
+
+ def __or__(self, other):
+ return self.value | self._extract_value(other)
+
+ def __ror__(self, other):
+ return self._extract_value(other) | self.value
+
+ def __invert__(self):
+ return ~self.value
+
+ def __ilshift__(self, other):
+ self.value = self << other
+ return self
+
+ def __irshift__(self, other):
+ self.value = self >> other
+ return self
+
+ def __iand__(self, other):
+ self.value = self & other
+ return self
+
+ def __ixor__(self, other):
+ self.value = self ^ other
+ return self
+
+ def __ior__(self, other):
+ self.value = self | other
+ return self
+
+
+class _RealField(_NumericField, numbers.Real):
+ pass
+
+
+class _IntegerField(_IntegralField):
+ _NAME = 'Integer'
+
+ def _value_to_int(self, value):
+ if not isinstance(value, numbers.Real):
+ raise TypeError('expecting a real number object')
+
+ value = int(value)
+
+ if self.field_type.is_signed:
+ utils._check_int64(value)
+ else:
+ utils._check_uint64(value)
+
+ return value
+
+ @property
+ def value(self):
+ if self.field_type.is_signed:
+ ret, value = native_bt.ctf_field_signed_integer_get_value(self._ptr)
+ else:
+ ret, value = native_bt.ctf_field_unsigned_integer_get_value(self._ptr)
+
+ if ret < 0:
+ # field is not set
+ return
+
+ return value
+
+ @value.setter
+ def value(self, value):
+ value = self._value_to_int(value)
+
+ if self.field_type.is_signed:
+ ret = native_bt.ctf_field_signed_integer_set_value(self._ptr, value)
+ else:
+ ret = native_bt.ctf_field_unsigned_integer_set_value(self._ptr, value)
+
+ utils._handle_ret(ret, "cannot set integer field object's value")
+
+
+class _FloatingPointNumberField(_RealField):
+ _NAME = 'Floating point number'
+
+ def _value_to_float(self, value):
+ if not isinstance(value, numbers.Real):
+ raise TypeError("expecting a real number object")
+
+ return float(value)
+
+ @property
+ def value(self):
+ ret, value = native_bt.ctf_field_floating_point_get_value(self._ptr)
+
+ if ret < 0:
+ # field is not set
+ return
+
+ return value
+
+ @value.setter
+ def value(self, value):
+ value = self._value_to_float(value)
+ ret = native_bt.ctf_field_floating_point_set_value(self._ptr, value)
+ utils._handle_ret(ret, "cannot set floating point number field object's value")
+
+
+class _EnumerationField(_IntegerField):
+ _NAME = 'Enumeration'
+
+ @property
+ def integer_field(self):
+ int_field_ptr = native_bt.ctf_field_enumeration_get_container(self._ptr)
+ assert(int_field_ptr)
+ return _create_from_ptr(int_field_ptr)
+
+ @property
+ def value(self):
+ return self.integer_field.value
+
+ @value.setter
+ def value(self, value):
+ self.integer_field.value = value
+
+ @property
+ def mappings(self):
+ iter_ptr = native_bt.ctf_field_enumeration_get_mappings(self._ptr)
+ assert(iter_ptr)
+ return bt2.field_types._EnumerationFieldTypeMappingIterator(iter_ptr,
+ self.field_type.is_signed)
+
+
+@functools.total_ordering
+class _StringField(_Field, collections.abc.Sequence):
+ _NAME = 'String'
+
+ def _value_to_str(self, value):
+ if isinstance(value, self.__class__):
+ value = value.value
+
+ if not isinstance(value, str):
+ raise TypeError("expecting a 'str' object")
+
+ return value
+
+ @property
+ def value(self):
+ value = native_bt.ctf_field_string_get_value(self._ptr)
+
+ if value is None:
+ # field is not set
+ return
+
+ return value
+
+ @value.setter
+ def value(self, value):
+ value = self._value_to_str(value)
+ ret = native_bt.ctf_field_string_set_value(self._ptr, value)
+ utils._handle_ret(ret, "cannot set string field object's value")
+
+ def __eq__(self, other):
+ try:
+ other = self._value_to_str(other)
+ except:
+ return False
+
+ return self.value == other
+
+ def __le__(self, other):
+ return self.value <= self._value_to_str(other)
+
+ def __lt__(self, other):
+ return self.value < self._value_to_str(other)
+
+ def __bool__(self):
+ return bool(self.value)
+
+ def __str__(self):
+ return self.value
+
+ def __getitem__(self, index):
+ return self.value[index]
+
+ def __len__(self):
+ return len(self.value)
+
+ def __iadd__(self, value):
+ value = self._value_to_str(value)
+ ret = native_bt.ctf_field_string_append(self._ptr, value)
+ utils._handle_ret(ret, "cannot append to string field object's value")
+ return self
+
+
+class _ContainerField(_Field):
+ def __bool__(self):
+ return len(self) != 0
+
+ def __len__(self):
+ count = self._count()
+ assert(count >= 0)
+ return count
+
+ def __delitem__(self, index):
+ raise NotImplementedError
+
+
+class _StructureField(_ContainerField, collections.abc.MutableMapping):
+ _NAME = 'Structure'
+
+ def _count(self):
+ return len(self.field_type)
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ ptr = native_bt.ctf_field_structure_get_field_by_name(self._ptr, key)
+
+ if ptr is None:
+ raise KeyError(key)
+
+ return _create_from_ptr(ptr)
+
+ def __setitem__(self, key, value):
+ # we can only set numbers and strings
+ if not isinstance(value, (numbers.Number, str)):
+ raise TypeError('expecting number object or string')
+
+ # raises if index is somehow invalid
+ field = self[key]
+
+ if not isinstance(field, (_NumericField, _StringField)):
+ raise TypeError('can only set the value of a number or string field')
+
+ # the field's property does the appropriate conversion or raises
+ # the appropriate exception
+ field.value = value
+
+ def at_index(self, index):
+ utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
+ field_ptr = native_bt.ctf_field_structure_get_field_by_index(self._ptr, index)
+ assert(field_ptr)
+ return _create_from_ptr(field_ptr)
+
+ def __iter__(self):
+ # same name iterator
+ return iter(self.field_type)
+
+ def __eq__(self, other):
+ if not isinstance(other, collections.abc.Mapping):
+ return False
+
+ if len(self) != len(other):
+ return False
+
+ for self_key, self_value in self.items():
+ if self_key not in other:
+ return False
+
+ other_value = other[self_key]
+
+ if self_value != other_value:
+ return False
+
+ return True
+
+
+class _VariantField(_Field):
+ _NAME = 'Variant'
+
+ @property
+ def tag_field(self):
+ field_ptr = native_bt.ctf_field_variant_get_tag(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return _create_from_ptr(field_ptr)
+
+ @property
+ def selected_field(self):
+ return self.field()
+
+ def field(self, tag_field=None):
+ if tag_field is None:
+ field_ptr = native_bt.ctf_field_variant_get_current_field(self._ptr)
+
+ if field_ptr is None:
+ return
+ else:
+ utils._check_type(tag_field, _EnumerationField)
+ field_ptr = native_bt.ctf_field_variant_get_field(self._ptr, tag_field._ptr)
+ utils._handle_ptr(field_ptr, "cannot select variant field object's field")
+
+ return _create_from_ptr(field_ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self.selected_field == other.selected_field
+
+ def __bool__(self):
+ return bool(self.selected_field)
+
+
+class _ArraySequenceField(_ContainerField, collections.abc.MutableSequence):
+ def __getitem__(self, index):
+ if not isinstance(index, numbers.Integral):
+ raise TypeError("'{}' is not an integral number object: invalid index".format(index.__class__.__name__))
+
+ index = int(index)
+
+ if index < 0 or index >= len(self):
+ raise IndexError('{} field object index is out of range'.format(self._NAME))
+
+ field_ptr = self._get_field_ptr_at_index(index)
+ assert(field_ptr)
+ return _create_from_ptr(field_ptr)
+
+ def __setitem__(self, index, value):
+ # we can only set numbers and strings
+ if not isinstance(value, (numbers.Number, _StringField, str)):
+ raise TypeError('expecting number or string object')
+
+ # raises if index is somehow invalid
+ field = self[index]
+
+ if not isinstance(field, (_NumericField, _StringField)):
+ raise TypeError('can only set the value of a number or string field')
+
+ # the field's property does the appropriate conversion or raises
+ # the appropriate exception
+ field.value = value
+
+ def insert(self, index, value):
+ raise NotImplementedError
+
+ def __eq__(self, other):
+ if not isinstance(other, collections.abc.Sequence):
+ return False
+
+ if len(self) != len(other):
+ return False
+
+ for self_field, other_field in zip(self, other):
+ if self_field != other_field:
+ return False
+
+ return True
+
+
+class _ArrayField(_ArraySequenceField):
+ _NAME = 'Array'
+
+ def _count(self):
+ return self.field_type.length
+
+ def _get_field_ptr_at_index(self, index):
+ return native_bt.ctf_field_array_get_field(self._ptr, index)
+
+
+class _SequenceField(_ArraySequenceField):
+ _NAME = 'Sequence'
+
+ def _count(self):
+ return self.length_field.value
+
+ @property
+ def length_field(self):
+ field_ptr = native_bt.ctf_field_sequence_get_length(self._ptr)
+ utils._handle_ptr("cannot get sequence field object's length field")
+ return _create_from_ptr(field_ptr)
+
+ @length_field.setter
+ def length_field(self, length_field):
+ utils._check_type(length_field, _IntegerField)
+ ret = native_bt.ctf_field_sequence_set_length(self._ptr, length_field._ptr)
+ utils._handle_ret(ret, "cannot set sequence field object's length field")
+
+ def _get_field_ptr_at_index(self, index):
+ return native_bt.ctf_field_sequence_get_field(self._ptr, index)
+
+
+_TYPE_ID_TO_OBJ = {
+ native_bt.CTF_FIELD_TYPE_ID_INTEGER: _IntegerField,
+ native_bt.CTF_FIELD_TYPE_ID_FLOAT: _FloatingPointNumberField,
+ native_bt.CTF_FIELD_TYPE_ID_ENUM: _EnumerationField,
+ native_bt.CTF_FIELD_TYPE_ID_STRING: _StringField,
+ native_bt.CTF_FIELD_TYPE_ID_STRUCT: _StructureField,
+ native_bt.CTF_FIELD_TYPE_ID_ARRAY: _ArrayField,
+ native_bt.CTF_FIELD_TYPE_ID_SEQUENCE: _SequenceField,
+ native_bt.CTF_FIELD_TYPE_ID_VARIANT: _VariantField,
+}
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.connection
+import bt2.component
+import functools
+import bt2.port
+import bt2
+
+
+class GraphListenerType:
+ PORT_ADDED = 0
+ PORT_REMOVED = 1
+ PORTS_CONNECTED = 2
+ PORTS_DISCONNECTED = 3
+
+
+def _graph_port_added_listener_from_native(user_listener, port_ptr):
+ try:
+ port = bt2.port._create_from_ptr(port_ptr)
+ port._get()
+ user_listener(port)
+ except:
+ pass
+
+
+def _graph_port_removed_listener_from_native(user_listener, port_ptr):
+ try:
+ port = bt2.port._create_from_ptr(port_ptr)
+ port._get()
+ user_listener(port)
+ except:
+ pass
+
+
+def _graph_ports_connected_listener_from_native(user_listener,
+ upstream_port_ptr,
+ downstream_port_ptr):
+ try:
+ upstream_port = bt2.port._create_from_ptr(upstream_port_ptr)
+ upstream_port._get()
+ downstream_port = bt2.port._create_from_ptr(downstream_port_ptr)
+ downstream_port._get()
+ user_listener(upstream_port, downstream_port)
+ except:
+ pass
+
+
+def _graph_ports_disconnected_listener_from_native(user_listener,
+ upstream_comp_ptr,
+ downstream_comp_ptr,
+ upstream_port_ptr,
+ downstream_port_ptr):
+ try:
+ upstream_comp = bt2.component._create_generic_component_from_ptr(upstream_comp_ptr)
+ upstream_comp._get()
+ downstream_comp = bt2.component._create_generic_component_from_ptr(downstream_comp_ptr)
+ downstream_comp._get()
+ upstream_port = bt2.port._create_from_ptr(upstream_port_ptr)
+ upstream_port._get()
+ downstream_port = bt2.port._create_from_ptr(downstream_port_ptr)
+ downstream_port._get()
+ user_listener(upstream_comp, downstream_comp, upstream_port,
+ downstream_port)
+ except:
+ pass
+
+
+class Graph(object._Object):
+ def __init__(self):
+ ptr = native_bt.graph_create()
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create graph object')
+
+ super().__init__(ptr)
+
+ def _handle_status(self, status, gen_error_msg):
+ if status == native_bt.GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION:
+ raise bt2.PortConnectionRefused
+ elif status == native_bt.GRAPH_STATUS_CANCELED:
+ raise bt2.GraphCanceled
+ elif status == native_bt.GRAPH_STATUS_END:
+ raise bt2.Stop
+ elif status == native_bt.GRAPH_STATUS_AGAIN:
+ raise bt2.TryAgain
+ elif status == native_bt.GRAPH_STATUS_NO_SINK:
+ raise bt2.NoSinkComponent
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+ def add_component(self, component_class, name, params=None):
+ if isinstance(component_class, bt2.component._GenericComponentClass):
+ cc_ptr = component_class._ptr
+ elif issubclass(component_class, bt2.component._UserComponent):
+ cc_ptr = component_class._cc_ptr
+ else:
+ raise TypeError("'{}' is not a component class".format(component_class.__class__.__name__))
+
+ utils._check_str(name)
+ params = bt2.create_value(params)
+
+ if params is None:
+ params_ptr = None
+ else:
+ params_ptr = params._ptr
+
+ status, comp_ptr = native_bt.graph_add_component(self._ptr, cc_ptr,
+ name, params_ptr)
+ self._handle_status(status, 'cannot add component to graph')
+ assert(comp_ptr)
+ return bt2.component._create_generic_component_from_ptr(comp_ptr)
+
+ def connect_ports(self, upstream_port, downstream_port):
+ utils._check_type(upstream_port, bt2.port._OutputPort)
+ utils._check_type(downstream_port, bt2.port._InputPort)
+ status, conn_ptr = native_bt.graph_connect_ports(self._ptr,
+ upstream_port._ptr,
+ downstream_port._ptr)
+ self._handle_status(status, 'cannot connect component ports within graph')
+ assert(conn_ptr)
+ return bt2.connection._Connection._create_from_ptr(conn_ptr)
+
+ def add_listener(self, listener_type, listener):
+ if not hasattr(listener, '__call__'):
+ raise TypeError("'listener' parameter is not callable")
+
+ if listener_type == GraphListenerType.PORT_ADDED:
+ fn = native_bt.py3_graph_add_port_added_listener
+ listener_from_native = functools.partial(_graph_port_added_listener_from_native,
+ listener)
+ elif listener_type == GraphListenerType.PORT_REMOVED:
+ fn = native_bt.py3_graph_add_port_removed_listener
+ listener_from_native = functools.partial(_graph_port_removed_listener_from_native,
+ listener)
+ elif listener_type == GraphListenerType.PORTS_CONNECTED:
+ fn = native_bt.py3_graph_add_ports_connected_listener
+ listener_from_native = functools.partial(_graph_ports_connected_listener_from_native,
+ listener)
+ elif listener_type == GraphListenerType.PORTS_DISCONNECTED:
+ fn = native_bt.py3_graph_add_ports_disconnected_listener
+ listener_from_native = functools.partial(_graph_ports_disconnected_listener_from_native,
+ listener)
+ else:
+ raise TypeError
+
+ listener_id = fn(self._ptr, listener_from_native)
+ utils._handle_ret(listener_id, 'cannot add listener to graph object')
+ return bt2._ListenerHandle(listener_id, self)
+
+ def run(self):
+ status = native_bt.graph_run(self._ptr)
+
+ if status == native_bt.GRAPH_STATUS_END:
+ return
+
+ self._handle_status(status, 'graph object stopped running because of an unexpected error')
+
+ def cancel(self):
+ status = native_bt.graph_cancel(self._ptr)
+ self._handle_status(status, 'cannot cancel graph object')
+
+ @property
+ def is_canceled(self):
+ is_canceled = native_bt.graph_is_canceled(self._ptr)
+ assert(is_canceled >= 0)
+ return is_canceled > 0
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ return self.addr == other.addr
--- /dev/null
+/*
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL bt_cli_log_level
+#include <babeltrace/logging-internal.h>
+
+BT_LOG_INIT_LOG_LEVEL(bt_cli_log_level, "BABELTRACE_CLI_LOG_LEVEL");
--- /dev/null
+#ifndef CLI_LOGGING_H
+#define CLI_LOGGING_H
+
+/*
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL bt_cli_log_level
+#include <babeltrace/logging-internal.h>
+
+BT_LOG_LEVEL_EXTERN_SYMBOL(bt_cli_log_level);
+
+#endif /* CLI_LOGGING_H */
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2
+
+
+class LoggingLevel:
+ VERBOSE = native_bt.LOGGING_LEVEL_VERBOSE
+ DEBUG = native_bt.LOGGING_LEVEL_DEBUG
+ INFO = native_bt.LOGGING_LEVEL_INFO
+ WARN = native_bt.LOGGING_LEVEL_WARN
+ ERROR = native_bt.LOGGING_LEVEL_ERROR
+ FATAL = native_bt.LOGGING_LEVEL_FATAL
+ NONE = native_bt.LOGGING_LEVEL_NONE
+
+
+def get_minimal_logging_level():
+ return native_bt.logging_get_minimal_level()
+
+
+def get_global_logging_level():
+ return native_bt.logging_get_global_level()
+
+
+def set_global_logging_level(level):
+ levels = (
+ LoggingLevel.VERBOSE,
+ LoggingLevel.DEBUG,
+ LoggingLevel.INFO,
+ LoggingLevel.WARN,
+ LoggingLevel.ERROR,
+ LoggingLevel.FATAL,
+ LoggingLevel.NONE,
+ )
+
+ if level not in levels:
+ raise TypeError("'{}' is not a valid logging level".format(level))
+
+ return native_bt.logging_set_global_level(level)
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SWIGPYTHON
+# error Unsupported output language
+#endif
+
+%module native_bt
+
+%{
+#define BT_LOG_TAG "PY-NATIVE"
+#include "logging.h"
+
+#include <babeltrace/babeltrace.h>
+
+typedef const unsigned char *BTUUID;
+%}
+
+typedef int bt_bool;
+
+/* For uint*_t/int*_t */
+%include "stdint.i"
+
+/* Remove `bt_` and `BT_` prefixes from function names and enumeration items */
+%rename("%(strip:[bt_])s", %$isfunction) "";
+%rename("%(strip:[BT_])s", %$isenumitem) "";
+
+/* Output argument typemap for string output (always appends) */
+%typemap(in, numinputs=0) const char **BTOUTSTR (char *temp_value = NULL) {
+ $1 = &temp_value;
+}
+
+%typemap(argout) const char **BTOUTSTR {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_Python_str_FromChar(*$1));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for field type output (always appends) */
+%typemap(in, numinputs=0) struct bt_ctf_field_type **BTOUTFT (struct bt_ctf_field_type *temp_ft = NULL) {
+ $1 = &temp_ft;
+}
+
+%typemap(argout) struct bt_ctf_field_type **BTOUTFT {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_ctf_field_type, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for component output (always appends) */
+%typemap(in, numinputs=0) struct bt_component **BTOUTCOMP (struct bt_component *temp_comp = NULL) {
+ $1 = &temp_comp;
+}
+
+%typemap(argout) struct bt_component **BTOUTCOMP {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_component, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for connection output (always appends) */
+%typemap(in, numinputs=0) struct bt_connection **BTOUTCONN (struct bt_connection *temp_conn = NULL) {
+ $1 = &temp_conn;
+}
+
+%typemap(argout) struct bt_connection **BTOUTCONN {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_connection, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for private port output (always appends) */
+%typemap(in, numinputs=0) struct bt_private_port **BTOUTPRIVPORT (struct bt_private_port *temp_priv_port = NULL) {
+ $1 = &temp_priv_port;
+}
+
+%typemap(argout) struct bt_private_port **BTOUTPRIVPORT {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_private_port, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for initialized uint64_t output parameter (always appends) */
+%typemap(in, numinputs=0) uint64_t *OUTPUTINIT (uint64_t temp = -1ULL) {
+ $1 = &temp;
+}
+
+%typemap(argout) uint64_t *OUTPUTINIT {
+ $result = SWIG_Python_AppendOutput(resultobj, SWIG_From_unsigned_SS_long_SS_long((*$1)));
+}
+
+/* Output argument typemap for initialized unsigned int output parameter (always appends) */
+%typemap(in, numinputs=0) unsigned int *OUTPUTINIT (unsigned int temp = -1) {
+ $1 = &temp;
+}
+
+%typemap(argout) unsigned int *OUTPUTINIT {
+ $result = SWIG_Python_AppendOutput(resultobj, SWIG_From_unsigned_SS_long_SS_long((uint64_t) (*$1)));
+}
+
+/* Input argument typemap for UUID bytes */
+%typemap(in) BTUUID {
+ $1 = (unsigned char *) PyBytes_AsString($input);
+}
+
+/* Output argument typemap for UUID bytes */
+%typemap(out) BTUUID {
+ if (!$1) {
+ Py_INCREF(Py_None);
+ $result = Py_None;
+ } else {
+ $result = PyBytes_FromStringAndSize((const char *) $1, 16);
+ }
+}
+
+/*
+ * Input and output argument typemaps for raw Python objects (direct).
+ *
+ * Those typemaps honor the convention of Python C function calls with
+ * respect to reference counting: parameters are passed as borrowed
+ * references, and objects are returned as new references. The wrapped
+ * C function must ensure that the return value is always a new
+ * reference, and never steal parameter references.
+ */
+%typemap(in) PyObject * {
+ $1 = $input;
+}
+
+%typemap(out) PyObject * {
+ $result = $1;
+}
+
+/* Per-module interface files */
+%include "native_btccpriomap.i"
+%include "native_btclockclass.i"
+%include "native_btcomponent.i"
+%include "native_btcomponentclass.i"
+%include "native_btconnection.i"
+%include "native_btctfwriter.i"
+%include "native_btevent.i"
+%include "native_bteventclass.i"
+%include "native_btfields.i"
+%include "native_btft.i"
+%include "native_btgraph.i"
+%include "native_btlogging.i"
+%include "native_btnotification.i"
+%include "native_btnotifiter.i"
+%include "native_btpacket.i"
+%include "native_btplugin.i"
+%include "native_btport.i"
+%include "native_btref.i"
+%include "native_btstream.i"
+%include "native_btstreamclass.i"
+%include "native_bttrace.i"
+%include "native_btvalues.i"
+%include "native_btversion.i"
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+%{
+#include <babeltrace/graph/clock-class-priority-map.h>
+%}
+
+/* Type */
+struct bt_clock_class_priority_map;
+
+/* Functions */
+struct bt_clock_class_priority_map *bt_clock_class_priority_map_create();
+int64_t bt_clock_class_priority_map_get_clock_class_count(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_clock_class_by_index(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ uint64_t index);
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_clock_class_by_name(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ const char *name);
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_highest_priority_clock_class(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+int bt_clock_class_priority_map_get_clock_class_priority(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ struct bt_ctf_clock_class *clock_class, uint64_t *OUTPUTINIT);
+int bt_clock_class_priority_map_add_clock_class(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ struct bt_ctf_clock_class *clock_class, uint64_t priority);
+struct bt_clock_class_priority_map *bt_clock_class_priority_map_copy(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_ctf_clock_class;
+struct bt_ctf_clock_value;
+
+/* Clock class functions */
+struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
+ uint64_t freq);
+const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class);
+int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class, const char *name);
+const char *bt_ctf_clock_class_get_description(struct bt_ctf_clock_class *clock_class);
+int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
+ const char *desc);
+uint64_t bt_ctf_clock_class_get_frequency(struct bt_ctf_clock_class *clock_class);
+int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
+ uint64_t freq);
+uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class);
+int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
+ uint64_t precision);
+int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
+ int64_t *OUTPUT);
+int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
+ int64_t offset_s);
+int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
+ int64_t *OUTPUT);
+int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
+ int64_t offset);
+int bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class);
+int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
+ int is_absolute);
+BTUUID bt_ctf_clock_class_get_uuid(struct bt_ctf_clock_class *clock_class);
+int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
+ BTUUID uuid);
+
+/* Clock value functions */
+struct bt_ctf_clock_value *bt_ctf_clock_value_create(
+ struct bt_ctf_clock_class *clock_class, uint64_t value);
+int bt_ctf_clock_value_get_value(
+ struct bt_ctf_clock_value *clock_value, uint64_t *OUTPUT);
+int bt_ctf_clock_value_get_value_ns_from_epoch(
+ struct bt_ctf_clock_value *clock_value, int64_t *OUTPUT);
+struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
+ struct bt_ctf_clock_value *clock_value);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_component;
+
+/* Status */
+enum bt_component_status {
+ BT_COMPONENT_STATUS_OK = 0,
+ BT_COMPONENT_STATUS_END = 1,
+ BT_COMPONENT_STATUS_AGAIN = 11,
+ BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION = 111,
+ BT_COMPONENT_STATUS_ERROR = -1,
+ BT_COMPONENT_STATUS_UNSUPPORTED = -2,
+ BT_COMPONENT_STATUS_INVALID = -22,
+ BT_COMPONENT_STATUS_NOMEM = -12,
+ BT_COMPONENT_STATUS_NOT_FOUND = -19,
+ BT_COMPONENT_STATUS_GRAPH_IS_CANCELED = 125,
+};
+
+/* General functions */
+const char *bt_component_get_name(struct bt_component *component);
+struct bt_component_class *bt_component_get_class(
+ struct bt_component *component);
+enum bt_component_class_type bt_component_get_class_type(
+ struct bt_component *component);
+struct bt_graph *bt_component_get_graph(struct bt_component *component);
+struct bt_component *bt_component_from_private_component(
+ struct bt_private_component *private_component);
+
+/* Source component functions */
+int64_t bt_component_source_get_output_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_source_get_output_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_source_get_output_port_by_index(
+ struct bt_component *component, uint64_t index);
+
+/* Private source component functions */
+struct bt_private_port *
+bt_private_component_source_get_output_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_source_get_output_private_port_by_index(
+ struct bt_private_component *private_component,
+ uint64_t index);
+enum bt_component_status
+bt_private_component_source_add_output_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
+
+/* Filter component functions */
+int64_t bt_component_filter_get_input_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_filter_get_input_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_filter_get_input_port_by_index(
+ struct bt_component *component, uint64_t index);
+int64_t bt_component_filter_get_output_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_filter_get_output_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_filter_get_output_port_by_index(
+ struct bt_component *component, uint64_t index);
+
+/* Private filter component functions */
+struct bt_private_port *
+bt_private_component_filter_get_output_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_filter_get_output_private_port_by_index(
+ struct bt_private_component *private_component, uint64_t index);
+enum bt_component_status
+bt_private_component_filter_add_output_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
+struct bt_private_port *
+bt_private_component_filter_get_input_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_filter_get_input_private_port_by_index(
+ struct bt_private_component *private_component, uint64_t index);
+enum bt_component_status
+bt_private_component_filter_add_input_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
+
+/* Sink component functions */
+int64_t bt_component_sink_get_input_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_sink_get_input_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_sink_get_input_port_by_index(
+ struct bt_component *component, uint64_t index);
+
+/* Private sink component functions */
+struct bt_private_port *
+bt_private_component_sink_get_input_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_sink_get_input_private_port_by_index(
+ struct bt_private_component *private_component, uint64_t index);
+enum bt_component_status
+bt_private_component_sink_add_input_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_component_class;
+
+/* Status */
+enum bt_component_class_type {
+ BT_COMPONENT_CLASS_TYPE_UNKNOWN = -1,
+ BT_COMPONENT_CLASS_TYPE_SOURCE = 0,
+ BT_COMPONENT_CLASS_TYPE_SINK = 1,
+ BT_COMPONENT_CLASS_TYPE_FILTER = 2,
+};
+
+/* General functions */
+const char *bt_component_class_get_name(
+ struct bt_component_class *component_class);
+const char *bt_component_class_get_description(
+ struct bt_component_class *component_class);
+const char *bt_component_class_get_help(
+ struct bt_component_class *component_class);
+struct bt_value *bt_component_class_query(
+ struct bt_component_class *component_class,
+ const char *object, struct bt_value *params);
+enum bt_component_class_type bt_component_class_get_type(
+ struct bt_component_class *component_class);
+
+%{
+/*
+ * This hash table associates a BT component class object address to a
+ * user-defined Python class (PyObject *). The keys and values are NOT
+ * owned by this hash table. The Python class objects are owned by the
+ * Python module, which should not be unloaded until it is not possible
+ * to create a user Python component anyway.
+ *
+ * This hash table is written to when a user-defined Python component
+ * class is created by one of the bt_py3_component_class_*_create()
+ * functions.
+ *
+ * This function is read from when a user calls bt_component_create()
+ * with a component class pointer created by one of the functions above.
+ * In this case, the original Python class needs to be found to
+ * instantiate it and associate the created Python component object with
+ * a BT component object instance.
+ */
+
+static GHashTable *bt_cc_ptr_to_py_cls;
+
+static void register_cc_ptr_to_py_cls(struct bt_component_class *bt_cc,
+ PyObject *py_cls)
+{
+ if (!bt_cc_ptr_to_py_cls) {
+ /*
+ * Lazy-initializing this GHashTable because GLib
+ * might not be initialized yet and it needs to be
+ * before we call g_hash_table_new()
+ */
+ BT_LOGD_STR("Creating native component class to Python component class hash table.");
+ bt_cc_ptr_to_py_cls = g_hash_table_new(g_direct_hash, g_direct_equal);
+ assert(bt_cc_ptr_to_py_cls);
+ }
+
+ g_hash_table_insert(bt_cc_ptr_to_py_cls, (gpointer) bt_cc,
+ (gpointer) py_cls);
+}
+
+static PyObject *lookup_cc_ptr_to_py_cls(struct bt_component_class *bt_cc)
+{
+ if (!bt_cc_ptr_to_py_cls) {
+ BT_LOGW("Cannot look up Python component class because hash table is NULL: "
+ "comp-cls-addr=%p", bt_cc);
+ return NULL;
+ }
+
+ return (PyObject *) g_hash_table_lookup(bt_cc_ptr_to_py_cls,
+ (gconstpointer) bt_cc);
+}
+
+
+/*
+ * Useful Python objects.
+ */
+
+static PyObject *py_mod_bt2 = NULL;
+static PyObject *py_mod_bt2_exc_error_type = NULL;
+static PyObject *py_mod_bt2_exc_unsupported_feature_type = NULL;
+static PyObject *py_mod_bt2_exc_try_again_type = NULL;
+static PyObject *py_mod_bt2_exc_stop_type = NULL;
+static PyObject *py_mod_bt2_exc_port_connection_refused_type = NULL;
+static PyObject *py_mod_bt2_exc_graph_canceled_type = NULL;
+static PyObject *py_mod_bt2_exc_notif_iter_canceled_type = NULL;
+static PyObject *py_mod_bt2_exc_connection_ended_type = NULL;
+
+static void bt_py3_cc_init_from_bt2(void)
+{
+ /*
+ * This is called once the bt2 package is loaded.
+ *
+ * Those modules and functions are needed while the package is
+ * used. Loading them here is safe because we know the bt2
+ * package is imported, and we know that the user cannot use the
+ * code here without importing bt2 first.
+ */
+ py_mod_bt2 = PyImport_ImportModule("bt2");
+ assert(py_mod_bt2);
+ py_mod_bt2_exc_error_type =
+ PyObject_GetAttrString(py_mod_bt2, "Error");
+ assert(py_mod_bt2_exc_error_type);
+ py_mod_bt2_exc_unsupported_feature_type =
+ PyObject_GetAttrString(py_mod_bt2, "UnsupportedFeature");
+ py_mod_bt2_exc_try_again_type =
+ PyObject_GetAttrString(py_mod_bt2, "TryAgain");
+ py_mod_bt2_exc_stop_type =
+ PyObject_GetAttrString(py_mod_bt2, "Stop");
+ py_mod_bt2_exc_port_connection_refused_type =
+ PyObject_GetAttrString(py_mod_bt2, "PortConnectionRefused");
+ py_mod_bt2_exc_graph_canceled_type =
+ PyObject_GetAttrString(py_mod_bt2, "GraphCanceled");
+ py_mod_bt2_exc_connection_ended_type =
+ PyObject_GetAttrString(py_mod_bt2, "ConnectionEnded");
+ assert(py_mod_bt2_exc_stop_type);
+}
+
+static void bt_py3_cc_exit_handler(void)
+{
+ /*
+ * This is an exit handler (set by the bt2 package).
+ *
+ * We only give back the references that we took in
+ * bt_py3_cc_init_from_bt2() here. The global variables continue
+ * to exist for the code of this file, but they are now borrowed
+ * references. If this code is executed, it means that somehow
+ * the modules are still loaded, so it should be safe to use
+ * them even without a strong reference.
+ *
+ * We cannot do this in the library's destructor because it
+ * gets executed once Python is already finalized.
+ */
+ Py_XDECREF(py_mod_bt2);
+ Py_XDECREF(py_mod_bt2_exc_error_type);
+ Py_XDECREF(py_mod_bt2_exc_unsupported_feature_type);
+ Py_XDECREF(py_mod_bt2_exc_try_again_type);
+ Py_XDECREF(py_mod_bt2_exc_stop_type);
+ Py_XDECREF(py_mod_bt2_exc_port_connection_refused_type);
+ Py_XDECREF(py_mod_bt2_exc_graph_canceled_type);
+ Py_XDECREF(py_mod_bt2_exc_notif_iter_canceled_type);
+ Py_XDECREF(py_mod_bt2_exc_connection_ended_type);
+}
+
+
+/* Library destructor */
+
+__attribute__((destructor))
+static void bt_py3_native_comp_class_dtor(void) {
+ /* Destroy component class association hash table */
+ if (bt_cc_ptr_to_py_cls) {
+ BT_LOGD_STR("Destroying native component class to Python component class hash table.");
+ g_hash_table_destroy(bt_cc_ptr_to_py_cls);
+ }
+}
+
+
+/* Component class proxy methods (delegate to the attached Python object) */
+
+static enum bt_notification_iterator_status bt_py3_exc_to_notif_iter_status(void)
+{
+ enum bt_notification_iterator_status status =
+ BT_NOTIFICATION_ITERATOR_STATUS_OK;
+ PyObject *exc = PyErr_Occurred();
+
+ if (!exc) {
+ goto end;
+ }
+
+ if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_unsupported_feature_type)) {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_stop_type)) {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_END;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_try_again_type)) {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_AGAIN;
+ } else {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
+ }
+
+end:
+ PyErr_Clear();
+ return status;
+}
+
+static enum bt_component_status bt_py3_exc_to_component_status(void)
+{
+ enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ PyObject *exc = PyErr_Occurred();
+
+ if (!exc) {
+ goto end;
+ }
+
+ if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_unsupported_feature_type)) {
+ status = BT_COMPONENT_STATUS_UNSUPPORTED;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_try_again_type)) {
+ status = BT_COMPONENT_STATUS_AGAIN;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_stop_type)) {
+ status = BT_COMPONENT_STATUS_END;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_port_connection_refused_type)) {
+ status = BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
+ } else {
+ status = BT_COMPONENT_STATUS_ERROR;
+ }
+
+end:
+ PyErr_Clear();
+ return status;
+}
+
+static enum bt_component_status bt_py3_cc_init(
+ struct bt_private_component *priv_comp,
+ struct bt_value *params, void *init_method_data)
+{
+ struct bt_component *comp =
+ bt_component_from_private_component(priv_comp);
+ struct bt_component_class *comp_cls = bt_component_get_class(comp);
+ enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ PyObject *py_cls = NULL;
+ PyObject *py_comp = NULL;
+ PyObject *py_params_ptr = NULL;
+ PyObject *py_comp_ptr = NULL;
+
+ (void) init_method_data;
+ assert(comp);
+ assert(comp_cls);
+
+ /*
+ * Get the user-defined Python class which created this
+ * component's class in the first place (borrowed
+ * reference).
+ */
+ py_cls = lookup_cc_ptr_to_py_cls(comp_cls);
+ if (!py_cls) {
+ BT_LOGE("Cannot find Python class associated to native component class: "
+ "comp-cls-addr=%p", comp_cls);
+ goto error;
+ }
+
+ /* Parameters pointer -> SWIG pointer Python object */
+ py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
+ SWIGTYPE_p_bt_value, 0);
+ if (!py_params_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
+
+ /* Private component pointer -> SWIG pointer Python object */
+ py_comp_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_comp),
+ SWIGTYPE_p_bt_private_component, 0);
+ if (!py_comp_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
+
+ /*
+ * Do the equivalent of this:
+ *
+ * py_comp = py_cls._init_from_native(py_comp_ptr, py_params_ptr)
+ *
+ * _UserComponentType._init_from_native() calls the Python
+ * component object's __init__() function.
+ */
+ py_comp = PyObject_CallMethod(py_cls,
+ "_init_from_native", "(OO)", py_comp_ptr, py_params_ptr);
+ if (!py_comp) {
+ BT_LOGE("Failed to call Python class's _init_from_native() method: "
+ "py-cls-addr=%p", py_cls);
+ goto error;
+ }
+
+ /*
+ * Our user Python component object is now fully created and
+ * initialized by the user. Since we just created it, this
+ * native component is its only (persistent) owner.
+ */
+ bt_private_component_set_user_data(priv_comp, py_comp);
+ py_comp = NULL;
+ goto end;
+
+error:
+ status = BT_COMPONENT_STATUS_ERROR;
+
+ /*
+ * Clear any exception: we're returning a bad status anyway. If
+ * this call originated from Python (creation from a plugin's
+ * component class, for example), then the user gets an
+ * appropriate creation error.
+ */
+ PyErr_Clear();
+
+end:
+ bt_put(comp_cls);
+ bt_put(comp);
+ Py_XDECREF(py_comp);
+ Py_XDECREF(py_params_ptr);
+ Py_XDECREF(py_comp_ptr);
+ return status;
+}
+
+static void bt_py3_cc_finalize(struct bt_private_component *priv_comp)
+{
+ PyObject *py_comp = bt_private_component_get_user_data(priv_comp);
+ PyObject *py_method_result = NULL;
+
+ assert(py_comp);
+
+ /* Call user's _finalize() method */
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_finalize", NULL);
+
+ if (PyErr_Occurred()) {
+ BT_LOGW("User's _finalize() method raised an exception: ignoring.");
+ }
+
+ /*
+ * Ignore any exception raised by the _finalize() method because
+ * it won't change anything at this point: the component is
+ * being destroyed anyway.
+ */
+ PyErr_Clear();
+ Py_XDECREF(py_method_result);
+ Py_DECREF(py_comp);
+}
+
+static enum bt_component_status bt_py3_cc_accept_port_connection(
+ struct bt_private_component *priv_comp,
+ struct bt_private_port *self_priv_port,
+ struct bt_port *other_port)
+{
+ enum bt_component_status status;
+ PyObject *py_comp = NULL;
+ PyObject *py_self_port_ptr = NULL;
+ PyObject *py_other_port_ptr = NULL;
+ PyObject *py_method_result = NULL;
+
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ assert(py_comp);
+ py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_priv_port),
+ SWIGTYPE_p_bt_private_port, 0);
+ if (!py_self_port_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
+
+ py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_other_port_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
+
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_accept_port_connection_from_native", "(OO)", py_self_port_ptr,
+ py_other_port_ptr);
+ status = bt_py3_exc_to_component_status();
+ if (!py_method_result && status == BT_COMPONENT_STATUS_OK) {
+ /* Pretty sure this should never happen, but just in case */
+ BT_LOGE("User's _accept_port_connection() method failed without raising an exception: "
+ "status=%d", status);
+ goto error;
+ }
+
+ if (status == BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION) {
+ /*
+ * Looks like the user method raised
+ * PortConnectionRefused: accept this like if it
+ * returned False.
+ */
+ goto end;
+ } else if (status != BT_COMPONENT_STATUS_OK) {
+ BT_LOGE("User's _accept_port_connection() raised an unexpected exception: "
+ "status=%d", status);
+ goto error;
+ }
+
+ assert(PyBool_Check(py_method_result));
+
+ if (py_method_result == Py_True) {
+ status = BT_COMPONENT_STATUS_OK;
+ } else {
+ status = BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
+ }
+
+ goto end;
+
+error:
+ status = BT_COMPONENT_STATUS_ERROR;
+
+ /*
+ * Clear any exception: we're returning a bad status anyway. If
+ * this call originated from Python, then the user gets an
+ * appropriate error.
+ */
+ PyErr_Clear();
+
+end:
+ Py_XDECREF(py_self_port_ptr);
+ Py_XDECREF(py_other_port_ptr);
+ Py_XDECREF(py_method_result);
+ return status;
+}
+
+static void bt_py3_cc_port_connected(
+ struct bt_private_component *priv_comp,
+ struct bt_private_port *self_priv_port,
+ struct bt_port *other_port)
+{
+ PyObject *py_comp = NULL;
+ PyObject *py_self_port_ptr = NULL;
+ PyObject *py_other_port_ptr = NULL;
+ PyObject *py_method_result = NULL;
+
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ assert(py_comp);
+ py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_priv_port),
+ SWIGTYPE_p_bt_private_port, 0);
+ if (!py_self_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_other_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_port_connected_from_native", "(OO)", py_self_port_ptr,
+ py_other_port_ptr);
+ assert(py_method_result == Py_None);
+ Py_XDECREF(py_self_port_ptr);
+ Py_XDECREF(py_other_port_ptr);
+ Py_XDECREF(py_method_result);
+}
+
+static void bt_py3_cc_port_disconnected(
+ struct bt_private_component *priv_comp,
+ struct bt_private_port *priv_port)
+{
+ PyObject *py_comp = NULL;
+ PyObject *py_port_ptr = NULL;
+ PyObject *py_method_result = NULL;
+
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ assert(py_comp);
+ py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_port),
+ SWIGTYPE_p_bt_private_port, 0);
+ if (!py_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_port_disconnected_from_native", "(O)", py_port_ptr);
+ assert(py_method_result == Py_None);
+ Py_XDECREF(py_port_ptr);
+ Py_XDECREF(py_method_result);
+}
+
+static struct bt_value *bt_py3_cc_query(
+ struct bt_component_class *comp_cls,
+ const char *object, struct bt_value *params)
+{
+ PyObject *py_cls = NULL;
+ PyObject *py_params_ptr = NULL;
+ PyObject *py_query_func = NULL;
+ PyObject *py_object = NULL;
+ PyObject *py_results_addr = NULL;
+ struct bt_value *results = NULL;
+
+ py_cls = lookup_cc_ptr_to_py_cls(comp_cls);
+ if (!py_cls) {
+ BT_LOGE("Cannot find Python class associated to native component class: "
+ "comp-cls-addr=%p", comp_cls);
+ goto error;
+ }
+
+ py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
+ SWIGTYPE_p_bt_value, 0);
+ if (!py_params_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
+
+ py_object = SWIG_FromCharPtr(object);
+ if (!py_object) {
+ BT_LOGE_STR("Failed to create a Python string.");
+ goto error;
+ }
+
+ py_results_addr = PyObject_CallMethod(py_cls,
+ "_query_from_native", "(OO)", py_object, py_params_ptr);
+ if (!py_results_addr || py_results_addr == Py_None) {
+ BT_LOGE_STR("User's _query() method failed.");
+ goto error;
+ }
+
+ if (py_results_addr == Py_NotImplemented) {
+ BT_LOGE_STR("User's _query() method is not implemented.");
+ goto error;
+ }
+
+ /*
+ * The returned object, on success, is an integer object
+ * (PyLong) containing the address of a BT value object (new
+ * reference).
+ */
+ results = (void *) PyLong_AsUnsignedLongLong(py_results_addr);
+ assert(!PyErr_Occurred());
+ assert(results);
+ goto end;
+
+error:
+ BT_PUT(results);
+ PyErr_Clear();
+
+end:
+ Py_XDECREF(py_params_ptr);
+ Py_XDECREF(py_query_func);
+ Py_XDECREF(py_object);
+ Py_XDECREF(py_results_addr);
+ return results;
+}
+
+static enum bt_notification_iterator_status bt_py3_cc_notification_iterator_init(
+ struct bt_private_notification_iterator *priv_notif_iter,
+ struct bt_private_port *priv_port)
+{
+ enum bt_notification_iterator_status status =
+ BT_NOTIFICATION_ITERATOR_STATUS_OK;
+ PyObject *py_comp_cls = NULL;
+ PyObject *py_iter_cls = NULL;
+ PyObject *py_iter_ptr = NULL;
+ PyObject *py_init_method_result = NULL;
+ PyObject *py_iter = NULL;
+ struct bt_private_component *priv_comp =
+ bt_private_notification_iterator_get_private_component(
+ priv_notif_iter);
+ PyObject *py_comp;
+
+ assert(priv_comp);
+ py_comp = bt_private_component_get_user_data(priv_comp);
+
+ /* Find user's Python notification iterator class */
+ py_comp_cls = PyObject_GetAttrString(py_comp, "__class__");
+ if (!py_comp_cls) {
+ BT_LOGE_STR("Cannot get Python object's `__class__` attribute.");
+ goto error;
+ }
+
+ py_iter_cls = PyObject_GetAttrString(py_comp_cls, "_iter_cls");
+ if (!py_iter_cls) {
+ BT_LOGE_STR("Cannot get Python class's `_iter_cls` attribute.");
+ goto error;
+ }
+
+ py_iter_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_notif_iter),
+ SWIGTYPE_p_bt_private_notification_iterator, 0);
+ if (!py_iter_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
+
+ /*
+ * Create object with borrowed native notification iterator
+ * reference:
+ *
+ * py_iter = py_iter_cls.__new__(py_iter_cls, py_iter_ptr)
+ */
+ py_iter = PyObject_CallMethod(py_iter_cls, "__new__",
+ "(OO)", py_iter_cls, py_iter_ptr);
+ if (!py_iter) {
+ BT_LOGE("Failed to call Python class's __new__() method: "
+ "py-cls-addr=%p", py_iter_cls);
+ goto error;
+ }
+
+ /*
+ * Initialize object:
+ *
+ * py_iter.__init__()
+ *
+ * At this point, py_iter._ptr is set, so this initialization
+ * function has access to self._component (which gives it the
+ * user Python component object from which the iterator was
+ * created).
+ */
+ py_init_method_result = PyObject_CallMethod(py_iter, "__init__", NULL);
+ if (!py_init_method_result) {
+ BT_LOGE_STR("User's __init__() method failed.");
+ goto error;
+ }
+
+ /*
+ * Since the Python code can never instantiate a user-defined
+ * notification iterator class, the native notification iterator
+ * object does NOT belong to a user Python notification iterator
+ * object (borrowed reference). However this Python object is
+ * owned by this native notification iterator object.
+ *
+ * In the Python world, the lifetime of the native notification
+ * iterator is managed by a _GenericNotificationIterator
+ * instance:
+ *
+ * _GenericNotificationIterator instance:
+ * owns a native bt_notification_iterator object (iter)
+ * owns a _UserNotificationIterator instance (py_iter)
+ * self._ptr is a borrowed reference to the
+ * native bt_private_notification_iterator
+ * object (iter)
+ */
+ bt_private_notification_iterator_set_user_data(priv_notif_iter,
+ py_iter);
+ py_iter = NULL;
+ goto end;
+
+error:
+ status = bt_py3_exc_to_notif_iter_status();
+ if (status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
+ /*
+ * Looks like there wasn't any exception from the Python
+ * side, but we're still in an error state here.
+ */
+ status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
+ }
+
+ /*
+ * Clear any exception: we're returning a bad status anyway. If
+ * this call originated from Python, then the user gets an
+ * appropriate creation error.
+ */
+ PyErr_Clear();
+
+end:
+ bt_put(priv_comp);
+ Py_XDECREF(py_comp_cls);
+ Py_XDECREF(py_iter_cls);
+ Py_XDECREF(py_iter_ptr);
+ Py_XDECREF(py_init_method_result);
+ Py_XDECREF(py_iter);
+ return status;
+}
+
+static void bt_py3_cc_notification_iterator_finalize(
+ struct bt_private_notification_iterator *priv_notif_iter)
+{
+ PyObject *py_notif_iter =
+ bt_private_notification_iterator_get_user_data(priv_notif_iter);
+ PyObject *py_method_result = NULL;
+
+ assert(py_notif_iter);
+
+ /* Call user's _finalize() method */
+ py_method_result = PyObject_CallMethod(py_notif_iter,
+ "_finalize", NULL);
+
+ if (PyErr_Occurred()) {
+ BT_LOGW("User's _finalize() method raised an exception: ignoring.");
+ }
+
+ /*
+ * Ignore any exception raised by the _finalize() method because
+ * it won't change anything at this point: the component is
+ * being destroyed anyway.
+ */
+ PyErr_Clear();
+ Py_XDECREF(py_method_result);
+ Py_DECREF(py_notif_iter);
+}
+
+static struct bt_notification_iterator_next_return
+bt_py3_cc_notification_iterator_next(
+ struct bt_private_notification_iterator *priv_notif_iter)
+{
+ struct bt_notification_iterator_next_return next_ret = {
+ .status = BT_NOTIFICATION_ITERATOR_STATUS_OK,
+ .notification = NULL,
+ };
+ PyObject *py_notif_iter =
+ bt_private_notification_iterator_get_user_data(priv_notif_iter);
+ PyObject *py_method_result = NULL;
+
+ assert(py_notif_iter);
+ py_method_result = PyObject_CallMethod(py_notif_iter,
+ "_next_from_native", NULL);
+ if (!py_method_result) {
+ next_ret.status = bt_py3_exc_to_notif_iter_status();
+ assert(next_ret.status != BT_NOTIFICATION_ITERATOR_STATUS_OK);
+ goto end;
+ }
+
+ /*
+ * The returned object, on success, is an integer object
+ * (PyLong) containing the address of a native notification
+ * object (which is now ours).
+ */
+ next_ret.notification =
+ (struct bt_notification *) PyLong_AsUnsignedLongLong(
+ py_method_result);
+
+ /* Clear potential overflow error; should never happen */
+ assert(!PyErr_Occurred());
+ assert(next_ret.notification);
+ goto end;
+
+end:
+ Py_XDECREF(py_method_result);
+ return next_ret;
+}
+
+static enum bt_component_status bt_py3_cc_sink_consume(
+ struct bt_private_component *priv_comp)
+{
+ PyObject *py_comp = bt_private_component_get_user_data(priv_comp);
+ PyObject *py_method_result = NULL;
+ enum bt_component_status status;
+
+ assert(py_comp);
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_consume", NULL);
+ status = bt_py3_exc_to_component_status();
+ if (!py_method_result && status == BT_COMPONENT_STATUS_OK) {
+ /* Pretty sure this should never happen, but just in case */
+ BT_LOGE("User's _consume() method failed without raising an exception: "
+ "status=%d", status);
+ status = BT_COMPONENT_STATUS_ERROR;
+ }
+
+ Py_XDECREF(py_method_result);
+ return status;
+}
+
+
+/* Component class creation functions (called from Python module) */
+
+static int bt_py3_cc_set_optional_attrs_methods(struct bt_component_class *cc,
+ const char *description, const char *help)
+{
+ int ret = 0;
+
+ if (description) {
+ ret = bt_component_class_set_description(cc, description);
+ if (ret) {
+ BT_LOGE("Cannot set component class's description: "
+ "comp-cls-addr=%p", cc);
+ goto end;
+ }
+ }
+
+ if (help) {
+ ret = bt_component_class_set_help(cc, help);
+ if (ret) {
+ BT_LOGE("Cannot set component class's help text: "
+ "comp-cls-addr=%p", cc);
+ goto end;
+ }
+ }
+
+ ret = bt_component_class_set_init_method(cc, bt_py3_cc_init);
+ assert(ret == 0);
+ ret = bt_component_class_set_finalize_method(cc, bt_py3_cc_finalize);
+ assert(ret == 0);
+ ret = bt_component_class_set_accept_port_connection_method(cc,
+ bt_py3_cc_accept_port_connection);
+ assert(ret == 0);
+ ret = bt_component_class_set_port_connected_method(cc,
+ bt_py3_cc_port_connected);
+ assert(ret == 0);
+ ret = bt_component_class_set_port_disconnected_method(cc,
+ bt_py3_cc_port_disconnected);
+ assert(ret == 0);
+ ret = bt_component_class_set_query_method(cc, bt_py3_cc_query);
+ assert(ret == 0);
+
+end:
+ return ret;
+}
+
+static void bt_py3_cc_set_optional_iter_methods(struct bt_component_class *cc,
+ int (*set_notif_iter_init_method)(struct bt_component_class *, bt_component_class_notification_iterator_init_method),
+ int (*set_notif_iter_finalize_method)(struct bt_component_class *, bt_component_class_notification_iterator_finalize_method))
+{
+ int ret;
+
+ ret = set_notif_iter_init_method(
+ cc, bt_py3_cc_notification_iterator_init);
+ assert(ret == 0);
+ ret = set_notif_iter_finalize_method(
+ cc, bt_py3_cc_notification_iterator_finalize);
+ assert(ret == 0);
+}
+
+static struct bt_component_class *bt_py3_component_class_source_create(
+ PyObject *py_cls, const char *name, const char *description,
+ const char *help)
+{
+ struct bt_component_class *cc;
+ int ret;
+
+ assert(py_cls);
+ cc = bt_component_class_source_create(name,
+ bt_py3_cc_notification_iterator_next);
+ if (!cc) {
+ BT_LOGE_STR("Cannot create source component class.");
+ goto end;
+ }
+
+ ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
+ if (ret) {
+ BT_LOGE_STR("Cannot set source component class's optional attributes and methods.");
+ BT_PUT(cc);
+ goto end;
+ }
+
+ bt_py3_cc_set_optional_iter_methods(cc,
+ bt_component_class_source_set_notification_iterator_init_method,
+ bt_component_class_source_set_notification_iterator_finalize_method);
+ register_cc_ptr_to_py_cls(cc, py_cls);
+ bt_component_class_freeze(cc);
+
+end:
+ return cc;
+}
+
+static struct bt_component_class *bt_py3_component_class_filter_create(
+ PyObject *py_cls, const char *name, const char *description,
+ const char *help)
+{
+ struct bt_component_class *cc;
+ int ret;
+
+ assert(py_cls);
+ cc = bt_component_class_filter_create(name,
+ bt_py3_cc_notification_iterator_next);
+ if (!cc) {
+ BT_LOGE_STR("Cannot create filter component class.");
+ goto end;
+ }
+
+ ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
+ if (ret) {
+ BT_LOGE_STR("Cannot set filter component class's optional attributes and methods.");
+ BT_PUT(cc);
+ goto end;
+ }
+
+ bt_py3_cc_set_optional_iter_methods(cc,
+ bt_component_class_filter_set_notification_iterator_init_method,
+ bt_component_class_filter_set_notification_iterator_finalize_method);
+ register_cc_ptr_to_py_cls(cc, py_cls);
+ bt_component_class_freeze(cc);
+
+end:
+ return cc;
+}
+
+static struct bt_component_class *bt_py3_component_class_sink_create(
+ PyObject *py_cls, const char *name, const char *description,
+ const char *help)
+{
+ struct bt_component_class *cc;
+ int ret;
+
+ assert(py_cls);
+ cc = bt_component_class_sink_create(name, bt_py3_cc_sink_consume);
+ if (!cc) {
+ BT_LOGE_STR("Cannot create sink component class.");
+ goto end;
+ }
+
+ ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
+ if (ret) {
+ BT_LOGE_STR("Cannot set sink component class's optional attributes and methods.");
+ BT_PUT(cc);
+ goto end;
+ }
+
+ register_cc_ptr_to_py_cls(cc, py_cls);
+ bt_component_class_freeze(cc);
+
+end:
+ return cc;
+}
+%}
+
+struct bt_component_class *bt_py3_component_class_source_create(
+ PyObject *py_cls, const char *name, const char *description,
+ const char *help);
+struct bt_component_class *bt_py3_component_class_filter_create(
+ PyObject *py_cls, const char *name, const char *description,
+ const char *help);
+struct bt_component_class *bt_py3_component_class_sink_create(
+ PyObject *py_cls, const char *name, const char *description,
+ const char *help);
+void bt_py3_cc_init_from_bt2(void);
+void bt_py3_cc_exit_handler(void);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_connection;
+struct bt_private_connection;
+
+/* Status */
+enum bt_connection_status {
+ BT_CONNECTION_STATUS_GRAPH_IS_CANCELED = 125,
+ BT_CONNECTION_STATUS_OK = 0,
+ BT_CONNECTION_STATUS_INVALID = -22,
+ BT_CONNECTION_STATUS_ERROR = -1,
+ BT_CONNECTION_STATUS_NOMEM = -12,
+ BT_CONNECTION_STATUS_IS_ENDED = 104,
+};
+
+/* Functions (public) */
+struct bt_port *bt_connection_get_downstream_port(
+ struct bt_connection *connection);
+struct bt_port *bt_connection_get_upstream_port(
+ struct bt_connection *connection);
+int bt_connection_is_ended(struct bt_connection *connection);
+
+/* Functions (private) */
+struct bt_connection *bt_connection_from_private_connection(
+ struct bt_private_connection *private_connection);
+
+/* Helper functions for Python */
+%typemap(out) struct bt_py3_create_notif_iter_ret {
+ $result = PyTuple_New(2);
+ PyObject *py_notif_iter_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr($1.notif_iter),
+ SWIGTYPE_p_bt_notification_iterator, 0);
+ PyObject *py_status = SWIG_From_long_SS_long($1.status);
+ PyTuple_SET_ITEM($result, 0, py_status);
+ PyTuple_SET_ITEM($result, 1, py_notif_iter_ptr);
+}
+
+%{
+struct bt_py3_create_notif_iter_ret {
+ enum bt_connection_status status;
+ struct bt_notification_iterator *notif_iter;
+};
+
+static struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter(
+ unsigned long long priv_conn_addr, PyObject *py_notif_types)
+{
+ struct bt_private_connection *priv_conn;
+ enum bt_notification_type *notification_types = NULL;
+ struct bt_py3_create_notif_iter_ret ret;
+
+ priv_conn = (void *) priv_conn_addr;
+ assert(!PyErr_Occurred());
+ assert(priv_conn);
+
+ if (py_notif_types != Py_None) {
+ size_t i;
+
+ assert(PyList_Check(py_notif_types));
+ notification_types = g_new0(enum bt_notification_type,
+ PyList_Size(py_notif_types) + 1);
+ assert(notification_types);
+ notification_types[PyList_Size(py_notif_types)] =
+ BT_NOTIFICATION_TYPE_SENTINEL;
+
+ for (i = 0; i < PyList_Size(py_notif_types); i++) {
+ PyObject *item = PyList_GetItem(py_notif_types, i);
+ long value;
+ int overflow;
+
+ assert(item);
+ assert(PyLong_Check(item));
+ value = PyLong_AsLongAndOverflow(item, &overflow);
+ assert(overflow == 0);
+ notification_types[i] = value;
+ }
+ }
+
+ ret.status = bt_private_connection_create_notification_iterator(
+ priv_conn, notification_types, &ret.notif_iter);
+
+ if (notification_types) {
+ g_free(notification_types);
+ }
+
+ return ret;
+}
+%}
+
+struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter(
+ unsigned long long priv_conn_addr, PyObject *notif_types);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_ctf_clock;
+struct bt_ctf_writer;
+
+/* Clock functions */
+struct bt_ctf_clock *bt_ctf_clock_create(const char *name);
+const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock);
+const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock);
+int bt_ctf_clock_set_description(struct bt_ctf_clock *clock,
+ const char *desc);
+uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock);
+int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock,
+ uint64_t freq);
+uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock);
+int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock,
+ uint64_t precision);
+int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock,
+ int64_t *OUTPUT);
+int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock,
+ int64_t offset_s);
+int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock,
+ int64_t *OUTPUT);
+int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock,
+ int64_t offset);
+int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock);
+int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock,
+ int is_absolute);
+BTUUID bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock);
+int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock,
+ BTUUID uuid);
+int bt_ctf_clock_set_time(struct bt_ctf_clock *clock,
+ int64_t time);
+
+/* Stream functions */
+int bt_ctf_stream_get_discarded_events_count(
+ struct bt_ctf_stream *stream, uint64_t *OUTPUT);
+void bt_ctf_stream_append_discarded_events(struct bt_ctf_stream *stream,
+ uint64_t event_count);
+int bt_ctf_stream_append_event(struct bt_ctf_stream *stream,
+ struct bt_ctf_event *event);
+struct bt_ctf_field *bt_ctf_stream_get_packet_header(
+ struct bt_ctf_stream *stream);
+int bt_ctf_stream_set_packet_header(
+ struct bt_ctf_stream *stream,
+ struct bt_ctf_field *packet_header);
+struct bt_ctf_field *bt_ctf_stream_get_packet_context(
+ struct bt_ctf_stream *stream);
+int bt_ctf_stream_set_packet_context(
+ struct bt_ctf_stream *stream,
+ struct bt_ctf_field *packet_context);
+int bt_ctf_stream_flush(struct bt_ctf_stream *stream);
+int bt_ctf_stream_is_writer(struct bt_ctf_stream *stream);
+
+/* Stream class functions */
+int bt_ctf_stream_class_set_clock(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_clock *clock);
+struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
+ struct bt_ctf_stream_class *stream_class);
+
+/* Writer functions */
+struct bt_ctf_writer *bt_ctf_writer_create(const char *path);
+struct bt_ctf_trace *bt_ctf_writer_get_trace(
+ struct bt_ctf_writer *writer);
+int bt_ctf_writer_add_clock(struct bt_ctf_writer *writer,
+ struct bt_ctf_clock *clock);
+char *bt_ctf_writer_get_metadata_string(struct bt_ctf_writer *writer);
+void bt_ctf_writer_flush_metadata(struct bt_ctf_writer *writer);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_event;
+
+/* Functions */
+struct bt_ctf_event *bt_ctf_event_create(
+ struct bt_ctf_event_class *event_class);
+struct bt_ctf_event_class *bt_ctf_event_get_class(
+ struct bt_ctf_event *event);
+struct bt_ctf_packet *bt_ctf_event_get_packet(
+ struct bt_ctf_event *event);
+int bt_ctf_event_set_packet(struct bt_ctf_event *event,
+ struct bt_ctf_packet *packet);
+struct bt_ctf_stream *bt_ctf_event_get_stream(
+ struct bt_ctf_event *event);
+struct bt_ctf_field *bt_ctf_event_get_header(
+ struct bt_ctf_event *event);
+int bt_ctf_event_set_header(struct bt_ctf_event *event,
+ struct bt_ctf_field *header);
+struct bt_ctf_field *bt_ctf_event_get_stream_event_context(
+ struct bt_ctf_event *event);
+int bt_ctf_event_set_stream_event_context(struct bt_ctf_event *event,
+ struct bt_ctf_field *context);
+struct bt_ctf_field *bt_ctf_event_get_event_context(
+ struct bt_ctf_event *event);
+int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
+ struct bt_ctf_field *context);
+struct bt_ctf_field *bt_ctf_event_get_event_payload(
+ struct bt_ctf_event *event);
+int bt_ctf_event_set_event_payload(struct bt_ctf_event *event,
+ struct bt_ctf_field *payload);
+struct bt_ctf_clock_value *bt_ctf_event_get_clock_value(
+ struct bt_ctf_event *event,
+ struct bt_ctf_clock_class *clock_class);
+int bt_ctf_event_set_clock_value(
+ struct bt_ctf_event *event,
+ struct bt_ctf_clock_value *clock_value);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_event_class;
+
+/* Log levels */
+enum bt_ctf_event_class_log_level {
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN = -1,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED = 255,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY = 0,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT = 1,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL = 2,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR = 3,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING = 4,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE = 5,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO = 6,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM = 7,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM = 8,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS = 9,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE = 10,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT = 11,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION = 12,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE = 13,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG = 14,
+};
+
+/* Functions */
+struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name);
+struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
+ struct bt_ctf_event_class *event_class);
+const char *bt_ctf_event_class_get_name(
+ struct bt_ctf_event_class *event_class);
+int64_t bt_ctf_event_class_get_id(
+ struct bt_ctf_event_class *event_class);
+int bt_ctf_event_class_set_id(
+ struct bt_ctf_event_class *event_class, uint64_t id);
+enum bt_ctf_event_class_log_level bt_ctf_event_class_get_log_level(
+ struct bt_ctf_event_class *event_class);
+int bt_ctf_event_class_set_log_level(
+ struct bt_ctf_event_class *event_class,
+ enum bt_ctf_event_class_log_level log_level);
+const char *bt_ctf_event_class_get_emf_uri(
+ struct bt_ctf_event_class *event_class);
+int bt_ctf_event_class_set_emf_uri(
+ struct bt_ctf_event_class *event_class,
+ const char *emf_uri);
+struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
+ struct bt_ctf_event_class *event_class);
+int bt_ctf_event_class_set_context_type(
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_field_type *context_type);
+struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
+ struct bt_ctf_event_class *event_class);
+int bt_ctf_event_class_set_payload_type(
+ struct bt_ctf_event_class *event_class,
+ struct bt_ctf_field_type *payload_type);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_field;
+
+/* Common functions */
+struct bt_ctf_field *bt_ctf_field_create(
+ struct bt_ctf_field_type *type);
+struct bt_ctf_field_type *bt_ctf_field_get_type(
+ struct bt_ctf_field *field);
+struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field);
+
+/* Integer field functions */
+int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *integer,
+ int64_t *OUTPUT);
+int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *integer,
+ int64_t value);
+int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *integer,
+ uint64_t *OUTPUT);
+int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *integer,
+ uint64_t value);
+
+/* Floating point number field functions */
+int bt_ctf_field_floating_point_get_value(
+ struct bt_ctf_field *floating_point, double *OUTPUT);
+int bt_ctf_field_floating_point_set_value(
+ struct bt_ctf_field *floating_point,
+ double value);
+
+/* Enumeration field functions */
+struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
+ struct bt_ctf_field *enumeration);
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *enum_field);
+
+/* String field functions */
+const char *bt_ctf_field_string_get_value(
+ struct bt_ctf_field *string_field);
+int bt_ctf_field_string_set_value(struct bt_ctf_field *string_field,
+ const char *value);
+int bt_ctf_field_string_append(struct bt_ctf_field *string_field,
+ const char *value);
+int bt_ctf_field_string_append_len(
+ struct bt_ctf_field *string_field, const char *value,
+ unsigned int length);
+
+/* Structure field functions */
+struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
+ struct bt_ctf_field *structure, int index);
+struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
+ struct bt_ctf_field *struct_field, const char *name);
+int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *struct_field,
+ const char *name, struct bt_ctf_field *field);
+
+/* Array field functions */
+struct bt_ctf_field *bt_ctf_field_array_get_field(
+ struct bt_ctf_field *array, uint64_t index);
+
+/* Sequence field functions */
+struct bt_ctf_field *bt_ctf_field_sequence_get_length(
+ struct bt_ctf_field *sequence);
+int bt_ctf_field_sequence_set_length(struct bt_ctf_field *sequence,
+ struct bt_ctf_field *length_field);
+struct bt_ctf_field *bt_ctf_field_sequence_get_field(
+ struct bt_ctf_field *sequence, uint64_t index);
+
+/* Variant field functions */
+struct bt_ctf_field *bt_ctf_field_variant_get_field(
+ struct bt_ctf_field *variant, struct bt_ctf_field *tag);
+struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
+ struct bt_ctf_field *variant);
+struct bt_ctf_field *bt_ctf_field_variant_get_tag(
+ struct bt_ctf_field *variant);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_field_type;
+
+/* Common enumerations */
+enum bt_ctf_scope {
+ BT_CTF_SCOPE_UNKNOWN = -1,
+ BT_CTF_SCOPE_TRACE_PACKET_HEADER = 1,
+ BT_CTF_SCOPE_STREAM_PACKET_CONTEXT = 2,
+ BT_CTF_SCOPE_STREAM_EVENT_HEADER = 3,
+ BT_CTF_SCOPE_STREAM_EVENT_CONTEXT = 4,
+ BT_CTF_SCOPE_EVENT_CONTEXT = 5,
+ BT_CTF_SCOPE_EVENT_PAYLOAD = 6,
+ BT_CTF_SCOPE_ENV = 0,
+ BT_CTF_SCOPE_EVENT_FIELDS = 6,
+};
+
+enum bt_ctf_field_type_id {
+ BT_CTF_FIELD_TYPE_ID_UNKNOWN = CTF_TYPE_UNKNOWN,
+ BT_CTF_FIELD_TYPE_ID_INTEGER = CTF_TYPE_INTEGER,
+ BT_CTF_FIELD_TYPE_ID_FLOAT = CTF_TYPE_FLOAT,
+ BT_CTF_FIELD_TYPE_ID_ENUM = CTF_TYPE_ENUM,
+ BT_CTF_FIELD_TYPE_ID_STRING = CTF_TYPE_STRING,
+ BT_CTF_FIELD_TYPE_ID_STRUCT = CTF_TYPE_STRUCT,
+ BT_CTF_FIELD_TYPE_ID_ARRAY = CTF_TYPE_ARRAY,
+ BT_CTF_FIELD_TYPE_ID_SEQUENCE = CTF_TYPE_SEQUENCE,
+ BT_CTF_FIELD_TYPE_ID_VARIANT = CTF_TYPE_VARIANT,
+ BT_CTF_NR_TYPE_IDS = NR_CTF_TYPES,
+};
+
+enum bt_ctf_byte_order {
+ BT_CTF_BYTE_ORDER_UNKNOWN = -1,
+ BT_CTF_BYTE_ORDER_NATIVE = 0,
+ BT_CTF_BYTE_ORDER_UNSPECIFIED,
+ BT_CTF_BYTE_ORDER_LITTLE_ENDIAN,
+ BT_CTF_BYTE_ORDER_BIG_ENDIAN,
+ BT_CTF_BYTE_ORDER_NETWORK,
+};
+
+enum bt_ctf_string_encoding {
+ BT_CTF_STRING_ENCODING_UNKNOWN = CTF_STRING_UNKNOWN,
+ BT_CTF_STRING_ENCODING_NONE = CTF_STRING_NONE,
+ BT_CTF_STRING_ENCODING_UTF8 = CTF_STRING_UTF8,
+ BT_CTF_STRING_ENCODING_ASCII = CTF_STRING_ASCII,
+};
+
+/* Common functions */
+enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
+ struct bt_ctf_field_type *field_type);
+int bt_ctf_field_type_get_alignment(
+ struct bt_ctf_field_type *field_type);
+int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *field_type,
+ unsigned int alignment);
+enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
+ struct bt_ctf_field_type *field_type);
+int bt_ctf_field_type_set_byte_order(
+ struct bt_ctf_field_type *field_type,
+ enum bt_ctf_byte_order byte_order);
+int bt_ctf_field_type_compare(struct bt_ctf_field_type *field_type_a,
+ struct bt_ctf_field_type *field_type_b);
+struct bt_ctf_field_type *bt_ctf_field_type_copy(
+ struct bt_ctf_field_type *field_type);
+
+/* Integer field type base enumeration */
+enum bt_ctf_integer_base {
+ BT_CTF_INTEGER_BASE_UNKNOWN = -1,
+ BT_CTF_INTEGER_BASE_BINARY = 2,
+ BT_CTF_INTEGER_BASE_OCTAL = 8,
+ BT_CTF_INTEGER_BASE_DECIMAL = 10,
+ BT_CTF_INTEGER_BASE_HEXADECIMAL = 16,
+};
+
+/* Integer field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_integer_create(
+ unsigned int size);
+int bt_ctf_field_type_integer_get_size(
+ struct bt_ctf_field_type *int_field_type);
+int bt_ctf_field_type_integer_set_size(
+ struct bt_ctf_field_type *int_field_type, unsigned int size);
+int bt_ctf_field_type_integer_is_signed(
+ struct bt_ctf_field_type *int_field_type);
+int bt_ctf_field_type_integer_set_is_signed(
+ struct bt_ctf_field_type *int_field_type, int is_signed);
+enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
+ struct bt_ctf_field_type *int_field_type);
+int bt_ctf_field_type_integer_set_base(
+ struct bt_ctf_field_type *int_field_type,
+ enum bt_ctf_integer_base base);
+enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
+ struct bt_ctf_field_type *int_field_type);
+int bt_ctf_field_type_integer_set_encoding(
+ struct bt_ctf_field_type *int_field_type,
+ enum bt_ctf_string_encoding encoding);
+struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
+ struct bt_ctf_field_type *int_field_type);
+int bt_ctf_field_type_integer_set_mapped_clock_class(
+ struct bt_ctf_field_type *int_field_type,
+ struct bt_ctf_clock_class *clock_class);
+
+/* Floating point number field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void);
+int bt_ctf_field_type_floating_point_get_exponent_digits(
+ struct bt_ctf_field_type *float_field_type);
+int bt_ctf_field_type_floating_point_set_exponent_digits(
+ struct bt_ctf_field_type *float_field_type,
+ unsigned int exponent_size);
+int bt_ctf_field_type_floating_point_get_mantissa_digits(
+ struct bt_ctf_field_type *float_field_type);
+int bt_ctf_field_type_floating_point_set_mantissa_digits(
+ struct bt_ctf_field_type *float_field_type,
+ unsigned int mantissa_sign_size);
+
+/* Enumeration field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
+ struct bt_ctf_field_type *int_field_type);
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
+ struct bt_ctf_field_type *enum_field_type);
+int64_t bt_ctf_field_type_enumeration_get_mapping_count(
+ struct bt_ctf_field_type *enum_field_type);
+int bt_ctf_field_type_enumeration_get_mapping_signed(
+ struct bt_ctf_field_type *enum_field_type, int index,
+ const char **BTOUTSTR, int64_t *OUTPUT, int64_t *OUTPUT);
+int bt_ctf_field_type_enumeration_get_mapping_unsigned(
+ struct bt_ctf_field_type *enum_field_type, int index,
+ const char **BTOUTSTR, uint64_t *OUTPUT,
+ uint64_t *OUTPUT);
+int bt_ctf_field_type_enumeration_add_mapping_signed(
+ struct bt_ctf_field_type *enum_field_type, const char *name,
+ int64_t range_begin, int64_t range_end);
+int bt_ctf_field_type_enumeration_add_mapping_unsigned(
+ struct bt_ctf_field_type *enum_field_type, const char *name,
+ uint64_t range_begin, uint64_t range_end);
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_by_name(
+ struct bt_ctf_field_type *enum_field_type,
+ const char *name);
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
+ struct bt_ctf_field_type *enum_field_type,
+ int64_t value);
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
+ struct bt_ctf_field_type *enum_field_type,
+ uint64_t value);
+
+/* Enumeration field type mapping iterator functions */
+int bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+ const char **BTOUTSTR, int64_t *OUTPUT, int64_t *OUTPUT);
+int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+ const char **BTOUTSTR, uint64_t *OUTPUT, uint64_t *OUTPUT);
+int bt_ctf_field_type_enumeration_mapping_iterator_next(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter);
+
+/* String field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_string_create(void);
+enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
+ struct bt_ctf_field_type *string_field_type);
+int bt_ctf_field_type_string_set_encoding(
+ struct bt_ctf_field_type *string_field_type,
+ enum bt_ctf_string_encoding encoding);
+
+/* Structure field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void);
+int64_t bt_ctf_field_type_structure_get_field_count(
+ struct bt_ctf_field_type *struct_field_type);
+int bt_ctf_field_type_structure_get_field_by_index(
+ struct bt_ctf_field_type *struct_field_type,
+ const char **BTOUTSTR, struct bt_ctf_field_type **BTOUTFT,
+ uint64_t index);
+struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
+ struct bt_ctf_field_type *struct_field_type,
+ const char *field_name);
+int bt_ctf_field_type_structure_add_field(
+ struct bt_ctf_field_type *struct_field_type,
+ struct bt_ctf_field_type *field_type,
+ const char *field_name);
+
+/* Array field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_array_create(
+ struct bt_ctf_field_type *element_field_type,
+ unsigned int length);
+struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
+ struct bt_ctf_field_type *array_field_type);
+int64_t bt_ctf_field_type_array_get_length(
+ struct bt_ctf_field_type *array_field_type);
+
+/* Sequence field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
+ struct bt_ctf_field_type *element_field_type,
+ const char *length_name);
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
+ struct bt_ctf_field_type *sequence_field_type);
+const char *bt_ctf_field_type_sequence_get_length_field_name(
+ struct bt_ctf_field_type *sequence_field_type);
+struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
+ struct bt_ctf_field_type *sequence_field_type);
+
+/* Variant field type functions */
+struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
+ struct bt_ctf_field_type *tag_field_type,
+ const char *tag_name);
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
+ struct bt_ctf_field_type *variant_field_type);
+const char *bt_ctf_field_type_variant_get_tag_name(
+ struct bt_ctf_field_type *variant_field_type);
+int bt_ctf_field_type_variant_set_tag_name(
+ struct bt_ctf_field_type *variant_field_type,
+ const char *tag_name);
+struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
+ struct bt_ctf_field_type *variant_field_type);
+int64_t bt_ctf_field_type_variant_get_field_count(
+ struct bt_ctf_field_type *variant_field_type);
+int bt_ctf_field_type_variant_get_field_by_index(
+ struct bt_ctf_field_type *variant_field_type,
+ const char **BTOUTSTR,
+ struct bt_ctf_field_type **BTOUTFT, uint64_t index);
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
+ struct bt_ctf_field_type *variant_field_type,
+ const char *field_name);
+int bt_ctf_field_type_variant_add_field(
+ struct bt_ctf_field_type *variant_field_type,
+ struct bt_ctf_field_type *field_type,
+ const char *field_name);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_graph;
+
+/* Status */
+enum bt_graph_status {
+ BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION = 111,
+ BT_GRAPH_STATUS_CANCELED = 125,
+ BT_GRAPH_STATUS_AGAIN = 11,
+ BT_GRAPH_STATUS_END = 1,
+ BT_GRAPH_STATUS_OK = 0,
+ BT_GRAPH_STATUS_INVALID = -22,
+ BT_GRAPH_STATUS_NO_SINK = -6,
+ BT_GRAPH_STATUS_ERROR = -1,
+ BT_GRAPH_STATUS_NOMEM = -12,
+};
+
+/* Functions */
+struct bt_graph *bt_graph_create(void);
+enum bt_graph_status bt_graph_add_component(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ struct bt_component **BTOUTCOMP);
+enum bt_graph_status bt_graph_add_component_with_init_method_data(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ void *init_method_data,
+ struct bt_component **BTOUTCOMP);
+enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph,
+ struct bt_port *upstream, struct bt_port *downstream,
+ struct bt_connection **BTOUTCONN);
+enum bt_graph_status bt_graph_run(struct bt_graph *graph);
+enum bt_graph_status bt_graph_consume(struct bt_graph *graph);
+enum bt_graph_status bt_graph_cancel(struct bt_graph *graph);
+int bt_graph_is_canceled(struct bt_graph *graph);
+
+/* Helper functions for Python */
+%{
+static void port_added_listener(struct bt_port *port, void *py_callable)
+{
+ PyObject *py_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(O)", py_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void port_removed_listener(struct bt_component *component,
+ struct bt_port *port, void *py_callable)
+{
+ PyObject *py_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(O)", py_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void ports_connected_listener(struct bt_port *upstream_port,
+ struct bt_port *downstream_port, void *py_callable)
+{
+ PyObject *py_upstream_port_ptr = NULL;
+ PyObject *py_downstream_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_upstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_upstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_downstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_downstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(OO)",
+ py_upstream_port_ptr, py_downstream_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_upstream_port_ptr);
+ Py_DECREF(py_downstream_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void ports_disconnected_listener(
+ struct bt_component *upstream_component,
+ struct bt_component *downstream_component,
+ struct bt_port *upstream_port, struct bt_port *downstream_port,
+ void *py_callable)
+{
+ PyObject *py_upstream_comp_ptr = NULL;
+ PyObject *py_downstream_comp_ptr = NULL;
+ PyObject *py_upstream_port_ptr = NULL;
+ PyObject *py_downstream_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_upstream_comp_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(upstream_component),
+ SWIGTYPE_p_bt_component, 0);
+ if (!py_upstream_comp_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_downstream_comp_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(downstream_component),
+ SWIGTYPE_p_bt_component, 0);
+ if (!py_downstream_comp_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_upstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_upstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_downstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_downstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(OOOO)",
+ py_upstream_comp_ptr, py_downstream_comp_ptr,
+ py_upstream_port_ptr, py_downstream_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_upstream_comp_ptr);
+ Py_DECREF(py_downstream_comp_ptr);
+ Py_DECREF(py_upstream_port_ptr);
+ Py_DECREF(py_downstream_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void graph_listener_removed(void *py_callable)
+{
+ assert(py_callable);
+ Py_DECREF(py_callable);
+}
+
+static int bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_port_added_listener(graph, port_added_listener,
+ graph_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+
+static int bt_py3_graph_add_port_removed_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_port_removed_listener(graph, port_removed_listener,
+ graph_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+
+static int bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_ports_connected_listener(graph,
+ ports_connected_listener, graph_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+
+static int bt_py3_graph_add_ports_disconnected_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_ports_disconnected_listener(graph,
+ ports_disconnected_listener, graph_listener_removed,
+ py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+%}
+
+int bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
+ PyObject *py_callable);
+int bt_py3_graph_add_port_removed_listener(struct bt_graph *graph,
+ PyObject *py_callable);
+int bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
+ PyObject *py_callable);
+int bt_py3_graph_add_ports_disconnected_listener(struct bt_graph *graph,
+ PyObject *py_callable);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+%{
+#include <babeltrace/logging.h>
+%}
+
+/* Log levels */
+enum bt_logging_level {
+ BT_LOGGING_LEVEL_VERBOSE = 1,
+ BT_LOGGING_LEVEL_DEBUG = 2,
+ BT_LOGGING_LEVEL_INFO = 3,
+ BT_LOGGING_LEVEL_WARN = 4,
+ BT_LOGGING_LEVEL_ERROR = 5,
+ BT_LOGGING_LEVEL_FATAL = 6,
+ BT_LOGGING_LEVEL_NONE = 0xff,
+};
+
+/* Logging functions */
+enum bt_logging_level bt_logging_get_minimal_level(void);
+enum bt_logging_level bt_logging_get_global_level(void);
+void bt_logging_set_global_level(enum bt_logging_level log_level);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_notification;
+
+/* Notification type */
+enum bt_notification_type {
+ BT_NOTIFICATION_TYPE_SENTINEL = -1000,
+ BT_NOTIFICATION_TYPE_UNKNOWN = -1,
+ BT_NOTIFICATION_TYPE_ALL = -2,
+ BT_NOTIFICATION_TYPE_EVENT = 0,
+ BT_NOTIFICATION_TYPE_INACTIVITY = 1,
+ BT_NOTIFICATION_TYPE_STREAM_BEGIN = 2,
+ BT_NOTIFICATION_TYPE_STREAM_END = 3,
+ BT_NOTIFICATION_TYPE_PACKET_BEGIN = 4,
+ BT_NOTIFICATION_TYPE_PACKET_END = 5,
+ BT_NOTIFICATION_TYPE_DISCARDED_EVENTS = 6,
+ BT_NOTIFICATION_TYPE_DISCARDED_PACKETS = 7,
+};
+
+/* General functions */
+enum bt_notification_type bt_notification_get_type(
+ struct bt_notification *notification);
+
+/* Event notification functions */
+struct bt_notification *bt_notification_event_create(
+ struct bt_ctf_event *event,
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+struct bt_ctf_event *bt_notification_event_get_event(
+ struct bt_notification *notification);
+struct bt_clock_class_priority_map *
+bt_notification_event_get_clock_class_priority_map(
+ struct bt_notification *notification);
+
+/* Inactivity notification functions */
+struct bt_notification *bt_notification_inactivity_create(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+struct bt_clock_class_priority_map *
+bt_notification_inactivity_get_clock_class_priority_map(
+ struct bt_notification *notification);
+struct bt_ctf_clock_value *bt_notification_inactivity_get_clock_value(
+ struct bt_notification *notification,
+ struct bt_ctf_clock_class *clock_class);
+int bt_notification_inactivity_set_clock_value(
+ struct bt_notification *notification,
+ struct bt_ctf_clock_value *clock_value);
+
+/* Packet notification functions */
+struct bt_notification *bt_notification_packet_begin_create(
+ struct bt_ctf_packet *packet);
+struct bt_notification *bt_notification_packet_end_create(
+ struct bt_ctf_packet *packet);
+struct bt_ctf_packet *bt_notification_packet_begin_get_packet(
+ struct bt_notification *notification);
+struct bt_ctf_packet *bt_notification_packet_end_get_packet(
+ struct bt_notification *notification);
+
+/* Stream notification functions */
+struct bt_notification *bt_notification_stream_begin_create(
+ struct bt_ctf_stream *stream);
+struct bt_notification *bt_notification_stream_end_create(
+ struct bt_ctf_stream *stream);
+struct bt_ctf_stream *bt_notification_stream_begin_get_stream(
+ struct bt_notification *notification);
+struct bt_ctf_stream *bt_notification_stream_end_get_stream(
+ struct bt_notification *notification);
+
+/* Discarded packets notification functions */
+struct bt_ctf_clock_value *
+bt_notification_discarded_packets_get_begin_clock_value(
+ struct bt_notification *notification);
+struct bt_ctf_clock_value *
+bt_notification_discarded_packets_get_end_clock_value(
+ struct bt_notification *notification);
+int64_t bt_notification_discarded_packets_get_count(
+ struct bt_notification *notification);
+struct bt_ctf_stream *bt_notification_discarded_packets_get_stream(
+ struct bt_notification *notification);
+
+/* Discarded events notification functions */
+struct bt_ctf_clock_value *
+bt_notification_discarded_events_get_begin_clock_value(
+ struct bt_notification *notification);
+struct bt_ctf_clock_value *
+bt_notification_discarded_events_get_end_clock_value(
+ struct bt_notification *notification);
+int64_t bt_notification_discarded_events_get_count(
+ struct bt_notification *notification);
+struct bt_ctf_stream *bt_notification_discarded_events_get_stream(
+ struct bt_notification *notification);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_notification_iterator;
+
+/* Status */
+enum bt_notification_iterator_status {
+ BT_NOTIFICATION_ITERATOR_STATUS_CANCELED = 125,
+ BT_NOTIFICATION_ITERATOR_STATUS_AGAIN = 11,
+ BT_NOTIFICATION_ITERATOR_STATUS_END = 1,
+ BT_NOTIFICATION_ITERATOR_STATUS_OK = 0,
+ BT_NOTIFICATION_ITERATOR_STATUS_INVALID = -22,
+ BT_NOTIFICATION_ITERATOR_STATUS_ERROR = -1,
+ BT_NOTIFICATION_ITERATOR_STATUS_NOMEM = -12,
+ BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED = -2,
+};
+
+/* Functions */
+struct bt_notification *bt_notification_iterator_get_notification(
+ struct bt_notification_iterator *iterator);
+enum bt_notification_iterator_status bt_notification_iterator_next(
+ struct bt_notification_iterator *iterator);
+struct bt_component *bt_notification_iterator_get_component(
+ struct bt_notification_iterator *iterator);
+
+/* Helper functions for Python */
+%{
+static PyObject *bt_py3_get_user_component_from_user_notif_iter(
+ struct bt_private_notification_iterator *priv_notif_iter)
+{
+ struct bt_private_component *priv_comp =
+ bt_private_notification_iterator_get_private_component(
+ priv_notif_iter);
+ PyObject *py_comp;
+
+ assert(priv_comp);
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ bt_put(priv_comp);
+ assert(py_comp);
+
+ /* Return new reference */
+ Py_INCREF(py_comp);
+ return py_comp;
+}
+%}
+
+PyObject *bt_py3_get_user_component_from_user_notif_iter(
+ struct bt_private_notification_iterator *priv_notif_iter);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_packet;
+
+/* Functions */
+struct bt_ctf_packet *bt_ctf_packet_create(
+ struct bt_ctf_stream *stream);
+struct bt_ctf_stream *bt_ctf_packet_get_stream(
+ struct bt_ctf_packet *packet);
+struct bt_ctf_field *bt_ctf_packet_get_header(
+ struct bt_ctf_packet *packet);
+int bt_ctf_packet_set_header(
+ struct bt_ctf_packet *packet, struct bt_ctf_field *header);
+struct bt_ctf_field *bt_ctf_packet_get_context(
+ struct bt_ctf_packet *packet);
+int bt_ctf_packet_set_context(
+ struct bt_ctf_packet *packet, struct bt_ctf_field *context);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_plugin;
+struct bt_plugin_set;
+
+/* Status */
+enum bt_plugin_status {
+ BT_PLUGIN_STATUS_OK = 0,
+ BT_PLUGIN_STATUS_ERROR = -1,
+ BT_PLUGIN_STATUS_NOMEM = -4,
+};
+
+/* Plugin functions */
+struct bt_plugin *bt_plugin_find(const char *plugin_name);
+struct bt_component_class *bt_plugin_find_component_class(
+ const char *plugin_name, const char *component_class_name,
+ enum bt_component_class_type component_class_type);
+struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path);
+struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path,
+ int recurse);
+struct bt_plugin_set *bt_plugin_create_all_from_static(void);
+const char *bt_plugin_get_name(struct bt_plugin *plugin);
+const char *bt_plugin_get_author(struct bt_plugin *plugin);
+const char *bt_plugin_get_license(struct bt_plugin *plugin);
+const char *bt_plugin_get_description(struct bt_plugin *plugin);
+const char *bt_plugin_get_path(struct bt_plugin *plugin);
+enum bt_plugin_status bt_plugin_get_version(struct bt_plugin *plugin,
+ unsigned int *OUTPUTINIT, unsigned int *OUTPUTINIT,
+ unsigned int *OUTPUTINIT, const char **BTOUTSTR);
+int64_t bt_plugin_get_component_class_count(struct bt_plugin *plugin);
+struct bt_component_class *bt_plugin_get_component_class_by_index(
+ struct bt_plugin *plugin, uint64_t index);
+struct bt_component_class *bt_plugin_get_component_class_by_name_and_type(
+ struct bt_plugin *plugin, const char *name,
+ enum bt_component_class_type type);
+
+/* Plugin set functions */
+int64_t bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set);
+struct bt_plugin *bt_plugin_set_get_plugin(struct bt_plugin_set *plugin_set,
+ uint64_t index);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_port;
+struct bt_private_port;
+
+/* Status */
+enum bt_port_status {
+ BT_PORT_STATUS_OK = 0,
+ BT_PORT_STATUS_ERROR = -1,
+ BT_PORT_STATUS_INVALID = -2,
+};
+
+/* Port type */
+enum bt_port_type {
+ BT_PORT_TYPE_INPUT = 0,
+ BT_PORT_TYPE_OUTPUT = 1,
+ BT_PORT_TYPE_UNKOWN = -1,
+};
+
+/* Functions (public) */
+const char *bt_port_get_name(struct bt_port *port);
+enum bt_port_type bt_port_get_type(struct bt_port *port);
+struct bt_connection *bt_port_get_connection(struct bt_port *port);
+struct bt_component *bt_port_get_component(struct bt_port *port);
+enum bt_port_status bt_port_disconnect(struct bt_port *port);
+int bt_port_is_connected(struct bt_port *port);
+
+/* Functions (private) */
+struct bt_port *bt_port_from_private_port(struct bt_private_port *private_port);
+struct bt_private_connection *bt_private_port_get_private_connection(
+ struct bt_private_port *private_port);
+struct bt_private_component *bt_private_port_get_private_component(
+ struct bt_private_port *private_port);
+enum bt_port_status bt_private_port_remove_from_component(
+ struct bt_private_port *private_port);
+void *bt_private_port_get_user_data(
+ struct bt_private_port *private_port);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Functions */
+void *bt_get(void *obj);
+void bt_put(void *obj);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_stream;
+
+/* Functions */
+struct bt_ctf_stream *bt_ctf_stream_create(
+ struct bt_ctf_stream_class *stream_class,
+ const char *name);
+struct bt_ctf_stream *bt_ctf_stream_create_with_id(
+ struct bt_ctf_stream_class *stream_class,
+ const char *name, uint64_t id);
+const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream);
+int64_t bt_ctf_stream_get_id(struct bt_ctf_stream *stream);
+struct bt_ctf_stream_class *bt_ctf_stream_get_class(
+ struct bt_ctf_stream *stream);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_stream_class;
+
+/* Functions */
+struct bt_ctf_stream_class *bt_ctf_stream_class_create_empty(
+ const char *name);
+struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name);
+struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
+ struct bt_ctf_stream_class *stream_class);
+const char *bt_ctf_stream_class_get_name(
+ struct bt_ctf_stream_class *stream_class);
+int bt_ctf_stream_class_set_name(
+ struct bt_ctf_stream_class *stream_class, const char *name);
+int64_t bt_ctf_stream_class_get_id(
+ struct bt_ctf_stream_class *stream_class);
+int bt_ctf_stream_class_set_id(
+ struct bt_ctf_stream_class *stream_class, uint64_t id);
+struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
+ struct bt_ctf_stream_class *stream_class);
+int bt_ctf_stream_class_set_packet_context_type(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_field_type *packet_context_type);
+struct bt_ctf_field_type *
+bt_ctf_stream_class_get_event_header_type(
+ struct bt_ctf_stream_class *stream_class);
+int bt_ctf_stream_class_set_event_header_type(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_field_type *event_header_type);
+struct bt_ctf_field_type *
+bt_ctf_stream_class_get_event_context_type(
+ struct bt_ctf_stream_class *stream_class);
+int bt_ctf_stream_class_set_event_context_type(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_field_type *event_context_type);
+int64_t bt_ctf_stream_class_get_event_class_count(
+ struct bt_ctf_stream_class *stream_class);
+struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_index(
+ struct bt_ctf_stream_class *stream_class, uint64_t index);
+struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
+ struct bt_ctf_stream_class *stream_class, uint64_t id);
+int bt_ctf_stream_class_add_event_class(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_event_class *event_class);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_ctf_trace;
+
+/* Functions */
+struct bt_ctf_trace *bt_ctf_trace_create(void);
+const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_name(struct bt_ctf_trace *trace_class,
+ const char *name);
+enum bt_ctf_byte_order bt_ctf_trace_get_native_byte_order(
+ struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_native_byte_order(struct bt_ctf_trace *trace_class,
+ enum bt_ctf_byte_order native_byte_order);
+BTUUID bt_ctf_trace_get_uuid(
+ struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_uuid(struct bt_ctf_trace *trace_class,
+ BTUUID uuid);
+int64_t bt_ctf_trace_get_environment_field_count(
+ struct bt_ctf_trace *trace_class);
+const char *
+bt_ctf_trace_get_environment_field_name_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
+struct bt_value *
+bt_ctf_trace_get_environment_field_value_by_index(struct bt_ctf_trace *trace_class,
+ uint64_t index);
+struct bt_value *
+bt_ctf_trace_get_environment_field_value_by_name(
+ struct bt_ctf_trace *trace_class, const char *name);
+int bt_ctf_trace_set_environment_field(
+ struct bt_ctf_trace *trace_class, const char *name,
+ struct bt_value *value);
+struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
+ struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace_class,
+ struct bt_ctf_field_type *packet_header_type);
+int64_t bt_ctf_trace_get_clock_class_count(
+ struct bt_ctf_trace *trace_class);
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
+ struct bt_ctf_trace *trace_class, const char *name);
+int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace_class,
+ struct bt_ctf_clock_class *clock_class);
+int64_t bt_ctf_trace_get_stream_class_count(
+ struct bt_ctf_trace *trace_class);
+struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
+struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
+ struct bt_ctf_trace *trace_class, uint64_t id);
+int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace_class,
+ struct bt_ctf_stream_class *stream_class);
+int64_t bt_ctf_trace_get_stream_count(struct bt_ctf_trace *trace_class);
+struct bt_ctf_stream *bt_ctf_trace_get_stream_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
+int bt_ctf_trace_is_static(struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace_class);
+
+/* Helper functions for Python */
+%{
+void trace_is_static_listener(struct bt_ctf_trace *trace, void *py_callable)
+{
+ PyObject *py_trace_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_trace_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(trace),
+ SWIGTYPE_p_bt_ctf_trace, 0);
+ if (!py_trace_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(O)", py_trace_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_trace_ptr);
+ Py_DECREF(py_res);
+}
+
+void trace_listener_removed(struct bt_ctf_trace *trace, void *py_callable)
+{
+ assert(py_callable);
+ Py_DECREF(py_callable);
+}
+
+static int bt_py3_trace_add_is_staitc_listener(unsigned long long trace_addr,
+ PyObject *py_callable)
+{
+ struct bt_ctf_trace *trace = (void *) trace_addr;
+ int ret = 0;
+
+ assert(trace);
+ assert(py_callable);
+ ret = bt_ctf_trace_add_is_static_listener(trace,
+ trace_is_static_listener, trace_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+%}
+
+int bt_py3_trace_add_is_staitc_listener(unsigned long long trace_addr,
+ PyObject *py_callable);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Remove prefix from `bt_value_null` */
+%rename(value_null) bt_value_null;
+
+/* Type and status */
+struct bt_value;
+
+enum bt_value_type {
+ BT_VALUE_TYPE_UNKNOWN = -1,
+ BT_VALUE_TYPE_NULL = 0,
+ BT_VALUE_TYPE_BOOL = 1,
+ BT_VALUE_TYPE_INTEGER = 2,
+ BT_VALUE_TYPE_FLOAT = 3,
+ BT_VALUE_TYPE_STRING = 4,
+ BT_VALUE_TYPE_ARRAY = 5,
+ BT_VALUE_TYPE_MAP = 6,
+};
+
+enum bt_value_type bt_value_get_type(const struct bt_value *object);
+
+enum bt_value_status {
+ BT_VALUE_STATUS_FROZEN = -4,
+ BT_VALUE_STATUS_CANCELLED = -3,
+ BT_VALUE_STATUS_INVAL = -22,
+ BT_VALUE_STATUS_ERROR = -1,
+ BT_VALUE_STATUS_OK = 0,
+};
+
+/* Null value object singleton */
+struct bt_value * const bt_value_null;
+
+/* Common functions */
+enum bt_value_status bt_value_freeze(struct bt_value *object);
+int bt_value_is_frozen(const struct bt_value *object);
+struct bt_value *bt_value_copy(const struct bt_value *object);
+int bt_value_compare(const struct bt_value *object_a,
+ const struct bt_value *object_b);
+
+/* Boolean value object functions */
+struct bt_value *bt_value_bool_create(void);
+struct bt_value *bt_value_bool_create_init(int val);
+enum bt_value_status bt_value_bool_get(
+ const struct bt_value *bool_obj, int *OUTPUT);
+enum bt_value_status bt_value_bool_set(struct bt_value *bool_obj,
+ int val);
+
+/* Integer value object functions */
+struct bt_value *bt_value_integer_create(void);
+struct bt_value *bt_value_integer_create_init(int64_t val);
+enum bt_value_status bt_value_integer_get(
+ const struct bt_value *integer_obj, int64_t *OUTPUT);
+enum bt_value_status bt_value_integer_set(
+ struct bt_value *integer_obj, int64_t val);
+
+/* Floating point number value object functions */
+struct bt_value *bt_value_float_create(void);
+struct bt_value *bt_value_float_create_init(double val);
+enum bt_value_status bt_value_float_get(
+ const struct bt_value *float_obj, double *OUTPUT);
+enum bt_value_status bt_value_float_set(
+ struct bt_value *float_obj, double val);
+
+/* String value object functions */
+struct bt_value *bt_value_string_create(void);
+struct bt_value *bt_value_string_create_init(const char *val);
+enum bt_value_status bt_value_string_set(struct bt_value *string_obj,
+ const char *val);
+enum bt_value_status bt_value_string_get(
+ const struct bt_value *string_obj, const char **BTOUTSTR);
+
+/* Array value object functions */
+struct bt_value *bt_value_array_create(void);
+int bt_value_array_size(const struct bt_value *array_obj);
+struct bt_value *bt_value_array_get(const struct bt_value *array_obj,
+ size_t index);
+enum bt_value_status bt_value_array_append(struct bt_value *array_obj,
+ struct bt_value *element_obj);
+enum bt_value_status bt_value_array_set(struct bt_value *array_obj,
+ size_t index, struct bt_value *element_obj);
+
+/* Map value object functions */
+struct bt_value *bt_value_map_create(void);
+int bt_value_map_size(const struct bt_value *map_obj);
+struct bt_value *bt_value_map_get(const struct bt_value *map_obj,
+ const char *key);
+int bt_value_map_has_key(const struct bt_value *map_obj,
+ const char *key);
+enum bt_value_status bt_value_map_insert(
+ struct bt_value *map_obj, const char *key,
+ struct bt_value *element_obj);
+struct bt_value *bt_value_map_extend(struct bt_value *base_map_obj,
+ struct bt_value *extension_map_obj);
+
+%{
+struct bt_value_map_get_keys_private_data {
+ struct bt_value *keys;
+};
+
+static int bt_value_map_get_keys_private_cb(const char *key,
+ struct bt_value *object, void *data)
+{
+ enum bt_value_status status;
+ struct bt_value_map_get_keys_private_data *priv_data = data;
+
+ status = bt_value_array_append_string(priv_data->keys, key);
+ if (status != BT_VALUE_STATUS_OK) {
+ return BT_FALSE;
+ }
+
+ return BT_TRUE;
+}
+
+static struct bt_value *bt_value_map_get_keys_private(
+ const struct bt_value *map_obj)
+{
+ enum bt_value_status status;
+ struct bt_value_map_get_keys_private_data data;
+
+ data.keys = bt_value_array_create();
+ if (!data.keys) {
+ return NULL;
+ }
+
+ status = bt_value_map_foreach(map_obj, bt_value_map_get_keys_private_cb,
+ &data);
+ if (status != BT_VALUE_STATUS_OK) {
+ goto error;
+ }
+
+ goto end;
+
+error:
+ if (data.keys) {
+ BT_PUT(data.keys);
+ }
+
+end:
+ return data.keys;
+}
+%}
+
+struct bt_value *bt_value_map_get_keys_private(const struct bt_value *map_obj);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+%{
+#include <babeltrace/version.h>
+%}
+
+/* Version functions */
+int bt_version_get_major(void);
+int bt_version_get_minor(void);
+int bt_version_get_patch(void);
+const char *bt_version_get_extra(void);
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.clock_class_priority_map
+import bt2.packet
+import bt2.stream
+import bt2.event
+import copy
+import bt2
+
+
+def _create_from_ptr(ptr):
+ notif_type = native_bt.notification_get_type(ptr)
+ cls = None
+
+ if notif_type not in _NOTIF_TYPE_TO_CLS:
+ raise bt2.Error('unknown notification type: {}'.format(notif_type))
+
+ return _NOTIF_TYPE_TO_CLS[notif_type]._create_from_ptr(ptr)
+
+
+class _Notification(object._Object):
+ pass
+
+
+class _CopyableNotification(_Notification):
+ 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 EventNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_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.notification_event_create(event._ptr, cc_prio_map_ptr)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create event notification object')
+
+ super().__init__(ptr)
+
+ @property
+ def event(self):
+ event_ptr = native_bt.notification_event_get_event(self._ptr)
+ assert(event_ptr)
+ return bt2.event._create_from_ptr(event_ptr)
+
+ @property
+ def clock_class_priority_map(self):
+ cc_prio_map_ptr = native_bt.notification_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 notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return EventNotification(self.event, self.clock_class_priority_map)
+
+
+class PacketBeginningNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_PACKET_BEGIN
+
+ def __init__(self, packet):
+ utils._check_type(packet, bt2.packet._Packet)
+ ptr = native_bt.notification_packet_begin_create(packet._ptr)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create packet beginning notification object')
+
+ super().__init__(ptr)
+
+ @property
+ def packet(self):
+ packet_ptr = native_bt.notification_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 notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return PacketBeginningNotification(self.packet)
+
+
+class PacketEndNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_PACKET_END
+
+ def __init__(self, packet):
+ utils._check_type(packet, bt2.packet._Packet)
+ ptr = native_bt.notification_packet_end_create(packet._ptr)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create packet end notification object')
+
+ super().__init__(ptr)
+
+ @property
+ def packet(self):
+ packet_ptr = native_bt.notification_packet_end_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 notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return PacketEndNotification(self.packet)
+
+
+class StreamBeginningNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_STREAM_BEGIN
+
+ def __init__(self, stream):
+ utils._check_type(stream, bt2.stream._Stream)
+ ptr = native_bt.notification_stream_begin_create(stream._ptr)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create stream beginning notification object')
+
+ super().__init__(ptr)
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.notification_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
+
+ 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 notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return StreamBeginningNotification(self.stream)
+
+
+class StreamEndNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_STREAM_END
+
+ def __init__(self, stream):
+ utils._check_type(stream, bt2.stream._Stream)
+ ptr = native_bt.notification_stream_end_create(stream._ptr)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create stream end notification object')
+
+ super().__init__(ptr)
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.notification_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 notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return StreamEndNotification(self.stream)
+
+
+class InactivityNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_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
+ else:
+ cc_prio_map_ptr = None
+
+ ptr = native_bt.notification_inactivity_create(cc_prio_map_ptr)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create inactivity notification object')
+
+ super().__init__(ptr)
+
+ @property
+ def clock_class_priority_map(self):
+ cc_prio_map_ptr = native_bt.notification_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)
+
+ def clock_value(self, clock_class):
+ utils._check_type(clock_class, bt2.ClockClass)
+ clock_value_ptr = native_bt.notification_inactivity_get_clock_value(self._ptr,
+ clock_class._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ def add_clock_value(self, clock_value):
+ utils._check_type(clock_value, bt2.clock_class._ClockValue)
+ ret = native_bt.notification_inactivity_set_clock_value(self._ptr,
+ clock_value._ptr)
+ utils._handle_ret(ret, "cannot set inactivity notification object's clock value")
+
+ def _get_clock_values(self):
+ clock_values = {}
+
+ for clock_class in self.clock_class_priority_map:
+ clock_value = self.clock_value(clock_class)
+
+ 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 = InactivityNotification(self.clock_class_priority_map)
+
+ for clock_class in self.clock_class_priority_map:
+ clock_value = self.clock_value(clock_class)
+
+ if clock_value is None:
+ continue
+
+ cpy.add_clock_value(clock_value)
+
+ return cpy
+
+ def __deepcopy__(self, memo):
+ cc_prio_map_cpy = copy.deepcopy(self.clock_class_priority_map)
+ cpy = InactivityNotification(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 notification copy
+ cpy.add_clock_value(clock_value_cpy)
+
+ memo[id(self)] = cpy
+ return cpy
+
+
+class _DiscardedElementsNotification(_Notification):
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ 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 _DiscardedPacketsNotification(_DiscardedElementsNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_DISCARDED_PACKETS
+
+ @property
+ def count(self):
+ count = native_bt.notification_discarded_packets_get_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.notification_discarded_packets_get_stream(self._ptr)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+ @property
+ def beginning_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_packets_get_begin_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ @property
+ def end_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_packets_get_end_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+
+class _DiscardedEventsNotification(_DiscardedElementsNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_DISCARDED_EVENTS
+
+ @property
+ def count(self):
+ count = native_bt.notification_discarded_events_get_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.notification_discarded_events_get_stream(self._ptr)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+ @property
+ def beginning_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_events_get_begin_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ @property
+ def end_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_events_get_end_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+
+_NOTIF_TYPE_TO_CLS = {
+ native_bt.NOTIFICATION_TYPE_EVENT: EventNotification,
+ native_bt.NOTIFICATION_TYPE_PACKET_BEGIN: PacketBeginningNotification,
+ native_bt.NOTIFICATION_TYPE_PACKET_END: PacketEndNotification,
+ native_bt.NOTIFICATION_TYPE_STREAM_BEGIN: StreamBeginningNotification,
+ native_bt.NOTIFICATION_TYPE_STREAM_END: StreamEndNotification,
+ native_bt.NOTIFICATION_TYPE_INACTIVITY: InactivityNotification,
+ native_bt.NOTIFICATION_TYPE_DISCARDED_PACKETS: _DiscardedPacketsNotification,
+ native_bt.NOTIFICATION_TYPE_DISCARDED_EVENTS: _DiscardedEventsNotification,
+}
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.notification
+import collections.abc
+import bt2.component
+import bt2
+
+
+class _NotificationIterator(collections.abc.Iterator):
+ def _handle_status(self, status, gen_error_msg):
+ if status == native_bt.NOTIFICATION_ITERATOR_STATUS_CANCELED:
+ raise bt2.NotificationIteratorCanceled
+ elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_AGAIN:
+ raise bt2.TryAgain
+ elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_END:
+ raise bt2.Stop
+ elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED:
+ raise bt2.UnsupportedFeature
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+ def __next__(self):
+ raise NotImplementedError
+
+
+class _GenericNotificationIterator(object._Object, _NotificationIterator):
+ @property
+ def component(self):
+ comp_ptr = native_bt.notification_iterator_get_component(self._ptr)
+ assert(comp_ptr)
+ return bt2.component._create_generic_component_from_ptr(comp_ptr)
+
+ def _get_notif(self):
+ notif_ptr = native_bt.notification_iterator_get_notification(self._ptr)
+ utils._handle_ptr(notif_ptr, "cannot get notification iterator object's current notification object")
+ return bt2.notification._create_from_ptr(notif_ptr)
+
+ def _next(self):
+ status = native_bt.notification_iterator_next(self._ptr)
+ self._handle_status(status,
+ 'unexpected error: cannot advance the notification iterator')
+
+ def __next__(self):
+ self._next()
+ return self._get_notif()
+
+
+class _UserNotificationIterator(_NotificationIterator):
+ def __new__(cls, ptr):
+ # User iterator objects are always created by the native side,
+ # that is, never instantiated directly by Python code.
+ #
+ # The native code calls this, then manually calls
+ # self.__init__() without the `ptr` argument. The user has
+ # access to self.component during this call, thanks to this
+ # self._ptr argument being set.
+ #
+ # self._ptr is NOT owned by this object here, so there's nothing
+ # to do in __del__().
+ self = super().__new__(cls)
+ self._ptr = ptr
+ return self
+
+ def __init__(self):
+ pass
+
+ @property
+ def _component(self):
+ return native_bt.py3_get_user_component_from_user_notif_iter(self._ptr)
+
+ @property
+ def addr(self):
+ return int(self._ptr)
+
+ def _finalize(self):
+ pass
+
+ def __next__(self):
+ raise bt2.Stop
+
+ def _next_from_native(self):
+ # this can raise anything: it's catched by the native part
+ try:
+ notif = next(self)
+ except StopIteration:
+ raise bt2.Stop
+ except:
+ raise
+
+ utils._check_type(notif, bt2.notification._Notification)
+
+ # take a new reference for the native part
+ notif._get()
+ return int(notif._ptr)
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt
+import abc
+
+
+class _Object:
+ def __init__(self, ptr):
+ self._ptr = ptr
+
+ @property
+ def addr(self):
+ return int(self._ptr)
+
+ @classmethod
+ def _create_from_ptr(cls, ptr):
+ obj = cls.__new__(cls)
+ obj._ptr = ptr
+ return obj
+
+ def _get(self):
+ native_bt.get(self._ptr)
+
+ def __del__(self):
+ ptr = getattr(self, '_ptr', None)
+ native_bt.put(ptr)
+ self._ptr = None
+
+ def __repr__(self):
+ return '<{}.{} object @ {}>'.format(self.__class__.__module__,
+ self.__class__.__name__,
+ hex(self.addr))
+
+
+class _PrivateObject:
+ def __del__(self):
+ pub_ptr = getattr(self, '_pub_ptr', None)
+ native_bt.put(pub_ptr)
+ self._pub_ptr = None
+ super().__del__()
+
+
+class _Freezable(metaclass=abc.ABCMeta):
+ @property
+ def is_frozen(self):
+ return self._is_frozen()
+
+ @property
+ def frozen(self):
+ return self.is_frozen
+
+ def freeze(self):
+ self._freeze()
+
+ @abc.abstractmethod
+ def _is_frozen(self):
+ pass
+
+ @abc.abstractmethod
+ def _freeze(self):
+ pass
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.fields
+import bt2.stream
+import copy
+import abc
+import bt2
+
+
+class _Packet(object._Object):
+ @property
+ def stream(self):
+ stream_ptr = native_bt.ctf_packet_get_stream(self._ptr)
+ assert(stream_ptr)
+ return bt2.stream._Stream._create_from_ptr(stream_ptr)
+
+ @property
+ def header_field(self):
+ field_ptr = native_bt.ctf_packet_get_header(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return bt2.fields._create_from_ptr(field_ptr)
+
+ @header_field.setter
+ def header_field(self, header_field):
+ header_field_ptr = None
+
+ if header_field is not None:
+ utils._check_type(header_field, bt2.fields._Field)
+ header_field_ptr = header_field._ptr
+
+ ret = native_bt.ctf_packet_set_header(self._ptr, header_field_ptr)
+ utils._handle_ret(ret, "cannot set packet object's header field")
+
+ @property
+ def context_field(self):
+ field_ptr = native_bt.ctf_packet_get_context(self._ptr)
+
+ if field_ptr is None:
+ return
+
+ return bt2.fields._create_from_ptr(field_ptr)
+
+ @context_field.setter
+ def context_field(self, context_field):
+ context_field_ptr = None
+
+ if context_field is not None:
+ utils._check_type(context_field, bt2.fields._Field)
+ context_field_ptr = context_field._ptr
+
+ ret = native_bt.ctf_packet_set_context(self._ptr, context_field_ptr)
+ utils._handle_ret(ret, "cannot set packet object's context field")
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = (
+ self.header_field,
+ self.context_field,
+ )
+ other_props = (
+ other.header_field,
+ other.context_field,
+ )
+ return self_props == other_props
+
+ def _copy(self, copy_func):
+ cpy = self.stream.create_packet()
+ cpy.header_field = copy_func(self.header_field)
+ cpy.context_field = copy_func(self.context_field)
+ return cpy
+
+ def __copy__(self):
+ return self._copy(copy.copy)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import bt2.component
+import os.path
+import bt2
+
+
+def find_plugins(path, recurse=True):
+ utils._check_str(path)
+ utils._check_bool(recurse)
+ plugin_set_ptr = None
+
+ if os.path.isfile(path):
+ plugin_set_ptr = native_bt.plugin_create_all_from_file(path)
+ elif os.path.isdir(path):
+ plugin_set_ptr = native_bt.plugin_create_all_from_dir(path, int(recurse))
+
+ if plugin_set_ptr is None:
+ return
+
+ return _PluginSet._create_from_ptr(plugin_set_ptr)
+
+
+def find_plugin(name):
+ utils._check_str(name)
+ ptr = native_bt.plugin_find(name)
+
+ if ptr is None:
+ return
+
+ return _Plugin._create_from_ptr(ptr)
+
+
+class _PluginSet(object._Object, collections.abc.Sequence):
+ def __len__(self):
+ count = native_bt.plugin_set_get_plugin_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ def __getitem__(self, index):
+ utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
+ plugin_ptr = native_bt.plugin_set_get_plugin(self._ptr, index)
+ assert(plugin_ptr)
+ return _Plugin._create_from_ptr(plugin_ptr)
+
+
+class _PluginVersion:
+ def __init__(self, major, minor, patch, extra):
+ self._major = major
+ self._minor = minor
+ self._patch = patch
+ self._extra = extra
+
+ @property
+ def major(self):
+ return self._major
+
+ @property
+ def minor(self):
+ return self._minor
+
+ @property
+ def patch(self):
+ return self._patch
+
+ @property
+ def extra(self):
+ return self._extra
+
+ def __str__(self):
+ extra = ''
+
+ if self._extra is not None:
+ extra = self._extra
+
+ return '{}.{}.{}{}'.format(self._major, self._minor, self._patch, extra)
+
+
+class _PluginComponentClassesIterator(collections.abc.Iterator):
+ def __init__(self, plugin_comp_cls):
+ self._plugin_comp_cls = plugin_comp_cls
+ self._at = 0
+
+ def __next__(self):
+ plugin_ptr = self._plugin_comp_cls._plugin._ptr
+ comp_cls_type = self._plugin_comp_cls._comp_cls_type
+ total = native_bt.plugin_get_component_class_count(plugin_ptr)
+
+ while True:
+ if self._at == total:
+ raise StopIteration
+
+ comp_cls_ptr = native_bt.plugin_get_component_class_by_index(plugin_ptr,
+ self._at)
+ assert(comp_cls_ptr)
+ cc_type = native_bt.component_class_get_type(comp_cls_ptr)
+ self._at += 1
+
+ if cc_type == comp_cls_type:
+ break
+
+ native_bt.put(comp_cls_ptr)
+
+ name = native_bt.component_class_get_name(comp_cls_ptr)
+ native_bt.put(comp_cls_ptr)
+ assert(name is not None)
+ return name
+
+
+class _PluginComponentClasses(collections.abc.Mapping):
+ def __init__(self, plugin, comp_cls_type):
+ self._plugin = plugin
+ self._comp_cls_type = comp_cls_type
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ cc_ptr = native_bt.plugin_get_component_class_by_name_and_type(self._plugin._ptr,
+ key,
+ self._comp_cls_type)
+
+ if cc_ptr is None:
+ raise KeyError(key)
+
+ return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
+
+ def __len__(self):
+ count = 0
+ total = native_bt.plugin_get_component_class_count(self._plugin._ptr)
+
+ for at in range(total):
+ comp_cls_ptr = native_bt.plugin_get_component_class_by_index(self._plugin._ptr,
+ at)
+ assert(comp_cls_ptr)
+ cc_type = native_bt.component_class_get_type(comp_cls_ptr)
+
+ if cc_type == self._comp_cls_type:
+ count += 1
+
+ native_bt.put(comp_cls_ptr)
+
+ return count
+
+ def __iter__(self):
+ return _PluginComponentClassesIterator(self)
+
+
+class _Plugin(object._Object):
+ @property
+ def name(self):
+ name = native_bt.plugin_get_name(self._ptr)
+ assert(name is not None)
+ return name
+
+ @property
+ def author(self):
+ return native_bt.plugin_get_author(self._ptr)
+
+ @property
+ def license(self):
+ return native_bt.plugin_get_license(self._ptr)
+
+ @property
+ def description(self):
+ return native_bt.plugin_get_description(self._ptr)
+
+ @property
+ def path(self):
+ return native_bt.plugin_get_path(self._ptr)
+
+ @property
+ def version(self):
+ status, major, minor, patch, extra = native_bt.plugin_get_version(self._ptr)
+
+ if status < 0:
+ return
+
+ return _PluginVersion(major, minor, patch, extra)
+
+ @property
+ def source_component_classes(self):
+ return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_SOURCE)
+
+ @property
+ def filter_component_classes(self):
+ return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_FILTER)
+
+ @property
+ def sink_component_classes(self):
+ return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_SINK)
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import bt2.component
+import bt2.connection
+import copy
+import bt2
+
+
+def _create_from_ptr(ptr):
+ port_type = native_bt.port_get_type(ptr)
+
+ if port_type == native_bt.PORT_TYPE_INPUT:
+ cls = _InputPort
+ elif port_type == native_bt.PORT_TYPE_OUTPUT:
+ cls = _OutputPort
+ else:
+ raise bt2.Error('unknown port type: {}'.format(port_type))
+
+ return cls._create_from_ptr(ptr)
+
+
+def _create_private_from_ptr(ptr):
+ pub_ptr = native_bt.port_from_private_port(ptr)
+ utils._handle_ptr(pub_ptr, 'cannot get port object from private port object')
+ port_type = native_bt.port_get_type(pub_ptr)
+ assert(port_type == native_bt.PORT_TYPE_INPUT or port_type == native_bt.PORT_TYPE_OUTPUT)
+
+ if port_type == native_bt.PORT_TYPE_INPUT:
+ cls = _PrivateInputPort
+ elif port_type == native_bt.PORT_TYPE_OUTPUT:
+ cls = _PrivateOutputPort
+
+ obj = cls._create_from_ptr(ptr)
+ obj._pub_ptr = pub_ptr
+ return obj
+
+
+class _Port(object._Object):
+ @staticmethod
+ def _name(ptr):
+ name = native_bt.port_get_name(ptr)
+ assert(name is not None)
+ return name
+
+ @staticmethod
+ def _disconnect(ptr):
+ status = native_bt.port_disconnect(ptr)
+
+ if status < 0:
+ raise bt2.Error('cannot disconnect port')
+
+ @property
+ def name(self):
+ return self._name(self._ptr)
+
+ @property
+ def component(self):
+ comp_ptr = native_bt.port_get_component(self._ptr)
+
+ if comp_ptr is None:
+ return
+
+ return bt2.component._create_generic_component_from_ptr(comp_ptr)
+
+ @property
+ def connection(self):
+ conn_ptr = native_bt.port_get_connection(self._ptr)
+
+ if conn_ptr is None:
+ return
+
+ return bt2.connection._Connection._create_from_ptr(conn_ptr)
+
+ @property
+ def is_connected(self):
+ return self.connection is not None
+
+ def disconnect(self):
+ self._disconnect(self._ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ return self.addr == other.addr
+
+
+class _InputPort(_Port):
+ pass
+
+
+class _OutputPort(_Port):
+ pass
+
+
+class _PrivatePort(object._PrivateObject, _Port):
+ @property
+ def name(self):
+ return self._name(self._pub_ptr)
+
+ @property
+ def component(self):
+ comp_ptr = native_bt.private_port_get_private_component(self._ptr)
+
+ if comp_ptr is None:
+ return
+
+ pub_comp_ptr = native_bt.component_from_private_component(comp_ptr)
+ assert(pub_comp_ptr)
+ comp = bt2.component._create_generic_component_from_ptr(pub_comp_ptr)
+ native_bt.put(comp_ptr)
+ return comp
+
+ @property
+ def connection(self):
+ conn_ptr = native_bt.private_port_get_private_connection(self._ptr)
+
+ if conn_ptr is None:
+ return
+
+ return bt2.connection._create_private_from_ptr(conn_ptr)
+
+ def remove_from_component(self):
+ status = native_bt.private_port_remove_from_component(self._ptr)
+
+ if status < 0:
+ raise bt2.Error("cannot remove port from component")
+
+ def disconnect(self):
+ self._disconnect(self._pub_ptr)
+
+
+class _PrivateInputPort(_PrivatePort, _InputPort):
+ pass
+
+
+class _PrivateOutputPort(_PrivatePort, _OutputPort):
+ pass
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import utils
+import bt2.component
+
+
+def plugin_component_class(component_class):
+ if not issubclass(component_class, bt2.component._UserComponent):
+ raise TypeError('component class is not a subclass of a user component class')
+
+ component_class._bt_plugin_component_class = None
+ return component_class
+
+
+def register_plugin(module_name, name, description=None, author=None,
+ license=None, version=None):
+ import sys
+
+ if module_name not in sys.modules:
+ raise RuntimeError("cannot find module '{}' in loaded modules".format(module_name))
+
+ utils._check_str(name)
+
+ if description is not None:
+ utils._check_str(description)
+
+ if author is not None:
+ utils._check_str(author)
+
+ if license is not None:
+ utils._check_str(license)
+
+ if version is not None:
+ if not _validate_version(version):
+ raise ValueError('wrong version: expecting a tuple: (major, minor, patch) or (major, minor, patch, extra)')
+
+ sys.modules[module_name]._bt_plugin_info = _PluginInfo(name, description,
+ author, license,
+ version)
+
+
+def _validate_version(version):
+ if version is None:
+ return True
+
+ if not isinstance(version, tuple):
+ return False
+
+ if len(version) < 3 or len(version) > 4:
+ return False
+
+ if not isinstance(version[0], int):
+ return False
+
+ if not isinstance(version[1], int):
+ return False
+
+ if not isinstance(version[2], int):
+ return False
+
+ if len(version) == 4:
+ if not isinstance(version[3], str):
+ return False
+
+ return True
+
+
+class _PluginInfo:
+ def __init__(self, name, description, author, license, version):
+ self.name = name
+ self.description = description
+ self.author = author
+ self.license = license
+ self.version = version
+ self.comp_class_addrs = None
+
+
+# called by the BT plugin system
+def _try_load_plugin_module(path):
+ import importlib.machinery
+ import inspect
+ import hashlib
+
+ if path is None:
+ raise TypeError('missing path')
+
+ # In order to load the module uniquely from its path, even from
+ # different files which have the same basename, we hash the path
+ # and prefix with `bt_plugin_`. This is its key in sys.modules.
+ h = hashlib.sha256()
+ h.update(path.encode())
+ module_name = 'bt_plugin_{}'.format(h.hexdigest())
+
+ # try loading the module: any raised exception is catched by the caller
+ mod = importlib.machinery.SourceFileLoader(module_name, path).load_module()
+
+ # we have the module: look for its plugin info first
+ if not hasattr(mod, '_bt_plugin_info'):
+ raise RuntimeError("missing '_bt_plugin_info' module attribute")
+
+ plugin_info = mod._bt_plugin_info
+
+ # search for user component classes
+ def is_user_comp_class(obj):
+ if not inspect.isclass(obj):
+ return False
+
+ if not hasattr(obj, '_bt_plugin_component_class'):
+ return False
+
+ return True
+
+ comp_class_entries = inspect.getmembers(mod, is_user_comp_class)
+ plugin_info.comp_class_addrs = [entry[1].addr for entry in comp_class_entries]
+ return plugin_info
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.packet
+import bt2.event
+import abc
+import bt2
+
+
+def _create_from_ptr(stream_ptr):
+ if native_bt.ctf_stream_is_writer(stream_ptr):
+ import ctf_writer
+
+ cls = ctf_writer._CtfWriterStream
+ else:
+ cls = _Stream
+
+ return cls._create_from_ptr(stream_ptr)
+
+
+class _StreamBase(object._Object):
+ @property
+ def stream_class(self):
+ stream_class_ptr = native_bt.ctf_stream_get_class(self._ptr)
+ assert(stream_class_ptr)
+ return bt2.StreamClass._create_from_ptr(stream_class_ptr)
+
+ @property
+ def name(self):
+ return native_bt.ctf_stream_get_name(self._ptr)
+
+ @property
+ def id(self):
+ id = native_bt.ctf_stream_get_id(self._ptr)
+ return id if id >= 0 else None
+
+ def __eq__(self, other):
+ if self.addr == other.addr:
+ return True
+
+ return (self.name, self.id) == (other.name, other.id)
+
+
+class _Stream(_StreamBase):
+ def create_packet(self):
+ packet_ptr = native_bt.ctf_packet_create(self._ptr)
+
+ if packet_ptr is None:
+ raise bt2.CreationError('cannot create packet object')
+
+ return bt2.packet._Packet._create_from_ptr(packet_ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ return _StreamBase.__eq__(self, other)
+
+ def _copy(self):
+ return self.stream_class(self.name, self.id)
+
+ def __copy__(self):
+ return self._copy()
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy()
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.field_types
+import collections.abc
+import bt2.ctf_writer
+import bt2.stream
+import copy
+import bt2
+
+
+class _EventClassIterator(collections.abc.Iterator):
+ def __init__(self, stream_class):
+ self._stream_class = stream_class
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._stream_class):
+ raise StopIteration
+
+ ec_ptr = native_bt.ctf_stream_class_get_event_class_by_index(self._stream_class._ptr,
+ self._at)
+ assert(ec_ptr)
+ ev_id = native_bt.ctf_event_class_get_id(ec_ptr)
+ native_bt.put(ec_ptr)
+ utils._handle_ret(ev_id, "cannot get event class object's ID")
+ self._at += 1
+ return ev_id
+
+
+class StreamClass(object._Object, collections.abc.Mapping):
+ def __init__(self, name=None, id=None, packet_context_field_type=None,
+ event_header_field_type=None, event_context_field_type=None,
+ event_classes=None):
+ ptr = native_bt.ctf_stream_class_create_empty(None)
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create stream class object')
+
+ super().__init__(ptr)
+
+ if name is not None:
+ self.name = name
+
+ if id is not None:
+ self.id = id
+
+ if packet_context_field_type is not None:
+ self.packet_context_field_type = packet_context_field_type
+
+ if event_header_field_type is not None:
+ self.event_header_field_type = event_header_field_type
+
+ if event_context_field_type is not None:
+ self.event_context_field_type = event_context_field_type
+
+ if event_classes is not None:
+ for event_class in event_classes:
+ self.add_event_class(event_class)
+
+ def __getitem__(self, key):
+ utils._check_int64(key)
+ ec_ptr = native_bt.ctf_stream_class_get_event_class_by_id(self._ptr,
+ key)
+
+ if ec_ptr is None:
+ raise KeyError(key)
+
+ return bt2.EventClass._create_from_ptr(ec_ptr)
+
+ def __len__(self):
+ count = native_bt.ctf_stream_class_get_event_class_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ def __iter__(self):
+ return _EventClassIterator(self)
+
+ def add_event_class(self, event_class):
+ utils._check_type(event_class, bt2.EventClass)
+ ret = native_bt.ctf_stream_class_add_event_class(self._ptr, event_class._ptr)
+ utils._handle_ret(ret, "cannot add event class object to stream class object's")
+
+ @property
+ def trace(self):
+ tc_ptr = native_bt.ctf_stream_class_get_trace(self._ptr)
+
+ if tc_ptr is not None:
+ return bt2.Trace._create_from_ptr(tc_ptr)
+
+ @property
+ def name(self):
+ return native_bt.ctf_stream_class_get_name(self._ptr)
+
+ @name.setter
+ def name(self, name):
+ utils._check_str(name)
+ ret = native_bt.ctf_stream_class_set_name(self._ptr, name)
+ utils._handle_ret(ret, "cannot set stream class object's name")
+
+ @property
+ def id(self):
+ id = native_bt.ctf_stream_class_get_id(self._ptr)
+
+ if id < 0:
+ return
+
+ return id
+
+ @id.setter
+ def id(self, id):
+ utils._check_int64(id)
+ ret = native_bt.ctf_stream_class_set_id(self._ptr, id)
+ utils._handle_ret(ret, "cannot set stream class object's ID")
+
+ @property
+ def clock(self):
+ clock_ptr = native_bt.ctf_stream_class_get_clock(self._ptr)
+
+ if clock_ptr is None:
+ return
+
+ return bt2.ctf_writer.CtfWriterClock._create_from_ptr(clock_ptr)
+
+ @clock.setter
+ def clock(self, clock):
+ utils._check_type(clock, bt2.ctf_writer.CtfWriterClock)
+ ret = native_bt.ctf_stream_class_set_clock(self._ptr, clock._ptr)
+ utils._handle_ret(ret, "cannot set stream class object's CTF writer clock object")
+
+ @property
+ def packet_context_field_type(self):
+ ft_ptr = native_bt.ctf_stream_class_get_packet_context_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return bt2.field_types._create_from_ptr(ft_ptr)
+
+ @packet_context_field_type.setter
+ def packet_context_field_type(self, packet_context_field_type):
+ packet_context_field_type_ptr = None
+
+ if packet_context_field_type is not None:
+ utils._check_type(packet_context_field_type, bt2.field_types._FieldType)
+ packet_context_field_type_ptr = packet_context_field_type._ptr
+
+ ret = native_bt.ctf_stream_class_set_packet_context_type(self._ptr,
+ packet_context_field_type_ptr)
+ utils._handle_ret(ret, "cannot set stream class object's packet context field type")
+
+ @property
+ def event_header_field_type(self):
+ ft_ptr = native_bt.ctf_stream_class_get_event_header_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return bt2.field_types._create_from_ptr(ft_ptr)
+
+ @event_header_field_type.setter
+ def event_header_field_type(self, event_header_field_type):
+ event_header_field_type_ptr = None
+
+ if event_header_field_type is not None:
+ utils._check_type(event_header_field_type, bt2.field_types._FieldType)
+ event_header_field_type_ptr = event_header_field_type._ptr
+
+ ret = native_bt.ctf_stream_class_set_event_header_type(self._ptr,
+ event_header_field_type_ptr)
+ utils._handle_ret(ret, "cannot set stream class object's event header field type")
+
+ @property
+ def event_context_field_type(self):
+ ft_ptr = native_bt.ctf_stream_class_get_event_context_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return bt2.field_types._create_from_ptr(ft_ptr)
+
+ @event_context_field_type.setter
+ def event_context_field_type(self, event_context_field_type):
+ event_context_field_type_ptr = None
+
+ if event_context_field_type is not None:
+ utils._check_type(event_context_field_type, bt2.field_types._FieldType)
+ event_context_field_type_ptr = event_context_field_type._ptr
+
+ ret = native_bt.ctf_stream_class_set_event_context_type(self._ptr,
+ event_context_field_type_ptr)
+ utils._handle_ret(ret, "cannot set stream class object's event context field type")
+
+ def __call__(self, name=None, id=None):
+ if name is not None:
+ utils._check_str(name)
+
+ if id is None:
+ stream_ptr = native_bt.ctf_stream_create(self._ptr, name)
+ else:
+ stream_ptr = native_bt.ctf_stream_create_with_id(self._ptr, name, id)
+
+ if stream_ptr is None:
+ raise bt2.CreationError('cannot create stream object')
+
+ 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
+
+ self_event_classes = list(self.values())
+ other_event_classes = list(other.values())
+ self_props = (
+ self_event_classes,
+ self.name,
+ self.id,
+ self.packet_context_field_type,
+ self.event_header_field_type,
+ self.event_context_field_type,
+ self.clock,
+ )
+ other_props = (
+ other_event_classes,
+ other.name,
+ other.id,
+ other.packet_context_field_type,
+ other.event_header_field_type,
+ other.event_context_field_type,
+ other.clock,
+ )
+
+ return self_props == other_props
+
+ def _copy(self, ft_copy_func, ev_copy_func):
+ cpy = StreamClass()
+
+ if self.id is not None:
+ cpy.id = self.id
+
+ if self.name is not None:
+ cpy.name = self.name
+
+ if self.clock is not None:
+ cpy.clock = self.clock
+
+ cpy.packet_context_field_type = ft_copy_func(self.packet_context_field_type)
+ cpy.event_header_field_type = ft_copy_func(self.event_header_field_type)
+ cpy.event_context_field_type = ft_copy_func(self.event_context_field_type)
+
+ for event_class in self.values():
+ cpy.add_event_class(ev_copy_func(event_class))
+
+ return cpy
+
+ def __copy__(self):
+ return self._copy(lambda ft: ft, copy.copy)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy, copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.field_types
+import collections.abc
+import bt2.values
+import bt2.stream
+import copy
+import bt2
+
+
+class _StreamClassIterator(collections.abc.Iterator):
+ def __init__(self, trace):
+ self._trace = trace
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._trace):
+ raise StopIteration
+
+ sc_ptr = native_bt.ctf_trace_get_stream_class_by_index(self._trace._ptr,
+ self._at)
+ assert(sc_ptr)
+ id = native_bt.ctf_stream_class_get_id(sc_ptr)
+ native_bt.put(sc_ptr)
+ assert(id >= 0)
+ self._at += 1
+ return id
+
+
+class _TraceStreams(collections.abc.Sequence):
+ def __init__(self, trace):
+ self._trace = trace
+
+ def __len__(self):
+ count = native_bt.ctf_trace_get_stream_count(self._trace._ptr)
+ assert(count >= 0)
+ return count
+
+ def __getitem__(self, index):
+ utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
+ stream_ptr = native_bt.ctf_trace_get_stream_by_index(self._trace._ptr,
+ index)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+
+class _TraceClockClassesIterator(collections.abc.Iterator):
+ def __init__(self, trace_clock_classes):
+ self._trace_clock_classes = trace_clock_classes
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._trace_clock_classes):
+ raise StopIteration
+
+ trace_ptr = self._trace_clock_classes._trace._ptr
+ cc_ptr = native_bt.ctf_trace_get_clock_class_by_index(trace_ptr, self._at)
+ assert(cc_ptr)
+ name = native_bt.ctf_clock_class_get_name(cc_ptr)
+ native_bt.put(cc_ptr)
+ assert(name is not None)
+ self._at += 1
+ return name
+
+
+class _TraceClockClasses(collections.abc.Mapping):
+ def __init__(self, trace):
+ self._trace = trace
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ cc_ptr = native_bt.ctf_trace_get_clock_class_by_name(self._trace._ptr,
+ key)
+
+ if cc_ptr is None:
+ raise KeyError(key)
+
+ return bt2.ClockClass._create_from_ptr(cc_ptr)
+
+ def __len__(self):
+ count = native_bt.ctf_trace_get_clock_class_count(self._trace._ptr)
+ assert(count >= 0)
+ return count
+
+ def __iter__(self):
+ return _TraceClockClassesIterator(self)
+
+
+class _TraceEnvIterator(collections.abc.Iterator):
+ def __init__(self, trace_env):
+ self._trace_env = trace_env
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._trace_env):
+ raise StopIteration
+
+ trace_ptr = self._trace_env._trace._ptr
+ entry_name = native_bt.ctf_trace_get_environment_field_name_by_index(trace_ptr,
+ self._at)
+ assert(entry_name is not None)
+ self._at += 1
+ return entry_name
+
+
+class _TraceEnv(collections.abc.MutableMapping):
+ def __init__(self, trace):
+ self._trace = trace
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ value_ptr = native_bt.ctf_trace_get_environment_field_value_by_name(self._trace._ptr,
+ key)
+
+ if value_ptr is None:
+ raise KeyError(key)
+
+ return bt2.values._create_from_ptr(value_ptr)
+
+ def __setitem__(self, key, value):
+ utils._check_str(key)
+ value = bt2.create_value(value)
+ ret = native_bt.ctf_trace_set_environment_field(self._trace._ptr,
+ key, value._ptr)
+ utils._handle_ret(ret, "cannot set trace class object's environment entry")
+
+ def __delitem__(self, key):
+ raise NotImplementedError
+
+ def __len__(self):
+ count = native_bt.ctf_trace_get_environment_field_count(self._trace._ptr)
+ assert(count >= 0)
+ return count
+
+ def __iter__(self):
+ return _TraceEnvIterator(self)
+
+
+class Trace(object._Object, collections.abc.Mapping):
+ def __init__(self, name=None, native_byte_order=None, env=None,
+ packet_header_field_type=None, clock_classes=None,
+ stream_classes=None):
+ ptr = native_bt.ctf_trace_create()
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create trace class object')
+
+ super().__init__(ptr)
+
+ if name is not None:
+ self.name = name
+
+ if native_byte_order is not None:
+ self.native_byte_order = native_byte_order
+
+ if packet_header_field_type is not None:
+ self.packet_header_field_type = packet_header_field_type
+
+ if env is not None:
+ for key, value in env.items():
+ self.env[key] = value
+
+ if clock_classes is not None:
+ for clock_class in clock_classes:
+ self.add_clock_class(clock_class)
+
+ if stream_classes is not None:
+ for stream_class in stream_classes:
+ self.add_stream_class(stream_class)
+
+ def __getitem__(self, key):
+ utils._check_int64(key)
+ sc_ptr = native_bt.ctf_trace_get_stream_class_by_id(self._ptr, key)
+
+ if sc_ptr is None:
+ raise KeyError(key)
+
+ return bt2.StreamClass._create_from_ptr(sc_ptr)
+
+ def __len__(self):
+ count = native_bt.ctf_trace_get_stream_class_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ def __iter__(self):
+ return _StreamClassIterator(self)
+
+ def add_stream_class(self, stream_class):
+ utils._check_type(stream_class, bt2.StreamClass)
+ ret = native_bt.ctf_trace_add_stream_class(self._ptr, stream_class._ptr)
+ utils._handle_ret(ret, "cannot add stream class object to trace class object")
+
+ @property
+ def name(self):
+ return native_bt.ctf_trace_get_name(self._ptr)
+
+ @name.setter
+ def name(self, name):
+ utils._check_str(name)
+ ret = native_bt.ctf_trace_set_name(self._ptr, name)
+ utils._handle_ret(ret, "cannot set trace class object's name")
+
+ @property
+ def native_byte_order(self):
+ bo = native_bt.ctf_trace_get_native_byte_order(self._ptr)
+ assert(bo >= 0)
+ return bo
+
+ @native_byte_order.setter
+ def native_byte_order(self, native_byte_order):
+ utils._check_int(native_byte_order)
+ ret = native_bt.ctf_trace_set_native_byte_order(self._ptr, native_byte_order)
+ utils._handle_ret(ret, "cannot set trace class object's native byte order")
+
+ @property
+ def is_static(self):
+ is_static = native_bt.ctf_trace_is_static(self._ptr)
+ return is_static > 0
+
+ def set_is_static(self):
+ ret = native_bt.ctf_trace_set_is_static(self._ptr)
+ utils._handle_ret(ret, "cannot set trace object as static")
+
+ @property
+ def env(self):
+ return _TraceEnv(self)
+
+ @property
+ def clock_classes(self):
+ return _TraceClockClasses(self)
+
+ def add_clock_class(self, clock_class):
+ utils._check_type(clock_class, bt2.ClockClass)
+ ret = native_bt.ctf_trace_add_clock_class(self._ptr, clock_class._ptr)
+ utils._handle_ret(ret, "cannot add clock class object to trace class object")
+
+ @property
+ def streams(self):
+ return _TraceStreams(self)
+
+ @property
+ def packet_header_field_type(self):
+ ft_ptr = native_bt.ctf_trace_get_packet_header_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return bt2.field_types._create_from_ptr(ft_ptr)
+
+ @packet_header_field_type.setter
+ def packet_header_field_type(self, packet_header_field_type):
+ packet_header_field_type_ptr = None
+
+ if packet_header_field_type is not None:
+ utils._check_type(packet_header_field_type, bt2.field_types._FieldType)
+ packet_header_field_type_ptr = packet_header_field_type._ptr
+
+ ret = native_bt.ctf_trace_set_packet_header_type(self._ptr,
+ packet_header_field_type_ptr)
+ utils._handle_ret(ret, "cannot set trace class object's packet header field type")
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ # not comparing apples to apples
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_stream_classes = list(self.values())
+ self_clock_classes = list(self.clock_classes.values())
+ self_env = {key: val for key, val in self.env.items()}
+ other_stream_classes = list(other.values())
+ other_clock_classes = list(other.clock_classes.values())
+ other_env = {key: val for key, val in other.env.items()}
+ self_props = (
+ self_stream_classes,
+ self_clock_classes,
+ self_env,
+ self.name,
+ self.native_byte_order,
+ self.packet_header_field_type,
+ )
+ other_props = (
+ other_stream_classes,
+ other_clock_classes,
+ other_env,
+ other.name,
+ other.native_byte_order,
+ other.packet_header_field_type,
+ )
+ return self_props == other_props
+
+ def _copy(self, gen_copy_func, sc_copy_func):
+ cpy = Trace()
+
+ if self.name is not None:
+ cpy.name = self.name
+
+ cpy.packet_header_field_type = gen_copy_func(self.packet_header_field_type)
+
+ for key, val in self.env.items():
+ cpy.env[key] = gen_copy_func(val)
+
+ for clock_class in self.clock_classes.values():
+ cpy.add_clock_class(gen_copy_func(clock_class))
+
+ for stream_class in self.values():
+ cpy.add_stream_class(sc_copy_func(stream_class))
+
+ return cpy
+
+ def __copy__(self):
+ return self._copy(lambda obj: obj, copy.copy)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy, copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import bt2
+
+
+def _check_bool(o):
+ if not isinstance(o, bool):
+ raise TypeError("'{}' is not a 'bool' object".format(o.__class__.__name__))
+
+
+def _check_int(o):
+ if not isinstance(o, int):
+ raise TypeError("'{}' is not an 'int' object".format(o.__class__.__name__))
+
+
+def _check_float(o):
+ if not isinstance(o, float):
+ raise TypeError("'{}' is not a 'float' object".format(o.__class__.__name__))
+
+
+def _check_str(o):
+ if not isinstance(o, str):
+ raise TypeError("'{}' is not a 'str' object".format(o.__class__.__name__))
+
+
+def _check_type(o, expected_type):
+ if not isinstance(o, expected_type):
+ raise TypeError("'{}' is not a '{}' object".format(o.__class__.__name__,
+ expected_type))
+
+
+def _is_int64(v):
+ _check_int(v)
+ return v >= -(2**63) and v <= (2**63 - 1)
+
+
+def _is_uint64(v):
+ _check_int(v)
+ return v >= 0 and v <= (2**64 - 1)
+
+
+def _check_int64(v, msg=None):
+ if not _is_int64(v):
+ if msg is None:
+ msg = 'expecting a signed 64-bit integral value'
+
+ msg += ' (got {})'.format(v)
+ raise ValueError(msg)
+
+
+def _check_uint64(v, msg=None):
+ if not _is_uint64(v):
+ if msg is None:
+ msg = 'expecting an unsigned 64-bit integral value'
+
+ msg += ' (got {})'.format(v)
+ raise ValueError(msg)
+
+
+def _is_m1ull(v):
+ return v == 18446744073709551615
+
+
+def _is_pow2(v):
+ return v != 0 and ((v & (v - 1)) == 0)
+
+
+def _check_alignment(a):
+ _check_uint64(a)
+
+ if not _is_pow2(a):
+ raise ValueError('{} is not a power of two'.format(a))
+
+
+def _handle_ret(ret, msg=None):
+ if int(ret) < 0:
+ if msg is None:
+ error = bt2.Error()
+ else:
+ error = bt2.Error(msg)
+
+ raise error
+
+
+def _handle_ptr(ptr, msg=None):
+ if ptr is None:
+ if msg is None:
+ error = bt2.Error()
+ else:
+ error = bt2.Error(msg)
+
+ raise error
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import functools
+import numbers
+import math
+import abc
+import bt2
+
+
+def _handle_status(status, obj_name):
+ if status >= 0:
+ return
+
+ if status == native_bt.VALUE_STATUS_FROZEN:
+ raise bt2.Frozen('{} value object is frozen'.format(obj_name))
+ elif status == native_bt.VALUE_STATUS_INVAL:
+ # In practice, this should never happen, because arguments
+ # should always be validated in this Python module before
+ # calling the native functions.
+ raise ValueError('unexpected invalid argument')
+ else:
+ # In practice, this should never happen, because arguments
+ # should always be validated in this Python module before
+ # calling the native functions.
+ raise RuntimeError('unexpected error')
+
+
+def _create_from_ptr(ptr):
+ if ptr is None or ptr == native_bt.value_null:
+ return
+
+ typeid = native_bt.value_get_type(ptr)
+ return _TYPE_TO_OBJ[typeid]._create_from_ptr(ptr)
+
+
+def create_value(value):
+ if value is None:
+ # null value object
+ return
+
+ if isinstance(value, _Value):
+ return value
+
+ if isinstance(value, bool):
+ return BoolValue(value)
+
+ if isinstance(value, int):
+ return IntegerValue(value)
+
+ if isinstance(value, float):
+ return FloatValue(value)
+
+ if isinstance(value, str):
+ return StringValue(value)
+
+ try:
+ return MapValue(value)
+ except:
+ pass
+
+ try:
+ return ArrayValue(value)
+ except:
+ pass
+
+ raise TypeError("cannot create value object from '{}' object".format(value.__class__.__name__))
+
+
+class _Value(object._Object, object._Freezable, metaclass=abc.ABCMeta):
+ def __eq__(self, other):
+ if other is None:
+ # self is never the null value object
+ return False
+
+ # try type-specific comparison first
+ spec_eq = self._spec_eq(other)
+
+ if spec_eq is not None:
+ return spec_eq
+
+ if not isinstance(other, _Value):
+ # not comparing apples to apples
+ return False
+
+ # fall back to native comparison function
+ return native_bt.value_compare(self._ptr, other._ptr)
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ @abc.abstractmethod
+ def _spec_eq(self, other):
+ pass
+
+ def _handle_status(self, status):
+ _handle_status(status, self._NAME)
+
+ def _check_create_status(self, ptr):
+ if ptr is None:
+ raise bt2.CreationError('cannot create {} value object'.format(self._NAME.lower()))
+
+ def _is_frozen(self):
+ return native_bt.value_is_frozen(self._ptr)
+
+ def _freeze(self):
+ status = native_bt.value_freeze(self._ptr)
+ self._handle_status(status)
+
+
+class _BasicCopy:
+ def __copy__(self):
+ return self.__class__(self.value)
+
+ def __deepcopy__(self, memo):
+ copy = self.__copy__()
+ memo[id(self)] = copy
+ return copy
+
+
+@functools.total_ordering
+class _NumericValue(_Value, _BasicCopy):
+ @staticmethod
+ def _extract_value(other):
+ if isinstance(other, _NumericValue):
+ return other.value
+
+ if other is True or other is False:
+ return other
+
+ if isinstance(other, numbers.Integral):
+ return int(other)
+
+ if isinstance(other, numbers.Real):
+ return float(other)
+
+ if isinstance(other, numbers.Complex):
+ return complex(other)
+
+ raise TypeError("'{}' object is not a number object".format(other.__class__.__name__))
+
+ def __int__(self):
+ return int(self.value)
+
+ def __float__(self):
+ return float(self.value)
+
+ def __str__(self):
+ return str(self.value)
+
+ def __lt__(self, other):
+ if not isinstance(other, numbers.Number):
+ raise TypeError('unorderable types: {}() < {}()'.format(self.__class__.__name__,
+ other.__class__.__name__))
+
+ return self.value < float(other)
+
+ def __le__(self, other):
+ if not isinstance(other, numbers.Number):
+ raise TypeError('unorderable types: {}() <= {}()'.format(self.__class__.__name__,
+ other.__class__.__name__))
+
+ return self.value <= float(other)
+
+ def _spec_eq(self, other):
+ pass
+
+ def __eq__(self, other):
+ if not isinstance(other, numbers.Number):
+ return False
+
+ return self.value == complex(other)
+
+ def __rmod__(self, other):
+ return self._extract_value(other) % self.value
+
+ def __mod__(self, other):
+ return self.value % self._extract_value(other)
+
+ def __rfloordiv__(self, other):
+ return self._extract_value(other) // self.value
+
+ def __floordiv__(self, other):
+ return self.value // self._extract_value(other)
+
+ def __round__(self, ndigits=None):
+ if ndigits is None:
+ return round(self.value)
+ else:
+ return round(self.value, ndigits)
+
+ def __ceil__(self):
+ return math.ceil(self.value)
+
+ def __floor__(self):
+ return math.floor(self.value)
+
+ def __trunc__(self):
+ return int(self.value)
+
+ def __abs__(self):
+ return abs(self.value)
+
+ def __add__(self, other):
+ return self.value + self._extract_value(other)
+
+ def __radd__(self, other):
+ return self.__add__(other)
+
+ def __neg__(self):
+ return -self.value
+
+ def __pos__(self):
+ return +self.value
+
+ def __mul__(self, other):
+ return self.value * self._extract_value(other)
+
+ def __rmul__(self, other):
+ return self.__mul__(other)
+
+ def __truediv__(self, other):
+ return self.value / self._extract_value(other)
+
+ def __rtruediv__(self, other):
+ return self._extract_value(other) / self.value
+
+ def __pow__(self, exponent):
+ return self.value ** self._extract_value(exponent)
+
+ def __rpow__(self, base):
+ return self._extract_value(base) ** self.value
+
+ def __iadd__(self, other):
+ self.value = self + other
+ return self
+
+ def __isub__(self, other):
+ self.value = self - other
+ return self
+
+ def __imul__(self, other):
+ self.value = self * other
+ return self
+
+ def __itruediv__(self, other):
+ self.value = self / other
+ return self
+
+ def __ifloordiv__(self, other):
+ self.value = self // other
+ return self
+
+ def __imod__(self, other):
+ self.value = self % other
+ return self
+
+ def __ipow__(self, other):
+ self.value = self ** other
+ return self
+
+
+class _IntegralValue(_NumericValue, numbers.Integral):
+ def __lshift__(self, other):
+ return self.value << self._extract_value(other)
+
+ def __rlshift__(self, other):
+ return self._extract_value(other) << self.value
+
+ def __rshift__(self, other):
+ return self.value >> self._extract_value(other)
+
+ def __rrshift__(self, other):
+ return self._extract_value(other) >> self.value
+
+ def __and__(self, other):
+ return self.value & self._extract_value(other)
+
+ def __rand__(self, other):
+ return self._extract_value(other) & self.value
+
+ def __xor__(self, other):
+ return self.value ^ self._extract_value(other)
+
+ def __rxor__(self, other):
+ return self._extract_value(other) ^ self.value
+
+ def __or__(self, other):
+ return self.value | self._extract_value(other)
+
+ def __ror__(self, other):
+ return self._extract_value(other) | self.value
+
+ def __invert__(self):
+ return ~self.value
+
+ def __ilshift__(self, other):
+ self.value = self << other
+ return self
+
+ def __irshift__(self, other):
+ self.value = self >> other
+ return self
+
+ def __iand__(self, other):
+ self.value = self & other
+ return self
+
+ def __ixor__(self, other):
+ self.value = self ^ other
+ return self
+
+ def __ior__(self, other):
+ self.value = self | other
+ return self
+
+
+class _RealValue(_NumericValue, numbers.Real):
+ pass
+
+
+class BoolValue(_Value, _BasicCopy):
+ _NAME = 'Boolean'
+
+ def __init__(self, value=None):
+ if value is None:
+ ptr = native_bt.value_bool_create()
+ else:
+ ptr = native_bt.value_bool_create_init(self._value_to_bool(value))
+
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ def _spec_eq(self, other):
+ if isinstance(other, numbers.Number):
+ return self.value == bool(other)
+
+ def __bool__(self):
+ return self.value
+
+ def __str__(self):
+ return str(self.value)
+
+ def _value_to_bool(self, value):
+ if isinstance(value, BoolValue):
+ value = value.value
+
+ if not isinstance(value, bool):
+ raise TypeError("'{}' object is not a 'bool' or 'BoolValue' object".format(value.__class__))
+
+ return int(value)
+
+ @property
+ def value(self):
+ status, value = native_bt.value_bool_get(self._ptr)
+ assert(status == native_bt.VALUE_STATUS_OK)
+ return value > 0
+
+ @value.setter
+ def value(self, value):
+ status = native_bt.value_bool_set(self._ptr, self._value_to_bool(value))
+ self._handle_status(status)
+
+
+class IntegerValue(_IntegralValue):
+ _NAME = 'Integer'
+
+ def __init__(self, value=None):
+ if value is None:
+ ptr = native_bt.value_integer_create()
+ else:
+ ptr = native_bt.value_integer_create_init(self._value_to_int(value))
+
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ def _value_to_int(self, value):
+ if not isinstance(value, numbers.Real):
+ raise TypeError('expecting a number object')
+
+ value = int(value)
+ utils._check_int64(value)
+ return value
+
+ @property
+ def value(self):
+ status, value = native_bt.value_integer_get(self._ptr)
+ assert(status == native_bt.VALUE_STATUS_OK)
+ return value
+
+ @value.setter
+ def value(self, value):
+ status = native_bt.value_integer_set(self._ptr, self._value_to_int(value))
+ self._handle_status(status)
+
+
+class FloatValue(_RealValue):
+ _NAME = 'Floating point number'
+
+ def __init__(self, value=None):
+ if value is None:
+ ptr = native_bt.value_float_create()
+ else:
+ value = self._value_to_float(value)
+ ptr = native_bt.value_float_create_init(value)
+
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ def _value_to_float(self, value):
+ if not isinstance(value, numbers.Real):
+ raise TypeError("expecting a real number object")
+
+ return float(value)
+
+ @property
+ def value(self):
+ status, value = native_bt.value_float_get(self._ptr)
+ assert(status == native_bt.VALUE_STATUS_OK)
+ return value
+
+ @value.setter
+ def value(self, value):
+ value = self._value_to_float(value)
+ status = native_bt.value_float_set(self._ptr, value)
+ self._handle_status(status)
+
+
+@functools.total_ordering
+class StringValue(_BasicCopy, collections.abc.Sequence, _Value):
+ _NAME = 'String'
+
+ def __init__(self, value=None):
+ if value is None:
+ ptr = native_bt.value_string_create()
+ else:
+ ptr = native_bt.value_string_create_init(self._value_to_str(value))
+
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ def _value_to_str(self, value):
+ if isinstance(value, self.__class__):
+ value = value.value
+
+ utils._check_str(value)
+ return value
+
+ @property
+ def value(self):
+ status, value = native_bt.value_string_get(self._ptr)
+ assert(status == native_bt.VALUE_STATUS_OK)
+ return value
+
+ @value.setter
+ def value(self, value):
+ status = native_bt.value_string_set(self._ptr, self._value_to_str(value))
+ self._handle_status(status)
+
+ def _spec_eq(self, other):
+ try:
+ return self.value == self._value_to_str(other)
+ except:
+ return
+
+ def __le__(self, other):
+ return self.value <= self._value_to_str(other)
+
+ def __lt__(self, other):
+ return self.value < self._value_to_str(other)
+
+ def __bool__(self):
+ return bool(self.value)
+
+ def __str__(self):
+ return self.value
+
+ def __getitem__(self, index):
+ return self.value[index]
+
+ def __len__(self):
+ return len(self.value)
+
+ def __iadd__(self, value):
+ curvalue = self.value
+ curvalue += self._value_to_str(value)
+ self.value = curvalue
+ return self
+
+
+class _Container:
+ def __bool__(self):
+ return len(self) != 0
+
+ def __copy__(self):
+ return self.__class__(self)
+
+ def __deepcopy__(self, memo):
+ ptr = native_bt.value_copy(self._ptr)
+
+ if ptr is None:
+ raise RuntimeError('unexpected error: cannot deep-copy {} value object'.format(self._NAME))
+
+ copy = self.__class__._create_from_ptr(ptr)
+ memo[id(self)] = copy
+ return copy
+
+ def __delitem__(self, index):
+ raise NotImplementedError
+
+
+class ArrayValue(_Container, collections.abc.MutableSequence, _Value):
+ _NAME = 'Array'
+
+ def __init__(self, value=None):
+ ptr = native_bt.value_array_create()
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ # Python will raise a TypeError if there's anything wrong with
+ # the iterable protocol.
+ if value is not None:
+ for elem in value:
+ self.append(elem)
+
+ def _spec_eq(self, other):
+ try:
+ if len(self) != len(other):
+ # early mismatch
+ return False
+
+ for self_elem, other_elem in zip(self, other):
+ if self_elem != other_elem:
+ return False
+
+ return True
+ except:
+ return
+
+ def __len__(self):
+ size = native_bt.value_array_size(self._ptr)
+ assert(size >= 0)
+ return size
+
+ def _check_index(self, index):
+ # TODO: support slices also
+ if not isinstance(index, numbers.Integral):
+ raise TypeError("'{}' object is not an integral number object: invalid index".format(index.__class__.__name__))
+
+ index = int(index)
+
+ if index < 0 or index >= len(self):
+ raise IndexError('array value object index is out of range')
+
+ def __getitem__(self, index):
+ self._check_index(index)
+ ptr = native_bt.value_array_get(self._ptr, index)
+ assert(ptr)
+ return _create_from_ptr(ptr)
+
+ def __setitem__(self, index, value):
+ self._check_index(index)
+ value = create_value(value)
+
+ if value is None:
+ ptr = native_bt.value_null
+ else:
+ ptr = value._ptr
+
+ status = native_bt.value_array_set(self._ptr, index, ptr)
+ self._handle_status(status)
+
+ def append(self, value):
+ value = create_value(value)
+
+ if value is None:
+ ptr = native_bt.value_null
+ else:
+ ptr = value._ptr
+
+ status = native_bt.value_array_append(self._ptr, ptr)
+ self._handle_status(status)
+
+ def __iadd__(self, iterable):
+ # Python will raise a TypeError if there's anything wrong with
+ # the iterable protocol.
+ for elem in iterable:
+ self.append(elem)
+
+ return self
+
+ def __str__(self):
+ strings = []
+
+ for elem in self:
+ if isinstance(elem, StringValue):
+ strings.append(repr(elem.value))
+ else:
+ strings.append(str(elem))
+
+ return '[{}]'.format(', '.join(strings))
+
+ def insert(self, value):
+ raise NotImplementedError
+
+
+class _MapValueKeyIterator(collections.abc.Iterator):
+ def __init__(self, map_obj):
+ self._map_obj = map_obj
+ self._at = 0
+ keys_ptr = native_bt.value_map_get_keys_private(map_obj._ptr)
+
+ if keys_ptr is None:
+ raise RuntimeError('unexpected error: cannot get map value object keys')
+
+ self._keys = _create_from_ptr(keys_ptr)
+
+ def __next__(self):
+ if self._at == len(self._map_obj):
+ raise StopIteration
+
+ key = self._keys[self._at]
+ self._at += 1
+ return str(key)
+
+
+class MapValue(_Container, collections.abc.MutableMapping, _Value):
+ _NAME = 'Map'
+
+ def __init__(self, value=None):
+ ptr = native_bt.value_map_create()
+ self._check_create_status(ptr)
+ super().__init__(ptr)
+
+ # Python will raise a TypeError if there's anything wrong with
+ # the iterable/mapping protocol.
+ if value is not None:
+ for key, elem in value.items():
+ self[key] = elem
+
+ def __eq__(self, other):
+ return _Value.__eq__(self, other)
+
+ def __ne__(self, other):
+ return _Value.__ne__(self, other)
+
+ def _spec_eq(self, other):
+ try:
+ if len(self) != len(other):
+ # early mismatch
+ return False
+
+ for self_key in self:
+ if self_key not in other:
+ return False
+
+ self_value = self[self_key]
+ other_value = other[self_key]
+
+ if self_value != other_value:
+ return False
+
+ return True
+ except:
+ return
+
+ def __len__(self):
+ size = native_bt.value_map_size(self._ptr)
+ assert(size >= 0)
+ return size
+
+ def __contains__(self, key):
+ self._check_key_type(key)
+ return native_bt.value_map_has_key(self._ptr, key)
+
+ def _check_key_type(self, key):
+ utils._check_str(key)
+
+ def _check_key(self, key):
+ if key not in self:
+ raise KeyError(key)
+
+ def __getitem__(self, key):
+ self._check_key(key)
+ ptr = native_bt.value_map_get(self._ptr, key)
+ assert(ptr)
+ return _create_from_ptr(ptr)
+
+ def __iter__(self):
+ return _MapValueKeyIterator(self)
+
+ def __setitem__(self, key, value):
+ self._check_key_type(key)
+ value = create_value(value)
+
+ if value is None:
+ ptr = native_bt.value_null
+ else:
+ ptr = value._ptr
+
+ status = native_bt.value_map_insert(self._ptr, key, ptr)
+ self._handle_status(status)
+
+ def __str__(self):
+ strings = []
+
+ for key, elem in self.items():
+ if isinstance(elem, StringValue):
+ value = repr(elem.value)
+ else:
+ value = str(elem)
+
+ strings.append('{}: {}'.format(repr(key), value))
+
+ return '{{{}}}'.format(', '.join(strings))
+
+
+_TYPE_TO_OBJ = {
+ native_bt.VALUE_TYPE_BOOL: BoolValue,
+ native_bt.VALUE_TYPE_INTEGER: IntegerValue,
+ native_bt.VALUE_TYPE_FLOAT: FloatValue,
+ native_bt.VALUE_TYPE_STRING: StringValue,
+ native_bt.VALUE_TYPE_ARRAY: ArrayValue,
+ native_bt.VALUE_TYPE_MAP: MapValue,
+}
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import uuid as uuidp
-import numbers
-import bt2
-
-
-class ClockClassOffset:
- def __init__(self, seconds=0, cycles=0):
- utils._check_int64(seconds)
- utils._check_int64(cycles)
- self._seconds = seconds
- self._cycles = cycles
-
- @property
- def seconds(self):
- return self._seconds
-
- @property
- def cycles(self):
- return self._cycles
-
- def __hash__(self):
- return hash((self.seconds, self.cycles))
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- # not comparing apples to apples
- return False
-
- return (self.seconds, self.cycles) == (other.seconds, other.cycles)
-
-
-class ClockClass(object._Object):
- def __init__(self, name, frequency, description=None, precision=None,
- offset=None, is_absolute=None, uuid=None):
- utils._check_str(name)
- utils._check_uint64(frequency)
- ptr = native_bt.ctf_clock_class_create(name, frequency)
-
- if ptr is None:
- raise bt2.CreationError('cannot create clock class object')
-
- super().__init__(ptr)
-
- if description is not None:
- self.description = description
-
- if frequency is not None:
- self.frequency = frequency
-
- if precision is not None:
- self.precision = precision
-
- if offset is not None:
- self.offset = offset
-
- if is_absolute is not None:
- self.is_absolute = is_absolute
-
- if uuid is not None:
- self.uuid = uuid
-
- def __eq__(self, other):
- if type(self) is not type(other):
- # not comparing apples to apples
- return False
-
- self_props = (
- self.name,
- self.description,
- self.frequency,
- self.precision,
- self.offset,
- self.is_absolute,
- self.uuid
- )
- other_props = (
- other.name,
- other.description,
- other.frequency,
- other.precision,
- other.offset,
- other.is_absolute,
- other.uuid
- )
- return self_props == other_props
-
- def __copy__(self):
- return ClockClass(name=self.name, description=self.description,
- frequency=self.frequency, precision=self.precision,
- offset=self.offset, is_absolute=self.is_absolute,
- uuid=self.uuid)
-
- def __deepcopy__(self, memo):
- cpy = self.__copy__()
- memo[id(self)] = cpy
- return cpy
-
- def __hash__(self):
- return hash((
- self.name,
- self.description,
- self.frequency,
- self.precision,
- self.offset.seconds,
- self.offset.cycles,
- self.is_absolute,
- self.uuid))
-
- @property
- def name(self):
- name = native_bt.ctf_clock_class_get_name(self._ptr)
- assert(name is not None)
- return name
-
- @name.setter
- def name(self, name):
- utils._check_str(name)
- ret = native_bt.ctf_clock_class_set_name(self._ptr, name)
- utils._handle_ret(ret, "cannot set clock class object's name")
-
- @property
- def description(self):
- return native_bt.ctf_clock_class_get_description(self._ptr)
-
- @description.setter
- def description(self, description):
- utils._check_str(description)
- ret = native_bt.ctf_clock_class_set_description(self._ptr, description)
- utils._handle_ret(ret, "cannot set clock class object's description")
-
- @property
- def frequency(self):
- frequency = native_bt.ctf_clock_class_get_frequency(self._ptr)
- assert(frequency >= 1)
- return frequency
-
- @frequency.setter
- def frequency(self, frequency):
- utils._check_uint64(frequency)
- ret = native_bt.ctf_clock_class_set_frequency(self._ptr, frequency)
- utils._handle_ret(ret, "cannot set clock class object's frequency")
-
- @property
- def precision(self):
- precision = native_bt.ctf_clock_class_get_precision(self._ptr)
- assert(precision >= 0)
- return precision
-
- @precision.setter
- def precision(self, precision):
- utils._check_uint64(precision)
- ret = native_bt.ctf_clock_class_set_precision(self._ptr, precision)
- utils._handle_ret(ret, "cannot set clock class object's precision")
-
- @property
- def offset(self):
- ret, offset_s = native_bt.ctf_clock_class_get_offset_s(self._ptr)
- assert(ret == 0)
- ret, offset_cycles = native_bt.ctf_clock_class_get_offset_cycles(self._ptr)
- assert(ret == 0)
- return ClockClassOffset(offset_s, offset_cycles)
-
- @offset.setter
- def offset(self, offset):
- utils._check_type(offset, ClockClassOffset)
- ret = native_bt.ctf_clock_class_set_offset_s(self._ptr, offset.seconds)
- utils._handle_ret(ret, "cannot set clock class object's offset (seconds)")
- ret = native_bt.ctf_clock_class_set_offset_cycles(self._ptr, offset.cycles)
- utils._handle_ret(ret, "cannot set clock class object's offset (cycles)")
-
- @property
- def is_absolute(self):
- is_absolute = native_bt.ctf_clock_class_is_absolute(self._ptr)
- assert(is_absolute >= 0)
- return is_absolute > 0
-
- @is_absolute.setter
- def is_absolute(self, is_absolute):
- utils._check_bool(is_absolute)
- ret = native_bt.ctf_clock_class_set_is_absolute(self._ptr, int(is_absolute))
- utils._handle_ret(ret, "cannot set clock class object's absoluteness")
-
- @property
- def uuid(self):
- uuid_bytes = native_bt.ctf_clock_class_get_uuid(self._ptr)
-
- if uuid_bytes is None:
- return
-
- return uuidp.UUID(bytes=uuid_bytes)
-
- @uuid.setter
- def uuid(self, uuid):
- utils._check_type(uuid, uuidp.UUID)
- ret = native_bt.ctf_clock_class_set_uuid(self._ptr, uuid.bytes)
- utils._handle_ret(ret, "cannot set clock class object's UUID")
-
- def __call__(self, cycles):
- return _ClockValue(self._ptr, cycles)
-
-
-def _create_clock_value_from_ptr(ptr):
- clock_value = _ClockValue._create_from_ptr(ptr)
- return clock_value
-
-
-class _ClockValue(object._Object):
- def __init__(self, clock_class_ptr, cycles):
- utils._check_uint64(cycles)
- ptr = native_bt.ctf_clock_value_create(clock_class_ptr, cycles)
-
- if ptr is None:
- raise bt2.CreationError('cannot create clock value object')
-
- super().__init__(ptr)
-
- @property
- def clock_class(self):
- ptr = native_bt.ctf_clock_value_get_class(self._ptr)
- assert(ptr)
- return ClockClass._create_from_ptr(ptr)
-
- @property
- def cycles(self):
- ret, cycles = native_bt.ctf_clock_value_get_value(self._ptr)
- assert(ret == 0)
- return cycles
-
- @property
- def ns_from_epoch(self):
- ret, ns = native_bt.ctf_clock_value_get_value_ns_from_epoch(self._ptr)
- utils._handle_ret(ret, "cannot get clock value object's nanoseconds from Epoch")
- return ns
-
- def __eq__(self, other):
- if isinstance(other, numbers.Integral):
- return int(other) == self.cycles
-
- if not isinstance(other, self.__class__):
- # not comparing apples to apples
- return False
-
- if self.addr == other.addr:
- return True
-
- self_props = self.clock_class, self.cycles
- other_props = other.clock_class, other.cycles
- return self_props == other_props
-
- def __copy__(self):
- return self.clock_class(self.cycles)
-
- def __deepcopy__(self, memo):
- cpy = self.__copy__()
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import collections.abc
-import bt2.clock_class
-import copy
-import bt2
-
-
-class _ClockClassIterator(collections.abc.Iterator):
- def __init__(self, cc_prio_map):
- self._cc_prio_map = cc_prio_map
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._cc_prio_map):
- raise StopIteration
-
- cc_ptr = native_bt.clock_class_priority_map_get_clock_class_by_index(self._cc_prio_map._ptr,
- self._at)
- assert(cc_ptr)
- clock_class = bt2.ClockClass._create_from_ptr(cc_ptr)
- self._at += 1
- return clock_class
-
-
-class ClockClassPriorityMap(object._Object, collections.abc.MutableMapping):
- def __init__(self, clock_class_priorities=None):
- ptr = native_bt.clock_class_priority_map_create()
-
- if ptr is None:
- raise bt2.CreationError('cannot create clock class priority map object')
-
- super().__init__(ptr)
-
- if clock_class_priorities is not None:
- for clock_class, priority in clock_class_priorities.items():
- self[clock_class] = priority
-
- def __getitem__(self, key):
- utils._check_type(key, bt2.ClockClass)
- ret, prio = native_bt.clock_class_priority_map_get_clock_class_priority(self._ptr,
- key._ptr)
-
- if ret != 0:
- raise KeyError(key)
-
- return prio
-
- def __len__(self):
- count = native_bt.clock_class_priority_map_get_clock_class_count(self._ptr)
- assert(count >= 0)
- return count
-
- def __delitem__(self):
- raise NotImplementedError
-
- def __setitem__(self, key, value):
- utils._check_type(key, bt2.ClockClass)
- utils._check_uint64(value)
- ret = native_bt.clock_class_priority_map_add_clock_class(self._ptr,
- key._ptr,
- value)
- utils._handle_ret(ret, "cannot set clock class's priority in clock class priority map object")
-
- def __iter__(self):
- return _ClockClassIterator(self)
-
- @property
- def highest_priority_clock_class(self):
- cc_ptr = native_bt.clock_class_priority_map_get_highest_priority_clock_class(self._ptr)
-
- if cc_ptr is None:
- return
-
- return bt2.ClockClass._create_from_ptr(cc_ptr)
-
- def _get_prios(self):
- prios = {}
-
- for clock_class, prio in self.items():
- prios[clock_class] = prio
-
- return prios
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- if self.addr == other.addr:
- return True
-
- return self._get_prios() == other._get_prios()
-
- def _copy(self, cc_copy_func):
- cpy = ClockClassPriorityMap()
-
- for clock_class, prio in self.items():
- cpy[cc_copy_func(clock_class)] = prio
-
- return cpy
-
- def __copy__(self):
- return self._copy(lambda obj: obj)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.notification_iterator
-import collections.abc
-import bt2.values
-import traceback
-import bt2.port
-import sys
-import bt2
-import os
-
-
-_env_var = os.environ.get('BABELTRACE_PYTHON_BT2_NO_TRACEBACK')
-_NO_PRINT_TRACEBACK = _env_var == '1'
-
-
-# This class wraps a component class pointer. This component class could
-# have been created by Python code, but since we only have the pointer,
-# we can only wrap it in a generic way and lose the original Python
-# class.
-class _GenericComponentClass(object._Object):
- @property
- def name(self):
- name = native_bt.component_class_get_name(self._ptr)
- assert(name is not None)
- return name
-
- @property
- def description(self):
- return native_bt.component_class_get_description(self._ptr)
-
- @property
- def help(self):
- return native_bt.component_class_get_help(self._ptr)
-
- def query(self, obj, params=None):
- return _query(self._ptr, obj, params)
-
- def __eq__(self, other):
- if not isinstance(other, _GenericComponentClass):
- try:
- if not issubclass(other, _UserComponent):
- return False
- except TypeError:
- return False
-
- return self.addr == other.addr
-
-
-class _GenericSourceComponentClass(_GenericComponentClass):
- pass
-
-
-class _GenericFilterComponentClass(_GenericComponentClass):
- pass
-
-
-class _GenericSinkComponentClass(_GenericComponentClass):
- pass
-
-
-def _handle_component_status(status, gen_error_msg):
- if status == native_bt.COMPONENT_STATUS_END:
- raise bt2.Stop
- elif status == native_bt.COMPONENT_STATUS_AGAIN:
- raise bt2.TryAgain
- elif status == native_bt.COMPONENT_STATUS_UNSUPPORTED:
- raise bt2.UnsupportedFeature
- elif status == native_bt.COMPONENT_STATUS_REFUSE_PORT_CONNECTION:
- raise bt2.PortConnectionRefused
- elif status == native_bt.COMPONENT_STATUS_GRAPH_IS_CANCELED:
- raise bt2.GraphCanceled
- elif status < 0:
- raise bt2.Error(gen_error_msg)
-
-
-class _PortIterator(collections.abc.Iterator):
- def __init__(self, comp_ports):
- self._comp_ports = comp_ports
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._comp_ports):
- raise StopIteration
-
- comp_ports = self._comp_ports
- comp_ptr = comp_ports._component._ptr
- port_ptr = comp_ports._get_port_at_index_fn(comp_ptr, self._at)
- assert(port_ptr)
-
- if comp_ports._is_private:
- port_pub_ptr = native_bt.port_from_private_port(port_ptr)
- name = native_bt.port_get_name(port_pub_ptr)
- native_bt.put(port_pub_ptr)
- else:
- name = native_bt.port_get_name(port_ptr)
-
- assert(name is not None)
- native_bt.put(port_ptr)
- self._at += 1
- return name
-
-
-class _ComponentPorts(collections.abc.Mapping):
- def __init__(self, is_private, component,
- get_port_by_name_fn, get_port_at_index_fn,
- get_port_count_fn):
- self._is_private = is_private
- self._component = component
- self._get_port_by_name_fn = get_port_by_name_fn
- self._get_port_at_index_fn = get_port_at_index_fn
- self._get_port_count_fn = get_port_count_fn
-
- def __getitem__(self, key):
- utils._check_str(key)
- port_ptr = self._get_port_by_name_fn(self._component._ptr, key)
-
- if port_ptr is None:
- raise KeyError(key)
-
- if self._is_private:
- return bt2.port._create_private_from_ptr(port_ptr)
- else:
- return bt2.port._create_from_ptr(port_ptr)
-
- def __len__(self):
- if self._is_private:
- pub_ptr = native_bt.component_from_private_component(self._component._ptr)
- count = self._get_port_count_fn(pub_ptr)
- native_bt.put(pub_ptr)
- else:
- count = self._get_port_count_fn(self._component._ptr)
-
- assert(count >= 0)
- return count
-
- def __iter__(self):
- return _PortIterator(self)
-
-
-# This class holds the methods which are common to both generic
-# component objects and Python user component objects. They use the
-# internal native _ptr, however it was set, to call native API
-# functions.
-class _Component:
- @property
- def name(self):
- name = native_bt.component_get_name(self._ptr)
- assert(name is not None)
- return name
-
- @property
- def graph(self):
- ptr = native_bt.component_get_graph(self._ptr)
- assert(ptr)
- return bt2.Graph._create_from_ptr(ptr)
-
- @property
- def component_class(self):
- cc_ptr = native_bt.component_get_class(self._ptr)
- assert(cc_ptr)
- return _create_generic_component_class_from_ptr(cc_ptr)
-
- def __eq__(self, other):
- if not hasattr(other, 'addr'):
- return False
-
- return self.addr == other.addr
-
-
-class _SourceComponent(_Component):
- pass
-
-
-class _FilterComponent(_Component):
- pass
-
-
-class _SinkComponent(_Component):
- pass
-
-
-# This is analogous to _GenericSourceComponentClass, but for source
-# component objects.
-class _GenericSourceComponent(object._Object, _SourceComponent):
- @property
- def output_ports(self):
- return _ComponentPorts(False, self,
- native_bt.component_source_get_output_port_by_name,
- native_bt.component_source_get_output_port_by_index,
- native_bt.component_source_get_output_port_count)
-
-
-# This is analogous to _GenericFilterComponentClass, but for filter
-# component objects.
-class _GenericFilterComponent(object._Object, _FilterComponent):
- @property
- def output_ports(self):
- return _ComponentPorts(False, self,
- native_bt.component_filter_get_output_port_by_name,
- native_bt.component_filter_get_output_port_by_index,
- native_bt.component_filter_get_output_port_count)
-
- @property
- def input_ports(self):
- return _ComponentPorts(False, self,
- native_bt.component_filter_get_input_port_by_name,
- native_bt.component_filter_get_input_port_by_index,
- native_bt.component_filter_get_input_port_count)
-
-
-# This is analogous to _GenericSinkComponentClass, but for sink
-# component objects.
-class _GenericSinkComponent(object._Object, _SinkComponent):
- @property
- def input_ports(self):
- return _ComponentPorts(False, self,
- native_bt.component_sink_get_input_port_by_name,
- native_bt.component_sink_get_input_port_by_index,
- native_bt.component_sink_get_input_port_count)
-
-
-_COMP_CLS_TYPE_TO_GENERIC_COMP_PYCLS = {
- native_bt.COMPONENT_CLASS_TYPE_SOURCE: _GenericSourceComponent,
- native_bt.COMPONENT_CLASS_TYPE_FILTER: _GenericFilterComponent,
- native_bt.COMPONENT_CLASS_TYPE_SINK: _GenericSinkComponent,
-}
-
-
-_COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_PYCLS = {
- native_bt.COMPONENT_CLASS_TYPE_SOURCE: _GenericSourceComponentClass,
- native_bt.COMPONENT_CLASS_TYPE_FILTER: _GenericFilterComponentClass,
- native_bt.COMPONENT_CLASS_TYPE_SINK: _GenericSinkComponentClass,
-}
-
-
-def _create_generic_component_from_ptr(ptr):
- comp_cls_type = native_bt.component_get_class_type(ptr)
- return _COMP_CLS_TYPE_TO_GENERIC_COMP_PYCLS[comp_cls_type]._create_from_ptr(ptr)
-
-
-def _create_generic_component_class_from_ptr(ptr):
- comp_cls_type = native_bt.component_class_get_type(ptr)
- return _COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_PYCLS[comp_cls_type]._create_from_ptr(ptr)
-
-
-def _trim_docstring(docstring):
- lines = docstring.expandtabs().splitlines()
- indent = sys.maxsize
-
- for line in lines[1:]:
- stripped = line.lstrip()
-
- if stripped:
- indent = min(indent, len(line) - len(stripped))
-
- trimmed = [lines[0].strip()]
-
- if indent < sys.maxsize:
- for line in lines[1:]:
- trimmed.append(line[indent:].rstrip())
-
- while trimmed and not trimmed[-1]:
- trimmed.pop()
-
- while trimmed and not trimmed[0]:
- trimmed.pop(0)
-
- return '\n'.join(trimmed)
-
-
-def _query(comp_cls_ptr, obj, params):
- utils._check_str(obj)
-
- if params is None:
- params_ptr = native_bt.value_null
- else:
- params = bt2.create_value(params)
- params_ptr = params._ptr
-
- results_ptr = native_bt.component_class_query(comp_cls_ptr, obj,
- params_ptr)
-
- if results_ptr is None:
- raise bt2.Error('cannot query info with object "{}"'.format(obj))
-
- return bt2.values._create_from_ptr(results_ptr)
-
-
-# Metaclass for component classes defined by Python code.
-#
-# The Python user can create a standard Python class which inherits one
-# of the three base classes (_UserSourceComponent, _UserFilterComponent,
-# or _UserSinkComponent). Those base classes set this class
-# (_UserComponentType) as their metaclass.
-#
-# Once the body of a user-defined component class is executed, this
-# metaclass is used to create and initialize the class. The metaclass
-# creates a native BT component class of the corresponding type and
-# associates it with this user-defined class. The metaclass also defines
-# class methods like the `name` and `description` properties to match
-# the _GenericComponentClass interface.
-#
-# The component class name which is used is either:
-#
-# * The `name` parameter of the class:
-#
-# class MySink(bt2.SinkComponent, name='my-custom-sink'):
-# ...
-#
-# * If the `name` class parameter is not used: the name of the class
-# itself (`MySink` in the example above).
-#
-# The component class description which is used is the user-defined
-# class's docstring:
-#
-# class MySink(bt2.SinkComponent):
-# 'Description goes here'
-# ...
-#
-# A user-defined Python component class can have an __init__() method
-# which must at least accept the `params` and `name` arguments:
-#
-# def __init__(self, params, name, something_else):
-# ...
-#
-# The user-defined component class can also have a _finalize() method
-# (do NOT use __del__()) to be notified when the component object is
-# finalized.
-#
-# User-defined source and filter component classes must use the
-# `notification_iterator_class` class parameter to specify the
-# notification iterator class to use for this component class:
-#
-# class MyNotificationIterator(bt2._UserNotificationIterator):
-# ...
-#
-# class MySource(bt2._UserSourceComponent,
-# notification_iterator_class=MyNotificationIterator):
-# ...
-#
-# This notification iterator class must inherit
-# bt2._UserNotificationIterator, and it must define the _get() and
-# _next() methods. The notification iterator class can also define an
-# __init__() method: this method has access to the original Python
-# component object which was used to create it as the `component`
-# property. The notification iterator class can also define a
-# _finalize() method (again, do NOT use __del__()): this is called when
-# the notification iterator is (really) destroyed.
-#
-# When the user-defined class is destroyed, this metaclass's __del__()
-# method is called: the native BT component class pointer is put (not
-# needed anymore, at least not by any Python code since all references
-# are dropped for __del__() to be called).
-class _UserComponentType(type):
- # __new__() is used to catch custom class parameters
- def __new__(meta_cls, class_name, bases, attrs, **kwargs):
- return super().__new__(meta_cls, class_name, bases, attrs)
-
- def __init__(cls, class_name, bases, namespace, **kwargs):
- super().__init__(class_name, bases, namespace)
-
- # skip our own bases; they are never directly instantiated by the user
- own_bases = (
- '_UserComponent',
- '_UserFilterSinkComponent',
- '_UserSourceComponent',
- '_UserFilterComponent',
- '_UserSinkComponent',
- )
-
- if class_name in own_bases:
- return
-
- comp_cls_name = kwargs.get('name', class_name)
- utils._check_str(comp_cls_name)
- comp_cls_descr = None
- comp_cls_help = None
-
- if hasattr(cls, '__doc__') and cls.__doc__ is not None:
- utils._check_str(cls.__doc__)
- docstring = _trim_docstring(cls.__doc__)
- lines = docstring.splitlines()
-
- if len(lines) >= 1:
- comp_cls_descr = lines[0]
-
- if len(lines) >= 3:
- comp_cls_help = '\n'.join(lines[2:])
-
- iter_cls = kwargs.get('notification_iterator_class')
-
- if _UserSourceComponent in bases:
- _UserComponentType._set_iterator_class(cls, iter_cls)
- cc_ptr = native_bt.py3_component_class_source_create(cls,
- comp_cls_name,
- comp_cls_descr,
- comp_cls_help)
- elif _UserFilterComponent in bases:
- _UserComponentType._set_iterator_class(cls, iter_cls)
- cc_ptr = native_bt.py3_component_class_filter_create(cls,
- comp_cls_name,
- comp_cls_descr,
- comp_cls_help)
- elif _UserSinkComponent in bases:
- if not hasattr(cls, '_consume'):
- raise bt2.IncompleteUserClass("cannot create component class '{}': missing a _consume() method".format(class_name))
-
- cc_ptr = native_bt.py3_component_class_sink_create(cls,
- comp_cls_name,
- comp_cls_descr,
- comp_cls_help)
- else:
- raise bt2.IncompleteUserClass("cannot find a known component class base in the bases of '{}'".format(class_name))
-
- if cc_ptr is None:
- raise bt2.CreationError("cannot create component class '{}'".format(class_name))
-
- cls._cc_ptr = cc_ptr
-
- def _init_from_native(cls, comp_ptr, params_ptr):
- # create instance, not user-initialized yet
- self = cls.__new__(cls)
-
- # pointer to native private component object (weak/borrowed)
- self._ptr = comp_ptr
-
- # call user's __init__() method
- if params_ptr is not None:
- native_bt.get(params_ptr)
- params = bt2.values._create_from_ptr(params_ptr)
- else:
- params = None
-
- self.__init__(params)
- return self
-
- def __call__(cls, *args, **kwargs):
- raise bt2.Error('cannot directly instantiate a user component from a Python module')
-
- @staticmethod
- def _set_iterator_class(cls, iter_cls):
- if iter_cls is None:
- raise bt2.IncompleteUserClass("cannot create component class '{}': missing notification iterator class".format(cls.__name__))
-
- if not issubclass(iter_cls, bt2.notification_iterator._UserNotificationIterator):
- raise bt2.IncompleteUserClass("cannot create component class '{}': notification iterator class does not inherit bt2._UserNotificationIterator".format(cls.__name__))
-
- if not hasattr(iter_cls, '__next__'):
- raise bt2.IncompleteUserClass("cannot create component class '{}': notification iterator class is missing a __next__() method".format(cls.__name__))
-
- cls._iter_cls = iter_cls
-
- @property
- def name(cls):
- return native_bt.component_class_get_name(cls._cc_ptr)
-
- @property
- def description(cls):
- return native_bt.component_class_get_description(cls._cc_ptr)
-
- @property
- def help(cls):
- return native_bt.component_class_get_help(cls._cc_ptr)
-
- @property
- def addr(cls):
- return int(cls._cc_ptr)
-
- def query(cls, obj, params=None):
- return _query(cls._cc_ptr, obj, params)
-
- def _query_from_native(cls, obj, params_ptr):
- # this can raise, in which case the native call to
- # bt_component_class_query() returns NULL
- if params_ptr is not None:
- native_bt.get(params_ptr)
- params = bt2.values._create_from_ptr(params_ptr)
- else:
- params = None
-
- try:
- results = cls._query(obj, params)
- except:
- if not _NO_PRINT_TRACEBACK:
- traceback.print_exc()
-
- return
-
- if results is NotImplemented:
- return results
-
- try:
- results = bt2.create_value(results)
- except:
- if not _NO_PRINT_TRACEBACK:
- traceback.print_exc()
-
- return
-
- if results is None:
- results_addr = int(native_bt.value_null)
- else:
- # return new reference
- results._get()
- results_addr = int(results._ptr)
-
- return results_addr
-
- @classmethod
- def _query(cls, obj, params):
- # BT catches this and returns NULL to the user
- return NotImplemented
-
- def __eq__(self, other):
- if not hasattr(other, 'addr'):
- return False
-
- return self.addr == other.addr
-
- def __del__(cls):
- if hasattr(cls, '_cc_ptr'):
- native_bt.put(cls._cc_ptr)
-
-
-class _UserComponent(metaclass=_UserComponentType):
- @property
- def name(self):
- pub_ptr = native_bt.component_from_private_component(self._ptr)
- name = native_bt.component_get_name(pub_ptr)
- native_bt.put(pub_ptr)
- assert(name is not None)
- return name
-
- @property
- def graph(self):
- pub_ptr = native_bt.component_from_private_component(self._ptr)
- ptr = native_bt.component_get_graph(pub_ptr)
- native_bt.put(pub_ptr)
- assert(ptr)
- return bt2.Graph._create_from_ptr(ptr)
-
- @property
- def component_class(self):
- pub_ptr = native_bt.component_from_private_component(self._ptr)
- cc_ptr = native_bt.component_get_class(pub_ptr)
- native_bt.put(pub_ptr)
- assert(cc_ptr)
- return _create_generic_component_class_from_ptr(cc_ptr)
-
- @property
- def addr(self):
- return int(self._ptr)
-
- def __init__(self, params=None):
- pass
-
- def _finalize(self):
- pass
-
- def _accept_port_connection(self, port, other_port):
- return True
-
- def _accept_port_connection_from_native(self, port_ptr, other_port_ptr):
- native_bt.get(port_ptr)
- native_bt.get(other_port_ptr)
- port = bt2.port._create_private_from_ptr(port_ptr)
- other_port = bt2.port._create_from_ptr(other_port_ptr)
- res = self._accept_port_connection(port, other_port_ptr)
-
- if type(res) is not bool:
- raise TypeError("'{}' is not a 'bool' object")
-
- return res
-
- def _port_connected(self, port, other_port):
- pass
-
- def _port_connected_from_native(self, port_ptr, other_port_ptr):
- native_bt.get(port_ptr)
- native_bt.get(other_port_ptr)
- port = bt2.port._create_private_from_ptr(port_ptr)
- other_port = bt2.port._create_from_ptr(other_port_ptr)
-
- try:
- self._port_connected(port, other_port_ptr)
- except:
- if not _NO_PRINT_TRACEBACK:
- traceback.print_exc()
-
- def _port_disconnected(self, port):
- pass
-
- def _port_disconnected_from_native(self, port_ptr):
- native_bt.get(port_ptr)
- port = bt2.port._create_private_from_ptr(port_ptr)
-
- try:
- self._port_disconnected(port)
- except:
- if not _NO_PRINT_TRACEBACK:
- traceback.print_exc()
-
-
-class _UserSourceComponent(_UserComponent, _SourceComponent):
- @property
- def _output_ports(self):
- return _ComponentPorts(True, self,
- native_bt.private_component_source_get_output_private_port_by_name,
- native_bt.private_component_source_get_output_private_port_by_index,
- native_bt.component_source_get_output_port_count)
-
- def _add_output_port(self, name):
- utils._check_str(name)
- fn = native_bt.private_component_source_add_output_private_port
- comp_status, priv_port_ptr = fn(self._ptr, name, None)
- _handle_component_status(comp_status,
- 'cannot add output port to source component object')
- assert(priv_port_ptr)
- return bt2.port._create_private_from_ptr(priv_port_ptr)
-
-
-class _UserFilterComponent(_UserComponent, _FilterComponent):
- @property
- def _output_ports(self):
- return _ComponentPorts(True, self,
- native_bt.private_component_filter_get_output_private_port_by_name,
- native_bt.private_component_filter_get_output_private_port_by_index,
- native_bt.component_filter_get_output_port_count)
-
- @property
- def _input_ports(self):
- return _ComponentPorts(True, self,
- native_bt.private_component_filter_get_input_private_port_by_name,
- native_bt.private_component_filter_get_input_private_port_by_index,
- native_bt.component_filter_get_input_port_count)
-
- def _add_output_port(self, name):
- utils._check_str(name)
- fn = native_bt.private_component_filter_add_output_private_port
- comp_status, priv_port_ptr = fn(self._ptr, name, None)
- _handle_component_status(comp_status,
- 'cannot add output port to filter component object')
- assert(priv_port_ptr)
- return bt2.port._create_private_from_ptr(priv_port_ptr)
-
- def _add_input_port(self, name):
- utils._check_str(name)
- fn = native_bt.private_component_filter_add_input_private_port
- comp_status, priv_port_ptr = fn(self._ptr, name, None)
- _handle_component_status(comp_status,
- 'cannot add input port to filter component object')
- assert(priv_port_ptr)
- return bt2.port._create_private_from_ptr(priv_port_ptr)
-
-
-class _UserSinkComponent(_UserComponent, _SinkComponent):
- @property
- def _input_ports(self):
- return _ComponentPorts(True, self,
- native_bt.private_component_sink_get_input_private_port_by_name,
- native_bt.private_component_sink_get_input_private_port_by_index,
- native_bt.component_sink_get_input_port_count)
-
- def _add_input_port(self, name):
- utils._check_str(name)
- fn = native_bt.private_component_sink_add_input_private_port
- comp_status, priv_port_ptr = fn(self._ptr, name, None)
- _handle_component_status(comp_status,
- 'cannot add input port to sink component object')
- assert(priv_port_ptr)
- return bt2.port._create_private_from_ptr(priv_port_ptr)
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.notification_iterator
-import collections.abc
-import bt2.port
-import copy
-import bt2
-
-
-def _handle_status(status, gen_error_msg):
- if status == native_bt.CONNECTION_STATUS_GRAPH_IS_CANCELED:
- raise bt2.GraphCanceled
- elif status == native_bt.CONNECTION_STATUS_IS_ENDED:
- raise bt2.ConnectionEnded
- elif status < 0:
- raise bt2.Error(gen_error_msg)
-
-
-def _create_private_from_ptr(ptr):
- obj = _PrivateConnection._create_from_ptr(ptr)
- obj._pub_ptr = native_bt.connection_from_private_connection(ptr)
- assert(obj._pub_ptr)
- return obj
-
-
-class _Connection(object._Object):
- @staticmethod
- def _downstream_port(ptr):
- port_ptr = native_bt.connection_get_downstream_port(ptr)
- utils._handle_ptr(port_ptr, "cannot get connection object's downstream port object")
- return bt2.port._create_from_ptr(port_ptr)
-
- @staticmethod
- def _upstream_port(ptr):
- port_ptr = native_bt.connection_get_upstream_port(ptr)
- utils._handle_ptr(port_ptr, "cannot get connection object's upstream port object")
- return bt2.port._create_from_ptr(port_ptr)
-
- @property
- def downstream_port(self):
- return self._downstream_port(self._ptr)
-
- @property
- def upstream_port(self):
- return self._upstream_port(self._ptr)
-
- @staticmethod
- def _is_ended(ptr):
- return native_bt.connection_is_ended(ptr) == 1
-
- @property
- def is_ended(self):
- return self._is_ended(self._ptr)
-
- def __eq__(self, other):
- if type(other) not in (_Connection, _PrivateConnection):
- return False
-
- return self.addr == other.addr
-
-
-class _PrivateConnection(object._PrivateObject, _Connection):
- def create_notification_iterator(self, notification_types=None):
- if notification_types is None:
- notif_types = None
- else:
- for notif_cls in notification_types:
- if notif_cls not in bt2.notification._NOTIF_TYPE_TO_CLS.values():
- raise ValueError("'{}' is not a notification class".format(notif_cls))
-
- notif_types = [notif_cls._TYPE for notif_cls in notification_types]
-
- status, notif_iter_ptr = native_bt.py3_create_notif_iter(int(self._ptr),
- notif_types)
- _handle_status(status, 'cannot create notification iterator object')
- assert(notif_iter_ptr)
- return bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(notif_iter_ptr)
-
- @property
- def is_ended(self):
- return self._is_ended(self._pub_ptr)
-
- @property
- def downstream_port(self):
- return self._downstream_port(self._pub_ptr)
-
- @property
- def upstream_port(self):
- return self._upstream_port(self._pub_ptr)
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, stream, utils
-import uuid as uuidp
-import bt2.event
-import abc
-import bt2
-
-
-class CtfWriterClock(object._Object):
- def __init__(self, name, description=None, frequency=None, precision=None,
- offset=None, is_absolute=None, uuid=None):
- utils._check_str(name)
- ptr = native_bt.ctf_clock_create(name)
-
- if ptr is None:
- raise bt2.CreationError('cannot create CTF writer clock object')
-
- super().__init__(ptr)
-
- if description is not None:
- self.description = description
-
- if frequency is not None:
- self.frequency = frequency
-
- if precision is not None:
- self.precision = precision
-
- if offset is not None:
- self.offset = offset
-
- if is_absolute is not None:
- self.is_absolute = is_absolute
-
- if uuid is not None:
- self.uuid = uuid
-
- def __eq__(self, other):
- if type(self) is not type(other):
- # not comparing apples to apples
- return False
-
- if self.addr == other.addr:
- return True
-
- self_props = (
- self.name,
- self.description,
- self.frequency,
- self.precision,
- self.offset,
- self.is_absolute,
- self.uuid
- )
- other_props = (
- other.name,
- other.description,
- other.frequency,
- other.precision,
- other.offset,
- other.is_absolute,
- other.uuid
- )
- return self_props == other_props
-
- def __copy__(self):
- return CtfWriterClock(name=self.name, description=self.description,
- frequency=self.frequency,
- precision=self.precision, offset=self.offset,
- is_absolute=self.is_absolute, uuid=self.uuid)
-
- def __deepcopy__(self, memo):
- cpy = self.__copy__()
- memo[id(self)] = cpy
- return cpy
-
- @property
- def name(self):
- name = native_bt.ctf_clock_get_name(self._ptr)
- assert(name is not None)
- return name
-
- @property
- def description(self):
- description = native_bt.ctf_clock_get_description(self._ptr)
- return description
-
- @description.setter
- def description(self, description):
- utils._check_str(description)
- ret = native_bt.ctf_clock_set_description(self._ptr, description)
- utils._handle_ret(ret, "cannot set CTF writer clock object's description")
-
- @property
- def frequency(self):
- frequency = native_bt.ctf_clock_get_frequency(self._ptr)
- assert(frequency >= 1)
- return frequency
-
- @frequency.setter
- def frequency(self, frequency):
- utils._check_uint64(frequency)
- ret = native_bt.ctf_clock_set_frequency(self._ptr, frequency)
- utils._handle_ret(ret, "cannot set CTF writer clock object's frequency")
-
- @property
- def precision(self):
- precision = native_bt.ctf_clock_get_precision(self._ptr)
- assert(precision >= 0)
- return precision
-
- @precision.setter
- def precision(self, precision):
- utils._check_uint64(precision)
- ret = native_bt.ctf_clock_set_precision(self._ptr, precision)
- utils._handle_ret(ret, "cannot set CTF writer clock object's precision")
-
- @property
- def offset(self):
- ret, offset_s = native_bt.ctf_clock_get_offset_s(self._ptr)
- assert(ret == 0)
- ret, offset_cycles = native_bt.ctf_clock_get_offset(self._ptr)
- assert(ret == 0)
- return bt2.ClockClassOffset(offset_s, offset_cycles)
-
- @offset.setter
- def offset(self, offset):
- utils._check_type(offset, bt2.ClockClassOffset)
- ret = native_bt.ctf_clock_set_offset_s(self._ptr, offset.seconds)
- utils._handle_ret(ret, "cannot set CTF writer clock object's offset (seconds)")
- ret = native_bt.ctf_clock_set_offset(self._ptr, offset.cycles)
- utils._handle_ret(ret, "cannot set CTF writer clock object's offset (cycles)")
-
- @property
- def is_absolute(self):
- is_absolute = native_bt.ctf_clock_get_is_absolute(self._ptr)
- assert(is_absolute >= 0)
- return is_absolute > 0
-
- @is_absolute.setter
- def is_absolute(self, is_absolute):
- utils._check_bool(is_absolute)
- ret = native_bt.ctf_clock_set_is_absolute(self._ptr, int(is_absolute))
- utils._handle_ret(ret, "cannot set CTF writer clock object's absoluteness")
-
- @property
- def uuid(self):
- uuid_bytes = native_bt.ctf_clock_get_uuid(self._ptr)
- assert(uuid_bytes is not None)
- return uuidp.UUID(bytes=uuid_bytes)
-
- @uuid.setter
- def uuid(self, uuid):
- utils._check_type(uuid, uuidp.UUID)
- ret = native_bt.ctf_clock_set_uuid(self._ptr, uuid.bytes)
- utils._handle_ret(ret, "cannot set CTF writer clock object's UUID")
-
- def _time(self, time):
- utils._check_int64(time)
- ret = native_bt.ctf_clock_set_time(self._ptr, time)
-
- time = property(fset=_time)
-
-
-class _CtfWriterStream(stream._StreamBase):
- @property
- def discarded_events_count(self):
- ret, count = native_bt.ctf_stream_get_discarded_events_count(self._ptr)
- utils._handle_ret(ret, "cannot get CTF writer stream object's discarded events count")
- return count
-
- def append_discarded_events(self, count):
- utils._check_uint64(count)
- native_bt.ctf_stream_append_discarded_events(self._ptr, count)
-
- def append_event(self, event):
- utils._check_type(event, bt2.event._Event)
- ret = native_bt.ctf_stream_append_event(self._ptr, event._ptr)
- utils._handle_ret(ret, 'cannot append event object to CTF writer stream object')
-
- def flush(self):
- ret = native_bt.ctf_stream_flush(self._ptr)
- utils._handle_ret(ret, 'cannot cannot flush CTF writer stream object')
-
- @property
- def packet_header_field(self):
- field_ptr = native_bt.ctf_stream_get_packet_header(self._ptr)
-
- if field_ptr is None:
- return
-
- return fields._create_from_ptr(field_ptr)
-
- @packet_header_field.setter
- def packet_header_field(self, packet_header_field):
- packet_header_field_ptr = None
-
- if packet_header_field is not None:
- utils._check_type(packet_header_field, fields._Field)
- packet_header_field_ptr = packet_header_field._ptr
-
- ret = native_bt.ctf_stream_set_packet_header(self._ptr,
- packet_header_field_ptr)
- utils._handle_ret(ret, "cannot set CTF writer stream object's packet header field")
-
- @property
- def packet_context_field(self):
- field_ptr = native_bt.ctf_stream_get_packet_context(self._ptr)
-
- if field_ptr is None:
- return
-
- return fields._create_from_ptr(field_ptr)
-
- @packet_context_field.setter
- def packet_context_field(self, packet_context_field):
- packet_context_field_ptr = None
-
- if packet_context_field is not None:
- utils._check_type(packet_context_field, fields._Field)
- packet_context_field_ptr = packet_context_field._ptr
-
- ret = native_bt.ctf_stream_set_packet_context(self._ptr,
- packet_context_field_ptr)
- utils._handle_ret(ret, "cannot set CTF writer stream object's packet context field")
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- if self.addr == other.addr:
- return True
-
- if not _StreamBase.__eq__(self, other):
- return False
-
- self_props = (
- self.discarded_events_count,
- self.packet_header_field,
- self.packet_context_field,
- )
- other_props = (
- other.discarded_events_count,
- other.packet_header_field,
- other.packet_context_field,
- )
- return self_props == other_props
-
- def _copy(self, copy_func):
- cpy = self.stream_class(self.name)
- cpy.append_discarded_events(self.discarded_events_count)
- cpy.packet_header_field = copy_func(self.packet_header_field)
- cpy.packet_context_field = copy_func(self.packet_context_field)
- return cpy
-
- def __copy__(self):
- return self._copy(copy.copy)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
-
-
-class CtfWriter(object._Object):
- def __init__(self, path):
- utils._check_str(path)
- ptr = native_bt.ctf_writer_create(path)
-
- if ptr is None:
- raise bt2.CreationError('cannot create CTF writer object')
-
- super().__init__(ptr)
-
- @property
- def trace(self):
- trace_ptr = native_bt.ctf_writer_get_trace(self._ptr)
- assert(trace_ptr)
- return bt2.Trace._create_from_ptr(trace_ptr)
-
- @property
- def metadata_string(self):
- metadata_string = native_bt.ctf_writer_get_metadata_string(self._ptr)
- assert(metadata_string is not None)
- return metadata_string
-
- def flush_metadata(self):
- native_bt.ctf_writer_flush_metadata(self._ptr)
-
- def add_clock(self, clock):
- utils._check_type(clock, CtfWriterClock)
- ret = native_bt.ctf_writer_add_clock(self._ptr, clock._ptr)
- utils._handle_ret(ret, 'cannot add CTF writer clock object to CTF writer object')
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.clock_class
-import bt2.packet
-import bt2.stream
-import bt2.fields
-import numbers
-import copy
-import abc
-import bt2
-
-
-def _create_from_ptr(ptr):
- # recreate the event class wrapper of this event's class (the
- # identity could be different, but the underlying address should be
- # the same)
- event_class_ptr = native_bt.ctf_event_get_class(ptr)
- utils._handle_ptr(event_class_ptr, "cannot get event object's class")
- event_class = bt2.EventClass._create_from_ptr(event_class_ptr)
- event = _Event._create_from_ptr(ptr)
- event._event_class = event_class
- return event
-
-
-class _Event(object._Object):
- @property
- def event_class(self):
- return self._event_class
-
- @property
- def name(self):
- return self._event_class.name
-
- @property
- def id(self):
- return self._event_class.id
-
- @property
- def packet(self):
- packet_ptr = native_bt.ctf_event_get_packet(self._ptr)
-
- if packet_ptr is None:
- return packet_ptr
-
- return bt2.packet._Packet._create_from_ptr(packet_ptr)
-
- @packet.setter
- def packet(self, packet):
- utils._check_type(packet, bt2.packet._Packet)
- ret = native_bt.ctf_event_set_packet(self._ptr, packet._ptr)
- utils._handle_ret(ret, "cannot set event object's packet object")
-
- @property
- def stream(self):
- stream_ptr = native_bt.ctf_event_get_stream(self._ptr)
-
- if stream_ptr is None:
- return stream_ptr
-
- return bt2.stream._Stream._create_from_ptr(stream_ptr)
-
- @property
- def header_field(self):
- field_ptr = native_bt.ctf_event_get_header(self._ptr)
-
- if field_ptr is None:
- return
-
- return bt2.fields._create_from_ptr(field_ptr)
-
- @header_field.setter
- def header_field(self, header_field):
- header_field_ptr = None
-
- if header_field is not None:
- utils._check_type(header_field, bt2.fields._Field)
- header_field_ptr = header_field._ptr
-
- ret = native_bt.ctf_event_set_header(self._ptr, header_field_ptr)
- utils._handle_ret(ret, "cannot set event object's header field")
-
- @property
- def stream_event_context_field(self):
- field_ptr = native_bt.ctf_event_get_stream_event_context(self._ptr)
-
- if field_ptr is None:
- return
-
- return bt2.fields._create_from_ptr(field_ptr)
-
- @stream_event_context_field.setter
- def stream_event_context_field(self, stream_event_context):
- stream_event_context_ptr = None
-
- if stream_event_context is not None:
- utils._check_type(stream_event_context, bt2.fields._Field)
- stream_event_context_ptr = stream_event_context._ptr
-
- ret = native_bt.ctf_event_set_stream_event_context(self._ptr,
- stream_event_context_ptr)
- utils._handle_ret(ret, "cannot set event object's stream event context field")
-
- @property
- def context_field(self):
- field_ptr = native_bt.ctf_event_get_event_context(self._ptr)
-
- if field_ptr is None:
- return
-
- return bt2.fields._create_from_ptr(field_ptr)
-
- @context_field.setter
- def context_field(self, context):
- context_ptr = None
-
- if context is not None:
- utils._check_type(context, bt2.fields._Field)
- context_ptr = context._ptr
-
- ret = native_bt.ctf_event_set_event_context(self._ptr, context_ptr)
- utils._handle_ret(ret, "cannot set event object's context field")
-
- @property
- def payload_field(self):
- field_ptr = native_bt.ctf_event_get_event_payload(self._ptr)
-
- if field_ptr is None:
- return
-
- return bt2.fields._create_from_ptr(field_ptr)
-
- @payload_field.setter
- def payload_field(self, payload):
- payload_ptr = None
-
- if payload is not None:
- utils._check_type(payload, bt2.fields._Field)
- payload_ptr = payload._ptr
-
- ret = native_bt.ctf_event_set_event_payload(self._ptr, payload_ptr)
- utils._handle_ret(ret, "cannot set event object's payload field")
-
- def _get_clock_value_cycles(self, clock_class_ptr):
- clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
- clock_class_ptr)
-
- if clock_value_ptr is None:
- return
-
- ret, cycles = native_bt.ctf_clock_value_get_value(clock_value_ptr)
- native_bt.put(clock_value_ptr)
- utils._handle_ret(ret, "cannot get clock value object's cycles")
- return cycles
-
- def clock_value(self, clock_class):
- utils._check_type(clock_class, bt2.ClockClass)
- clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
- clock_class._ptr)
-
- if clock_value_ptr is None:
- return
-
- clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
- return clock_value
-
- def add_clock_value(self, clock_value):
- utils._check_type(clock_value, bt2.clock_class._ClockValue)
- ret = native_bt.ctf_event_set_clock_value(self._ptr,
- clock_value._ptr)
- utils._handle_ret(ret, "cannot set event object's clock value")
-
- def __getitem__(self, key):
- utils._check_str(key)
- payload_field = self.payload_field
-
- if payload_field is not None and key in payload_field:
- return payload_field[key]
-
- context_field = self.context_field
-
- if context_field is not None and key in context_field:
- return context_field[key]
-
- sec_field = self.stream_event_context_field
-
- if sec_field is not None and key in sec_field:
- return sec_field[key]
-
- header_field = self.header_field
-
- if header_field is not None and key in header_field:
- return header_field[key]
-
- packet = self.packet
-
- if packet is None:
- raise KeyError(key)
-
- pkt_context_field = packet.context_field
-
- if pkt_context_field is not None and key in pkt_context_field:
- return pkt_context_field[key]
-
- pkt_header_field = packet.header_field
-
- if pkt_header_field is not None and key in pkt_header_field:
- return pkt_header_field[key]
-
- raise KeyError(key)
-
- @property
- def _clock_classes(self):
- stream_class = self.event_class.stream_class
-
- if stream_class is None:
- return []
-
- trace = stream_class.trace
-
- if trace is None:
- return []
-
- clock_classes = []
-
- for clock_class in trace.clock_classes.values():
- clock_classes.append(clock_class)
-
- return clock_classes
-
- @property
- def _clock_class_ptrs(self):
- return [cc._ptr for cc in self._clock_classes]
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- if self.addr == other.addr:
- return True
-
- self_clock_values = {}
- other_clock_values = {}
-
- for clock_class_ptr in self._clock_class_ptrs:
- self_clock_values[int(clock_class_ptr)] = self._get_clock_value_cycles(clock_class_ptr)
-
- for clock_class_ptr in other._clock_class_ptrs:
- other_clock_values[int(clock_class_ptr)] = self._get_clock_value_cycles(clock_class_ptr)
-
- self_props = (
- self.header_field,
- self.stream_event_context_field,
- self.context_field,
- self.payload_field,
- self_clock_values,
- )
- other_props = (
- other.header_field,
- other.stream_event_context_field,
- other.context_field,
- other.payload_field,
- other_clock_values,
- )
- return self_props == other_props
-
- def _copy(self, copy_func):
- cpy = self.event_class()
-
- # copy fields
- cpy.header_field = copy_func(self.header_field)
- cpy.stream_event_context_field = copy_func(self.stream_event_context_field)
- cpy.context_field = copy_func(self.context_field)
- cpy.payload_field = copy_func(self.payload_field)
-
- # Copy known clock value references. It's not necessary to copy
- # clock class or clock value objects because once a clock value
- # is created from a clock class, the clock class is frozen.
- # Thus even if we copy the clock class, the user cannot modify
- # it, therefore it's useless to copy it.
- for clock_class in self._clock_classes:
- clock_value = self.clock_value(clock_class)
-
- if clock_value is not None:
- cpy.add_clock_value(clock_value)
-
- return cpy
-
- def __copy__(self):
- return self._copy(copy.copy)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.field_types
-import collections.abc
-import bt2.values
-import bt2.event
-import copy
-import bt2
-
-
-class EventClassLogLevel:
- UNKNOWN = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN
- UNSPECIFIED = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
- EMERGENCY = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY
- ALERT = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_ALERT
- CRITICAL = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL
- ERROR = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_ERROR
- WARNING = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_WARNING
- NOTICE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_NOTICE
- INFO = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_INFO
- DEBUG_SYSTEM = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
- DEBUG_PROGRAM = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
- DEBUG_PROCESS = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
- DEBUG_MODULE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
- DEBUG_UNIT = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
- DEBUG_FUNCTION = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
- DEBUG_LINE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
- DEBUG = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG
-
-
-class EventClass(object._Object):
- def __init__(self, name, id=None, log_level=None, emf_uri=None,
- context_field_type=None, payload_field_type=None):
- utils._check_str(name)
- ptr = native_bt.ctf_event_class_create(name)
-
- if ptr is None:
- raise bt2.CreationError('cannot create event class object')
-
- super().__init__(ptr)
-
- if id is not None:
- self.id = id
-
- if log_level is not None:
- self.log_level = log_level
-
- if emf_uri is not None:
- self.emf_uri = emf_uri
-
- if context_field_type is not None:
- self.context_field_type = context_field_type
-
- if payload_field_type is not None:
- self.payload_field_type = payload_field_type
-
- @property
- def stream_class(self):
- sc_ptr = native_bt.ctf_event_class_get_stream_class(self._ptr)
-
- if sc_ptr is not None:
- return bt2.StreamClass._create_from_ptr(sc_ptr)
-
- @property
- def name(self):
- return native_bt.ctf_event_class_get_name(self._ptr)
-
- @property
- def id(self):
- id = native_bt.ctf_event_class_get_id(self._ptr)
- return id if id >= 0 else None
-
- @id.setter
- def id(self, id):
- utils._check_int64(id)
- ret = native_bt.ctf_event_class_set_id(self._ptr, id)
- utils._handle_ret(ret, "cannot set event class object's ID")
-
- @property
- def log_level(self):
- log_level = native_bt.ctf_event_class_get_log_level(self._ptr)
- return log_level if log_level >= 0 else None
-
- @log_level.setter
- def log_level(self, log_level):
- log_levels = (
- EventClassLogLevel.UNSPECIFIED,
- EventClassLogLevel.EMERGENCY,
- EventClassLogLevel.ALERT,
- EventClassLogLevel.CRITICAL,
- EventClassLogLevel.ERROR,
- EventClassLogLevel.WARNING,
- EventClassLogLevel.NOTICE,
- EventClassLogLevel.INFO,
- EventClassLogLevel.DEBUG_SYSTEM,
- EventClassLogLevel.DEBUG_PROGRAM,
- EventClassLogLevel.DEBUG_PROCESS,
- EventClassLogLevel.DEBUG_MODULE,
- EventClassLogLevel.DEBUG_UNIT,
- EventClassLogLevel.DEBUG_FUNCTION,
- EventClassLogLevel.DEBUG_LINE,
- EventClassLogLevel.DEBUG,
- )
-
- if log_level not in log_levels:
- raise ValueError("'{}' is not a valid log level".format(log_level))
-
- ret = native_bt.ctf_event_class_set_log_level(self._ptr, log_level)
- utils._handle_ret(ret, "cannot set event class object's log level")
-
- @property
- def emf_uri(self):
- return native_bt.ctf_event_class_get_emf_uri(self._ptr)
-
- @emf_uri.setter
- def emf_uri(self, emf_uri):
- utils._check_str(emf_uri)
- ret = native_bt.ctf_event_class_set_emf_uri(self._ptr, emf_uri)
- utils._handle_ret(ret, "cannot set event class object's EMF URI")
-
- @property
- def context_field_type(self):
- ft_ptr = native_bt.ctf_event_class_get_context_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return bt2.field_types._create_from_ptr(ft_ptr)
-
- @context_field_type.setter
- def context_field_type(self, context_field_type):
- context_field_type_ptr = None
-
- if context_field_type is not None:
- utils._check_type(context_field_type, bt2.field_types._FieldType)
- context_field_type_ptr = context_field_type._ptr
-
- ret = native_bt.ctf_event_class_set_context_type(self._ptr, context_field_type_ptr)
- utils._handle_ret(ret, "cannot set event class object's context field type")
-
- @property
- def payload_field_type(self):
- ft_ptr = native_bt.ctf_event_class_get_payload_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return bt2.field_types._create_from_ptr(ft_ptr)
-
- @payload_field_type.setter
- def payload_field_type(self, payload_field_type):
- payload_field_type_ptr = None
-
- if payload_field_type is not None:
- utils._check_type(payload_field_type, bt2.field_types._FieldType)
- payload_field_type_ptr = payload_field_type._ptr
-
- ret = native_bt.ctf_event_class_set_payload_type(self._ptr, payload_field_type_ptr)
- utils._handle_ret(ret, "cannot set event class object's payload field type")
-
- def __call__(self):
- event_ptr = native_bt.ctf_event_create(self._ptr)
-
- if event_ptr is None:
- raise bt2.CreationError('cannot create event field object')
-
- return bt2.event._create_from_ptr(event_ptr)
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- if self.addr == other.addr:
- return True
-
- self_props = (
- self.name,
- self.id,
- self.log_level,
- self.emf_uri,
- self.context_field_type,
- self.payload_field_type
- )
- other_props = (
- other.name,
- other.id,
- other.log_level,
- other.emf_uri,
- other.context_field_type,
- other.payload_field_type
- )
- return self_props == other_props
-
- def _copy(self, ft_copy_func):
- cpy = EventClass(self.name)
- cpy.id = self.id
-
- if self.log_level is not None:
- cpy.log_level = self.log_level
-
- if self.emf_uri is not None:
- cpy.emf_uri = self.emf_uri
-
- cpy.context_field_type = ft_copy_func(self.context_field_type)
- cpy.payload_field_type = ft_copy_func(self.payload_field_type)
- return cpy
-
- def __copy__(self):
- return self._copy(lambda ft: ft)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import collections.abc
-import bt2.fields
-import abc
-import bt2
-
-
-def _create_from_ptr(ptr):
- typeid = native_bt.ctf_field_type_get_type_id(ptr)
- return _TYPE_ID_TO_OBJ[typeid]._create_from_ptr(ptr)
-
-
-class _FieldType(object._Object, metaclass=abc.ABCMeta):
- def __init__(self, ptr):
- super().__init__(ptr)
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- # not comparing apples to apples
- return False
-
- if self.addr == other.addr:
- return True
-
- ret = native_bt.ctf_field_type_compare(self._ptr, other._ptr)
- utils._handle_ret(ret, "cannot compare field types")
- return ret == 0
-
- def _check_create_status(self, ptr):
- if ptr is None:
- raise bt2.CreationError('cannot create {} field type object'.format(self._NAME.lower()))
-
- def __copy__(self):
- ptr = native_bt.ctf_field_type_copy(self._ptr)
- utils._handle_ptr(ptr, 'cannot copy {} field type object'.format(self._NAME.lower()))
- return _create_from_ptr(ptr)
-
- def __deepcopy__(self, memo):
- cpy = self.__copy__()
- memo[id(self)] = cpy
- return cpy
-
- def __call__(self, value=None):
- field_ptr = native_bt.ctf_field_create(self._ptr)
-
- if field_ptr is None:
- raise bt2.CreationError('cannot create {} field object'.format(self._NAME.lower()))
-
- field = bt2.fields._create_from_ptr(field_ptr)
-
- if value is not None:
- if not isinstance(field, (bt2.fields._IntegerField, bt2.fields._FloatingPointNumberField, bt2.fields._StringField)):
- raise bt2.Error('cannot assign an initial value to a {} field object'.format(field._NAME))
-
- field.value = value
-
- return field
-
-
-class ByteOrder:
- NATIVE = native_bt.CTF_BYTE_ORDER_NATIVE
- LITTLE_ENDIAN = native_bt.CTF_BYTE_ORDER_LITTLE_ENDIAN
- BIG_ENDIAN = native_bt.CTF_BYTE_ORDER_BIG_ENDIAN
- NETWORK = native_bt.CTF_BYTE_ORDER_NETWORK
-
-
-class Encoding:
- NONE = native_bt.CTF_STRING_ENCODING_NONE
- UTF8 = native_bt.CTF_STRING_ENCODING_UTF8
- ASCII = native_bt.CTF_STRING_ENCODING_ASCII
-
-
-class Base:
- BINARY = native_bt.CTF_INTEGER_BASE_BINARY
- OCTAL = native_bt.CTF_INTEGER_BASE_OCTAL
- DECIMAL = native_bt.CTF_INTEGER_BASE_DECIMAL
- HEXADECIMAL = native_bt.CTF_INTEGER_BASE_HEXADECIMAL
-
-
-class _AlignmentProp:
- @property
- def alignment(self):
- alignment = native_bt.ctf_field_type_get_alignment(self._ptr)
- assert(alignment >= 0)
- return alignment
-
- @alignment.setter
- def alignment(self, alignment):
- utils._check_alignment(alignment)
- ret = native_bt.ctf_field_type_set_alignment(self._ptr, alignment)
- utils._handle_ret(ret, "cannot set field type object's alignment")
-
-
-class _ByteOrderProp:
- @property
- def byte_order(self):
- bo = native_bt.ctf_field_type_get_byte_order(self._ptr)
- assert(bo >= 0)
- return bo
-
- @byte_order.setter
- def byte_order(self, byte_order):
- utils._check_int(byte_order)
- ret = native_bt.ctf_field_type_set_byte_order(self._ptr, byte_order)
- utils._handle_ret(ret, "cannot set field type object's byte order")
-
-
-class IntegerFieldType(_FieldType, _AlignmentProp, _ByteOrderProp):
- _NAME = 'Integer'
-
- def __init__(self, size, alignment=None, byte_order=None, is_signed=None,
- base=None, encoding=None, mapped_clock_class=None):
- utils._check_uint64(size)
-
- if size == 0:
- raise ValueError('size is 0 bits')
-
- ptr = native_bt.ctf_field_type_integer_create(size)
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- if alignment is not None:
- self.alignment = alignment
-
- if byte_order is not None:
- self.byte_order = byte_order
-
- if is_signed is not None:
- self.is_signed = is_signed
-
- if base is not None:
- self.base = base
-
- if encoding is not None:
- self.encoding = encoding
-
- if mapped_clock_class is not None:
- self.mapped_clock_class = mapped_clock_class
-
- @property
- def size(self):
- size = native_bt.ctf_field_type_integer_get_size(self._ptr)
- assert(size >= 1)
- return size
-
- @property
- def is_signed(self):
- is_signed = native_bt.ctf_field_type_integer_is_signed(self._ptr)
- assert(is_signed >= 0)
- return is_signed > 0
-
- @is_signed.setter
- def is_signed(self, is_signed):
- utils._check_bool(is_signed)
- ret = native_bt.ctf_field_type_integer_set_is_signed(self._ptr, int(is_signed))
- utils._handle_ret(ret, "cannot set integer field type object's signedness")
-
- @property
- def base(self):
- base = native_bt.ctf_field_type_integer_get_base(self._ptr)
- assert(base >= 0)
- return base
-
- @base.setter
- def base(self, base):
- utils._check_int(base)
- ret = native_bt.ctf_field_type_integer_set_base(self._ptr, base)
- utils._handle_ret(ret, "cannot set integer field type object's base")
-
- @property
- def encoding(self):
- encoding = native_bt.ctf_field_type_integer_get_encoding(self._ptr)
- assert(encoding >= 0)
- return encoding
-
- @encoding.setter
- def encoding(self, encoding):
- utils._check_int(encoding)
- ret = native_bt.ctf_field_type_integer_set_encoding(self._ptr, encoding)
- utils._handle_ret(ret, "cannot set integer field type object's encoding")
-
- @property
- def mapped_clock_class(self):
- ptr = native_bt.ctf_field_type_integer_get_mapped_clock_class(self._ptr)
-
- if ptr is None:
- return
-
- return bt2.ClockClass._create_from_ptr(ptr)
-
- @mapped_clock_class.setter
- def mapped_clock_class(self, clock_class):
- utils._check_type(clock_class, bt2.ClockClass)
- ret = native_bt.ctf_field_type_integer_set_mapped_clock_class(self._ptr, clock_class._ptr)
- utils._handle_ret(ret, "cannot set integer field type object's mapped clock class")
-
-
-class FloatingPointNumberFieldType(_FieldType, _AlignmentProp, _ByteOrderProp):
- _NAME = 'Floating point number'
-
- def __init__(self, alignment=None, byte_order=None, exponent_size=None,
- mantissa_size=None):
- ptr = native_bt.ctf_field_type_floating_point_create()
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- if alignment is not None:
- self.alignment = alignment
-
- if byte_order is not None:
- self.byte_order = byte_order
-
- if exponent_size is not None:
- self.exponent_size = exponent_size
-
- if mantissa_size is not None:
- self.mantissa_size = mantissa_size
-
- @property
- def exponent_size(self):
- exp_size = native_bt.ctf_field_type_floating_point_get_exponent_digits(self._ptr)
- assert(exp_size >= 0)
- return exp_size
-
- @exponent_size.setter
- def exponent_size(self, exponent_size):
- utils._check_uint64(exponent_size)
- ret = native_bt.ctf_field_type_floating_point_set_exponent_digits(self._ptr, exponent_size)
- utils._handle_ret(ret, "cannot set floating point number field type object's exponent size")
-
- @property
- def mantissa_size(self):
- mant_size = native_bt.ctf_field_type_floating_point_get_mantissa_digits(self._ptr)
- assert(mant_size >= 0)
- return mant_size
-
- @mantissa_size.setter
- def mantissa_size(self, mantissa_size):
- utils._check_uint64(mantissa_size)
- ret = native_bt.ctf_field_type_floating_point_set_mantissa_digits(self._ptr, mantissa_size)
- utils._handle_ret(ret, "cannot set floating point number field type object's mantissa size")
-
-
-class _EnumerationFieldTypeMapping:
- def __init__(self, name, lower, upper):
- self._name = name
- self._lower = lower
- self._upper = upper
-
- @property
- def name(self):
- return self._name
-
- @property
- def lower(self):
- return self._lower
-
- @property
- def upper(self):
- return self._upper
-
- def __eq__(self, other):
- if type(other) is not self.__class__:
- return False
-
- return (self.name, self.lower, self.upper) == (other.name, other.lower, other.upper)
-
-
-class _EnumerationFieldTypeMappingIterator(object._Object,
- collections.abc.Iterator):
- def __init__(self, iter_ptr, is_signed):
- super().__init__(iter_ptr)
- self._is_signed = is_signed
- self._done = (iter_ptr is None)
-
- def __next__(self):
- if self._done:
- raise StopIteration
-
- if self._is_signed:
- ret, name, lower, upper = native_bt.ctf_field_type_enumeration_mapping_iterator_get_signed(self._ptr)
- else:
- ret, name, lower, upper = native_bt.ctf_field_type_enumeration_mapping_iterator_get_unsigned(self._ptr)
-
- assert(ret == 0)
- mapping = _EnumerationFieldTypeMapping(name, lower, upper)
- ret = native_bt.ctf_field_type_enumeration_mapping_iterator_next(self._ptr)
-
- if ret < 0:
- self._done = True
-
- return mapping
-
-
-class EnumerationFieldType(IntegerFieldType, collections.abc.Sequence):
- _NAME = 'Enumeration'
-
- def __init__(self, int_field_type=None, size=None, alignment=None,
- byte_order=None, is_signed=None, base=None, encoding=None,
- mapped_clock_class=None):
- if int_field_type is None:
- int_field_type = IntegerFieldType(size=size, alignment=alignment,
- byte_order=byte_order,
- is_signed=is_signed, base=base,
- encoding=encoding,
- mapped_clock_class=mapped_clock_class)
-
- utils._check_type(int_field_type, IntegerFieldType)
- ptr = native_bt.ctf_field_type_enumeration_create(int_field_type._ptr)
- self._check_create_status(ptr)
- _FieldType.__init__(self, ptr)
-
- @property
- def integer_field_type(self):
- ptr = native_bt.ctf_field_type_enumeration_get_container_type(self._ptr)
- assert(ptr)
- return _create_from_ptr(ptr)
-
- @property
- def size(self):
- return self.integer_field_type.size
-
- @property
- def alignment(self):
- return self.integer_field_type.alignment
-
- @alignment.setter
- def alignment(self, alignment):
- self.integer_field_type.alignment = alignment
-
- @property
- def byte_order(self):
- return self.integer_field_type.byte_order
-
- @byte_order.setter
- def byte_order(self, byte_order):
- self.integer_field_type.byte_order = byte_order
-
- @property
- def is_signed(self):
- return self.integer_field_type.is_signed
-
- @is_signed.setter
- def is_signed(self, is_signed):
- self.integer_field_type.is_signed = is_signed
-
- @property
- def base(self):
- return self.integer_field_type.base
-
- @base.setter
- def base(self, base):
- self.integer_field_type.base = base
-
- @property
- def encoding(self):
- return self.integer_field_type.encoding
-
- @encoding.setter
- def encoding(self, encoding):
- self.integer_field_type.encoding = encoding
-
- @property
- def mapped_clock_class(self):
- return self.integer_field_type.mapped_clock_class
-
- @mapped_clock_class.setter
- def mapped_clock_class(self, mapped_clock_class):
- self.integer_field_type.mapped_clock_class = mapped_clock_class
-
- def __len__(self):
- count = native_bt.ctf_field_type_enumeration_get_mapping_count(self._ptr)
- assert(count >= 0)
- return count
-
- def __getitem__(self, index):
- utils._check_uint64(index)
-
- if index >= len(self):
- raise IndexError
-
- if self.is_signed:
- get_fn = native_bt.ctf_field_type_enumeration_get_mapping_signed
- else:
- get_fn = native_bt.ctf_field_type_enumeration_get_mapping_unsigned
-
- ret, name, lower, upper = get_fn(self._ptr, index)
- assert(ret == 0)
- return _EnumerationFieldTypeMapping(name, lower, upper)
-
- def _get_mapping_iter(self, iter_ptr):
- return _EnumerationFieldTypeMappingIterator(iter_ptr, self.is_signed)
-
- def mappings_by_name(self, name):
- utils._check_str(name)
- iter_ptr = native_bt.ctf_field_type_enumeration_find_mappings_by_name(self._ptr, name)
- return self._get_mapping_iter(iter_ptr)
-
- def mappings_by_value(self, value):
- if self.is_signed:
- utils._check_int64(value)
- iter_ptr = native_bt.ctf_field_type_enumeration_find_mappings_by_signed_value(self._ptr, value)
- else:
- utils._check_uint64(value)
- iter_ptr = native_bt.ctf_field_type_enumeration_find_mappings_by_unsigned_value(self._ptr, value)
-
- return self._get_mapping_iter(iter_ptr)
-
- def append_mapping(self, name, lower, upper=None):
- utils._check_str(name)
-
- if upper is None:
- upper = lower
-
- if self.is_signed:
- add_fn = native_bt.ctf_field_type_enumeration_add_mapping_signed
- utils._check_int64(lower)
- utils._check_int64(upper)
- else:
- add_fn = native_bt.ctf_field_type_enumeration_add_mapping_unsigned
- utils._check_uint64(lower)
- utils._check_uint64(upper)
-
- ret = add_fn(self._ptr, name, lower, upper)
- utils._handle_ret(ret, "cannot add mapping to enumeration field type object")
-
- def __iadd__(self, mappings):
- for mapping in mappings:
- self.append_mapping(mapping.name, mapping.lower, mapping.upper)
-
- return self
-
-
-class StringFieldType(_FieldType):
- _NAME = 'String'
-
- def __init__(self, encoding=None):
- ptr = native_bt.ctf_field_type_string_create()
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- if encoding is not None:
- self.encoding = encoding
-
- @property
- def encoding(self):
- encoding = native_bt.ctf_field_type_string_get_encoding(self._ptr)
- assert(encoding >= 0)
- return encoding
-
- @encoding.setter
- def encoding(self, encoding):
- utils._check_int(encoding)
- ret = native_bt.ctf_field_type_string_set_encoding(self._ptr, encoding)
- utils._handle_ret(ret, "cannot set string field type object's encoding")
-
-
-class _FieldContainer(collections.abc.Mapping):
- def __len__(self):
- count = self._count()
- assert(count >= 0)
- return count
-
- def __getitem__(self, key):
- if not isinstance(key, str):
- raise TypeError("'{}' is not a 'str' object".format(key.__class__.__name__))
-
- ptr = self._get_field_by_name(key)
-
- if ptr is None:
- raise KeyError(key)
-
- return _create_from_ptr(ptr)
-
- def __iter__(self):
- return self._ITER_CLS(self)
-
- def append_field(self, name, field_type):
- utils._check_str(name)
- utils._check_type(field_type, _FieldType)
- ret = self._add_field(field_type._ptr, name)
- utils._handle_ret(ret, "cannot add field to {} field type object".format(self._NAME.lower()))
-
- def __iadd__(self, fields):
- for name, field_type in fields.items():
- self.append_field(name, field_type)
-
- return self
-
- def at_index(self, index):
- utils._check_uint64(index)
- return self._at(index)
-
-
-class _StructureFieldTypeFieldIterator(collections.abc.Iterator):
- def __init__(self, struct_field_type):
- self._struct_field_type = struct_field_type
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._struct_field_type):
- raise StopIteration
-
- get_ft_by_index = native_bt.ctf_field_type_structure_get_field_by_index
- ret, name, field_type_ptr = get_ft_by_index(self._struct_field_type._ptr,
- self._at)
- assert(ret == 0)
- native_bt.put(field_type_ptr)
- self._at += 1
- return name
-
-
-class StructureFieldType(_FieldType, _FieldContainer, _AlignmentProp):
- _NAME = 'Structure'
- _ITER_CLS = _StructureFieldTypeFieldIterator
-
- def __init__(self, min_alignment=None):
- ptr = native_bt.ctf_field_type_structure_create()
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- if min_alignment is not None:
- self.min_alignment = min_alignment
-
- def _count(self):
- return native_bt.ctf_field_type_structure_get_field_count(self._ptr)
-
- def _get_field_by_name(self, key):
- return native_bt.ctf_field_type_structure_get_field_type_by_name(self._ptr, key)
-
- def _add_field(self, ptr, name):
- return native_bt.ctf_field_type_structure_add_field(self._ptr, ptr,
- name)
-
- def _at(self, index):
- if index < 0 or index >= len(self):
- raise IndexError
-
- ret, name, field_type_ptr = native_bt.ctf_field_type_structure_get_field_by_index(self._ptr, index)
- assert(ret == 0)
- return _create_from_ptr(field_type_ptr)
-
-
-StructureFieldType.min_alignment = property(fset=StructureFieldType.alignment.fset)
-StructureFieldType.alignment = property(fget=StructureFieldType.alignment.fget)
-
-
-class _VariantFieldTypeFieldIterator(collections.abc.Iterator):
- def __init__(self, variant_field_type):
- self._variant_field_type = variant_field_type
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._variant_field_type):
- raise StopIteration
-
- ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field_by_index(self._variant_field_type._ptr,
- self._at)
- assert(ret == 0)
- native_bt.put(field_type_ptr)
- self._at += 1
- return name
-
-
-class VariantFieldType(_FieldType, _FieldContainer, _AlignmentProp):
- _NAME = 'Variant'
- _ITER_CLS = _VariantFieldTypeFieldIterator
-
- def __init__(self, tag_name, tag_field_type=None):
- utils._check_str(tag_name)
-
- if tag_field_type is None:
- tag_ft_ptr = None
- else:
- utils._check_type(tag_field_type, EnumerationFieldType)
- tag_ft_ptr = tag_field_type._ptr
-
- ptr = native_bt.ctf_field_type_variant_create(tag_ft_ptr,
- tag_name)
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- @property
- def tag_name(self):
- tag_name = native_bt.ctf_field_type_variant_get_tag_name(self._ptr)
- assert(tag_name is not None)
- return tag_name
-
- @tag_name.setter
- def tag_name(self, tag_name):
- utils._check_str(tag_name)
- ret = native_bt.ctf_field_type_variant_set_tag_name(self._ptr, tag_name)
- utils._handle_ret(ret, "cannot set variant field type object's tag name")
-
- @property
- def tag_field_type(self):
- ft_ptr = native_bt.ctf_field_type_variant_get_tag_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return _create_from_ptr(ft_ptr)
-
- def _count(self):
- return native_bt.ctf_field_type_variant_get_field_count(self._ptr)
-
- def _get_field_by_name(self, key):
- return native_bt.ctf_field_type_variant_get_field_type_by_name(self._ptr, key)
-
- def _add_field(self, ptr, name):
- return native_bt.ctf_field_type_variant_add_field(self._ptr, ptr, name)
-
- def _at(self, index):
- if index < 0 or index >= len(self):
- raise IndexError
-
- ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field_by_index(self._ptr, index)
- assert(ret == 0)
- return _create_from_ptr(field_type_ptr)
-
-
-class ArrayFieldType(_FieldType):
- _NAME = 'Array'
-
- def __init__(self, element_field_type, length):
- utils._check_type(element_field_type, _FieldType)
- utils._check_uint64(length)
- ptr = native_bt.ctf_field_type_array_create(element_field_type._ptr, length)
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- @property
- def length(self):
- length = native_bt.ctf_field_type_array_get_length(self._ptr)
- assert(length >= 0)
- return length
-
- @property
- def element_field_type(self):
- ptr = native_bt.ctf_field_type_array_get_element_type(self._ptr)
- assert(ptr)
- return _create_from_ptr(ptr)
-
-
-class SequenceFieldType(_FieldType):
- _NAME = 'Sequence'
-
- def __init__(self, element_field_type, length_name):
- utils._check_type(element_field_type, _FieldType)
- utils._check_str(length_name)
- ptr = native_bt.ctf_field_type_sequence_create(element_field_type._ptr,
- length_name)
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- @property
- def length_name(self):
- length_name = native_bt.ctf_field_type_sequence_get_length_field_name(self._ptr)
- assert(length_name is not None)
- return length_name
-
- @property
- def element_field_type(self):
- ptr = native_bt.ctf_field_type_sequence_get_element_type(self._ptr)
- assert(ptr)
- return _create_from_ptr(ptr)
-
-
-_TYPE_ID_TO_OBJ = {
- native_bt.CTF_FIELD_TYPE_ID_INTEGER: IntegerFieldType,
- native_bt.CTF_FIELD_TYPE_ID_FLOAT: FloatingPointNumberFieldType,
- native_bt.CTF_FIELD_TYPE_ID_ENUM: EnumerationFieldType,
- native_bt.CTF_FIELD_TYPE_ID_STRING: StringFieldType,
- native_bt.CTF_FIELD_TYPE_ID_STRUCT: StructureFieldType,
- native_bt.CTF_FIELD_TYPE_ID_ARRAY: ArrayFieldType,
- native_bt.CTF_FIELD_TYPE_ID_SEQUENCE: SequenceFieldType,
- native_bt.CTF_FIELD_TYPE_ID_VARIANT: VariantFieldType,
-}
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.field_types
-import collections.abc
-import functools
-import numbers
-import math
-import abc
-import bt2
-
-
-def _create_from_ptr(ptr):
- # recreate the field type wrapper of this field's type (the identity
- # could be different, but the underlying address should be the
- # same)
- field_type_ptr = native_bt.ctf_field_get_type(ptr)
- utils._handle_ptr(field_type_ptr, "cannot get field object's type")
- field_type = bt2.field_types._create_from_ptr(field_type_ptr)
- typeid = native_bt.ctf_field_type_get_type_id(field_type._ptr)
- field = _TYPE_ID_TO_OBJ[typeid]._create_from_ptr(ptr)
- field._field_type = field_type
- return field
-
-
-class _Field(object._Object, metaclass=abc.ABCMeta):
- def __copy__(self):
- ptr = native_bt.ctf_field_copy(self._ptr)
- utils._handle_ptr(ptr, 'cannot copy {} field object'.format(self._NAME.lower()))
- return _create_from_ptr(ptr)
-
- def __deepcopy__(self, memo):
- cpy = self.__copy__()
- memo[id(self)] = cpy
- return cpy
-
- @property
- def field_type(self):
- return self._field_type
-
-
-@functools.total_ordering
-class _NumericField(_Field):
- @staticmethod
- def _extract_value(other):
- if other is True or other is False:
- return other
-
- if isinstance(other, numbers.Integral):
- return int(other)
-
- if isinstance(other, numbers.Real):
- return float(other)
-
- if isinstance(other, numbers.Complex):
- return complex(other)
-
- raise TypeError("'{}' object is not a number object".format(other.__class__.__name__))
-
- def __int__(self):
- return int(self.value)
-
- def __float__(self):
- return float(self.value)
-
- def __str__(self):
- return str(self.value)
-
- def __lt__(self, other):
- if not isinstance(other, numbers.Number):
- raise TypeError('unorderable types: {}() < {}()'.format(self.__class__.__name__,
- other.__class__.__name__))
-
- return self.value < float(other)
-
- def __le__(self, other):
- if not isinstance(other, numbers.Number):
- raise TypeError('unorderable types: {}() <= {}()'.format(self.__class__.__name__,
- other.__class__.__name__))
-
- return self.value <= float(other)
-
- def __eq__(self, other):
- if not isinstance(other, numbers.Number):
- return False
-
- return self.value == complex(other)
-
- def __rmod__(self, other):
- return self._extract_value(other) % self.value
-
- def __mod__(self, other):
- return self.value % self._extract_value(other)
-
- def __rfloordiv__(self, other):
- return self._extract_value(other) // self.value
-
- def __floordiv__(self, other):
- return self.value // self._extract_value(other)
-
- def __round__(self, ndigits=None):
- if ndigits is None:
- return round(self.value)
- else:
- return round(self.value, ndigits)
-
- def __ceil__(self):
- return math.ceil(self.value)
-
- def __floor__(self):
- return math.floor(self.value)
-
- def __trunc__(self):
- return int(self.value)
-
- def __abs__(self):
- return abs(self.value)
-
- def __add__(self, other):
- return self.value + self._extract_value(other)
-
- def __radd__(self, other):
- return self.__add__(other)
-
- def __neg__(self):
- return -self.value
-
- def __pos__(self):
- return +self.value
-
- def __mul__(self, other):
- return self.value * self._extract_value(other)
-
- def __rmul__(self, other):
- return self.__mul__(other)
-
- def __truediv__(self, other):
- return self.value / self._extract_value(other)
-
- def __rtruediv__(self, other):
- return self._extract_value(other) / self.value
-
- def __pow__(self, exponent):
- return self.value ** self._extract_value(exponent)
-
- def __rpow__(self, base):
- return self._extract_value(base) ** self.value
-
- def __iadd__(self, other):
- self.value = self + other
- return self
-
- def __isub__(self, other):
- self.value = self - other
- return self
-
- def __imul__(self, other):
- self.value = self * other
- return self
-
- def __itruediv__(self, other):
- self.value = self / other
- return self
-
- def __ifloordiv__(self, other):
- self.value = self // other
- return self
-
- def __imod__(self, other):
- self.value = self % other
- return self
-
- def __ipow__(self, other):
- self.value = self ** other
- return self
-
-
-class _IntegralField(_NumericField, numbers.Integral):
- def __lshift__(self, other):
- return self.value << self._extract_value(other)
-
- def __rlshift__(self, other):
- return self._extract_value(other) << self.value
-
- def __rshift__(self, other):
- return self.value >> self._extract_value(other)
-
- def __rrshift__(self, other):
- return self._extract_value(other) >> self.value
-
- def __and__(self, other):
- return self.value & self._extract_value(other)
-
- def __rand__(self, other):
- return self._extract_value(other) & self.value
-
- def __xor__(self, other):
- return self.value ^ self._extract_value(other)
-
- def __rxor__(self, other):
- return self._extract_value(other) ^ self.value
-
- def __or__(self, other):
- return self.value | self._extract_value(other)
-
- def __ror__(self, other):
- return self._extract_value(other) | self.value
-
- def __invert__(self):
- return ~self.value
-
- def __ilshift__(self, other):
- self.value = self << other
- return self
-
- def __irshift__(self, other):
- self.value = self >> other
- return self
-
- def __iand__(self, other):
- self.value = self & other
- return self
-
- def __ixor__(self, other):
- self.value = self ^ other
- return self
-
- def __ior__(self, other):
- self.value = self | other
- return self
-
-
-class _RealField(_NumericField, numbers.Real):
- pass
-
-
-class _IntegerField(_IntegralField):
- _NAME = 'Integer'
-
- def _value_to_int(self, value):
- if not isinstance(value, numbers.Real):
- raise TypeError('expecting a real number object')
-
- value = int(value)
-
- if self.field_type.is_signed:
- utils._check_int64(value)
- else:
- utils._check_uint64(value)
-
- return value
-
- @property
- def value(self):
- if self.field_type.is_signed:
- ret, value = native_bt.ctf_field_signed_integer_get_value(self._ptr)
- else:
- ret, value = native_bt.ctf_field_unsigned_integer_get_value(self._ptr)
-
- if ret < 0:
- # field is not set
- return
-
- return value
-
- @value.setter
- def value(self, value):
- value = self._value_to_int(value)
-
- if self.field_type.is_signed:
- ret = native_bt.ctf_field_signed_integer_set_value(self._ptr, value)
- else:
- ret = native_bt.ctf_field_unsigned_integer_set_value(self._ptr, value)
-
- utils._handle_ret(ret, "cannot set integer field object's value")
-
-
-class _FloatingPointNumberField(_RealField):
- _NAME = 'Floating point number'
-
- def _value_to_float(self, value):
- if not isinstance(value, numbers.Real):
- raise TypeError("expecting a real number object")
-
- return float(value)
-
- @property
- def value(self):
- ret, value = native_bt.ctf_field_floating_point_get_value(self._ptr)
-
- if ret < 0:
- # field is not set
- return
-
- return value
-
- @value.setter
- def value(self, value):
- value = self._value_to_float(value)
- ret = native_bt.ctf_field_floating_point_set_value(self._ptr, value)
- utils._handle_ret(ret, "cannot set floating point number field object's value")
-
-
-class _EnumerationField(_IntegerField):
- _NAME = 'Enumeration'
-
- @property
- def integer_field(self):
- int_field_ptr = native_bt.ctf_field_enumeration_get_container(self._ptr)
- assert(int_field_ptr)
- return _create_from_ptr(int_field_ptr)
-
- @property
- def value(self):
- return self.integer_field.value
-
- @value.setter
- def value(self, value):
- self.integer_field.value = value
-
- @property
- def mappings(self):
- iter_ptr = native_bt.ctf_field_enumeration_get_mappings(self._ptr)
- assert(iter_ptr)
- return bt2.field_types._EnumerationFieldTypeMappingIterator(iter_ptr,
- self.field_type.is_signed)
-
-
-@functools.total_ordering
-class _StringField(_Field, collections.abc.Sequence):
- _NAME = 'String'
-
- def _value_to_str(self, value):
- if isinstance(value, self.__class__):
- value = value.value
-
- if not isinstance(value, str):
- raise TypeError("expecting a 'str' object")
-
- return value
-
- @property
- def value(self):
- value = native_bt.ctf_field_string_get_value(self._ptr)
-
- if value is None:
- # field is not set
- return
-
- return value
-
- @value.setter
- def value(self, value):
- value = self._value_to_str(value)
- ret = native_bt.ctf_field_string_set_value(self._ptr, value)
- utils._handle_ret(ret, "cannot set string field object's value")
-
- def __eq__(self, other):
- try:
- other = self._value_to_str(other)
- except:
- return False
-
- return self.value == other
-
- def __le__(self, other):
- return self.value <= self._value_to_str(other)
-
- def __lt__(self, other):
- return self.value < self._value_to_str(other)
-
- def __bool__(self):
- return bool(self.value)
-
- def __str__(self):
- return self.value
-
- def __getitem__(self, index):
- return self.value[index]
-
- def __len__(self):
- return len(self.value)
-
- def __iadd__(self, value):
- value = self._value_to_str(value)
- ret = native_bt.ctf_field_string_append(self._ptr, value)
- utils._handle_ret(ret, "cannot append to string field object's value")
- return self
-
-
-class _ContainerField(_Field):
- def __bool__(self):
- return len(self) != 0
-
- def __len__(self):
- count = self._count()
- assert(count >= 0)
- return count
-
- def __delitem__(self, index):
- raise NotImplementedError
-
-
-class _StructureField(_ContainerField, collections.abc.MutableMapping):
- _NAME = 'Structure'
-
- def _count(self):
- return len(self.field_type)
-
- def __getitem__(self, key):
- utils._check_str(key)
- ptr = native_bt.ctf_field_structure_get_field_by_name(self._ptr, key)
-
- if ptr is None:
- raise KeyError(key)
-
- return _create_from_ptr(ptr)
-
- def __setitem__(self, key, value):
- # we can only set numbers and strings
- if not isinstance(value, (numbers.Number, str)):
- raise TypeError('expecting number object or string')
-
- # raises if index is somehow invalid
- field = self[key]
-
- if not isinstance(field, (_NumericField, _StringField)):
- raise TypeError('can only set the value of a number or string field')
-
- # the field's property does the appropriate conversion or raises
- # the appropriate exception
- field.value = value
-
- def at_index(self, index):
- utils._check_uint64(index)
-
- if index >= len(self):
- raise IndexError
-
- field_ptr = native_bt.ctf_field_structure_get_field_by_index(self._ptr, index)
- assert(field_ptr)
- return _create_from_ptr(field_ptr)
-
- def __iter__(self):
- # same name iterator
- return iter(self.field_type)
-
- def __eq__(self, other):
- if not isinstance(other, collections.abc.Mapping):
- return False
-
- if len(self) != len(other):
- return False
-
- for self_key, self_value in self.items():
- if self_key not in other:
- return False
-
- other_value = other[self_key]
-
- if self_value != other_value:
- return False
-
- return True
-
-
-class _VariantField(_Field):
- _NAME = 'Variant'
-
- @property
- def tag_field(self):
- field_ptr = native_bt.ctf_field_variant_get_tag(self._ptr)
-
- if field_ptr is None:
- return
-
- return _create_from_ptr(field_ptr)
-
- @property
- def selected_field(self):
- return self.field()
-
- def field(self, tag_field=None):
- if tag_field is None:
- field_ptr = native_bt.ctf_field_variant_get_current_field(self._ptr)
-
- if field_ptr is None:
- return
- else:
- utils._check_type(tag_field, _EnumerationField)
- field_ptr = native_bt.ctf_field_variant_get_field(self._ptr, tag_field._ptr)
- utils._handle_ptr(field_ptr, "cannot select variant field object's field")
-
- return _create_from_ptr(field_ptr)
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- if self.addr == other.addr:
- return True
-
- return self.selected_field == other.selected_field
-
- def __bool__(self):
- return bool(self.selected_field)
-
-
-class _ArraySequenceField(_ContainerField, collections.abc.MutableSequence):
- def __getitem__(self, index):
- if not isinstance(index, numbers.Integral):
- raise TypeError("'{}' is not an integral number object: invalid index".format(index.__class__.__name__))
-
- index = int(index)
-
- if index < 0 or index >= len(self):
- raise IndexError('{} field object index is out of range'.format(self._NAME))
-
- field_ptr = self._get_field_ptr_at_index(index)
- assert(field_ptr)
- return _create_from_ptr(field_ptr)
-
- def __setitem__(self, index, value):
- # we can only set numbers and strings
- if not isinstance(value, (numbers.Number, _StringField, str)):
- raise TypeError('expecting number or string object')
-
- # raises if index is somehow invalid
- field = self[index]
-
- if not isinstance(field, (_NumericField, _StringField)):
- raise TypeError('can only set the value of a number or string field')
-
- # the field's property does the appropriate conversion or raises
- # the appropriate exception
- field.value = value
-
- def insert(self, index, value):
- raise NotImplementedError
-
- def __eq__(self, other):
- if not isinstance(other, collections.abc.Sequence):
- return False
-
- if len(self) != len(other):
- return False
-
- for self_field, other_field in zip(self, other):
- if self_field != other_field:
- return False
-
- return True
-
-
-class _ArrayField(_ArraySequenceField):
- _NAME = 'Array'
-
- def _count(self):
- return self.field_type.length
-
- def _get_field_ptr_at_index(self, index):
- return native_bt.ctf_field_array_get_field(self._ptr, index)
-
-
-class _SequenceField(_ArraySequenceField):
- _NAME = 'Sequence'
-
- def _count(self):
- return self.length_field.value
-
- @property
- def length_field(self):
- field_ptr = native_bt.ctf_field_sequence_get_length(self._ptr)
- utils._handle_ptr("cannot get sequence field object's length field")
- return _create_from_ptr(field_ptr)
-
- @length_field.setter
- def length_field(self, length_field):
- utils._check_type(length_field, _IntegerField)
- ret = native_bt.ctf_field_sequence_set_length(self._ptr, length_field._ptr)
- utils._handle_ret(ret, "cannot set sequence field object's length field")
-
- def _get_field_ptr_at_index(self, index):
- return native_bt.ctf_field_sequence_get_field(self._ptr, index)
-
-
-_TYPE_ID_TO_OBJ = {
- native_bt.CTF_FIELD_TYPE_ID_INTEGER: _IntegerField,
- native_bt.CTF_FIELD_TYPE_ID_FLOAT: _FloatingPointNumberField,
- native_bt.CTF_FIELD_TYPE_ID_ENUM: _EnumerationField,
- native_bt.CTF_FIELD_TYPE_ID_STRING: _StringField,
- native_bt.CTF_FIELD_TYPE_ID_STRUCT: _StructureField,
- native_bt.CTF_FIELD_TYPE_ID_ARRAY: _ArrayField,
- native_bt.CTF_FIELD_TYPE_ID_SEQUENCE: _SequenceField,
- native_bt.CTF_FIELD_TYPE_ID_VARIANT: _VariantField,
-}
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.connection
-import bt2.component
-import functools
-import bt2.port
-import bt2
-
-
-class GraphListenerType:
- PORT_ADDED = 0
- PORT_REMOVED = 1
- PORTS_CONNECTED = 2
- PORTS_DISCONNECTED = 3
-
-
-def _graph_port_added_listener_from_native(user_listener, port_ptr):
- try:
- port = bt2.port._create_from_ptr(port_ptr)
- port._get()
- user_listener(port)
- except:
- pass
-
-
-def _graph_port_removed_listener_from_native(user_listener, port_ptr):
- try:
- port = bt2.port._create_from_ptr(port_ptr)
- port._get()
- user_listener(port)
- except:
- pass
-
-
-def _graph_ports_connected_listener_from_native(user_listener,
- upstream_port_ptr,
- downstream_port_ptr):
- try:
- upstream_port = bt2.port._create_from_ptr(upstream_port_ptr)
- upstream_port._get()
- downstream_port = bt2.port._create_from_ptr(downstream_port_ptr)
- downstream_port._get()
- user_listener(upstream_port, downstream_port)
- except:
- pass
-
-
-def _graph_ports_disconnected_listener_from_native(user_listener,
- upstream_comp_ptr,
- downstream_comp_ptr,
- upstream_port_ptr,
- downstream_port_ptr):
- try:
- upstream_comp = bt2.component._create_generic_component_from_ptr(upstream_comp_ptr)
- upstream_comp._get()
- downstream_comp = bt2.component._create_generic_component_from_ptr(downstream_comp_ptr)
- downstream_comp._get()
- upstream_port = bt2.port._create_from_ptr(upstream_port_ptr)
- upstream_port._get()
- downstream_port = bt2.port._create_from_ptr(downstream_port_ptr)
- downstream_port._get()
- user_listener(upstream_comp, downstream_comp, upstream_port,
- downstream_port)
- except:
- pass
-
-
-class Graph(object._Object):
- def __init__(self):
- ptr = native_bt.graph_create()
-
- if ptr is None:
- raise bt2.CreationError('cannot create graph object')
-
- super().__init__(ptr)
-
- def _handle_status(self, status, gen_error_msg):
- if status == native_bt.GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION:
- raise bt2.PortConnectionRefused
- elif status == native_bt.GRAPH_STATUS_CANCELED:
- raise bt2.GraphCanceled
- elif status == native_bt.GRAPH_STATUS_END:
- raise bt2.Stop
- elif status == native_bt.GRAPH_STATUS_AGAIN:
- raise bt2.TryAgain
- elif status == native_bt.GRAPH_STATUS_NO_SINK:
- raise bt2.NoSinkComponent
- elif status < 0:
- raise bt2.Error(gen_error_msg)
-
- def add_component(self, component_class, name, params=None):
- if isinstance(component_class, bt2.component._GenericComponentClass):
- cc_ptr = component_class._ptr
- elif issubclass(component_class, bt2.component._UserComponent):
- cc_ptr = component_class._cc_ptr
- else:
- raise TypeError("'{}' is not a component class".format(component_class.__class__.__name__))
-
- utils._check_str(name)
- params = bt2.create_value(params)
-
- if params is None:
- params_ptr = None
- else:
- params_ptr = params._ptr
-
- status, comp_ptr = native_bt.graph_add_component(self._ptr, cc_ptr,
- name, params_ptr)
- self._handle_status(status, 'cannot add component to graph')
- assert(comp_ptr)
- return bt2.component._create_generic_component_from_ptr(comp_ptr)
-
- def connect_ports(self, upstream_port, downstream_port):
- utils._check_type(upstream_port, bt2.port._OutputPort)
- utils._check_type(downstream_port, bt2.port._InputPort)
- status, conn_ptr = native_bt.graph_connect_ports(self._ptr,
- upstream_port._ptr,
- downstream_port._ptr)
- self._handle_status(status, 'cannot connect component ports within graph')
- assert(conn_ptr)
- return bt2.connection._Connection._create_from_ptr(conn_ptr)
-
- def add_listener(self, listener_type, listener):
- if not hasattr(listener, '__call__'):
- raise TypeError("'listener' parameter is not callable")
-
- if listener_type == GraphListenerType.PORT_ADDED:
- fn = native_bt.py3_graph_add_port_added_listener
- listener_from_native = functools.partial(_graph_port_added_listener_from_native,
- listener)
- elif listener_type == GraphListenerType.PORT_REMOVED:
- fn = native_bt.py3_graph_add_port_removed_listener
- listener_from_native = functools.partial(_graph_port_removed_listener_from_native,
- listener)
- elif listener_type == GraphListenerType.PORTS_CONNECTED:
- fn = native_bt.py3_graph_add_ports_connected_listener
- listener_from_native = functools.partial(_graph_ports_connected_listener_from_native,
- listener)
- elif listener_type == GraphListenerType.PORTS_DISCONNECTED:
- fn = native_bt.py3_graph_add_ports_disconnected_listener
- listener_from_native = functools.partial(_graph_ports_disconnected_listener_from_native,
- listener)
- else:
- raise TypeError
-
- listener_id = fn(self._ptr, listener_from_native)
- utils._handle_ret(listener_id, 'cannot add listener to graph object')
- return bt2._ListenerHandle(listener_id, self)
-
- def run(self):
- status = native_bt.graph_run(self._ptr)
-
- if status == native_bt.GRAPH_STATUS_END:
- return
-
- self._handle_status(status, 'graph object stopped running because of an unexpected error')
-
- def cancel(self):
- status = native_bt.graph_cancel(self._ptr)
- self._handle_status(status, 'cannot cancel graph object')
-
- @property
- def is_canceled(self):
- is_canceled = native_bt.graph_is_canceled(self._ptr)
- assert(is_canceled >= 0)
- return is_canceled > 0
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- return self.addr == other.addr
+++ /dev/null
-/*
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_OUTPUT_LEVEL bt_cli_log_level
-#include <babeltrace/logging-internal.h>
-
-BT_LOG_INIT_LOG_LEVEL(bt_cli_log_level, "BABELTRACE_CLI_LOG_LEVEL");
+++ /dev/null
-#ifndef CLI_LOGGING_H
-#define CLI_LOGGING_H
-
-/*
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_OUTPUT_LEVEL bt_cli_log_level
-#include <babeltrace/logging-internal.h>
-
-BT_LOG_LEVEL_EXTERN_SYMBOL(bt_cli_log_level);
-
-#endif /* CLI_LOGGING_H */
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2
-
-
-class LoggingLevel:
- VERBOSE = native_bt.LOGGING_LEVEL_VERBOSE
- DEBUG = native_bt.LOGGING_LEVEL_DEBUG
- INFO = native_bt.LOGGING_LEVEL_INFO
- WARN = native_bt.LOGGING_LEVEL_WARN
- ERROR = native_bt.LOGGING_LEVEL_ERROR
- FATAL = native_bt.LOGGING_LEVEL_FATAL
- NONE = native_bt.LOGGING_LEVEL_NONE
-
-
-def get_minimal_logging_level():
- return native_bt.logging_get_minimal_level()
-
-
-def get_global_logging_level():
- return native_bt.logging_get_global_level()
-
-
-def set_global_logging_level(level):
- levels = (
- LoggingLevel.VERBOSE,
- LoggingLevel.DEBUG,
- LoggingLevel.INFO,
- LoggingLevel.WARN,
- LoggingLevel.ERROR,
- LoggingLevel.FATAL,
- LoggingLevel.NONE,
- )
-
- if level not in levels:
- raise TypeError("'{}' is not a valid logging level".format(level))
-
- return native_bt.logging_set_global_level(level)
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef SWIGPYTHON
-# error Unsupported output language
-#endif
-
-%{
-#define BT_LOG_TAG "PY-NATIVE"
-#include "logging.h"
-
-#include <babeltrace/babeltrace.h>
-
-typedef const unsigned char *BTUUID;
-%}
-
-typedef int bt_bool;
-
-/* For uint*_t/int*_t */
-%include "stdint.i"
-
-/* Remove `bt_` and `BT_` prefixes from function names and enumeration items */
-%rename("%(strip:[bt_])s", %$isfunction) "";
-%rename("%(strip:[BT_])s", %$isenumitem) "";
-
-/* Output argument typemap for string output (always appends) */
-%typemap(in, numinputs=0) const char **BTOUTSTR (char *temp_value = NULL) {
- $1 = &temp_value;
-}
-
-%typemap(argout) const char **BTOUTSTR {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result, SWIG_Python_str_FromChar(*$1));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
-/* Output argument typemap for field type output (always appends) */
-%typemap(in, numinputs=0) struct bt_ctf_field_type **BTOUTFT (struct bt_ctf_field_type *temp_ft = NULL) {
- $1 = &temp_ft;
-}
-
-%typemap(argout) struct bt_ctf_field_type **BTOUTFT {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_ctf_field_type, 0));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
-/* Output argument typemap for component output (always appends) */
-%typemap(in, numinputs=0) struct bt_component **BTOUTCOMP (struct bt_component *temp_comp = NULL) {
- $1 = &temp_comp;
-}
-
-%typemap(argout) struct bt_component **BTOUTCOMP {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_component, 0));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
-/* Output argument typemap for connection output (always appends) */
-%typemap(in, numinputs=0) struct bt_connection **BTOUTCONN (struct bt_connection *temp_conn = NULL) {
- $1 = &temp_conn;
-}
-
-%typemap(argout) struct bt_connection **BTOUTCONN {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_connection, 0));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
-/* Output argument typemap for private port output (always appends) */
-%typemap(in, numinputs=0) struct bt_private_port **BTOUTPRIVPORT (struct bt_private_port *temp_priv_port = NULL) {
- $1 = &temp_priv_port;
-}
-
-%typemap(argout) struct bt_private_port **BTOUTPRIVPORT {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_private_port, 0));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
-/* Output argument typemap for initialized uint64_t output parameter (always appends) */
-%typemap(in, numinputs=0) uint64_t *OUTPUTINIT (uint64_t temp = -1ULL) {
- $1 = &temp;
-}
-
-%typemap(argout) uint64_t *OUTPUTINIT {
- $result = SWIG_Python_AppendOutput(resultobj, SWIG_From_unsigned_SS_long_SS_long((*$1)));
-}
-
-/* Output argument typemap for initialized unsigned int output parameter (always appends) */
-%typemap(in, numinputs=0) unsigned int *OUTPUTINIT (unsigned int temp = -1) {
- $1 = &temp;
-}
-
-%typemap(argout) unsigned int *OUTPUTINIT {
- $result = SWIG_Python_AppendOutput(resultobj, SWIG_From_unsigned_SS_long_SS_long((uint64_t) (*$1)));
-}
-
-/* Input argument typemap for UUID bytes */
-%typemap(in) BTUUID {
- $1 = (unsigned char *) PyBytes_AsString($input);
-}
-
-/* Output argument typemap for UUID bytes */
-%typemap(out) BTUUID {
- if (!$1) {
- Py_INCREF(Py_None);
- $result = Py_None;
- } else {
- $result = PyBytes_FromStringAndSize((const char *) $1, 16);
- }
-}
-
-/*
- * Input and output argument typemaps for raw Python objects (direct).
- *
- * Those typemaps honor the convention of Python C function calls with
- * respect to reference counting: parameters are passed as borrowed
- * references, and objects are returned as new references. The wrapped
- * C function must ensure that the return value is always a new
- * reference, and never steal parameter references.
- */
-%typemap(in) PyObject * {
- $1 = $input;
-}
-
-%typemap(out) PyObject * {
- $result = $1;
-}
-
-/* Per-module interface files */
-%include "native_btccpriomap.i"
-%include "native_btclockclass.i"
-%include "native_btcomponent.i"
-%include "native_btcomponentclass.i"
-%include "native_btconnection.i"
-%include "native_btctfwriter.i"
-%include "native_btevent.i"
-%include "native_bteventclass.i"
-%include "native_btfields.i"
-%include "native_btft.i"
-%include "native_btgraph.i"
-%include "native_btlogging.i"
-%include "native_btnotification.i"
-%include "native_btnotifiter.i"
-%include "native_btpacket.i"
-%include "native_btplugin.i"
-%include "native_btport.i"
-%include "native_btref.i"
-%include "native_btstream.i"
-%include "native_btstreamclass.i"
-%include "native_bttrace.i"
-%include "native_btvalues.i"
-%include "native_btversion.i"
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-%{
-#include <babeltrace/graph/clock-class-priority-map.h>
-%}
-
-/* Type */
-struct bt_clock_class_priority_map;
-
-/* Functions */
-struct bt_clock_class_priority_map *bt_clock_class_priority_map_create();
-int64_t bt_clock_class_priority_map_get_clock_class_count(
- struct bt_clock_class_priority_map *clock_class_priority_map);
-struct bt_ctf_clock_class *
-bt_clock_class_priority_map_get_clock_class_by_index(
- struct bt_clock_class_priority_map *clock_class_priority_map,
- uint64_t index);
-struct bt_ctf_clock_class *
-bt_clock_class_priority_map_get_clock_class_by_name(
- struct bt_clock_class_priority_map *clock_class_priority_map,
- const char *name);
-struct bt_ctf_clock_class *
-bt_clock_class_priority_map_get_highest_priority_clock_class(
- struct bt_clock_class_priority_map *clock_class_priority_map);
-int bt_clock_class_priority_map_get_clock_class_priority(
- struct bt_clock_class_priority_map *clock_class_priority_map,
- struct bt_ctf_clock_class *clock_class, uint64_t *OUTPUTINIT);
-int bt_clock_class_priority_map_add_clock_class(
- struct bt_clock_class_priority_map *clock_class_priority_map,
- struct bt_ctf_clock_class *clock_class, uint64_t priority);
-struct bt_clock_class_priority_map *bt_clock_class_priority_map_copy(
- struct bt_clock_class_priority_map *clock_class_priority_map);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Types */
-struct bt_ctf_clock_class;
-struct bt_ctf_clock_value;
-
-/* Clock class functions */
-struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
- uint64_t freq);
-const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class);
-int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class, const char *name);
-const char *bt_ctf_clock_class_get_description(struct bt_ctf_clock_class *clock_class);
-int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
- const char *desc);
-uint64_t bt_ctf_clock_class_get_frequency(struct bt_ctf_clock_class *clock_class);
-int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
- uint64_t freq);
-uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class);
-int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
- uint64_t precision);
-int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
- int64_t *OUTPUT);
-int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
- int64_t offset_s);
-int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
- int64_t *OUTPUT);
-int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
- int64_t offset);
-int bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class);
-int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
- int is_absolute);
-BTUUID bt_ctf_clock_class_get_uuid(struct bt_ctf_clock_class *clock_class);
-int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
- BTUUID uuid);
-
-/* Clock value functions */
-struct bt_ctf_clock_value *bt_ctf_clock_value_create(
- struct bt_ctf_clock_class *clock_class, uint64_t value);
-int bt_ctf_clock_value_get_value(
- struct bt_ctf_clock_value *clock_value, uint64_t *OUTPUT);
-int bt_ctf_clock_value_get_value_ns_from_epoch(
- struct bt_ctf_clock_value *clock_value, int64_t *OUTPUT);
-struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
- struct bt_ctf_clock_value *clock_value);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Types */
-struct bt_component;
-
-/* Status */
-enum bt_component_status {
- BT_COMPONENT_STATUS_OK = 0,
- BT_COMPONENT_STATUS_END = 1,
- BT_COMPONENT_STATUS_AGAIN = 11,
- BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION = 111,
- BT_COMPONENT_STATUS_ERROR = -1,
- BT_COMPONENT_STATUS_UNSUPPORTED = -2,
- BT_COMPONENT_STATUS_INVALID = -22,
- BT_COMPONENT_STATUS_NOMEM = -12,
- BT_COMPONENT_STATUS_NOT_FOUND = -19,
- BT_COMPONENT_STATUS_GRAPH_IS_CANCELED = 125,
-};
-
-/* General functions */
-const char *bt_component_get_name(struct bt_component *component);
-struct bt_component_class *bt_component_get_class(
- struct bt_component *component);
-enum bt_component_class_type bt_component_get_class_type(
- struct bt_component *component);
-struct bt_graph *bt_component_get_graph(struct bt_component *component);
-struct bt_component *bt_component_from_private_component(
- struct bt_private_component *private_component);
-
-/* Source component functions */
-int64_t bt_component_source_get_output_port_count(
- struct bt_component *component);
-struct bt_port *bt_component_source_get_output_port_by_name(
- struct bt_component *component, const char *name);
-struct bt_port *bt_component_source_get_output_port_by_index(
- struct bt_component *component, uint64_t index);
-
-/* Private source component functions */
-struct bt_private_port *
-bt_private_component_source_get_output_private_port_by_name(
- struct bt_private_component *private_component,
- const char *name);
-struct bt_private_port *
-bt_private_component_source_get_output_private_port_by_index(
- struct bt_private_component *private_component,
- uint64_t index);
-enum bt_component_status
-bt_private_component_source_add_output_private_port(
- struct bt_private_component *private_component,
- const char *name, void *user_data,
- struct bt_private_port **BTOUTPRIVPORT);
-
-/* Filter component functions */
-int64_t bt_component_filter_get_input_port_count(
- struct bt_component *component);
-struct bt_port *bt_component_filter_get_input_port_by_name(
- struct bt_component *component, const char *name);
-struct bt_port *bt_component_filter_get_input_port_by_index(
- struct bt_component *component, uint64_t index);
-int64_t bt_component_filter_get_output_port_count(
- struct bt_component *component);
-struct bt_port *bt_component_filter_get_output_port_by_name(
- struct bt_component *component, const char *name);
-struct bt_port *bt_component_filter_get_output_port_by_index(
- struct bt_component *component, uint64_t index);
-
-/* Private filter component functions */
-struct bt_private_port *
-bt_private_component_filter_get_output_private_port_by_name(
- struct bt_private_component *private_component,
- const char *name);
-struct bt_private_port *
-bt_private_component_filter_get_output_private_port_by_index(
- struct bt_private_component *private_component, uint64_t index);
-enum bt_component_status
-bt_private_component_filter_add_output_private_port(
- struct bt_private_component *private_component,
- const char *name, void *user_data,
- struct bt_private_port **BTOUTPRIVPORT);
-struct bt_private_port *
-bt_private_component_filter_get_input_private_port_by_name(
- struct bt_private_component *private_component,
- const char *name);
-struct bt_private_port *
-bt_private_component_filter_get_input_private_port_by_index(
- struct bt_private_component *private_component, uint64_t index);
-enum bt_component_status
-bt_private_component_filter_add_input_private_port(
- struct bt_private_component *private_component,
- const char *name, void *user_data,
- struct bt_private_port **BTOUTPRIVPORT);
-
-/* Sink component functions */
-int64_t bt_component_sink_get_input_port_count(
- struct bt_component *component);
-struct bt_port *bt_component_sink_get_input_port_by_name(
- struct bt_component *component, const char *name);
-struct bt_port *bt_component_sink_get_input_port_by_index(
- struct bt_component *component, uint64_t index);
-
-/* Private sink component functions */
-struct bt_private_port *
-bt_private_component_sink_get_input_private_port_by_name(
- struct bt_private_component *private_component,
- const char *name);
-struct bt_private_port *
-bt_private_component_sink_get_input_private_port_by_index(
- struct bt_private_component *private_component, uint64_t index);
-enum bt_component_status
-bt_private_component_sink_add_input_private_port(
- struct bt_private_component *private_component,
- const char *name, void *user_data,
- struct bt_private_port **BTOUTPRIVPORT);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Types */
-struct bt_component_class;
-
-/* Status */
-enum bt_component_class_type {
- BT_COMPONENT_CLASS_TYPE_UNKNOWN = -1,
- BT_COMPONENT_CLASS_TYPE_SOURCE = 0,
- BT_COMPONENT_CLASS_TYPE_SINK = 1,
- BT_COMPONENT_CLASS_TYPE_FILTER = 2,
-};
-
-/* General functions */
-const char *bt_component_class_get_name(
- struct bt_component_class *component_class);
-const char *bt_component_class_get_description(
- struct bt_component_class *component_class);
-const char *bt_component_class_get_help(
- struct bt_component_class *component_class);
-struct bt_value *bt_component_class_query(
- struct bt_component_class *component_class,
- const char *object, struct bt_value *params);
-enum bt_component_class_type bt_component_class_get_type(
- struct bt_component_class *component_class);
-
-%{
-/*
- * This hash table associates a BT component class object address to a
- * user-defined Python class (PyObject *). The keys and values are NOT
- * owned by this hash table. The Python class objects are owned by the
- * Python module, which should not be unloaded until it is not possible
- * to create a user Python component anyway.
- *
- * This hash table is written to when a user-defined Python component
- * class is created by one of the bt_py3_component_class_*_create()
- * functions.
- *
- * This function is read from when a user calls bt_component_create()
- * with a component class pointer created by one of the functions above.
- * In this case, the original Python class needs to be found to
- * instantiate it and associate the created Python component object with
- * a BT component object instance.
- */
-
-static GHashTable *bt_cc_ptr_to_py_cls;
-
-static void register_cc_ptr_to_py_cls(struct bt_component_class *bt_cc,
- PyObject *py_cls)
-{
- if (!bt_cc_ptr_to_py_cls) {
- /*
- * Lazy-initializing this GHashTable because GLib
- * might not be initialized yet and it needs to be
- * before we call g_hash_table_new()
- */
- BT_LOGD_STR("Creating native component class to Python component class hash table.");
- bt_cc_ptr_to_py_cls = g_hash_table_new(g_direct_hash, g_direct_equal);
- assert(bt_cc_ptr_to_py_cls);
- }
-
- g_hash_table_insert(bt_cc_ptr_to_py_cls, (gpointer) bt_cc,
- (gpointer) py_cls);
-}
-
-static PyObject *lookup_cc_ptr_to_py_cls(struct bt_component_class *bt_cc)
-{
- if (!bt_cc_ptr_to_py_cls) {
- BT_LOGW("Cannot look up Python component class because hash table is NULL: "
- "comp-cls-addr=%p", bt_cc);
- return NULL;
- }
-
- return (PyObject *) g_hash_table_lookup(bt_cc_ptr_to_py_cls,
- (gconstpointer) bt_cc);
-}
-
-
-/*
- * Useful Python objects.
- */
-
-static PyObject *py_mod_bt2 = NULL;
-static PyObject *py_mod_bt2_exc_error_type = NULL;
-static PyObject *py_mod_bt2_exc_unsupported_feature_type = NULL;
-static PyObject *py_mod_bt2_exc_try_again_type = NULL;
-static PyObject *py_mod_bt2_exc_stop_type = NULL;
-static PyObject *py_mod_bt2_exc_port_connection_refused_type = NULL;
-static PyObject *py_mod_bt2_exc_graph_canceled_type = NULL;
-static PyObject *py_mod_bt2_exc_notif_iter_canceled_type = NULL;
-static PyObject *py_mod_bt2_exc_connection_ended_type = NULL;
-
-static void bt_py3_cc_init_from_bt2(void)
-{
- /*
- * This is called once the bt2 package is loaded.
- *
- * Those modules and functions are needed while the package is
- * used. Loading them here is safe because we know the bt2
- * package is imported, and we know that the user cannot use the
- * code here without importing bt2 first.
- */
- py_mod_bt2 = PyImport_ImportModule("bt2");
- assert(py_mod_bt2);
- py_mod_bt2_exc_error_type =
- PyObject_GetAttrString(py_mod_bt2, "Error");
- assert(py_mod_bt2_exc_error_type);
- py_mod_bt2_exc_unsupported_feature_type =
- PyObject_GetAttrString(py_mod_bt2, "UnsupportedFeature");
- py_mod_bt2_exc_try_again_type =
- PyObject_GetAttrString(py_mod_bt2, "TryAgain");
- py_mod_bt2_exc_stop_type =
- PyObject_GetAttrString(py_mod_bt2, "Stop");
- py_mod_bt2_exc_port_connection_refused_type =
- PyObject_GetAttrString(py_mod_bt2, "PortConnectionRefused");
- py_mod_bt2_exc_graph_canceled_type =
- PyObject_GetAttrString(py_mod_bt2, "GraphCanceled");
- py_mod_bt2_exc_connection_ended_type =
- PyObject_GetAttrString(py_mod_bt2, "ConnectionEnded");
- assert(py_mod_bt2_exc_stop_type);
-}
-
-static void bt_py3_cc_exit_handler(void)
-{
- /*
- * This is an exit handler (set by the bt2 package).
- *
- * We only give back the references that we took in
- * bt_py3_cc_init_from_bt2() here. The global variables continue
- * to exist for the code of this file, but they are now borrowed
- * references. If this code is executed, it means that somehow
- * the modules are still loaded, so it should be safe to use
- * them even without a strong reference.
- *
- * We cannot do this in the library's destructor because it
- * gets executed once Python is already finalized.
- */
- Py_XDECREF(py_mod_bt2);
- Py_XDECREF(py_mod_bt2_exc_error_type);
- Py_XDECREF(py_mod_bt2_exc_unsupported_feature_type);
- Py_XDECREF(py_mod_bt2_exc_try_again_type);
- Py_XDECREF(py_mod_bt2_exc_stop_type);
- Py_XDECREF(py_mod_bt2_exc_port_connection_refused_type);
- Py_XDECREF(py_mod_bt2_exc_graph_canceled_type);
- Py_XDECREF(py_mod_bt2_exc_notif_iter_canceled_type);
- Py_XDECREF(py_mod_bt2_exc_connection_ended_type);
-}
-
-
-/* Library destructor */
-
-__attribute__((destructor))
-static void bt_py3_native_comp_class_dtor(void) {
- /* Destroy component class association hash table */
- if (bt_cc_ptr_to_py_cls) {
- BT_LOGD_STR("Destroying native component class to Python component class hash table.");
- g_hash_table_destroy(bt_cc_ptr_to_py_cls);
- }
-}
-
-
-/* Component class proxy methods (delegate to the attached Python object) */
-
-static enum bt_notification_iterator_status bt_py3_exc_to_notif_iter_status(void)
-{
- enum bt_notification_iterator_status status =
- BT_NOTIFICATION_ITERATOR_STATUS_OK;
- PyObject *exc = PyErr_Occurred();
-
- if (!exc) {
- goto end;
- }
-
- if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_unsupported_feature_type)) {
- status = BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_stop_type)) {
- status = BT_NOTIFICATION_ITERATOR_STATUS_END;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_try_again_type)) {
- status = BT_NOTIFICATION_ITERATOR_STATUS_AGAIN;
- } else {
- status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
- }
-
-end:
- PyErr_Clear();
- return status;
-}
-
-static enum bt_component_status bt_py3_exc_to_component_status(void)
-{
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- PyObject *exc = PyErr_Occurred();
-
- if (!exc) {
- goto end;
- }
-
- if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_unsupported_feature_type)) {
- status = BT_COMPONENT_STATUS_UNSUPPORTED;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_try_again_type)) {
- status = BT_COMPONENT_STATUS_AGAIN;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_stop_type)) {
- status = BT_COMPONENT_STATUS_END;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_port_connection_refused_type)) {
- status = BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
- } else {
- status = BT_COMPONENT_STATUS_ERROR;
- }
-
-end:
- PyErr_Clear();
- return status;
-}
-
-static enum bt_component_status bt_py3_cc_init(
- struct bt_private_component *priv_comp,
- struct bt_value *params, void *init_method_data)
-{
- struct bt_component *comp =
- bt_component_from_private_component(priv_comp);
- struct bt_component_class *comp_cls = bt_component_get_class(comp);
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- PyObject *py_cls = NULL;
- PyObject *py_comp = NULL;
- PyObject *py_params_ptr = NULL;
- PyObject *py_comp_ptr = NULL;
-
- (void) init_method_data;
- assert(comp);
- assert(comp_cls);
-
- /*
- * Get the user-defined Python class which created this
- * component's class in the first place (borrowed
- * reference).
- */
- py_cls = lookup_cc_ptr_to_py_cls(comp_cls);
- if (!py_cls) {
- BT_LOGE("Cannot find Python class associated to native component class: "
- "comp-cls-addr=%p", comp_cls);
- goto error;
- }
-
- /* Parameters pointer -> SWIG pointer Python object */
- py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
- SWIGTYPE_p_bt_value, 0);
- if (!py_params_ptr) {
- BT_LOGE_STR("Failed to create a SWIG pointer object.");
- goto error;
- }
-
- /* Private component pointer -> SWIG pointer Python object */
- py_comp_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_comp),
- SWIGTYPE_p_bt_private_component, 0);
- if (!py_comp_ptr) {
- BT_LOGE_STR("Failed to create a SWIG pointer object.");
- goto error;
- }
-
- /*
- * Do the equivalent of this:
- *
- * py_comp = py_cls._init_from_native(py_comp_ptr, py_params_ptr)
- *
- * _UserComponentType._init_from_native() calls the Python
- * component object's __init__() function.
- */
- py_comp = PyObject_CallMethod(py_cls,
- "_init_from_native", "(OO)", py_comp_ptr, py_params_ptr);
- if (!py_comp) {
- BT_LOGE("Failed to call Python class's _init_from_native() method: "
- "py-cls-addr=%p", py_cls);
- goto error;
- }
-
- /*
- * Our user Python component object is now fully created and
- * initialized by the user. Since we just created it, this
- * native component is its only (persistent) owner.
- */
- bt_private_component_set_user_data(priv_comp, py_comp);
- py_comp = NULL;
- goto end;
-
-error:
- status = BT_COMPONENT_STATUS_ERROR;
-
- /*
- * Clear any exception: we're returning a bad status anyway. If
- * this call originated from Python (creation from a plugin's
- * component class, for example), then the user gets an
- * appropriate creation error.
- */
- PyErr_Clear();
-
-end:
- bt_put(comp_cls);
- bt_put(comp);
- Py_XDECREF(py_comp);
- Py_XDECREF(py_params_ptr);
- Py_XDECREF(py_comp_ptr);
- return status;
-}
-
-static void bt_py3_cc_finalize(struct bt_private_component *priv_comp)
-{
- PyObject *py_comp = bt_private_component_get_user_data(priv_comp);
- PyObject *py_method_result = NULL;
-
- assert(py_comp);
-
- /* Call user's _finalize() method */
- py_method_result = PyObject_CallMethod(py_comp,
- "_finalize", NULL);
-
- if (PyErr_Occurred()) {
- BT_LOGW("User's _finalize() method raised an exception: ignoring.");
- }
-
- /*
- * Ignore any exception raised by the _finalize() method because
- * it won't change anything at this point: the component is
- * being destroyed anyway.
- */
- PyErr_Clear();
- Py_XDECREF(py_method_result);
- Py_DECREF(py_comp);
-}
-
-static enum bt_component_status bt_py3_cc_accept_port_connection(
- struct bt_private_component *priv_comp,
- struct bt_private_port *self_priv_port,
- struct bt_port *other_port)
-{
- enum bt_component_status status;
- PyObject *py_comp = NULL;
- PyObject *py_self_port_ptr = NULL;
- PyObject *py_other_port_ptr = NULL;
- PyObject *py_method_result = NULL;
-
- py_comp = bt_private_component_get_user_data(priv_comp);
- assert(py_comp);
- py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_priv_port),
- SWIGTYPE_p_bt_private_port, 0);
- if (!py_self_port_ptr) {
- BT_LOGE_STR("Failed to create a SWIG pointer object.");
- goto error;
- }
-
- py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
- SWIGTYPE_p_bt_port, 0);
- if (!py_other_port_ptr) {
- BT_LOGE_STR("Failed to create a SWIG pointer object.");
- goto error;
- }
-
- py_method_result = PyObject_CallMethod(py_comp,
- "_accept_port_connection_from_native", "(OO)", py_self_port_ptr,
- py_other_port_ptr);
- status = bt_py3_exc_to_component_status();
- if (!py_method_result && status == BT_COMPONENT_STATUS_OK) {
- /* Pretty sure this should never happen, but just in case */
- BT_LOGE("User's _accept_port_connection() method failed without raising an exception: "
- "status=%d", status);
- goto error;
- }
-
- if (status == BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION) {
- /*
- * Looks like the user method raised
- * PortConnectionRefused: accept this like if it
- * returned False.
- */
- goto end;
- } else if (status != BT_COMPONENT_STATUS_OK) {
- BT_LOGE("User's _accept_port_connection() raised an unexpected exception: "
- "status=%d", status);
- goto error;
- }
-
- assert(PyBool_Check(py_method_result));
-
- if (py_method_result == Py_True) {
- status = BT_COMPONENT_STATUS_OK;
- } else {
- status = BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
- }
-
- goto end;
-
-error:
- status = BT_COMPONENT_STATUS_ERROR;
-
- /*
- * Clear any exception: we're returning a bad status anyway. If
- * this call originated from Python, then the user gets an
- * appropriate error.
- */
- PyErr_Clear();
-
-end:
- Py_XDECREF(py_self_port_ptr);
- Py_XDECREF(py_other_port_ptr);
- Py_XDECREF(py_method_result);
- return status;
-}
-
-static void bt_py3_cc_port_connected(
- struct bt_private_component *priv_comp,
- struct bt_private_port *self_priv_port,
- struct bt_port *other_port)
-{
- PyObject *py_comp = NULL;
- PyObject *py_self_port_ptr = NULL;
- PyObject *py_other_port_ptr = NULL;
- PyObject *py_method_result = NULL;
-
- py_comp = bt_private_component_get_user_data(priv_comp);
- assert(py_comp);
- py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_priv_port),
- SWIGTYPE_p_bt_private_port, 0);
- if (!py_self_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
- SWIGTYPE_p_bt_port, 0);
- if (!py_other_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_method_result = PyObject_CallMethod(py_comp,
- "_port_connected_from_native", "(OO)", py_self_port_ptr,
- py_other_port_ptr);
- assert(py_method_result == Py_None);
- Py_XDECREF(py_self_port_ptr);
- Py_XDECREF(py_other_port_ptr);
- Py_XDECREF(py_method_result);
-}
-
-static void bt_py3_cc_port_disconnected(
- struct bt_private_component *priv_comp,
- struct bt_private_port *priv_port)
-{
- PyObject *py_comp = NULL;
- PyObject *py_port_ptr = NULL;
- PyObject *py_method_result = NULL;
-
- py_comp = bt_private_component_get_user_data(priv_comp);
- assert(py_comp);
- py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_port),
- SWIGTYPE_p_bt_private_port, 0);
- if (!py_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_method_result = PyObject_CallMethod(py_comp,
- "_port_disconnected_from_native", "(O)", py_port_ptr);
- assert(py_method_result == Py_None);
- Py_XDECREF(py_port_ptr);
- Py_XDECREF(py_method_result);
-}
-
-static struct bt_value *bt_py3_cc_query(
- struct bt_component_class *comp_cls,
- const char *object, struct bt_value *params)
-{
- PyObject *py_cls = NULL;
- PyObject *py_params_ptr = NULL;
- PyObject *py_query_func = NULL;
- PyObject *py_object = NULL;
- PyObject *py_results_addr = NULL;
- struct bt_value *results = NULL;
-
- py_cls = lookup_cc_ptr_to_py_cls(comp_cls);
- if (!py_cls) {
- BT_LOGE("Cannot find Python class associated to native component class: "
- "comp-cls-addr=%p", comp_cls);
- goto error;
- }
-
- py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
- SWIGTYPE_p_bt_value, 0);
- if (!py_params_ptr) {
- BT_LOGE_STR("Failed to create a SWIG pointer object.");
- goto error;
- }
-
- py_object = SWIG_FromCharPtr(object);
- if (!py_object) {
- BT_LOGE_STR("Failed to create a Python string.");
- goto error;
- }
-
- py_results_addr = PyObject_CallMethod(py_cls,
- "_query_from_native", "(OO)", py_object, py_params_ptr);
- if (!py_results_addr || py_results_addr == Py_None) {
- BT_LOGE_STR("User's _query() method failed.");
- goto error;
- }
-
- if (py_results_addr == Py_NotImplemented) {
- BT_LOGE_STR("User's _query() method is not implemented.");
- goto error;
- }
-
- /*
- * The returned object, on success, is an integer object
- * (PyLong) containing the address of a BT value object (new
- * reference).
- */
- results = (void *) PyLong_AsUnsignedLongLong(py_results_addr);
- assert(!PyErr_Occurred());
- assert(results);
- goto end;
-
-error:
- BT_PUT(results);
- PyErr_Clear();
-
-end:
- Py_XDECREF(py_params_ptr);
- Py_XDECREF(py_query_func);
- Py_XDECREF(py_object);
- Py_XDECREF(py_results_addr);
- return results;
-}
-
-static enum bt_notification_iterator_status bt_py3_cc_notification_iterator_init(
- struct bt_private_notification_iterator *priv_notif_iter,
- struct bt_private_port *priv_port)
-{
- enum bt_notification_iterator_status status =
- BT_NOTIFICATION_ITERATOR_STATUS_OK;
- PyObject *py_comp_cls = NULL;
- PyObject *py_iter_cls = NULL;
- PyObject *py_iter_ptr = NULL;
- PyObject *py_init_method_result = NULL;
- PyObject *py_iter = NULL;
- struct bt_private_component *priv_comp =
- bt_private_notification_iterator_get_private_component(
- priv_notif_iter);
- PyObject *py_comp;
-
- assert(priv_comp);
- py_comp = bt_private_component_get_user_data(priv_comp);
-
- /* Find user's Python notification iterator class */
- py_comp_cls = PyObject_GetAttrString(py_comp, "__class__");
- if (!py_comp_cls) {
- BT_LOGE_STR("Cannot get Python object's `__class__` attribute.");
- goto error;
- }
-
- py_iter_cls = PyObject_GetAttrString(py_comp_cls, "_iter_cls");
- if (!py_iter_cls) {
- BT_LOGE_STR("Cannot get Python class's `_iter_cls` attribute.");
- goto error;
- }
-
- py_iter_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_notif_iter),
- SWIGTYPE_p_bt_private_notification_iterator, 0);
- if (!py_iter_ptr) {
- BT_LOGE_STR("Failed to create a SWIG pointer object.");
- goto error;
- }
-
- /*
- * Create object with borrowed native notification iterator
- * reference:
- *
- * py_iter = py_iter_cls.__new__(py_iter_cls, py_iter_ptr)
- */
- py_iter = PyObject_CallMethod(py_iter_cls, "__new__",
- "(OO)", py_iter_cls, py_iter_ptr);
- if (!py_iter) {
- BT_LOGE("Failed to call Python class's __new__() method: "
- "py-cls-addr=%p", py_iter_cls);
- goto error;
- }
-
- /*
- * Initialize object:
- *
- * py_iter.__init__()
- *
- * At this point, py_iter._ptr is set, so this initialization
- * function has access to self._component (which gives it the
- * user Python component object from which the iterator was
- * created).
- */
- py_init_method_result = PyObject_CallMethod(py_iter, "__init__", NULL);
- if (!py_init_method_result) {
- BT_LOGE_STR("User's __init__() method failed.");
- goto error;
- }
-
- /*
- * Since the Python code can never instantiate a user-defined
- * notification iterator class, the native notification iterator
- * object does NOT belong to a user Python notification iterator
- * object (borrowed reference). However this Python object is
- * owned by this native notification iterator object.
- *
- * In the Python world, the lifetime of the native notification
- * iterator is managed by a _GenericNotificationIterator
- * instance:
- *
- * _GenericNotificationIterator instance:
- * owns a native bt_notification_iterator object (iter)
- * owns a _UserNotificationIterator instance (py_iter)
- * self._ptr is a borrowed reference to the
- * native bt_private_notification_iterator
- * object (iter)
- */
- bt_private_notification_iterator_set_user_data(priv_notif_iter,
- py_iter);
- py_iter = NULL;
- goto end;
-
-error:
- status = bt_py3_exc_to_notif_iter_status();
- if (status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
- /*
- * Looks like there wasn't any exception from the Python
- * side, but we're still in an error state here.
- */
- status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
- }
-
- /*
- * Clear any exception: we're returning a bad status anyway. If
- * this call originated from Python, then the user gets an
- * appropriate creation error.
- */
- PyErr_Clear();
-
-end:
- bt_put(priv_comp);
- Py_XDECREF(py_comp_cls);
- Py_XDECREF(py_iter_cls);
- Py_XDECREF(py_iter_ptr);
- Py_XDECREF(py_init_method_result);
- Py_XDECREF(py_iter);
- return status;
-}
-
-static void bt_py3_cc_notification_iterator_finalize(
- struct bt_private_notification_iterator *priv_notif_iter)
-{
- PyObject *py_notif_iter =
- bt_private_notification_iterator_get_user_data(priv_notif_iter);
- PyObject *py_method_result = NULL;
-
- assert(py_notif_iter);
-
- /* Call user's _finalize() method */
- py_method_result = PyObject_CallMethod(py_notif_iter,
- "_finalize", NULL);
-
- if (PyErr_Occurred()) {
- BT_LOGW("User's _finalize() method raised an exception: ignoring.");
- }
-
- /*
- * Ignore any exception raised by the _finalize() method because
- * it won't change anything at this point: the component is
- * being destroyed anyway.
- */
- PyErr_Clear();
- Py_XDECREF(py_method_result);
- Py_DECREF(py_notif_iter);
-}
-
-static struct bt_notification_iterator_next_return
-bt_py3_cc_notification_iterator_next(
- struct bt_private_notification_iterator *priv_notif_iter)
-{
- struct bt_notification_iterator_next_return next_ret = {
- .status = BT_NOTIFICATION_ITERATOR_STATUS_OK,
- .notification = NULL,
- };
- PyObject *py_notif_iter =
- bt_private_notification_iterator_get_user_data(priv_notif_iter);
- PyObject *py_method_result = NULL;
-
- assert(py_notif_iter);
- py_method_result = PyObject_CallMethod(py_notif_iter,
- "_next_from_native", NULL);
- if (!py_method_result) {
- next_ret.status = bt_py3_exc_to_notif_iter_status();
- assert(next_ret.status != BT_NOTIFICATION_ITERATOR_STATUS_OK);
- goto end;
- }
-
- /*
- * The returned object, on success, is an integer object
- * (PyLong) containing the address of a native notification
- * object (which is now ours).
- */
- next_ret.notification =
- (struct bt_notification *) PyLong_AsUnsignedLongLong(
- py_method_result);
-
- /* Clear potential overflow error; should never happen */
- assert(!PyErr_Occurred());
- assert(next_ret.notification);
- goto end;
-
-end:
- Py_XDECREF(py_method_result);
- return next_ret;
-}
-
-static enum bt_component_status bt_py3_cc_sink_consume(
- struct bt_private_component *priv_comp)
-{
- PyObject *py_comp = bt_private_component_get_user_data(priv_comp);
- PyObject *py_method_result = NULL;
- enum bt_component_status status;
-
- assert(py_comp);
- py_method_result = PyObject_CallMethod(py_comp,
- "_consume", NULL);
- status = bt_py3_exc_to_component_status();
- if (!py_method_result && status == BT_COMPONENT_STATUS_OK) {
- /* Pretty sure this should never happen, but just in case */
- BT_LOGE("User's _consume() method failed without raising an exception: "
- "status=%d", status);
- status = BT_COMPONENT_STATUS_ERROR;
- }
-
- Py_XDECREF(py_method_result);
- return status;
-}
-
-
-/* Component class creation functions (called from Python module) */
-
-static int bt_py3_cc_set_optional_attrs_methods(struct bt_component_class *cc,
- const char *description, const char *help)
-{
- int ret = 0;
-
- if (description) {
- ret = bt_component_class_set_description(cc, description);
- if (ret) {
- BT_LOGE("Cannot set component class's description: "
- "comp-cls-addr=%p", cc);
- goto end;
- }
- }
-
- if (help) {
- ret = bt_component_class_set_help(cc, help);
- if (ret) {
- BT_LOGE("Cannot set component class's help text: "
- "comp-cls-addr=%p", cc);
- goto end;
- }
- }
-
- ret = bt_component_class_set_init_method(cc, bt_py3_cc_init);
- assert(ret == 0);
- ret = bt_component_class_set_finalize_method(cc, bt_py3_cc_finalize);
- assert(ret == 0);
- ret = bt_component_class_set_accept_port_connection_method(cc,
- bt_py3_cc_accept_port_connection);
- assert(ret == 0);
- ret = bt_component_class_set_port_connected_method(cc,
- bt_py3_cc_port_connected);
- assert(ret == 0);
- ret = bt_component_class_set_port_disconnected_method(cc,
- bt_py3_cc_port_disconnected);
- assert(ret == 0);
- ret = bt_component_class_set_query_method(cc, bt_py3_cc_query);
- assert(ret == 0);
-
-end:
- return ret;
-}
-
-static void bt_py3_cc_set_optional_iter_methods(struct bt_component_class *cc,
- int (*set_notif_iter_init_method)(struct bt_component_class *, bt_component_class_notification_iterator_init_method),
- int (*set_notif_iter_finalize_method)(struct bt_component_class *, bt_component_class_notification_iterator_finalize_method))
-{
- int ret;
-
- ret = set_notif_iter_init_method(
- cc, bt_py3_cc_notification_iterator_init);
- assert(ret == 0);
- ret = set_notif_iter_finalize_method(
- cc, bt_py3_cc_notification_iterator_finalize);
- assert(ret == 0);
-}
-
-static struct bt_component_class *bt_py3_component_class_source_create(
- PyObject *py_cls, const char *name, const char *description,
- const char *help)
-{
- struct bt_component_class *cc;
- int ret;
-
- assert(py_cls);
- cc = bt_component_class_source_create(name,
- bt_py3_cc_notification_iterator_next);
- if (!cc) {
- BT_LOGE_STR("Cannot create source component class.");
- goto end;
- }
-
- ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
- if (ret) {
- BT_LOGE_STR("Cannot set source component class's optional attributes and methods.");
- BT_PUT(cc);
- goto end;
- }
-
- bt_py3_cc_set_optional_iter_methods(cc,
- bt_component_class_source_set_notification_iterator_init_method,
- bt_component_class_source_set_notification_iterator_finalize_method);
- register_cc_ptr_to_py_cls(cc, py_cls);
- bt_component_class_freeze(cc);
-
-end:
- return cc;
-}
-
-static struct bt_component_class *bt_py3_component_class_filter_create(
- PyObject *py_cls, const char *name, const char *description,
- const char *help)
-{
- struct bt_component_class *cc;
- int ret;
-
- assert(py_cls);
- cc = bt_component_class_filter_create(name,
- bt_py3_cc_notification_iterator_next);
- if (!cc) {
- BT_LOGE_STR("Cannot create filter component class.");
- goto end;
- }
-
- ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
- if (ret) {
- BT_LOGE_STR("Cannot set filter component class's optional attributes and methods.");
- BT_PUT(cc);
- goto end;
- }
-
- bt_py3_cc_set_optional_iter_methods(cc,
- bt_component_class_filter_set_notification_iterator_init_method,
- bt_component_class_filter_set_notification_iterator_finalize_method);
- register_cc_ptr_to_py_cls(cc, py_cls);
- bt_component_class_freeze(cc);
-
-end:
- return cc;
-}
-
-static struct bt_component_class *bt_py3_component_class_sink_create(
- PyObject *py_cls, const char *name, const char *description,
- const char *help)
-{
- struct bt_component_class *cc;
- int ret;
-
- assert(py_cls);
- cc = bt_component_class_sink_create(name, bt_py3_cc_sink_consume);
- if (!cc) {
- BT_LOGE_STR("Cannot create sink component class.");
- goto end;
- }
-
- ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
- if (ret) {
- BT_LOGE_STR("Cannot set sink component class's optional attributes and methods.");
- BT_PUT(cc);
- goto end;
- }
-
- register_cc_ptr_to_py_cls(cc, py_cls);
- bt_component_class_freeze(cc);
-
-end:
- return cc;
-}
-%}
-
-struct bt_component_class *bt_py3_component_class_source_create(
- PyObject *py_cls, const char *name, const char *description,
- const char *help);
-struct bt_component_class *bt_py3_component_class_filter_create(
- PyObject *py_cls, const char *name, const char *description,
- const char *help);
-struct bt_component_class *bt_py3_component_class_sink_create(
- PyObject *py_cls, const char *name, const char *description,
- const char *help);
-void bt_py3_cc_init_from_bt2(void);
-void bt_py3_cc_exit_handler(void);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_connection;
-struct bt_private_connection;
-
-/* Status */
-enum bt_connection_status {
- BT_CONNECTION_STATUS_GRAPH_IS_CANCELED = 125,
- BT_CONNECTION_STATUS_OK = 0,
- BT_CONNECTION_STATUS_INVALID = -22,
- BT_CONNECTION_STATUS_ERROR = -1,
- BT_CONNECTION_STATUS_NOMEM = -12,
- BT_CONNECTION_STATUS_IS_ENDED = 104,
-};
-
-/* Functions (public) */
-struct bt_port *bt_connection_get_downstream_port(
- struct bt_connection *connection);
-struct bt_port *bt_connection_get_upstream_port(
- struct bt_connection *connection);
-int bt_connection_is_ended(struct bt_connection *connection);
-
-/* Functions (private) */
-struct bt_connection *bt_connection_from_private_connection(
- struct bt_private_connection *private_connection);
-
-/* Helper functions for Python */
-%typemap(out) struct bt_py3_create_notif_iter_ret {
- $result = PyTuple_New(2);
- PyObject *py_notif_iter_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr($1.notif_iter),
- SWIGTYPE_p_bt_notification_iterator, 0);
- PyObject *py_status = SWIG_From_long_SS_long($1.status);
- PyTuple_SET_ITEM($result, 0, py_status);
- PyTuple_SET_ITEM($result, 1, py_notif_iter_ptr);
-}
-
-%{
-struct bt_py3_create_notif_iter_ret {
- enum bt_connection_status status;
- struct bt_notification_iterator *notif_iter;
-};
-
-static struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter(
- unsigned long long priv_conn_addr, PyObject *py_notif_types)
-{
- struct bt_private_connection *priv_conn;
- enum bt_notification_type *notification_types = NULL;
- struct bt_py3_create_notif_iter_ret ret;
-
- priv_conn = (void *) priv_conn_addr;
- assert(!PyErr_Occurred());
- assert(priv_conn);
-
- if (py_notif_types != Py_None) {
- size_t i;
-
- assert(PyList_Check(py_notif_types));
- notification_types = g_new0(enum bt_notification_type,
- PyList_Size(py_notif_types) + 1);
- assert(notification_types);
- notification_types[PyList_Size(py_notif_types)] =
- BT_NOTIFICATION_TYPE_SENTINEL;
-
- for (i = 0; i < PyList_Size(py_notif_types); i++) {
- PyObject *item = PyList_GetItem(py_notif_types, i);
- long value;
- int overflow;
-
- assert(item);
- assert(PyLong_Check(item));
- value = PyLong_AsLongAndOverflow(item, &overflow);
- assert(overflow == 0);
- notification_types[i] = value;
- }
- }
-
- ret.status = bt_private_connection_create_notification_iterator(
- priv_conn, notification_types, &ret.notif_iter);
-
- if (notification_types) {
- g_free(notification_types);
- }
-
- return ret;
-}
-%}
-
-struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter(
- unsigned long long priv_conn_addr, PyObject *notif_types);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Types */
-struct bt_ctf_clock;
-struct bt_ctf_writer;
-
-/* Clock functions */
-struct bt_ctf_clock *bt_ctf_clock_create(const char *name);
-const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock);
-const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_description(struct bt_ctf_clock *clock,
- const char *desc);
-uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock,
- uint64_t freq);
-uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock,
- uint64_t precision);
-int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock,
- int64_t *OUTPUT);
-int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock,
- int64_t offset_s);
-int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock,
- int64_t *OUTPUT);
-int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock,
- int64_t offset);
-int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock,
- int is_absolute);
-BTUUID bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock,
- BTUUID uuid);
-int bt_ctf_clock_set_time(struct bt_ctf_clock *clock,
- int64_t time);
-
-/* Stream functions */
-int bt_ctf_stream_get_discarded_events_count(
- struct bt_ctf_stream *stream, uint64_t *OUTPUT);
-void bt_ctf_stream_append_discarded_events(struct bt_ctf_stream *stream,
- uint64_t event_count);
-int bt_ctf_stream_append_event(struct bt_ctf_stream *stream,
- struct bt_ctf_event *event);
-struct bt_ctf_field *bt_ctf_stream_get_packet_header(
- struct bt_ctf_stream *stream);
-int bt_ctf_stream_set_packet_header(
- struct bt_ctf_stream *stream,
- struct bt_ctf_field *packet_header);
-struct bt_ctf_field *bt_ctf_stream_get_packet_context(
- struct bt_ctf_stream *stream);
-int bt_ctf_stream_set_packet_context(
- struct bt_ctf_stream *stream,
- struct bt_ctf_field *packet_context);
-int bt_ctf_stream_flush(struct bt_ctf_stream *stream);
-int bt_ctf_stream_is_writer(struct bt_ctf_stream *stream);
-
-/* Stream class functions */
-int bt_ctf_stream_class_set_clock(
- struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_clock *clock);
-struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
- struct bt_ctf_stream_class *stream_class);
-
-/* Writer functions */
-struct bt_ctf_writer *bt_ctf_writer_create(const char *path);
-struct bt_ctf_trace *bt_ctf_writer_get_trace(
- struct bt_ctf_writer *writer);
-int bt_ctf_writer_add_clock(struct bt_ctf_writer *writer,
- struct bt_ctf_clock *clock);
-char *bt_ctf_writer_get_metadata_string(struct bt_ctf_writer *writer);
-void bt_ctf_writer_flush_metadata(struct bt_ctf_writer *writer);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_event;
-
-/* Functions */
-struct bt_ctf_event *bt_ctf_event_create(
- struct bt_ctf_event_class *event_class);
-struct bt_ctf_event_class *bt_ctf_event_get_class(
- struct bt_ctf_event *event);
-struct bt_ctf_packet *bt_ctf_event_get_packet(
- struct bt_ctf_event *event);
-int bt_ctf_event_set_packet(struct bt_ctf_event *event,
- struct bt_ctf_packet *packet);
-struct bt_ctf_stream *bt_ctf_event_get_stream(
- struct bt_ctf_event *event);
-struct bt_ctf_field *bt_ctf_event_get_header(
- struct bt_ctf_event *event);
-int bt_ctf_event_set_header(struct bt_ctf_event *event,
- struct bt_ctf_field *header);
-struct bt_ctf_field *bt_ctf_event_get_stream_event_context(
- struct bt_ctf_event *event);
-int bt_ctf_event_set_stream_event_context(struct bt_ctf_event *event,
- struct bt_ctf_field *context);
-struct bt_ctf_field *bt_ctf_event_get_event_context(
- struct bt_ctf_event *event);
-int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
- struct bt_ctf_field *context);
-struct bt_ctf_field *bt_ctf_event_get_event_payload(
- struct bt_ctf_event *event);
-int bt_ctf_event_set_event_payload(struct bt_ctf_event *event,
- struct bt_ctf_field *payload);
-struct bt_ctf_clock_value *bt_ctf_event_get_clock_value(
- struct bt_ctf_event *event,
- struct bt_ctf_clock_class *clock_class);
-int bt_ctf_event_set_clock_value(
- struct bt_ctf_event *event,
- struct bt_ctf_clock_value *clock_value);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_event_class;
-
-/* Log levels */
-enum bt_ctf_event_class_log_level {
- BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN = -1,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED = 255,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY = 0,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT = 1,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL = 2,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR = 3,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING = 4,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE = 5,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO = 6,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM = 7,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM = 8,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS = 9,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE = 10,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT = 11,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION = 12,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE = 13,
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG = 14,
-};
-
-/* Functions */
-struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name);
-struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
- struct bt_ctf_event_class *event_class);
-const char *bt_ctf_event_class_get_name(
- struct bt_ctf_event_class *event_class);
-int64_t bt_ctf_event_class_get_id(
- struct bt_ctf_event_class *event_class);
-int bt_ctf_event_class_set_id(
- struct bt_ctf_event_class *event_class, uint64_t id);
-enum bt_ctf_event_class_log_level bt_ctf_event_class_get_log_level(
- struct bt_ctf_event_class *event_class);
-int bt_ctf_event_class_set_log_level(
- struct bt_ctf_event_class *event_class,
- enum bt_ctf_event_class_log_level log_level);
-const char *bt_ctf_event_class_get_emf_uri(
- struct bt_ctf_event_class *event_class);
-int bt_ctf_event_class_set_emf_uri(
- struct bt_ctf_event_class *event_class,
- const char *emf_uri);
-struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
- struct bt_ctf_event_class *event_class);
-int bt_ctf_event_class_set_context_type(
- struct bt_ctf_event_class *event_class,
- struct bt_ctf_field_type *context_type);
-struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
- struct bt_ctf_event_class *event_class);
-int bt_ctf_event_class_set_payload_type(
- struct bt_ctf_event_class *event_class,
- struct bt_ctf_field_type *payload_type);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_field;
-
-/* Common functions */
-struct bt_ctf_field *bt_ctf_field_create(
- struct bt_ctf_field_type *type);
-struct bt_ctf_field_type *bt_ctf_field_get_type(
- struct bt_ctf_field *field);
-struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field);
-
-/* Integer field functions */
-int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *integer,
- int64_t *OUTPUT);
-int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *integer,
- int64_t value);
-int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *integer,
- uint64_t *OUTPUT);
-int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *integer,
- uint64_t value);
-
-/* Floating point number field functions */
-int bt_ctf_field_floating_point_get_value(
- struct bt_ctf_field *floating_point, double *OUTPUT);
-int bt_ctf_field_floating_point_set_value(
- struct bt_ctf_field *floating_point,
- double value);
-
-/* Enumeration field functions */
-struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
- struct bt_ctf_field *enumeration);
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *enum_field);
-
-/* String field functions */
-const char *bt_ctf_field_string_get_value(
- struct bt_ctf_field *string_field);
-int bt_ctf_field_string_set_value(struct bt_ctf_field *string_field,
- const char *value);
-int bt_ctf_field_string_append(struct bt_ctf_field *string_field,
- const char *value);
-int bt_ctf_field_string_append_len(
- struct bt_ctf_field *string_field, const char *value,
- unsigned int length);
-
-/* Structure field functions */
-struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
- struct bt_ctf_field *structure, int index);
-struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
- struct bt_ctf_field *struct_field, const char *name);
-int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *struct_field,
- const char *name, struct bt_ctf_field *field);
-
-/* Array field functions */
-struct bt_ctf_field *bt_ctf_field_array_get_field(
- struct bt_ctf_field *array, uint64_t index);
-
-/* Sequence field functions */
-struct bt_ctf_field *bt_ctf_field_sequence_get_length(
- struct bt_ctf_field *sequence);
-int bt_ctf_field_sequence_set_length(struct bt_ctf_field *sequence,
- struct bt_ctf_field *length_field);
-struct bt_ctf_field *bt_ctf_field_sequence_get_field(
- struct bt_ctf_field *sequence, uint64_t index);
-
-/* Variant field functions */
-struct bt_ctf_field *bt_ctf_field_variant_get_field(
- struct bt_ctf_field *variant, struct bt_ctf_field *tag);
-struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
- struct bt_ctf_field *variant);
-struct bt_ctf_field *bt_ctf_field_variant_get_tag(
- struct bt_ctf_field *variant);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_field_type;
-
-/* Common enumerations */
-enum bt_ctf_scope {
- BT_CTF_SCOPE_UNKNOWN = -1,
- BT_CTF_SCOPE_TRACE_PACKET_HEADER = 1,
- BT_CTF_SCOPE_STREAM_PACKET_CONTEXT = 2,
- BT_CTF_SCOPE_STREAM_EVENT_HEADER = 3,
- BT_CTF_SCOPE_STREAM_EVENT_CONTEXT = 4,
- BT_CTF_SCOPE_EVENT_CONTEXT = 5,
- BT_CTF_SCOPE_EVENT_PAYLOAD = 6,
- BT_CTF_SCOPE_ENV = 0,
- BT_CTF_SCOPE_EVENT_FIELDS = 6,
-};
-
-enum bt_ctf_field_type_id {
- BT_CTF_FIELD_TYPE_ID_UNKNOWN = CTF_TYPE_UNKNOWN,
- BT_CTF_FIELD_TYPE_ID_INTEGER = CTF_TYPE_INTEGER,
- BT_CTF_FIELD_TYPE_ID_FLOAT = CTF_TYPE_FLOAT,
- BT_CTF_FIELD_TYPE_ID_ENUM = CTF_TYPE_ENUM,
- BT_CTF_FIELD_TYPE_ID_STRING = CTF_TYPE_STRING,
- BT_CTF_FIELD_TYPE_ID_STRUCT = CTF_TYPE_STRUCT,
- BT_CTF_FIELD_TYPE_ID_ARRAY = CTF_TYPE_ARRAY,
- BT_CTF_FIELD_TYPE_ID_SEQUENCE = CTF_TYPE_SEQUENCE,
- BT_CTF_FIELD_TYPE_ID_VARIANT = CTF_TYPE_VARIANT,
- BT_CTF_NR_TYPE_IDS = NR_CTF_TYPES,
-};
-
-enum bt_ctf_byte_order {
- BT_CTF_BYTE_ORDER_UNKNOWN = -1,
- BT_CTF_BYTE_ORDER_NATIVE = 0,
- BT_CTF_BYTE_ORDER_UNSPECIFIED,
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN,
- BT_CTF_BYTE_ORDER_BIG_ENDIAN,
- BT_CTF_BYTE_ORDER_NETWORK,
-};
-
-enum bt_ctf_string_encoding {
- BT_CTF_STRING_ENCODING_UNKNOWN = CTF_STRING_UNKNOWN,
- BT_CTF_STRING_ENCODING_NONE = CTF_STRING_NONE,
- BT_CTF_STRING_ENCODING_UTF8 = CTF_STRING_UTF8,
- BT_CTF_STRING_ENCODING_ASCII = CTF_STRING_ASCII,
-};
-
-/* Common functions */
-enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
- struct bt_ctf_field_type *field_type);
-int bt_ctf_field_type_get_alignment(
- struct bt_ctf_field_type *field_type);
-int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *field_type,
- unsigned int alignment);
-enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
- struct bt_ctf_field_type *field_type);
-int bt_ctf_field_type_set_byte_order(
- struct bt_ctf_field_type *field_type,
- enum bt_ctf_byte_order byte_order);
-int bt_ctf_field_type_compare(struct bt_ctf_field_type *field_type_a,
- struct bt_ctf_field_type *field_type_b);
-struct bt_ctf_field_type *bt_ctf_field_type_copy(
- struct bt_ctf_field_type *field_type);
-
-/* Integer field type base enumeration */
-enum bt_ctf_integer_base {
- BT_CTF_INTEGER_BASE_UNKNOWN = -1,
- BT_CTF_INTEGER_BASE_BINARY = 2,
- BT_CTF_INTEGER_BASE_OCTAL = 8,
- BT_CTF_INTEGER_BASE_DECIMAL = 10,
- BT_CTF_INTEGER_BASE_HEXADECIMAL = 16,
-};
-
-/* Integer field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_integer_create(
- unsigned int size);
-int bt_ctf_field_type_integer_get_size(
- struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_set_size(
- struct bt_ctf_field_type *int_field_type, unsigned int size);
-int bt_ctf_field_type_integer_is_signed(
- struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_set_is_signed(
- struct bt_ctf_field_type *int_field_type, int is_signed);
-enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
- struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_set_base(
- struct bt_ctf_field_type *int_field_type,
- enum bt_ctf_integer_base base);
-enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
- struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_set_encoding(
- struct bt_ctf_field_type *int_field_type,
- enum bt_ctf_string_encoding encoding);
-struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
- struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_set_mapped_clock_class(
- struct bt_ctf_field_type *int_field_type,
- struct bt_ctf_clock_class *clock_class);
-
-/* Floating point number field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void);
-int bt_ctf_field_type_floating_point_get_exponent_digits(
- struct bt_ctf_field_type *float_field_type);
-int bt_ctf_field_type_floating_point_set_exponent_digits(
- struct bt_ctf_field_type *float_field_type,
- unsigned int exponent_size);
-int bt_ctf_field_type_floating_point_get_mantissa_digits(
- struct bt_ctf_field_type *float_field_type);
-int bt_ctf_field_type_floating_point_set_mantissa_digits(
- struct bt_ctf_field_type *float_field_type,
- unsigned int mantissa_sign_size);
-
-/* Enumeration field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
- struct bt_ctf_field_type *int_field_type);
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
- struct bt_ctf_field_type *enum_field_type);
-int64_t bt_ctf_field_type_enumeration_get_mapping_count(
- struct bt_ctf_field_type *enum_field_type);
-int bt_ctf_field_type_enumeration_get_mapping_signed(
- struct bt_ctf_field_type *enum_field_type, int index,
- const char **BTOUTSTR, int64_t *OUTPUT, int64_t *OUTPUT);
-int bt_ctf_field_type_enumeration_get_mapping_unsigned(
- struct bt_ctf_field_type *enum_field_type, int index,
- const char **BTOUTSTR, uint64_t *OUTPUT,
- uint64_t *OUTPUT);
-int bt_ctf_field_type_enumeration_add_mapping_signed(
- struct bt_ctf_field_type *enum_field_type, const char *name,
- int64_t range_begin, int64_t range_end);
-int bt_ctf_field_type_enumeration_add_mapping_unsigned(
- struct bt_ctf_field_type *enum_field_type, const char *name,
- uint64_t range_begin, uint64_t range_end);
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_by_name(
- struct bt_ctf_field_type *enum_field_type,
- const char *name);
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
- struct bt_ctf_field_type *enum_field_type,
- int64_t value);
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
- struct bt_ctf_field_type *enum_field_type,
- uint64_t value);
-
-/* Enumeration field type mapping iterator functions */
-int bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
- struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
- const char **BTOUTSTR, int64_t *OUTPUT, int64_t *OUTPUT);
-int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
- struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
- const char **BTOUTSTR, uint64_t *OUTPUT, uint64_t *OUTPUT);
-int bt_ctf_field_type_enumeration_mapping_iterator_next(
- struct bt_ctf_field_type_enumeration_mapping_iterator *iter);
-
-/* String field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_string_create(void);
-enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
- struct bt_ctf_field_type *string_field_type);
-int bt_ctf_field_type_string_set_encoding(
- struct bt_ctf_field_type *string_field_type,
- enum bt_ctf_string_encoding encoding);
-
-/* Structure field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void);
-int64_t bt_ctf_field_type_structure_get_field_count(
- struct bt_ctf_field_type *struct_field_type);
-int bt_ctf_field_type_structure_get_field_by_index(
- struct bt_ctf_field_type *struct_field_type,
- const char **BTOUTSTR, struct bt_ctf_field_type **BTOUTFT,
- uint64_t index);
-struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
- struct bt_ctf_field_type *struct_field_type,
- const char *field_name);
-int bt_ctf_field_type_structure_add_field(
- struct bt_ctf_field_type *struct_field_type,
- struct bt_ctf_field_type *field_type,
- const char *field_name);
-
-/* Array field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_array_create(
- struct bt_ctf_field_type *element_field_type,
- unsigned int length);
-struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
- struct bt_ctf_field_type *array_field_type);
-int64_t bt_ctf_field_type_array_get_length(
- struct bt_ctf_field_type *array_field_type);
-
-/* Sequence field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
- struct bt_ctf_field_type *element_field_type,
- const char *length_name);
-struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
- struct bt_ctf_field_type *sequence_field_type);
-const char *bt_ctf_field_type_sequence_get_length_field_name(
- struct bt_ctf_field_type *sequence_field_type);
-struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
- struct bt_ctf_field_type *sequence_field_type);
-
-/* Variant field type functions */
-struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
- struct bt_ctf_field_type *tag_field_type,
- const char *tag_name);
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
- struct bt_ctf_field_type *variant_field_type);
-const char *bt_ctf_field_type_variant_get_tag_name(
- struct bt_ctf_field_type *variant_field_type);
-int bt_ctf_field_type_variant_set_tag_name(
- struct bt_ctf_field_type *variant_field_type,
- const char *tag_name);
-struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
- struct bt_ctf_field_type *variant_field_type);
-int64_t bt_ctf_field_type_variant_get_field_count(
- struct bt_ctf_field_type *variant_field_type);
-int bt_ctf_field_type_variant_get_field_by_index(
- struct bt_ctf_field_type *variant_field_type,
- const char **BTOUTSTR,
- struct bt_ctf_field_type **BTOUTFT, uint64_t index);
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
- struct bt_ctf_field_type *variant_field_type,
- const char *field_name);
-int bt_ctf_field_type_variant_add_field(
- struct bt_ctf_field_type *variant_field_type,
- struct bt_ctf_field_type *field_type,
- const char *field_name);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Types */
-struct bt_graph;
-
-/* Status */
-enum bt_graph_status {
- BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION = 111,
- BT_GRAPH_STATUS_CANCELED = 125,
- BT_GRAPH_STATUS_AGAIN = 11,
- BT_GRAPH_STATUS_END = 1,
- BT_GRAPH_STATUS_OK = 0,
- BT_GRAPH_STATUS_INVALID = -22,
- BT_GRAPH_STATUS_NO_SINK = -6,
- BT_GRAPH_STATUS_ERROR = -1,
- BT_GRAPH_STATUS_NOMEM = -12,
-};
-
-/* Functions */
-struct bt_graph *bt_graph_create(void);
-enum bt_graph_status bt_graph_add_component(
- struct bt_graph *graph,
- struct bt_component_class *component_class,
- const char *name, struct bt_value *params,
- struct bt_component **BTOUTCOMP);
-enum bt_graph_status bt_graph_add_component_with_init_method_data(
- struct bt_graph *graph,
- struct bt_component_class *component_class,
- const char *name, struct bt_value *params,
- void *init_method_data,
- struct bt_component **BTOUTCOMP);
-enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph,
- struct bt_port *upstream, struct bt_port *downstream,
- struct bt_connection **BTOUTCONN);
-enum bt_graph_status bt_graph_run(struct bt_graph *graph);
-enum bt_graph_status bt_graph_consume(struct bt_graph *graph);
-enum bt_graph_status bt_graph_cancel(struct bt_graph *graph);
-int bt_graph_is_canceled(struct bt_graph *graph);
-
-/* Helper functions for Python */
-%{
-static void port_added_listener(struct bt_port *port, void *py_callable)
-{
- PyObject *py_port_ptr = NULL;
- PyObject *py_res = NULL;
-
- py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port),
- SWIGTYPE_p_bt_port, 0);
- if (!py_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_res = PyObject_CallFunction(py_callable, "(O)", py_port_ptr);
- assert(py_res == Py_None);
- Py_DECREF(py_port_ptr);
- Py_DECREF(py_res);
-}
-
-static void port_removed_listener(struct bt_component *component,
- struct bt_port *port, void *py_callable)
-{
- PyObject *py_port_ptr = NULL;
- PyObject *py_res = NULL;
-
- py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port),
- SWIGTYPE_p_bt_port, 0);
- if (!py_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_res = PyObject_CallFunction(py_callable, "(O)", py_port_ptr);
- assert(py_res == Py_None);
- Py_DECREF(py_port_ptr);
- Py_DECREF(py_res);
-}
-
-static void ports_connected_listener(struct bt_port *upstream_port,
- struct bt_port *downstream_port, void *py_callable)
-{
- PyObject *py_upstream_port_ptr = NULL;
- PyObject *py_downstream_port_ptr = NULL;
- PyObject *py_res = NULL;
-
- py_upstream_port_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port, 0);
- if (!py_upstream_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_downstream_port_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port, 0);
- if (!py_downstream_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_res = PyObject_CallFunction(py_callable, "(OO)",
- py_upstream_port_ptr, py_downstream_port_ptr);
- assert(py_res == Py_None);
- Py_DECREF(py_upstream_port_ptr);
- Py_DECREF(py_downstream_port_ptr);
- Py_DECREF(py_res);
-}
-
-static void ports_disconnected_listener(
- struct bt_component *upstream_component,
- struct bt_component *downstream_component,
- struct bt_port *upstream_port, struct bt_port *downstream_port,
- void *py_callable)
-{
- PyObject *py_upstream_comp_ptr = NULL;
- PyObject *py_downstream_comp_ptr = NULL;
- PyObject *py_upstream_port_ptr = NULL;
- PyObject *py_downstream_port_ptr = NULL;
- PyObject *py_res = NULL;
-
- py_upstream_comp_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr(upstream_component),
- SWIGTYPE_p_bt_component, 0);
- if (!py_upstream_comp_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_downstream_comp_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr(downstream_component),
- SWIGTYPE_p_bt_component, 0);
- if (!py_downstream_comp_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_upstream_port_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port, 0);
- if (!py_upstream_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_downstream_port_ptr = SWIG_NewPointerObj(
- SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port, 0);
- if (!py_downstream_port_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_res = PyObject_CallFunction(py_callable, "(OOOO)",
- py_upstream_comp_ptr, py_downstream_comp_ptr,
- py_upstream_port_ptr, py_downstream_port_ptr);
- assert(py_res == Py_None);
- Py_DECREF(py_upstream_comp_ptr);
- Py_DECREF(py_downstream_comp_ptr);
- Py_DECREF(py_upstream_port_ptr);
- Py_DECREF(py_downstream_port_ptr);
- Py_DECREF(py_res);
-}
-
-static void graph_listener_removed(void *py_callable)
-{
- assert(py_callable);
- Py_DECREF(py_callable);
-}
-
-static int bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
- PyObject *py_callable)
-{
- int ret = 0;
-
- assert(graph);
- assert(py_callable);
- ret = bt_graph_add_port_added_listener(graph, port_added_listener,
- graph_listener_removed, py_callable);
- if (ret >= 0) {
- Py_INCREF(py_callable);
- }
-
- return ret;
-}
-
-static int bt_py3_graph_add_port_removed_listener(struct bt_graph *graph,
- PyObject *py_callable)
-{
- int ret = 0;
-
- assert(graph);
- assert(py_callable);
- ret = bt_graph_add_port_removed_listener(graph, port_removed_listener,
- graph_listener_removed, py_callable);
- if (ret >= 0) {
- Py_INCREF(py_callable);
- }
-
- return ret;
-}
-
-static int bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
- PyObject *py_callable)
-{
- int ret = 0;
-
- assert(graph);
- assert(py_callable);
- ret = bt_graph_add_ports_connected_listener(graph,
- ports_connected_listener, graph_listener_removed, py_callable);
- if (ret >= 0) {
- Py_INCREF(py_callable);
- }
-
- return ret;
-}
-
-static int bt_py3_graph_add_ports_disconnected_listener(struct bt_graph *graph,
- PyObject *py_callable)
-{
- int ret = 0;
-
- assert(graph);
- assert(py_callable);
- ret = bt_graph_add_ports_disconnected_listener(graph,
- ports_disconnected_listener, graph_listener_removed,
- py_callable);
- if (ret >= 0) {
- Py_INCREF(py_callable);
- }
-
- return ret;
-}
-%}
-
-int bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
- PyObject *py_callable);
-int bt_py3_graph_add_port_removed_listener(struct bt_graph *graph,
- PyObject *py_callable);
-int bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
- PyObject *py_callable);
-int bt_py3_graph_add_ports_disconnected_listener(struct bt_graph *graph,
- PyObject *py_callable);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-%{
-#include <babeltrace/logging.h>
-%}
-
-/* Log levels */
-enum bt_logging_level {
- BT_LOGGING_LEVEL_VERBOSE = 1,
- BT_LOGGING_LEVEL_DEBUG = 2,
- BT_LOGGING_LEVEL_INFO = 3,
- BT_LOGGING_LEVEL_WARN = 4,
- BT_LOGGING_LEVEL_ERROR = 5,
- BT_LOGGING_LEVEL_FATAL = 6,
- BT_LOGGING_LEVEL_NONE = 0xff,
-};
-
-/* Logging functions */
-enum bt_logging_level bt_logging_get_minimal_level(void);
-enum bt_logging_level bt_logging_get_global_level(void);
-void bt_logging_set_global_level(enum bt_logging_level log_level);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_notification;
-
-/* Notification type */
-enum bt_notification_type {
- BT_NOTIFICATION_TYPE_SENTINEL = -1000,
- BT_NOTIFICATION_TYPE_UNKNOWN = -1,
- BT_NOTIFICATION_TYPE_ALL = -2,
- BT_NOTIFICATION_TYPE_EVENT = 0,
- BT_NOTIFICATION_TYPE_INACTIVITY = 1,
- BT_NOTIFICATION_TYPE_STREAM_BEGIN = 2,
- BT_NOTIFICATION_TYPE_STREAM_END = 3,
- BT_NOTIFICATION_TYPE_PACKET_BEGIN = 4,
- BT_NOTIFICATION_TYPE_PACKET_END = 5,
- BT_NOTIFICATION_TYPE_DISCARDED_EVENTS = 6,
- BT_NOTIFICATION_TYPE_DISCARDED_PACKETS = 7,
-};
-
-/* General functions */
-enum bt_notification_type bt_notification_get_type(
- struct bt_notification *notification);
-
-/* Event notification functions */
-struct bt_notification *bt_notification_event_create(
- struct bt_ctf_event *event,
- struct bt_clock_class_priority_map *clock_class_priority_map);
-struct bt_ctf_event *bt_notification_event_get_event(
- struct bt_notification *notification);
-struct bt_clock_class_priority_map *
-bt_notification_event_get_clock_class_priority_map(
- struct bt_notification *notification);
-
-/* Inactivity notification functions */
-struct bt_notification *bt_notification_inactivity_create(
- struct bt_clock_class_priority_map *clock_class_priority_map);
-struct bt_clock_class_priority_map *
-bt_notification_inactivity_get_clock_class_priority_map(
- struct bt_notification *notification);
-struct bt_ctf_clock_value *bt_notification_inactivity_get_clock_value(
- struct bt_notification *notification,
- struct bt_ctf_clock_class *clock_class);
-int bt_notification_inactivity_set_clock_value(
- struct bt_notification *notification,
- struct bt_ctf_clock_value *clock_value);
-
-/* Packet notification functions */
-struct bt_notification *bt_notification_packet_begin_create(
- struct bt_ctf_packet *packet);
-struct bt_notification *bt_notification_packet_end_create(
- struct bt_ctf_packet *packet);
-struct bt_ctf_packet *bt_notification_packet_begin_get_packet(
- struct bt_notification *notification);
-struct bt_ctf_packet *bt_notification_packet_end_get_packet(
- struct bt_notification *notification);
-
-/* Stream notification functions */
-struct bt_notification *bt_notification_stream_begin_create(
- struct bt_ctf_stream *stream);
-struct bt_notification *bt_notification_stream_end_create(
- struct bt_ctf_stream *stream);
-struct bt_ctf_stream *bt_notification_stream_begin_get_stream(
- struct bt_notification *notification);
-struct bt_ctf_stream *bt_notification_stream_end_get_stream(
- struct bt_notification *notification);
-
-/* Discarded packets notification functions */
-struct bt_ctf_clock_value *
-bt_notification_discarded_packets_get_begin_clock_value(
- struct bt_notification *notification);
-struct bt_ctf_clock_value *
-bt_notification_discarded_packets_get_end_clock_value(
- struct bt_notification *notification);
-int64_t bt_notification_discarded_packets_get_count(
- struct bt_notification *notification);
-struct bt_ctf_stream *bt_notification_discarded_packets_get_stream(
- struct bt_notification *notification);
-
-/* Discarded events notification functions */
-struct bt_ctf_clock_value *
-bt_notification_discarded_events_get_begin_clock_value(
- struct bt_notification *notification);
-struct bt_ctf_clock_value *
-bt_notification_discarded_events_get_end_clock_value(
- struct bt_notification *notification);
-int64_t bt_notification_discarded_events_get_count(
- struct bt_notification *notification);
-struct bt_ctf_stream *bt_notification_discarded_events_get_stream(
- struct bt_notification *notification);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_notification_iterator;
-
-/* Status */
-enum bt_notification_iterator_status {
- BT_NOTIFICATION_ITERATOR_STATUS_CANCELED = 125,
- BT_NOTIFICATION_ITERATOR_STATUS_AGAIN = 11,
- BT_NOTIFICATION_ITERATOR_STATUS_END = 1,
- BT_NOTIFICATION_ITERATOR_STATUS_OK = 0,
- BT_NOTIFICATION_ITERATOR_STATUS_INVALID = -22,
- BT_NOTIFICATION_ITERATOR_STATUS_ERROR = -1,
- BT_NOTIFICATION_ITERATOR_STATUS_NOMEM = -12,
- BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED = -2,
-};
-
-/* Functions */
-struct bt_notification *bt_notification_iterator_get_notification(
- struct bt_notification_iterator *iterator);
-enum bt_notification_iterator_status bt_notification_iterator_next(
- struct bt_notification_iterator *iterator);
-struct bt_component *bt_notification_iterator_get_component(
- struct bt_notification_iterator *iterator);
-
-/* Helper functions for Python */
-%{
-static PyObject *bt_py3_get_user_component_from_user_notif_iter(
- struct bt_private_notification_iterator *priv_notif_iter)
-{
- struct bt_private_component *priv_comp =
- bt_private_notification_iterator_get_private_component(
- priv_notif_iter);
- PyObject *py_comp;
-
- assert(priv_comp);
- py_comp = bt_private_component_get_user_data(priv_comp);
- bt_put(priv_comp);
- assert(py_comp);
-
- /* Return new reference */
- Py_INCREF(py_comp);
- return py_comp;
-}
-%}
-
-PyObject *bt_py3_get_user_component_from_user_notif_iter(
- struct bt_private_notification_iterator *priv_notif_iter);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_packet;
-
-/* Functions */
-struct bt_ctf_packet *bt_ctf_packet_create(
- struct bt_ctf_stream *stream);
-struct bt_ctf_stream *bt_ctf_packet_get_stream(
- struct bt_ctf_packet *packet);
-struct bt_ctf_field *bt_ctf_packet_get_header(
- struct bt_ctf_packet *packet);
-int bt_ctf_packet_set_header(
- struct bt_ctf_packet *packet, struct bt_ctf_field *header);
-struct bt_ctf_field *bt_ctf_packet_get_context(
- struct bt_ctf_packet *packet);
-int bt_ctf_packet_set_context(
- struct bt_ctf_packet *packet, struct bt_ctf_field *context);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Types */
-struct bt_plugin;
-struct bt_plugin_set;
-
-/* Status */
-enum bt_plugin_status {
- BT_PLUGIN_STATUS_OK = 0,
- BT_PLUGIN_STATUS_ERROR = -1,
- BT_PLUGIN_STATUS_NOMEM = -4,
-};
-
-/* Plugin functions */
-struct bt_plugin *bt_plugin_find(const char *plugin_name);
-struct bt_component_class *bt_plugin_find_component_class(
- const char *plugin_name, const char *component_class_name,
- enum bt_component_class_type component_class_type);
-struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path);
-struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path,
- int recurse);
-struct bt_plugin_set *bt_plugin_create_all_from_static(void);
-const char *bt_plugin_get_name(struct bt_plugin *plugin);
-const char *bt_plugin_get_author(struct bt_plugin *plugin);
-const char *bt_plugin_get_license(struct bt_plugin *plugin);
-const char *bt_plugin_get_description(struct bt_plugin *plugin);
-const char *bt_plugin_get_path(struct bt_plugin *plugin);
-enum bt_plugin_status bt_plugin_get_version(struct bt_plugin *plugin,
- unsigned int *OUTPUTINIT, unsigned int *OUTPUTINIT,
- unsigned int *OUTPUTINIT, const char **BTOUTSTR);
-int64_t bt_plugin_get_component_class_count(struct bt_plugin *plugin);
-struct bt_component_class *bt_plugin_get_component_class_by_index(
- struct bt_plugin *plugin, uint64_t index);
-struct bt_component_class *bt_plugin_get_component_class_by_name_and_type(
- struct bt_plugin *plugin, const char *name,
- enum bt_component_class_type type);
-
-/* Plugin set functions */
-int64_t bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set);
-struct bt_plugin *bt_plugin_set_get_plugin(struct bt_plugin_set *plugin_set,
- uint64_t index);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_port;
-struct bt_private_port;
-
-/* Status */
-enum bt_port_status {
- BT_PORT_STATUS_OK = 0,
- BT_PORT_STATUS_ERROR = -1,
- BT_PORT_STATUS_INVALID = -2,
-};
-
-/* Port type */
-enum bt_port_type {
- BT_PORT_TYPE_INPUT = 0,
- BT_PORT_TYPE_OUTPUT = 1,
- BT_PORT_TYPE_UNKOWN = -1,
-};
-
-/* Functions (public) */
-const char *bt_port_get_name(struct bt_port *port);
-enum bt_port_type bt_port_get_type(struct bt_port *port);
-struct bt_connection *bt_port_get_connection(struct bt_port *port);
-struct bt_component *bt_port_get_component(struct bt_port *port);
-enum bt_port_status bt_port_disconnect(struct bt_port *port);
-int bt_port_is_connected(struct bt_port *port);
-
-/* Functions (private) */
-struct bt_port *bt_port_from_private_port(struct bt_private_port *private_port);
-struct bt_private_connection *bt_private_port_get_private_connection(
- struct bt_private_port *private_port);
-struct bt_private_component *bt_private_port_get_private_component(
- struct bt_private_port *private_port);
-enum bt_port_status bt_private_port_remove_from_component(
- struct bt_private_port *private_port);
-void *bt_private_port_get_user_data(
- struct bt_private_port *private_port);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Functions */
-void *bt_get(void *obj);
-void bt_put(void *obj);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_stream;
-
-/* Functions */
-struct bt_ctf_stream *bt_ctf_stream_create(
- struct bt_ctf_stream_class *stream_class,
- const char *name);
-struct bt_ctf_stream *bt_ctf_stream_create_with_id(
- struct bt_ctf_stream_class *stream_class,
- const char *name, uint64_t id);
-const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream);
-int64_t bt_ctf_stream_get_id(struct bt_ctf_stream *stream);
-struct bt_ctf_stream_class *bt_ctf_stream_get_class(
- struct bt_ctf_stream *stream);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_stream_class;
-
-/* Functions */
-struct bt_ctf_stream_class *bt_ctf_stream_class_create_empty(
- const char *name);
-struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name);
-struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
- struct bt_ctf_stream_class *stream_class);
-const char *bt_ctf_stream_class_get_name(
- struct bt_ctf_stream_class *stream_class);
-int bt_ctf_stream_class_set_name(
- struct bt_ctf_stream_class *stream_class, const char *name);
-int64_t bt_ctf_stream_class_get_id(
- struct bt_ctf_stream_class *stream_class);
-int bt_ctf_stream_class_set_id(
- struct bt_ctf_stream_class *stream_class, uint64_t id);
-struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
- struct bt_ctf_stream_class *stream_class);
-int bt_ctf_stream_class_set_packet_context_type(
- struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_field_type *packet_context_type);
-struct bt_ctf_field_type *
-bt_ctf_stream_class_get_event_header_type(
- struct bt_ctf_stream_class *stream_class);
-int bt_ctf_stream_class_set_event_header_type(
- struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_field_type *event_header_type);
-struct bt_ctf_field_type *
-bt_ctf_stream_class_get_event_context_type(
- struct bt_ctf_stream_class *stream_class);
-int bt_ctf_stream_class_set_event_context_type(
- struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_field_type *event_context_type);
-int64_t bt_ctf_stream_class_get_event_class_count(
- struct bt_ctf_stream_class *stream_class);
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_index(
- struct bt_ctf_stream_class *stream_class, uint64_t index);
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
- struct bt_ctf_stream_class *stream_class, uint64_t id);
-int bt_ctf_stream_class_add_event_class(
- struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_event_class *event_class);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Type */
-struct bt_ctf_trace;
-
-/* Functions */
-struct bt_ctf_trace *bt_ctf_trace_create(void);
-const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace_class);
-int bt_ctf_trace_set_name(struct bt_ctf_trace *trace_class,
- const char *name);
-enum bt_ctf_byte_order bt_ctf_trace_get_native_byte_order(
- struct bt_ctf_trace *trace_class);
-int bt_ctf_trace_set_native_byte_order(struct bt_ctf_trace *trace_class,
- enum bt_ctf_byte_order native_byte_order);
-BTUUID bt_ctf_trace_get_uuid(
- struct bt_ctf_trace *trace_class);
-int bt_ctf_trace_set_uuid(struct bt_ctf_trace *trace_class,
- BTUUID uuid);
-int64_t bt_ctf_trace_get_environment_field_count(
- struct bt_ctf_trace *trace_class);
-const char *
-bt_ctf_trace_get_environment_field_name_by_index(
- struct bt_ctf_trace *trace_class, uint64_t index);
-struct bt_value *
-bt_ctf_trace_get_environment_field_value_by_index(struct bt_ctf_trace *trace_class,
- uint64_t index);
-struct bt_value *
-bt_ctf_trace_get_environment_field_value_by_name(
- struct bt_ctf_trace *trace_class, const char *name);
-int bt_ctf_trace_set_environment_field(
- struct bt_ctf_trace *trace_class, const char *name,
- struct bt_value *value);
-struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
- struct bt_ctf_trace *trace_class);
-int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace_class,
- struct bt_ctf_field_type *packet_header_type);
-int64_t bt_ctf_trace_get_clock_class_count(
- struct bt_ctf_trace *trace_class);
-struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
- struct bt_ctf_trace *trace_class, uint64_t index);
-struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
- struct bt_ctf_trace *trace_class, const char *name);
-int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace_class,
- struct bt_ctf_clock_class *clock_class);
-int64_t bt_ctf_trace_get_stream_class_count(
- struct bt_ctf_trace *trace_class);
-struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_index(
- struct bt_ctf_trace *trace_class, uint64_t index);
-struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
- struct bt_ctf_trace *trace_class, uint64_t id);
-int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace_class,
- struct bt_ctf_stream_class *stream_class);
-int64_t bt_ctf_trace_get_stream_count(struct bt_ctf_trace *trace_class);
-struct bt_ctf_stream *bt_ctf_trace_get_stream_by_index(
- struct bt_ctf_trace *trace_class, uint64_t index);
-int bt_ctf_trace_is_static(struct bt_ctf_trace *trace_class);
-int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace_class);
-
-/* Helper functions for Python */
-%{
-void trace_is_static_listener(struct bt_ctf_trace *trace, void *py_callable)
-{
- PyObject *py_trace_ptr = NULL;
- PyObject *py_res = NULL;
-
- py_trace_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(trace),
- SWIGTYPE_p_bt_ctf_trace, 0);
- if (!py_trace_ptr) {
- BT_LOGF_STR("Failed to create a SWIG pointer object.");
- abort();
- }
-
- py_res = PyObject_CallFunction(py_callable, "(O)", py_trace_ptr);
- assert(py_res == Py_None);
- Py_DECREF(py_trace_ptr);
- Py_DECREF(py_res);
-}
-
-void trace_listener_removed(struct bt_ctf_trace *trace, void *py_callable)
-{
- assert(py_callable);
- Py_DECREF(py_callable);
-}
-
-static int bt_py3_trace_add_is_staitc_listener(unsigned long long trace_addr,
- PyObject *py_callable)
-{
- struct bt_ctf_trace *trace = (void *) trace_addr;
- int ret = 0;
-
- assert(trace);
- assert(py_callable);
- ret = bt_ctf_trace_add_is_static_listener(trace,
- trace_is_static_listener, trace_listener_removed, py_callable);
- if (ret >= 0) {
- Py_INCREF(py_callable);
- }
-
- return ret;
-}
-%}
-
-int bt_py3_trace_add_is_staitc_listener(unsigned long long trace_addr,
- PyObject *py_callable);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Remove prefix from `bt_value_null` */
-%rename(value_null) bt_value_null;
-
-/* Type and status */
-struct bt_value;
-
-enum bt_value_type {
- BT_VALUE_TYPE_UNKNOWN = -1,
- BT_VALUE_TYPE_NULL = 0,
- BT_VALUE_TYPE_BOOL = 1,
- BT_VALUE_TYPE_INTEGER = 2,
- BT_VALUE_TYPE_FLOAT = 3,
- BT_VALUE_TYPE_STRING = 4,
- BT_VALUE_TYPE_ARRAY = 5,
- BT_VALUE_TYPE_MAP = 6,
-};
-
-enum bt_value_type bt_value_get_type(const struct bt_value *object);
-
-enum bt_value_status {
- BT_VALUE_STATUS_FROZEN = -4,
- BT_VALUE_STATUS_CANCELLED = -3,
- BT_VALUE_STATUS_INVAL = -22,
- BT_VALUE_STATUS_ERROR = -1,
- BT_VALUE_STATUS_OK = 0,
-};
-
-/* Null value object singleton */
-struct bt_value * const bt_value_null;
-
-/* Common functions */
-enum bt_value_status bt_value_freeze(struct bt_value *object);
-int bt_value_is_frozen(const struct bt_value *object);
-struct bt_value *bt_value_copy(const struct bt_value *object);
-int bt_value_compare(const struct bt_value *object_a,
- const struct bt_value *object_b);
-
-/* Boolean value object functions */
-struct bt_value *bt_value_bool_create(void);
-struct bt_value *bt_value_bool_create_init(int val);
-enum bt_value_status bt_value_bool_get(
- const struct bt_value *bool_obj, int *OUTPUT);
-enum bt_value_status bt_value_bool_set(struct bt_value *bool_obj,
- int val);
-
-/* Integer value object functions */
-struct bt_value *bt_value_integer_create(void);
-struct bt_value *bt_value_integer_create_init(int64_t val);
-enum bt_value_status bt_value_integer_get(
- const struct bt_value *integer_obj, int64_t *OUTPUT);
-enum bt_value_status bt_value_integer_set(
- struct bt_value *integer_obj, int64_t val);
-
-/* Floating point number value object functions */
-struct bt_value *bt_value_float_create(void);
-struct bt_value *bt_value_float_create_init(double val);
-enum bt_value_status bt_value_float_get(
- const struct bt_value *float_obj, double *OUTPUT);
-enum bt_value_status bt_value_float_set(
- struct bt_value *float_obj, double val);
-
-/* String value object functions */
-struct bt_value *bt_value_string_create(void);
-struct bt_value *bt_value_string_create_init(const char *val);
-enum bt_value_status bt_value_string_set(struct bt_value *string_obj,
- const char *val);
-enum bt_value_status bt_value_string_get(
- const struct bt_value *string_obj, const char **BTOUTSTR);
-
-/* Array value object functions */
-struct bt_value *bt_value_array_create(void);
-int bt_value_array_size(const struct bt_value *array_obj);
-struct bt_value *bt_value_array_get(const struct bt_value *array_obj,
- size_t index);
-enum bt_value_status bt_value_array_append(struct bt_value *array_obj,
- struct bt_value *element_obj);
-enum bt_value_status bt_value_array_set(struct bt_value *array_obj,
- size_t index, struct bt_value *element_obj);
-
-/* Map value object functions */
-struct bt_value *bt_value_map_create(void);
-int bt_value_map_size(const struct bt_value *map_obj);
-struct bt_value *bt_value_map_get(const struct bt_value *map_obj,
- const char *key);
-int bt_value_map_has_key(const struct bt_value *map_obj,
- const char *key);
-enum bt_value_status bt_value_map_insert(
- struct bt_value *map_obj, const char *key,
- struct bt_value *element_obj);
-struct bt_value *bt_value_map_extend(struct bt_value *base_map_obj,
- struct bt_value *extension_map_obj);
-
-%{
-struct bt_value_map_get_keys_private_data {
- struct bt_value *keys;
-};
-
-static int bt_value_map_get_keys_private_cb(const char *key,
- struct bt_value *object, void *data)
-{
- enum bt_value_status status;
- struct bt_value_map_get_keys_private_data *priv_data = data;
-
- status = bt_value_array_append_string(priv_data->keys, key);
- if (status != BT_VALUE_STATUS_OK) {
- return BT_FALSE;
- }
-
- return BT_TRUE;
-}
-
-static struct bt_value *bt_value_map_get_keys_private(
- const struct bt_value *map_obj)
-{
- enum bt_value_status status;
- struct bt_value_map_get_keys_private_data data;
-
- data.keys = bt_value_array_create();
- if (!data.keys) {
- return NULL;
- }
-
- status = bt_value_map_foreach(map_obj, bt_value_map_get_keys_private_cb,
- &data);
- if (status != BT_VALUE_STATUS_OK) {
- goto error;
- }
-
- goto end;
-
-error:
- if (data.keys) {
- BT_PUT(data.keys);
- }
-
-end:
- return data.keys;
-}
-%}
-
-struct bt_value *bt_value_map_get_keys_private(const struct bt_value *map_obj);
+++ /dev/null
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-%{
-#include <babeltrace/version.h>
-%}
-
-/* Version functions */
-int bt_version_get_major(void);
-int bt_version_get_minor(void);
-int bt_version_get_patch(void);
-const char *bt_version_get_extra(void);
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.clock_class_priority_map
-import bt2.packet
-import bt2.stream
-import bt2.event
-import copy
-import bt2
-
-
-def _create_from_ptr(ptr):
- notif_type = native_bt.notification_get_type(ptr)
- cls = None
-
- if notif_type not in _NOTIF_TYPE_TO_CLS:
- raise bt2.Error('unknown notification type: {}'.format(notif_type))
-
- return _NOTIF_TYPE_TO_CLS[notif_type]._create_from_ptr(ptr)
-
-
-class _Notification(object._Object):
- pass
-
-
-class _CopyableNotification(_Notification):
- 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 EventNotification(_CopyableNotification):
- _TYPE = native_bt.NOTIFICATION_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.notification_event_create(event._ptr, cc_prio_map_ptr)
-
- if ptr is None:
- raise bt2.CreationError('cannot create event notification object')
-
- super().__init__(ptr)
-
- @property
- def event(self):
- event_ptr = native_bt.notification_event_get_event(self._ptr)
- assert(event_ptr)
- return bt2.event._create_from_ptr(event_ptr)
-
- @property
- def clock_class_priority_map(self):
- cc_prio_map_ptr = native_bt.notification_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 notification. Since the
- # user cannot modify them after copying the notification, it's
- # useless to copy/deep-copy them.
- return EventNotification(self.event, self.clock_class_priority_map)
-
-
-class PacketBeginningNotification(_CopyableNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_PACKET_BEGIN
-
- def __init__(self, packet):
- utils._check_type(packet, bt2.packet._Packet)
- ptr = native_bt.notification_packet_begin_create(packet._ptr)
-
- if ptr is None:
- raise bt2.CreationError('cannot create packet beginning notification object')
-
- super().__init__(ptr)
-
- @property
- def packet(self):
- packet_ptr = native_bt.notification_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 notification. Since the
- # user cannot modify them after copying the notification, it's
- # useless to copy/deep-copy them.
- return PacketBeginningNotification(self.packet)
-
-
-class PacketEndNotification(_CopyableNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_PACKET_END
-
- def __init__(self, packet):
- utils._check_type(packet, bt2.packet._Packet)
- ptr = native_bt.notification_packet_end_create(packet._ptr)
-
- if ptr is None:
- raise bt2.CreationError('cannot create packet end notification object')
-
- super().__init__(ptr)
-
- @property
- def packet(self):
- packet_ptr = native_bt.notification_packet_end_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 notification. Since the
- # user cannot modify them after copying the notification, it's
- # useless to copy/deep-copy them.
- return PacketEndNotification(self.packet)
-
-
-class StreamBeginningNotification(_CopyableNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_STREAM_BEGIN
-
- def __init__(self, stream):
- utils._check_type(stream, bt2.stream._Stream)
- ptr = native_bt.notification_stream_begin_create(stream._ptr)
-
- if ptr is None:
- raise bt2.CreationError('cannot create stream beginning notification object')
-
- super().__init__(ptr)
-
- @property
- def stream(self):
- stream_ptr = native_bt.notification_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
-
- 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 notification. Since the
- # user cannot modify them after copying the notification, it's
- # useless to copy/deep-copy them.
- return StreamBeginningNotification(self.stream)
-
-
-class StreamEndNotification(_CopyableNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_STREAM_END
-
- def __init__(self, stream):
- utils._check_type(stream, bt2.stream._Stream)
- ptr = native_bt.notification_stream_end_create(stream._ptr)
-
- if ptr is None:
- raise bt2.CreationError('cannot create stream end notification object')
-
- super().__init__(ptr)
-
- @property
- def stream(self):
- stream_ptr = native_bt.notification_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 notification. Since the
- # user cannot modify them after copying the notification, it's
- # useless to copy/deep-copy them.
- return StreamEndNotification(self.stream)
-
-
-class InactivityNotification(_CopyableNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_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
- else:
- cc_prio_map_ptr = None
-
- ptr = native_bt.notification_inactivity_create(cc_prio_map_ptr)
-
- if ptr is None:
- raise bt2.CreationError('cannot create inactivity notification object')
-
- super().__init__(ptr)
-
- @property
- def clock_class_priority_map(self):
- cc_prio_map_ptr = native_bt.notification_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)
-
- def clock_value(self, clock_class):
- utils._check_type(clock_class, bt2.ClockClass)
- clock_value_ptr = native_bt.notification_inactivity_get_clock_value(self._ptr,
- clock_class._ptr)
-
- if clock_value_ptr is None:
- return
-
- clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
- return clock_value
-
- def add_clock_value(self, clock_value):
- utils._check_type(clock_value, bt2.clock_class._ClockValue)
- ret = native_bt.notification_inactivity_set_clock_value(self._ptr,
- clock_value._ptr)
- utils._handle_ret(ret, "cannot set inactivity notification object's clock value")
-
- def _get_clock_values(self):
- clock_values = {}
-
- for clock_class in self.clock_class_priority_map:
- clock_value = self.clock_value(clock_class)
-
- 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 = InactivityNotification(self.clock_class_priority_map)
-
- for clock_class in self.clock_class_priority_map:
- clock_value = self.clock_value(clock_class)
-
- if clock_value is None:
- continue
-
- cpy.add_clock_value(clock_value)
-
- return cpy
-
- def __deepcopy__(self, memo):
- cc_prio_map_cpy = copy.deepcopy(self.clock_class_priority_map)
- cpy = InactivityNotification(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 notification copy
- cpy.add_clock_value(clock_value_cpy)
-
- memo[id(self)] = cpy
- return cpy
-
-
-class _DiscardedElementsNotification(_Notification):
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- 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 _DiscardedPacketsNotification(_DiscardedElementsNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_DISCARDED_PACKETS
-
- @property
- def count(self):
- count = native_bt.notification_discarded_packets_get_count(self._ptr)
- assert(count >= 0)
- return count
-
- @property
- def stream(self):
- stream_ptr = native_bt.notification_discarded_packets_get_stream(self._ptr)
- assert(stream_ptr)
- return bt2.stream._create_from_ptr(stream_ptr)
-
- @property
- def beginning_clock_value(self):
- clock_value_ptr = native_bt.notification_discarded_packets_get_begin_clock_value(self._ptr)
-
- if clock_value_ptr is None:
- return
-
- clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
- return clock_value
-
- @property
- def end_clock_value(self):
- clock_value_ptr = native_bt.notification_discarded_packets_get_end_clock_value(self._ptr)
-
- if clock_value_ptr is None:
- return
-
- clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
- return clock_value
-
-
-class _DiscardedEventsNotification(_DiscardedElementsNotification):
- _TYPE = native_bt.NOTIFICATION_TYPE_DISCARDED_EVENTS
-
- @property
- def count(self):
- count = native_bt.notification_discarded_events_get_count(self._ptr)
- assert(count >= 0)
- return count
-
- @property
- def stream(self):
- stream_ptr = native_bt.notification_discarded_events_get_stream(self._ptr)
- assert(stream_ptr)
- return bt2.stream._create_from_ptr(stream_ptr)
-
- @property
- def beginning_clock_value(self):
- clock_value_ptr = native_bt.notification_discarded_events_get_begin_clock_value(self._ptr)
-
- if clock_value_ptr is None:
- return
-
- clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
- return clock_value
-
- @property
- def end_clock_value(self):
- clock_value_ptr = native_bt.notification_discarded_events_get_end_clock_value(self._ptr)
-
- if clock_value_ptr is None:
- return
-
- clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
- return clock_value
-
-
-_NOTIF_TYPE_TO_CLS = {
- native_bt.NOTIFICATION_TYPE_EVENT: EventNotification,
- native_bt.NOTIFICATION_TYPE_PACKET_BEGIN: PacketBeginningNotification,
- native_bt.NOTIFICATION_TYPE_PACKET_END: PacketEndNotification,
- native_bt.NOTIFICATION_TYPE_STREAM_BEGIN: StreamBeginningNotification,
- native_bt.NOTIFICATION_TYPE_STREAM_END: StreamEndNotification,
- native_bt.NOTIFICATION_TYPE_INACTIVITY: InactivityNotification,
- native_bt.NOTIFICATION_TYPE_DISCARDED_PACKETS: _DiscardedPacketsNotification,
- native_bt.NOTIFICATION_TYPE_DISCARDED_EVENTS: _DiscardedEventsNotification,
-}
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.notification
-import collections.abc
-import bt2.component
-import bt2
-
-
-class _NotificationIterator(collections.abc.Iterator):
- def _handle_status(self, status, gen_error_msg):
- if status == native_bt.NOTIFICATION_ITERATOR_STATUS_CANCELED:
- raise bt2.NotificationIteratorCanceled
- elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_AGAIN:
- raise bt2.TryAgain
- elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_END:
- raise bt2.Stop
- elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED:
- raise bt2.UnsupportedFeature
- elif status < 0:
- raise bt2.Error(gen_error_msg)
-
- def __next__(self):
- raise NotImplementedError
-
-
-class _GenericNotificationIterator(object._Object, _NotificationIterator):
- @property
- def component(self):
- comp_ptr = native_bt.notification_iterator_get_component(self._ptr)
- assert(comp_ptr)
- return bt2.component._create_generic_component_from_ptr(comp_ptr)
-
- def _get_notif(self):
- notif_ptr = native_bt.notification_iterator_get_notification(self._ptr)
- utils._handle_ptr(notif_ptr, "cannot get notification iterator object's current notification object")
- return bt2.notification._create_from_ptr(notif_ptr)
-
- def _next(self):
- status = native_bt.notification_iterator_next(self._ptr)
- self._handle_status(status,
- 'unexpected error: cannot advance the notification iterator')
-
- def __next__(self):
- self._next()
- return self._get_notif()
-
-
-class _UserNotificationIterator(_NotificationIterator):
- def __new__(cls, ptr):
- # User iterator objects are always created by the native side,
- # that is, never instantiated directly by Python code.
- #
- # The native code calls this, then manually calls
- # self.__init__() without the `ptr` argument. The user has
- # access to self.component during this call, thanks to this
- # self._ptr argument being set.
- #
- # self._ptr is NOT owned by this object here, so there's nothing
- # to do in __del__().
- self = super().__new__(cls)
- self._ptr = ptr
- return self
-
- def __init__(self):
- pass
-
- @property
- def _component(self):
- return native_bt.py3_get_user_component_from_user_notif_iter(self._ptr)
-
- @property
- def addr(self):
- return int(self._ptr)
-
- def _finalize(self):
- pass
-
- def __next__(self):
- raise bt2.Stop
-
- def _next_from_native(self):
- # this can raise anything: it's catched by the native part
- try:
- notif = next(self)
- except StopIteration:
- raise bt2.Stop
- except:
- raise
-
- utils._check_type(notif, bt2.notification._Notification)
-
- # take a new reference for the native part
- notif._get()
- return int(notif._ptr)
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt
-import abc
-
-
-class _Object:
- def __init__(self, ptr):
- self._ptr = ptr
-
- @property
- def addr(self):
- return int(self._ptr)
-
- @classmethod
- def _create_from_ptr(cls, ptr):
- obj = cls.__new__(cls)
- obj._ptr = ptr
- return obj
-
- def _get(self):
- native_bt.get(self._ptr)
-
- def __del__(self):
- ptr = getattr(self, '_ptr', None)
- native_bt.put(ptr)
- self._ptr = None
-
- def __repr__(self):
- return '<{}.{} object @ {}>'.format(self.__class__.__module__,
- self.__class__.__name__,
- hex(self.addr))
-
-
-class _PrivateObject:
- def __del__(self):
- pub_ptr = getattr(self, '_pub_ptr', None)
- native_bt.put(pub_ptr)
- self._pub_ptr = None
- super().__del__()
-
-
-class _Freezable(metaclass=abc.ABCMeta):
- @property
- def is_frozen(self):
- return self._is_frozen()
-
- @property
- def frozen(self):
- return self.is_frozen
-
- def freeze(self):
- self._freeze()
-
- @abc.abstractmethod
- def _is_frozen(self):
- pass
-
- @abc.abstractmethod
- def _freeze(self):
- pass
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.fields
-import bt2.stream
-import copy
-import abc
-import bt2
-
-
-class _Packet(object._Object):
- @property
- def stream(self):
- stream_ptr = native_bt.ctf_packet_get_stream(self._ptr)
- assert(stream_ptr)
- return bt2.stream._Stream._create_from_ptr(stream_ptr)
-
- @property
- def header_field(self):
- field_ptr = native_bt.ctf_packet_get_header(self._ptr)
-
- if field_ptr is None:
- return
-
- return bt2.fields._create_from_ptr(field_ptr)
-
- @header_field.setter
- def header_field(self, header_field):
- header_field_ptr = None
-
- if header_field is not None:
- utils._check_type(header_field, bt2.fields._Field)
- header_field_ptr = header_field._ptr
-
- ret = native_bt.ctf_packet_set_header(self._ptr, header_field_ptr)
- utils._handle_ret(ret, "cannot set packet object's header field")
-
- @property
- def context_field(self):
- field_ptr = native_bt.ctf_packet_get_context(self._ptr)
-
- if field_ptr is None:
- return
-
- return bt2.fields._create_from_ptr(field_ptr)
-
- @context_field.setter
- def context_field(self, context_field):
- context_field_ptr = None
-
- if context_field is not None:
- utils._check_type(context_field, bt2.fields._Field)
- context_field_ptr = context_field._ptr
-
- ret = native_bt.ctf_packet_set_context(self._ptr, context_field_ptr)
- utils._handle_ret(ret, "cannot set packet object's context field")
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- if self.addr == other.addr:
- return True
-
- self_props = (
- self.header_field,
- self.context_field,
- )
- other_props = (
- other.header_field,
- other.context_field,
- )
- return self_props == other_props
-
- def _copy(self, copy_func):
- cpy = self.stream.create_packet()
- cpy.header_field = copy_func(self.header_field)
- cpy.context_field = copy_func(self.context_field)
- return cpy
-
- def __copy__(self):
- return self._copy(copy.copy)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import collections.abc
-import bt2.component
-import os.path
-import bt2
-
-
-def find_plugins(path, recurse=True):
- utils._check_str(path)
- utils._check_bool(recurse)
- plugin_set_ptr = None
-
- if os.path.isfile(path):
- plugin_set_ptr = native_bt.plugin_create_all_from_file(path)
- elif os.path.isdir(path):
- plugin_set_ptr = native_bt.plugin_create_all_from_dir(path, int(recurse))
-
- if plugin_set_ptr is None:
- return
-
- return _PluginSet._create_from_ptr(plugin_set_ptr)
-
-
-def find_plugin(name):
- utils._check_str(name)
- ptr = native_bt.plugin_find(name)
-
- if ptr is None:
- return
-
- return _Plugin._create_from_ptr(ptr)
-
-
-class _PluginSet(object._Object, collections.abc.Sequence):
- def __len__(self):
- count = native_bt.plugin_set_get_plugin_count(self._ptr)
- assert(count >= 0)
- return count
-
- def __getitem__(self, index):
- utils._check_uint64(index)
-
- if index >= len(self):
- raise IndexError
-
- plugin_ptr = native_bt.plugin_set_get_plugin(self._ptr, index)
- assert(plugin_ptr)
- return _Plugin._create_from_ptr(plugin_ptr)
-
-
-class _PluginVersion:
- def __init__(self, major, minor, patch, extra):
- self._major = major
- self._minor = minor
- self._patch = patch
- self._extra = extra
-
- @property
- def major(self):
- return self._major
-
- @property
- def minor(self):
- return self._minor
-
- @property
- def patch(self):
- return self._patch
-
- @property
- def extra(self):
- return self._extra
-
- def __str__(self):
- extra = ''
-
- if self._extra is not None:
- extra = self._extra
-
- return '{}.{}.{}{}'.format(self._major, self._minor, self._patch, extra)
-
-
-class _PluginComponentClassesIterator(collections.abc.Iterator):
- def __init__(self, plugin_comp_cls):
- self._plugin_comp_cls = plugin_comp_cls
- self._at = 0
-
- def __next__(self):
- plugin_ptr = self._plugin_comp_cls._plugin._ptr
- comp_cls_type = self._plugin_comp_cls._comp_cls_type
- total = native_bt.plugin_get_component_class_count(plugin_ptr)
-
- while True:
- if self._at == total:
- raise StopIteration
-
- comp_cls_ptr = native_bt.plugin_get_component_class_by_index(plugin_ptr,
- self._at)
- assert(comp_cls_ptr)
- cc_type = native_bt.component_class_get_type(comp_cls_ptr)
- self._at += 1
-
- if cc_type == comp_cls_type:
- break
-
- native_bt.put(comp_cls_ptr)
-
- name = native_bt.component_class_get_name(comp_cls_ptr)
- native_bt.put(comp_cls_ptr)
- assert(name is not None)
- return name
-
-
-class _PluginComponentClasses(collections.abc.Mapping):
- def __init__(self, plugin, comp_cls_type):
- self._plugin = plugin
- self._comp_cls_type = comp_cls_type
-
- def __getitem__(self, key):
- utils._check_str(key)
- cc_ptr = native_bt.plugin_get_component_class_by_name_and_type(self._plugin._ptr,
- key,
- self._comp_cls_type)
-
- if cc_ptr is None:
- raise KeyError(key)
-
- return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
-
- def __len__(self):
- count = 0
- total = native_bt.plugin_get_component_class_count(self._plugin._ptr)
-
- for at in range(total):
- comp_cls_ptr = native_bt.plugin_get_component_class_by_index(self._plugin._ptr,
- at)
- assert(comp_cls_ptr)
- cc_type = native_bt.component_class_get_type(comp_cls_ptr)
-
- if cc_type == self._comp_cls_type:
- count += 1
-
- native_bt.put(comp_cls_ptr)
-
- return count
-
- def __iter__(self):
- return _PluginComponentClassesIterator(self)
-
-
-class _Plugin(object._Object):
- @property
- def name(self):
- name = native_bt.plugin_get_name(self._ptr)
- assert(name is not None)
- return name
-
- @property
- def author(self):
- return native_bt.plugin_get_author(self._ptr)
-
- @property
- def license(self):
- return native_bt.plugin_get_license(self._ptr)
-
- @property
- def description(self):
- return native_bt.plugin_get_description(self._ptr)
-
- @property
- def path(self):
- return native_bt.plugin_get_path(self._ptr)
-
- @property
- def version(self):
- status, major, minor, patch, extra = native_bt.plugin_get_version(self._ptr)
-
- if status < 0:
- return
-
- return _PluginVersion(major, minor, patch, extra)
-
- @property
- def source_component_classes(self):
- return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_SOURCE)
-
- @property
- def filter_component_classes(self):
- return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_FILTER)
-
- @property
- def sink_component_classes(self):
- return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_SINK)
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import collections.abc
-import bt2.component
-import bt2.connection
-import copy
-import bt2
-
-
-def _create_from_ptr(ptr):
- port_type = native_bt.port_get_type(ptr)
-
- if port_type == native_bt.PORT_TYPE_INPUT:
- cls = _InputPort
- elif port_type == native_bt.PORT_TYPE_OUTPUT:
- cls = _OutputPort
- else:
- raise bt2.Error('unknown port type: {}'.format(port_type))
-
- return cls._create_from_ptr(ptr)
-
-
-def _create_private_from_ptr(ptr):
- pub_ptr = native_bt.port_from_private_port(ptr)
- utils._handle_ptr(pub_ptr, 'cannot get port object from private port object')
- port_type = native_bt.port_get_type(pub_ptr)
- assert(port_type == native_bt.PORT_TYPE_INPUT or port_type == native_bt.PORT_TYPE_OUTPUT)
-
- if port_type == native_bt.PORT_TYPE_INPUT:
- cls = _PrivateInputPort
- elif port_type == native_bt.PORT_TYPE_OUTPUT:
- cls = _PrivateOutputPort
-
- obj = cls._create_from_ptr(ptr)
- obj._pub_ptr = pub_ptr
- return obj
-
-
-class _Port(object._Object):
- @staticmethod
- def _name(ptr):
- name = native_bt.port_get_name(ptr)
- assert(name is not None)
- return name
-
- @staticmethod
- def _disconnect(ptr):
- status = native_bt.port_disconnect(ptr)
-
- if status < 0:
- raise bt2.Error('cannot disconnect port')
-
- @property
- def name(self):
- return self._name(self._ptr)
-
- @property
- def component(self):
- comp_ptr = native_bt.port_get_component(self._ptr)
-
- if comp_ptr is None:
- return
-
- return bt2.component._create_generic_component_from_ptr(comp_ptr)
-
- @property
- def connection(self):
- conn_ptr = native_bt.port_get_connection(self._ptr)
-
- if conn_ptr is None:
- return
-
- return bt2.connection._Connection._create_from_ptr(conn_ptr)
-
- @property
- def is_connected(self):
- return self.connection is not None
-
- def disconnect(self):
- self._disconnect(self._ptr)
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- return self.addr == other.addr
-
-
-class _InputPort(_Port):
- pass
-
-
-class _OutputPort(_Port):
- pass
-
-
-class _PrivatePort(object._PrivateObject, _Port):
- @property
- def name(self):
- return self._name(self._pub_ptr)
-
- @property
- def component(self):
- comp_ptr = native_bt.private_port_get_private_component(self._ptr)
-
- if comp_ptr is None:
- return
-
- pub_comp_ptr = native_bt.component_from_private_component(comp_ptr)
- assert(pub_comp_ptr)
- comp = bt2.component._create_generic_component_from_ptr(pub_comp_ptr)
- native_bt.put(comp_ptr)
- return comp
-
- @property
- def connection(self):
- conn_ptr = native_bt.private_port_get_private_connection(self._ptr)
-
- if conn_ptr is None:
- return
-
- return bt2.connection._create_private_from_ptr(conn_ptr)
-
- def remove_from_component(self):
- status = native_bt.private_port_remove_from_component(self._ptr)
-
- if status < 0:
- raise bt2.Error("cannot remove port from component")
-
- def disconnect(self):
- self._disconnect(self._pub_ptr)
-
-
-class _PrivateInputPort(_PrivatePort, _InputPort):
- pass
-
-
-class _PrivateOutputPort(_PrivatePort, _OutputPort):
- pass
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import utils
-import bt2.component
-
-
-def plugin_component_class(component_class):
- if not issubclass(component_class, bt2.component._UserComponent):
- raise TypeError('component class is not a subclass of a user component class')
-
- component_class._bt_plugin_component_class = None
- return component_class
-
-
-def register_plugin(module_name, name, description=None, author=None,
- license=None, version=None):
- import sys
-
- if module_name not in sys.modules:
- raise RuntimeError("cannot find module '{}' in loaded modules".format(module_name))
-
- utils._check_str(name)
-
- if description is not None:
- utils._check_str(description)
-
- if author is not None:
- utils._check_str(author)
-
- if license is not None:
- utils._check_str(license)
-
- if version is not None:
- if not _validate_version(version):
- raise ValueError('wrong version: expecting a tuple: (major, minor, patch) or (major, minor, patch, extra)')
-
- sys.modules[module_name]._bt_plugin_info = _PluginInfo(name, description,
- author, license,
- version)
-
-
-def _validate_version(version):
- if version is None:
- return True
-
- if not isinstance(version, tuple):
- return False
-
- if len(version) < 3 or len(version) > 4:
- return False
-
- if not isinstance(version[0], int):
- return False
-
- if not isinstance(version[1], int):
- return False
-
- if not isinstance(version[2], int):
- return False
-
- if len(version) == 4:
- if not isinstance(version[3], str):
- return False
-
- return True
-
-
-class _PluginInfo:
- def __init__(self, name, description, author, license, version):
- self.name = name
- self.description = description
- self.author = author
- self.license = license
- self.version = version
- self.comp_class_addrs = None
-
-
-# called by the BT plugin system
-def _try_load_plugin_module(path):
- import importlib.machinery
- import inspect
- import hashlib
-
- if path is None:
- raise TypeError('missing path')
-
- # In order to load the module uniquely from its path, even from
- # different files which have the same basename, we hash the path
- # and prefix with `bt_plugin_`. This is its key in sys.modules.
- h = hashlib.sha256()
- h.update(path.encode())
- module_name = 'bt_plugin_{}'.format(h.hexdigest())
-
- # try loading the module: any raised exception is catched by the caller
- mod = importlib.machinery.SourceFileLoader(module_name, path).load_module()
-
- # we have the module: look for its plugin info first
- if not hasattr(mod, '_bt_plugin_info'):
- raise RuntimeError("missing '_bt_plugin_info' module attribute")
-
- plugin_info = mod._bt_plugin_info
-
- # search for user component classes
- def is_user_comp_class(obj):
- if not inspect.isclass(obj):
- return False
-
- if not hasattr(obj, '_bt_plugin_component_class'):
- return False
-
- return True
-
- comp_class_entries = inspect.getmembers(mod, is_user_comp_class)
- plugin_info.comp_class_addrs = [entry[1].addr for entry in comp_class_entries]
- return plugin_info
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (C) 2017 - Francis Deslauriers <francis.deslauriers@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import sys
+
+from distutils.core import setup, Extension
+
+PY_PATH_WARN_MSG = """
+-------------------------------------WARNING------------------------------------
+The install directory used:\n ({})\nis not included in your PYTHONPATH.
+
+To add this directory to your Python search path permanently you can add the
+following command to your .bashrc/.zshrc:
+ export PYTHONPATH="${{PYTHONPATH}}:{}"
+--------------------------------------------------------------------------------
+"""
+
+def main():
+ babeltrace_ext = Extension('_native_bt',
+ sources=['bt2/native_bt.i', 'bt2/logging.c'],
+ libraries=['babeltrace', 'glib-2.0'],
+ extra_objects=['@top_builddir@/logging/.libs/libbabeltrace-logging.a',
+ '@top_builddir@/common/.libs/libbabeltrace-common.a'],)
+
+ dist = setup(name='bt2',
+ version='@PACKAGE_VERSION@',
+ description='Babeltrace 2 Python Bindings',
+ packages=['bt2'],
+ package_dir={'bt2': 'bt2'},
+ options={'build':
+ {
+ 'build_base': 'build',
+ 'build_lib': 'build/build_lib'
+ },
+ 'build_ext':
+ {
+ 'build_lib': 'build/build_lib'
+ }
+ },
+ url='http://diamon.org/babeltrace',
+ ext_modules=[babeltrace_ext],
+ license='MIT',
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: The MIT License',
+ 'Programming Language :: Python :: 3'
+ 'Topic :: System :: Logging',
+ ])
+
+# After the installation, we check that the install directory is included in
+# the Python search path and we print a warning message when it's not.
+# We need to do this because Python search path differs depending on the distro
+# and some distros don't include any /usr/local/ in the search path. This is
+# also useful for out-of-tree installs and tests.
+# It's only relevant to make this check on the `install` command.
+
+ if 'install' in dist.command_obj:
+ install_dir = dist.command_obj['install'].install_libbase
+ if install_dir not in sys.path:
+ # We can't consider this an error because if affects every
+ # distro differently. We only warn the user that some
+ # extra configuration is needed to use the bindings
+ print(PY_PATH_WARN_MSG.format(install_dir, install_dir))
+
+if __name__ == "__main__":
+ main()
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2016-2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.packet
-import bt2.event
-import abc
-import bt2
-
-
-def _create_from_ptr(stream_ptr):
- if native_bt.ctf_stream_is_writer(stream_ptr):
- import ctf_writer
-
- cls = ctf_writer._CtfWriterStream
- else:
- cls = _Stream
-
- return cls._create_from_ptr(stream_ptr)
-
-
-class _StreamBase(object._Object):
- @property
- def stream_class(self):
- stream_class_ptr = native_bt.ctf_stream_get_class(self._ptr)
- assert(stream_class_ptr)
- return bt2.StreamClass._create_from_ptr(stream_class_ptr)
-
- @property
- def name(self):
- return native_bt.ctf_stream_get_name(self._ptr)
-
- @property
- def id(self):
- id = native_bt.ctf_stream_get_id(self._ptr)
- return id if id >= 0 else None
-
- def __eq__(self, other):
- if self.addr == other.addr:
- return True
-
- return (self.name, self.id) == (other.name, other.id)
-
-
-class _Stream(_StreamBase):
- def create_packet(self):
- packet_ptr = native_bt.ctf_packet_create(self._ptr)
-
- if packet_ptr is None:
- raise bt2.CreationError('cannot create packet object')
-
- return bt2.packet._Packet._create_from_ptr(packet_ptr)
-
- def __eq__(self, other):
- if type(other) is not type(self):
- return False
-
- return _StreamBase.__eq__(self, other)
-
- def _copy(self):
- return self.stream_class(self.name, self.id)
-
- def __copy__(self):
- return self._copy()
-
- def __deepcopy__(self, memo):
- cpy = self._copy()
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.field_types
-import collections.abc
-import bt2.ctf_writer
-import bt2.stream
-import copy
-import bt2
-
-
-class _EventClassIterator(collections.abc.Iterator):
- def __init__(self, stream_class):
- self._stream_class = stream_class
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._stream_class):
- raise StopIteration
-
- ec_ptr = native_bt.ctf_stream_class_get_event_class_by_index(self._stream_class._ptr,
- self._at)
- assert(ec_ptr)
- ev_id = native_bt.ctf_event_class_get_id(ec_ptr)
- native_bt.put(ec_ptr)
- utils._handle_ret(ev_id, "cannot get event class object's ID")
- self._at += 1
- return ev_id
-
-
-class StreamClass(object._Object, collections.abc.Mapping):
- def __init__(self, name=None, id=None, packet_context_field_type=None,
- event_header_field_type=None, event_context_field_type=None,
- event_classes=None):
- ptr = native_bt.ctf_stream_class_create_empty(None)
-
- if ptr is None:
- raise bt2.CreationError('cannot create stream class object')
-
- super().__init__(ptr)
-
- if name is not None:
- self.name = name
-
- if id is not None:
- self.id = id
-
- if packet_context_field_type is not None:
- self.packet_context_field_type = packet_context_field_type
-
- if event_header_field_type is not None:
- self.event_header_field_type = event_header_field_type
-
- if event_context_field_type is not None:
- self.event_context_field_type = event_context_field_type
-
- if event_classes is not None:
- for event_class in event_classes:
- self.add_event_class(event_class)
-
- def __getitem__(self, key):
- utils._check_int64(key)
- ec_ptr = native_bt.ctf_stream_class_get_event_class_by_id(self._ptr,
- key)
-
- if ec_ptr is None:
- raise KeyError(key)
-
- return bt2.EventClass._create_from_ptr(ec_ptr)
-
- def __len__(self):
- count = native_bt.ctf_stream_class_get_event_class_count(self._ptr)
- assert(count >= 0)
- return count
-
- def __iter__(self):
- return _EventClassIterator(self)
-
- def add_event_class(self, event_class):
- utils._check_type(event_class, bt2.EventClass)
- ret = native_bt.ctf_stream_class_add_event_class(self._ptr, event_class._ptr)
- utils._handle_ret(ret, "cannot add event class object to stream class object's")
-
- @property
- def trace(self):
- tc_ptr = native_bt.ctf_stream_class_get_trace(self._ptr)
-
- if tc_ptr is not None:
- return bt2.Trace._create_from_ptr(tc_ptr)
-
- @property
- def name(self):
- return native_bt.ctf_stream_class_get_name(self._ptr)
-
- @name.setter
- def name(self, name):
- utils._check_str(name)
- ret = native_bt.ctf_stream_class_set_name(self._ptr, name)
- utils._handle_ret(ret, "cannot set stream class object's name")
-
- @property
- def id(self):
- id = native_bt.ctf_stream_class_get_id(self._ptr)
-
- if id < 0:
- return
-
- return id
-
- @id.setter
- def id(self, id):
- utils._check_int64(id)
- ret = native_bt.ctf_stream_class_set_id(self._ptr, id)
- utils._handle_ret(ret, "cannot set stream class object's ID")
-
- @property
- def clock(self):
- clock_ptr = native_bt.ctf_stream_class_get_clock(self._ptr)
-
- if clock_ptr is None:
- return
-
- return bt2.ctf_writer.CtfWriterClock._create_from_ptr(clock_ptr)
-
- @clock.setter
- def clock(self, clock):
- utils._check_type(clock, bt2.ctf_writer.CtfWriterClock)
- ret = native_bt.ctf_stream_class_set_clock(self._ptr, clock._ptr)
- utils._handle_ret(ret, "cannot set stream class object's CTF writer clock object")
-
- @property
- def packet_context_field_type(self):
- ft_ptr = native_bt.ctf_stream_class_get_packet_context_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return bt2.field_types._create_from_ptr(ft_ptr)
-
- @packet_context_field_type.setter
- def packet_context_field_type(self, packet_context_field_type):
- packet_context_field_type_ptr = None
-
- if packet_context_field_type is not None:
- utils._check_type(packet_context_field_type, bt2.field_types._FieldType)
- packet_context_field_type_ptr = packet_context_field_type._ptr
-
- ret = native_bt.ctf_stream_class_set_packet_context_type(self._ptr,
- packet_context_field_type_ptr)
- utils._handle_ret(ret, "cannot set stream class object's packet context field type")
-
- @property
- def event_header_field_type(self):
- ft_ptr = native_bt.ctf_stream_class_get_event_header_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return bt2.field_types._create_from_ptr(ft_ptr)
-
- @event_header_field_type.setter
- def event_header_field_type(self, event_header_field_type):
- event_header_field_type_ptr = None
-
- if event_header_field_type is not None:
- utils._check_type(event_header_field_type, bt2.field_types._FieldType)
- event_header_field_type_ptr = event_header_field_type._ptr
-
- ret = native_bt.ctf_stream_class_set_event_header_type(self._ptr,
- event_header_field_type_ptr)
- utils._handle_ret(ret, "cannot set stream class object's event header field type")
-
- @property
- def event_context_field_type(self):
- ft_ptr = native_bt.ctf_stream_class_get_event_context_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return bt2.field_types._create_from_ptr(ft_ptr)
-
- @event_context_field_type.setter
- def event_context_field_type(self, event_context_field_type):
- event_context_field_type_ptr = None
-
- if event_context_field_type is not None:
- utils._check_type(event_context_field_type, bt2.field_types._FieldType)
- event_context_field_type_ptr = event_context_field_type._ptr
-
- ret = native_bt.ctf_stream_class_set_event_context_type(self._ptr,
- event_context_field_type_ptr)
- utils._handle_ret(ret, "cannot set stream class object's event context field type")
-
- def __call__(self, name=None, id=None):
- if name is not None:
- utils._check_str(name)
-
- if id is None:
- stream_ptr = native_bt.ctf_stream_create(self._ptr, name)
- else:
- stream_ptr = native_bt.ctf_stream_create_with_id(self._ptr, name, id)
-
- if stream_ptr is None:
- raise bt2.CreationError('cannot create stream object')
-
- 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
-
- self_event_classes = list(self.values())
- other_event_classes = list(other.values())
- self_props = (
- self_event_classes,
- self.name,
- self.id,
- self.packet_context_field_type,
- self.event_header_field_type,
- self.event_context_field_type,
- self.clock,
- )
- other_props = (
- other_event_classes,
- other.name,
- other.id,
- other.packet_context_field_type,
- other.event_header_field_type,
- other.event_context_field_type,
- other.clock,
- )
-
- return self_props == other_props
-
- def _copy(self, ft_copy_func, ev_copy_func):
- cpy = StreamClass()
-
- if self.id is not None:
- cpy.id = self.id
-
- if self.name is not None:
- cpy.name = self.name
-
- if self.clock is not None:
- cpy.clock = self.clock
-
- cpy.packet_context_field_type = ft_copy_func(self.packet_context_field_type)
- cpy.event_header_field_type = ft_copy_func(self.event_header_field_type)
- cpy.event_context_field_type = ft_copy_func(self.event_context_field_type)
-
- for event_class in self.values():
- cpy.add_event_class(ev_copy_func(event_class))
-
- return cpy
-
- def __copy__(self):
- return self._copy(lambda ft: ft, copy.copy)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy, copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import bt2.field_types
-import collections.abc
-import bt2.values
-import bt2.stream
-import copy
-import bt2
-
-
-class _StreamClassIterator(collections.abc.Iterator):
- def __init__(self, trace):
- self._trace = trace
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._trace):
- raise StopIteration
-
- sc_ptr = native_bt.ctf_trace_get_stream_class_by_index(self._trace._ptr,
- self._at)
- assert(sc_ptr)
- id = native_bt.ctf_stream_class_get_id(sc_ptr)
- native_bt.put(sc_ptr)
- assert(id >= 0)
- self._at += 1
- return id
-
-
-class _TraceStreams(collections.abc.Sequence):
- def __init__(self, trace):
- self._trace = trace
-
- def __len__(self):
- count = native_bt.ctf_trace_get_stream_count(self._trace._ptr)
- assert(count >= 0)
- return count
-
- def __getitem__(self, index):
- utils._check_uint64(index)
-
- if index >= len(self):
- raise IndexError
-
- stream_ptr = native_bt.ctf_trace_get_stream_by_index(self._trace._ptr,
- index)
- assert(stream_ptr)
- return bt2.stream._create_from_ptr(stream_ptr)
-
-
-class _TraceClockClassesIterator(collections.abc.Iterator):
- def __init__(self, trace_clock_classes):
- self._trace_clock_classes = trace_clock_classes
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._trace_clock_classes):
- raise StopIteration
-
- trace_ptr = self._trace_clock_classes._trace._ptr
- cc_ptr = native_bt.ctf_trace_get_clock_class_by_index(trace_ptr, self._at)
- assert(cc_ptr)
- name = native_bt.ctf_clock_class_get_name(cc_ptr)
- native_bt.put(cc_ptr)
- assert(name is not None)
- self._at += 1
- return name
-
-
-class _TraceClockClasses(collections.abc.Mapping):
- def __init__(self, trace):
- self._trace = trace
-
- def __getitem__(self, key):
- utils._check_str(key)
- cc_ptr = native_bt.ctf_trace_get_clock_class_by_name(self._trace._ptr,
- key)
-
- if cc_ptr is None:
- raise KeyError(key)
-
- return bt2.ClockClass._create_from_ptr(cc_ptr)
-
- def __len__(self):
- count = native_bt.ctf_trace_get_clock_class_count(self._trace._ptr)
- assert(count >= 0)
- return count
-
- def __iter__(self):
- return _TraceClockClassesIterator(self)
-
-
-class _TraceEnvIterator(collections.abc.Iterator):
- def __init__(self, trace_env):
- self._trace_env = trace_env
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._trace_env):
- raise StopIteration
-
- trace_ptr = self._trace_env._trace._ptr
- entry_name = native_bt.ctf_trace_get_environment_field_name_by_index(trace_ptr,
- self._at)
- assert(entry_name is not None)
- self._at += 1
- return entry_name
-
-
-class _TraceEnv(collections.abc.MutableMapping):
- def __init__(self, trace):
- self._trace = trace
-
- def __getitem__(self, key):
- utils._check_str(key)
- value_ptr = native_bt.ctf_trace_get_environment_field_value_by_name(self._trace._ptr,
- key)
-
- if value_ptr is None:
- raise KeyError(key)
-
- return bt2.values._create_from_ptr(value_ptr)
-
- def __setitem__(self, key, value):
- utils._check_str(key)
- value = bt2.create_value(value)
- ret = native_bt.ctf_trace_set_environment_field(self._trace._ptr,
- key, value._ptr)
- utils._handle_ret(ret, "cannot set trace class object's environment entry")
-
- def __delitem__(self, key):
- raise NotImplementedError
-
- def __len__(self):
- count = native_bt.ctf_trace_get_environment_field_count(self._trace._ptr)
- assert(count >= 0)
- return count
-
- def __iter__(self):
- return _TraceEnvIterator(self)
-
-
-class Trace(object._Object, collections.abc.Mapping):
- def __init__(self, name=None, native_byte_order=None, env=None,
- packet_header_field_type=None, clock_classes=None,
- stream_classes=None):
- ptr = native_bt.ctf_trace_create()
-
- if ptr is None:
- raise bt2.CreationError('cannot create trace class object')
-
- super().__init__(ptr)
-
- if name is not None:
- self.name = name
-
- if native_byte_order is not None:
- self.native_byte_order = native_byte_order
-
- if packet_header_field_type is not None:
- self.packet_header_field_type = packet_header_field_type
-
- if env is not None:
- for key, value in env.items():
- self.env[key] = value
-
- if clock_classes is not None:
- for clock_class in clock_classes:
- self.add_clock_class(clock_class)
-
- if stream_classes is not None:
- for stream_class in stream_classes:
- self.add_stream_class(stream_class)
-
- def __getitem__(self, key):
- utils._check_int64(key)
- sc_ptr = native_bt.ctf_trace_get_stream_class_by_id(self._ptr, key)
-
- if sc_ptr is None:
- raise KeyError(key)
-
- return bt2.StreamClass._create_from_ptr(sc_ptr)
-
- def __len__(self):
- count = native_bt.ctf_trace_get_stream_class_count(self._ptr)
- assert(count >= 0)
- return count
-
- def __iter__(self):
- return _StreamClassIterator(self)
-
- def add_stream_class(self, stream_class):
- utils._check_type(stream_class, bt2.StreamClass)
- ret = native_bt.ctf_trace_add_stream_class(self._ptr, stream_class._ptr)
- utils._handle_ret(ret, "cannot add stream class object to trace class object")
-
- @property
- def name(self):
- return native_bt.ctf_trace_get_name(self._ptr)
-
- @name.setter
- def name(self, name):
- utils._check_str(name)
- ret = native_bt.ctf_trace_set_name(self._ptr, name)
- utils._handle_ret(ret, "cannot set trace class object's name")
-
- @property
- def native_byte_order(self):
- bo = native_bt.ctf_trace_get_native_byte_order(self._ptr)
- assert(bo >= 0)
- return bo
-
- @native_byte_order.setter
- def native_byte_order(self, native_byte_order):
- utils._check_int(native_byte_order)
- ret = native_bt.ctf_trace_set_native_byte_order(self._ptr, native_byte_order)
- utils._handle_ret(ret, "cannot set trace class object's native byte order")
-
- @property
- def is_static(self):
- is_static = native_bt.ctf_trace_is_static(self._ptr)
- return is_static > 0
-
- def set_is_static(self):
- ret = native_bt.ctf_trace_set_is_static(self._ptr)
- utils._handle_ret(ret, "cannot set trace object as static")
-
- @property
- def env(self):
- return _TraceEnv(self)
-
- @property
- def clock_classes(self):
- return _TraceClockClasses(self)
-
- def add_clock_class(self, clock_class):
- utils._check_type(clock_class, bt2.ClockClass)
- ret = native_bt.ctf_trace_add_clock_class(self._ptr, clock_class._ptr)
- utils._handle_ret(ret, "cannot add clock class object to trace class object")
-
- @property
- def streams(self):
- return _TraceStreams(self)
-
- @property
- def packet_header_field_type(self):
- ft_ptr = native_bt.ctf_trace_get_packet_header_type(self._ptr)
-
- if ft_ptr is None:
- return
-
- return bt2.field_types._create_from_ptr(ft_ptr)
-
- @packet_header_field_type.setter
- def packet_header_field_type(self, packet_header_field_type):
- packet_header_field_type_ptr = None
-
- if packet_header_field_type is not None:
- utils._check_type(packet_header_field_type, bt2.field_types._FieldType)
- packet_header_field_type_ptr = packet_header_field_type._ptr
-
- ret = native_bt.ctf_trace_set_packet_header_type(self._ptr,
- packet_header_field_type_ptr)
- utils._handle_ret(ret, "cannot set trace class object's packet header field type")
-
- def __eq__(self, other):
- if type(other) is not type(self):
- # not comparing apples to apples
- return False
-
- if self.addr == other.addr:
- return True
-
- self_stream_classes = list(self.values())
- self_clock_classes = list(self.clock_classes.values())
- self_env = {key: val for key, val in self.env.items()}
- other_stream_classes = list(other.values())
- other_clock_classes = list(other.clock_classes.values())
- other_env = {key: val for key, val in other.env.items()}
- self_props = (
- self_stream_classes,
- self_clock_classes,
- self_env,
- self.name,
- self.native_byte_order,
- self.packet_header_field_type,
- )
- other_props = (
- other_stream_classes,
- other_clock_classes,
- other_env,
- other.name,
- other.native_byte_order,
- other.packet_header_field_type,
- )
- return self_props == other_props
-
- def _copy(self, gen_copy_func, sc_copy_func):
- cpy = Trace()
-
- if self.name is not None:
- cpy.name = self.name
-
- cpy.packet_header_field_type = gen_copy_func(self.packet_header_field_type)
-
- for key, val in self.env.items():
- cpy.env[key] = gen_copy_func(val)
-
- for clock_class in self.clock_classes.values():
- cpy.add_clock_class(gen_copy_func(clock_class))
-
- for stream_class in self.values():
- cpy.add_stream_class(sc_copy_func(stream_class))
-
- return cpy
-
- def __copy__(self):
- return self._copy(lambda obj: obj, copy.copy)
-
- def __deepcopy__(self, memo):
- cpy = self._copy(copy.deepcopy, copy.deepcopy)
- memo[id(self)] = cpy
- return cpy
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-import bt2
-
-
-def _check_bool(o):
- if not isinstance(o, bool):
- raise TypeError("'{}' is not a 'bool' object".format(o.__class__.__name__))
-
-
-def _check_int(o):
- if not isinstance(o, int):
- raise TypeError("'{}' is not an 'int' object".format(o.__class__.__name__))
-
-
-def _check_float(o):
- if not isinstance(o, float):
- raise TypeError("'{}' is not a 'float' object".format(o.__class__.__name__))
-
-
-def _check_str(o):
- if not isinstance(o, str):
- raise TypeError("'{}' is not a 'str' object".format(o.__class__.__name__))
-
-
-def _check_type(o, expected_type):
- if not isinstance(o, expected_type):
- raise TypeError("'{}' is not a '{}' object".format(o.__class__.__name__,
- expected_type))
-
-
-def _is_int64(v):
- _check_int(v)
- return v >= -(2**63) and v <= (2**63 - 1)
-
-
-def _is_uint64(v):
- _check_int(v)
- return v >= 0 and v <= (2**64 - 1)
-
-
-def _check_int64(v, msg=None):
- if not _is_int64(v):
- if msg is None:
- msg = 'expecting a signed 64-bit integral value'
-
- msg += ' (got {})'.format(v)
- raise ValueError(msg)
-
-
-def _check_uint64(v, msg=None):
- if not _is_uint64(v):
- if msg is None:
- msg = 'expecting an unsigned 64-bit integral value'
-
- msg += ' (got {})'.format(v)
- raise ValueError(msg)
-
-
-def _is_m1ull(v):
- return v == 18446744073709551615
-
-
-def _is_pow2(v):
- return v != 0 and ((v & (v - 1)) == 0)
-
-
-def _check_alignment(a):
- _check_uint64(a)
-
- if not _is_pow2(a):
- raise ValueError('{} is not a power of two'.format(a))
-
-
-def _handle_ret(ret, msg=None):
- if int(ret) < 0:
- if msg is None:
- error = bt2.Error()
- else:
- error = bt2.Error(msg)
-
- raise error
-
-
-def _handle_ptr(ptr, msg=None):
- if ptr is None:
- if msg is None:
- error = bt2.Error()
- else:
- error = bt2.Error(msg)
-
- raise error
+++ /dev/null
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-from bt2 import native_bt, object, utils
-import collections.abc
-import functools
-import numbers
-import math
-import abc
-import bt2
-
-
-def _handle_status(status, obj_name):
- if status >= 0:
- return
-
- if status == native_bt.VALUE_STATUS_FROZEN:
- raise bt2.Frozen('{} value object is frozen'.format(obj_name))
- elif status == native_bt.VALUE_STATUS_INVAL:
- # In practice, this should never happen, because arguments
- # should always be validated in this Python module before
- # calling the native functions.
- raise ValueError('unexpected invalid argument')
- else:
- # In practice, this should never happen, because arguments
- # should always be validated in this Python module before
- # calling the native functions.
- raise RuntimeError('unexpected error')
-
-
-def _create_from_ptr(ptr):
- if ptr is None or ptr == native_bt.value_null:
- return
-
- typeid = native_bt.value_get_type(ptr)
- return _TYPE_TO_OBJ[typeid]._create_from_ptr(ptr)
-
-
-def create_value(value):
- if value is None:
- # null value object
- return
-
- if isinstance(value, _Value):
- return value
-
- if isinstance(value, bool):
- return BoolValue(value)
-
- if isinstance(value, int):
- return IntegerValue(value)
-
- if isinstance(value, float):
- return FloatValue(value)
-
- if isinstance(value, str):
- return StringValue(value)
-
- try:
- return MapValue(value)
- except:
- pass
-
- try:
- return ArrayValue(value)
- except:
- pass
-
- raise TypeError("cannot create value object from '{}' object".format(value.__class__.__name__))
-
-
-class _Value(object._Object, object._Freezable, metaclass=abc.ABCMeta):
- def __eq__(self, other):
- if other is None:
- # self is never the null value object
- return False
-
- # try type-specific comparison first
- spec_eq = self._spec_eq(other)
-
- if spec_eq is not None:
- return spec_eq
-
- if not isinstance(other, _Value):
- # not comparing apples to apples
- return False
-
- # fall back to native comparison function
- return native_bt.value_compare(self._ptr, other._ptr)
-
- def __ne__(self, other):
- return not (self == other)
-
- @abc.abstractmethod
- def _spec_eq(self, other):
- pass
-
- def _handle_status(self, status):
- _handle_status(status, self._NAME)
-
- def _check_create_status(self, ptr):
- if ptr is None:
- raise bt2.CreationError('cannot create {} value object'.format(self._NAME.lower()))
-
- def _is_frozen(self):
- return native_bt.value_is_frozen(self._ptr)
-
- def _freeze(self):
- status = native_bt.value_freeze(self._ptr)
- self._handle_status(status)
-
-
-class _BasicCopy:
- def __copy__(self):
- return self.__class__(self.value)
-
- def __deepcopy__(self, memo):
- copy = self.__copy__()
- memo[id(self)] = copy
- return copy
-
-
-@functools.total_ordering
-class _NumericValue(_Value, _BasicCopy):
- @staticmethod
- def _extract_value(other):
- if isinstance(other, _NumericValue):
- return other.value
-
- if other is True or other is False:
- return other
-
- if isinstance(other, numbers.Integral):
- return int(other)
-
- if isinstance(other, numbers.Real):
- return float(other)
-
- if isinstance(other, numbers.Complex):
- return complex(other)
-
- raise TypeError("'{}' object is not a number object".format(other.__class__.__name__))
-
- def __int__(self):
- return int(self.value)
-
- def __float__(self):
- return float(self.value)
-
- def __str__(self):
- return str(self.value)
-
- def __lt__(self, other):
- if not isinstance(other, numbers.Number):
- raise TypeError('unorderable types: {}() < {}()'.format(self.__class__.__name__,
- other.__class__.__name__))
-
- return self.value < float(other)
-
- def __le__(self, other):
- if not isinstance(other, numbers.Number):
- raise TypeError('unorderable types: {}() <= {}()'.format(self.__class__.__name__,
- other.__class__.__name__))
-
- return self.value <= float(other)
-
- def _spec_eq(self, other):
- pass
-
- def __eq__(self, other):
- if not isinstance(other, numbers.Number):
- return False
-
- return self.value == complex(other)
-
- def __rmod__(self, other):
- return self._extract_value(other) % self.value
-
- def __mod__(self, other):
- return self.value % self._extract_value(other)
-
- def __rfloordiv__(self, other):
- return self._extract_value(other) // self.value
-
- def __floordiv__(self, other):
- return self.value // self._extract_value(other)
-
- def __round__(self, ndigits=None):
- if ndigits is None:
- return round(self.value)
- else:
- return round(self.value, ndigits)
-
- def __ceil__(self):
- return math.ceil(self.value)
-
- def __floor__(self):
- return math.floor(self.value)
-
- def __trunc__(self):
- return int(self.value)
-
- def __abs__(self):
- return abs(self.value)
-
- def __add__(self, other):
- return self.value + self._extract_value(other)
-
- def __radd__(self, other):
- return self.__add__(other)
-
- def __neg__(self):
- return -self.value
-
- def __pos__(self):
- return +self.value
-
- def __mul__(self, other):
- return self.value * self._extract_value(other)
-
- def __rmul__(self, other):
- return self.__mul__(other)
-
- def __truediv__(self, other):
- return self.value / self._extract_value(other)
-
- def __rtruediv__(self, other):
- return self._extract_value(other) / self.value
-
- def __pow__(self, exponent):
- return self.value ** self._extract_value(exponent)
-
- def __rpow__(self, base):
- return self._extract_value(base) ** self.value
-
- def __iadd__(self, other):
- self.value = self + other
- return self
-
- def __isub__(self, other):
- self.value = self - other
- return self
-
- def __imul__(self, other):
- self.value = self * other
- return self
-
- def __itruediv__(self, other):
- self.value = self / other
- return self
-
- def __ifloordiv__(self, other):
- self.value = self // other
- return self
-
- def __imod__(self, other):
- self.value = self % other
- return self
-
- def __ipow__(self, other):
- self.value = self ** other
- return self
-
-
-class _IntegralValue(_NumericValue, numbers.Integral):
- def __lshift__(self, other):
- return self.value << self._extract_value(other)
-
- def __rlshift__(self, other):
- return self._extract_value(other) << self.value
-
- def __rshift__(self, other):
- return self.value >> self._extract_value(other)
-
- def __rrshift__(self, other):
- return self._extract_value(other) >> self.value
-
- def __and__(self, other):
- return self.value & self._extract_value(other)
-
- def __rand__(self, other):
- return self._extract_value(other) & self.value
-
- def __xor__(self, other):
- return self.value ^ self._extract_value(other)
-
- def __rxor__(self, other):
- return self._extract_value(other) ^ self.value
-
- def __or__(self, other):
- return self.value | self._extract_value(other)
-
- def __ror__(self, other):
- return self._extract_value(other) | self.value
-
- def __invert__(self):
- return ~self.value
-
- def __ilshift__(self, other):
- self.value = self << other
- return self
-
- def __irshift__(self, other):
- self.value = self >> other
- return self
-
- def __iand__(self, other):
- self.value = self & other
- return self
-
- def __ixor__(self, other):
- self.value = self ^ other
- return self
-
- def __ior__(self, other):
- self.value = self | other
- return self
-
-
-class _RealValue(_NumericValue, numbers.Real):
- pass
-
-
-class BoolValue(_Value, _BasicCopy):
- _NAME = 'Boolean'
-
- def __init__(self, value=None):
- if value is None:
- ptr = native_bt.value_bool_create()
- else:
- ptr = native_bt.value_bool_create_init(self._value_to_bool(value))
-
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- def _spec_eq(self, other):
- if isinstance(other, numbers.Number):
- return self.value == bool(other)
-
- def __bool__(self):
- return self.value
-
- def __str__(self):
- return str(self.value)
-
- def _value_to_bool(self, value):
- if isinstance(value, BoolValue):
- value = value.value
-
- if not isinstance(value, bool):
- raise TypeError("'{}' object is not a 'bool' or 'BoolValue' object".format(value.__class__))
-
- return int(value)
-
- @property
- def value(self):
- status, value = native_bt.value_bool_get(self._ptr)
- assert(status == native_bt.VALUE_STATUS_OK)
- return value > 0
-
- @value.setter
- def value(self, value):
- status = native_bt.value_bool_set(self._ptr, self._value_to_bool(value))
- self._handle_status(status)
-
-
-class IntegerValue(_IntegralValue):
- _NAME = 'Integer'
-
- def __init__(self, value=None):
- if value is None:
- ptr = native_bt.value_integer_create()
- else:
- ptr = native_bt.value_integer_create_init(self._value_to_int(value))
-
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- def _value_to_int(self, value):
- if not isinstance(value, numbers.Real):
- raise TypeError('expecting a number object')
-
- value = int(value)
- utils._check_int64(value)
- return value
-
- @property
- def value(self):
- status, value = native_bt.value_integer_get(self._ptr)
- assert(status == native_bt.VALUE_STATUS_OK)
- return value
-
- @value.setter
- def value(self, value):
- status = native_bt.value_integer_set(self._ptr, self._value_to_int(value))
- self._handle_status(status)
-
-
-class FloatValue(_RealValue):
- _NAME = 'Floating point number'
-
- def __init__(self, value=None):
- if value is None:
- ptr = native_bt.value_float_create()
- else:
- value = self._value_to_float(value)
- ptr = native_bt.value_float_create_init(value)
-
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- def _value_to_float(self, value):
- if not isinstance(value, numbers.Real):
- raise TypeError("expecting a real number object")
-
- return float(value)
-
- @property
- def value(self):
- status, value = native_bt.value_float_get(self._ptr)
- assert(status == native_bt.VALUE_STATUS_OK)
- return value
-
- @value.setter
- def value(self, value):
- value = self._value_to_float(value)
- status = native_bt.value_float_set(self._ptr, value)
- self._handle_status(status)
-
-
-@functools.total_ordering
-class StringValue(_BasicCopy, collections.abc.Sequence, _Value):
- _NAME = 'String'
-
- def __init__(self, value=None):
- if value is None:
- ptr = native_bt.value_string_create()
- else:
- ptr = native_bt.value_string_create_init(self._value_to_str(value))
-
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- def _value_to_str(self, value):
- if isinstance(value, self.__class__):
- value = value.value
-
- utils._check_str(value)
- return value
-
- @property
- def value(self):
- status, value = native_bt.value_string_get(self._ptr)
- assert(status == native_bt.VALUE_STATUS_OK)
- return value
-
- @value.setter
- def value(self, value):
- status = native_bt.value_string_set(self._ptr, self._value_to_str(value))
- self._handle_status(status)
-
- def _spec_eq(self, other):
- try:
- return self.value == self._value_to_str(other)
- except:
- return
-
- def __le__(self, other):
- return self.value <= self._value_to_str(other)
-
- def __lt__(self, other):
- return self.value < self._value_to_str(other)
-
- def __bool__(self):
- return bool(self.value)
-
- def __str__(self):
- return self.value
-
- def __getitem__(self, index):
- return self.value[index]
-
- def __len__(self):
- return len(self.value)
-
- def __iadd__(self, value):
- curvalue = self.value
- curvalue += self._value_to_str(value)
- self.value = curvalue
- return self
-
-
-class _Container:
- def __bool__(self):
- return len(self) != 0
-
- def __copy__(self):
- return self.__class__(self)
-
- def __deepcopy__(self, memo):
- ptr = native_bt.value_copy(self._ptr)
-
- if ptr is None:
- raise RuntimeError('unexpected error: cannot deep-copy {} value object'.format(self._NAME))
-
- copy = self.__class__._create_from_ptr(ptr)
- memo[id(self)] = copy
- return copy
-
- def __delitem__(self, index):
- raise NotImplementedError
-
-
-class ArrayValue(_Container, collections.abc.MutableSequence, _Value):
- _NAME = 'Array'
-
- def __init__(self, value=None):
- ptr = native_bt.value_array_create()
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- # Python will raise a TypeError if there's anything wrong with
- # the iterable protocol.
- if value is not None:
- for elem in value:
- self.append(elem)
-
- def _spec_eq(self, other):
- try:
- if len(self) != len(other):
- # early mismatch
- return False
-
- for self_elem, other_elem in zip(self, other):
- if self_elem != other_elem:
- return False
-
- return True
- except:
- return
-
- def __len__(self):
- size = native_bt.value_array_size(self._ptr)
- assert(size >= 0)
- return size
-
- def _check_index(self, index):
- # TODO: support slices also
- if not isinstance(index, numbers.Integral):
- raise TypeError("'{}' object is not an integral number object: invalid index".format(index.__class__.__name__))
-
- index = int(index)
-
- if index < 0 or index >= len(self):
- raise IndexError('array value object index is out of range')
-
- def __getitem__(self, index):
- self._check_index(index)
- ptr = native_bt.value_array_get(self._ptr, index)
- assert(ptr)
- return _create_from_ptr(ptr)
-
- def __setitem__(self, index, value):
- self._check_index(index)
- value = create_value(value)
-
- if value is None:
- ptr = native_bt.value_null
- else:
- ptr = value._ptr
-
- status = native_bt.value_array_set(self._ptr, index, ptr)
- self._handle_status(status)
-
- def append(self, value):
- value = create_value(value)
-
- if value is None:
- ptr = native_bt.value_null
- else:
- ptr = value._ptr
-
- status = native_bt.value_array_append(self._ptr, ptr)
- self._handle_status(status)
-
- def __iadd__(self, iterable):
- # Python will raise a TypeError if there's anything wrong with
- # the iterable protocol.
- for elem in iterable:
- self.append(elem)
-
- return self
-
- def __str__(self):
- strings = []
-
- for elem in self:
- if isinstance(elem, StringValue):
- strings.append(repr(elem.value))
- else:
- strings.append(str(elem))
-
- return '[{}]'.format(', '.join(strings))
-
- def insert(self, value):
- raise NotImplementedError
-
-
-class _MapValueKeyIterator(collections.abc.Iterator):
- def __init__(self, map_obj):
- self._map_obj = map_obj
- self._at = 0
- keys_ptr = native_bt.value_map_get_keys_private(map_obj._ptr)
-
- if keys_ptr is None:
- raise RuntimeError('unexpected error: cannot get map value object keys')
-
- self._keys = _create_from_ptr(keys_ptr)
-
- def __next__(self):
- if self._at == len(self._map_obj):
- raise StopIteration
-
- key = self._keys[self._at]
- self._at += 1
- return str(key)
-
-
-class MapValue(_Container, collections.abc.MutableMapping, _Value):
- _NAME = 'Map'
-
- def __init__(self, value=None):
- ptr = native_bt.value_map_create()
- self._check_create_status(ptr)
- super().__init__(ptr)
-
- # Python will raise a TypeError if there's anything wrong with
- # the iterable/mapping protocol.
- if value is not None:
- for key, elem in value.items():
- self[key] = elem
-
- def __eq__(self, other):
- return _Value.__eq__(self, other)
-
- def __ne__(self, other):
- return _Value.__ne__(self, other)
-
- def _spec_eq(self, other):
- try:
- if len(self) != len(other):
- # early mismatch
- return False
-
- for self_key in self:
- if self_key not in other:
- return False
-
- self_value = self[self_key]
- other_value = other[self_key]
-
- if self_value != other_value:
- return False
-
- return True
- except:
- return
-
- def __len__(self):
- size = native_bt.value_map_size(self._ptr)
- assert(size >= 0)
- return size
-
- def __contains__(self, key):
- self._check_key_type(key)
- return native_bt.value_map_has_key(self._ptr, key)
-
- def _check_key_type(self, key):
- utils._check_str(key)
-
- def _check_key(self, key):
- if key not in self:
- raise KeyError(key)
-
- def __getitem__(self, key):
- self._check_key(key)
- ptr = native_bt.value_map_get(self._ptr, key)
- assert(ptr)
- return _create_from_ptr(ptr)
-
- def __iter__(self):
- return _MapValueKeyIterator(self)
-
- def __setitem__(self, key, value):
- self._check_key_type(key)
- value = create_value(value)
-
- if value is None:
- ptr = native_bt.value_null
- else:
- ptr = value._ptr
-
- status = native_bt.value_map_insert(self._ptr, key, ptr)
- self._handle_status(status)
-
- def __str__(self):
- strings = []
-
- for key, elem in self.items():
- if isinstance(elem, StringValue):
- value = repr(elem.value)
- else:
- value = str(elem)
-
- strings.append('{}: {}'.format(repr(key), value))
-
- return '{{{}}}'.format(', '.join(strings))
-
-
-_TYPE_TO_OBJ = {
- native_bt.VALUE_TYPE_BOOL: BoolValue,
- native_bt.VALUE_TYPE_INTEGER: IntegerValue,
- native_bt.VALUE_TYPE_FLOAT: FloatValue,
- native_bt.VALUE_TYPE_STRING: StringValue,
- native_bt.VALUE_TYPE_ARRAY: ArrayValue,
- native_bt.VALUE_TYPE_MAP: MapValue,
-}
Makefile
bindings/python/Makefile
bindings/python/bt2/Makefile
- bindings/python/bt2/__init__.py
+ bindings/python/bt2/setup.py
+ bindings/python/bt2/bt2/__init__.py
common/Makefile
compat/Makefile
cli/Makefile
export BABELTRACE_PYTHON_BT2_NO_TRACEBACK=1
export TEST_PLUGIN_PLUGINS_PATH="${BT_BUILD_PATH}/plugins"
export BABELTRACE_PLUGIN_PATH="${BT_BUILD_PATH}/plugins/ctf:${BT_BUILD_PATH}/plugins/utils:${BT_BUILD_PATH}/plugins/text"
-PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python"
-BT2_NATIVE_LIBS_DIR="${BT_BUILD_PATH}/bindings/python/bt2/.libs"
+export LD_LIBRARY_PATH="${BT_BUILD_PATH}/lib/.libs"
+PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python/bt2/build/build_lib"
TESTS_UTILS_PYTHON_DIR="${BT_SRC_PATH}/tests/utils/python"
TESTRUNNER_PY="${BT_SRC_PATH}/tests/utils/python/testrunner.py"
THIS_DIR="${BT_SRC_PATH}/tests/bindings/python/bt2"
fi
-PYTHONPATH="$PYTHON_BUILD_DIR:$BT2_NATIVE_LIBS_DIR:$TESTS_UTILS_PYTHON_DIR" \
+PYTHONPATH="$PYTHON_BUILD_DIR:$TESTS_UTILS_PYTHON_DIR" \
"$EXEC" "$TESTRUNNER_PY" "$THIS_DIR"
res=$?