Fix copytrace: copy the entire payload_type
[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 count, i, ret;
216
217 name = bt_ctf_event_class_get_name(event_class);
218 if (!name) {
219 fprintf(err, "[error] %s in %s:%d\n", __func__,
220 __FILE__, __LINE__);
221 goto end;
222 }
223
224 writer_event_class = bt_ctf_event_class_create(name);
225 if (!writer_event_class) {
226 fprintf(err, "[error] %s in %s:%d\n", __func__,
227 __FILE__, __LINE__);
228 goto end;
229 }
230
231 count = bt_ctf_event_class_get_attribute_count(event_class);
232 for (i = 0; i < count; i++) {
233 const char *attr_name;
234 struct bt_value *attr_value;
235 int ret;
236
237 attr_name = bt_ctf_event_class_get_attribute_name_by_index(
238 event_class, i);
239 if (!attr_name) {
240 fprintf(err, "[error] %s in %s:%d\n", __func__,
241 __FILE__, __LINE__);
242 goto error;
243 }
244 attr_value = bt_ctf_event_class_get_attribute_value_by_index(
245 event_class, i);
246 if (!attr_value) {
247 fprintf(err, "[error] %s in %s:%d\n", __func__,
248 __FILE__, __LINE__);
249 goto error;
250 }
251
252 ret = bt_ctf_event_class_set_attribute(writer_event_class,
253 attr_name, attr_value);
254 BT_PUT(attr_value);
255 if (ret < 0) {
256 fprintf(err, "[error] %s in %s:%d\n", __func__,
257 __FILE__, __LINE__);
258 goto error;
259 }
260 }
261
262 payload_type = bt_ctf_event_class_get_payload_type(event_class);
263 if (payload_type) {
264 ret = bt_ctf_event_class_set_payload_type(writer_event_class,
265 payload_type);
266 if (ret < 0) {
267 fprintf(err, "[error] %s in %s:%d\n", __func__,
268 __FILE__, __LINE__);
269 goto error;
270 }
271 BT_PUT(payload_type);
272 }
273
274 context = bt_ctf_event_class_get_context_type(event_class);
275 if (context) {
276 ret = bt_ctf_event_class_set_context_type(
277 writer_event_class, context);
278 BT_PUT(context);
279 if (ret < 0) {
280 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
281 __LINE__);
282 goto error;
283 }
284 }
285
286 goto end;
287
288 error:
289 BT_PUT(writer_event_class);
290 end:
291 return writer_event_class;
292 }
293
294 BT_HIDDEN
295 enum bt_component_status ctf_copy_event_classes(FILE *err,
296 struct bt_ctf_stream_class *stream_class,
297 struct bt_ctf_stream_class *writer_stream_class)
298 {
299 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
300 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
301 int count, i;
302
303 count = bt_ctf_stream_class_get_event_class_count(stream_class);
304 if (count < 0) {
305 fprintf(err, "[error] %s in %s:%d\n", __func__,
306 __FILE__, __LINE__);
307 goto end;
308 }
309
310 for (i = 0; i < count; i++) {
311 int int_ret;
312
313 event_class = bt_ctf_stream_class_get_event_class_by_index(
314 stream_class, i);
315 if (!event_class) {
316 fprintf(err, "[error] %s in %s:%d\n", __func__,
317 __FILE__, __LINE__);
318 ret = BT_COMPONENT_STATUS_ERROR;
319 goto error;
320 }
321 writer_event_class = ctf_copy_event_class(err, event_class);
322 if (!writer_event_class) {
323 fprintf(err, "[error] %s in %s:%d\n", __func__,
324 __FILE__, __LINE__);
325 ret = BT_COMPONENT_STATUS_ERROR;
326 goto error;
327 }
328
329 int_ret = bt_ctf_stream_class_add_event_class(writer_stream_class,
330 writer_event_class);
331 if (int_ret < 0) {
332 fprintf(err, "[error] Failed to add event class\n");
333 fprintf(err, "[error] %s in %s:%d\n", __func__,
334 __FILE__, __LINE__);
335 ret = BT_COMPONENT_STATUS_ERROR;
336 goto error;
337 }
338 BT_PUT(writer_event_class);
339 BT_PUT(event_class);
340 }
341
342 goto end;
343
344 error:
345 bt_put(event_class);
346 bt_put(writer_event_class);
347 end:
348 return ret;
349 }
350
351 BT_HIDDEN
352 struct bt_ctf_stream_class *ctf_copy_stream_class(FILE *err,
353 struct bt_ctf_stream_class *stream_class,
354 struct bt_ctf_trace *writer_trace,
355 bool override_ts64)
356 {
357 struct bt_ctf_field_type *type = NULL;
358 struct bt_ctf_stream_class *writer_stream_class = NULL;
359 int ret_int;
360 const char *name = bt_ctf_stream_class_get_name(stream_class);
361
362 if (strlen(name) == 0) {
363 name = NULL;
364 }
365
366 writer_stream_class = bt_ctf_stream_class_create(name);
367 if (!writer_stream_class) {
368 fprintf(err, "[error] %s in %s:%d\n",
369 __func__, __FILE__, __LINE__);
370 goto end;
371 }
372
373 type = bt_ctf_stream_class_get_packet_context_type(stream_class);
374 if (!type) {
375 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
376 __LINE__);
377 goto error;
378 }
379
380 ret_int = bt_ctf_stream_class_set_packet_context_type(
381 writer_stream_class, type);
382 if (ret_int < 0) {
383 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
384 __LINE__);
385 goto error;
386 }
387 BT_PUT(type);
388
389 type = bt_ctf_stream_class_get_event_header_type(stream_class);
390 if (!type) {
391 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
392 __LINE__);
393 goto error;
394 }
395
396 if (override_ts64) {
397 struct bt_ctf_field_type *new_event_header_type;
398
399 new_event_header_type = override_header_type(err, type,
400 writer_trace);
401 if (!new_event_header_type) {
402 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
403 __LINE__);
404 goto error;
405 }
406 ret_int = bt_ctf_stream_class_set_event_header_type(
407 writer_stream_class, new_event_header_type);
408 BT_PUT(new_event_header_type);
409 if (ret_int < 0) {
410 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
411 __LINE__);
412 goto error;
413 }
414 } else {
415 ret_int = bt_ctf_stream_class_set_event_header_type(
416 writer_stream_class, type);
417 if (ret_int < 0) {
418 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
419 __LINE__);
420 goto error;
421 }
422 }
423 BT_PUT(type);
424
425 type = bt_ctf_stream_class_get_event_context_type(stream_class);
426 if (type) {
427 ret_int = bt_ctf_stream_class_set_event_context_type(
428 writer_stream_class, type);
429 if (ret_int < 0) {
430 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
431 __LINE__);
432 goto error;
433 }
434 }
435 BT_PUT(type);
436
437 goto end;
438
439 error:
440 BT_PUT(writer_stream_class);
441 end:
442 bt_put(type);
443 return writer_stream_class;
444 }
445
446 BT_HIDDEN
447 enum bt_component_status ctf_copy_packet_context_field(FILE *err,
448 struct bt_ctf_field *field, const char *field_name,
449 struct bt_ctf_field *writer_packet_context,
450 struct bt_ctf_field_type *writer_packet_context_type)
451 {
452 enum bt_component_status ret;
453 struct bt_ctf_field *writer_field = NULL;
454 struct bt_ctf_field_type *field_type = NULL;
455 int int_ret;
456 uint64_t value;
457
458 field_type = bt_ctf_field_get_type(field);
459 if (!field_type) {
460 ret = BT_COMPONENT_STATUS_ERROR;
461 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
462 __LINE__);
463 goto end;
464 }
465 /*
466 * Only support for integers for now.
467 */
468 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
469 fprintf(err, "[error] Unsupported packet context field type\n");
470 ret = BT_COMPONENT_STATUS_ERROR;
471 goto error;
472 }
473 BT_PUT(field_type);
474
475 writer_field = bt_ctf_field_structure_get_field_by_name(
476 writer_packet_context, field_name);
477 if (!writer_field) {
478 ret = BT_COMPONENT_STATUS_ERROR;
479 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
480 __LINE__);
481 goto end;
482 }
483
484 int_ret = bt_ctf_field_unsigned_integer_get_value(field, &value);
485 if (int_ret < 0) {
486 fprintf(err, "[error] Wrong packet_context field type\n");
487 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
488 __LINE__);
489 ret = BT_COMPONENT_STATUS_ERROR;
490 goto end;
491 }
492
493 int_ret = bt_ctf_field_unsigned_integer_set_value(writer_field, value);
494 if (int_ret < 0) {
495 ret = BT_COMPONENT_STATUS_ERROR;
496 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
497 __LINE__);
498 goto end;
499 }
500
501 ret = BT_COMPONENT_STATUS_OK;
502
503 goto end;
504
505 error:
506 bt_put(field_type);
507 end:
508 bt_put(writer_field);
509 return ret;
510 }
511
512 BT_HIDDEN
513 struct bt_ctf_field *ctf_copy_packet_context(FILE *err,
514 struct bt_ctf_packet *packet,
515 struct bt_ctf_stream *writer_stream,
516 int skip_content_size)
517 {
518 enum bt_component_status ret;
519 struct bt_ctf_field *packet_context = NULL, *writer_packet_context = NULL;
520 struct bt_ctf_field_type *struct_type = NULL, *writer_packet_context_type = NULL;
521 struct bt_ctf_stream_class *writer_stream_class = NULL;
522 struct bt_ctf_field *field = NULL;
523 struct bt_ctf_field_type *field_type = NULL;
524 int nr_fields, i;
525
526 packet_context = bt_ctf_packet_get_context(packet);
527 if (!packet_context) {
528 goto end;
529 }
530
531 writer_stream_class = bt_ctf_stream_get_class(writer_stream);
532 if (!writer_stream_class) {
533 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
534 __LINE__);
535 goto error;
536 }
537
538 writer_packet_context_type = bt_ctf_stream_class_get_packet_context_type(
539 writer_stream_class);
540 BT_PUT(writer_stream_class);
541 if (!writer_packet_context_type) {
542 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
543 __LINE__);
544 goto error;
545 }
546
547 struct_type = bt_ctf_field_get_type(packet_context);
548 if (!struct_type) {
549 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
550 __LINE__);
551 goto error;
552 }
553
554 writer_packet_context = bt_ctf_field_create(writer_packet_context_type);
555 if (!writer_packet_context) {
556 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
557 __LINE__);
558 goto error;
559 }
560
561 nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
562 for (i = 0; i < nr_fields; i++) {
563 const char *field_name;
564
565 field = bt_ctf_field_structure_get_field_by_index(
566 packet_context, i);
567 if (!field) {
568 fprintf(err, "[error] %s in %s:%d\n", __func__,
569 __FILE__, __LINE__);
570 goto error;
571 }
572 if (bt_ctf_field_type_structure_get_field_by_index(struct_type,
573 &field_name, &field_type, i) < 0) {
574 fprintf(err, "[error] %s in %s:%d\n", __func__,
575 __FILE__, __LINE__);
576 goto error;
577 }
578 if (skip_content_size &&
579 (!strncmp(field_name, "content_size", strlen("content_size")) ||
580 !strncmp(field_name, "packet_size", strlen("packet_size")))) {
581 BT_PUT(field_type);
582 BT_PUT(field);
583 continue;
584 }
585
586 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
587 fprintf(err, "[error] Unexpected packet context field type\n");
588 goto error;
589 }
590
591 ret = ctf_copy_packet_context_field(err, field, field_name,
592 writer_packet_context, writer_packet_context_type);
593 BT_PUT(field_type);
594 BT_PUT(field);
595 if (ret != BT_COMPONENT_STATUS_OK) {
596 fprintf(err, "[error] %s in %s:%d\n", __func__,
597 __FILE__, __LINE__);
598 goto error;
599 }
600 }
601
602 goto end;
603
604 error:
605 BT_PUT(writer_packet_context);
606 end:
607 bt_put(field);
608 bt_put(field_type);
609 bt_put(struct_type);
610 bt_put(writer_packet_context_type);
611 bt_put(writer_stream_class);
612 bt_put(packet_context);
613 return writer_packet_context;
614 }
615
616 BT_HIDDEN
617 int ctf_copy_event_header(FILE *err, struct bt_ctf_event *event,
618 struct bt_ctf_event_class *writer_event_class,
619 struct bt_ctf_event *writer_event,
620 struct bt_ctf_field *event_header)
621 {
622 struct bt_ctf_clock_class *clock_class = NULL, *writer_clock_class = NULL;
623 struct bt_ctf_clock_value *clock_value = NULL, *writer_clock_value = NULL;
624
625 int ret;
626 struct bt_ctf_field *writer_event_header = NULL;
627 uint64_t value;
628
629 clock_class = event_get_clock_class(err, event);
630 if (!clock_class) {
631 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
632 __LINE__);
633 goto error;
634 }
635
636 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
637 BT_PUT(clock_class);
638 if (!clock_value) {
639 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
640 __LINE__);
641 goto error;
642 }
643
644 ret = bt_ctf_clock_value_get_value(clock_value, &value);
645 BT_PUT(clock_value);
646 if (ret) {
647 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
648 __LINE__);
649 goto error;
650 }
651
652 writer_clock_class = event_get_clock_class(err, writer_event);
653 if (!writer_clock_class) {
654 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
655 __LINE__);
656 goto error;
657 }
658
659 writer_clock_value = bt_ctf_clock_value_create(writer_clock_class, value);
660 BT_PUT(writer_clock_class);
661 if (!writer_clock_value) {
662 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
663 __LINE__);
664 goto error;
665 }
666
667 ret = bt_ctf_event_set_clock_value(writer_event, writer_clock_value);
668 BT_PUT(writer_clock_value);
669 if (ret) {
670 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
671 __LINE__);
672 goto error;
673 }
674
675 writer_event_header = bt_ctf_field_copy(event_header);
676 if (!writer_event_header) {
677 fprintf(err, "[error] %s in %s:%d\n", __func__,
678 __FILE__, __LINE__);
679 goto end;
680 }
681
682 ret = bt_ctf_event_set_header(writer_event, writer_event_header);
683 BT_PUT(writer_event_header);
684 if (ret < 0) {
685 fprintf(err, "[error] %s in %s:%d\n", __func__,
686 __FILE__, __LINE__);
687 goto error;
688 }
689
690 ret = 0;
691
692 goto end;
693
694 error:
695 ret = -1;
696 end:
697 return ret;
698 }
699
700 BT_HIDDEN
701 struct bt_ctf_event *ctf_copy_event(FILE *err, struct bt_ctf_event *event,
702 struct bt_ctf_event_class *writer_event_class,
703 bool override_ts64)
704 {
705 struct bt_ctf_event *writer_event = NULL;
706 struct bt_ctf_field *field = NULL, *copy_field = NULL;
707 int ret;
708
709 writer_event = bt_ctf_event_create(writer_event_class);
710 if (!writer_event) {
711 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
712 __LINE__);
713 goto end;
714 }
715
716 field = bt_ctf_event_get_header(event);
717 if (!field) {
718 fprintf(err, "[error] %s in %s:%d\n", __func__,
719 __FILE__, __LINE__);
720 goto error;
721 }
722
723 /*
724 * If override_ts64, we override all integer fields mapped to a clock
725 * to a uint64_t field type, otherwise, we just copy it as is.
726 */
727 if (override_ts64) {
728 copy_field = bt_ctf_event_get_header(writer_event);
729 if (!copy_field) {
730 fprintf(err, "[error] %s in %s:%d\n", __func__,
731 __FILE__, __LINE__);
732 goto error;
733 }
734
735 ret = copy_override_field(err, event, writer_event, field,
736 copy_field);
737 if (ret) {
738 fprintf(err, "[error] %s in %s:%d\n", __func__,
739 __FILE__, __LINE__);
740 goto error;
741 }
742 BT_PUT(copy_field);
743 } else {
744 ret = ctf_copy_event_header(err, event, writer_event_class,
745 writer_event, field);
746 if (ret) {
747 fprintf(err, "[error] %s in %s:%d\n", __func__,
748 __FILE__, __LINE__);
749 goto error;
750 }
751 }
752 BT_PUT(field);
753
754 /* Optional field, so it can fail silently. */
755 field = bt_ctf_event_get_stream_event_context(event);
756 copy_field = bt_ctf_field_copy(field);
757 if (copy_field) {
758 ret = bt_ctf_event_set_stream_event_context(writer_event,
759 copy_field);
760 if (ret < 0) {
761 fprintf(err, "[error] %s in %s:%d\n", __func__,
762 __FILE__, __LINE__);
763 goto error;
764 }
765 }
766 BT_PUT(field);
767 BT_PUT(copy_field);
768
769 /* Optional field, so it can fail silently. */
770 field = bt_ctf_event_get_event_context(event);
771 copy_field = bt_ctf_field_copy(field);
772 if (copy_field) {
773 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
774 if (ret < 0) {
775 fprintf(err, "[error] %s in %s:%d\n", __func__,
776 __FILE__, __LINE__);
777 goto error;
778 }
779 }
780 BT_PUT(field);
781 BT_PUT(copy_field);
782
783 field = bt_ctf_event_get_event_payload(event);
784 if (!field) {
785 fprintf(err, "[error] %s in %s:%d\n", __func__,
786 __FILE__, __LINE__);
787 goto error;
788 }
789 copy_field = bt_ctf_field_copy(field);
790 if (copy_field) {
791 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
792 if (ret < 0) {
793 fprintf(err, "[error] %s in %s:%d\n", __func__,
794 __FILE__, __LINE__);
795 goto error;
796 }
797 }
798 BT_PUT(field);
799 BT_PUT(copy_field);
800
801 goto end;
802
803 error:
804 BT_PUT(writer_event);
805 end:
806 bt_put(field);
807 bt_put(copy_field);
808 return writer_event;
809 }
810
811 BT_HIDDEN
812 enum bt_component_status ctf_copy_trace(FILE *err, struct bt_ctf_trace *trace,
813 struct bt_ctf_trace *writer_trace)
814 {
815 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
816 int field_count, i, int_ret;
817 struct bt_ctf_field_type *header_type = NULL;
818 enum bt_ctf_byte_order order;
819
820 field_count = bt_ctf_trace_get_environment_field_count(trace);
821 for (i = 0; i < field_count; i++) {
822 int ret_int;
823 const char *name;
824 struct bt_value *value = NULL;
825
826 name = bt_ctf_trace_get_environment_field_name_by_index(
827 trace, i);
828 if (!name) {
829 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
830 __LINE__);
831 ret = BT_COMPONENT_STATUS_ERROR;
832 goto end;
833 }
834 value = bt_ctf_trace_get_environment_field_value_by_index(
835 trace, i);
836 if (!value) {
837 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
838 __LINE__);
839 ret = BT_COMPONENT_STATUS_ERROR;
840 goto end;
841 }
842
843 ret_int = bt_ctf_trace_set_environment_field(writer_trace,
844 name, value);
845 BT_PUT(value);
846 if (ret_int < 0) {
847 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
848 __LINE__);
849 fprintf(err, "[error] Unable to set environment field %s\n",
850 name);
851 ret = BT_COMPONENT_STATUS_ERROR;
852 goto end;
853 }
854 }
855
856 order = bt_ctf_trace_get_native_byte_order(trace);
857 if (order == BT_CTF_BYTE_ORDER_UNKNOWN) {
858 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
859 ret = BT_COMPONENT_STATUS_ERROR;
860 goto end;
861 }
862
863 /*
864 * Only explicitly set the writer trace's native byte order if
865 * the original trace has a specific one. Otherwise leave what
866 * the CTF writer object chooses, which is the machine's native
867 * byte order.
868 */
869 if (order != BT_CTF_BYTE_ORDER_NONE) {
870 ret = bt_ctf_trace_set_native_byte_order(writer_trace, order);
871 if (ret) {
872 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
873 ret = BT_COMPONENT_STATUS_ERROR;
874 goto end;
875 }
876 }
877
878 header_type = bt_ctf_trace_get_packet_header_type(writer_trace);
879 if (header_type) {
880 int_ret = bt_ctf_trace_set_packet_header_type(writer_trace, header_type);
881 BT_PUT(header_type);
882 if (int_ret < 0) {
883 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
884 ret = BT_COMPONENT_STATUS_ERROR;
885 goto end;
886 }
887 }
888
889 end:
890 return ret;
891 }
This page took 0.048686 seconds and 5 git commands to generate.