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 enum bt_component_status
copy_clock(FILE *err
, struct bt_ctf_writer
*writer
,
43 struct bt_ctf_stream_class
*writer_stream_class
,
44 struct bt_ctf_clock
*clock
)
46 int64_t offset
, offset_s
;
49 const char *name
, *description
;
50 struct bt_ctf_clock
*writer_clock
= NULL
;
51 enum bt_component_status ret
;
53 name
= bt_ctf_clock_get_name(clock
);
55 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
57 ret
= BT_COMPONENT_STATUS_ERROR
;
61 writer_clock
= bt_ctf_clock_create(name
);
63 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
65 ret
= BT_COMPONENT_STATUS_ERROR
;
69 description
= bt_ctf_clock_get_description(clock
);
71 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
73 ret
= BT_COMPONENT_STATUS_ERROR
;
77 int_ret
= bt_ctf_clock_set_description(writer_clock
,
80 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
82 ret
= BT_COMPONENT_STATUS_ERROR
;
86 u64_ret
= bt_ctf_clock_get_frequency(clock
);
87 if (u64_ret
== -1ULL) {
88 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
90 ret
= BT_COMPONENT_STATUS_ERROR
;
93 int_ret
= bt_ctf_clock_set_frequency(writer_clock
, u64_ret
);
95 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
97 ret
= BT_COMPONENT_STATUS_ERROR
;
101 u64_ret
= bt_ctf_clock_get_precision(clock
);
102 if (u64_ret
== -1ULL) {
103 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
105 ret
= BT_COMPONENT_STATUS_ERROR
;
108 int_ret
= bt_ctf_clock_set_precision(writer_clock
, u64_ret
);
110 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
112 ret
= BT_COMPONENT_STATUS_ERROR
;
116 int_ret
= bt_ctf_clock_get_offset_s(clock
, &offset_s
);
118 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
120 ret
= BT_COMPONENT_STATUS_ERROR
;
124 int_ret
= bt_ctf_clock_set_offset_s(writer_clock
, offset_s
);
126 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
128 ret
= BT_COMPONENT_STATUS_ERROR
;
132 int_ret
= bt_ctf_clock_get_offset(clock
, &offset
);
134 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
136 ret
= BT_COMPONENT_STATUS_ERROR
;
140 int_ret
= bt_ctf_clock_set_offset(writer_clock
, offset
);
142 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
144 ret
= BT_COMPONENT_STATUS_ERROR
;
148 int_ret
= bt_ctf_clock_get_is_absolute(clock
);
150 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
152 ret
= BT_COMPONENT_STATUS_ERROR
;
156 int_ret
= bt_ctf_clock_set_is_absolute(writer_clock
, int_ret
);
158 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
160 ret
= BT_COMPONENT_STATUS_ERROR
;
164 int_ret
= bt_ctf_writer_add_clock(writer
, writer_clock
);
166 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
168 ret
= BT_COMPONENT_STATUS_ERROR
;
173 * Ownership transferred to the writer and the stream_class.
175 bt_put(writer_clock
);
176 ret
= BT_COMPONENT_STATUS_OK
;
181 BT_PUT(writer_clock
);
187 struct bt_ctf_event_class
*copy_event_class(FILE *err
, struct bt_ctf_event_class
*event_class
)
189 struct bt_ctf_event_class
*writer_event_class
= NULL
;
191 struct bt_ctf_field_type
*context
;
194 name
= bt_ctf_event_class_get_name(event_class
);
196 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
201 writer_event_class
= bt_ctf_event_class_create(name
);
202 if (!writer_event_class
) {
203 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
208 count
= bt_ctf_event_class_get_attribute_count(event_class
);
209 for (i
= 0; i
< count
; i
++) {
210 const char *attr_name
;
211 struct bt_value
*attr_value
;
214 attr_name
= bt_ctf_event_class_get_attribute_name(event_class
, i
);
216 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
218 BT_PUT(writer_event_class
);
221 attr_value
= bt_ctf_event_class_get_attribute_value(event_class
, i
);
223 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
225 BT_PUT(writer_event_class
);
229 ret
= bt_ctf_event_class_set_attribute(writer_event_class
,
230 attr_name
, attr_value
);
232 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
234 BT_PUT(writer_event_class
);
239 context
= bt_ctf_event_class_get_context_type(event_class
);
240 ret
= bt_ctf_event_class_set_context_type(writer_event_class
, context
);
242 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
247 count
= bt_ctf_event_class_get_field_count(event_class
);
248 for (i
= 0; i
< count
; i
++) {
249 const char *field_name
;
250 struct bt_ctf_field_type
*field_type
;
253 ret
= bt_ctf_event_class_get_field(event_class
, &field_name
,
256 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
257 BT_PUT(writer_event_class
);
261 ret
= bt_ctf_event_class_add_field(writer_event_class
, field_type
,
264 fprintf(err
, "[error] Cannot add field %s\n", field_name
);
265 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
267 BT_PUT(writer_event_class
);
274 return writer_event_class
;
278 enum bt_component_status
copy_event_classes(FILE *err
,
279 struct bt_ctf_writer
*writer
,
280 struct bt_ctf_stream_class
*stream_class
,
281 struct bt_ctf_stream_class
*writer_stream_class
)
283 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
286 count
= bt_ctf_stream_class_get_event_class_count(stream_class
);
288 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
293 for (i
= 0; i
< count
; i
++) {
294 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
297 event_class
= bt_ctf_stream_class_get_event_class(
300 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
302 ret
= BT_COMPONENT_STATUS_ERROR
;
306 writer_event_class
= copy_event_class(err
, event_class
);
307 if (!writer_event_class
) {
308 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
310 ret
= BT_COMPONENT_STATUS_ERROR
;
314 int_ret
= bt_ctf_stream_class_add_event_class(writer_stream_class
,
317 fprintf(err
, "[error] Failed to add event class\n");
318 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
320 ret
= BT_COMPONENT_STATUS_ERROR
;
332 enum bt_component_status
copy_stream_class(FILE *err
,
333 struct bt_ctf_writer
*writer
,
334 struct bt_ctf_stream_class
*stream_class
,
335 struct bt_ctf_stream_class
*writer_stream_class
)
337 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
338 struct bt_ctf_field_type
*type
;
339 int ret_int
, clock_count
, i
;
340 struct bt_ctf_trace
*trace
;
342 trace
= bt_ctf_stream_class_get_trace(stream_class
);
344 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
346 ret
= BT_COMPONENT_STATUS_ERROR
;
350 clock_count
= bt_ctf_trace_get_clock_count(trace
);
352 for (i
= 0; i
< clock_count
; i
++) {
353 struct bt_ctf_clock
*clock
= bt_ctf_trace_get_clock(trace
, i
);
356 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
358 ret
= BT_COMPONENT_STATUS_ERROR
;
362 ret
= copy_clock(err
, writer
, writer_stream_class
, clock
);
364 if (ret
!= BT_COMPONENT_STATUS_OK
) {
365 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
371 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
373 ret
= BT_COMPONENT_STATUS_ERROR
;
374 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
379 ret_int
= bt_ctf_stream_class_set_packet_context_type(
380 writer_stream_class
, type
);
382 ret
= BT_COMPONENT_STATUS_ERROR
;
383 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
388 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
390 ret
= BT_COMPONENT_STATUS_ERROR
;
391 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
396 ret_int
= bt_ctf_stream_class_set_event_header_type(
397 writer_stream_class
, type
);
399 ret
= BT_COMPONENT_STATUS_ERROR
;
400 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
405 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
406 ret_int
= bt_ctf_stream_class_set_event_context_type(
407 writer_stream_class
, type
);
409 ret
= BT_COMPONENT_STATUS_ERROR
;
410 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
415 ret
= copy_event_classes(err
, writer
, stream_class
, writer_stream_class
);
416 if (ret
!= BT_COMPONENT_STATUS_OK
) {
417 fprintf(err
, "[error] Failed to copy event classes\n");
418 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
430 enum bt_component_status
copy_trace(FILE *err
, struct bt_ctf_writer
*ctf_writer
,
431 struct bt_ctf_trace
*trace
)
433 struct bt_ctf_trace
*writer_trace
;
434 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
435 int field_count
, i
, int_ret
;
436 struct bt_ctf_field_type
*header_type
;
438 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
440 ret
= BT_COMPONENT_STATUS_ERROR
;
441 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
446 field_count
= bt_ctf_trace_get_environment_field_count(trace
);
447 for (i
= 0; i
< field_count
; i
++) {
450 struct bt_value
*value
;
452 name
= bt_ctf_trace_get_environment_field_name(trace
, i
);
454 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
456 ret
= BT_COMPONENT_STATUS_ERROR
;
457 goto end_put_writer_trace
;
459 value
= bt_ctf_trace_get_environment_field_value(trace
, i
);
461 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
463 ret
= BT_COMPONENT_STATUS_ERROR
;
464 goto end_put_writer_trace
;
467 ret_int
= bt_ctf_trace_set_environment_field(writer_trace
,
470 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
472 fprintf(err
, "[error] Unable to set environment field %s\n",
474 ret
= BT_COMPONENT_STATUS_ERROR
;
475 goto end_put_writer_trace
;
479 header_type
= bt_ctf_trace_get_packet_header_type(writer_trace
);
481 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
482 ret
= BT_COMPONENT_STATUS_ERROR
;
483 goto end_put_writer_trace
;
486 int_ret
= bt_ctf_trace_set_packet_header_type(writer_trace
, header_type
);
488 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
489 ret
= BT_COMPONENT_STATUS_ERROR
;
490 goto end_put_header_type
;
495 end_put_writer_trace
:
496 bt_put(writer_trace
);
502 struct bt_ctf_stream_class
*insert_new_stream_class(
503 struct writer_component
*writer_component
,
504 struct bt_ctf_writer
*ctf_writer
,
505 struct bt_ctf_stream_class
*stream_class
)
507 struct bt_ctf_stream_class
*writer_stream_class
;
508 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
509 enum bt_component_status ret
;
511 if (strlen(name
) == 0) {
515 writer_stream_class
= bt_ctf_stream_class_create(name
);
516 if (!writer_stream_class
) {
517 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
518 __func__
, __FILE__
, __LINE__
);
522 ret
= copy_stream_class(writer_component
->err
,
523 ctf_writer
, stream_class
, writer_stream_class
);
524 if (ret
!= BT_COMPONENT_STATUS_OK
) {
525 fprintf(writer_component
->err
, "[error] Failed to copy stream class\n");
526 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
527 __func__
, __FILE__
, __LINE__
);
528 BT_PUT(writer_stream_class
);
531 g_hash_table_insert(writer_component
->stream_class_map
,
532 (gpointer
) stream_class
, writer_stream_class
);
535 return writer_stream_class
;
539 struct bt_ctf_stream
*insert_new_stream(
540 struct writer_component
*writer_component
,
541 struct bt_ctf_writer
*ctf_writer
,
542 struct bt_ctf_stream_class
*stream_class
,
543 struct bt_ctf_stream
*stream
)
545 struct bt_ctf_stream
*writer_stream
;
546 struct bt_ctf_stream_class
*writer_stream_class
;
548 writer_stream_class
= g_hash_table_lookup(
549 writer_component
->stream_class_map
,
550 (gpointer
) stream_class
);
551 if (writer_stream_class
) {
552 if (!bt_get(writer_stream_class
)) {
553 writer_stream
= NULL
;
554 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
555 __func__
, __FILE__
, __LINE__
);
559 writer_stream_class
= insert_new_stream_class(
560 writer_component
, ctf_writer
, stream_class
);
561 if (!writer_stream_class
) {
562 writer_stream
= NULL
;
563 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
564 __func__
, __FILE__
, __LINE__
);
569 writer_stream
= bt_ctf_writer_create_stream(ctf_writer
,
570 writer_stream_class
);
571 if (!writer_stream
) {
572 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
573 __func__
, __FILE__
, __LINE__
);
577 g_hash_table_insert(writer_component
->stream_map
, (gpointer
) stream
,
580 bt_ctf_writer_flush_metadata(ctf_writer
);
583 bt_put(writer_stream_class
);
585 return writer_stream
;
589 struct bt_ctf_stream
*lookup_stream(struct writer_component
*writer_component
,
590 struct bt_ctf_stream
*stream
)
592 return (struct bt_ctf_stream
*) g_hash_table_lookup(
593 writer_component
->stream_map
,
598 struct bt_ctf_event_class
*get_event_class(struct writer_component
*writer_component
,
599 struct bt_ctf_stream_class
*writer_stream_class
,
600 struct bt_ctf_event_class
*event_class
)
602 return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class
,
603 bt_ctf_event_class_get_name(event_class
));
606 struct bt_ctf_writer
*insert_new_writer(
607 struct writer_component
*writer_component
,
608 struct bt_ctf_trace
*trace
)
610 struct bt_ctf_writer
*ctf_writer
;
611 char trace_name
[PATH_MAX
];
612 enum bt_component_status ret
;
614 snprintf(trace_name
, PATH_MAX
, "%s/%s_%03d",
615 writer_component
->base_path
->str
,
616 writer_component
->trace_name_base
->str
,
617 writer_component
->trace_id
++);
618 printf_verbose("CTF-Writer creating trace in %s\n", trace_name
);
620 ctf_writer
= bt_ctf_writer_create(trace_name
);
622 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
623 __func__
, __FILE__
, __LINE__
);
627 ret
= copy_trace(writer_component
->err
, ctf_writer
, trace
);
628 if (ret
!= BT_COMPONENT_STATUS_OK
) {
629 fprintf(writer_component
->err
, "[error] Failed to copy trace\n");
630 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
631 __func__
, __FILE__
, __LINE__
);
636 g_hash_table_insert(writer_component
->trace_map
, (gpointer
) trace
,
644 struct bt_ctf_writer
*get_writer(struct writer_component
*writer_component
,
645 struct bt_ctf_stream_class
*stream_class
)
647 struct bt_ctf_trace
*trace
;
648 struct bt_ctf_writer
*ctf_writer
;
650 trace
= bt_ctf_stream_class_get_trace(stream_class
);
653 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
654 __func__
, __FILE__
, __LINE__
);
658 ctf_writer
= g_hash_table_lookup(writer_component
->trace_map
,
661 if (!bt_get(ctf_writer
)) {
663 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
664 __func__
, __FILE__
, __LINE__
);
668 ctf_writer
= insert_new_writer(writer_component
, trace
);
677 struct bt_ctf_stream
*get_writer_stream(
678 struct writer_component
*writer_component
,
679 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
681 struct bt_ctf_stream_class
*stream_class
;
682 struct bt_ctf_writer
*ctf_writer
;
683 struct bt_ctf_stream
*writer_stream
;
685 stream_class
= bt_ctf_stream_get_class(stream
);
687 writer_stream
= NULL
;
688 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
689 __func__
, __FILE__
, __LINE__
);
693 ctf_writer
= get_writer(writer_component
, stream_class
);
695 writer_stream
= NULL
;
696 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
697 __func__
, __FILE__
, __LINE__
);
698 goto end_put_stream_class
;
701 writer_stream
= lookup_stream(writer_component
, stream
);
704 if (!bt_get(writer_stream
)) {
705 writer_stream
= NULL
;
706 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
707 __func__
, __FILE__
, __LINE__
);
708 goto end_put_stream_class
;
711 writer_stream
= insert_new_stream(writer_component
, ctf_writer
,
712 stream_class
, stream
);
716 end_put_stream_class
:
717 bt_put(stream_class
);
719 return writer_stream
;
723 enum bt_component_status
writer_new_packet(
724 struct writer_component
*writer_component
,
725 struct bt_ctf_packet
*packet
)
727 struct bt_ctf_stream
*stream
, *writer_stream
;
728 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
730 stream
= bt_ctf_packet_get_stream(packet
);
732 ret
= BT_COMPONENT_STATUS_ERROR
;
733 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
734 __func__
, __FILE__
, __LINE__
);
738 /* TODO: copy values for event discarded and packet_seq_num */
739 writer_stream
= get_writer_stream(writer_component
, packet
, stream
);
740 if (!writer_stream
) {
741 ret
= BT_COMPONENT_STATUS_ERROR
;
742 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
743 __func__
, __FILE__
, __LINE__
);
747 bt_put(writer_stream
);
756 enum bt_component_status
copy_packet_context_field(FILE *err
,
757 struct bt_ctf_field
*field
, const char *field_name
,
758 struct bt_ctf_field
*writer_packet_context
,
759 struct bt_ctf_field_type
*writer_packet_context_type
)
761 enum bt_component_status ret
;
762 struct bt_ctf_field
*writer_field
;
767 * TODO: handle the special case of the first/last packet that might
768 * be trimmed. In these cases, the timestamp_begin/end need to be
769 * explicitely set to the first/last event timestamps.
772 writer_field
= bt_ctf_field_structure_get_field(writer_packet_context
,
775 ret
= BT_COMPONENT_STATUS_ERROR
;
776 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
781 int_ret
= bt_ctf_field_unsigned_integer_get_value(field
, &value
);
783 fprintf(err
, "[error] Wrong packet_context field type\n");
784 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
786 ret
= BT_COMPONENT_STATUS_ERROR
;
787 goto end_put_writer_field
;
790 int_ret
= bt_ctf_field_unsigned_integer_set_value(writer_field
, value
);
792 ret
= BT_COMPONENT_STATUS_ERROR
;
793 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
795 goto end_put_writer_field
;
798 ret
= BT_COMPONENT_STATUS_OK
;
800 end_put_writer_field
:
801 bt_put(writer_field
);
807 enum bt_component_status
copy_packet_context(FILE *err
,
808 struct bt_ctf_packet
*packet
,
809 struct bt_ctf_stream
*writer_stream
)
811 enum bt_component_status ret
;
812 struct bt_ctf_field
*packet_context
, *writer_packet_context
;
813 struct bt_ctf_field_type
*struct_type
, *writer_packet_context_type
;
814 struct bt_ctf_stream_class
*writer_stream_class
;
815 int nr_fields
, i
, int_ret
;
817 packet_context
= bt_ctf_packet_get_context(packet
);
818 if (!packet_context
) {
819 ret
= BT_COMPONENT_STATUS_ERROR
;
820 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
825 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
826 if (!writer_stream_class
) {
827 ret
= BT_COMPONENT_STATUS_ERROR
;
828 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
830 goto end_put_packet_context
;
833 writer_packet_context_type
= bt_ctf_stream_class_get_packet_context_type(
834 writer_stream_class
);
835 if (!writer_packet_context_type
) {
836 ret
= BT_COMPONENT_STATUS_ERROR
;
837 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
839 goto end_put_writer_stream_class
;
842 struct_type
= bt_ctf_field_get_type(packet_context
);
844 ret
= BT_COMPONENT_STATUS_ERROR
;
845 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
847 goto end_put_writer_packet_context_type
;
850 writer_packet_context
= bt_ctf_field_create(writer_packet_context_type
);
851 if (!writer_packet_context
) {
852 ret
= BT_COMPONENT_STATUS_ERROR
;
853 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
855 goto end_put_struct_type
;
858 nr_fields
= bt_ctf_field_type_structure_get_field_count(struct_type
);
859 for (i
= 0; i
< nr_fields
; i
++) {
860 struct bt_ctf_field
*field
;
861 struct bt_ctf_field_type
*field_type
;
862 const char *field_name
;
864 field
= bt_ctf_field_structure_get_field_by_index(
867 ret
= BT_COMPONENT_STATUS_ERROR
;
868 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
870 goto end_put_writer_packet_context
;
872 if (bt_ctf_field_type_structure_get_field(struct_type
,
873 &field_name
, &field_type
, i
) < 0) {
874 ret
= BT_COMPONENT_STATUS_ERROR
;
876 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
878 goto end_put_writer_packet_context
;
881 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_TYPE_ID_INTEGER
) {
882 fprintf(err
, "[error] Unexpected packet context field type\n");
884 ret
= BT_COMPONENT_STATUS_ERROR
;
885 goto end_put_writer_packet_context
;
888 ret
= copy_packet_context_field(err
, field
, field_name
,
889 writer_packet_context
, writer_packet_context_type
);
892 if (ret
!= BT_COMPONENT_STATUS_OK
) {
893 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
895 goto end_put_writer_packet_context
;
899 int_ret
= bt_ctf_stream_set_packet_context(writer_stream
,
900 writer_packet_context
);
902 ret
= BT_COMPONENT_STATUS_ERROR
;
903 goto end_put_writer_packet_context
;
906 end_put_writer_packet_context
:
907 bt_put(writer_packet_context
);
910 end_put_writer_packet_context_type
:
911 bt_put(writer_packet_context_type
);
912 end_put_writer_stream_class
:
913 bt_put(writer_stream_class
);
914 end_put_packet_context
:
915 bt_put(packet_context
);
921 enum bt_component_status
writer_close_packet(
922 struct writer_component
*writer_component
,
923 struct bt_ctf_packet
*packet
)
925 struct bt_ctf_stream
*stream
, *writer_stream
;
926 enum bt_component_status ret
;
928 stream
= bt_ctf_packet_get_stream(packet
);
930 ret
= BT_COMPONENT_STATUS_ERROR
;
931 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
932 __func__
, __FILE__
, __LINE__
);
936 writer_stream
= lookup_stream(writer_component
, stream
);
937 if (!writer_stream
) {
938 ret
= BT_COMPONENT_STATUS_ERROR
;
939 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
940 __func__
, __FILE__
, __LINE__
);
944 if (!bt_get(writer_stream
)) {
945 fprintf(writer_component
->err
,
946 "[error] Failed to get reference on writer stream\n");
947 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
948 __func__
, __FILE__
, __LINE__
);
949 ret
= BT_COMPONENT_STATUS_ERROR
;
953 ret
= copy_packet_context(writer_component
->err
, packet
, writer_stream
);
954 if (ret
!= BT_COMPONENT_STATUS_OK
) {
955 ret
= BT_COMPONENT_STATUS_ERROR
;
956 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
957 __func__
, __FILE__
, __LINE__
);
961 ret
= bt_ctf_stream_flush(writer_stream
);
963 fprintf(writer_component
->err
,
964 "[error] Failed to flush packet\n");
965 ret
= BT_COMPONENT_STATUS_ERROR
;
968 ret
= BT_COMPONENT_STATUS_OK
;
970 bt_put(writer_stream
);
979 struct bt_ctf_event
*copy_event(FILE *err
, struct bt_ctf_event
*event
,
980 struct bt_ctf_event_class
*writer_event_class
)
982 struct bt_ctf_event
*writer_event
;
983 struct bt_ctf_field
*field
;
986 writer_event
= bt_ctf_event_create(writer_event_class
);
988 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
992 field
= bt_ctf_event_get_header(event
);
993 ret
= bt_ctf_event_set_header(writer_event
,
994 bt_ctf_field_copy(field
));
996 BT_PUT(writer_event
);
997 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1001 field
= bt_ctf_event_get_stream_event_context(event
);
1002 ret
= bt_ctf_event_set_stream_event_context(writer_event
,
1003 bt_ctf_field_copy(field
));
1005 BT_PUT(writer_event
);
1006 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1010 field
= bt_ctf_event_get_event_context(event
);
1011 ret
= bt_ctf_event_set_event_context(writer_event
,
1012 bt_ctf_field_copy(field
));
1014 BT_PUT(writer_event
);
1015 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1019 field
= bt_ctf_event_get_payload_field(event
);
1020 ret
= bt_ctf_event_set_payload_field(writer_event
,
1021 bt_ctf_field_copy(field
));
1023 BT_PUT(writer_event
);
1024 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1029 return writer_event
;
1033 enum bt_component_status
writer_output_event(
1034 struct writer_component
*writer_component
,
1035 struct bt_ctf_event
*event
)
1037 enum bt_component_status ret
;
1038 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
1039 struct bt_ctf_stream
*stream
, *writer_stream
;
1040 struct bt_ctf_stream_class
*stream_class
, *writer_stream_class
;
1041 struct bt_ctf_event
*writer_event
;
1042 const char *event_name
;
1045 event_class
= bt_ctf_event_get_class(event
);
1047 ret
= BT_COMPONENT_STATUS_ERROR
;
1048 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1049 __FILE__
, __LINE__
);
1053 event_name
= bt_ctf_event_class_get_name(event_class
);
1055 ret
= BT_COMPONENT_STATUS_ERROR
;
1056 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1057 __FILE__
, __LINE__
);
1058 goto end_put_event_class
;
1061 stream
= bt_ctf_event_get_stream(event
);
1063 ret
= BT_COMPONENT_STATUS_ERROR
;
1064 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1065 __FILE__
, __LINE__
);
1066 goto end_put_event_class
;
1069 writer_stream
= lookup_stream(writer_component
, stream
);
1070 if (!writer_stream
|| !bt_get(writer_stream
)) {
1071 ret
= BT_COMPONENT_STATUS_ERROR
;
1072 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1073 __FILE__
, __LINE__
);
1074 goto end_put_stream
;
1077 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1078 if (!stream_class
) {
1079 ret
= BT_COMPONENT_STATUS_ERROR
;
1080 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1081 __FILE__
, __LINE__
);
1082 goto end_put_writer_stream
;
1085 writer_stream_class
= g_hash_table_lookup(
1086 writer_component
->stream_class_map
,
1087 (gpointer
) stream_class
);
1088 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1089 ret
= BT_COMPONENT_STATUS_ERROR
;
1090 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1091 __FILE__
, __LINE__
);
1092 goto end_put_stream_class
;
1095 writer_event_class
= get_event_class(writer_component
,
1096 writer_stream_class
, event_class
);
1097 if (!writer_event_class
) {
1098 ret
= BT_COMPONENT_STATUS_ERROR
;
1099 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1100 __FILE__
, __LINE__
);
1101 goto end_put_writer_stream_class
;
1104 writer_event
= copy_event(writer_component
->err
, event
, writer_event_class
);
1105 if (!writer_event
) {
1106 ret
= BT_COMPONENT_STATUS_ERROR
;
1107 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1108 __FILE__
, __LINE__
);
1109 fprintf(writer_component
->err
, "[error] Failed to copy event %s\n",
1110 bt_ctf_event_class_get_name(writer_event_class
));
1111 goto end_put_writer_event_class
;
1114 int_ret
= bt_ctf_stream_append_event(writer_stream
, writer_event
);
1116 ret
= BT_COMPONENT_STATUS_ERROR
;
1117 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
1118 __FILE__
, __LINE__
);
1119 fprintf(writer_component
->err
, "[error] Failed to append event %s\n",
1120 bt_ctf_event_class_get_name(writer_event_class
));
1121 goto end_put_writer_event
;
1124 ret
= BT_COMPONENT_STATUS_OK
;
1126 end_put_writer_event
:
1127 bt_put(writer_event
);
1128 end_put_writer_event_class
:
1129 bt_put(writer_event_class
);
1130 end_put_writer_stream_class
:
1131 bt_put(writer_stream_class
);
1132 end_put_stream_class
:
1133 bt_put(stream_class
);
1134 end_put_writer_stream
:
1135 bt_put(writer_stream
);
1138 end_put_event_class
:
1139 bt_put(event_class
);