Fix Python: Add a comment warning about an API limitation
[babeltrace.git] / bindings / python / babeltrace.i.in
index aaa400aab717754d9c37c95c28a2f63a8abef852..5142952ec5fdeac715a28e01510354b29ed68f07 100644 (file)
@@ -60,6 +60,7 @@ trace to it."
 typedef unsigned long long uint64_t;
 typedef long long int64_t;
 typedef int bt_intern_str;
+typedef int64_t ssize_t;
 
 /* =================================================================
                PYTHON-COMPLEMENTS.H
@@ -90,6 +91,12 @@ struct definition_array *_bt_python_get_array_from_def(
                struct bt_definition *field);
 struct definition_sequence *_bt_python_get_sequence_from_def(
                struct bt_definition *field);
+struct bt_declaration *_bt_python_get_array_element_declaration(
+               struct bt_declaration *field);
+struct bt_declaration *_bt_python_get_sequence_element_declaration(
+               struct bt_declaration *field);
+const char *_bt_python_get_array_string(struct bt_definition *field);
+const char *_bt_python_get_sequence_string(struct bt_definition *field);
 int _bt_python_field_integer_get_signedness(const struct bt_ctf_field *field);
 enum ctf_type_id _bt_python_get_field_type(const struct bt_ctf_field *field);
 
@@ -204,6 +211,17 @@ class TraceCollection:
                """
                Generator function to iterate over the events of open in the current
                TraceCollection.
+
+               Due to limitations of the native Babeltrace API, only one event
+               may be "alive" at a time (i.e. a user should never store a copy
+               of the events returned by this function for ulterior use). Users
+               shall make sure to copy the information they need from an event
+               before accessing the next one.
+
+               Furthermore, event objects become invalid when the generator goes
+               out of scope as the underlying iterator will be reclaimed. Using an
+               event after the the generator has gone out of scope may result in a
+               crash or data corruption.
                """
                begin_pos_ptr = _bt_iter_pos()
                end_pos_ptr = _bt_iter_pos()
@@ -386,7 +404,7 @@ int bt_ctf_event_get_handle_id(const struct bt_ctf_event *event);
 
 %pythoncode%{
 
-# Based on enum bt_clock_type in clock-type.h­
+# Based on enum bt_clock_type in clock-type.h
 class ClockType:
        CLOCK_CYCLES = 0
        CLOCK_REAL = 1
@@ -935,11 +953,27 @@ class ArrayFieldDeclaration(FieldDeclaration):
                """
                return _bt_ctf_get_array_len(self._fd)
 
+       @property
+       def element_declaration(self):
+               """
+               Return element declaration.
+               """
+               field_decl_ptr = _bt_python_get_array_element_declaration(self._fd)
+               return _create_field_declaration(field_decl_ptr, "", self.scope)
+
 class SequenceFieldDeclaration(FieldDeclaration):
        """Do not instantiate."""
        def __init__(self):
                raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
 
+       @property
+       def element_declaration(self):
+               """
+               Return element declaration.
+               """
+               field_decl_ptr = _bt_python_get_sequence_element_declaration(self._fd)
+               return _create_field_declaration(field_decl_ptr, "", self.scope)
+
 class FloatFieldDeclaration(FieldDeclaration):
        """Do not instantiate."""
        def __init__(self):
@@ -1015,7 +1049,7 @@ class _Definition(object):
                """Return the name of a field or None on error."""
                return _bt_ctf_field_name(self._d)
 
-       @property       
+       @property
        def type(self):
                """Return the type of a field or -1 if unknown."""
                return _bt_ctf_field_type(_bt_ctf_get_decl_from_def(self._d))
@@ -1145,13 +1179,20 @@ class _Definition(object):
                """
                id = self.type
                value = None
+
                if id == CTFTypeId.STRING:
                        value = self._get_str()
                elif id == CTFTypeId.ARRAY:
-                       value = []
-                       for i in range(self.declaration.length):
-                               element = self._get_array_element_at(i)
-                               value.append(element.value)
+                       element_decl = self.declaration.element_declaration
+                       if ((element_decl.type == CTFTypeId.INTEGER
+                               and element_decl.length == 8)
+                               and (element_decl.encoding == CTFStringEncoding.ASCII or element_decl.encoding == CTFStringEncoding.UTF8)):
+                               value = _bt_python_get_array_string(self._d)
+                       else:
+                               value = []
+                               for i in range(self.declaration.length):
+                                       element = self._get_array_element_at(i)
+                                       value.append(element.value)
                elif id == CTFTypeId.INTEGER:
                        if self.declaration.signedness == 0:
                                value = self._get_uint64()
@@ -1160,11 +1201,17 @@ class _Definition(object):
                elif id == CTFTypeId.ENUM:
                        value = self._get_enum_str()
                elif id == CTFTypeId.SEQUENCE:
-                       seq_len = self._get_sequence_len()
-                       value = []
-                       for i in range(seq_len):
-                               evDef = self._get_sequence_element_at(i)
-                               value.append(evDef.value)
+                       element_decl = self.declaration.element_declaration
+                       if ((element_decl.type == CTFTypeId.INTEGER
+                               and element_decl.length == 8)
+                               and (element_decl.encoding == CTFStringEncoding.ASCII or element_decl.encoding == CTFStringEncoding.UTF8)):
+                               value = _bt_python_get_sequence_string(self._d)
+                       else:
+                               seq_len = self._get_sequence_len()
+                               value = []
+                               for i in range(seq_len):
+                                       evDef = self._get_sequence_element_at(i)
+                                       value.append(evDef.value)
                elif id == CTFTypeId.FLOAT:
                        value = self._get_float()
                elif id == CTFTypeId.VARIANT:
@@ -1178,7 +1225,7 @@ class _Definition(object):
                                value[member.name] = member.value
 
                if field_error():
-                       raise FieldError("Error occurred while accessing field {} of type {}".format(self.name, CTFTypeId.type_name(self.declaration.type)))
+                       raise FieldError("Error occurred while accessing field {} of type {}".format(self.name, CTFTypeId.type_name(id)))
                return value
 
        @property
@@ -1920,9 +1967,9 @@ class CTFWriter:
                """
                @length.setter
                def length(self, length_field):
-                       if not isinstance(length, CTFWriter.IntegerField):
+                       if not isinstance(length_field, CTFWriter.IntegerField):
                                raise TypeError("Invalid length field.")
-                       ret = _bt_ctf_field_sequence_set_length(self._f, length._f)
+                       ret = _bt_ctf_field_sequence_set_length(self._f, length_field._f)
                        if ret < 0:
                                raise ValueError("Could not set sequence length.")
 
@@ -1993,7 +2040,7 @@ class CTFWriter:
                def set_payload(self, field_name, value_field):
                        if not isinstance(value, CTFWriter.Field):
                                raise TypeError("Invalid value type.")
-                       ret = _bt_ctf_event_set_payload(self._e, str(field_name), value._f)
+                       ret = _bt_ctf_event_set_payload(self._e, str(field_name), value_field._f)
                        if ret < 0:
                                raise ValueError("Could not set event field payload.")
 
@@ -2069,9 +2116,7 @@ class CTFWriter:
                Increase the current packet's discarded event count.
                """
                def append_discarded_events(self, event_count):
-                       ret = _bt_ctf_stream_append_discarded_events(self._s, event_count)
-                       if ret < 0:
-                               raise ValueError("Could not append discarded events.")
+                       _bt_ctf_stream_append_discarded_events(self._s, event_count)
 
                """
                Append "event" to the stream's current packet. The stream's associated clock
This page took 0.024919 seconds and 4 git commands to generate.