2 * Babeltrace - CTF notification iterator
4 * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015-2016 Philippe Proulx <pproulx@efficios.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <babeltrace/ctf-ir/field-types.h>
34 #include <babeltrace/ctf-ir/field-path.h>
35 #include <babeltrace/ctf-ir/fields.h>
36 #include <babeltrace/ctf-ir/stream-class.h>
37 #include <babeltrace/ctf-ir/packet.h>
38 #include <babeltrace/ctf-ir/stream.h>
39 #include <babeltrace/ctf-ir/clock.h>
40 #include <babeltrace/ctf-ir/event-class.h>
41 #include <babeltrace/ref.h>
44 #define PRINT_ERR_STREAM notit->err_stream
45 #define PRINT_PREFIX "ctf-notif-iter"
48 #include "ctf-notif-iter.h"
49 #include "../ctf-btr/ctf-btr.h"
51 #define BYTES_TO_BITS(x) ((x) * 8)
53 struct bt_ctf_notif_iter
;
55 /* A visit stack entry */
58 * Current base field, one of:
66 * Field is owned by this.
68 struct bt_ctf_field
*base
;
70 /* index of next field to set */
76 /* Entries (struct stack_entry *) (top is last element) */
80 struct bt_ctf_notif_iter
*notit
;
86 STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN
,
87 STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE
,
88 STATE_AFTER_TRACE_PACKET_HEADER
,
89 STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN
,
90 STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE
,
91 STATE_AFTER_STREAM_PACKET_CONTEXT
,
92 STATE_EMIT_NOTIF_NEW_PACKET
,
93 STATE_DSCOPE_STREAM_EVENT_HEADER_BEGIN
,
94 STATE_DSCOPE_STREAM_EVENT_HEADER_CONTINUE
,
95 STATE_AFTER_STREAM_EVENT_HEADER
,
96 STATE_DSCOPE_STREAM_EVENT_CONTEXT_BEGIN
,
97 STATE_DSCOPE_STREAM_EVENT_CONTEXT_CONTINUE
,
98 STATE_DSCOPE_EVENT_CONTEXT_BEGIN
,
99 STATE_DSCOPE_EVENT_CONTEXT_CONTINUE
,
100 STATE_DSCOPE_EVENT_PAYLOAD_BEGIN
,
101 STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE
,
102 STATE_EMIT_NOTIF_EVENT
,
103 STATE_EMIT_NOTIF_END_OF_PACKET
,
104 STATE_SKIP_PACKET_PADDING
,
107 /* CTF notification iterator */
108 struct bt_ctf_notif_iter
{
112 /* Error stream (may be NULL) */
116 * Current dynamic scope field pointer.
118 * This is set when a dynamic scope field is first created by
119 * btr_compound_begin_cb(). It points to one of the fields in
122 struct bt_ctf_field
**cur_dscope_field
;
124 /* Trace and classes (owned by this) */
126 struct bt_ctf_trace
*trace
;
127 struct bt_ctf_stream_class
*stream_class
;
128 struct bt_ctf_event_class
*event_class
;
131 /* Current packet (NULL if not created yet) */
132 struct bt_ctf_packet
*packet
;
134 /* Database of current dynamic scopes (owned by this) */
136 struct bt_ctf_field
*trace_packet_header
;
137 struct bt_ctf_field
*stream_packet_context
;
138 struct bt_ctf_field
*stream_event_header
;
139 struct bt_ctf_field
*stream_event_context
;
140 struct bt_ctf_field
*event_context
;
141 struct bt_ctf_field
*event_payload
;
147 /* User buffer stuff */
149 /* Last address provided by medium */
152 /* Buffer size provided by medium (bytes) */
155 /* Offset within whole packet of addr (bits) */
156 size_t packet_offset
;
158 /* Current position from addr (bits) */
162 /* Binary type reader */
163 struct bt_ctf_btr
*btr
;
167 struct bt_ctf_notif_iter_medium_ops medops
;
168 size_t max_request_sz
;
172 /* Current packet size (bits) (-1 if unknown) */
173 size_t cur_packet_size
;
175 /* Current content size (bits) (-1 if unknown) */
176 size_t cur_content_size
;
180 void stack_entry_free_func(gpointer data
)
182 struct stack_entry
*entry
= data
;
189 struct stack
*stack_new(struct bt_ctf_notif_iter
*notit
)
191 struct stack
*stack
= NULL
;
193 stack
= g_new0(struct stack
, 1);
198 stack
->entries
= g_ptr_array_new_with_free_func(stack_entry_free_func
);
199 if (!stack
->entries
) {
203 stack
->notit
= notit
;
214 void stack_destroy(struct stack
*stack
)
217 g_ptr_array_free(stack
->entries
, TRUE
);
222 int stack_push(struct stack
*stack
, struct bt_ctf_field
*base
)
225 struct stack_entry
*entry
;
226 struct bt_ctf_notif_iter
*notit
;
230 notit
= stack
->notit
;
231 entry
= g_new0(struct stack_entry
, 1);
233 PERR("Cannot create new stack entry\n");
238 entry
->base
= bt_get(base
);
239 g_ptr_array_add(stack
->entries
, entry
);
246 unsigned int stack_size(struct stack
*stack
)
250 return stack
->entries
->len
;
254 void stack_pop(struct stack
*stack
)
257 assert(stack_size(stack
));
258 g_ptr_array_remove_index(stack
->entries
, stack
->entries
->len
- 1);
262 struct stack_entry
*stack_top(struct stack
*stack
)
265 assert(stack_size(stack
));
267 return g_ptr_array_index(stack
->entries
, stack
->entries
->len
- 1);
271 bool stack_empty(struct stack
*stack
)
273 return stack_size(stack
) == 0;
277 void stack_clear(struct stack
*stack
)
281 if (!stack_empty(stack
)) {
282 g_ptr_array_remove_range(stack
->entries
, 0, stack_size(stack
));
285 assert(stack_empty(stack
));
289 enum bt_ctf_notif_iter_status
notif_iter_status_from_m_status(
290 enum bt_ctf_notif_iter_medium_status m_status
)
296 size_t buf_size_bits(struct bt_ctf_notif_iter
*notit
)
298 return BYTES_TO_BITS(notit
->buf
.sz
);
302 size_t buf_available_bits(struct bt_ctf_notif_iter
*notit
)
304 return buf_size_bits(notit
) - notit
->buf
.at
;
308 size_t packet_at(struct bt_ctf_notif_iter
*notit
)
310 return notit
->buf
.packet_offset
+ notit
->buf
.at
;
314 size_t remaining_content_bits(struct bt_ctf_notif_iter
*notit
)
316 if (notit
->cur_content_size
== -1) {
320 return notit
->cur_content_size
- packet_at(notit
);
324 size_t remaining_packet_bits(struct bt_ctf_notif_iter
*notit
)
326 if (notit
->cur_packet_size
== -1) {
330 return notit
->cur_packet_size
- packet_at(notit
);
334 void buf_consume_bits(struct bt_ctf_notif_iter
*notit
, size_t incr
)
336 notit
->buf
.at
+= incr
;
340 bool buf_has_enough_bits(struct bt_ctf_notif_iter
*notit
, size_t sz
)
342 return buf_available_bits(notit
) >= sz
;
346 enum bt_ctf_notif_iter_status
request_medium_bytes(struct bt_ctf_notif_iter
*notit
)
348 uint8_t *buffer_addr
;
350 enum bt_ctf_notif_iter_medium_status m_status
;
352 m_status
= notit
->medium
.medops
.request_bytes(
353 notit
->medium
.max_request_sz
, &buffer_addr
,
354 &buffer_sz
, notit
->medium
.data
);
355 if (m_status
== BT_CTF_NOTIF_ITER_MEDIUM_STATUS_OK
) {
356 assert(buffer_sz
!= 0);
358 /* New packet offset is old one + old size (in bits) */
359 notit
->buf
.packet_offset
+= buf_size_bits(notit
);
361 /* Restart at the beginning of the new medium buffer */
364 /* New medium buffer size */
365 notit
->buf
.sz
= buffer_sz
;
367 /* New medium buffer address */
368 notit
->buf
.addr
= buffer_addr
;
371 return notif_iter_status_from_m_status(m_status
);
375 enum bt_ctf_notif_iter_status
buf_ensure_available_bits(
376 struct bt_ctf_notif_iter
*notit
)
378 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
380 if (buf_available_bits(notit
) == 0) {
382 * This _cannot_ return BT_CTF_NOTIF_ITER_STATUS_OK
385 status
= request_medium_bytes(notit
);
392 enum bt_ctf_notif_iter_status
read_dscope_begin_state(
393 struct bt_ctf_notif_iter
*notit
,
394 struct bt_ctf_field_type
*dscope_field_type
,
395 enum state done_state
, enum state continue_state
,
396 struct bt_ctf_field
**dscope_field
)
398 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
399 enum bt_ctf_btr_status btr_status
;
400 size_t consumed_bits
;
402 status
= buf_ensure_available_bits(notit
);
403 if (status
!= BT_CTF_NOTIF_ITER_STATUS_OK
) {
407 bt_put(*dscope_field
);
408 notit
->cur_dscope_field
= dscope_field
;
409 consumed_bits
= bt_ctf_btr_start(notit
->btr
, dscope_field_type
,
410 notit
->buf
.addr
, notit
->buf
.at
, packet_at(notit
),
411 notit
->buf
.sz
, &btr_status
);
413 switch (btr_status
) {
414 case BT_CTF_BTR_STATUS_OK
:
415 /* type was read completely */
416 notit
->state
= done_state
;
418 case BT_CTF_BTR_STATUS_EOF
:
419 notit
->state
= continue_state
;
422 PERR("Binary type reader failed to start\n");
423 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
427 /* Consume bits now since we know we're not in an error state */
428 buf_consume_bits(notit
, consumed_bits
);
435 enum bt_ctf_notif_iter_status
read_dscope_continue_state(
436 struct bt_ctf_notif_iter
*notit
, enum state done_state
)
438 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
439 enum bt_ctf_btr_status btr_status
;
440 size_t consumed_bits
;
442 status
= buf_ensure_available_bits(notit
);
443 if (status
!= BT_CTF_NOTIF_ITER_STATUS_OK
) {
447 consumed_bits
= bt_ctf_btr_continue(notit
->btr
, notit
->buf
.addr
,
448 notit
->buf
.sz
, &btr_status
);
450 switch (btr_status
) {
451 case BT_CTF_BTR_STATUS_OK
:
452 /* Type was read completely */
453 notit
->state
= done_state
;
455 case BT_CTF_BTR_STATUS_EOF
:
456 /* Stay in this continue state */
459 PERR("Binary type reader failed to continue\n");
460 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
464 /* Consume bits now since we know we're not in an error state */
465 buf_consume_bits(notit
, consumed_bits
);
472 void put_event_dscopes(struct bt_ctf_notif_iter
*notit
)
474 BT_PUT(notit
->dscopes
.stream_event_header
);
475 BT_PUT(notit
->dscopes
.stream_event_context
);
476 BT_PUT(notit
->dscopes
.event_context
);
477 BT_PUT(notit
->dscopes
.event_payload
);
481 void put_all_dscopes(struct bt_ctf_notif_iter
*notit
)
483 BT_PUT(notit
->dscopes
.trace_packet_header
);
484 BT_PUT(notit
->dscopes
.stream_packet_context
);
485 put_event_dscopes(notit
);
489 enum bt_ctf_notif_iter_status
read_packet_header_begin_state(
490 struct bt_ctf_notif_iter
*notit
)
492 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
493 struct bt_ctf_field_type
*packet_header_type
;
495 /* Reset all dynamic scopes since we're reading a new packet */
496 put_all_dscopes(notit
);
497 BT_PUT(notit
->packet
);
498 BT_PUT(notit
->meta
.stream_class
);
499 BT_PUT(notit
->meta
.event_class
);
501 /* Packet header type is common to the whole trace */
502 packet_header_type
= bt_ctf_trace_get_packet_header_type(
504 if (!packet_header_type
) {
505 PERR("Failed to retrieve trace's packet header type\n");
506 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
510 status
= read_dscope_begin_state(notit
, packet_header_type
,
511 STATE_AFTER_TRACE_PACKET_HEADER
,
512 STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE
,
513 ¬it
->dscopes
.trace_packet_header
);
516 BT_PUT(packet_header_type
);
522 enum bt_ctf_notif_iter_status
read_packet_header_continue_state(
523 struct bt_ctf_notif_iter
*notit
)
525 return read_dscope_continue_state(notit
,
526 STATE_AFTER_TRACE_PACKET_HEADER
);
530 bool is_struct_type(struct bt_ctf_field_type
*field_type
)
532 return bt_ctf_field_type_get_type_id(field_type
) == BT_CTF_TYPE_ID_STRUCT
;
536 bool is_variant_type(struct bt_ctf_field_type
*field_type
)
538 return bt_ctf_field_type_get_type_id(field_type
) == BT_CTF_TYPE_ID_VARIANT
;
542 enum bt_ctf_notif_iter_status
set_current_stream_class(struct bt_ctf_notif_iter
*notit
)
544 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
545 struct bt_ctf_field_type
*packet_header_type
;
546 struct bt_ctf_field_type
*stream_id_field_type
= NULL
;
549 /* Is there any "stream_id" field in the packet header? */
550 packet_header_type
= bt_ctf_trace_get_packet_header_type(
552 if (!packet_header_type
) {
553 PERR("Failed to retrieve trace's packet header type\n");
554 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
558 assert(is_struct_type(packet_header_type
));
561 stream_id_field_type
=
562 bt_ctf_field_type_structure_get_field_type_by_name(
563 packet_header_type
, "stream_id");
564 if (stream_id_field_type
) {
565 /* Find appropriate stream class using current stream ID */
566 struct bt_ctf_field
*stream_id_field
= NULL
;
569 assert(notit
->dscopes
.trace_packet_header
);
572 stream_id_field
= bt_ctf_field_structure_get_field(
573 notit
->dscopes
.trace_packet_header
, "stream_id");
574 assert(stream_id_field
);
575 ret
= bt_ctf_field_unsigned_integer_get_value(
576 stream_id_field
, &stream_id
);
578 BT_PUT(stream_id_field
);
580 /* Only one stream: pick the first stream class */
581 assert(bt_ctf_trace_get_stream_class_count(
582 notit
->meta
.trace
) == 1);
586 BT_PUT(notit
->meta
.stream_class
);
589 notit
->meta
.stream_class
= bt_ctf_trace_get_stream_class(
590 notit
->meta
.trace
, stream_id
);
591 if (!notit
->meta
.stream_class
) {
592 PERR("Cannot find stream class with ID %" PRIu64
"\n",
594 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
599 BT_PUT(packet_header_type
);
600 BT_PUT(stream_id_field_type
);
606 enum bt_ctf_notif_iter_status
after_packet_header_state(
607 struct bt_ctf_notif_iter
*notit
)
609 enum bt_ctf_notif_iter_status status
;
611 status
= set_current_stream_class(notit
);
612 if (status
== BT_CTF_NOTIF_ITER_STATUS_OK
) {
613 notit
->state
= STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN
;
620 enum bt_ctf_notif_iter_status
read_packet_context_begin_state(
621 struct bt_ctf_notif_iter
*notit
)
623 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
624 struct bt_ctf_field_type
*packet_context_type
;
626 assert(notit
->meta
.stream_class
);
627 packet_context_type
= bt_ctf_stream_class_get_packet_context_type(
628 notit
->meta
.stream_class
);
629 if (!packet_context_type
) {
630 PERR("Failed to retrieve stream class's packet context\n");
631 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
635 status
= read_dscope_begin_state(notit
, packet_context_type
,
636 STATE_AFTER_STREAM_PACKET_CONTEXT
,
637 STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE
,
638 ¬it
->dscopes
.stream_packet_context
);
641 BT_PUT(packet_context_type
);
647 enum bt_ctf_notif_iter_status
read_packet_context_continue_state(
648 struct bt_ctf_notif_iter
*notit
)
650 return read_dscope_continue_state(notit
,
651 STATE_AFTER_STREAM_PACKET_CONTEXT
);
655 enum bt_ctf_notif_iter_status
set_current_packet_content_sizes(
656 struct bt_ctf_notif_iter
*notit
)
658 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
659 struct bt_ctf_field
*packet_size_field
= NULL
;
660 struct bt_ctf_field
*content_size_field
= NULL
;
661 uint64_t content_size
= -1, packet_size
= -1;
663 assert(notit
->dscopes
.stream_packet_context
);
666 packet_size_field
= bt_ctf_field_structure_get_field(
667 notit
->dscopes
.stream_packet_context
, "packet_size");
668 content_size_field
= bt_ctf_field_structure_get_field(
669 notit
->dscopes
.stream_packet_context
, "content_size");
670 if (packet_size_field
) {
671 int ret
= bt_ctf_field_unsigned_integer_get_value(
672 packet_size_field
, &packet_size
);
675 if (packet_size
== 0) {
676 PERR("Decoded packet size is 0\n");
677 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
679 } else if ((packet_size
% 8) != 0) {
680 PERR("Decoded packet size is not a multiple of 8\n");
681 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
685 if (content_size_field
) {
686 int ret
= bt_ctf_field_unsigned_integer_get_value(
687 content_size_field
, &content_size
);
690 content_size
= packet_size
;
693 notit
->cur_packet_size
= packet_size
;
694 notit
->cur_content_size
= content_size
;
697 BT_PUT(packet_size_field
);
698 BT_PUT(content_size_field
);
704 enum bt_ctf_notif_iter_status
after_packet_context_state(
705 struct bt_ctf_notif_iter
*notit
)
707 enum bt_ctf_notif_iter_status status
;
709 status
= set_current_packet_content_sizes(notit
);
710 if (status
== BT_CTF_NOTIF_ITER_STATUS_OK
) {
711 notit
->state
= STATE_EMIT_NOTIF_NEW_PACKET
;
718 enum bt_ctf_notif_iter_status
read_event_header_begin_state(
719 struct bt_ctf_notif_iter
*notit
)
721 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
722 struct bt_ctf_field_type
*event_header_type
= NULL
;
724 /* Check if we have some content left */
725 if (notit
->cur_content_size
>= 0) {
726 if (packet_at(notit
) == notit
->cur_content_size
) {
727 /* No more events! */
728 notit
->state
= STATE_EMIT_NOTIF_END_OF_PACKET
;
730 } else if (packet_at(notit
) > notit
->cur_content_size
) {
731 /* That's not supposed to happen */
732 PERR("Cursor passed packet's content size:\n");
733 PERR(" Decoded content size: %zu\n",
734 notit
->cur_content_size
);
735 PERR(" Cursor position: %zu\n", packet_at(notit
));
736 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
741 event_header_type
= bt_ctf_stream_class_get_event_header_type(
742 notit
->meta
.stream_class
);
743 if (!event_header_type
) {
744 PERR("Failed to retrieve stream class's event header type\n");
745 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
749 put_event_dscopes(notit
);
750 status
= read_dscope_begin_state(notit
, event_header_type
,
751 STATE_AFTER_STREAM_EVENT_HEADER
,
752 STATE_DSCOPE_STREAM_EVENT_HEADER_CONTINUE
,
753 ¬it
->dscopes
.stream_event_header
);
756 BT_PUT(event_header_type
);
762 enum bt_ctf_notif_iter_status
read_event_header_continue_state(
763 struct bt_ctf_notif_iter
*notit
)
765 return read_dscope_continue_state(notit
,
766 STATE_AFTER_STREAM_EVENT_HEADER
);
770 enum bt_ctf_notif_iter_status
set_current_event_class(struct bt_ctf_notif_iter
*notit
)
773 * The assert() calls in this function are okay because it is
774 * assumed here that all the metadata objects have been
775 * validated for CTF correctness before decoding actual streams.
778 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
779 struct bt_ctf_field_type
*event_header_type
;
780 struct bt_ctf_field_type
*id_field_type
= NULL
;
781 struct bt_ctf_field_type
*v_field_type
= NULL
;
782 uint64_t event_id
= -1ULL;
785 event_header_type
= bt_ctf_stream_class_get_event_header_type(
786 notit
->meta
.stream_class
);
787 if (!event_header_type
) {
788 PERR("Failed to retrieve stream class's event header type\n");
789 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
793 /* Is there any "id"/"v" field in the event header? */
794 assert(is_struct_type(event_header_type
));
795 id_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
796 event_header_type
, "id");
797 v_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
798 event_header_type
, "v");
799 assert(notit
->dscopes
.stream_event_header
);
803 * | | |_ _|_ _| __ __ _
804 * | | | | | || '_ \ / _` |
805 * | |___| | | || | | | (_| | S P E C I A L
806 * |_____|_| |_||_| |_|\__, | C A S E ™
809 struct bt_ctf_field
*v_field
= NULL
;
810 struct bt_ctf_field
*v_struct_field
= NULL
;
811 struct bt_ctf_field
*v_struct_id_field
= NULL
;
814 v_field
= bt_ctf_field_structure_get_field(
815 notit
->dscopes
.stream_event_header
, "v");
819 bt_ctf_field_variant_get_current_field(v_field
);
820 if (!v_struct_field
) {
821 goto end_v_field_type
;
826 bt_ctf_field_structure_get_field(v_struct_field
, "id");
827 if (!v_struct_id_field
) {
828 goto end_v_field_type
;
831 ret
= bt_ctf_field_unsigned_integer_get_value(
832 v_struct_id_field
, &event_id
);
839 BT_PUT(v_struct_field
);
840 BT_PUT(v_struct_id_field
);
843 if (id_field_type
&& event_id
== -1ULL) {
844 /* Check "id" field */
845 struct bt_ctf_field
*id_field
= NULL
;
849 id_field
= bt_ctf_field_structure_get_field(
850 notit
->dscopes
.stream_event_header
, "id");
852 assert(bt_ctf_field_is_integer(id_field
) ||
853 bt_ctf_field_is_enumeration(id_field
));
855 if (bt_ctf_field_is_integer(id_field
)) {
856 ret
= bt_ctf_field_unsigned_integer_get_value(
857 id_field
, &event_id
);
859 struct bt_ctf_field
*container
;
861 container
= bt_ctf_field_enumeration_get_container(
864 ret
= bt_ctf_field_unsigned_integer_get_value(
865 container
, &event_id
);
872 if (event_id
== -1ULL) {
873 /* Event ID not found: single event? */
874 assert(bt_ctf_stream_class_get_event_class_count(
875 notit
->meta
.stream_class
) == 1);
879 BT_PUT(notit
->meta
.event_class
);
880 notit
->meta
.event_class
= bt_ctf_stream_class_get_event_class_by_id(
881 notit
->meta
.stream_class
, event_id
);
882 if (!notit
->meta
.event_class
) {
883 PERR("Cannot find event class with ID %" PRIu64
"\n", event_id
);
884 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
889 BT_PUT(event_header_type
);
890 BT_PUT(id_field_type
);
891 BT_PUT(v_field_type
);
897 enum bt_ctf_notif_iter_status
after_event_header_state(
898 struct bt_ctf_notif_iter
*notit
)
900 enum bt_ctf_notif_iter_status status
;
902 status
= set_current_packet_content_sizes(notit
);
903 if (status
!= BT_CTF_NOTIF_ITER_STATUS_OK
) {
904 PERR("Failed to set current packet and content sizes\n");
908 status
= set_current_event_class(notit
);
909 if (status
!= BT_CTF_NOTIF_ITER_STATUS_OK
) {
910 PERR("Failed to set current event class\n");
914 notit
->state
= STATE_DSCOPE_STREAM_EVENT_CONTEXT_BEGIN
;
921 enum bt_ctf_notif_iter_status
read_stream_event_context_begin_state(
922 struct bt_ctf_notif_iter
*notit
)
924 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
925 struct bt_ctf_field_type
*stream_event_context_type
;
927 stream_event_context_type
= bt_ctf_stream_class_get_event_context_type(
928 notit
->meta
.stream_class
);
929 if (!stream_event_context_type
) {
930 PERR("Failed to retrieve stream class's event context type\n");
931 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
935 status
= read_dscope_begin_state(notit
, stream_event_context_type
,
936 STATE_DSCOPE_EVENT_CONTEXT_BEGIN
,
937 STATE_DSCOPE_STREAM_EVENT_CONTEXT_CONTINUE
,
938 ¬it
->dscopes
.stream_event_context
);
941 BT_PUT(stream_event_context_type
);
947 enum bt_ctf_notif_iter_status
read_stream_event_context_continue_state(
948 struct bt_ctf_notif_iter
*notit
)
950 return read_dscope_continue_state(notit
,
951 STATE_DSCOPE_EVENT_CONTEXT_BEGIN
);
955 enum bt_ctf_notif_iter_status
read_event_context_begin_state(
956 struct bt_ctf_notif_iter
*notit
)
958 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
959 struct bt_ctf_field_type
*event_context_type
;
961 event_context_type
= bt_ctf_event_class_get_context_type(
962 notit
->meta
.event_class
);
963 if (!event_context_type
) {
964 PERR("Failed to retrieve event class's context type\n");
965 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
969 status
= read_dscope_begin_state(notit
, event_context_type
,
970 STATE_DSCOPE_EVENT_PAYLOAD_BEGIN
,
971 STATE_DSCOPE_EVENT_CONTEXT_CONTINUE
,
972 ¬it
->dscopes
.event_context
);
975 BT_PUT(event_context_type
);
981 enum bt_ctf_notif_iter_status
read_event_context_continue_state(
982 struct bt_ctf_notif_iter
*notit
)
984 return read_dscope_continue_state(notit
,
985 STATE_DSCOPE_EVENT_PAYLOAD_BEGIN
);
989 enum bt_ctf_notif_iter_status
read_event_payload_begin_state(
990 struct bt_ctf_notif_iter
*notit
)
992 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
993 struct bt_ctf_field_type
*event_payload_type
;
995 event_payload_type
= bt_ctf_event_class_get_payload_type(
996 notit
->meta
.event_class
);
997 if (!event_payload_type
) {
998 PERR("Failed to retrieve event class's payload type\n");
999 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
1003 status
= read_dscope_begin_state(notit
, event_payload_type
,
1004 STATE_EMIT_NOTIF_EVENT
,
1005 STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE
,
1006 ¬it
->dscopes
.event_payload
);
1009 BT_PUT(event_payload_type
);
1015 enum bt_ctf_notif_iter_status
read_event_payload_continue_state(
1016 struct bt_ctf_notif_iter
*notit
)
1018 return read_dscope_continue_state(notit
, STATE_EMIT_NOTIF_EVENT
);
1022 enum bt_ctf_notif_iter_status
skip_packet_padding_state(
1023 struct bt_ctf_notif_iter
*notit
)
1025 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
1026 size_t bits_to_skip
;
1028 assert(notit
->cur_packet_size
> 0);
1029 bits_to_skip
= notit
->cur_packet_size
- packet_at(notit
);
1030 if (bits_to_skip
== 0) {
1031 notit
->state
= STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN
;
1034 size_t bits_to_consume
;
1035 status
= buf_ensure_available_bits(notit
);
1036 if (status
!= BT_CTF_NOTIF_ITER_STATUS_OK
) {
1040 bits_to_consume
= MIN(buf_available_bits(notit
), bits_to_skip
);
1041 buf_consume_bits(notit
, bits_to_consume
);
1042 bits_to_skip
= notit
->cur_packet_size
- packet_at(notit
);
1043 if (bits_to_skip
== 0) {
1044 notit
->state
= STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN
;
1054 enum bt_ctf_notif_iter_status
handle_state(struct bt_ctf_notif_iter
*notit
)
1056 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
1058 PDBG("Handling state %d\n", notit
->state
);
1060 // TODO: optimalize!
1061 switch (notit
->state
) {
1063 notit
->state
= STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN
;
1065 case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN
:
1066 status
= read_packet_header_begin_state(notit
);
1068 case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE
:
1069 status
= read_packet_header_continue_state(notit
);
1071 case STATE_AFTER_TRACE_PACKET_HEADER
:
1072 status
= after_packet_header_state(notit
);
1074 case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN
:
1075 status
= read_packet_context_begin_state(notit
);
1077 case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE
:
1078 status
= read_packet_context_continue_state(notit
);
1080 case STATE_AFTER_STREAM_PACKET_CONTEXT
:
1081 status
= after_packet_context_state(notit
);
1083 case STATE_EMIT_NOTIF_NEW_PACKET
:
1084 notit
->state
= STATE_DSCOPE_STREAM_EVENT_HEADER_BEGIN
;
1086 case STATE_DSCOPE_STREAM_EVENT_HEADER_BEGIN
:
1087 status
= read_event_header_begin_state(notit
);
1089 case STATE_DSCOPE_STREAM_EVENT_HEADER_CONTINUE
:
1090 status
= read_event_header_continue_state(notit
);
1092 case STATE_AFTER_STREAM_EVENT_HEADER
:
1093 status
= after_event_header_state(notit
);
1095 case STATE_DSCOPE_STREAM_EVENT_CONTEXT_BEGIN
:
1096 status
= read_stream_event_context_begin_state(notit
);
1098 case STATE_DSCOPE_STREAM_EVENT_CONTEXT_CONTINUE
:
1099 status
= read_stream_event_context_continue_state(notit
);
1101 case STATE_DSCOPE_EVENT_CONTEXT_BEGIN
:
1102 status
= read_event_context_begin_state(notit
);
1104 case STATE_DSCOPE_EVENT_CONTEXT_CONTINUE
:
1105 status
= read_event_context_continue_state(notit
);
1107 case STATE_DSCOPE_EVENT_PAYLOAD_BEGIN
:
1108 status
= read_event_payload_begin_state(notit
);
1110 case STATE_DSCOPE_EVENT_PAYLOAD_CONTINUE
:
1111 status
= read_event_payload_continue_state(notit
);
1113 case STATE_EMIT_NOTIF_EVENT
:
1114 notit
->state
= STATE_DSCOPE_STREAM_EVENT_HEADER_BEGIN
;
1116 case STATE_SKIP_PACKET_PADDING
:
1117 status
= skip_packet_padding_state(notit
);
1119 case STATE_EMIT_NOTIF_END_OF_PACKET
:
1120 notit
->state
= STATE_SKIP_PACKET_PADDING
;
1127 void bt_ctf_notif_iter_reset(struct bt_ctf_notif_iter
*notit
)
1130 stack_clear(notit
->stack
);
1131 BT_PUT(notit
->meta
.stream_class
);
1132 BT_PUT(notit
->meta
.event_class
);
1133 BT_PUT(notit
->packet
);
1134 put_all_dscopes(notit
);
1135 notit
->buf
.addr
= NULL
;
1138 notit
->buf
.packet_offset
= 0;
1139 notit
->state
= STATE_INIT
;
1140 notit
->cur_content_size
= -1;
1141 notit
->cur_packet_size
= -1;
1145 struct bt_ctf_field
*get_next_field(struct bt_ctf_notif_iter
*notit
)
1147 struct bt_ctf_field
*next_field
= NULL
;
1148 struct bt_ctf_field
*base_field
;
1149 struct bt_ctf_field_type
*base_type
;
1152 assert(!stack_empty(notit
->stack
));
1153 index
= stack_top(notit
->stack
)->index
;
1154 base_field
= stack_top(notit
->stack
)->base
;
1155 base_type
= bt_ctf_field_get_type(base_field
);
1157 PERR("Failed to get base field's type\n");
1161 switch (bt_ctf_field_type_get_type_id(base_type
)) {
1162 case BT_CTF_TYPE_ID_STRUCT
:
1163 next_field
= bt_ctf_field_structure_get_field_by_index(
1166 case BT_CTF_TYPE_ID_ARRAY
:
1167 next_field
= bt_ctf_field_array_get_field(base_field
, index
);
1169 case BT_CTF_TYPE_ID_SEQUENCE
:
1170 next_field
= bt_ctf_field_sequence_get_field(base_field
, index
);
1172 case BT_CTF_TYPE_ID_VARIANT
:
1173 next_field
= bt_ctf_field_variant_get_current_field(base_field
);
1187 enum bt_ctf_btr_status
btr_signed_int_cb(int64_t value
,
1188 struct bt_ctf_field_type
*type
, void *data
)
1190 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1191 struct bt_ctf_field
*field
= NULL
;
1192 struct bt_ctf_field
*int_field
= NULL
;
1193 struct bt_ctf_notif_iter
*notit
= data
;
1196 /* create next field */
1197 field
= get_next_field(notit
);
1199 PERR("Failed to get next field (signed int)\n");
1200 status
= BT_CTF_BTR_STATUS_ERROR
;
1204 switch(bt_ctf_field_type_get_type_id(type
)) {
1205 case BT_CTF_TYPE_ID_INTEGER
:
1206 /* Integer field is created field */
1207 BT_MOVE(int_field
, field
);
1209 case BT_CTF_TYPE_ID_ENUM
:
1210 int_field
= bt_ctf_field_enumeration_get_container(field
);
1217 PERR("Failed to get integer field\n");
1218 status
= BT_CTF_BTR_STATUS_ERROR
;
1222 ret
= bt_ctf_field_signed_integer_set_value(int_field
, value
);
1224 stack_top(notit
->stack
)->index
++;
1234 enum bt_ctf_btr_status
btr_unsigned_int_cb(uint64_t value
,
1235 struct bt_ctf_field_type
*type
, void *data
)
1237 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1238 struct bt_ctf_field
*field
= NULL
;
1239 struct bt_ctf_field
*int_field
= NULL
;
1240 struct bt_ctf_notif_iter
*notit
= data
;
1243 /* Create next field */
1244 field
= get_next_field(notit
);
1246 PERR("Failed to get next field (unsigned int)\n");
1247 status
= BT_CTF_BTR_STATUS_ERROR
;
1251 switch(bt_ctf_field_type_get_type_id(type
)) {
1252 case BT_CTF_TYPE_ID_INTEGER
:
1253 /* Integer field is created field */
1254 BT_MOVE(int_field
, field
);
1256 case BT_CTF_TYPE_ID_ENUM
:
1257 int_field
= bt_ctf_field_enumeration_get_container(field
);
1264 PERR("Failed to get integer field\n");
1265 status
= BT_CTF_BTR_STATUS_ERROR
;
1269 ret
= bt_ctf_field_unsigned_integer_set_value(int_field
, value
);
1271 stack_top(notit
->stack
)->index
++;
1281 enum bt_ctf_btr_status
btr_floating_point_cb(double value
,
1282 struct bt_ctf_field_type
*type
, void *data
)
1284 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1285 struct bt_ctf_field
*field
= NULL
;
1286 struct bt_ctf_notif_iter
*notit
= data
;
1289 /* Create next field */
1290 field
= get_next_field(notit
);
1292 PERR("Failed to get next field (floating point number)\n");
1293 status
= BT_CTF_BTR_STATUS_ERROR
;
1297 ret
= bt_ctf_field_floating_point_set_value(field
, value
);
1299 stack_top(notit
->stack
)->index
++;
1308 enum bt_ctf_btr_status
btr_string_begin_cb(
1309 struct bt_ctf_field_type
*type
, void *data
)
1311 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1312 struct bt_ctf_field
*field
= NULL
;
1313 struct bt_ctf_notif_iter
*notit
= data
;
1316 /* Create next field */
1317 field
= get_next_field(notit
);
1319 PERR("Failed to get next field (string)\n");
1320 status
= BT_CTF_BTR_STATUS_ERROR
;
1325 * Push on stack. Not a compound type per se, but we know that only
1326 * btr_string_cb() may be called between this call and a subsequent
1327 * call to btr_string_end_cb().
1329 ret
= stack_push(notit
->stack
, field
);
1331 PERR("Failed to push string field onto the stack\n");
1332 status
= BT_CTF_BTR_STATUS_ERROR
;
1343 enum bt_ctf_btr_status
btr_string_cb(const char *value
,
1344 size_t len
, struct bt_ctf_field_type
*type
, void *data
)
1346 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1347 struct bt_ctf_field
*field
= NULL
;
1348 struct bt_ctf_notif_iter
*notit
= data
;
1351 /* Get string field */
1352 field
= stack_top(notit
->stack
)->base
;
1355 /* Append current string */
1356 ret
= bt_ctf_field_string_append_len(field
, value
, len
);
1358 PERR("Failed to append a string to a string field\n");
1359 status
= BT_CTF_BTR_STATUS_ERROR
;
1368 enum bt_ctf_btr_status
btr_string_end_cb(
1369 struct bt_ctf_field_type
*type
, void *data
)
1371 struct bt_ctf_notif_iter
*notit
= data
;
1373 /* Pop string field */
1374 stack_pop(notit
->stack
);
1376 /* Go to next field */
1377 stack_top(notit
->stack
)->index
++;
1379 return BT_CTF_BTR_STATUS_OK
;
1382 enum bt_ctf_btr_status
btr_compound_begin_cb(
1383 struct bt_ctf_field_type
*type
, void *data
)
1385 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1386 struct bt_ctf_notif_iter
*notit
= data
;
1387 struct bt_ctf_field
*field
;
1391 if (stack_empty(notit
->stack
)) {
1392 /* Root: create dynamic scope field */
1393 *notit
->cur_dscope_field
= bt_ctf_field_create(type
);
1394 field
= *notit
->cur_dscope_field
;
1397 * Field will be put at the end of this function
1398 * (stack_push() will take one reference, but this
1399 * reference is lost upon the equivalent stack_pop()
1400 * later), so also get it for our context to own it.
1402 bt_get(*notit
->cur_dscope_field
);
1404 field
= get_next_field(notit
);
1408 PERR("Failed to get next field or create dynamic scope field\n");
1409 status
= BT_CTF_BTR_STATUS_ERROR
;
1414 ret
= stack_push(notit
->stack
, field
);
1416 PERR("Failed to push compound field onto the stack\n");
1417 status
= BT_CTF_BTR_STATUS_ERROR
;
1427 enum bt_ctf_btr_status
btr_compound_end_cb(
1428 struct bt_ctf_field_type
*type
, void *data
)
1430 struct bt_ctf_notif_iter
*notit
= data
;
1432 assert(!stack_empty(notit
->stack
));
1435 stack_pop(notit
->stack
);
1437 /* If the stack is not empty, increment the base's index */
1438 if (!stack_empty(notit
->stack
)) {
1439 stack_top(notit
->stack
)->index
++;
1442 return BT_CTF_BTR_STATUS_OK
;
1446 struct bt_ctf_field
*resolve_field(struct bt_ctf_notif_iter
*notit
,
1447 struct bt_ctf_field_path
*path
)
1449 struct bt_ctf_field
*field
= NULL
;
1452 switch (bt_ctf_field_path_get_root_scope(path
)) {
1453 case BT_CTF_SCOPE_TRACE_PACKET_HEADER
:
1454 field
= notit
->dscopes
.trace_packet_header
;
1456 case BT_CTF_SCOPE_STREAM_PACKET_CONTEXT
:
1457 field
= notit
->dscopes
.stream_packet_context
;
1459 case BT_CTF_SCOPE_STREAM_EVENT_HEADER
:
1460 field
= notit
->dscopes
.stream_event_header
;
1462 case BT_CTF_SCOPE_STREAM_EVENT_CONTEXT
:
1463 field
= notit
->dscopes
.stream_event_context
;
1465 case BT_CTF_SCOPE_EVENT_CONTEXT
:
1466 field
= notit
->dscopes
.event_context
;
1468 case BT_CTF_SCOPE_EVENT_FIELDS
:
1469 field
= notit
->dscopes
.event_payload
;
1481 for (i
= 0; i
< bt_ctf_field_path_get_index_count(path
); ++i
) {
1482 struct bt_ctf_field
*next_field
= NULL
;
1483 struct bt_ctf_field_type
*field_type
;
1484 int index
= bt_ctf_field_path_get_index(path
, i
);
1486 field_type
= bt_ctf_field_get_type(field
);
1492 if (is_struct_type(field_type
)) {
1493 next_field
= bt_ctf_field_structure_get_field_by_index(
1495 } else if (is_variant_type(field_type
)) {
1497 bt_ctf_field_variant_get_current_field(field
);
1507 /* Move next field -> field */
1508 BT_MOVE(field
, next_field
);
1516 int64_t btr_get_sequence_length_cb(struct bt_ctf_field_type
*type
, void *data
)
1520 struct bt_ctf_field_path
*field_path
;
1521 struct bt_ctf_notif_iter
*notit
= data
;
1522 struct bt_ctf_field
*field
= NULL
;
1525 field_path
= bt_ctf_field_type_sequence_get_length_field_path(type
);
1530 field
= resolve_field(notit
, field_path
);
1535 iret
= bt_ctf_field_unsigned_integer_get_value(field
, &length
);
1540 ret
= (int64_t) length
;
1550 struct bt_ctf_field_type
*btr_get_variant_type_cb(
1551 struct bt_ctf_field_type
*type
, void *data
)
1553 struct bt_ctf_field_path
*path
;
1554 struct bt_ctf_notif_iter
*notit
= data
;
1555 struct bt_ctf_field
*tag_field
= NULL
;
1556 struct bt_ctf_field
*selected_field
= NULL
;
1557 struct bt_ctf_field_type
*selected_field_type
= NULL
;
1559 path
= bt_ctf_field_type_variant_get_tag_field_path(type
);
1564 tag_field
= resolve_field(notit
, path
);
1570 * We found the enumeration tag field instance which should be
1571 * able to select a current field for this variant. This
1572 * callback function we're in is called _after_
1573 * compound_begin(), so the current stack top's base field is
1574 * the variant field in question. We get the selected field here
1575 * thanks to this tag field (thus creating the selected field),
1576 * which will also provide us with its type. Then, this field
1577 * will remain the current selected one until the next callback
1578 * function call which is used to fill the current selected
1581 selected_field
= bt_ctf_field_variant_get_field(
1582 stack_top(notit
->stack
)->base
, tag_field
);
1583 if (!selected_field
) {
1587 selected_field_type
= bt_ctf_field_get_type(selected_field
);
1591 BT_PUT(selected_field
);
1593 return selected_field_type
;
1596 static struct bt_ctf_event
*create_event(struct bt_ctf_notif_iter
*notit
)
1598 struct bt_ctf_event
*event
;
1601 /* Create event object */
1602 event
= bt_ctf_event_create(notit
->meta
.event_class
);
1607 /* Set header, stream event context, context, and payload fields */
1608 ret
= bt_ctf_event_set_header(event
,
1609 notit
->dscopes
.stream_event_header
);
1614 ret
= bt_ctf_event_set_stream_event_context(event
,
1615 notit
->dscopes
.stream_event_context
);
1620 ret
= bt_ctf_event_set_event_context(event
,
1621 notit
->dscopes
.event_context
);
1626 ret
= bt_ctf_event_set_payload_field(event
,
1627 notit
->dscopes
.event_payload
);
1632 /* Associate with current packet */
1633 assert(notit
->packet
);
1634 ret
= bt_ctf_event_set_packet(event
, notit
->packet
);
1648 static void create_packet(struct bt_ctf_notif_iter
*notit
)
1651 struct bt_ctf_stream
*stream
= NULL
;
1652 struct bt_ctf_packet
*packet
= NULL
;
1654 /* Ask the user for the stream */
1655 stream
= notit
->medium
.medops
.get_stream(notit
->meta
.stream_class
,
1656 notit
->medium
.data
);
1662 packet
= bt_ctf_packet_create(stream
);
1667 /* Set packet's context and header fields */
1668 if (notit
->dscopes
.trace_packet_header
) {
1669 ret
= bt_ctf_packet_set_header(packet
,
1670 notit
->dscopes
.trace_packet_header
);
1676 if (notit
->dscopes
.stream_packet_context
) {
1677 ret
= bt_ctf_packet_set_context(packet
,
1678 notit
->dscopes
.stream_packet_context
);
1690 BT_MOVE(notit
->packet
, packet
);
1693 static void notify_new_packet(struct bt_ctf_notif_iter
*notit
,
1694 struct bt_ctf_notif_iter_notif
**notification
)
1696 struct bt_ctf_notif_iter_notif_new_packet
*rnotif
;
1698 rnotif
= g_new0(struct bt_ctf_notif_iter_notif_new_packet
, 1);
1703 rnotif
->base
.type
= BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET
;
1706 create_packet(notit
);
1707 if (!notit
->packet
) {
1711 rnotif
->packet
= bt_get(notit
->packet
);
1712 *notification
= (struct bt_ctf_notif_iter_notif
*) rnotif
;
1716 bt_ctf_notif_iter_notif_destroy(rnotif
);
1719 static void notify_end_of_packet(struct bt_ctf_notif_iter
*notit
,
1720 struct bt_ctf_notif_iter_notif
**notification
)
1722 struct bt_ctf_notif_iter_notif_end_of_packet
*rnotif
;
1724 rnotif
= g_new0(struct bt_ctf_notif_iter_notif_end_of_packet
, 1);
1729 rnotif
->base
.type
= BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET
;
1732 create_packet(notit
);
1733 if (!notit
->packet
) {
1737 rnotif
->packet
= bt_get(notit
->packet
);
1738 *notification
= (struct bt_ctf_notif_iter_notif
*) rnotif
;
1742 bt_ctf_notif_iter_notif_destroy(rnotif
);
1745 static void notify_event(struct bt_ctf_notif_iter
*notit
,
1746 struct bt_ctf_notif_iter_notif
**notification
)
1748 struct bt_ctf_notif_iter_notif_event
*rnotif
;
1749 struct bt_ctf_event
*event
= NULL
;
1751 rnotif
= g_new0(struct bt_ctf_notif_iter_notif_event
, 1);
1756 rnotif
->base
.type
= BT_CTF_NOTIF_ITER_NOTIF_EVENT
;
1759 event
= create_event(notit
);
1764 BT_MOVE(rnotif
->event
, event
);
1765 *notification
= (struct bt_ctf_notif_iter_notif
*) rnotif
;
1770 bt_ctf_notif_iter_notif_destroy(rnotif
);
1773 void bt_ctf_notif_iter_notif_destroy(void *vnotif
)
1775 struct bt_ctf_notif_iter_notif
*notif
= vnotif
;
1777 switch (notif
->type
) {
1778 case BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET
:
1780 struct bt_ctf_notif_iter_notif_new_packet
*rnotif
=
1781 (struct bt_ctf_notif_iter_notif_new_packet
*) notif
;
1783 BT_PUT(rnotif
->packet
);
1786 case BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET
:
1788 struct bt_ctf_notif_iter_notif_end_of_packet
*rnotif
=
1789 (struct bt_ctf_notif_iter_notif_end_of_packet
*) notif
;
1791 BT_PUT(rnotif
->packet
);
1794 case BT_CTF_NOTIF_ITER_NOTIF_EVENT
:
1796 struct bt_ctf_notif_iter_notif_event
*rnotif
=
1797 (struct bt_ctf_notif_iter_notif_event
*) notif
;
1799 BT_PUT(rnotif
->event
);
1809 struct bt_ctf_notif_iter
*bt_ctf_notif_iter_create(struct bt_ctf_trace
*trace
,
1810 size_t max_request_sz
,
1811 struct bt_ctf_notif_iter_medium_ops medops
,
1812 void *data
, FILE *err_stream
)
1814 struct bt_ctf_notif_iter
*notit
= NULL
;
1815 struct bt_ctf_btr_cbs cbs
= {
1817 .signed_int
= btr_signed_int_cb
,
1818 .unsigned_int
= btr_unsigned_int_cb
,
1819 .floating_point
= btr_floating_point_cb
,
1820 .string_begin
= btr_string_begin_cb
,
1821 .string
= btr_string_cb
,
1822 .string_end
= btr_string_end_cb
,
1823 .compound_begin
= btr_compound_begin_cb
,
1824 .compound_end
= btr_compound_end_cb
,
1827 .get_sequence_length
= btr_get_sequence_length_cb
,
1828 .get_variant_type
= btr_get_variant_type_cb
,
1833 assert(medops
.request_bytes
);
1834 notit
= g_new0(struct bt_ctf_notif_iter
, 1);
1836 PERR("Failed to allocate memory for CTF notification iterator\n");
1840 notit
->meta
.trace
= trace
;
1841 bt_get(notit
->meta
.trace
);
1842 notit
->medium
.medops
= medops
;
1843 notit
->medium
.max_request_sz
= max_request_sz
;
1844 notit
->medium
.data
= data
;
1845 notit
->err_stream
= err_stream
;
1846 notit
->stack
= stack_new(notit
);
1847 if (!notit
->stack
) {
1848 PERR("Failed to create stack\n");
1849 bt_ctf_notif_iter_destroy(notit
);
1854 notit
->btr
= bt_ctf_btr_create(cbs
, notit
, err_stream
);
1856 PERR("Failed to create binary type reader\n");
1857 bt_ctf_notif_iter_destroy(notit
);
1862 bt_ctf_notif_iter_reset(notit
);
1868 void bt_ctf_notif_iter_destroy(struct bt_ctf_notif_iter
*notit
)
1870 BT_PUT(notit
->meta
.trace
);
1871 BT_PUT(notit
->meta
.stream_class
);
1872 BT_PUT(notit
->meta
.event_class
);
1873 BT_PUT(notit
->packet
);
1874 put_all_dscopes(notit
);
1877 stack_destroy(notit
->stack
);
1881 bt_ctf_btr_destroy(notit
->btr
);
1887 enum bt_ctf_notif_iter_status
bt_ctf_notif_iter_get_next_notification(
1888 struct bt_ctf_notif_iter
*notit
,
1889 struct bt_ctf_notif_iter_notif
**notification
)
1891 enum bt_ctf_notif_iter_status status
= BT_CTF_NOTIF_ITER_STATUS_OK
;
1894 assert(notification
);
1897 status
= handle_state(notit
);
1898 if (status
!= BT_CTF_NOTIF_ITER_STATUS_OK
) {
1899 if (status
== BT_CTF_NOTIF_ITER_STATUS_EOF
) {
1900 PDBG("Medium operation reported end of file\n");
1902 PERR("Failed to handle state:\n");
1903 PERR(" State: %d\n", notit
->state
);
1908 switch (notit
->state
) {
1909 case STATE_EMIT_NOTIF_NEW_PACKET
:
1910 PDBG("Emitting new packet notification\n");
1911 notify_new_packet(notit
, notification
);
1912 if (!*notification
) {
1913 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
1916 case STATE_EMIT_NOTIF_EVENT
:
1917 PDBG("Emitting event notification\n");
1918 notify_event(notit
, notification
);
1919 if (!*notification
) {
1920 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
1923 case STATE_EMIT_NOTIF_END_OF_PACKET
:
1924 PDBG("Emitting end of packet notification\n");
1925 notify_end_of_packet(notit
, notification
);
1926 if (!*notification
) {
1927 status
= BT_CTF_NOTIF_ITER_STATUS_ERROR
;
1931 /* Non-emitting state: continue */