Fix: variable declaration shadows previously declared variable
[babeltrace.git] / plugins / ctf / common / notif-iter / notif-iter.c
index 87e0581ddb63ef2f6b3ccf15eb582818ad92cdb1..a5d9e5c8aeaf1235510ccf70ac9f238f4f53b64c 100644 (file)
 #include <stdbool.h>
 #include <assert.h>
 #include <string.h>
-#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/babeltrace.h>
 #include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
 #include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/graph/notification-packet.h>
-#include <babeltrace/graph/notification-event.h>
-#include <babeltrace/graph/notification-stream.h>
-#include <babeltrace/graph/clock-class-priority-map.h>
-#include <babeltrace/ref.h>
 #include <glib.h>
 #include <stdlib.h>
 
@@ -162,6 +150,9 @@ struct bt_ctf_notif_iter {
        /* Current packet (NULL if not created yet) */
        struct bt_ctf_packet *packet;
 
+       /* Current stream (NULL if not set yet) */
+       struct bt_ctf_stream *stream;
+
        /*
         * Current timestamp_end field (to consider before switching packets).
         */
@@ -208,6 +199,9 @@ struct bt_ctf_notif_iter {
 
                /* Current position from addr (bits) */
                size_t at;
+
+               /* Position of the last event header from addr (bits) */
+               size_t last_eh_at;
        } buf;
 
        /* Binary type reader */
@@ -226,6 +220,12 @@ struct bt_ctf_notif_iter {
        /* Current content size (bits) (-1 if unknown) */
        int64_t cur_content_size;
 
+       /*
+        * Offset, in the underlying media, of the current packet's start
+        * (-1 if unknown).
+        */
+       off_t cur_packet_offset;
+
        /* bt_ctf_clock_class to uint64_t. */
        GHashTable *clock_states;
 
@@ -474,6 +474,7 @@ enum bt_ctf_notif_iter_status request_medium_bytes(
 
                /* Restart at the beginning of the new medium buffer */
                notit->buf.at = 0;
+               notit->buf.last_eh_at = SIZE_MAX;
 
                /* New medium buffer size */
                notit->buf.sz = buffer_sz;
@@ -487,6 +488,114 @@ enum bt_ctf_notif_iter_status request_medium_bytes(
                        notit->buf.sz, notit->buf.addr);
                BT_LOGV_MEM(buffer_addr, buffer_sz, "Returned bytes at %p:",
                        buffer_addr);
+       } else if (m_status == BT_CTF_NOTIF_ITER_MEDIUM_STATUS_EOF) {
+               struct bt_ctf_field_type *ph_ft =
+                       bt_ctf_trace_get_packet_header_type(notit->meta.trace);
+               struct bt_ctf_field_type *eh_ft = NULL;
+               struct bt_ctf_field_type *sec_ft = NULL;
+               struct bt_ctf_field_type *ec_ft = NULL;
+
+               /*
+                * User returned end of stream: validate that we're not
+                * in the middle of a packet header, packet context, or
+                * event.
+                */
+               if (notit->state == STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN) {
+                       /* Beginning of packet: always valid */
+                       goto good_state;
+               }
+
+               if (!notit->meta.stream_class) {
+                       goto bad_state;
+               }
+
+               if (notit->state == STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN) {
+                       /*
+                        * Beginning of packet context context is only
+                        * valid if there's no packet header.
+                        */
+                       if (!ph_ft) {
+                               goto good_state;
+                       }
+               }
+
+               eh_ft = bt_ctf_stream_class_get_event_header_type(
+                       notit->meta.stream_class);
+               sec_ft = bt_ctf_stream_class_get_event_context_type(
+                       notit->meta.stream_class);
+
+               if (notit->state == STATE_DSCOPE_STREAM_EVENT_HEADER_BEGIN) {
+                       /*
+                        * Beginning of event's header is only valid if
+                        * the packet is not supposed to have a specific
+                        * size (whole packet sequence has in fact only
+                        * one packet).
+                        */
+                       if (notit->cur_packet_size == -1) {
+                               goto good_state;
+                       }
+               }
+
+               if (notit->state == STATE_DSCOPE_STREAM_EVENT_CONTEXT_BEGIN) {
+                       /*
+                        * Beginning of event's stream event context is
+                        * only valid if the packet is not supposed to
+                        * have a specific size (whole packet sequence
+                        * has in fact only one packet), and there's no
+                        * event header.
+                        */
+                       if (notit->cur_packet_size == -1 && !eh_ft) {
+                               goto good_state;
+                       }
+               }
+
+               if (!notit->meta.event_class) {
+                       goto bad_state;
+               }
+
+               ec_ft = bt_ctf_event_class_get_context_type(
+                       notit->meta.event_class);
+
+               if (notit->state == STATE_DSCOPE_EVENT_CONTEXT_BEGIN) {
+                       /*
+                        * Beginning of event's context is only valid if
+                        * the packet is not supposed to have a specific
+                        * size (whole packet sequence has in fact only
+                        * one packet), and there's no event header and
+                        * no stream event context.
+                        */
+                       if (notit->cur_packet_size == -1 && !eh_ft && !sec_ft) {
+                               goto good_state;
+                       }
+               }
+
+               if (notit->state == STATE_DSCOPE_EVENT_PAYLOAD_BEGIN) {
+                       /*
+                        * Beginning of event's context is only valid if
+                        * the packet is not supposed to have a specific
+                        * size (whole packet sequence has in fact only
+                        * one packet), and there's no event header, no
+                        * stream event context, and no event context.
+                        */
+                       if (notit->cur_packet_size == -1 && !eh_ft && !sec_ft &&
+                                       !ec_ft) {
+                               goto good_state;
+                       }
+               }
+
+bad_state:
+               /* All other states are invalid */
+               BT_LOGW("User function returned %s, but notification iterator is in an unexpected state: "
+                       "state=%s",
+                       bt_ctf_notif_iter_medium_status_string(m_status),
+                       state_string(notit->state));
+               m_status = BT_CTF_NOTIF_ITER_MEDIUM_STATUS_ERROR;
+
+good_state:
+               bt_put(ph_ft);
+               bt_put(eh_ft);
+               bt_put(sec_ft);
+               bt_put(ec_ft);
        } else if (m_status < 0) {
                BT_LOGW("User function failed: status=%s",
                        bt_ctf_notif_iter_medium_status_string(m_status));
@@ -874,6 +983,7 @@ enum bt_ctf_notif_iter_status set_current_stream_class(
        enum bt_ctf_notif_iter_status status = BT_CTF_NOTIF_ITER_STATUS_OK;
        struct bt_ctf_field_type *packet_header_type = NULL;
        struct bt_ctf_field_type *stream_id_field_type = NULL;
+       struct bt_ctf_stream_class *new_stream_class = NULL;
        uint64_t stream_id;
 
        /* Clear the current stream class field path cache. */
@@ -925,10 +1035,9 @@ single_stream_class:
                notit, stream_id, notit->meta.trace,
                bt_ctf_trace_get_name(notit->meta.trace));
 
-       BT_PUT(notit->meta.stream_class);
-       notit->meta.stream_class = bt_ctf_trace_get_stream_class_by_id(
+       new_stream_class = bt_ctf_trace_get_stream_class_by_id(
                notit->meta.trace, stream_id);
-       if (!notit->meta.stream_class) {
+       if (!new_stream_class) {
                BT_LOGW("No stream class with ID of stream class ID to use in trace: "
                        "notit-addr=%p, stream-class-id=%" PRIu64 ", "
                        "trace-addr=%p, trace-name=\"%s\"",
@@ -938,6 +1047,31 @@ single_stream_class:
                goto end;
        }
 
+       if (notit->meta.stream_class) {
+               if (new_stream_class != notit->meta.stream_class) {
+                       BT_LOGW("Two packets refer to two different stream classes within the same packet sequence: "
+                               "notit-addr=%p, prev-stream-class-addr=%p, "
+                               "prev-stream-class-name=\"%s\", "
+                               "prev-stream-class-id=%" PRId64 ", "
+                               "next-stream-class-addr=%p, "
+                               "next-stream-class-name=\"%s\", "
+                               "next-stream-class-id=%" PRId64 ", "
+                               "trace-addr=%p, trace-name=\"%s\"",
+                               notit, notit->meta.stream_class,
+                               bt_ctf_stream_class_get_name(notit->meta.stream_class),
+                               bt_ctf_stream_class_get_id(notit->meta.stream_class),
+                               new_stream_class,
+                               bt_ctf_stream_class_get_name(new_stream_class),
+                               bt_ctf_stream_class_get_id(new_stream_class),
+                               notit->meta.trace,
+                               bt_ctf_trace_get_name(notit->meta.trace));
+                       status = BT_CTF_NOTIF_ITER_STATUS_ERROR;
+                       goto end;
+               }
+       } else {
+               BT_MOVE(notit->meta.stream_class, new_stream_class);
+       }
+
        BT_LOGV("Set current stream class: "
                "notit-addr=%p, stream-class-addr=%p, "
                "stream-class-name=\"%s\", stream-class-id=%" PRId64,
@@ -964,7 +1098,7 @@ single_stream_class:
 end:
        BT_PUT(packet_header_type);
        BT_PUT(stream_id_field_type);
-
+       bt_put(new_stream_class);
        return status;
 }
 
@@ -1046,7 +1180,7 @@ enum bt_ctf_notif_iter_status set_current_packet_content_sizes(
        enum bt_ctf_notif_iter_status status = BT_CTF_NOTIF_ITER_STATUS_OK;
        struct bt_ctf_field *packet_size_field = NULL;
        struct bt_ctf_field *content_size_field = NULL;
-       uint64_t content_size = -1, packet_size = -1;
+       uint64_t content_size = -1ULL, packet_size = -1ULL;
 
        if (!notit->dscopes.stream_packet_context) {
                goto end;
@@ -1097,7 +1231,16 @@ enum bt_ctf_notif_iter_status set_current_packet_content_sizes(
                goto end;
        }
 
-       notit->cur_packet_size = packet_size;
+       if (packet_size != -1ULL) {
+               notit->cur_packet_size = packet_size;
+       } else {
+               /*
+                * Use the content size as packet size indicator if the
+                * packet size field is missing. This means there is no
+                * padding in this stream.
+                */
+               notit->cur_packet_size = content_size;
+       }
        notit->cur_content_size = content_size;
        BT_LOGV("Set current packet and content sizes: "
                "notit-addr=%p, packet-size=%" PRIu64 ", content-size=%" PRIu64,
@@ -1129,6 +1272,9 @@ enum bt_ctf_notif_iter_status read_event_header_begin_state(
        enum bt_ctf_notif_iter_status status = BT_CTF_NOTIF_ITER_STATUS_OK;
        struct bt_ctf_field_type *event_header_type = NULL;
 
+       /* Reset the position of the last event header */
+       notit->buf.last_eh_at = notit->buf.at;
+
        /* Check if we have some content left */
        if (notit->cur_content_size >= 0) {
                if (packet_at(notit) == notit->cur_content_size) {
@@ -1140,7 +1286,7 @@ enum bt_ctf_notif_iter_status read_event_header_begin_state(
                } else if (packet_at(notit) > notit->cur_content_size) {
                        /* That's not supposed to happen */
                        BT_LOGV("Before decoding event header field: cursor is passed the packet's content: "
-                               "notit-addr=%p, content-size=%zu, "
+                               "notit-addr=%p, content-size=%" PRId64 ", "
                                "cur=%zu", notit, notit->cur_content_size,
                                packet_at(notit));
                        status = BT_CTF_NOTIF_ITER_STATUS_ERROR;
@@ -1276,7 +1422,7 @@ end_v_field_type:
        if (id_field_type && event_id == -1ULL) {
                /* Check "id" field */
                struct bt_ctf_field *id_field = NULL;
-               int ret = 0;
+               int ret_get_value = 0;
 
                // TODO: optimalize!
                id_field = bt_ctf_field_structure_get_field(
@@ -1286,7 +1432,7 @@ end_v_field_type:
                }
 
                if (bt_ctf_field_is_integer(id_field)) {
-                       ret = bt_ctf_field_unsigned_integer_get_value(
+                       ret_get_value = bt_ctf_field_unsigned_integer_get_value(
                                id_field, &event_id);
                } else if (bt_ctf_field_is_enumeration(id_field)) {
                        struct bt_ctf_field *container;
@@ -1294,12 +1440,12 @@ end_v_field_type:
                        container = bt_ctf_field_enumeration_get_container(
                                id_field);
                        assert(container);
-                       ret = bt_ctf_field_unsigned_integer_get_value(
+                       ret_get_value = bt_ctf_field_unsigned_integer_get_value(
                                container, &event_id);
                        BT_PUT(container);
                }
 
-               assert(ret == 0);
+               assert(ret_get_value == 0);
                BT_PUT(id_field);
        }
 
@@ -1654,14 +1800,17 @@ void bt_ctf_notif_iter_reset(struct bt_ctf_notif_iter *notit)
        BT_PUT(notit->meta.stream_class);
        BT_PUT(notit->meta.event_class);
        BT_PUT(notit->packet);
+       BT_PUT(notit->stream);
        put_all_dscopes(notit);
        notit->buf.addr = NULL;
        notit->buf.sz = 0;
        notit->buf.at = 0;
+       notit->buf.last_eh_at = SIZE_MAX;
        notit->buf.packet_offset = 0;
        notit->state = STATE_INIT;
        notit->cur_content_size = -1;
        notit->cur_packet_size = -1;
+       notit->cur_packet_offset = -1;
 }
 
 static
@@ -1669,11 +1818,19 @@ int bt_ctf_notif_iter_switch_packet(struct bt_ctf_notif_iter *notit)
 {
        int ret = 0;
 
+       /*
+        * We don't put the stream class here because we need to make
+        * sure that all the packets processed by the same notification
+        * iterator refer to the same stream class (the first one).
+        */
        assert(notit);
-       BT_LOGV("Switching packet: notit-addr=%p, cur=%zu",
-               notit, notit->buf.at);
+       if (notit->cur_packet_size != -1) {
+               notit->cur_packet_offset += notit->cur_packet_size;
+       }
+       BT_LOGV("Switching packet: notit-addr=%p, cur=%zu, "
+               "packet-offset=%" PRId64, notit, notit->buf.at,
+               notit->cur_packet_offset);
        stack_clear(notit->stack);
-       BT_PUT(notit->meta.stream_class);
        BT_PUT(notit->meta.event_class);
        BT_PUT(notit->packet);
        BT_PUT(notit->cur_timestamp_end);
@@ -1811,7 +1968,7 @@ enum bt_ctf_btr_status update_clock(struct bt_ctf_notif_iter *notit,
                struct bt_ctf_field *int_field)
 {
        gboolean clock_class_found;
-       uint64_t *clock_state;
+       uint64_t *clock_state = NULL;
        struct bt_ctf_field_type *int_field_type = NULL;
        enum bt_ctf_btr_status ret = BT_CTF_BTR_STATUS_OK;
        struct bt_ctf_clock_class *clock_class = NULL;
@@ -1826,12 +1983,7 @@ enum bt_ctf_btr_status update_clock(struct bt_ctf_notif_iter *notit,
 
        clock_class_found = g_hash_table_lookup_extended(notit->clock_states,
                clock_class, NULL, (gpointer) &clock_state);
-       if (unlikely(!clock_class_found)) {
-               ret = BT_CTF_BTR_STATUS_ERROR;
-               goto end;
-       }
-
-       if (unlikely(!clock_state)) {
+       if (!clock_class_found) {
                clock_state = g_new0(uint64_t, 1);
                if (!clock_state) {
                        BT_LOGE_STR("Failed to allocate a uint64_t.");
@@ -2640,28 +2792,81 @@ end:
 }
 
 static
-void create_packet(struct bt_ctf_notif_iter *notit)
+uint64_t get_cur_stream_instance_id(struct bt_ctf_notif_iter *notit)
 {
+       struct bt_ctf_field *stream_instance_id_field = NULL;
+       uint64_t stream_instance_id = -1ULL;
        int ret;
-       struct bt_ctf_stream *stream = NULL;
-       struct bt_ctf_packet *packet = NULL;
 
-       BT_LOGV("Creating packet for packet notification: "
-               "notit-addr=%p", notit);
+       if (!notit->dscopes.trace_packet_header) {
+               goto end;
+       }
+
+       stream_instance_id_field = bt_ctf_field_structure_get_field_by_name(
+               notit->dscopes.trace_packet_header, "stream_instance_id");
+       if (!stream_instance_id_field) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_unsigned_integer_get_value(stream_instance_id_field,
+               &stream_instance_id);
+       if (ret) {
+               stream_instance_id = -1ULL;
+               goto end;
+       }
+
+end:
+       bt_put(stream_instance_id_field);
+       return stream_instance_id;
+}
+
+static
+int set_stream(struct bt_ctf_notif_iter *notit)
+{
+       int ret = 0;
+       struct bt_ctf_stream *stream = NULL;
 
-       /* Ask the user for the stream */
        BT_LOGV("Calling user function (get stream): notit-addr=%p, "
                "stream-class-addr=%p, stream-class-name=\"%s\", "
                "stream-class-id=%" PRId64,
                notit, notit->meta.stream_class,
                bt_ctf_stream_class_get_name(notit->meta.stream_class),
                bt_ctf_stream_class_get_id(notit->meta.stream_class));
-       stream = notit->medium.medops.get_stream(notit->meta.stream_class,
-                       notit->medium.data);
-       BT_LOGV("User function returned: stream-addr=%p",
-               stream);
+       stream = bt_get(notit->medium.medops.get_stream(
+               notit->meta.stream_class, get_cur_stream_instance_id(notit),
+               notit->medium.data));
+       BT_LOGV("User function returned: stream-addr=%p", stream);
        if (!stream) {
                BT_LOGW_STR("User function failed to return a stream object for the given stream class.");
+               ret = -1;
+               goto end;
+       }
+
+       if (notit->stream && stream != notit->stream) {
+               BT_LOGW("User function returned a different stream than the previous one for the same sequence of packets.");
+               ret = -1;
+               goto end;
+       }
+
+       BT_MOVE(notit->stream, stream);
+
+end:
+       bt_put(stream);
+       return ret;
+}
+
+static
+void create_packet(struct bt_ctf_notif_iter *notit)
+{
+       int ret;
+       struct bt_ctf_packet *packet = NULL;
+
+       BT_LOGV("Creating packet for packet notification: "
+               "notit-addr=%p", notit);
+
+       /* Ask the user for the stream */
+       ret = set_stream(notit);
+       if (ret) {
                goto error;
        }
 
@@ -2670,19 +2875,19 @@ void create_packet(struct bt_ctf_notif_iter *notit)
                "stream-class-addr=%p, "
                "stream-class-name=\"%s\", "
                "stream-class-id=%" PRId64,
-               notit, stream, notit->meta.stream_class,
+               notit, notit->stream, notit->meta.stream_class,
                bt_ctf_stream_class_get_name(notit->meta.stream_class),
                bt_ctf_stream_class_get_id(notit->meta.stream_class));
 
        /* Create packet */
-       packet = bt_ctf_packet_create(stream);
+       packet = bt_ctf_packet_create(notit->stream);
        if (!packet) {
                BT_LOGE("Cannot create packet from stream: "
                        "notit-addr=%p, stream-addr=%p, "
                        "stream-class-addr=%p, "
                        "stream-class-name=\"%s\", "
                        "stream-class-id=%" PRId64,
-                       notit, stream, notit->meta.stream_class,
+                       notit, notit->stream, notit->meta.stream_class,
                        bt_ctf_stream_class_get_name(notit->meta.stream_class),
                        bt_ctf_stream_class_get_id(notit->meta.stream_class));
                goto error;
@@ -2700,7 +2905,7 @@ void create_packet(struct bt_ctf_notif_iter *notit)
                                "stream-class-name=\"%s\", "
                                "stream-class-id=%" PRId64 ", "
                                "field-addr=%p",
-                               notit, packet, stream, notit->meta.stream_class,
+                               notit, packet, notit->stream, notit->meta.stream_class,
                                bt_ctf_stream_class_get_name(notit->meta.stream_class),
                                bt_ctf_stream_class_get_id(notit->meta.stream_class),
                                notit->dscopes.trace_packet_header);
@@ -2719,7 +2924,7 @@ void create_packet(struct bt_ctf_notif_iter *notit)
                                "stream-class-name=\"%s\", "
                                "stream-class-id=%" PRId64 ", "
                                "field-addr=%p",
-                               notit, packet, stream, notit->meta.stream_class,
+                               notit, packet, notit->stream, notit->meta.stream_class,
                                bt_ctf_stream_class_get_name(notit->meta.stream_class),
                                bt_ctf_stream_class_get_id(notit->meta.stream_class),
                                notit->dscopes.trace_packet_header);
@@ -2786,9 +2991,17 @@ void notify_event(struct bt_ctf_notif_iter *notit,
                struct bt_clock_class_priority_map *cc_prio_map,
                struct bt_notification **notification)
 {
-       struct bt_ctf_event *event;
+       struct bt_ctf_event *event = NULL;
        struct bt_notification *ret = NULL;
 
+       /* Make sure that the event contains at least one bit of data */
+       if (notit->buf.at == notit->buf.last_eh_at) {
+               BT_LOGE("Cannot create empty event with 0 bits of data: "
+                       "notit-addr=%p, packet-cur=%zu",
+                       notit, packet_at(notit));
+               goto end;
+       }
+
        /* Create event */
        event = create_event(notit);
        if (!event) {
@@ -2810,27 +3023,6 @@ end:
        BT_PUT(event);
 }
 
-static
-int init_clock_states(GHashTable *clock_states, struct bt_ctf_trace *trace)
-{
-       int clock_class_count, i, ret = 0;
-
-       assert(trace);
-       clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
-       assert(clock_class_count >= 0);
-
-       for (i = 0; i < clock_class_count; i++) {
-               struct bt_ctf_clock_class *clock_class;
-
-               clock_class = bt_ctf_trace_get_clock_class_by_index(trace, i);
-               assert(clock_class);
-               g_hash_table_insert(clock_states, bt_get(clock_class), NULL);
-               bt_put(clock_class);
-       }
-
-       return ret;
-}
-
 static
 void init_trace_field_path_cache(struct bt_ctf_trace *trace,
                struct trace_field_path_cache *trace_field_path_cache)
@@ -2884,7 +3076,6 @@ struct bt_ctf_notif_iter *bt_ctf_notif_iter_create(struct bt_ctf_trace *trace,
                size_t max_request_sz,
                struct bt_ctf_notif_iter_medium_ops medops, void *data)
 {
-       int ret;
        struct bt_ctf_notif_iter *notit = NULL;
        struct bt_ctf_btr_cbs cbs = {
                .types = {
@@ -2921,11 +3112,6 @@ struct bt_ctf_notif_iter *bt_ctf_notif_iter_create(struct bt_ctf_trace *trace,
                BT_LOGE_STR("Failed to allocate a GHashTable.");
                goto error;
        }
-       ret = init_clock_states(notit->clock_states, trace);
-       if (ret) {
-               BT_LOGW("Cannot initialize clock values.");
-               goto error;
-       }
        notit->meta.trace = bt_get(trace);
        notit->medium.medops = medops;
        notit->medium.max_request_sz = max_request_sz;
@@ -2963,6 +3149,7 @@ struct bt_ctf_notif_iter *bt_ctf_notif_iter_create(struct bt_ctf_trace *trace,
                "data=%p, notit-addr=%p",
                trace, bt_ctf_trace_get_name(trace), max_request_sz, data,
                notit);
+       notit->cur_packet_offset = 0;
 
 end:
        return notit;
@@ -2979,6 +3166,7 @@ void bt_ctf_notif_iter_destroy(struct bt_ctf_notif_iter *notit)
        BT_PUT(notit->meta.stream_class);
        BT_PUT(notit->meta.event_class);
        BT_PUT(notit->packet);
+       BT_PUT(notit->stream);
        BT_PUT(notit->cur_timestamp_end);
        put_all_dscopes(notit);
 
@@ -3096,6 +3284,7 @@ enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_packet_header_context_fields
                struct bt_ctf_field **packet_header_field,
                struct bt_ctf_field **packet_context_field)
 {
+       int ret;
        enum bt_ctf_notif_iter_status status = BT_CTF_NOTIF_ITER_STATUS_OK;
 
        assert(notit);
@@ -3158,6 +3347,73 @@ set_fields:
                *packet_context_field = bt_get(notit->dscopes.stream_packet_context);
        }
 
+       ret = set_current_packet_content_sizes(notit);
+       if (ret) {
+               status = BT_CTF_NOTIF_ITER_STATUS_ERROR;
+               goto end;
+       }
 end:
        return status;
 }
+
+BT_HIDDEN
+void bt_ctf_notif_iter_set_medops_data(struct bt_ctf_notif_iter *notit,
+               void *medops_data)
+{
+       assert(notit);
+       notit->medium.data = medops_data;
+}
+
+BT_HIDDEN
+enum bt_ctf_notif_iter_status bt_ctf_notif_iter_seek(
+               struct bt_ctf_notif_iter *notit, off_t offset)
+{
+       enum bt_ctf_notif_iter_status ret = BT_CTF_NOTIF_ITER_STATUS_OK;
+       enum bt_ctf_notif_iter_medium_status medium_status;
+
+       assert(notit);
+       if (offset < 0) {
+               BT_LOGE("Cannot seek to negative offset: offset=%jd", offset);
+               ret = BT_CTF_NOTIF_ITER_STATUS_INVAL;
+               goto end;
+       }
+
+       if (!notit->medium.medops.seek) {
+               ret = BT_CTF_NOTIF_ITER_STATUS_UNSUPPORTED;
+               BT_LOGD("Aborting seek as the iterator's underlying media does not implement seek support.");
+               goto end;
+       }
+
+       medium_status = notit->medium.medops.seek(
+                       BT_CTF_NOTIF_ITER_SEEK_WHENCE_SET, offset,
+                       notit->medium.data);
+       if (medium_status != BT_CTF_NOTIF_ITER_MEDIUM_STATUS_OK) {
+               if (medium_status == BT_CTF_NOTIF_ITER_MEDIUM_STATUS_EOF) {
+                       ret = BT_CTF_NOTIF_ITER_STATUS_EOF;
+               } else {
+                       ret = BT_CTF_NOTIF_ITER_STATUS_ERROR;
+                       goto end;
+               }
+       }
+
+       bt_ctf_notif_iter_reset(notit);
+       notit->cur_packet_offset = offset;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+off_t bt_ctf_notif_iter_get_current_packet_offset(
+               struct bt_ctf_notif_iter *notit)
+{
+       assert(notit);
+       return notit->cur_packet_offset;
+}
+
+BT_HIDDEN
+off_t bt_ctf_notif_iter_get_current_packet_size(
+               struct bt_ctf_notif_iter *notit)
+{
+       assert(notit);
+       return notit->cur_packet_size;
+}
This page took 0.031084 seconds and 4 git commands to generate.