lib: make trace IR API const-correct
[babeltrace.git] / plugins / libctfcopytrace / ctfcopytrace.c
1 /*
2 * copytrace.c
3 *
4 * Babeltrace library to create a copy of a CTF trace
5 *
6 * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
7 *
8 * Author: Julien Desfossez <jdesfossez@efficios.com>
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
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
26 * SOFTWARE.
27 */
28
29 #define BT_LOG_TAG "PLUGIN-CTFCOPYTRACE-LIB"
30 #include "logging.h"
31
32 #include <babeltrace/babeltrace.h>
33 #include <babeltrace/assert-internal.h>
34
35 #include "ctfcopytrace.h"
36 #include "clock-fields.h"
37
38 BT_HIDDEN
39 const struct bt_clock_class *ctf_copy_clock_class(FILE *err,
40 const struct bt_clock_class *clock_class)
41 {
42 int64_t offset, offset_s;
43 int int_ret;
44 uint64_t u64_ret;
45 const char *name, *description;
46 const struct bt_clock_class *writer_clock_class = NULL;
47
48 BT_ASSERT(err && clock_class);
49
50 name = bt_clock_class_get_name(clock_class);
51 BT_ASSERT(name);
52
53 writer_clock_class = bt_clock_class_create(name,
54 bt_clock_class_get_frequency(clock_class));
55 if (!writer_clock_class) {
56 BT_LOGE_STR("Failed to create clock class.");
57 goto end;
58 }
59
60 description = bt_clock_class_get_description(clock_class);
61 if (description) {
62 int_ret = bt_clock_class_set_description(writer_clock_class,
63 description);
64 BT_ASSERT(!int_ret);
65 }
66
67 u64_ret = bt_clock_class_get_precision(clock_class);
68 BT_ASSERT(u64_ret != -1ULL);
69
70 int_ret = bt_clock_class_set_precision(writer_clock_class,
71 u64_ret);
72 BT_ASSERT(!int_ret);
73
74 int_ret = bt_clock_class_get_offset_s(clock_class, &offset_s);
75 BT_ASSERT(!int_ret);
76
77 int_ret = bt_clock_class_set_offset_s(writer_clock_class, offset_s);
78 BT_ASSERT(!int_ret);
79
80 int_ret = bt_clock_class_get_offset_cycles(clock_class, &offset);
81 BT_ASSERT(!int_ret);
82
83 int_ret = bt_clock_class_set_offset_cycles(writer_clock_class, offset);
84 BT_ASSERT(!int_ret);
85
86 int_ret = bt_clock_class_is_absolute(clock_class);
87 BT_ASSERT(int_ret >= 0);
88
89 int_ret = bt_clock_class_set_is_absolute(writer_clock_class, int_ret);
90 BT_ASSERT(!int_ret);
91
92 end:
93 return writer_clock_class;
94 }
95
96 BT_HIDDEN
97 enum bt_component_status ctf_copy_clock_classes(FILE *err,
98 const struct bt_trace *writer_trace,
99 const struct bt_stream_class *writer_stream_class,
100 const struct bt_trace *trace)
101 {
102 enum bt_component_status ret;
103 int int_ret, clock_class_count, i;
104
105 clock_class_count = bt_trace_get_clock_class_count(trace);
106
107 for (i = 0; i < clock_class_count; i++) {
108 const struct bt_clock_class *writer_clock_class;
109 const struct bt_clock_class *clock_class =
110 bt_trace_get_clock_class_by_index(trace, i);
111
112 BT_ASSERT(clock_class);
113
114 writer_clock_class = ctf_copy_clock_class(err, clock_class);
115 bt_object_put_ref(clock_class);
116 if (!writer_clock_class) {
117 BT_LOGE_STR("Failed to copy clock class.");
118 ret = BT_COMPONENT_STATUS_ERROR;
119 goto end;
120 }
121
122 int_ret = bt_trace_add_clock_class(writer_trace, writer_clock_class);
123 if (int_ret != 0) {
124 BT_OBJECT_PUT_REF_AND_RESET(writer_clock_class);
125 BT_LOGE_STR("Failed to add clock class.");
126 ret = BT_COMPONENT_STATUS_ERROR;
127 goto end;
128 }
129
130 /*
131 * Ownership transferred to the trace.
132 */
133 bt_object_put_ref(writer_clock_class);
134 }
135
136 ret = BT_COMPONENT_STATUS_OK;
137
138 end:
139 return ret;
140 }
141
142 static
143 void replace_clock_classes(const struct bt_trace *trace_copy,
144 struct bt_field_type *field_type)
145 {
146 int ret;
147
148 BT_ASSERT(trace_copy);
149 BT_ASSERT(field_type);
150
151 switch (bt_field_type_get_type_id(field_type)) {
152 case BT_FIELD_TYPE_ID_INTEGER:
153 {
154 const struct bt_clock_class *mapped_clock_class =
155 bt_field_type_integer_get_mapped_clock_class(field_type);
156 const struct bt_clock_class *clock_class_copy = NULL;
157 const char *name;
158
159 if (!mapped_clock_class) {
160 break;
161 }
162
163 name = bt_clock_class_get_name(mapped_clock_class);
164 BT_ASSERT(name);
165 clock_class_copy = bt_trace_get_clock_class_by_name(
166 trace_copy, name);
167 BT_ASSERT(clock_class_copy);
168 ret = bt_field_type_integer_set_mapped_clock_class(
169 field_type, clock_class_copy);
170 BT_ASSERT(ret == 0);
171 bt_object_put_ref(mapped_clock_class);
172 bt_object_put_ref(clock_class_copy);
173 break;
174 }
175 case BT_FIELD_TYPE_ID_ENUM:
176 case BT_FIELD_TYPE_ID_ARRAY:
177 case BT_FIELD_TYPE_ID_SEQUENCE:
178 {
179 struct bt_field_type *subtype = NULL;
180
181 switch (bt_field_type_get_type_id(field_type)) {
182 case BT_FIELD_TYPE_ID_ENUM:
183 subtype = bt_field_type_enumeration_get_container_type(
184 field_type);
185 break;
186 case BT_FIELD_TYPE_ID_ARRAY:
187 subtype = bt_field_type_array_get_element_type(
188 field_type);
189 break;
190 case BT_FIELD_TYPE_ID_SEQUENCE:
191 subtype = bt_field_type_sequence_get_element_type(
192 field_type);
193 break;
194 default:
195 BT_LOGF("Unexpected field type ID: id=%d",
196 bt_field_type_get_type_id(field_type));
197 abort();
198 }
199
200 BT_ASSERT(subtype);
201 replace_clock_classes(trace_copy, subtype);
202 bt_object_put_ref(subtype);
203 break;
204 }
205 case BT_FIELD_TYPE_ID_STRUCT:
206 {
207 uint64_t i;
208 int64_t count = bt_field_type_structure_get_field_count(
209 field_type);
210
211 for (i = 0; i < count; i++) {
212 const char *name;
213 struct bt_field_type *member_type;
214
215 ret = bt_field_type_structure_get_field_by_index(
216 field_type, &name, &member_type, i);
217 BT_ASSERT(ret == 0);
218 replace_clock_classes(trace_copy, member_type);
219 bt_object_put_ref(member_type);
220 }
221
222 break;
223 }
224 case BT_FIELD_TYPE_ID_VARIANT:
225 {
226 uint64_t i;
227 int64_t count = bt_field_type_variant_get_field_count(
228 field_type);
229
230 for (i = 0; i < count; i++) {
231 const char *name;
232 struct bt_field_type *member_type;
233
234 ret = bt_field_type_variant_get_field_by_index(
235 field_type, &name, &member_type, i);
236 BT_ASSERT(ret == 0);
237 replace_clock_classes(trace_copy, member_type);
238 bt_object_put_ref(member_type);
239 }
240
241 break;
242 }
243 default:
244 break;
245 }
246 }
247
248 BT_HIDDEN
249 const struct bt_event_class *ctf_copy_event_class(FILE *err,
250 const struct bt_trace *trace_copy,
251 const struct bt_event_class *event_class)
252 {
253 const struct bt_event_class *writer_event_class = NULL;
254 struct bt_field_type *context = NULL, *payload_type = NULL;
255 const char *name;
256 int ret;
257 int64_t id;
258 enum bt_event_class_log_level log_level;
259 const char *emf_uri;
260
261 name = bt_event_class_get_name(event_class);
262
263 writer_event_class = bt_event_class_create(name);
264 BT_ASSERT(writer_event_class);
265
266 id = bt_event_class_get_id(event_class);
267 BT_ASSERT(id >= 0);
268
269 ret = bt_event_class_set_id(writer_event_class, id);
270 if (ret) {
271 BT_LOGE_STR("Failed to set event_class id.");
272 goto error;
273 }
274
275 log_level = bt_event_class_get_log_level(event_class);
276 if (log_level < 0) {
277 BT_LOGE_STR("Failed to get log_level.");
278 goto error;
279 }
280
281 ret = bt_event_class_set_log_level(writer_event_class, log_level);
282 if (ret) {
283 BT_LOGE_STR("Failed to set log_level.");
284 goto error;
285 }
286
287 emf_uri = bt_event_class_get_emf_uri(event_class);
288 if (emf_uri) {
289 ret = bt_event_class_set_emf_uri(writer_event_class,
290 emf_uri);
291 if (ret) {
292 BT_LOGE_STR("Failed to set emf uri.");
293 goto error;
294 }
295 }
296
297 payload_type = bt_event_class_get_payload_type(event_class);
298 if (payload_type) {
299 struct bt_field_type *ft_copy =
300 bt_field_type_copy(payload_type);
301
302 if (!ft_copy) {
303 BT_LOGE_STR("Cannot copy payload field type.");
304 }
305
306 replace_clock_classes(trace_copy, ft_copy);
307 ret = bt_event_class_set_payload_type(writer_event_class,
308 ft_copy);
309 bt_object_put_ref(ft_copy);
310 if (ret < 0) {
311 BT_LOGE_STR("Failed to set payload type.");
312 goto error;
313 }
314 }
315
316 context = bt_event_class_get_context_type(event_class);
317 if (context) {
318 struct bt_field_type *ft_copy =
319 bt_field_type_copy(context);
320
321 if (!ft_copy) {
322 BT_LOGE_STR("Cannot copy context field type.");
323 }
324
325 ret = bt_event_class_set_context_type(
326 writer_event_class, ft_copy);
327 bt_object_put_ref(ft_copy);
328 if (ret < 0) {
329 BT_LOGE_STR("Failed to set context type.");
330 goto error;
331 }
332 }
333
334 goto end;
335
336 error:
337 BT_OBJECT_PUT_REF_AND_RESET(writer_event_class);
338 end:
339 BT_OBJECT_PUT_REF_AND_RESET(context);
340 BT_OBJECT_PUT_REF_AND_RESET(payload_type);
341 return writer_event_class;
342 }
343
344 BT_HIDDEN
345 enum bt_component_status ctf_copy_event_classes(FILE *err,
346 const struct bt_stream_class *stream_class,
347 const struct bt_stream_class *writer_stream_class)
348 {
349 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
350 const struct bt_event_class *event_class = NULL, *writer_event_class = NULL;
351 int count, i;
352 const struct bt_trace *writer_trace =
353 bt_stream_class_get_trace(writer_stream_class);
354
355 BT_ASSERT(writer_trace);
356 count = bt_stream_class_get_event_class_count(stream_class);
357 BT_ASSERT(count >= 0);
358
359 for (i = 0; i < count; i++) {
360 int int_ret;
361
362 event_class = bt_stream_class_get_event_class_by_index(
363 stream_class, i);
364 BT_ASSERT(event_class);
365
366 if (i < bt_stream_class_get_event_class_count(writer_stream_class)) {
367 writer_event_class = bt_stream_class_get_event_class_by_index(
368 writer_stream_class, i);
369 if (writer_event_class) {
370 /*
371 * If the writer_event_class already exists,
372 * just skip it. It can be used to resync the
373 * event_classes after a trace has become
374 * static.
375 */
376 BT_OBJECT_PUT_REF_AND_RESET(writer_event_class);
377 BT_OBJECT_PUT_REF_AND_RESET(event_class);
378 continue;
379 }
380 }
381
382 writer_event_class = ctf_copy_event_class(err, writer_trace,
383 event_class);
384 if (!writer_event_class) {
385 BT_LOGE_STR("Failed to copy event_class.");
386 ret = BT_COMPONENT_STATUS_ERROR;
387 goto error;
388 }
389
390 int_ret = bt_stream_class_add_event_class(writer_stream_class,
391 writer_event_class);
392 if (int_ret < 0) {
393 BT_LOGE_STR("Failed to add event class.");
394 ret = BT_COMPONENT_STATUS_ERROR;
395 goto error;
396 }
397 BT_OBJECT_PUT_REF_AND_RESET(writer_event_class);
398 BT_OBJECT_PUT_REF_AND_RESET(event_class);
399 }
400
401 goto end;
402
403 error:
404 bt_object_put_ref(event_class);
405 bt_object_put_ref(writer_event_class);
406 end:
407 bt_object_put_ref(writer_trace);
408 return ret;
409 }
410
411 BT_HIDDEN
412 const struct bt_stream_class *ctf_copy_stream_class(FILE *err,
413 const struct bt_stream_class *stream_class,
414 const struct bt_trace *writer_trace,
415 bool override_ts64)
416 {
417 struct bt_field_type *type = NULL;
418 struct bt_field_type *type_copy = NULL;
419 const struct bt_stream_class *writer_stream_class = NULL;
420 int ret_int;
421 const char *name = bt_stream_class_get_name(stream_class);
422
423 writer_stream_class = bt_stream_class_create_empty(name);
424 BT_ASSERT(writer_stream_class);
425
426 type = bt_stream_class_get_packet_context_type(stream_class);
427 if (type) {
428 type_copy = bt_field_type_copy(type);
429 if (!type_copy) {
430 BT_LOGE_STR("Cannot copy packet context field type.");
431 }
432
433 replace_clock_classes(writer_trace, type_copy);
434 ret_int = bt_stream_class_set_packet_context_type(
435 writer_stream_class, type_copy);
436 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
437 if (ret_int < 0) {
438 BT_LOGE_STR("Failed to set packet_context type.");
439 goto error;
440 }
441 BT_OBJECT_PUT_REF_AND_RESET(type);
442 }
443
444 type = bt_stream_class_get_event_header_type(stream_class);
445 if (type) {
446 type_copy = bt_field_type_copy(type);
447 if (!type_copy) {
448 BT_LOGE_STR("Cannot copy event header field type.");
449 }
450
451 ret_int = bt_trace_get_clock_class_count(writer_trace);
452 BT_ASSERT(ret_int >= 0);
453 if (override_ts64 && ret_int > 0) {
454 struct bt_field_type *new_event_header_type;
455
456 new_event_header_type = override_header_type(err, type_copy,
457 writer_trace);
458 if (!new_event_header_type) {
459 BT_LOGE_STR("Failed to override header type.");
460 goto error;
461 }
462 replace_clock_classes(writer_trace, type_copy);
463 ret_int = bt_stream_class_set_event_header_type(
464 writer_stream_class, new_event_header_type);
465 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
466 BT_OBJECT_PUT_REF_AND_RESET(new_event_header_type);
467 if (ret_int < 0) {
468 BT_LOGE_STR("Failed to set event_header type.");
469 goto error;
470 }
471 } else {
472 replace_clock_classes(writer_trace, type_copy);
473 ret_int = bt_stream_class_set_event_header_type(
474 writer_stream_class, type_copy);
475 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
476 if (ret_int < 0) {
477 BT_LOGE_STR("Failed to set event_header type.");
478 goto error;
479 }
480 }
481 BT_OBJECT_PUT_REF_AND_RESET(type);
482 }
483
484 type = bt_stream_class_get_event_context_type(stream_class);
485 if (type) {
486 type_copy = bt_field_type_copy(type);
487 if (!type_copy) {
488 BT_LOGE_STR("Cannot copy event context field type.");
489 }
490
491 replace_clock_classes(writer_trace, type_copy);
492 ret_int = bt_stream_class_set_event_context_type(
493 writer_stream_class, type_copy);
494 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
495 if (ret_int < 0) {
496 BT_LOGE_STR("Failed to set event_contexttype.");
497 goto error;
498 }
499 }
500 BT_OBJECT_PUT_REF_AND_RESET(type);
501
502 goto end;
503
504 error:
505 BT_OBJECT_PUT_REF_AND_RESET(writer_stream_class);
506 end:
507 bt_object_put_ref(type);
508 bt_object_put_ref(type_copy);
509 return writer_stream_class;
510 }
511
512 BT_HIDDEN
513 int ctf_stream_copy_packet_header(FILE *err, const struct bt_packet *packet,
514 const struct bt_stream *writer_stream)
515 {
516 const struct bt_field *packet_header = NULL, *writer_packet_header = NULL;
517 int ret = 0;
518
519 packet_header = bt_packet_get_header(packet);
520 if (!packet_header) {
521 goto end;
522 }
523
524 writer_packet_header = bt_field_copy(packet_header);
525 if (!writer_packet_header) {
526 BT_LOGE_STR("Failed to copy field from stream packet header.");
527 goto error;
528 }
529
530 ret = bt_stream_set_packet_header(writer_stream,
531 writer_packet_header);
532 if (ret) {
533 BT_LOGE_STR("Failed to set stream packet header.");
534 goto error;
535 }
536
537 goto end;
538
539 error:
540 ret = -1;
541 end:
542 bt_object_put_ref(writer_packet_header);
543 bt_object_put_ref(packet_header);
544 return ret;
545 }
546
547 BT_HIDDEN
548 int ctf_packet_copy_header(FILE *err, const struct bt_packet *packet,
549 const struct bt_packet *writer_packet)
550 {
551 const struct bt_field *packet_header = NULL, *writer_packet_header = NULL;
552 int ret = 0;
553
554 packet_header = bt_packet_get_header(packet);
555 if (!packet_header) {
556 goto end;
557 }
558
559 writer_packet_header = bt_field_copy(packet_header);
560 if (!writer_packet_header) {
561 BT_LOGE_STR("Failed to copy field from packet header.");
562 goto error;
563 }
564
565 ret = bt_packet_set_header(writer_packet, writer_packet_header);
566 if (ret) {
567 BT_LOGE_STR("Failed to set packet header.");
568 goto error;
569 }
570
571 goto end;
572
573 error:
574 ret = -1;
575 end:
576 bt_object_put_ref(packet_header);
577 bt_object_put_ref(writer_packet_header);
578 return ret;
579 }
580
581 BT_HIDDEN
582 int ctf_stream_copy_packet_context(FILE *err, const struct bt_packet *packet,
583 const struct bt_stream *writer_stream)
584 {
585 const struct bt_field *packet_context = NULL, *writer_packet_context = NULL;
586 int ret = 0;
587
588 packet_context = bt_packet_get_context(packet);
589 if (!packet_context) {
590 goto end;
591 }
592
593 writer_packet_context = bt_field_copy(packet_context);
594 if (!writer_packet_context) {
595 BT_LOGE_STR("Failed to copy field from stream packet context.");
596 goto error;
597 }
598
599 ret = bt_stream_set_packet_context(writer_stream,
600 writer_packet_context);
601 if (ret) {
602 BT_LOGE_STR("Failed to set stream packet context.");
603 goto error;
604 }
605
606 goto end;
607
608 error:
609 ret = -1;
610 end:
611 bt_object_put_ref(packet_context);
612 bt_object_put_ref(writer_packet_context);
613 return ret;
614 }
615
616 BT_HIDDEN
617 int ctf_packet_copy_context(FILE *err, const struct bt_packet *packet,
618 const struct bt_stream *writer_stream,
619 const struct bt_packet *writer_packet)
620 {
621 const struct bt_field *packet_context = NULL, *writer_packet_context = NULL;
622 int ret = 0;
623
624 packet_context = bt_packet_get_context(packet);
625 if (!packet_context) {
626 goto end;
627 }
628
629 writer_packet_context = bt_field_copy(packet_context);
630 if (!writer_packet_context) {
631 BT_LOGE_STR("Failed to copy field from packet context.");
632 goto error;
633 }
634
635 ret = bt_packet_set_context(writer_packet, writer_packet_context);
636 if (ret) {
637 BT_LOGE_STR("Failed to set packet context.");
638 goto error;
639 }
640
641 goto end;
642
643 error:
644 ret = -1;
645 end:
646 bt_object_put_ref(writer_packet_context);
647 bt_object_put_ref(packet_context);
648 return ret;
649 }
650
651 BT_HIDDEN
652 int ctf_copy_event_header(FILE *err, const struct bt_event *event,
653 const struct bt_event_class *writer_event_class,
654 const struct bt_event *writer_event,
655 const struct bt_field *event_header)
656 {
657 const struct bt_clock_class *clock_class = NULL, *writer_clock_class = NULL;
658 struct bt_clock_value *clock_value = NULL, *writer_clock_value = NULL;
659
660 int ret;
661 const struct bt_field *writer_event_header = NULL;
662 uint64_t value;
663
664 clock_class = event_get_clock_class(err, event);
665 if (!clock_class) {
666 BT_LOGE_STR("Failed to get event clock_class.");
667 goto error;
668 }
669
670 clock_value = bt_event_get_clock_value(event, clock_class);
671 BT_OBJECT_PUT_REF_AND_RESET(clock_class);
672 BT_ASSERT(clock_value);
673
674 ret = bt_clock_value_get_value(clock_value, &value);
675 BT_OBJECT_PUT_REF_AND_RESET(clock_value);
676 if (ret) {
677 BT_LOGE_STR("Failed to get clock value.");
678 goto error;
679 }
680
681 writer_clock_class = event_get_clock_class(err, writer_event);
682 if (!writer_clock_class) {
683 BT_LOGE_STR("Failed to get event clock_class.");
684 goto error;
685 }
686
687 writer_clock_value = bt_clock_value_create(writer_clock_class, value);
688 BT_OBJECT_PUT_REF_AND_RESET(writer_clock_class);
689 if (!writer_clock_value) {
690 BT_LOGE_STR("Failed to create clock value.");
691 goto error;
692 }
693
694 ret = bt_event_set_clock_value(writer_event, writer_clock_value);
695 BT_OBJECT_PUT_REF_AND_RESET(writer_clock_value);
696 if (ret) {
697 BT_LOGE_STR("Failed to set clock value.");
698 goto error;
699 }
700
701 writer_event_header = bt_field_copy(event_header);
702 if (!writer_event_header) {
703 BT_LOGE_STR("Failed to copy event_header.");
704 goto end;
705 }
706
707 ret = bt_event_set_header(writer_event, writer_event_header);
708 BT_OBJECT_PUT_REF_AND_RESET(writer_event_header);
709 if (ret < 0) {
710 BT_LOGE_STR("Failed to set event_header.");
711 goto error;
712 }
713
714 ret = 0;
715
716 goto end;
717
718 error:
719 ret = -1;
720 end:
721 return ret;
722 }
723
724 static
725 const struct bt_trace *event_class_get_trace(FILE *err,
726 const struct bt_event_class *event_class)
727 {
728 const struct bt_trace *trace = NULL;
729 const struct bt_stream_class *stream_class = NULL;
730
731 stream_class = bt_event_class_get_stream_class(event_class);
732 BT_ASSERT(stream_class);
733
734 trace = bt_stream_class_get_trace(stream_class);
735 BT_ASSERT(trace);
736
737 bt_object_put_ref(stream_class);
738 return trace;
739 }
740
741 BT_HIDDEN
742 const struct bt_event *ctf_copy_event(FILE *err, const struct bt_event *event,
743 const struct bt_event_class *writer_event_class,
744 bool override_ts64)
745 {
746 const struct bt_event *writer_event = NULL;
747 const struct bt_field *field = NULL, *copy_field = NULL;
748 const struct bt_trace *writer_trace = NULL;
749 int ret;
750
751 writer_event = bt_event_create(writer_event_class);
752 if (!writer_event) {
753 BT_LOGE_STR("Failed to create event.");
754 goto error;
755 }
756
757 writer_trace = event_class_get_trace(err, writer_event_class);
758 if (!writer_trace) {
759 BT_LOGE_STR("Failed to get trace from event_class.");
760 goto error;
761 }
762
763 field = bt_event_get_header(event);
764 if (field) {
765 /*
766 * If override_ts64, we override all integer fields mapped to a
767 * clock to a uint64_t field type, otherwise, we just copy it as
768 * is.
769 */
770 ret = bt_trace_get_clock_class_count(writer_trace);
771 BT_ASSERT(ret >= 0);
772
773 if (override_ts64 && ret > 0) {
774 copy_field = bt_event_get_header(writer_event);
775 BT_ASSERT(copy_field);
776
777 ret = copy_override_field(err, event, writer_event, field,
778 copy_field);
779 if (ret) {
780 BT_LOGE_STR("Failed to copy and override field.");
781 goto error;
782 }
783 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
784 } else {
785 ret = ctf_copy_event_header(err, event, writer_event_class,
786 writer_event, field);
787 if (ret) {
788 BT_LOGE_STR("Failed to copy event_header.");
789 goto error;
790 }
791 }
792 BT_OBJECT_PUT_REF_AND_RESET(field);
793 }
794
795 /* Optional field, so it can fail silently. */
796 field = bt_event_get_stream_event_context(event);
797 if (field) {
798 copy_field = bt_field_copy(field);
799 if (!copy_field) {
800 BT_LOGE_STR("Failed to copy field.");
801 goto error;
802 }
803 ret = bt_event_set_stream_event_context(writer_event,
804 copy_field);
805 if (ret < 0) {
806 BT_LOGE_STR("Failed to set stream_event_context.");
807 goto error;
808 }
809 BT_OBJECT_PUT_REF_AND_RESET(field);
810 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
811 }
812
813 /* Optional field, so it can fail silently. */
814 field = bt_event_get_event_context(event);
815 if (field) {
816 copy_field = bt_field_copy(field);
817 if (!copy_field) {
818 BT_LOGE_STR("Failed to copy field.");
819 goto error;
820 }
821 ret = bt_event_set_event_context(writer_event, copy_field);
822 if (ret < 0) {
823 BT_LOGE_STR("Failed to set event_context.");
824 goto error;
825 }
826 BT_OBJECT_PUT_REF_AND_RESET(field);
827 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
828 }
829
830 field = bt_event_get_event_payload(event);
831 if (field) {
832 copy_field = bt_field_copy(field);
833 if (!copy_field) {
834 BT_LOGE_STR("Failed to copy field.");
835 goto error;
836 }
837 ret = bt_event_set_event_payload(writer_event, copy_field);
838 if (ret < 0) {
839 BT_LOGE_STR("Failed to set event_payload.");
840 goto error;
841 }
842 BT_OBJECT_PUT_REF_AND_RESET(field);
843 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
844 }
845
846 goto end;
847
848 error:
849 BT_OBJECT_PUT_REF_AND_RESET(writer_event);
850 end:
851 bt_object_put_ref(field);
852 bt_object_put_ref(copy_field);
853 bt_object_put_ref(writer_trace);
854 return writer_event;
855 }
856
857 BT_HIDDEN
858 enum bt_component_status ctf_copy_trace(FILE *err, const struct bt_trace *trace,
859 const struct bt_trace *writer_trace)
860 {
861 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
862 int field_count, i, int_ret;
863 struct bt_field_type *header_type = NULL;
864 enum bt_byte_order order;
865 const char *trace_name;
866 const unsigned char *trace_uuid;
867
868 field_count = bt_trace_get_environment_field_count(trace);
869 for (i = 0; i < field_count; i++) {
870 int ret_int;
871 const char *name;
872 struct bt_value *value = NULL;
873
874 name = bt_trace_get_environment_field_name_by_index(
875 trace, i);
876 BT_ASSERT(name);
877
878 value = bt_trace_get_environment_field_value_by_index(
879 trace, i);
880 BT_ASSERT(value);
881
882 ret_int = bt_trace_set_environment_field(writer_trace,
883 name, value);
884 BT_OBJECT_PUT_REF_AND_RESET(value);
885 if (ret_int < 0) {
886 BT_LOGE("Failed to set environment: field-name=\"%s\"",
887 name);
888 ret = BT_COMPONENT_STATUS_ERROR;
889 goto end;
890 }
891 }
892
893 order = bt_trace_get_native_byte_order(trace);
894 BT_ASSERT(order != BT_BYTE_ORDER_UNKNOWN);
895
896 /*
897 * Only explicitly set the writer trace's native byte order if
898 * the original trace has a specific one. Otherwise leave what
899 * the CTF writer object chooses, which is the machine's native
900 * byte order.
901 */
902 if (order != BT_BYTE_ORDER_UNSPECIFIED) {
903 ret = bt_trace_set_native_byte_order(writer_trace, order);
904 if (ret) {
905 BT_LOGE_STR("Failed to set native byte order.");
906 ret = BT_COMPONENT_STATUS_ERROR;
907 goto end;
908 }
909 }
910
911 header_type = bt_trace_get_packet_header_type(trace);
912 if (header_type) {
913 int_ret = bt_trace_set_packet_header_type(writer_trace, header_type);
914 BT_OBJECT_PUT_REF_AND_RESET(header_type);
915 if (int_ret < 0) {
916 BT_LOGE_STR("Failed to set packet header type.");
917 ret = BT_COMPONENT_STATUS_ERROR;
918 goto end;
919 }
920 }
921
922 trace_name = bt_trace_get_name(trace);
923 if (trace_name) {
924 int_ret = bt_trace_set_name(writer_trace, trace_name);
925 if (int_ret < 0) {
926 BT_LOGE_STR("Failed to set trace name.");
927 ret = BT_COMPONENT_STATUS_ERROR;
928 goto end;
929 }
930 }
931
932 trace_uuid = bt_trace_get_uuid(trace);
933 if (trace_uuid) {
934 int_ret = bt_trace_set_uuid(writer_trace, trace_uuid);
935 if (int_ret < 0) {
936 BT_LOGE_STR("Failed to set trace UUID.");
937 ret = BT_COMPONENT_STATUS_ERROR;
938 goto end;
939 }
940 }
941
942 end:
943 return ret;
944 }
This page took 0.048595 seconds and 4 git commands to generate.