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