+
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_borrow_packet_header_context_fields(
+ struct bt_notif_iter *notit,
+ struct bt_field **packet_header_field,
+ struct bt_field **packet_context_field)
+{
+ int ret;
+ enum bt_notif_iter_status status = BT_NOTIF_ITER_STATUS_OK;
+
+ BT_ASSERT(notit);
+
+ if (notit->state == STATE_EMIT_NOTIF_NEW_PACKET) {
+ /* We're already there */
+ goto set_fields;
+ }
+
+ while (true) {
+ status = handle_state(notit);
+ if (status == BT_NOTIF_ITER_STATUS_AGAIN) {
+ BT_LOGV_STR("Medium returned BT_NOTIF_ITER_STATUS_AGAIN.");
+ goto end;
+ }
+ if (status != BT_NOTIF_ITER_STATUS_OK) {
+ if (status == BT_NOTIF_ITER_STATUS_EOF) {
+ BT_LOGV_STR("Medium returned BT_NOTIF_ITER_STATUS_EOF.");
+ } else {
+ BT_LOGW("Cannot handle state: "
+ "notit-addr=%p, state=%s",
+ notit, state_string(notit->state));
+ }
+ goto end;
+ }
+
+ switch (notit->state) {
+ case STATE_EMIT_NOTIF_NEW_PACKET:
+ /*
+ * Packet header and context fields are
+ * potentially decoded (or they don't exist).
+ */
+ goto set_fields;
+ case STATE_INIT:
+ case STATE_EMIT_NOTIF_NEW_STREAM:
+ case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN:
+ case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE:
+ case STATE_AFTER_TRACE_PACKET_HEADER:
+ case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN:
+ case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE:
+ case STATE_AFTER_STREAM_PACKET_CONTEXT:
+ /* Non-emitting state: continue */
+ break;
+ default:
+ /*
+ * We should never get past the
+ * STATE_EMIT_NOTIF_NEW_PACKET state.
+ */
+ BT_LOGF("Unexpected state: notit-addr=%p, state=%s",
+ notit, state_string(notit->state));
+ abort();
+ }
+ }
+
+set_fields:
+ ret = set_current_packet_content_sizes(notit);
+ if (ret) {
+ status = BT_NOTIF_ITER_STATUS_ERROR;
+ goto end;
+ }
+
+ if (packet_header_field) {
+ *packet_header_field = notit->dscopes.trace_packet_header;
+ }
+
+ if (packet_context_field) {
+ *packet_context_field = notit->dscopes.stream_packet_context;
+ }
+
+end:
+ return status;
+}
+
+BT_HIDDEN
+void bt_notif_iter_set_medops_data(struct bt_notif_iter *notit,
+ void *medops_data)
+{
+ BT_ASSERT(notit);
+ notit->medium.data = medops_data;
+}
+
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_seek(
+ struct bt_notif_iter *notit, off_t offset)
+{
+ enum bt_notif_iter_status ret = BT_NOTIF_ITER_STATUS_OK;
+ enum bt_notif_iter_medium_status medium_status;
+
+ BT_ASSERT(notit);
+ if (offset < 0) {
+ BT_LOGE("Cannot seek to negative offset: offset=%jd", offset);
+ ret = BT_NOTIF_ITER_STATUS_INVAL;
+ goto end;
+ }
+
+ if (!notit->medium.medops.seek) {
+ ret = BT_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_NOTIF_ITER_SEEK_WHENCE_SET, offset, notit->medium.data);
+ if (medium_status != BT_NOTIF_ITER_MEDIUM_STATUS_OK) {
+ if (medium_status == BT_NOTIF_ITER_MEDIUM_STATUS_EOF) {
+ ret = BT_NOTIF_ITER_STATUS_EOF;
+ } else {
+ ret = BT_NOTIF_ITER_STATUS_ERROR;
+ goto end;
+ }
+ }
+
+ bt_notif_iter_reset(notit);
+ notit->cur_packet_offset = offset;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+off_t bt_notif_iter_get_current_packet_offset(struct bt_notif_iter *notit)
+{
+ BT_ASSERT(notit);
+ return notit->cur_packet_offset;
+}
+
+BT_HIDDEN
+off_t bt_notif_iter_get_current_packet_size(
+ struct bt_notif_iter *notit)
+{
+ BT_ASSERT(notit);
+ return notit->cur_exp_packet_total_size;
+}
+
+BT_HIDDEN
+void bt_notif_trace_class_changed(struct bt_notif_iter *notit)
+{
+ if (notit->meta.tc->stored_value_count > notit->stored_values->len) {
+ g_array_set_size(notit->stored_values,
+ notit->meta.tc->stored_value_count);
+ }
+}
+
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_get_packet_properties(
+ struct bt_notif_iter *notit,
+ struct bt_notif_iter_packet_properties *props)
+{
+ BT_ASSERT(notit);
+ BT_ASSERT(props);
+
+ props->exp_packet_total_size =
+ (uint64_t) notit->cur_exp_packet_total_size;
+ props->exp_packet_content_size =
+ (uint64_t) notit->cur_exp_packet_content_size;
+ BT_ASSERT(props->stream_class_id >= 0);
+ props->stream_class_id = (uint64_t) notit->cur_stream_class_id;
+ props->data_stream_id = notit->cur_data_stream_id;
+ props->snapshots.discarded_events = notit->snapshots.discarded_events;
+ props->snapshots.packets = notit->snapshots.packets;
+ props->snapshots.beginning_clock = notit->snapshots.beginning_clock;
+ props->snapshots.end_clock = notit->snapshots.end_clock;
+ return BT_NOTIF_ITER_STATUS_OK;
+}