2b408ace8d1765bb73ecdaa4d379a8a71d232e2e
[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 #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.h>
37 #include <assert.h>
38
39 #include "ctfcopytrace.h"
40 #include "clock-fields.h"
41
42 BT_HIDDEN
43 struct bt_ctf_clock_class *ctf_copy_clock_class(FILE *err,
44 struct bt_ctf_clock_class *clock_class)
45 {
46 int64_t offset, offset_s;
47 int int_ret;
48 uint64_t u64_ret;
49 const char *name, *description;
50 struct bt_ctf_clock_class *writer_clock_class = NULL;
51
52 assert(err && clock_class);
53
54 name = bt_ctf_clock_class_get_name(clock_class);
55 if (!name) {
56 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
57 __LINE__);
58 goto end;
59 }
60
61 writer_clock_class = bt_ctf_clock_class_create(name,
62 bt_ctf_clock_class_get_frequency(clock_class));
63 if (!writer_clock_class) {
64 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
65 __LINE__);
66 goto end;
67 }
68
69 description = bt_ctf_clock_class_get_description(clock_class);
70 if (description) {
71 int_ret = bt_ctf_clock_class_set_description(writer_clock_class,
72 description);
73 if (int_ret != 0) {
74 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
75 __LINE__);
76 goto end_destroy;
77 }
78 }
79
80 u64_ret = bt_ctf_clock_class_get_precision(clock_class);
81 if (u64_ret == -1ULL) {
82 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
83 __LINE__);
84 goto end_destroy;
85 }
86 int_ret = bt_ctf_clock_class_set_precision(writer_clock_class,
87 u64_ret);
88 if (int_ret != 0) {
89 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
90 __LINE__);
91 goto end_destroy;
92 }
93
94 int_ret = bt_ctf_clock_class_get_offset_s(clock_class, &offset_s);
95 if (int_ret != 0) {
96 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
97 __LINE__);
98 goto end_destroy;
99 }
100
101 int_ret = bt_ctf_clock_class_set_offset_s(writer_clock_class, offset_s);
102 if (int_ret != 0) {
103 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
104 __LINE__);
105 goto end_destroy;
106 }
107
108 int_ret = bt_ctf_clock_class_get_offset_cycles(clock_class, &offset);
109 if (int_ret != 0) {
110 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
111 __LINE__);
112 goto end_destroy;
113 }
114
115 int_ret = bt_ctf_clock_class_set_offset_cycles(writer_clock_class, offset);
116 if (int_ret != 0) {
117 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
118 __LINE__);
119 goto end_destroy;
120 }
121
122 int_ret = bt_ctf_clock_class_is_absolute(clock_class);
123 if (int_ret == -1) {
124 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
125 __LINE__);
126 goto end_destroy;
127 }
128
129 int_ret = bt_ctf_clock_class_set_is_absolute(writer_clock_class, int_ret);
130 if (int_ret != 0) {
131 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
132 __LINE__);
133 goto end_destroy;
134 }
135
136 goto end;
137
138 end_destroy:
139 BT_PUT(writer_clock_class);
140 end:
141 return writer_clock_class;
142 }
143
144 BT_HIDDEN
145 enum bt_component_status ctf_copy_clock_classes(FILE *err,
146 struct bt_ctf_trace *writer_trace,
147 struct bt_ctf_stream_class *writer_stream_class,
148 struct bt_ctf_trace *trace)
149 {
150 enum bt_component_status ret;
151 int int_ret, clock_class_count, i;
152
153 clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
154
155 for (i = 0; i < clock_class_count; i++) {
156 struct bt_ctf_clock_class *writer_clock_class;
157 struct bt_ctf_clock_class *clock_class =
158 bt_ctf_trace_get_clock_class_by_index(trace, i);
159
160 if (!clock_class) {
161 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
162 __LINE__);
163 ret = BT_COMPONENT_STATUS_ERROR;
164 goto end;
165 }
166
167 writer_clock_class = ctf_copy_clock_class(err, clock_class);
168 bt_put(clock_class);
169 if (!writer_clock_class) {
170 fprintf(err, "Failed to copy clock class");
171 ret = BT_COMPONENT_STATUS_ERROR;
172 goto end;
173 }
174
175 int_ret = bt_ctf_trace_add_clock_class(writer_trace, writer_clock_class);
176 if (int_ret != 0) {
177 BT_PUT(writer_clock_class);
178 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
179 __LINE__);
180 ret = BT_COMPONENT_STATUS_ERROR;
181 goto end;
182 }
183
184 /*
185 * Ownership transferred to the trace.
186 */
187 bt_put(writer_clock_class);
188 }
189
190 ret = BT_COMPONENT_STATUS_OK;
191
192 end:
193 return ret;
194 }
195
196 BT_HIDDEN
197 struct bt_ctf_event_class *ctf_copy_event_class(FILE *err,
198 struct bt_ctf_event_class *event_class)
199 {
200 struct bt_ctf_event_class *writer_event_class = NULL;
201 struct bt_ctf_field_type *context, *payload_type;
202 const char *name;
203 int ret;
204 int64_t id;
205 enum bt_ctf_event_class_log_level log_level;
206 const char *emf_uri;
207
208 name = bt_ctf_event_class_get_name(event_class);
209 if (!name) {
210 fprintf(err, "[error] %s in %s:%d\n", __func__,
211 __FILE__, __LINE__);
212 goto end;
213 }
214
215 writer_event_class = bt_ctf_event_class_create(name);
216 if (!writer_event_class) {
217 fprintf(err, "[error] %s in %s:%d\n", __func__,
218 __FILE__, __LINE__);
219 goto end;
220 }
221
222 id = bt_ctf_event_class_get_id(event_class);
223 if (id < 0) {
224 fprintf(err, "[error] %s in %s:%d\n", __func__,
225 __FILE__, __LINE__);
226 goto error;
227 }
228
229 ret = bt_ctf_event_class_set_id(writer_event_class, id);
230 if (ret) {
231 fprintf(err, "[error] %s in %s:%d\n", __func__,
232 __FILE__, __LINE__);
233 goto error;
234 }
235
236 log_level = bt_ctf_event_class_get_log_level(event_class);
237 if (log_level < 0) {
238 fprintf(err, "[error] %s in %s:%d\n", __func__,
239 __FILE__, __LINE__);
240 goto error;
241 }
242
243 ret = bt_ctf_event_class_set_log_level(writer_event_class, log_level);
244 if (ret) {
245 fprintf(err, "[error] %s in %s:%d\n", __func__,
246 __FILE__, __LINE__);
247 goto error;
248 }
249
250 emf_uri = bt_ctf_event_class_get_emf_uri(event_class);
251 if (emf_uri) {
252 ret = bt_ctf_event_class_set_emf_uri(writer_event_class,
253 emf_uri);
254 if (ret) {
255 fprintf(err, "[error] %s in %s:%d\n", __func__,
256 __FILE__, __LINE__);
257 goto error;
258 }
259 }
260
261 payload_type = bt_ctf_event_class_get_payload_type(event_class);
262 if (payload_type) {
263 ret = bt_ctf_event_class_set_payload_type(writer_event_class,
264 payload_type);
265 if (ret < 0) {
266 fprintf(err, "[error] %s in %s:%d\n", __func__,
267 __FILE__, __LINE__);
268 goto error;
269 }
270 BT_PUT(payload_type);
271 }
272
273 context = bt_ctf_event_class_get_context_type(event_class);
274 if (context) {
275 ret = bt_ctf_event_class_set_context_type(
276 writer_event_class, context);
277 BT_PUT(context);
278 if (ret < 0) {
279 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
280 __LINE__);
281 goto error;
282 }
283 }
284
285 goto end;
286
287 error:
288 BT_PUT(writer_event_class);
289 end:
290 return writer_event_class;
291 }
292
293 BT_HIDDEN
294 enum bt_component_status ctf_copy_event_classes(FILE *err,
295 struct bt_ctf_stream_class *stream_class,
296 struct bt_ctf_stream_class *writer_stream_class)
297 {
298 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
299 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
300 int count, i;
301
302 count = bt_ctf_stream_class_get_event_class_count(stream_class);
303 if (count < 0) {
304 fprintf(err, "[error] %s in %s:%d\n", __func__,
305 __FILE__, __LINE__);
306 goto end;
307 }
308
309 for (i = 0; i < count; i++) {
310 int int_ret;
311
312 event_class = bt_ctf_stream_class_get_event_class_by_index(
313 stream_class, i);
314 if (!event_class) {
315 fprintf(err, "[error] %s in %s:%d\n", __func__,
316 __FILE__, __LINE__);
317 ret = BT_COMPONENT_STATUS_ERROR;
318 goto error;
319 }
320 if (i < bt_ctf_stream_class_get_event_class_count(writer_stream_class)) {
321 writer_event_class = bt_ctf_stream_class_get_event_class_by_index(
322 writer_stream_class, i);
323 if (writer_event_class) {
324 /*
325 * If the writer_event_class already exists,
326 * just skip it. It can be used to resync the
327 * event_classes after a trace has become
328 * static.
329 */
330 BT_PUT(writer_event_class);
331 BT_PUT(event_class);
332 continue;
333 }
334 }
335
336 writer_event_class = ctf_copy_event_class(err, event_class);
337 if (!writer_event_class) {
338 fprintf(err, "[error] %s in %s:%d\n", __func__,
339 __FILE__, __LINE__);
340 ret = BT_COMPONENT_STATUS_ERROR;
341 goto error;
342 }
343
344 int_ret = bt_ctf_stream_class_add_event_class(writer_stream_class,
345 writer_event_class);
346 if (int_ret < 0) {
347 fprintf(err, "[error] Failed to add event class\n");
348 fprintf(err, "[error] %s in %s:%d\n", __func__,
349 __FILE__, __LINE__);
350 ret = BT_COMPONENT_STATUS_ERROR;
351 goto error;
352 }
353 BT_PUT(writer_event_class);
354 BT_PUT(event_class);
355 }
356
357 goto end;
358
359 error:
360 bt_put(event_class);
361 bt_put(writer_event_class);
362 end:
363 return ret;
364 }
365
366 BT_HIDDEN
367 struct bt_ctf_stream_class *ctf_copy_stream_class(FILE *err,
368 struct bt_ctf_stream_class *stream_class,
369 struct bt_ctf_trace *writer_trace,
370 bool override_ts64)
371 {
372 struct bt_ctf_field_type *type = NULL;
373 struct bt_ctf_stream_class *writer_stream_class = NULL;
374 int ret_int;
375 const char *name = bt_ctf_stream_class_get_name(stream_class);
376
377 writer_stream_class = bt_ctf_stream_class_create_empty(name);
378 if (!writer_stream_class) {
379 fprintf(err, "[error] %s in %s:%d\n",
380 __func__, __FILE__, __LINE__);
381 goto end;
382 }
383
384 type = bt_ctf_stream_class_get_packet_context_type(stream_class);
385 if (type) {
386 ret_int = bt_ctf_stream_class_set_packet_context_type(
387 writer_stream_class, type);
388 if (ret_int < 0) {
389 fprintf(err, "[error] %s in %s:%d\n", __func__,
390 __FILE__, __LINE__);
391 goto error;
392 }
393 BT_PUT(type);
394 }
395
396 type = bt_ctf_stream_class_get_event_header_type(stream_class);
397 if (type) {
398 ret_int = bt_ctf_trace_get_clock_class_count(writer_trace);
399 if (ret_int < 0) {
400 fprintf(err, "[error] %s in %s:%d\n", __func__,
401 __FILE__, __LINE__);
402 goto error;
403 }
404 if (override_ts64 && ret_int > 0) {
405 struct bt_ctf_field_type *new_event_header_type;
406
407 new_event_header_type = override_header_type(err, type,
408 writer_trace);
409 if (!new_event_header_type) {
410 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
411 __LINE__);
412 goto error;
413 }
414 ret_int = bt_ctf_stream_class_set_event_header_type(
415 writer_stream_class, new_event_header_type);
416 BT_PUT(new_event_header_type);
417 if (ret_int < 0) {
418 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
419 __LINE__);
420 goto error;
421 }
422 } else {
423 ret_int = bt_ctf_stream_class_set_event_header_type(
424 writer_stream_class, type);
425 if (ret_int < 0) {
426 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
427 __LINE__);
428 goto error;
429 }
430 }
431 BT_PUT(type);
432 }
433
434 type = bt_ctf_stream_class_get_event_context_type(stream_class);
435 if (type) {
436 ret_int = bt_ctf_stream_class_set_event_context_type(
437 writer_stream_class, type);
438 if (ret_int < 0) {
439 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
440 __LINE__);
441 goto error;
442 }
443 }
444 BT_PUT(type);
445
446 goto end;
447
448 error:
449 BT_PUT(writer_stream_class);
450 end:
451 bt_put(type);
452 return writer_stream_class;
453 }
454
455 BT_HIDDEN
456 int ctf_stream_copy_packet_header(FILE *err, struct bt_ctf_packet *packet,
457 struct bt_ctf_stream *writer_stream)
458 {
459 struct bt_ctf_field *packet_header = NULL, *writer_packet_header = NULL;
460 int ret = 0;
461
462 packet_header = bt_ctf_packet_get_header(packet);
463 if (!packet_header) {
464 goto end;
465 }
466
467 writer_packet_header = bt_ctf_field_copy(packet_header);
468 if (!writer_packet_header) {
469 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
470 __LINE__);
471 goto error;
472 }
473
474 ret = bt_ctf_stream_set_packet_header(writer_stream,
475 writer_packet_header);
476 if (ret) {
477 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
478 __LINE__);
479 goto error;
480 }
481
482 goto end;
483
484 error:
485 ret = -1;
486 end:
487 bt_put(writer_packet_header);
488 bt_put(packet_header);
489 return ret;
490 }
491
492 BT_HIDDEN
493 int ctf_packet_copy_header(FILE *err, struct bt_ctf_packet *packet,
494 struct bt_ctf_packet *writer_packet)
495 {
496 struct bt_ctf_field *packet_header = NULL, *writer_packet_header = NULL;
497 int ret = 0;
498
499 packet_header = bt_ctf_packet_get_header(packet);
500 if (!packet_header) {
501 goto end;
502 }
503
504 writer_packet_header = bt_ctf_field_copy(packet_header);
505 if (!writer_packet_header) {
506 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
507 __LINE__);
508 goto error;
509 }
510
511 ret = bt_ctf_packet_set_header(writer_packet, writer_packet_header);
512 if (ret) {
513 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
514 __LINE__);
515 goto error;
516 }
517
518 goto end;
519
520 error:
521 ret = -1;
522 end:
523 bt_put(packet_header);
524 bt_put(writer_packet_header);
525 return ret;
526 }
527
528 BT_HIDDEN
529 int ctf_stream_copy_packet_context(FILE *err, struct bt_ctf_packet *packet,
530 struct bt_ctf_stream *writer_stream)
531 {
532 struct bt_ctf_field *packet_context = NULL, *writer_packet_context = NULL;
533 int ret = 0;
534
535 packet_context = bt_ctf_packet_get_context(packet);
536 if (!packet_context) {
537 goto end;
538 }
539
540 writer_packet_context = bt_ctf_field_copy(packet_context);
541 if (!writer_packet_context) {
542 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
543 __LINE__);
544 goto error;
545 }
546
547 ret = bt_ctf_stream_set_packet_context(writer_stream,
548 writer_packet_context);
549 if (ret) {
550 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
551 __LINE__);
552 goto error;
553 }
554
555 goto end;
556
557 error:
558 ret = -1;
559 end:
560 bt_put(packet_context);
561 bt_put(writer_packet_context);
562 return ret;
563 }
564
565 BT_HIDDEN
566 int ctf_packet_copy_context(FILE *err, struct bt_ctf_packet *packet,
567 struct bt_ctf_stream *writer_stream,
568 struct bt_ctf_packet *writer_packet)
569 {
570 struct bt_ctf_field *packet_context = NULL, *writer_packet_context = NULL;
571 int ret = 0;
572
573 packet_context = bt_ctf_packet_get_context(packet);
574 if (!packet_context) {
575 goto end;
576 }
577
578 writer_packet_context = bt_ctf_field_copy(packet_context);
579 if (!writer_packet_context) {
580 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
581 __LINE__);
582 goto error;
583 }
584
585 ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context);
586 if (ret) {
587 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
588 __LINE__);
589 goto error;
590 }
591
592 goto end;
593
594 error:
595 ret = -1;
596 end:
597 bt_put(writer_packet_context);
598 bt_put(packet_context);
599 return ret;
600 }
601
602 BT_HIDDEN
603 int ctf_copy_event_header(FILE *err, struct bt_ctf_event *event,
604 struct bt_ctf_event_class *writer_event_class,
605 struct bt_ctf_event *writer_event,
606 struct bt_ctf_field *event_header)
607 {
608 struct bt_ctf_clock_class *clock_class = NULL, *writer_clock_class = NULL;
609 struct bt_ctf_clock_value *clock_value = NULL, *writer_clock_value = NULL;
610
611 int ret;
612 struct bt_ctf_field *writer_event_header = NULL;
613 uint64_t value;
614
615 clock_class = event_get_clock_class(err, event);
616 if (!clock_class) {
617 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
618 __LINE__);
619 goto error;
620 }
621
622 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
623 BT_PUT(clock_class);
624 if (!clock_value) {
625 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
626 __LINE__);
627 goto error;
628 }
629
630 ret = bt_ctf_clock_value_get_value(clock_value, &value);
631 BT_PUT(clock_value);
632 if (ret) {
633 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
634 __LINE__);
635 goto error;
636 }
637
638 writer_clock_class = event_get_clock_class(err, writer_event);
639 if (!writer_clock_class) {
640 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
641 __LINE__);
642 goto error;
643 }
644
645 writer_clock_value = bt_ctf_clock_value_create(writer_clock_class, value);
646 BT_PUT(writer_clock_class);
647 if (!writer_clock_value) {
648 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
649 __LINE__);
650 goto error;
651 }
652
653 ret = bt_ctf_event_set_clock_value(writer_event, writer_clock_value);
654 BT_PUT(writer_clock_value);
655 if (ret) {
656 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
657 __LINE__);
658 goto error;
659 }
660
661 writer_event_header = bt_ctf_field_copy(event_header);
662 if (!writer_event_header) {
663 fprintf(err, "[error] %s in %s:%d\n", __func__,
664 __FILE__, __LINE__);
665 goto end;
666 }
667
668 ret = bt_ctf_event_set_header(writer_event, writer_event_header);
669 BT_PUT(writer_event_header);
670 if (ret < 0) {
671 fprintf(err, "[error] %s in %s:%d\n", __func__,
672 __FILE__, __LINE__);
673 goto error;
674 }
675
676 ret = 0;
677
678 goto end;
679
680 error:
681 ret = -1;
682 end:
683 return ret;
684 }
685
686 static
687 struct bt_ctf_trace *event_class_get_trace(FILE *err,
688 struct bt_ctf_event_class *event_class)
689 {
690 struct bt_ctf_trace *trace = NULL;
691 struct bt_ctf_stream_class *stream_class = NULL;
692
693 stream_class = bt_ctf_event_class_get_stream_class(event_class);
694 if (!stream_class) {
695 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
696 __LINE__);
697 goto error;
698 }
699
700 trace = bt_ctf_stream_class_get_trace(stream_class);
701 if (!trace) {
702 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
703 __LINE__);
704 goto error;
705 }
706
707 goto end;
708
709 error:
710 BT_PUT(trace);
711 end:
712 bt_put(stream_class);
713 return trace;
714 }
715
716 BT_HIDDEN
717 struct bt_ctf_event *ctf_copy_event(FILE *err, struct bt_ctf_event *event,
718 struct bt_ctf_event_class *writer_event_class,
719 bool override_ts64)
720 {
721 struct bt_ctf_event *writer_event = NULL;
722 struct bt_ctf_field *field = NULL, *copy_field = NULL;
723 struct bt_ctf_trace *writer_trace = NULL;
724 int ret;
725
726 writer_event = bt_ctf_event_create(writer_event_class);
727 if (!writer_event) {
728 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
729 __LINE__);
730 goto error;
731 }
732
733 writer_trace = event_class_get_trace(err, writer_event_class);
734 if (!writer_trace) {
735 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
736 __LINE__);
737 goto error;
738 }
739
740 field = bt_ctf_event_get_header(event);
741 if (field) {
742 /*
743 * If override_ts64, we override all integer fields mapped to a
744 * clock to a uint64_t field type, otherwise, we just copy it as
745 * is.
746 */
747 ret = bt_ctf_trace_get_clock_class_count(writer_trace);
748 if (ret < 0) {
749 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
750 __LINE__);
751 goto error;
752 }
753 if (override_ts64 && ret > 0) {
754 copy_field = bt_ctf_event_get_header(writer_event);
755 if (!copy_field) {
756 fprintf(err, "[error] %s in %s:%d\n", __func__,
757 __FILE__, __LINE__);
758 goto error;
759 }
760
761 ret = copy_override_field(err, event, writer_event, field,
762 copy_field);
763 if (ret) {
764 fprintf(err, "[error] %s in %s:%d\n", __func__,
765 __FILE__, __LINE__);
766 goto error;
767 }
768 BT_PUT(copy_field);
769 } else {
770 ret = ctf_copy_event_header(err, event, writer_event_class,
771 writer_event, field);
772 if (ret) {
773 fprintf(err, "[error] %s in %s:%d\n", __func__,
774 __FILE__, __LINE__);
775 goto error;
776 }
777 }
778 BT_PUT(field);
779 }
780
781 /* Optional field, so it can fail silently. */
782 field = bt_ctf_event_get_stream_event_context(event);
783 if (field) {
784 copy_field = bt_ctf_field_copy(field);
785 if (!copy_field) {
786 fprintf(err, "[error] %s in %s:%d\n", __func__,
787 __FILE__, __LINE__);
788 goto error;
789 }
790 ret = bt_ctf_event_set_stream_event_context(writer_event,
791 copy_field);
792 if (ret < 0) {
793 fprintf(err, "[error] %s in %s:%d\n", __func__,
794 __FILE__, __LINE__);
795 goto error;
796 }
797 BT_PUT(field);
798 BT_PUT(copy_field);
799 }
800
801 /* Optional field, so it can fail silently. */
802 field = bt_ctf_event_get_event_context(event);
803 if (field) {
804 copy_field = bt_ctf_field_copy(field);
805 if (!copy_field) {
806 fprintf(err, "[error] %s in %s:%d\n", __func__,
807 __FILE__, __LINE__);
808 goto error;
809 }
810 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
811 if (ret < 0) {
812 fprintf(err, "[error] %s in %s:%d\n", __func__,
813 __FILE__, __LINE__);
814 goto error;
815 }
816 BT_PUT(field);
817 BT_PUT(copy_field);
818 }
819
820 field = bt_ctf_event_get_event_payload(event);
821 if (field) {
822 copy_field = bt_ctf_field_copy(field);
823 if (!copy_field) {
824 fprintf(err, "[error] %s in %s:%d\n", __func__,
825 __FILE__, __LINE__);
826 goto error;
827 }
828 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
829 if (ret < 0) {
830 fprintf(err, "[error] %s in %s:%d\n", __func__,
831 __FILE__, __LINE__);
832 goto error;
833 }
834 BT_PUT(field);
835 BT_PUT(copy_field);
836 }
837
838 goto end;
839
840 error:
841 BT_PUT(writer_event);
842 end:
843 bt_put(field);
844 bt_put(copy_field);
845 bt_put(writer_trace);
846 return writer_event;
847 }
848
849 BT_HIDDEN
850 enum bt_component_status ctf_copy_trace(FILE *err, struct bt_ctf_trace *trace,
851 struct bt_ctf_trace *writer_trace)
852 {
853 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
854 int field_count, i, int_ret;
855 struct bt_ctf_field_type *header_type = NULL;
856 enum bt_ctf_byte_order order;
857 const char *trace_name;
858 const unsigned char *trace_uuid;
859
860 field_count = bt_ctf_trace_get_environment_field_count(trace);
861 for (i = 0; i < field_count; i++) {
862 int ret_int;
863 const char *name;
864 struct bt_value *value = NULL;
865
866 name = bt_ctf_trace_get_environment_field_name_by_index(
867 trace, i);
868 if (!name) {
869 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
870 __LINE__);
871 ret = BT_COMPONENT_STATUS_ERROR;
872 goto end;
873 }
874 value = bt_ctf_trace_get_environment_field_value_by_index(
875 trace, i);
876 if (!value) {
877 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
878 __LINE__);
879 ret = BT_COMPONENT_STATUS_ERROR;
880 goto end;
881 }
882
883 ret_int = bt_ctf_trace_set_environment_field(writer_trace,
884 name, value);
885 BT_PUT(value);
886 if (ret_int < 0) {
887 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
888 __LINE__);
889 fprintf(err, "[error] Unable to set environment field %s\n",
890 name);
891 ret = BT_COMPONENT_STATUS_ERROR;
892 goto end;
893 }
894 }
895
896 order = bt_ctf_trace_get_native_byte_order(trace);
897 if (order == BT_CTF_BYTE_ORDER_UNKNOWN) {
898 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
899 ret = BT_COMPONENT_STATUS_ERROR;
900 goto end;
901 }
902
903 /*
904 * Only explicitly set the writer trace's native byte order if
905 * the original trace has a specific one. Otherwise leave what
906 * the CTF writer object chooses, which is the machine's native
907 * byte order.
908 */
909 if (order != BT_CTF_BYTE_ORDER_UNSPECIFIED) {
910 ret = bt_ctf_trace_set_native_byte_order(writer_trace, order);
911 if (ret) {
912 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
913 ret = BT_COMPONENT_STATUS_ERROR;
914 goto end;
915 }
916 }
917
918 header_type = bt_ctf_trace_get_packet_header_type(trace);
919 if (header_type) {
920 int_ret = bt_ctf_trace_set_packet_header_type(writer_trace, header_type);
921 BT_PUT(header_type);
922 if (int_ret < 0) {
923 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
924 ret = BT_COMPONENT_STATUS_ERROR;
925 goto end;
926 }
927 }
928
929 trace_name = bt_ctf_trace_get_name(trace);
930 if (trace_name) {
931 int_ret = bt_ctf_trace_set_name(writer_trace, trace_name);
932 if (int_ret < 0) {
933 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
934 ret = BT_COMPONENT_STATUS_ERROR;
935 goto end;
936 }
937 }
938
939 trace_uuid = bt_ctf_trace_get_uuid(trace);
940 if (trace_uuid) {
941 int_ret = bt_ctf_trace_set_uuid(writer_trace, trace_uuid);
942 if (int_ret < 0) {
943 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
944 ret = BT_COMPONENT_STATUS_ERROR;
945 goto end;
946 }
947 }
948
949 end:
950 return ret;
951 }
This page took 0.048354 seconds and 3 git commands to generate.