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
;
343 enum bt_component_status
copy_stream_class(FILE *err
,
344 struct bt_ctf_writer
*writer
,
345 struct bt_ctf_stream_class
*stream_class
,
346 struct bt_ctf_stream_class
*writer_stream_class
)
348 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
349 struct bt_ctf_field_type
*type
;
350 int ret_int
, clock_class_count
, i
;
351 struct bt_ctf_trace
*trace
;
353 trace
= bt_ctf_stream_class_get_trace(stream_class
);
355 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
357 ret
= BT_COMPONENT_STATUS_ERROR
;
361 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
363 for (i
= 0; i
< clock_class_count
; i
++) {
364 struct bt_ctf_clock_class
*clock_class
=
365 bt_ctf_trace_get_clock_class(trace
, i
);
368 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
370 ret
= BT_COMPONENT_STATUS_ERROR
;
374 ret
= copy_clock_class(err
, writer
, writer_stream_class
, clock_class
);
376 if (ret
!= BT_COMPONENT_STATUS_OK
) {
377 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
383 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
385 ret
= BT_COMPONENT_STATUS_ERROR
;
386 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
391 ret_int
= bt_ctf_stream_class_set_packet_context_type(
392 writer_stream_class
, type
);
395 ret
= BT_COMPONENT_STATUS_ERROR
;
396 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
401 type
= bt_ctf_stream_class_get_event_header_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_event_header_type(
410 writer_stream_class
, type
);
413 ret
= BT_COMPONENT_STATUS_ERROR
;
414 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
419 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
421 ret
= BT_COMPONENT_STATUS_ERROR
;
422 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
426 ret_int
= bt_ctf_stream_class_set_event_context_type(
427 writer_stream_class
, type
);
430 ret
= BT_COMPONENT_STATUS_ERROR
;
431 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
436 ret
= copy_event_classes(err
, writer
, stream_class
, writer_stream_class
);
437 if (ret
!= BT_COMPONENT_STATUS_OK
) {
438 fprintf(err
, "[error] Failed to copy event classes\n");
439 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
451 enum bt_component_status
copy_trace(FILE *err
, struct bt_ctf_writer
*ctf_writer
,
452 struct bt_ctf_trace
*trace
)
454 struct bt_ctf_trace
*writer_trace
;
455 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
456 int field_count
, i
, int_ret
;
457 struct bt_ctf_field_type
*header_type
;
459 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
461 ret
= BT_COMPONENT_STATUS_ERROR
;
462 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
467 field_count
= bt_ctf_trace_get_environment_field_count(trace
);
468 for (i
= 0; i
< field_count
; i
++) {
471 struct bt_value
*value
;
473 name
= bt_ctf_trace_get_environment_field_name(trace
, i
);
475 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
477 ret
= BT_COMPONENT_STATUS_ERROR
;
478 goto end_put_writer_trace
;
480 value
= bt_ctf_trace_get_environment_field_value(trace
, i
);
482 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
484 ret
= BT_COMPONENT_STATUS_ERROR
;
485 goto end_put_writer_trace
;
488 ret_int
= bt_ctf_trace_set_environment_field(writer_trace
,
492 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
494 fprintf(err
, "[error] Unable to set environment field %s\n",
496 ret
= BT_COMPONENT_STATUS_ERROR
;
497 goto end_put_writer_trace
;
501 header_type
= bt_ctf_trace_get_packet_header_type(writer_trace
);
503 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
504 ret
= BT_COMPONENT_STATUS_ERROR
;
505 goto end_put_writer_trace
;
508 int_ret
= bt_ctf_trace_set_packet_header_type(writer_trace
, header_type
);
510 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
511 ret
= BT_COMPONENT_STATUS_ERROR
;
512 goto end_put_header_type
;
517 end_put_writer_trace
:
518 bt_put(writer_trace
);
524 struct bt_ctf_stream_class
*insert_new_stream_class(
525 struct writer_component
*writer_component
,
526 struct bt_ctf_writer
*ctf_writer
,
527 struct bt_ctf_stream_class
*stream_class
)
529 struct bt_ctf_stream_class
*writer_stream_class
;
530 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
531 enum bt_component_status ret
;
533 if (strlen(name
) == 0) {
537 writer_stream_class
= bt_ctf_stream_class_create(name
);
538 if (!writer_stream_class
) {
539 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
540 __func__
, __FILE__
, __LINE__
);
544 ret
= copy_stream_class(writer_component
->err
,
545 ctf_writer
, stream_class
, writer_stream_class
);
546 if (ret
!= BT_COMPONENT_STATUS_OK
) {
547 fprintf(writer_component
->err
, "[error] Failed to copy stream class\n");
548 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
549 __func__
, __FILE__
, __LINE__
);
550 BT_PUT(writer_stream_class
);
553 g_hash_table_insert(writer_component
->stream_class_map
,
554 (gpointer
) stream_class
, writer_stream_class
);
557 return writer_stream_class
;
561 struct bt_ctf_stream
*insert_new_stream(
562 struct writer_component
*writer_component
,
563 struct bt_ctf_writer
*ctf_writer
,
564 struct bt_ctf_stream_class
*stream_class
,
565 struct bt_ctf_stream
*stream
)
567 struct bt_ctf_stream
*writer_stream
;
568 struct bt_ctf_stream_class
*writer_stream_class
;
570 writer_stream_class
= g_hash_table_lookup(
571 writer_component
->stream_class_map
,
572 (gpointer
) stream_class
);
573 if (writer_stream_class
) {
574 if (!bt_get(writer_stream_class
)) {
575 writer_stream
= NULL
;
576 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
577 __func__
, __FILE__
, __LINE__
);
581 writer_stream_class
= insert_new_stream_class(
582 writer_component
, ctf_writer
, stream_class
);
583 if (!writer_stream_class
) {
584 writer_stream
= NULL
;
585 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
586 __func__
, __FILE__
, __LINE__
);
591 writer_stream
= bt_ctf_writer_create_stream(ctf_writer
,
592 writer_stream_class
);
593 if (!writer_stream
) {
594 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
595 __func__
, __FILE__
, __LINE__
);
599 g_hash_table_insert(writer_component
->stream_map
, (gpointer
) stream
,
602 bt_ctf_writer_flush_metadata(ctf_writer
);
605 bt_put(writer_stream_class
);
607 return writer_stream
;
611 struct bt_ctf_stream
*lookup_stream(struct writer_component
*writer_component
,
612 struct bt_ctf_stream
*stream
)
614 return (struct bt_ctf_stream
*) g_hash_table_lookup(
615 writer_component
->stream_map
,
620 struct bt_ctf_event_class
*get_event_class(struct writer_component
*writer_component
,
621 struct bt_ctf_stream_class
*writer_stream_class
,
622 struct bt_ctf_event_class
*event_class
)
624 return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class
,
625 bt_ctf_event_class_get_name(event_class
));
628 struct bt_ctf_writer
*insert_new_writer(
629 struct writer_component
*writer_component
,
630 struct bt_ctf_trace
*trace
)
632 struct bt_ctf_writer
*ctf_writer
;
633 char trace_name
[PATH_MAX
];
634 enum bt_component_status ret
;
636 snprintf(trace_name
, PATH_MAX
, "%s/%s_%03d",
637 writer_component
->base_path
->str
,
638 writer_component
->trace_name_base
->str
,
639 writer_component
->trace_id
++);
640 printf_verbose("CTF-Writer creating trace in %s\n", trace_name
);
642 ctf_writer
= bt_ctf_writer_create(trace_name
);
644 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
645 __func__
, __FILE__
, __LINE__
);
649 ret
= copy_trace(writer_component
->err
, ctf_writer
, trace
);
650 if (ret
!= BT_COMPONENT_STATUS_OK
) {
651 fprintf(writer_component
->err
, "[error] Failed to copy trace\n");
652 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
653 __func__
, __FILE__
, __LINE__
);
658 g_hash_table_insert(writer_component
->trace_map
, (gpointer
) trace
,
666 struct bt_ctf_writer
*get_writer(struct writer_component
*writer_component
,
667 struct bt_ctf_stream_class
*stream_class
)
669 struct bt_ctf_trace
*trace
;
670 struct bt_ctf_writer
*ctf_writer
;
672 trace
= bt_ctf_stream_class_get_trace(stream_class
);
675 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
676 __func__
, __FILE__
, __LINE__
);
680 ctf_writer
= g_hash_table_lookup(writer_component
->trace_map
,
683 if (!bt_get(ctf_writer
)) {
685 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
686 __func__
, __FILE__
, __LINE__
);
690 ctf_writer
= insert_new_writer(writer_component
, trace
);
699 struct bt_ctf_stream
*get_writer_stream(
700 struct writer_component
*writer_component
,
701 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
703 struct bt_ctf_stream_class
*stream_class
;
704 struct bt_ctf_writer
*ctf_writer
;
705 struct bt_ctf_stream
*writer_stream
;
707 stream_class
= bt_ctf_stream_get_class(stream
);
709 writer_stream
= NULL
;
710 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
711 __func__
, __FILE__
, __LINE__
);
715 ctf_writer
= get_writer(writer_component
, stream_class
);
717 writer_stream
= NULL
;
718 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
719 __func__
, __FILE__
, __LINE__
);
720 goto end_put_stream_class
;
723 writer_stream
= lookup_stream(writer_component
, stream
);
726 if (!bt_get(writer_stream
)) {
727 writer_stream
= NULL
;
728 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
729 __func__
, __FILE__
, __LINE__
);
730 goto end_put_stream_class
;
733 writer_stream
= insert_new_stream(writer_component
, ctf_writer
,
734 stream_class
, stream
);
738 end_put_stream_class
:
739 bt_put(stream_class
);
741 return writer_stream
;
745 enum bt_component_status
writer_new_packet(
746 struct writer_component
*writer_component
,
747 struct bt_ctf_packet
*packet
)
749 struct bt_ctf_stream
*stream
, *writer_stream
;
750 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
752 stream
= bt_ctf_packet_get_stream(packet
);
754 ret
= BT_COMPONENT_STATUS_ERROR
;
755 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
756 __func__
, __FILE__
, __LINE__
);
760 /* TODO: copy values for event discarded and packet_seq_num */
761 writer_stream
= get_writer_stream(writer_component
, packet
, stream
);
762 if (!writer_stream
) {
763 ret
= BT_COMPONENT_STATUS_ERROR
;
764 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
765 __func__
, __FILE__
, __LINE__
);
769 bt_put(writer_stream
);
778 enum bt_component_status
copy_packet_context_field(FILE *err
,
779 struct bt_ctf_field
*field
, const char *field_name
,
780 struct bt_ctf_field
*writer_packet_context
,
781 struct bt_ctf_field_type
*writer_packet_context_type
)
783 enum bt_component_status ret
;
784 struct bt_ctf_field
*writer_field
;
789 * TODO: handle the special case of the first/last packet that might
790 * be trimmed. In these cases, the timestamp_begin/end need to be
791 * explicitely set to the first/last event timestamps.
794 writer_field
= bt_ctf_field_structure_get_field(writer_packet_context
,
797 ret
= BT_COMPONENT_STATUS_ERROR
;
798 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
803 int_ret
= bt_ctf_field_unsigned_integer_get_value(field
, &value
);
805 fprintf(err
, "[error] Wrong packet_context field type\n");
806 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
808 ret
= BT_COMPONENT_STATUS_ERROR
;
809 goto end_put_writer_field
;
812 int_ret
= bt_ctf_field_unsigned_integer_set_value(writer_field
, value
);
814 ret
= BT_COMPONENT_STATUS_ERROR
;
815 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
817 goto end_put_writer_field
;
820 ret
= BT_COMPONENT_STATUS_OK
;
822 end_put_writer_field
:
823 bt_put(writer_field
);
829 enum bt_component_status
copy_packet_context(FILE *err
,
830 struct bt_ctf_packet
*packet
,
831 struct bt_ctf_stream
*writer_stream
)
833 enum bt_component_status ret
;
834 struct bt_ctf_field
*packet_context
, *writer_packet_context
;
835 struct bt_ctf_field_type
*struct_type
, *writer_packet_context_type
;
836 struct bt_ctf_stream_class
*writer_stream_class
;
837 int nr_fields
, i
, int_ret
;
839 packet_context
= bt_ctf_packet_get_context(packet
);
840 if (!packet_context
) {
841 ret
= BT_COMPONENT_STATUS_ERROR
;
842 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
847 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
848 if (!writer_stream_class
) {
849 ret
= BT_COMPONENT_STATUS_ERROR
;
850 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
852 goto end_put_packet_context
;
855 writer_packet_context_type
= bt_ctf_stream_class_get_packet_context_type(
856 writer_stream_class
);
857 if (!writer_packet_context_type
) {
858 ret
= BT_COMPONENT_STATUS_ERROR
;
859 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
861 goto end_put_writer_stream_class
;
864 struct_type
= bt_ctf_field_get_type(packet_context
);
866 ret
= BT_COMPONENT_STATUS_ERROR
;
867 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
869 goto end_put_writer_packet_context_type
;
872 writer_packet_context
= bt_ctf_field_create(writer_packet_context_type
);
873 if (!writer_packet_context
) {
874 ret
= BT_COMPONENT_STATUS_ERROR
;
875 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
877 goto end_put_struct_type
;
880 nr_fields
= bt_ctf_field_type_structure_get_field_count(struct_type
);
881 for (i
= 0; i
< nr_fields
; i
++) {
882 struct bt_ctf_field
*field
;
883 struct bt_ctf_field_type
*field_type
;
884 const char *field_name
;
886 field
= bt_ctf_field_structure_get_field_by_index(
889 ret
= BT_COMPONENT_STATUS_ERROR
;
890 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
892 goto end_put_writer_packet_context
;
894 if (bt_ctf_field_type_structure_get_field(struct_type
,
895 &field_name
, &field_type
, i
) < 0) {
896 ret
= BT_COMPONENT_STATUS_ERROR
;
898 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
900 goto end_put_writer_packet_context
;
903 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_TYPE_ID_INTEGER
) {
904 fprintf(err
, "[error] Unexpected packet context field type\n");
906 ret
= BT_COMPONENT_STATUS_ERROR
;
907 goto end_put_writer_packet_context
;
910 ret
= copy_packet_context_field(err
, field
, field_name
,
911 writer_packet_context
, writer_packet_context_type
);
914 if (ret
!= BT_COMPONENT_STATUS_OK
) {
915 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
917 goto end_put_writer_packet_context
;
921 int_ret
= bt_ctf_stream_set_packet_context(writer_stream
,
922 writer_packet_context
);
924 ret
= BT_COMPONENT_STATUS_ERROR
;
925 goto end_put_writer_packet_context
;
928 end_put_writer_packet_context
:
929 bt_put(writer_packet_context
);
932 end_put_writer_packet_context_type
:
933 bt_put(writer_packet_context_type
);
934 end_put_writer_stream_class
:
935 bt_put(writer_stream_class
);
936 end_put_packet_context
:
937 bt_put(packet_context
);
943 enum bt_component_status
writer_close_packet(
944 struct writer_component
*writer_component
,
945 struct bt_ctf_packet
*packet
)
947 struct bt_ctf_stream
*stream
, *writer_stream
;
948 enum bt_component_status ret
;
950 stream
= bt_ctf_packet_get_stream(packet
);
952 ret
= BT_COMPONENT_STATUS_ERROR
;
953 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
954 __func__
, __FILE__
, __LINE__
);
958 writer_stream
= lookup_stream(writer_component
, stream
);
959 if (!writer_stream
) {
960 ret
= BT_COMPONENT_STATUS_ERROR
;
961 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
962 __func__
, __FILE__
, __LINE__
);
966 if (!bt_get(writer_stream
)) {
967 fprintf(writer_component
->err
,
968 "[error] Failed to get reference on writer stream\n");
969 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
970 __func__
, __FILE__
, __LINE__
);
971 ret
= BT_COMPONENT_STATUS_ERROR
;
975 ret
= copy_packet_context(writer_component
->err
, packet
, writer_stream
);
976 if (ret
!= BT_COMPONENT_STATUS_OK
) {
977 ret
= BT_COMPONENT_STATUS_ERROR
;
978 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
979 __func__
, __FILE__
, __LINE__
);
983 ret
= bt_ctf_stream_flush(writer_stream
);
985 fprintf(writer_component
->err
,
986 "[error] Failed to flush packet\n");
987 ret
= BT_COMPONENT_STATUS_ERROR
;
990 ret
= BT_COMPONENT_STATUS_OK
;
992 bt_put(writer_stream
);
1001 struct bt_ctf_event
*copy_event(FILE *err
, struct bt_ctf_event
*event
,
1002 struct bt_ctf_event_class
*writer_event_class
)
1004 struct bt_ctf_event
*writer_event
;
1005 struct bt_ctf_field
*field
, *copy_field
;
1008 writer_event
= bt_ctf_event_create(writer_event_class
);
1009 if (!writer_event
) {
1010 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1015 field
= bt_ctf_event_get_header(event
);
1017 BT_PUT(writer_event
);
1018 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1019 __FILE__
, __LINE__
);
1022 copy_field
= bt_ctf_field_copy(field
);
1025 ret
= bt_ctf_event_set_header(writer_event
, copy_field
);
1027 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1028 __FILE__
, __LINE__
);
1034 /* Optional field, so it can fail silently. */
1035 field
= bt_ctf_event_get_stream_event_context(event
);
1036 copy_field
= bt_ctf_field_copy(field
);
1039 ret
= bt_ctf_event_set_stream_event_context(writer_event
,
1042 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1043 __FILE__
, __LINE__
);
1049 /* Optional field, so it can fail silently. */
1050 field
= bt_ctf_event_get_event_context(event
);
1051 copy_field
= bt_ctf_field_copy(field
);
1054 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1056 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1057 __FILE__
, __LINE__
);
1063 field
= bt_ctf_event_get_payload_field(event
);
1065 BT_PUT(writer_event
);
1066 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1067 __FILE__
, __LINE__
);
1070 copy_field
= bt_ctf_field_copy(field
);
1073 ret
= bt_ctf_event_set_payload_field(writer_event
, copy_field
);
1075 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1076 __FILE__
, __LINE__
);
1085 BT_PUT(writer_event
);
1087 return writer_event
;
1091 enum bt_component_status
writer_output_event(
1092 struct writer_component
*writer_component
,
1093 struct bt_ctf_event
*event
)
1095 enum bt_component_status ret
;
1096 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
1097 struct bt_ctf_stream
*stream
, *writer_stream
;
1098 struct bt_ctf_stream_class
*stream_class
, *writer_stream_class
;
1099 struct bt_ctf_event
*writer_event
;
1100 const char *event_name
;
1103 event_class
= bt_ctf_event_get_class(event
);
1105 ret
= BT_COMPONENT_STATUS_ERROR
;
1106 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1107 __FILE__
, __LINE__
);
1111 event_name
= bt_ctf_event_class_get_name(event_class
);
1113 ret
= BT_COMPONENT_STATUS_ERROR
;
1114 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1115 __FILE__
, __LINE__
);
1116 goto end_put_event_class
;
1119 stream
= bt_ctf_event_get_stream(event
);
1121 ret
= BT_COMPONENT_STATUS_ERROR
;
1122 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1123 __FILE__
, __LINE__
);
1124 goto end_put_event_class
;
1127 writer_stream
= lookup_stream(writer_component
, stream
);
1128 if (!writer_stream
|| !bt_get(writer_stream
)) {
1129 ret
= BT_COMPONENT_STATUS_ERROR
;
1130 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1131 __FILE__
, __LINE__
);
1132 goto end_put_stream
;
1135 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1136 if (!stream_class
) {
1137 ret
= BT_COMPONENT_STATUS_ERROR
;
1138 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1139 __FILE__
, __LINE__
);
1140 goto end_put_writer_stream
;
1143 writer_stream_class
= g_hash_table_lookup(
1144 writer_component
->stream_class_map
,
1145 (gpointer
) stream_class
);
1146 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1147 ret
= BT_COMPONENT_STATUS_ERROR
;
1148 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1149 __FILE__
, __LINE__
);
1150 goto end_put_stream_class
;
1153 writer_event_class
= get_event_class(writer_component
,
1154 writer_stream_class
, event_class
);
1155 if (!writer_event_class
) {
1156 ret
= BT_COMPONENT_STATUS_ERROR
;
1157 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1158 __FILE__
, __LINE__
);
1159 goto end_put_writer_stream_class
;
1162 writer_event
= copy_event(writer_component
->err
, event
, writer_event_class
);
1163 if (!writer_event
) {
1164 ret
= BT_COMPONENT_STATUS_ERROR
;
1165 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1166 __FILE__
, __LINE__
);
1167 fprintf(writer_component
->err
, "[error] Failed to copy event %s\n",
1168 bt_ctf_event_class_get_name(writer_event_class
));
1169 goto end_put_writer_event_class
;
1172 int_ret
= bt_ctf_stream_append_event(writer_stream
, writer_event
);
1174 ret
= BT_COMPONENT_STATUS_ERROR
;
1175 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1176 __FILE__
, __LINE__
);
1177 fprintf(writer_component
->err
, "[error] Failed to append event %s\n",
1178 bt_ctf_event_class_get_name(writer_event_class
));
1179 goto end_put_writer_event
;
1182 ret
= BT_COMPONENT_STATUS_OK
;
1184 end_put_writer_event
:
1185 bt_put(writer_event
);
1186 end_put_writer_event_class
:
1187 bt_put(writer_event_class
);
1188 end_put_writer_stream_class
:
1189 bt_put(writer_stream_class
);
1190 end_put_stream_class
:
1191 bt_put(stream_class
);
1192 end_put_writer_stream
:
1193 bt_put(writer_stream
);
1196 end_put_event_class
:
1197 bt_put(event_class
);