4 * Babeltrace CTF Writer Output Plugin Event Handling
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/ctf-ir/event.h>
30 #include <babeltrace/ctf-ir/packet.h>
31 #include <babeltrace/ctf-ir/event-class.h>
32 #include <babeltrace/ctf-ir/stream.h>
33 #include <babeltrace/ctf-ir/stream-class.h>
34 #include <babeltrace/ctf-ir/clock.h>
35 #include <babeltrace/ctf-ir/fields.h>
36 #include <babeltrace/ctf-writer/stream-class.h>
37 #include <babeltrace/ctf-writer/stream.h>
42 void tmp_clock(struct bt_ctf_writer
*writer
,
43 struct bt_ctf_stream_class
*writer_stream_class
,
44 struct bt_ctf_clock
*writer_clock
)
46 const char *clock_description
= "This is a test clock";
47 const uint64_t frequency
= 1000000000ULL;
48 const uint64_t offset_s
= 1351530929945824323;
49 const uint64_t precision
= 10;
50 const int is_absolute
= 0xFF;
52 bt_ctf_clock_set_description(writer_clock
, clock_description
);
53 bt_ctf_clock_set_frequency(writer_clock
, frequency
);
54 bt_ctf_clock_set_offset_s(writer_clock
, offset_s
);
55 bt_ctf_clock_set_precision(writer_clock
, precision
);
56 bt_ctf_clock_set_is_absolute(writer_clock
, is_absolute
);
57 bt_ctf_writer_add_clock(writer
, writer_clock
);
58 bt_ctf_stream_class_set_clock(writer_stream_class
, writer_clock
);
62 enum bt_component_status
copy_clock(FILE *err
, struct bt_ctf_writer
*writer
,
63 struct bt_ctf_stream_class
*writer_stream_class
,
64 struct bt_ctf_clock
*clock
,
65 struct bt_ctf_clock
*writer_clock
)
67 enum bt_component_status ret
;
68 int64_t offset
, offset_s
;
71 const char *name
, *description
;
73 name
= bt_ctf_clock_get_name(clock
);
75 ret
= BT_COMPONENT_STATUS_ERROR
;
76 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
81 writer_clock
= bt_ctf_clock_create(name
);
83 ret
= BT_COMPONENT_STATUS_ERROR
;
84 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
89 description
= bt_ctf_clock_get_description(clock
);
91 ret
= BT_COMPONENT_STATUS_ERROR
;
92 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
97 int_ret
= bt_ctf_clock_set_description(writer_clock
,
100 ret
= BT_COMPONENT_STATUS_ERROR
;
101 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
106 u64_ret
= bt_ctf_clock_get_frequency(clock
);
107 if (u64_ret
== -1ULL) {
108 ret
= BT_COMPONENT_STATUS_ERROR
;
109 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
113 int_ret
= bt_ctf_clock_set_frequency(writer_clock
, u64_ret
);
115 ret
= BT_COMPONENT_STATUS_ERROR
;
116 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
121 u64_ret
= bt_ctf_clock_get_precision(clock
);
122 if (u64_ret
== -1ULL) {
123 ret
= BT_COMPONENT_STATUS_ERROR
;
124 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
128 int_ret
= bt_ctf_clock_set_precision(writer_clock
, u64_ret
);
130 ret
= BT_COMPONENT_STATUS_ERROR
;
131 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
136 int_ret
= bt_ctf_clock_get_offset_s(clock
, &offset_s
);
138 ret
= BT_COMPONENT_STATUS_ERROR
;
139 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
144 int_ret
= bt_ctf_clock_set_offset_s(writer_clock
, offset_s
);
146 ret
= BT_COMPONENT_STATUS_ERROR
;
147 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
152 int_ret
= bt_ctf_clock_get_offset(clock
, &offset
);
154 ret
= BT_COMPONENT_STATUS_ERROR
;
155 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
160 int_ret
= bt_ctf_clock_set_offset(writer_clock
, offset
);
162 ret
= BT_COMPONENT_STATUS_ERROR
;
163 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
168 int_ret
= bt_ctf_clock_get_is_absolute(clock
);
170 ret
= BT_COMPONENT_STATUS_ERROR
;
171 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
175 int_ret
= bt_ctf_clock_set_is_absolute(writer_clock
, int_ret
);
177 ret
= BT_COMPONENT_STATUS_ERROR
;
178 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
183 ret
= bt_ctf_writer_add_clock(writer
, writer_clock
);
185 ret
= BT_COMPONENT_STATUS_ERROR
;
186 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
191 ret
= bt_ctf_stream_class_set_clock(writer_stream_class
,
194 ret
= BT_COMPONENT_STATUS_ERROR
;
195 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
200 * Ownership transferred to the writer and the stream_class.
202 bt_put(writer_clock
);
204 ret
= BT_COMPONENT_STATUS_OK
;
208 bt_put(writer_clock
);
214 struct bt_ctf_event_class
*copy_event_class(FILE *err
, struct bt_ctf_event_class
*event_class
)
216 struct bt_ctf_event_class
*writer_event_class
= NULL
;
218 struct bt_ctf_field_type
*context
;
221 name
= bt_ctf_event_class_get_name(event_class
);
223 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
228 writer_event_class
= bt_ctf_event_class_create(name
);
229 if (!writer_event_class
) {
230 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
235 count
= bt_ctf_event_class_get_attribute_count(event_class
);
236 for (i
= 0; i
< count
; i
++) {
237 const char *attr_name
;
238 struct bt_value
*attr_value
;
241 attr_name
= bt_ctf_event_class_get_attribute_name(event_class
, i
);
243 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
245 BT_PUT(writer_event_class
);
248 attr_value
= bt_ctf_event_class_get_attribute_value(event_class
, i
);
250 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
252 BT_PUT(writer_event_class
);
256 ret
= bt_ctf_event_class_set_attribute(writer_event_class
,
257 attr_name
, attr_value
);
259 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
261 BT_PUT(writer_event_class
);
266 context
= bt_ctf_event_class_get_context_type(event_class
);
268 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
273 ret
= bt_ctf_event_class_set_context_type(writer_event_class
, context
);
275 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
280 count
= bt_ctf_event_class_get_field_count(event_class
);
281 for (i
= 0; i
< count
; i
++) {
282 const char *field_name
;
283 struct bt_ctf_field_type
*field_type
;
286 ret
= bt_ctf_event_class_get_field(event_class
, &field_name
,
289 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
290 BT_PUT(writer_event_class
);
294 ret
= bt_ctf_event_class_add_field(writer_event_class
, field_type
,
297 fprintf(err
, "[error] Cannot add field %s\n", field_name
);
298 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
300 BT_PUT(writer_event_class
);
307 return writer_event_class
;
311 enum bt_component_status
copy_event_classes(FILE *err
,
312 struct bt_ctf_writer
*writer
,
313 struct bt_ctf_stream_class
*stream_class
,
314 struct bt_ctf_stream_class
*writer_stream_class
)
316 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
319 count
= bt_ctf_stream_class_get_event_class_count(stream_class
);
321 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
326 for (i
= 0; i
< count
; i
++) {
327 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
330 event_class
= bt_ctf_stream_class_get_event_class(
333 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
335 ret
= BT_COMPONENT_STATUS_ERROR
;
339 writer_event_class
= copy_event_class(err
, event_class
);
340 if (!writer_event_class
) {
341 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
343 ret
= BT_COMPONENT_STATUS_ERROR
;
347 int_ret
= bt_ctf_stream_class_add_event_class(writer_stream_class
,
350 fprintf(err
, "[error] Failed to add event class\n");
351 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
353 ret
= BT_COMPONENT_STATUS_ERROR
;
365 enum bt_component_status
copy_stream_class(FILE *err
,
366 struct bt_ctf_writer
*writer
,
367 struct bt_ctf_stream_class
*stream_class
,
368 struct bt_ctf_stream_class
*writer_stream_class
)
370 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
371 struct bt_ctf_field_type
*type
;
373 struct bt_ctf_clock
*writer_clock
;
375 writer_clock
= bt_ctf_clock_create("monotonic");
377 ret
= BT_COMPONENT_STATUS_ERROR
;
378 fprintf(err
, "[error] Failed to create clock\n");
379 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
384 tmp_clock(writer
, writer_stream_class
, writer_clock
);
387 * FIXME: waiting for the clock to work
389 struct bt_ctf_clock *clock;
390 clock = bt_ctf_stream_class_get_clock(stream_class);
392 ret = BT_COMPONENT_STATUS_ERROR;
395 ret = copy_clock(err, writer, writer_stream_class, clock, writer_clock);
396 if (ret != BT_COMPONENT_STATUS_OK) {
401 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
403 ret
= BT_COMPONENT_STATUS_ERROR
;
404 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
409 ret_int
= bt_ctf_stream_class_set_packet_context_type(
410 writer_stream_class
, type
);
412 ret
= BT_COMPONENT_STATUS_ERROR
;
413 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
418 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
420 ret
= BT_COMPONENT_STATUS_ERROR
;
421 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
426 ret_int
= bt_ctf_stream_class_set_event_header_type(
427 writer_stream_class
, type
);
429 ret
= BT_COMPONENT_STATUS_ERROR
;
430 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
435 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
437 ret
= BT_COMPONENT_STATUS_ERROR
;
438 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
443 ret_int
= bt_ctf_stream_class_set_event_context_type(
444 writer_stream_class
, type
);
446 ret
= BT_COMPONENT_STATUS_ERROR
;
447 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
452 ret
= copy_event_classes(err
, writer
, stream_class
, writer_stream_class
);
453 if (ret
!= BT_COMPONENT_STATUS_OK
) {
454 fprintf(err
, "[error] Failed to copy event classes\n");
455 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
467 enum bt_component_status
copy_trace(FILE *err
, struct bt_ctf_writer
*ctf_writer
,
468 struct bt_ctf_trace
*trace
)
470 struct bt_ctf_trace
*writer_trace
;
471 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
472 int field_count
, i
, int_ret
;
473 struct bt_ctf_field_type
*header_type
;
475 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
477 ret
= BT_COMPONENT_STATUS_ERROR
;
478 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
483 field_count
= bt_ctf_trace_get_environment_field_count(trace
);
484 for (i
= 0; i
< field_count
; i
++) {
487 struct bt_value
*value
;
489 name
= bt_ctf_trace_get_environment_field_name(trace
, i
);
491 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
493 ret
= BT_COMPONENT_STATUS_ERROR
;
494 goto end_put_writer_trace
;
496 value
= bt_ctf_trace_get_environment_field_value(trace
, i
);
498 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
500 ret
= BT_COMPONENT_STATUS_ERROR
;
501 goto end_put_writer_trace
;
504 ret_int
= bt_ctf_trace_set_environment_field(writer_trace
,
507 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
509 fprintf(err
, "[error] Unable to set environment field %s\n",
511 ret
= BT_COMPONENT_STATUS_ERROR
;
512 goto end_put_writer_trace
;
516 header_type
= bt_ctf_trace_get_packet_header_type(writer_trace
);
518 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
519 ret
= BT_COMPONENT_STATUS_ERROR
;
520 goto end_put_writer_trace
;
523 int_ret
= bt_ctf_trace_set_packet_header_type(writer_trace
, header_type
);
525 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
526 ret
= BT_COMPONENT_STATUS_ERROR
;
527 goto end_put_header_type
;
532 end_put_writer_trace
:
533 bt_put(writer_trace
);
539 struct bt_ctf_stream_class
*insert_new_stream_class(
540 struct writer_component
*writer_component
,
541 struct bt_ctf_writer
*ctf_writer
,
542 struct bt_ctf_stream_class
*stream_class
)
544 struct bt_ctf_stream_class
*writer_stream_class
;
545 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
546 enum bt_component_status ret
;
548 if (strlen(name
) == 0) {
552 writer_stream_class
= bt_ctf_stream_class_create(name
);
553 if (!writer_stream_class
) {
554 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
555 __func__
, __FILE__
, __LINE__
);
559 ret
= copy_stream_class(writer_component
->err
,
560 ctf_writer
, stream_class
, writer_stream_class
);
561 if (ret
!= BT_COMPONENT_STATUS_OK
) {
562 fprintf(writer_component
->err
, "[error] Failed to copy stream class\n");
563 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
564 __func__
, __FILE__
, __LINE__
);
565 BT_PUT(writer_stream_class
);
568 g_hash_table_insert(writer_component
->stream_class_map
,
569 (gpointer
) stream_class
, writer_stream_class
);
572 return writer_stream_class
;
576 struct bt_ctf_stream
*insert_new_stream(
577 struct writer_component
*writer_component
,
578 struct bt_ctf_writer
*ctf_writer
,
579 struct bt_ctf_stream_class
*stream_class
,
580 struct bt_ctf_stream
*stream
)
582 struct bt_ctf_stream
*writer_stream
;
583 struct bt_ctf_stream_class
*writer_stream_class
;
585 writer_stream_class
= g_hash_table_lookup(
586 writer_component
->stream_class_map
,
587 (gpointer
) stream_class
);
588 if (writer_stream_class
) {
589 if (!bt_get(writer_stream_class
)) {
590 writer_stream
= NULL
;
591 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
592 __func__
, __FILE__
, __LINE__
);
596 writer_stream_class
= insert_new_stream_class(
597 writer_component
, ctf_writer
, stream_class
);
598 if (!writer_stream_class
) {
599 writer_stream
= NULL
;
600 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
601 __func__
, __FILE__
, __LINE__
);
606 writer_stream
= bt_ctf_writer_create_stream(ctf_writer
,
607 writer_stream_class
);
608 if (!writer_stream
) {
609 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
610 __func__
, __FILE__
, __LINE__
);
614 g_hash_table_insert(writer_component
->stream_map
, (gpointer
) stream
,
617 bt_ctf_writer_flush_metadata(ctf_writer
);
620 bt_put(writer_stream_class
);
622 return writer_stream
;
626 struct bt_ctf_stream
*lookup_stream(struct writer_component
*writer_component
,
627 struct bt_ctf_stream
*stream
)
629 return (struct bt_ctf_stream
*) g_hash_table_lookup(
630 writer_component
->stream_map
,
635 struct bt_ctf_event_class
*get_event_class(struct writer_component
*writer_component
,
636 struct bt_ctf_stream_class
*writer_stream_class
,
637 struct bt_ctf_event_class
*event_class
)
639 return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class
,
640 bt_ctf_event_class_get_name(event_class
));
643 struct bt_ctf_writer
*insert_new_writer(
644 struct writer_component
*writer_component
,
645 struct bt_ctf_trace
*trace
)
647 struct bt_ctf_writer
*ctf_writer
;
648 char trace_name
[PATH_MAX
];
649 enum bt_component_status ret
;
651 snprintf(trace_name
, PATH_MAX
, "%s/%s_%03d",
652 writer_component
->base_path
->str
,
653 writer_component
->trace_name_base
->str
,
654 writer_component
->trace_id
++);
655 printf_verbose("CTF-Writer creating trace in %s\n", trace_name
);
657 ctf_writer
= bt_ctf_writer_create(trace_name
);
659 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
660 __func__
, __FILE__
, __LINE__
);
664 ret
= copy_trace(writer_component
->err
, ctf_writer
, trace
);
665 if (ret
!= BT_COMPONENT_STATUS_OK
) {
666 fprintf(writer_component
->err
, "[error] Failed to copy trace\n");
667 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
668 __func__
, __FILE__
, __LINE__
);
673 g_hash_table_insert(writer_component
->trace_map
, (gpointer
) trace
,
681 struct bt_ctf_writer
*get_writer(struct writer_component
*writer_component
,
682 struct bt_ctf_stream_class
*stream_class
)
684 struct bt_ctf_trace
*trace
;
685 struct bt_ctf_writer
*ctf_writer
;
687 trace
= bt_ctf_stream_class_get_trace(stream_class
);
690 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
691 __func__
, __FILE__
, __LINE__
);
695 ctf_writer
= g_hash_table_lookup(writer_component
->trace_map
,
698 if (!bt_get(ctf_writer
)) {
700 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
701 __func__
, __FILE__
, __LINE__
);
705 ctf_writer
= insert_new_writer(writer_component
, trace
);
714 struct bt_ctf_stream
*get_writer_stream(
715 struct writer_component
*writer_component
,
716 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
718 struct bt_ctf_stream_class
*stream_class
;
719 struct bt_ctf_writer
*ctf_writer
;
720 struct bt_ctf_stream
*writer_stream
;
722 stream_class
= bt_ctf_stream_get_class(stream
);
724 writer_stream
= NULL
;
725 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
726 __func__
, __FILE__
, __LINE__
);
730 ctf_writer
= get_writer(writer_component
, stream_class
);
732 writer_stream
= NULL
;
733 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
734 __func__
, __FILE__
, __LINE__
);
735 goto end_put_stream_class
;
738 writer_stream
= lookup_stream(writer_component
, stream
);
741 if (!bt_get(writer_stream
)) {
742 writer_stream
= NULL
;
743 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
744 __func__
, __FILE__
, __LINE__
);
745 goto end_put_stream_class
;
748 writer_stream
= insert_new_stream(writer_component
, ctf_writer
,
749 stream_class
, stream
);
753 end_put_stream_class
:
754 bt_put(stream_class
);
756 return writer_stream
;
760 enum bt_component_status
writer_new_packet(
761 struct writer_component
*writer_component
,
762 struct bt_ctf_packet
*packet
)
764 struct bt_ctf_stream
*stream
, *writer_stream
;
765 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
767 stream
= bt_ctf_packet_get_stream(packet
);
769 ret
= BT_COMPONENT_STATUS_ERROR
;
770 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
771 __func__
, __FILE__
, __LINE__
);
775 /* TODO: copy values for event discarded and packet_seq_num */
776 writer_stream
= get_writer_stream(writer_component
, packet
, stream
);
777 if (!writer_stream
) {
778 ret
= BT_COMPONENT_STATUS_ERROR
;
779 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
780 __func__
, __FILE__
, __LINE__
);
784 bt_put(writer_stream
);
793 enum bt_component_status
copy_packet_context_field(FILE *err
,
794 struct bt_ctf_field
*field
, const char *field_name
,
795 struct bt_ctf_field
*writer_packet_context
,
796 struct bt_ctf_field_type
*writer_packet_context_type
)
798 enum bt_component_status ret
;
799 struct bt_ctf_field
*writer_field
;
804 * TODO: handle the special case of the first/last packet that might
805 * be trimmed. In these cases, the timestamp_begin/end need to be
806 * explicitely set to the first/last event timestamps.
809 writer_field
= bt_ctf_field_structure_get_field(writer_packet_context
,
812 ret
= BT_COMPONENT_STATUS_ERROR
;
813 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
818 int_ret
= bt_ctf_field_unsigned_integer_get_value(field
, &value
);
820 fprintf(err
, "[error] Wrong packet_context field type\n");
821 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
823 ret
= BT_COMPONENT_STATUS_ERROR
;
824 goto end_put_writer_field
;
827 int_ret
= bt_ctf_field_unsigned_integer_set_value(writer_field
, value
);
829 ret
= BT_COMPONENT_STATUS_ERROR
;
830 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
832 goto end_put_writer_field
;
835 ret
= BT_COMPONENT_STATUS_OK
;
837 end_put_writer_field
:
838 bt_put(writer_field
);
844 enum bt_component_status
copy_packet_context(FILE *err
,
845 struct bt_ctf_packet
*packet
,
846 struct bt_ctf_stream
*writer_stream
)
848 enum bt_component_status ret
;
849 struct bt_ctf_field
*packet_context
, *writer_packet_context
;
850 struct bt_ctf_field_type
*struct_type
, *writer_packet_context_type
;
851 struct bt_ctf_stream_class
*writer_stream_class
;
852 int nr_fields
, i
, int_ret
;
854 packet_context
= bt_ctf_packet_get_context(packet
);
855 if (!packet_context
) {
856 ret
= BT_COMPONENT_STATUS_ERROR
;
857 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
862 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
863 if (!writer_stream_class
) {
864 ret
= BT_COMPONENT_STATUS_ERROR
;
865 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
867 goto end_put_packet_context
;
870 writer_packet_context_type
= bt_ctf_stream_class_get_packet_context_type(
871 writer_stream_class
);
872 if (!writer_packet_context_type
) {
873 ret
= BT_COMPONENT_STATUS_ERROR
;
874 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
876 goto end_put_writer_stream_class
;
879 struct_type
= bt_ctf_field_get_type(packet_context
);
881 ret
= BT_COMPONENT_STATUS_ERROR
;
882 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
884 goto end_put_writer_packet_context_type
;
887 writer_packet_context
= bt_ctf_field_create(writer_packet_context_type
);
888 if (!writer_packet_context
) {
889 ret
= BT_COMPONENT_STATUS_ERROR
;
890 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
892 goto end_put_struct_type
;
895 nr_fields
= bt_ctf_field_type_structure_get_field_count(struct_type
);
896 for (i
= 0; i
< nr_fields
; i
++) {
897 struct bt_ctf_field
*field
;
898 struct bt_ctf_field_type
*field_type
;
899 const char *field_name
;
901 field
= bt_ctf_field_structure_get_field_by_index(
904 ret
= BT_COMPONENT_STATUS_ERROR
;
905 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
907 goto end_put_writer_packet_context
;
909 if (bt_ctf_field_type_structure_get_field(struct_type
,
910 &field_name
, &field_type
, i
) < 0) {
911 ret
= BT_COMPONENT_STATUS_ERROR
;
913 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
915 goto end_put_writer_packet_context
;
918 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_TYPE_ID_INTEGER
) {
919 fprintf(err
, "[error] Unexpected packet context field type\n");
921 ret
= BT_COMPONENT_STATUS_ERROR
;
922 goto end_put_writer_packet_context
;
925 ret
= copy_packet_context_field(err
, field
, field_name
,
926 writer_packet_context
, writer_packet_context_type
);
929 if (ret
!= BT_COMPONENT_STATUS_OK
) {
930 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
932 goto end_put_writer_packet_context
;
936 int_ret
= bt_ctf_stream_set_packet_context(writer_stream
,
937 writer_packet_context
);
939 ret
= BT_COMPONENT_STATUS_ERROR
;
940 goto end_put_writer_packet_context
;
943 end_put_writer_packet_context
:
944 bt_put(writer_packet_context
);
947 end_put_writer_packet_context_type
:
948 bt_put(writer_packet_context_type
);
949 end_put_writer_stream_class
:
950 bt_put(writer_stream_class
);
951 end_put_packet_context
:
952 bt_put(packet_context
);
958 enum bt_component_status
writer_close_packet(
959 struct writer_component
*writer_component
,
960 struct bt_ctf_packet
*packet
)
962 struct bt_ctf_stream
*stream
, *writer_stream
;
963 enum bt_component_status ret
;
965 stream
= bt_ctf_packet_get_stream(packet
);
967 ret
= BT_COMPONENT_STATUS_ERROR
;
968 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
969 __func__
, __FILE__
, __LINE__
);
973 writer_stream
= lookup_stream(writer_component
, stream
);
974 if (!writer_stream
) {
975 ret
= BT_COMPONENT_STATUS_ERROR
;
976 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
977 __func__
, __FILE__
, __LINE__
);
981 if (!bt_get(writer_stream
)) {
982 fprintf(writer_component
->err
,
983 "[error] Failed to get reference on writer stream\n");
984 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
985 __func__
, __FILE__
, __LINE__
);
986 ret
= BT_COMPONENT_STATUS_ERROR
;
990 ret
= copy_packet_context(writer_component
->err
, packet
, writer_stream
);
991 if (ret
!= BT_COMPONENT_STATUS_OK
) {
992 ret
= BT_COMPONENT_STATUS_ERROR
;
993 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
994 __func__
, __FILE__
, __LINE__
);
998 ret
= bt_ctf_stream_flush(writer_stream
);
1000 fprintf(writer_component
->err
,
1001 "[error] Failed to flush packet\n");
1002 ret
= BT_COMPONENT_STATUS_ERROR
;
1005 ret
= BT_COMPONENT_STATUS_OK
;
1007 bt_put(writer_stream
);
1016 struct bt_ctf_event
*copy_event(FILE *err
, struct bt_ctf_event
*event
,
1017 struct bt_ctf_event_class
*writer_event_class
)
1019 struct bt_ctf_event
*writer_event
;
1020 struct bt_ctf_field
*field
;
1023 writer_event
= bt_ctf_event_create(writer_event_class
);
1024 if (!writer_event
) {
1025 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1029 field
= bt_ctf_event_get_header(event
);
1030 ret
= bt_ctf_event_set_header(writer_event
,
1031 bt_ctf_field_copy(field
));
1033 BT_PUT(writer_event
);
1034 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1038 field
= bt_ctf_event_get_stream_event_context(event
);
1039 ret
= bt_ctf_event_set_stream_event_context(writer_event
,
1040 bt_ctf_field_copy(field
));
1042 BT_PUT(writer_event
);
1043 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1047 field
= bt_ctf_event_get_event_context(event
);
1048 ret
= bt_ctf_event_set_event_context(writer_event
,
1049 bt_ctf_field_copy(field
));
1051 BT_PUT(writer_event
);
1052 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1056 field
= bt_ctf_event_get_payload_field(event
);
1057 ret
= bt_ctf_event_set_payload_field(writer_event
,
1058 bt_ctf_field_copy(field
));
1060 BT_PUT(writer_event
);
1061 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1066 return writer_event
;
1070 enum bt_component_status
writer_output_event(
1071 struct writer_component
*writer_component
,
1072 struct bt_ctf_event
*event
)
1074 enum bt_component_status ret
;
1075 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
1076 struct bt_ctf_stream
*stream
, *writer_stream
;
1077 struct bt_ctf_stream_class
*stream_class
, *writer_stream_class
;
1078 struct bt_ctf_event
*writer_event
;
1079 const char *event_name
;
1082 event_class
= bt_ctf_event_get_class(event
);
1084 ret
= BT_COMPONENT_STATUS_ERROR
;
1085 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1086 __FILE__
, __LINE__
);
1090 event_name
= bt_ctf_event_class_get_name(event_class
);
1092 ret
= BT_COMPONENT_STATUS_ERROR
;
1093 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1094 __FILE__
, __LINE__
);
1095 goto end_put_event_class
;
1098 stream
= bt_ctf_event_get_stream(event
);
1100 ret
= BT_COMPONENT_STATUS_ERROR
;
1101 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1102 __FILE__
, __LINE__
);
1103 goto end_put_event_class
;
1106 writer_stream
= lookup_stream(writer_component
, stream
);
1107 if (!writer_stream
|| !bt_get(writer_stream
)) {
1108 ret
= BT_COMPONENT_STATUS_ERROR
;
1109 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1110 __FILE__
, __LINE__
);
1111 goto end_put_stream
;
1114 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1115 if (!stream_class
) {
1116 ret
= BT_COMPONENT_STATUS_ERROR
;
1117 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1118 __FILE__
, __LINE__
);
1119 goto end_put_writer_stream
;
1122 writer_stream_class
= g_hash_table_lookup(
1123 writer_component
->stream_class_map
,
1124 (gpointer
) stream_class
);
1125 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1126 ret
= BT_COMPONENT_STATUS_ERROR
;
1127 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1128 __FILE__
, __LINE__
);
1129 goto end_put_stream_class
;
1132 writer_event_class
= get_event_class(writer_component
,
1133 writer_stream_class
, event_class
);
1134 if (!writer_event_class
) {
1135 ret
= BT_COMPONENT_STATUS_ERROR
;
1136 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1137 __FILE__
, __LINE__
);
1138 goto end_put_writer_stream_class
;
1141 writer_event
= copy_event(writer_component
->err
, event
, writer_event_class
);
1142 if (!writer_event
) {
1143 ret
= BT_COMPONENT_STATUS_ERROR
;
1144 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1145 __FILE__
, __LINE__
);
1146 fprintf(writer_component
->err
, "[error] Failed to copy event %s\n",
1147 bt_ctf_event_class_get_name(writer_event_class
));
1148 goto end_put_writer_event_class
;
1151 int_ret
= bt_ctf_stream_append_event(writer_stream
, writer_event
);
1153 ret
= BT_COMPONENT_STATUS_ERROR
;
1154 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1155 __FILE__
, __LINE__
);
1156 fprintf(writer_component
->err
, "[error] Failed to append event %s\n",
1157 bt_ctf_event_class_get_name(writer_event_class
));
1158 goto end_put_writer_event
;
1161 ret
= BT_COMPONENT_STATUS_OK
;
1163 end_put_writer_event
:
1164 bt_put(writer_event
);
1165 end_put_writer_event_class
:
1166 bt_put(writer_event_class
);
1167 end_put_writer_stream_class
:
1168 bt_put(writer_stream_class
);
1169 end_put_stream_class
:
1170 bt_put(stream_class
);
1171 end_put_writer_stream
:
1172 bt_put(writer_stream
);
1175 end_put_event_class
:
1176 bt_put(event_class
);