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