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