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-class.h>
35 #include <babeltrace/ctf-ir/fields.h>
36 #include <babeltrace/ctf-writer/stream-class.h>
37 #include <babeltrace/ctf-writer/stream.h>
42 enum bt_component_status
copy_clock_class(FILE *err
, struct bt_ctf_writer
*writer
,
43 struct bt_ctf_stream_class
*writer_stream_class
,
44 struct bt_ctf_clock_class
*clock_class
)
46 int64_t offset
, offset_s
;
49 const char *name
, *description
;
50 struct bt_ctf_clock_class
*writer_clock_class
= NULL
;
51 struct bt_ctf_trace
*trace
= NULL
;
52 enum bt_component_status ret
;
54 name
= bt_ctf_clock_class_get_name(clock_class
);
56 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
58 ret
= BT_COMPONENT_STATUS_ERROR
;
62 writer_clock_class
= bt_ctf_clock_class_create(name
);
63 if (!writer_clock_class
) {
64 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
66 ret
= BT_COMPONENT_STATUS_ERROR
;
70 description
= bt_ctf_clock_class_get_description(clock_class
);
72 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
74 ret
= BT_COMPONENT_STATUS_ERROR
;
78 int_ret
= bt_ctf_clock_class_set_description(writer_clock_class
,
81 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
83 ret
= BT_COMPONENT_STATUS_ERROR
;
87 u64_ret
= bt_ctf_clock_class_get_frequency(clock_class
);
88 if (u64_ret
== -1ULL) {
89 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
91 ret
= BT_COMPONENT_STATUS_ERROR
;
94 int_ret
= bt_ctf_clock_class_set_frequency(writer_clock_class
, u64_ret
);
96 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
98 ret
= BT_COMPONENT_STATUS_ERROR
;
102 u64_ret
= bt_ctf_clock_class_get_precision(clock_class
);
103 if (u64_ret
== -1ULL) {
104 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
106 ret
= BT_COMPONENT_STATUS_ERROR
;
109 int_ret
= bt_ctf_clock_class_set_precision(writer_clock_class
,
112 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
114 ret
= BT_COMPONENT_STATUS_ERROR
;
118 int_ret
= bt_ctf_clock_class_get_offset_s(clock_class
, &offset_s
);
120 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
122 ret
= BT_COMPONENT_STATUS_ERROR
;
126 int_ret
= bt_ctf_clock_class_set_offset_s(writer_clock_class
, offset_s
);
128 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
130 ret
= BT_COMPONENT_STATUS_ERROR
;
134 int_ret
= bt_ctf_clock_class_get_offset_cycles(clock_class
, &offset
);
136 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
138 ret
= BT_COMPONENT_STATUS_ERROR
;
142 int_ret
= bt_ctf_clock_class_set_offset_cycles(writer_clock_class
, offset
);
144 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
146 ret
= BT_COMPONENT_STATUS_ERROR
;
150 int_ret
= bt_ctf_clock_class_get_is_absolute(clock_class
);
152 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
154 ret
= BT_COMPONENT_STATUS_ERROR
;
158 int_ret
= bt_ctf_clock_class_set_is_absolute(writer_clock_class
, int_ret
);
160 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
162 ret
= BT_COMPONENT_STATUS_ERROR
;
166 trace
= bt_ctf_writer_get_trace(writer
);
168 ret
= BT_COMPONENT_STATUS_ERROR
;
172 int_ret
= bt_ctf_trace_add_clock_class(trace
, writer_clock_class
);
174 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
176 ret
= BT_COMPONENT_STATUS_ERROR
;
181 * Ownership transferred to the writer and the stream_class.
183 bt_put(writer_clock_class
);
184 ret
= BT_COMPONENT_STATUS_OK
;
189 BT_PUT(writer_clock_class
);
196 struct bt_ctf_event_class
*copy_event_class(FILE *err
, struct bt_ctf_event_class
*event_class
)
198 struct bt_ctf_event_class
*writer_event_class
= NULL
;
200 struct bt_ctf_field_type
*context
;
203 name
= bt_ctf_event_class_get_name(event_class
);
205 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
210 writer_event_class
= bt_ctf_event_class_create(name
);
211 if (!writer_event_class
) {
212 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
217 count
= bt_ctf_event_class_get_attribute_count(event_class
);
218 for (i
= 0; i
< count
; i
++) {
219 const char *attr_name
;
220 struct bt_value
*attr_value
;
223 attr_name
= bt_ctf_event_class_get_attribute_name(event_class
, i
);
225 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
227 BT_PUT(writer_event_class
);
230 attr_value
= bt_ctf_event_class_get_attribute_value(event_class
, i
);
232 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
234 BT_PUT(writer_event_class
);
238 ret
= bt_ctf_event_class_set_attribute(writer_event_class
,
239 attr_name
, attr_value
);
242 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
244 BT_PUT(writer_event_class
);
249 context
= bt_ctf_event_class_get_context_type(event_class
);
250 ret
= bt_ctf_event_class_set_context_type(writer_event_class
, context
);
253 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
258 count
= bt_ctf_event_class_get_field_count(event_class
);
259 for (i
= 0; i
< count
; i
++) {
260 const char *field_name
;
261 struct bt_ctf_field_type
*field_type
;
264 ret
= bt_ctf_event_class_get_field(event_class
, &field_name
,
267 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
268 BT_PUT(writer_event_class
);
272 ret
= bt_ctf_event_class_add_field(writer_event_class
, field_type
,
275 fprintf(err
, "[error] Cannot add field %s\n", field_name
);
276 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
278 BT_PUT(writer_event_class
);
285 return writer_event_class
;
289 enum bt_component_status
copy_event_classes(FILE *err
,
290 struct bt_ctf_writer
*writer
,
291 struct bt_ctf_stream_class
*stream_class
,
292 struct bt_ctf_stream_class
*writer_stream_class
)
294 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
297 count
= bt_ctf_stream_class_get_event_class_count(stream_class
);
299 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
304 for (i
= 0; i
< count
; i
++) {
305 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
308 event_class
= bt_ctf_stream_class_get_event_class(
311 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
313 ret
= BT_COMPONENT_STATUS_ERROR
;
317 writer_event_class
= copy_event_class(err
, event_class
);
318 if (!writer_event_class
) {
319 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
321 ret
= BT_COMPONENT_STATUS_ERROR
;
325 int_ret
= bt_ctf_stream_class_add_event_class(writer_stream_class
,
328 fprintf(err
, "[error] Failed to add event class\n");
329 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
331 ret
= BT_COMPONENT_STATUS_ERROR
;
336 bt_put(writer_event_class
);
344 enum bt_component_status
copy_stream_class(FILE *err
,
345 struct bt_ctf_writer
*writer
,
346 struct bt_ctf_stream_class
*stream_class
,
347 struct bt_ctf_stream_class
*writer_stream_class
)
349 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
350 struct bt_ctf_field_type
*type
;
351 int ret_int
, clock_class_count
, i
;
352 struct bt_ctf_trace
*trace
;
354 trace
= bt_ctf_stream_class_get_trace(stream_class
);
356 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
358 ret
= BT_COMPONENT_STATUS_ERROR
;
362 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
364 for (i
= 0; i
< clock_class_count
; i
++) {
365 struct bt_ctf_clock_class
*clock_class
=
366 bt_ctf_trace_get_clock_class(trace
, i
);
369 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
371 ret
= BT_COMPONENT_STATUS_ERROR
;
375 ret
= copy_clock_class(err
, writer
, writer_stream_class
, clock_class
);
377 if (ret
!= BT_COMPONENT_STATUS_OK
) {
378 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
384 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
386 ret
= BT_COMPONENT_STATUS_ERROR
;
387 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
392 ret_int
= bt_ctf_stream_class_set_packet_context_type(
393 writer_stream_class
, type
);
396 ret
= BT_COMPONENT_STATUS_ERROR
;
397 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
402 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
404 ret
= BT_COMPONENT_STATUS_ERROR
;
405 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
410 ret_int
= bt_ctf_stream_class_set_event_header_type(
411 writer_stream_class
, type
);
414 ret
= BT_COMPONENT_STATUS_ERROR
;
415 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
420 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
422 ret
= BT_COMPONENT_STATUS_ERROR
;
423 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
427 ret_int
= bt_ctf_stream_class_set_event_context_type(
428 writer_stream_class
, type
);
431 ret
= BT_COMPONENT_STATUS_ERROR
;
432 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
437 ret
= copy_event_classes(err
, writer
, stream_class
, writer_stream_class
);
438 if (ret
!= BT_COMPONENT_STATUS_OK
) {
439 fprintf(err
, "[error] Failed to copy event classes\n");
440 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
452 enum bt_component_status
copy_trace(FILE *err
, struct bt_ctf_writer
*ctf_writer
,
453 struct bt_ctf_trace
*trace
)
455 struct bt_ctf_trace
*writer_trace
;
456 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
457 int field_count
, i
, int_ret
;
458 struct bt_ctf_field_type
*header_type
;
460 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
462 ret
= BT_COMPONENT_STATUS_ERROR
;
463 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
468 field_count
= bt_ctf_trace_get_environment_field_count(trace
);
469 for (i
= 0; i
< field_count
; i
++) {
472 struct bt_value
*value
;
474 name
= bt_ctf_trace_get_environment_field_name(trace
, i
);
476 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
478 ret
= BT_COMPONENT_STATUS_ERROR
;
479 goto end_put_writer_trace
;
481 value
= bt_ctf_trace_get_environment_field_value(trace
, i
);
483 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
485 ret
= BT_COMPONENT_STATUS_ERROR
;
486 goto end_put_writer_trace
;
489 ret_int
= bt_ctf_trace_set_environment_field(writer_trace
,
493 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
495 fprintf(err
, "[error] Unable to set environment field %s\n",
497 ret
= BT_COMPONENT_STATUS_ERROR
;
498 goto end_put_writer_trace
;
502 header_type
= bt_ctf_trace_get_packet_header_type(writer_trace
);
504 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
505 ret
= BT_COMPONENT_STATUS_ERROR
;
506 goto end_put_writer_trace
;
509 int_ret
= bt_ctf_trace_set_packet_header_type(writer_trace
, header_type
);
511 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
512 ret
= BT_COMPONENT_STATUS_ERROR
;
513 goto end_put_header_type
;
518 end_put_writer_trace
:
519 bt_put(writer_trace
);
525 struct bt_ctf_stream_class
*insert_new_stream_class(
526 struct writer_component
*writer_component
,
527 struct bt_ctf_writer
*ctf_writer
,
528 struct bt_ctf_stream_class
*stream_class
)
530 struct bt_ctf_stream_class
*writer_stream_class
;
531 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
532 enum bt_component_status ret
;
534 if (strlen(name
) == 0) {
538 writer_stream_class
= bt_ctf_stream_class_create(name
);
539 if (!writer_stream_class
) {
540 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
541 __func__
, __FILE__
, __LINE__
);
545 ret
= copy_stream_class(writer_component
->err
,
546 ctf_writer
, stream_class
, writer_stream_class
);
547 if (ret
!= BT_COMPONENT_STATUS_OK
) {
548 fprintf(writer_component
->err
, "[error] Failed to copy stream class\n");
549 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
550 __func__
, __FILE__
, __LINE__
);
551 BT_PUT(writer_stream_class
);
554 g_hash_table_insert(writer_component
->stream_class_map
,
555 (gpointer
) stream_class
, writer_stream_class
);
558 return writer_stream_class
;
562 struct bt_ctf_stream
*insert_new_stream(
563 struct writer_component
*writer_component
,
564 struct bt_ctf_writer
*ctf_writer
,
565 struct bt_ctf_stream_class
*stream_class
,
566 struct bt_ctf_stream
*stream
)
568 struct bt_ctf_stream
*writer_stream
;
569 struct bt_ctf_stream_class
*writer_stream_class
;
571 writer_stream_class
= g_hash_table_lookup(
572 writer_component
->stream_class_map
,
573 (gpointer
) stream_class
);
574 if (writer_stream_class
) {
575 if (!bt_get(writer_stream_class
)) {
576 writer_stream
= NULL
;
577 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
578 __func__
, __FILE__
, __LINE__
);
582 writer_stream_class
= insert_new_stream_class(
583 writer_component
, ctf_writer
, stream_class
);
584 if (!writer_stream_class
) {
585 writer_stream
= NULL
;
586 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
587 __func__
, __FILE__
, __LINE__
);
592 writer_stream
= bt_ctf_writer_create_stream(ctf_writer
,
593 writer_stream_class
);
594 if (!writer_stream
) {
595 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
596 __func__
, __FILE__
, __LINE__
);
600 g_hash_table_insert(writer_component
->stream_map
, (gpointer
) stream
,
603 bt_ctf_writer_flush_metadata(ctf_writer
);
606 bt_put(writer_stream_class
);
608 return writer_stream
;
612 struct bt_ctf_stream
*lookup_stream(struct writer_component
*writer_component
,
613 struct bt_ctf_stream
*stream
)
615 return (struct bt_ctf_stream
*) g_hash_table_lookup(
616 writer_component
->stream_map
,
621 struct bt_ctf_event_class
*get_event_class(struct writer_component
*writer_component
,
622 struct bt_ctf_stream_class
*writer_stream_class
,
623 struct bt_ctf_event_class
*event_class
)
625 return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class
,
626 bt_ctf_event_class_get_name(event_class
));
629 struct bt_ctf_writer
*insert_new_writer(
630 struct writer_component
*writer_component
,
631 struct bt_ctf_trace
*trace
)
633 struct bt_ctf_writer
*ctf_writer
;
634 char trace_name
[PATH_MAX
];
635 enum bt_component_status ret
;
637 snprintf(trace_name
, PATH_MAX
, "%s/%s_%03d",
638 writer_component
->base_path
->str
,
639 writer_component
->trace_name_base
->str
,
640 writer_component
->trace_id
++);
641 printf_verbose("CTF-Writer creating trace in %s\n", trace_name
);
643 ctf_writer
= bt_ctf_writer_create(trace_name
);
645 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
646 __func__
, __FILE__
, __LINE__
);
650 ret
= copy_trace(writer_component
->err
, ctf_writer
, trace
);
651 if (ret
!= BT_COMPONENT_STATUS_OK
) {
652 fprintf(writer_component
->err
, "[error] Failed to copy trace\n");
653 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
654 __func__
, __FILE__
, __LINE__
);
659 g_hash_table_insert(writer_component
->trace_map
, (gpointer
) trace
,
667 struct bt_ctf_writer
*get_writer(struct writer_component
*writer_component
,
668 struct bt_ctf_stream_class
*stream_class
)
670 struct bt_ctf_trace
*trace
;
671 struct bt_ctf_writer
*ctf_writer
;
673 trace
= bt_ctf_stream_class_get_trace(stream_class
);
676 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
677 __func__
, __FILE__
, __LINE__
);
681 ctf_writer
= g_hash_table_lookup(writer_component
->trace_map
,
684 if (!bt_get(ctf_writer
)) {
686 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
687 __func__
, __FILE__
, __LINE__
);
691 ctf_writer
= insert_new_writer(writer_component
, trace
);
700 struct bt_ctf_stream
*get_writer_stream(
701 struct writer_component
*writer_component
,
702 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
704 struct bt_ctf_stream_class
*stream_class
;
705 struct bt_ctf_writer
*ctf_writer
;
706 struct bt_ctf_stream
*writer_stream
;
708 stream_class
= bt_ctf_stream_get_class(stream
);
710 writer_stream
= NULL
;
711 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
712 __func__
, __FILE__
, __LINE__
);
716 ctf_writer
= get_writer(writer_component
, stream_class
);
718 writer_stream
= NULL
;
719 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
720 __func__
, __FILE__
, __LINE__
);
721 goto end_put_stream_class
;
724 writer_stream
= lookup_stream(writer_component
, stream
);
727 if (!bt_get(writer_stream
)) {
728 writer_stream
= NULL
;
729 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
730 __func__
, __FILE__
, __LINE__
);
731 goto end_put_stream_class
;
734 writer_stream
= insert_new_stream(writer_component
, ctf_writer
,
735 stream_class
, stream
);
736 bt_get(writer_stream
);
740 end_put_stream_class
:
741 bt_put(stream_class
);
743 return writer_stream
;
747 enum bt_component_status
writer_new_packet(
748 struct writer_component
*writer_component
,
749 struct bt_ctf_packet
*packet
)
751 struct bt_ctf_stream
*stream
, *writer_stream
;
752 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
754 stream
= bt_ctf_packet_get_stream(packet
);
756 ret
= BT_COMPONENT_STATUS_ERROR
;
757 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
758 __func__
, __FILE__
, __LINE__
);
762 /* TODO: copy values for event discarded and packet_seq_num */
763 writer_stream
= get_writer_stream(writer_component
, packet
, stream
);
764 if (!writer_stream
) {
765 ret
= BT_COMPONENT_STATUS_ERROR
;
766 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
767 __func__
, __FILE__
, __LINE__
);
771 bt_put(writer_stream
);
780 enum bt_component_status
copy_packet_context_field(FILE *err
,
781 struct bt_ctf_field
*field
, const char *field_name
,
782 struct bt_ctf_field
*writer_packet_context
,
783 struct bt_ctf_field_type
*writer_packet_context_type
)
785 enum bt_component_status ret
;
786 struct bt_ctf_field
*writer_field
;
791 * TODO: handle the special case of the first/last packet that might
792 * be trimmed. In these cases, the timestamp_begin/end need to be
793 * explicitely set to the first/last event timestamps.
796 writer_field
= bt_ctf_field_structure_get_field(writer_packet_context
,
799 ret
= BT_COMPONENT_STATUS_ERROR
;
800 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
805 int_ret
= bt_ctf_field_unsigned_integer_get_value(field
, &value
);
807 fprintf(err
, "[error] Wrong packet_context field type\n");
808 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
810 ret
= BT_COMPONENT_STATUS_ERROR
;
811 goto end_put_writer_field
;
814 int_ret
= bt_ctf_field_unsigned_integer_set_value(writer_field
, value
);
816 ret
= BT_COMPONENT_STATUS_ERROR
;
817 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
819 goto end_put_writer_field
;
822 ret
= BT_COMPONENT_STATUS_OK
;
824 end_put_writer_field
:
825 bt_put(writer_field
);
831 enum bt_component_status
copy_packet_context(FILE *err
,
832 struct bt_ctf_packet
*packet
,
833 struct bt_ctf_stream
*writer_stream
)
835 enum bt_component_status ret
;
836 struct bt_ctf_field
*packet_context
, *writer_packet_context
;
837 struct bt_ctf_field_type
*struct_type
, *writer_packet_context_type
;
838 struct bt_ctf_stream_class
*writer_stream_class
;
839 int nr_fields
, i
, int_ret
;
841 packet_context
= bt_ctf_packet_get_context(packet
);
842 if (!packet_context
) {
843 ret
= BT_COMPONENT_STATUS_ERROR
;
844 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
849 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
850 if (!writer_stream_class
) {
851 ret
= BT_COMPONENT_STATUS_ERROR
;
852 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
854 goto end_put_packet_context
;
857 writer_packet_context_type
= bt_ctf_stream_class_get_packet_context_type(
858 writer_stream_class
);
859 if (!writer_packet_context_type
) {
860 ret
= BT_COMPONENT_STATUS_ERROR
;
861 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
863 goto end_put_writer_stream_class
;
866 struct_type
= bt_ctf_field_get_type(packet_context
);
868 ret
= BT_COMPONENT_STATUS_ERROR
;
869 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
871 goto end_put_writer_packet_context_type
;
874 writer_packet_context
= bt_ctf_field_create(writer_packet_context_type
);
875 if (!writer_packet_context
) {
876 ret
= BT_COMPONENT_STATUS_ERROR
;
877 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
879 goto end_put_struct_type
;
882 nr_fields
= bt_ctf_field_type_structure_get_field_count(struct_type
);
883 for (i
= 0; i
< nr_fields
; i
++) {
884 struct bt_ctf_field
*field
;
885 struct bt_ctf_field_type
*field_type
;
886 const char *field_name
;
888 field
= bt_ctf_field_structure_get_field_by_index(
891 ret
= BT_COMPONENT_STATUS_ERROR
;
892 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
894 goto end_put_writer_packet_context
;
896 if (bt_ctf_field_type_structure_get_field(struct_type
,
897 &field_name
, &field_type
, i
) < 0) {
898 ret
= BT_COMPONENT_STATUS_ERROR
;
900 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
902 goto end_put_writer_packet_context
;
905 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_TYPE_ID_INTEGER
) {
906 fprintf(err
, "[error] Unexpected packet context field type\n");
908 ret
= BT_COMPONENT_STATUS_ERROR
;
909 goto end_put_writer_packet_context
;
912 ret
= copy_packet_context_field(err
, field
, field_name
,
913 writer_packet_context
, writer_packet_context_type
);
916 if (ret
!= BT_COMPONENT_STATUS_OK
) {
917 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
919 goto end_put_writer_packet_context
;
923 int_ret
= bt_ctf_stream_set_packet_context(writer_stream
,
924 writer_packet_context
);
926 ret
= BT_COMPONENT_STATUS_ERROR
;
927 goto end_put_writer_packet_context
;
930 end_put_writer_packet_context
:
931 bt_put(writer_packet_context
);
934 end_put_writer_packet_context_type
:
935 bt_put(writer_packet_context_type
);
936 end_put_writer_stream_class
:
937 bt_put(writer_stream_class
);
938 end_put_packet_context
:
939 bt_put(packet_context
);
945 enum bt_component_status
writer_close_packet(
946 struct writer_component
*writer_component
,
947 struct bt_ctf_packet
*packet
)
949 struct bt_ctf_stream
*stream
, *writer_stream
;
950 enum bt_component_status ret
;
952 stream
= bt_ctf_packet_get_stream(packet
);
954 ret
= BT_COMPONENT_STATUS_ERROR
;
955 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
956 __func__
, __FILE__
, __LINE__
);
960 writer_stream
= lookup_stream(writer_component
, stream
);
961 if (!writer_stream
) {
962 ret
= BT_COMPONENT_STATUS_ERROR
;
963 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
964 __func__
, __FILE__
, __LINE__
);
968 if (!bt_get(writer_stream
)) {
969 fprintf(writer_component
->err
,
970 "[error] Failed to get reference on writer stream\n");
971 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
972 __func__
, __FILE__
, __LINE__
);
973 ret
= BT_COMPONENT_STATUS_ERROR
;
977 ret
= copy_packet_context(writer_component
->err
, packet
, writer_stream
);
978 if (ret
!= BT_COMPONENT_STATUS_OK
) {
979 ret
= BT_COMPONENT_STATUS_ERROR
;
980 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
981 __func__
, __FILE__
, __LINE__
);
985 ret
= bt_ctf_stream_flush(writer_stream
);
987 fprintf(writer_component
->err
,
988 "[error] Failed to flush packet\n");
989 ret
= BT_COMPONENT_STATUS_ERROR
;
992 ret
= BT_COMPONENT_STATUS_OK
;
994 bt_put(writer_stream
);
1003 struct bt_ctf_event
*copy_event(FILE *err
, struct bt_ctf_event
*event
,
1004 struct bt_ctf_event_class
*writer_event_class
)
1006 struct bt_ctf_event
*writer_event
;
1007 struct bt_ctf_field
*field
, *copy_field
;
1010 writer_event
= bt_ctf_event_create(writer_event_class
);
1011 if (!writer_event
) {
1012 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1017 field
= bt_ctf_event_get_header(event
);
1019 BT_PUT(writer_event
);
1020 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1021 __FILE__
, __LINE__
);
1024 copy_field
= bt_ctf_field_copy(field
);
1027 ret
= bt_ctf_event_set_header(writer_event
, copy_field
);
1029 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1030 __FILE__
, __LINE__
);
1036 /* Optional field, so it can fail silently. */
1037 field
= bt_ctf_event_get_stream_event_context(event
);
1038 copy_field
= bt_ctf_field_copy(field
);
1041 ret
= bt_ctf_event_set_stream_event_context(writer_event
,
1044 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1045 __FILE__
, __LINE__
);
1051 /* Optional field, so it can fail silently. */
1052 field
= bt_ctf_event_get_event_context(event
);
1053 copy_field
= bt_ctf_field_copy(field
);
1056 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1058 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1059 __FILE__
, __LINE__
);
1065 field
= bt_ctf_event_get_payload_field(event
);
1067 BT_PUT(writer_event
);
1068 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1069 __FILE__
, __LINE__
);
1072 copy_field
= bt_ctf_field_copy(field
);
1075 ret
= bt_ctf_event_set_payload_field(writer_event
, copy_field
);
1077 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1078 __FILE__
, __LINE__
);
1087 BT_PUT(writer_event
);
1089 return writer_event
;
1093 enum bt_component_status
writer_output_event(
1094 struct writer_component
*writer_component
,
1095 struct bt_ctf_event
*event
)
1097 enum bt_component_status ret
;
1098 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
1099 struct bt_ctf_stream
*stream
, *writer_stream
;
1100 struct bt_ctf_stream_class
*stream_class
, *writer_stream_class
;
1101 struct bt_ctf_event
*writer_event
;
1102 const char *event_name
;
1105 event_class
= bt_ctf_event_get_class(event
);
1107 ret
= BT_COMPONENT_STATUS_ERROR
;
1108 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1109 __FILE__
, __LINE__
);
1113 event_name
= bt_ctf_event_class_get_name(event_class
);
1115 ret
= BT_COMPONENT_STATUS_ERROR
;
1116 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1117 __FILE__
, __LINE__
);
1118 goto end_put_event_class
;
1121 stream
= bt_ctf_event_get_stream(event
);
1123 ret
= BT_COMPONENT_STATUS_ERROR
;
1124 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1125 __FILE__
, __LINE__
);
1126 goto end_put_event_class
;
1129 writer_stream
= lookup_stream(writer_component
, stream
);
1130 if (!writer_stream
|| !bt_get(writer_stream
)) {
1131 ret
= BT_COMPONENT_STATUS_ERROR
;
1132 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1133 __FILE__
, __LINE__
);
1134 goto end_put_stream
;
1137 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1138 if (!stream_class
) {
1139 ret
= BT_COMPONENT_STATUS_ERROR
;
1140 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1141 __FILE__
, __LINE__
);
1142 goto end_put_writer_stream
;
1145 writer_stream_class
= g_hash_table_lookup(
1146 writer_component
->stream_class_map
,
1147 (gpointer
) stream_class
);
1148 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1149 ret
= BT_COMPONENT_STATUS_ERROR
;
1150 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1151 __FILE__
, __LINE__
);
1152 goto end_put_stream_class
;
1155 writer_event_class
= get_event_class(writer_component
,
1156 writer_stream_class
, event_class
);
1157 if (!writer_event_class
) {
1158 ret
= BT_COMPONENT_STATUS_ERROR
;
1159 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1160 __FILE__
, __LINE__
);
1161 goto end_put_writer_stream_class
;
1164 writer_event
= copy_event(writer_component
->err
, event
, writer_event_class
);
1165 if (!writer_event
) {
1166 ret
= BT_COMPONENT_STATUS_ERROR
;
1167 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1168 __FILE__
, __LINE__
);
1169 fprintf(writer_component
->err
, "[error] Failed to copy event %s\n",
1170 bt_ctf_event_class_get_name(writer_event_class
));
1171 goto end_put_writer_event_class
;
1174 int_ret
= bt_ctf_stream_append_event(writer_stream
, writer_event
);
1176 ret
= BT_COMPONENT_STATUS_ERROR
;
1177 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1178 __FILE__
, __LINE__
);
1179 fprintf(writer_component
->err
, "[error] Failed to append event %s\n",
1180 bt_ctf_event_class_get_name(writer_event_class
));
1181 goto end_put_writer_event
;
1184 ret
= BT_COMPONENT_STATUS_OK
;
1186 end_put_writer_event
:
1187 bt_put(writer_event
);
1188 end_put_writer_event_class
:
1189 bt_put(writer_event_class
);
1190 end_put_writer_stream_class
:
1191 bt_put(writer_stream_class
);
1192 end_put_stream_class
:
1193 bt_put(stream_class
);
1194 end_put_writer_stream
:
1195 bt_put(writer_stream
);
1198 end_put_event_class
:
1199 bt_put(event_class
);