Fix copytrace: check field exists before copy
[babeltrace.git] / plugins / libctfcopytrace / ctfcopytrace.c
CommitLineData
91b73004
JD
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"
b2f1f465 40#include "clock-fields.h"
91b73004 41
9ac68eb1 42BT_HIDDEN
91b73004
JD
43struct 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);
16cd0c80
JD
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 }
91b73004
JD
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
acd6aeb1 134 int_ret = bt_ctf_clock_class_is_absolute(clock_class);
91b73004
JD
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
150end_destroy:
151 BT_PUT(writer_clock_class);
152end:
153 return writer_clock_class;
154}
155
9ac68eb1 156BT_HIDDEN
91b73004
JD
157enum 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;
91b73004
JD
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 =
9ac68eb1 170 bt_ctf_trace_get_clock_class_by_index(trace, i);
91b73004
JD
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 /*
b2f1f465 197 * Ownership transferred to the trace.
91b73004
JD
198 */
199 bt_put(writer_clock_class);
200 }
201
202 ret = BT_COMPONENT_STATUS_OK;
203
204end:
205 return ret;
206}
207
9ac68eb1 208BT_HIDDEN
91b73004
JD
209struct 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;
f87fb9b4 213 struct bt_ctf_field_type *context, *payload_type;
91b73004 214 const char *name;
279c77d0 215 int count, i, ret;
91b73004
JD
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
9ac68eb1
PP
237 attr_name = bt_ctf_event_class_get_attribute_name_by_index(
238 event_class, i);
91b73004
JD
239 if (!attr_name) {
240 fprintf(err, "[error] %s in %s:%d\n", __func__,
241 __FILE__, __LINE__);
9ae49d3d 242 goto error;
91b73004 243 }
9ac68eb1
PP
244 attr_value = bt_ctf_event_class_get_attribute_value_by_index(
245 event_class, i);
91b73004
JD
246 if (!attr_value) {
247 fprintf(err, "[error] %s in %s:%d\n", __func__,
248 __FILE__, __LINE__);
9ae49d3d 249 goto error;
91b73004
JD
250 }
251
252 ret = bt_ctf_event_class_set_attribute(writer_event_class,
253 attr_name, attr_value);
9ae49d3d 254 BT_PUT(attr_value);
91b73004
JD
255 if (ret < 0) {
256 fprintf(err, "[error] %s in %s:%d\n", __func__,
257 __FILE__, __LINE__);
9ae49d3d 258 goto error;
91b73004
JD
259 }
260 }
261
f87fb9b4
JD
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);
91b73004 266 if (ret < 0) {
f87fb9b4
JD
267 fprintf(err, "[error] %s in %s:%d\n", __func__,
268 __FILE__, __LINE__);
9ae49d3d 269 goto error;
91b73004 270 }
f87fb9b4 271 BT_PUT(payload_type);
91b73004
JD
272 }
273
279c77d0
JD
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
9ae49d3d
JD
286 goto end;
287
288error:
289 BT_PUT(writer_event_class);
91b73004
JD
290end:
291 return writer_event_class;
292}
293
9ac68eb1 294BT_HIDDEN
91b73004
JD
295enum 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;
9ae49d3d 300 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
91b73004
JD
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++) {
91b73004
JD
311 int int_ret;
312
9ac68eb1 313 event_class = bt_ctf_stream_class_get_event_class_by_index(
91b73004
JD
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;
9ae49d3d 319 goto error;
91b73004 320 }
cb0a5cf8
JD
321 if (i < bt_ctf_stream_class_get_event_class_count(writer_stream_class)) {
322 writer_event_class = bt_ctf_stream_class_get_event_class_by_index(
323 writer_stream_class, i);
324 if (writer_event_class) {
325 /*
326 * If the writer_event_class already exists,
327 * just skip it. It can be used to resync the
328 * event_classes after a trace has become
329 * static.
330 */
331 BT_PUT(writer_event_class);
332 BT_PUT(event_class);
333 continue;
334 }
335 }
336
91b73004
JD
337 writer_event_class = ctf_copy_event_class(err, event_class);
338 if (!writer_event_class) {
339 fprintf(err, "[error] %s in %s:%d\n", __func__,
340 __FILE__, __LINE__);
341 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 342 goto error;
91b73004
JD
343 }
344
91b73004
JD
345 int_ret = bt_ctf_stream_class_add_event_class(writer_stream_class,
346 writer_event_class);
347 if (int_ret < 0) {
348 fprintf(err, "[error] Failed to add event class\n");
349 fprintf(err, "[error] %s in %s:%d\n", __func__,
350 __FILE__, __LINE__);
351 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 352 goto error;
91b73004 353 }
9ae49d3d
JD
354 BT_PUT(writer_event_class);
355 BT_PUT(event_class);
91b73004
JD
356 }
357
9ae49d3d
JD
358 goto end;
359
360error:
361 bt_put(event_class);
362 bt_put(writer_event_class);
91b73004
JD
363end:
364 return ret;
365}
366
9ac68eb1 367BT_HIDDEN
91b73004 368struct bt_ctf_stream_class *ctf_copy_stream_class(FILE *err,
b2f1f465
JD
369 struct bt_ctf_stream_class *stream_class,
370 struct bt_ctf_trace *writer_trace,
371 bool override_ts64)
91b73004 372{
9ae49d3d
JD
373 struct bt_ctf_field_type *type = NULL;
374 struct bt_ctf_stream_class *writer_stream_class = NULL;
91b73004
JD
375 int ret_int;
376 const char *name = bt_ctf_stream_class_get_name(stream_class);
377
378 if (strlen(name) == 0) {
379 name = NULL;
380 }
381
382 writer_stream_class = bt_ctf_stream_class_create(name);
383 if (!writer_stream_class) {
384 fprintf(err, "[error] %s in %s:%d\n",
385 __func__, __FILE__, __LINE__);
386 goto end;
387 }
388
389 type = bt_ctf_stream_class_get_packet_context_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 ret_int = bt_ctf_stream_class_set_packet_context_type(
397 writer_stream_class, type);
91b73004
JD
398 if (ret_int < 0) {
399 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
400 __LINE__);
401 goto error;
402 }
9ae49d3d 403 BT_PUT(type);
91b73004
JD
404
405 type = bt_ctf_stream_class_get_event_header_type(stream_class);
406 if (!type) {
407 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
408 __LINE__);
409 goto error;
410 }
411
b2f1f465 412 if (override_ts64) {
9ae49d3d
JD
413 struct bt_ctf_field_type *new_event_header_type;
414
b2f1f465
JD
415 new_event_header_type = override_header_type(err, type,
416 writer_trace);
b2f1f465
JD
417 if (!new_event_header_type) {
418 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
419 __LINE__);
420 goto error;
421 }
0f29db56
JD
422 ret_int = bt_ctf_stream_class_set_event_header_type(
423 writer_stream_class, new_event_header_type);
9ae49d3d 424 BT_PUT(new_event_header_type);
0f29db56
JD
425 if (ret_int < 0) {
426 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
427 __LINE__);
428 goto error;
429 }
b2f1f465 430 } else {
0f29db56
JD
431 ret_int = bt_ctf_stream_class_set_event_header_type(
432 writer_stream_class, type);
0f29db56
JD
433 if (ret_int < 0) {
434 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
435 __LINE__);
436 goto error;
437 }
91b73004 438 }
9ae49d3d 439 BT_PUT(type);
91b73004
JD
440
441 type = bt_ctf_stream_class_get_event_context_type(stream_class);
442 if (type) {
443 ret_int = bt_ctf_stream_class_set_event_context_type(
444 writer_stream_class, type);
91b73004
JD
445 if (ret_int < 0) {
446 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
447 __LINE__);
448 goto error;
449 }
450 }
9ae49d3d 451 BT_PUT(type);
91b73004
JD
452
453 goto end;
454
455error:
456 BT_PUT(writer_stream_class);
457end:
9ae49d3d 458 bt_put(type);
91b73004
JD
459 return writer_stream_class;
460}
461
9ac68eb1 462BT_HIDDEN
91b73004
JD
463enum bt_component_status ctf_copy_packet_context_field(FILE *err,
464 struct bt_ctf_field *field, const char *field_name,
465 struct bt_ctf_field *writer_packet_context,
466 struct bt_ctf_field_type *writer_packet_context_type)
467{
468 enum bt_component_status ret;
9ae49d3d
JD
469 struct bt_ctf_field *writer_field = NULL;
470 struct bt_ctf_field_type *field_type = NULL;
91b73004
JD
471 int int_ret;
472 uint64_t value;
473
474 field_type = bt_ctf_field_get_type(field);
475 if (!field_type) {
476 ret = BT_COMPONENT_STATUS_ERROR;
477 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
478 __LINE__);
479 goto end;
480 }
481 /*
482 * Only support for integers for now.
483 */
1487a16a 484 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
91b73004 485 fprintf(err, "[error] Unsupported packet context field type\n");
91b73004 486 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 487 goto error;
91b73004 488 }
9ae49d3d 489 BT_PUT(field_type);
91b73004 490
9ac68eb1
PP
491 writer_field = bt_ctf_field_structure_get_field_by_name(
492 writer_packet_context, field_name);
91b73004
JD
493 if (!writer_field) {
494 ret = BT_COMPONENT_STATUS_ERROR;
495 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
496 __LINE__);
497 goto end;
498 }
499
91b73004
JD
500 int_ret = bt_ctf_field_unsigned_integer_get_value(field, &value);
501 if (int_ret < 0) {
502 fprintf(err, "[error] Wrong packet_context field type\n");
503 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
504 __LINE__);
505 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 506 goto end;
91b73004
JD
507 }
508
509 int_ret = bt_ctf_field_unsigned_integer_set_value(writer_field, value);
510 if (int_ret < 0) {
511 ret = BT_COMPONENT_STATUS_ERROR;
512 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
513 __LINE__);
9ae49d3d 514 goto end;
91b73004
JD
515 }
516
517 ret = BT_COMPONENT_STATUS_OK;
518
9ae49d3d
JD
519 goto end;
520
521error:
522 bt_put(field_type);
91b73004 523end:
9ae49d3d 524 bt_put(writer_field);
91b73004
JD
525 return ret;
526}
527
9ac68eb1 528BT_HIDDEN
b2f1f465 529struct bt_ctf_field *ctf_copy_packet_context(FILE *err,
91b73004 530 struct bt_ctf_packet *packet,
79697a58 531 struct bt_ctf_stream *writer_stream)
91b73004
JD
532{
533 enum bt_component_status ret;
9ae49d3d
JD
534 struct bt_ctf_field *packet_context = NULL, *writer_packet_context = NULL;
535 struct bt_ctf_field_type *struct_type = NULL, *writer_packet_context_type = NULL;
536 struct bt_ctf_stream_class *writer_stream_class = NULL;
f6f999a3 537 struct bt_ctf_field *field = NULL;
9571c709 538 struct bt_ctf_field_type *field_type = NULL;
b2f1f465 539 int nr_fields, i;
91b73004
JD
540
541 packet_context = bt_ctf_packet_get_context(packet);
542 if (!packet_context) {
60ef553b 543 goto end;
91b73004
JD
544 }
545
546 writer_stream_class = bt_ctf_stream_get_class(writer_stream);
547 if (!writer_stream_class) {
91b73004
JD
548 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
549 __LINE__);
9ae49d3d 550 goto error;
91b73004
JD
551 }
552
553 writer_packet_context_type = bt_ctf_stream_class_get_packet_context_type(
554 writer_stream_class);
9ae49d3d 555 BT_PUT(writer_stream_class);
91b73004 556 if (!writer_packet_context_type) {
91b73004
JD
557 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
558 __LINE__);
9ae49d3d 559 goto error;
91b73004
JD
560 }
561
562 struct_type = bt_ctf_field_get_type(packet_context);
563 if (!struct_type) {
91b73004
JD
564 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
565 __LINE__);
9ae49d3d 566 goto error;
91b73004
JD
567 }
568
569 writer_packet_context = bt_ctf_field_create(writer_packet_context_type);
570 if (!writer_packet_context) {
91b73004
JD
571 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
572 __LINE__);
9ae49d3d 573 goto error;
91b73004
JD
574 }
575
576 nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
577 for (i = 0; i < nr_fields; i++) {
91b73004
JD
578 const char *field_name;
579
0f29db56 580 field = bt_ctf_field_structure_get_field_by_index(
91b73004
JD
581 packet_context, i);
582 if (!field) {
91b73004
JD
583 fprintf(err, "[error] %s in %s:%d\n", __func__,
584 __FILE__, __LINE__);
9ae49d3d 585 goto error;
91b73004 586 }
9ac68eb1 587 if (bt_ctf_field_type_structure_get_field_by_index(struct_type,
91b73004 588 &field_name, &field_type, i) < 0) {
91b73004
JD
589 fprintf(err, "[error] %s in %s:%d\n", __func__,
590 __FILE__, __LINE__);
9ae49d3d 591 goto error;
91b73004 592 }
91b73004 593
1487a16a 594 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
91b73004 595 fprintf(err, "[error] Unexpected packet context field type\n");
9ae49d3d 596 goto error;
91b73004
JD
597 }
598
599 ret = ctf_copy_packet_context_field(err, field, field_name,
600 writer_packet_context, writer_packet_context_type);
9ae49d3d
JD
601 BT_PUT(field_type);
602 BT_PUT(field);
91b73004
JD
603 if (ret != BT_COMPONENT_STATUS_OK) {
604 fprintf(err, "[error] %s in %s:%d\n", __func__,
605 __FILE__, __LINE__);
9ae49d3d 606 goto error;
91b73004
JD
607 }
608 }
609
9ae49d3d
JD
610 goto end;
611
612error:
613 BT_PUT(writer_packet_context);
614end:
615 bt_put(field);
616 bt_put(field_type);
91b73004 617 bt_put(struct_type);
91b73004 618 bt_put(writer_packet_context_type);
91b73004 619 bt_put(writer_stream_class);
91b73004 620 bt_put(packet_context);
b2f1f465
JD
621 return writer_packet_context;
622}
623
9ac68eb1 624BT_HIDDEN
0f29db56 625int ctf_copy_event_header(FILE *err, struct bt_ctf_event *event,
b2f1f465
JD
626 struct bt_ctf_event_class *writer_event_class,
627 struct bt_ctf_event *writer_event,
628 struct bt_ctf_field *event_header)
629{
9ae49d3d
JD
630 struct bt_ctf_clock_class *clock_class = NULL, *writer_clock_class = NULL;
631 struct bt_ctf_clock_value *clock_value = NULL, *writer_clock_value = NULL;
b2f1f465
JD
632
633 int ret;
0f29db56
JD
634 struct bt_ctf_field *writer_event_header = NULL;
635 uint64_t value;
b2f1f465 636
0f29db56
JD
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);
9ae49d3d 645 BT_PUT(clock_class);
0f29db56
JD
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);
9ae49d3d 653 BT_PUT(clock_value);
0f29db56
JD
654 if (ret) {
655 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
656 __LINE__);
657 goto error;
b2f1f465
JD
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
0f29db56 667 writer_clock_value = bt_ctf_clock_value_create(writer_clock_class, value);
9ae49d3d 668 BT_PUT(writer_clock_class);
0f29db56 669 if (!writer_clock_value) {
b2f1f465
JD
670 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
671 __LINE__);
9ae49d3d 672 goto error;
b2f1f465
JD
673 }
674
0f29db56 675 ret = bt_ctf_event_set_clock_value(writer_event, writer_clock_value);
9ae49d3d 676 BT_PUT(writer_clock_value);
b2f1f465
JD
677 if (ret) {
678 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
679 __LINE__);
680 goto error;
681 }
682
0f29db56
JD
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__);
0f29db56
JD
687 goto end;
688 }
689
b2f1f465 690 ret = bt_ctf_event_set_header(writer_event, writer_event_header);
9ae49d3d 691 BT_PUT(writer_event_header);
b2f1f465
JD
692 if (ret < 0) {
693 fprintf(err, "[error] %s in %s:%d\n", __func__,
694 __FILE__, __LINE__);
695 goto error;
696 }
b2f1f465
JD
697
698 ret = 0;
699
700 goto end;
701
702error:
b2f1f465 703 ret = -1;
91b73004
JD
704end:
705 return ret;
706}
707
9ac68eb1 708BT_HIDDEN
91b73004 709struct bt_ctf_event *ctf_copy_event(FILE *err, struct bt_ctf_event *event,
b2f1f465
JD
710 struct bt_ctf_event_class *writer_event_class,
711 bool override_ts64)
91b73004 712{
9ae49d3d
JD
713 struct bt_ctf_event *writer_event = NULL;
714 struct bt_ctf_field *field = NULL, *copy_field = NULL;
91b73004
JD
715 int ret;
716
717 writer_event = bt_ctf_event_create(writer_event_class);
718 if (!writer_event) {
719 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
720 __LINE__);
721 goto end;
722 }
723
724 field = bt_ctf_event_get_header(event);
725 if (!field) {
91b73004
JD
726 fprintf(err, "[error] %s in %s:%d\n", __func__,
727 __FILE__, __LINE__);
9ae49d3d 728 goto error;
91b73004
JD
729 }
730
b2f1f465
JD
731 /*
732 * If override_ts64, we override all integer fields mapped to a clock
733 * to a uint64_t field type, otherwise, we just copy it as is.
734 */
735 if (override_ts64) {
736 copy_field = bt_ctf_event_get_header(writer_event);
737 if (!copy_field) {
91b73004
JD
738 fprintf(err, "[error] %s in %s:%d\n", __func__,
739 __FILE__, __LINE__);
9ae49d3d 740 goto error;
b2f1f465
JD
741 }
742
743 ret = copy_override_field(err, event, writer_event, field,
744 copy_field);
b2f1f465 745 if (ret) {
b2f1f465
JD
746 fprintf(err, "[error] %s in %s:%d\n", __func__,
747 __FILE__, __LINE__);
9ae49d3d 748 goto error;
b2f1f465 749 }
9ae49d3d 750 BT_PUT(copy_field);
b2f1f465 751 } else {
0f29db56 752 ret = ctf_copy_event_header(err, event, writer_event_class,
b2f1f465
JD
753 writer_event, field);
754 if (ret) {
b2f1f465
JD
755 fprintf(err, "[error] %s in %s:%d\n", __func__,
756 __FILE__, __LINE__);
9ae49d3d 757 goto error;
91b73004 758 }
91b73004 759 }
9ae49d3d 760 BT_PUT(field);
91b73004
JD
761
762 /* Optional field, so it can fail silently. */
763 field = bt_ctf_event_get_stream_event_context(event);
961ec227
JD
764 if (field) {
765 copy_field = bt_ctf_field_copy(field);
766 if (!copy_field) {
767 fprintf(err, "[error] %s in %s:%d\n", __func__,
768 __FILE__, __LINE__);
769 goto error;
770 }
91b73004
JD
771 ret = bt_ctf_event_set_stream_event_context(writer_event,
772 copy_field);
91b73004
JD
773 if (ret < 0) {
774 fprintf(err, "[error] %s in %s:%d\n", __func__,
775 __FILE__, __LINE__);
776 goto error;
777 }
961ec227
JD
778 BT_PUT(field);
779 BT_PUT(copy_field);
91b73004
JD
780 }
781
782 /* Optional field, so it can fail silently. */
783 field = bt_ctf_event_get_event_context(event);
961ec227
JD
784 if (field) {
785 copy_field = bt_ctf_field_copy(field);
786 if (!copy_field) {
787 fprintf(err, "[error] %s in %s:%d\n", __func__,
788 __FILE__, __LINE__);
789 goto error;
790 }
91b73004 791 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
91b73004
JD
792 if (ret < 0) {
793 fprintf(err, "[error] %s in %s:%d\n", __func__,
794 __FILE__, __LINE__);
795 goto error;
796 }
961ec227
JD
797 BT_PUT(field);
798 BT_PUT(copy_field);
91b73004
JD
799 }
800
9ac68eb1 801 field = bt_ctf_event_get_event_payload(event);
961ec227
JD
802 if (field) {
803 copy_field = bt_ctf_field_copy(field);
804 if (!copy_field) {
805 fprintf(err, "[error] %s in %s:%d\n", __func__,
806 __FILE__, __LINE__);
807 goto error;
808 }
9ac68eb1 809 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
91b73004
JD
810 if (ret < 0) {
811 fprintf(err, "[error] %s in %s:%d\n", __func__,
812 __FILE__, __LINE__);
813 goto error;
814 }
961ec227
JD
815 BT_PUT(field);
816 BT_PUT(copy_field);
91b73004 817 }
9ae49d3d 818
91b73004
JD
819 goto end;
820
821error:
822 BT_PUT(writer_event);
823end:
9ae49d3d
JD
824 bt_put(field);
825 bt_put(copy_field);
91b73004
JD
826 return writer_event;
827}
828
9ac68eb1 829BT_HIDDEN
91b73004
JD
830enum 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;
9ae49d3d 835 struct bt_ctf_field_type *header_type = NULL;
6468dbd6 836 enum bt_ctf_byte_order order;
0ac862b4 837 const char *trace_name;
91b73004
JD
838
839 field_count = bt_ctf_trace_get_environment_field_count(trace);
840 for (i = 0; i < field_count; i++) {
841 int ret_int;
842 const char *name;
9ae49d3d 843 struct bt_value *value = NULL;
91b73004 844
9ac68eb1
PP
845 name = bt_ctf_trace_get_environment_field_name_by_index(
846 trace, i);
91b73004
JD
847 if (!name) {
848 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
849 __LINE__);
850 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 851 goto end;
91b73004 852 }
9ac68eb1
PP
853 value = bt_ctf_trace_get_environment_field_value_by_index(
854 trace, i);
91b73004
JD
855 if (!value) {
856 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
857 __LINE__);
858 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 859 goto end;
91b73004
JD
860 }
861
862 ret_int = bt_ctf_trace_set_environment_field(writer_trace,
863 name, value);
9ae49d3d 864 BT_PUT(value);
91b73004
JD
865 if (ret_int < 0) {
866 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
867 __LINE__);
868 fprintf(err, "[error] Unable to set environment field %s\n",
869 name);
870 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 871 goto end;
91b73004
JD
872 }
873 }
874
6468dbd6
JD
875 order = bt_ctf_trace_get_native_byte_order(trace);
876 if (order == BT_CTF_BYTE_ORDER_UNKNOWN) {
877 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
878 ret = BT_COMPONENT_STATUS_ERROR;
879 goto end;
880 }
881
d41cff38
PP
882 /*
883 * Only explicitly set the writer trace's native byte order if
884 * the original trace has a specific one. Otherwise leave what
885 * the CTF writer object chooses, which is the machine's native
886 * byte order.
887 */
888 if (order != BT_CTF_BYTE_ORDER_NONE) {
889 ret = bt_ctf_trace_set_native_byte_order(writer_trace, order);
890 if (ret) {
891 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
892 ret = BT_COMPONENT_STATUS_ERROR;
893 goto end;
894 }
6468dbd6
JD
895 }
896
91b73004 897 header_type = bt_ctf_trace_get_packet_header_type(writer_trace);
944eed39
JD
898 if (header_type) {
899 int_ret = bt_ctf_trace_set_packet_header_type(writer_trace, header_type);
900 BT_PUT(header_type);
901 if (int_ret < 0) {
902 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
903 ret = BT_COMPONENT_STATUS_ERROR;
904 goto end;
905 }
91b73004
JD
906 }
907
0ac862b4
JD
908 trace_name = bt_ctf_trace_get_name(trace);
909 if (trace_name) {
910 int_ret = bt_ctf_trace_set_name(writer_trace, trace_name);
911 if (int_ret < 0) {
912 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
913 ret = BT_COMPONENT_STATUS_ERROR;
914 goto end;
915 }
916 }
917
9ae49d3d 918end:
91b73004
JD
919 return ret;
920}
This page took 0.067535 seconds and 4 git commands to generate.