lib: replace trace is_static with destruction listeners
[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
0f60f957
JD
29#define BT_LOG_TAG "PLUGIN-CTFCOPYTRACE-LIB"
30#include "logging.h"
31
e0831b38 32#include <babeltrace/babeltrace.h>
8b45963b 33#include <babeltrace/assert-internal.h>
91b73004
JD
34
35#include "ctfcopytrace.h"
0f15f666 36#include "clock-field.h"
91b73004 37
9ac68eb1 38BT_HIDDEN
8eee8ea2
PP
39const bt_clock_class *ctf_copy_clock_class(FILE *err,
40 const bt_clock_class *clock_class)
91b73004
JD
41{
42 int64_t offset, offset_s;
43 int int_ret;
44 uint64_t u64_ret;
45 const char *name, *description;
8eee8ea2 46 const bt_clock_class *writer_clock_class = NULL;
91b73004 47
8b45963b 48 BT_ASSERT(err && clock_class);
91b73004 49
839d52a5 50 name = bt_clock_class_get_name(clock_class);
8b45963b 51 BT_ASSERT(name);
91b73004 52
839d52a5
PP
53 writer_clock_class = bt_clock_class_create(name,
54 bt_clock_class_get_frequency(clock_class));
91b73004 55 if (!writer_clock_class) {
0f60f957 56 BT_LOGE_STR("Failed to create clock class.");
91b73004
JD
57 goto end;
58 }
59
839d52a5 60 description = bt_clock_class_get_description(clock_class);
16cd0c80 61 if (description) {
839d52a5 62 int_ret = bt_clock_class_set_description(writer_clock_class,
16cd0c80 63 description);
8b45963b 64 BT_ASSERT(!int_ret);
91b73004
JD
65 }
66
839d52a5 67 u64_ret = bt_clock_class_get_precision(clock_class);
8b45963b 68 BT_ASSERT(u64_ret != -1ULL);
0f60f957 69
839d52a5 70 int_ret = bt_clock_class_set_precision(writer_clock_class,
91b73004 71 u64_ret);
8b45963b 72 BT_ASSERT(!int_ret);
91b73004 73
839d52a5 74 int_ret = bt_clock_class_get_offset_s(clock_class, &offset_s);
8b45963b 75 BT_ASSERT(!int_ret);
91b73004 76
839d52a5 77 int_ret = bt_clock_class_set_offset_s(writer_clock_class, offset_s);
8b45963b 78 BT_ASSERT(!int_ret);
91b73004 79
839d52a5 80 int_ret = bt_clock_class_get_offset_cycles(clock_class, &offset);
8b45963b 81 BT_ASSERT(!int_ret);
91b73004 82
839d52a5 83 int_ret = bt_clock_class_set_offset_cycles(writer_clock_class, offset);
8b45963b 84 BT_ASSERT(!int_ret);
91b73004 85
d608d675 86 int_ret = bt_clock_class_origin_is_unix_epoch(clock_class);
8b45963b 87 BT_ASSERT(int_ret >= 0);
91b73004 88
d608d675 89 int_ret = bt_clock_class_set_origin_is_unix_epoch(writer_clock_class, int_ret);
8b45963b 90 BT_ASSERT(!int_ret);
91b73004 91
91b73004
JD
92end:
93 return writer_clock_class;
94}
95
9ac68eb1 96BT_HIDDEN
ee78f405 97bt_component_status ctf_copy_clock_classes(FILE *err,
8eee8ea2
PP
98 const bt_trace *writer_trace,
99 const bt_stream_class *writer_stream_class,
100 const bt_trace *trace)
91b73004 101{
ee78f405 102 bt_component_status ret;
91b73004
JD
103 int int_ret, clock_class_count, i;
104
839d52a5 105 clock_class_count = bt_trace_get_clock_class_count(trace);
91b73004
JD
106
107 for (i = 0; i < clock_class_count; i++) {
8eee8ea2
PP
108 const bt_clock_class *writer_clock_class;
109 const bt_clock_class *clock_class =
839d52a5 110 bt_trace_get_clock_class_by_index(trace, i);
91b73004 111
8b45963b 112 BT_ASSERT(clock_class);
91b73004
JD
113
114 writer_clock_class = ctf_copy_clock_class(err, clock_class);
8c6884d9 115 bt_clock_class_put_ref(clock_class);
91b73004 116 if (!writer_clock_class) {
0f60f957 117 BT_LOGE_STR("Failed to copy clock class.");
91b73004
JD
118 ret = BT_COMPONENT_STATUS_ERROR;
119 goto end;
120 }
121
839d52a5 122 int_ret = bt_trace_add_clock_class(writer_trace, writer_clock_class);
91b73004 123 if (int_ret != 0) {
8c6884d9 124 BT_CLOCK_CLASS_PUT_REF_AND_RESET(writer_clock_class);
0f60f957 125 BT_LOGE_STR("Failed to add clock class.");
91b73004
JD
126 ret = BT_COMPONENT_STATUS_ERROR;
127 goto end;
128 }
129
130 /*
b2f1f465 131 * Ownership transferred to the trace.
91b73004 132 */
8c6884d9 133 bt_clock_class_put_ref(writer_clock_class);
91b73004
JD
134 }
135
136 ret = BT_COMPONENT_STATUS_OK;
137
138end:
139 return ret;
140}
141
59d1efc4 142static
8eee8ea2
PP
143void replace_clock_classes(const bt_trace *trace_copy,
144 bt_field_type *field_type)
59d1efc4
PP
145{
146 int ret;
147
8b45963b
PP
148 BT_ASSERT(trace_copy);
149 BT_ASSERT(field_type);
59d1efc4
PP
150
151 switch (bt_field_type_get_type_id(field_type)) {
152 case BT_FIELD_TYPE_ID_INTEGER:
153 {
8eee8ea2 154 const bt_clock_class *mapped_clock_class =
59d1efc4 155 bt_field_type_integer_get_mapped_clock_class(field_type);
8eee8ea2 156 const bt_clock_class *clock_class_copy = NULL;
59d1efc4
PP
157 const char *name;
158
159 if (!mapped_clock_class) {
160 break;
161 }
162
163 name = bt_clock_class_get_name(mapped_clock_class);
8b45963b 164 BT_ASSERT(name);
59d1efc4
PP
165 clock_class_copy = bt_trace_get_clock_class_by_name(
166 trace_copy, name);
8b45963b 167 BT_ASSERT(clock_class_copy);
59d1efc4
PP
168 ret = bt_field_type_integer_set_mapped_clock_class(
169 field_type, clock_class_copy);
8b45963b 170 BT_ASSERT(ret == 0);
8c6884d9
PP
171 bt_clock_class_put_ref(mapped_clock_class);
172 bt_clock_class_put_ref(clock_class_copy);
59d1efc4
PP
173 break;
174 }
175 case BT_FIELD_TYPE_ID_ENUM:
176 case BT_FIELD_TYPE_ID_ARRAY:
177 case BT_FIELD_TYPE_ID_SEQUENCE:
178 {
8eee8ea2 179 bt_field_type *subtype = NULL;
59d1efc4
PP
180
181 switch (bt_field_type_get_type_id(field_type)) {
182 case BT_FIELD_TYPE_ID_ENUM:
183 subtype = bt_field_type_enumeration_get_container_type(
184 field_type);
185 break;
186 case BT_FIELD_TYPE_ID_ARRAY:
187 subtype = bt_field_type_array_get_element_type(
188 field_type);
189 break;
190 case BT_FIELD_TYPE_ID_SEQUENCE:
191 subtype = bt_field_type_sequence_get_element_type(
192 field_type);
193 break;
194 default:
195 BT_LOGF("Unexpected field type ID: id=%d",
196 bt_field_type_get_type_id(field_type));
197 abort();
198 }
199
8b45963b 200 BT_ASSERT(subtype);
59d1efc4 201 replace_clock_classes(trace_copy, subtype);
8138bfe1 202 bt_object_put_ref(subtype);
59d1efc4
PP
203 break;
204 }
205 case BT_FIELD_TYPE_ID_STRUCT:
206 {
207 uint64_t i;
208 int64_t count = bt_field_type_structure_get_field_count(
209 field_type);
210
211 for (i = 0; i < count; i++) {
212 const char *name;
8eee8ea2 213 bt_field_type *member_type;
59d1efc4
PP
214
215 ret = bt_field_type_structure_get_field_by_index(
216 field_type, &name, &member_type, i);
8b45963b 217 BT_ASSERT(ret == 0);
59d1efc4 218 replace_clock_classes(trace_copy, member_type);
8138bfe1 219 bt_object_put_ref(member_type);
59d1efc4
PP
220 }
221
222 break;
223 }
224 case BT_FIELD_TYPE_ID_VARIANT:
225 {
226 uint64_t i;
227 int64_t count = bt_field_type_variant_get_field_count(
228 field_type);
229
230 for (i = 0; i < count; i++) {
231 const char *name;
8eee8ea2 232 bt_field_type *member_type;
59d1efc4
PP
233
234 ret = bt_field_type_variant_get_field_by_index(
235 field_type, &name, &member_type, i);
8b45963b 236 BT_ASSERT(ret == 0);
59d1efc4 237 replace_clock_classes(trace_copy, member_type);
8138bfe1 238 bt_object_put_ref(member_type);
59d1efc4
PP
239 }
240
241 break;
242 }
243 default:
244 break;
245 }
246}
247
9ac68eb1 248BT_HIDDEN
8eee8ea2
PP
249const bt_event_class *ctf_copy_event_class(FILE *err,
250 const bt_trace *trace_copy,
251 const bt_event_class *event_class)
91b73004 252{
8eee8ea2
PP
253 const bt_event_class *writer_event_class = NULL;
254 bt_field_type *context = NULL, *payload_type = NULL;
91b73004 255 const char *name;
9cf5d083
PP
256 int ret;
257 int64_t id;
ee78f405 258 bt_event_class_log_level log_level;
9cf5d083 259 const char *emf_uri;
91b73004 260
839d52a5 261 name = bt_event_class_get_name(event_class);
91b73004 262
78cf9df6 263 writer_event_class = bt_event_class_create(name);
8b45963b 264 BT_ASSERT(writer_event_class);
91b73004 265
839d52a5 266 id = bt_event_class_get_id(event_class);
8b45963b 267 BT_ASSERT(id >= 0);
91b73004 268
839d52a5 269 ret = bt_event_class_set_id(writer_event_class, id);
9cf5d083 270 if (ret) {
0f60f957 271 BT_LOGE_STR("Failed to set event_class id.");
9cf5d083
PP
272 goto error;
273 }
91b73004 274
839d52a5 275 log_level = bt_event_class_get_log_level(event_class);
9cf5d083 276 if (log_level < 0) {
0f60f957 277 BT_LOGE_STR("Failed to get log_level.");
9cf5d083
PP
278 goto error;
279 }
280
78cf9df6 281 ret = bt_event_class_set_log_level(writer_event_class, log_level);
9cf5d083 282 if (ret) {
0f60f957 283 BT_LOGE_STR("Failed to set log_level.");
9cf5d083
PP
284 goto error;
285 }
286
839d52a5 287 emf_uri = bt_event_class_get_emf_uri(event_class);
9cf5d083 288 if (emf_uri) {
78cf9df6 289 ret = bt_event_class_set_emf_uri(writer_event_class,
9cf5d083
PP
290 emf_uri);
291 if (ret) {
0f60f957 292 BT_LOGE_STR("Failed to set emf uri.");
9ae49d3d 293 goto error;
91b73004
JD
294 }
295 }
296
839d52a5 297 payload_type = bt_event_class_get_payload_type(event_class);
f87fb9b4 298 if (payload_type) {
8eee8ea2 299 bt_field_type *ft_copy =
59d1efc4
PP
300 bt_field_type_copy(payload_type);
301
302 if (!ft_copy) {
303 BT_LOGE_STR("Cannot copy payload field type.");
304 }
305
306 replace_clock_classes(trace_copy, ft_copy);
839d52a5 307 ret = bt_event_class_set_payload_type(writer_event_class,
59d1efc4 308 ft_copy);
8138bfe1 309 bt_object_put_ref(ft_copy);
91b73004 310 if (ret < 0) {
0f60f957 311 BT_LOGE_STR("Failed to set payload type.");
9ae49d3d 312 goto error;
91b73004 313 }
91b73004
JD
314 }
315
839d52a5 316 context = bt_event_class_get_context_type(event_class);
279c77d0 317 if (context) {
8eee8ea2 318 bt_field_type *ft_copy =
59d1efc4
PP
319 bt_field_type_copy(context);
320
321 if (!ft_copy) {
322 BT_LOGE_STR("Cannot copy context field type.");
323 }
324
839d52a5 325 ret = bt_event_class_set_context_type(
59d1efc4 326 writer_event_class, ft_copy);
8138bfe1 327 bt_object_put_ref(ft_copy);
279c77d0 328 if (ret < 0) {
0f60f957 329 BT_LOGE_STR("Failed to set context type.");
279c77d0
JD
330 goto error;
331 }
332 }
333
9ae49d3d
JD
334 goto end;
335
336error:
8c6884d9 337 BT_EVENT_CLASS_PUT_REF_AND_RESET(writer_event_class);
91b73004 338end:
8138bfe1
PP
339 BT_OBJECT_PUT_REF_AND_RESET(context);
340 BT_OBJECT_PUT_REF_AND_RESET(payload_type);
91b73004
JD
341 return writer_event_class;
342}
343
9ac68eb1 344BT_HIDDEN
ee78f405 345bt_component_status ctf_copy_event_classes(FILE *err,
8eee8ea2
PP
346 const bt_stream_class *stream_class,
347 const bt_stream_class *writer_stream_class)
91b73004 348{
ee78f405 349 bt_component_status ret = BT_COMPONENT_STATUS_OK;
8eee8ea2 350 const bt_event_class *event_class = NULL, *writer_event_class = NULL;
91b73004 351 int count, i;
8eee8ea2 352 const bt_trace *writer_trace =
59d1efc4 353 bt_stream_class_get_trace(writer_stream_class);
91b73004 354
8b45963b 355 BT_ASSERT(writer_trace);
839d52a5 356 count = bt_stream_class_get_event_class_count(stream_class);
8b45963b 357 BT_ASSERT(count >= 0);
91b73004
JD
358
359 for (i = 0; i < count; i++) {
91b73004
JD
360 int int_ret;
361
839d52a5 362 event_class = bt_stream_class_get_event_class_by_index(
91b73004 363 stream_class, i);
8b45963b 364 BT_ASSERT(event_class);
0f60f957 365
839d52a5
PP
366 if (i < bt_stream_class_get_event_class_count(writer_stream_class)) {
367 writer_event_class = bt_stream_class_get_event_class_by_index(
cb0a5cf8
JD
368 writer_stream_class, i);
369 if (writer_event_class) {
370 /*
371 * If the writer_event_class already exists,
372 * just skip it. It can be used to resync the
373 * event_classes after a trace has become
374 * static.
375 */
8c6884d9
PP
376 BT_EVENT_CLASS_PUT_REF_AND_RESET(writer_event_class);
377 BT_EVENT_CLASS_PUT_REF_AND_RESET(event_class);
cb0a5cf8
JD
378 continue;
379 }
380 }
381
59d1efc4
PP
382 writer_event_class = ctf_copy_event_class(err, writer_trace,
383 event_class);
91b73004 384 if (!writer_event_class) {
0f60f957 385 BT_LOGE_STR("Failed to copy event_class.");
91b73004 386 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 387 goto error;
91b73004
JD
388 }
389
839d52a5 390 int_ret = bt_stream_class_add_event_class(writer_stream_class,
91b73004
JD
391 writer_event_class);
392 if (int_ret < 0) {
0f60f957 393 BT_LOGE_STR("Failed to add event class.");
91b73004 394 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 395 goto error;
91b73004 396 }
8c6884d9
PP
397 BT_EVENT_CLASS_PUT_REF_AND_RESET(writer_event_class);
398 BT_EVENT_CLASS_PUT_REF_AND_RESET(event_class);
91b73004
JD
399 }
400
9ae49d3d
JD
401 goto end;
402
403error:
8c6884d9
PP
404 bt_event_class_put_ref(event_class);
405 bt_event_class_put_ref(writer_event_class);
91b73004 406end:
8c6884d9 407 bt_trace_put_ref(writer_trace);
91b73004
JD
408 return ret;
409}
410
9ac68eb1 411BT_HIDDEN
8eee8ea2
PP
412const bt_stream_class *ctf_copy_stream_class(FILE *err,
413 const bt_stream_class *stream_class,
414 const bt_trace *writer_trace,
b2f1f465 415 bool override_ts64)
91b73004 416{
8eee8ea2
PP
417 bt_field_type *type = NULL;
418 bt_field_type *type_copy = NULL;
419 const bt_stream_class *writer_stream_class = NULL;
91b73004 420 int ret_int;
839d52a5 421 const char *name = bt_stream_class_get_name(stream_class);
91b73004 422
839d52a5 423 writer_stream_class = bt_stream_class_create_empty(name);
8b45963b 424 BT_ASSERT(writer_stream_class);
91b73004 425
839d52a5 426 type = bt_stream_class_get_packet_context_type(stream_class);
2ca6de5c 427 if (type) {
59d1efc4
PP
428 type_copy = bt_field_type_copy(type);
429 if (!type_copy) {
430 BT_LOGE_STR("Cannot copy packet context field type.");
431 }
432
433 replace_clock_classes(writer_trace, type_copy);
839d52a5 434 ret_int = bt_stream_class_set_packet_context_type(
59d1efc4 435 writer_stream_class, type_copy);
8138bfe1 436 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
2ca6de5c 437 if (ret_int < 0) {
0f60f957 438 BT_LOGE_STR("Failed to set packet_context type.");
2ca6de5c
JD
439 goto error;
440 }
8138bfe1 441 BT_OBJECT_PUT_REF_AND_RESET(type);
91b73004
JD
442 }
443
839d52a5 444 type = bt_stream_class_get_event_header_type(stream_class);
93872409 445 if (type) {
59d1efc4
PP
446 type_copy = bt_field_type_copy(type);
447 if (!type_copy) {
448 BT_LOGE_STR("Cannot copy event header field type.");
449 }
450
839d52a5 451 ret_int = bt_trace_get_clock_class_count(writer_trace);
8b45963b 452 BT_ASSERT(ret_int >= 0);
5171f417 453 if (override_ts64 && ret_int > 0) {
8eee8ea2 454 bt_field_type *new_event_header_type;
93872409 455
59d1efc4 456 new_event_header_type = override_header_type(err, type_copy,
93872409
JD
457 writer_trace);
458 if (!new_event_header_type) {
0f60f957 459 BT_LOGE_STR("Failed to override header type.");
93872409
JD
460 goto error;
461 }
59d1efc4 462 replace_clock_classes(writer_trace, type_copy);
839d52a5 463 ret_int = bt_stream_class_set_event_header_type(
93872409 464 writer_stream_class, new_event_header_type);
8138bfe1
PP
465 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
466 BT_OBJECT_PUT_REF_AND_RESET(new_event_header_type);
93872409 467 if (ret_int < 0) {
0f60f957 468 BT_LOGE_STR("Failed to set event_header type.");
93872409
JD
469 goto error;
470 }
471 } else {
59d1efc4 472 replace_clock_classes(writer_trace, type_copy);
839d52a5 473 ret_int = bt_stream_class_set_event_header_type(
59d1efc4 474 writer_stream_class, type_copy);
8138bfe1 475 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
93872409 476 if (ret_int < 0) {
0f60f957 477 BT_LOGE_STR("Failed to set event_header type.");
93872409
JD
478 goto error;
479 }
0f29db56 480 }
8138bfe1 481 BT_OBJECT_PUT_REF_AND_RESET(type);
91b73004
JD
482 }
483
839d52a5 484 type = bt_stream_class_get_event_context_type(stream_class);
91b73004 485 if (type) {
59d1efc4
PP
486 type_copy = bt_field_type_copy(type);
487 if (!type_copy) {
488 BT_LOGE_STR("Cannot copy event context field type.");
489 }
490
491 replace_clock_classes(writer_trace, type_copy);
839d52a5 492 ret_int = bt_stream_class_set_event_context_type(
59d1efc4 493 writer_stream_class, type_copy);
8138bfe1 494 BT_OBJECT_PUT_REF_AND_RESET(type_copy);
91b73004 495 if (ret_int < 0) {
0f60f957 496 BT_LOGE_STR("Failed to set event_contexttype.");
91b73004
JD
497 goto error;
498 }
499 }
8138bfe1 500 BT_OBJECT_PUT_REF_AND_RESET(type);
91b73004
JD
501
502 goto end;
503
504error:
8c6884d9 505 BT_STREAM_CLASS_PUT_REF_AND_RESET(writer_stream_class);
91b73004 506end:
8138bfe1
PP
507 bt_object_put_ref(type);
508 bt_object_put_ref(type_copy);
91b73004
JD
509 return writer_stream_class;
510}
511
c8cb4c2a 512BT_HIDDEN
8eee8ea2
PP
513int ctf_stream_copy_packet_header(FILE *err, const bt_packet *packet,
514 const bt_stream *writer_stream)
c8cb4c2a 515{
8eee8ea2 516 const bt_field *packet_header = NULL, *writer_packet_header = NULL;
c8cb4c2a
JD
517 int ret = 0;
518
839d52a5 519 packet_header = bt_packet_get_header(packet);
c8cb4c2a
JD
520 if (!packet_header) {
521 goto end;
522 }
523
839d52a5 524 writer_packet_header = bt_field_copy(packet_header);
c8cb4c2a 525 if (!writer_packet_header) {
0f60f957 526 BT_LOGE_STR("Failed to copy field from stream packet header.");
c8cb4c2a
JD
527 goto error;
528 }
529
839d52a5 530 ret = bt_stream_set_packet_header(writer_stream,
c8cb4c2a
JD
531 writer_packet_header);
532 if (ret) {
0f60f957 533 BT_LOGE_STR("Failed to set stream packet header.");
c8cb4c2a
JD
534 goto error;
535 }
536
537 goto end;
538
539error:
540 ret = -1;
541end:
8138bfe1
PP
542 bt_object_put_ref(writer_packet_header);
543 bt_object_put_ref(packet_header);
c8cb4c2a
JD
544 return ret;
545}
546
547BT_HIDDEN
8eee8ea2
PP
548int ctf_packet_copy_header(FILE *err, const bt_packet *packet,
549 const bt_packet *writer_packet)
c8cb4c2a 550{
8eee8ea2 551 const bt_field *packet_header = NULL, *writer_packet_header = NULL;
c8cb4c2a
JD
552 int ret = 0;
553
839d52a5 554 packet_header = bt_packet_get_header(packet);
c8cb4c2a
JD
555 if (!packet_header) {
556 goto end;
557 }
558
839d52a5 559 writer_packet_header = bt_field_copy(packet_header);
c8cb4c2a 560 if (!writer_packet_header) {
0f60f957 561 BT_LOGE_STR("Failed to copy field from packet header.");
c8cb4c2a
JD
562 goto error;
563 }
564
839d52a5 565 ret = bt_packet_set_header(writer_packet, writer_packet_header);
c8cb4c2a 566 if (ret) {
0f60f957 567 BT_LOGE_STR("Failed to set packet header.");
c8cb4c2a
JD
568 goto error;
569 }
570
571 goto end;
572
573error:
574 ret = -1;
575end:
8138bfe1
PP
576 bt_object_put_ref(packet_header);
577 bt_object_put_ref(writer_packet_header);
c8cb4c2a
JD
578 return ret;
579}
580
9ac68eb1 581BT_HIDDEN
8eee8ea2
PP
582int ctf_stream_copy_packet_context(FILE *err, const bt_packet *packet,
583 const bt_stream *writer_stream)
91b73004 584{
8eee8ea2 585 const bt_field *packet_context = NULL, *writer_packet_context = NULL;
674221e5 586 int ret = 0;
91b73004 587
839d52a5 588 packet_context = bt_packet_get_context(packet);
674221e5 589 if (!packet_context) {
91b73004
JD
590 goto end;
591 }
592
839d52a5 593 writer_packet_context = bt_field_copy(packet_context);
674221e5 594 if (!writer_packet_context) {
0f60f957 595 BT_LOGE_STR("Failed to copy field from stream packet context.");
674221e5 596 goto error;
91b73004
JD
597 }
598
839d52a5 599 ret = bt_stream_set_packet_context(writer_stream,
674221e5
JD
600 writer_packet_context);
601 if (ret) {
0f60f957 602 BT_LOGE_STR("Failed to set stream packet context.");
674221e5 603 goto error;
91b73004
JD
604 }
605
9ae49d3d
JD
606 goto end;
607
608error:
674221e5 609 ret = -1;
91b73004 610end:
8138bfe1
PP
611 bt_object_put_ref(packet_context);
612 bt_object_put_ref(writer_packet_context);
91b73004
JD
613 return ret;
614}
615
9ac68eb1 616BT_HIDDEN
8eee8ea2
PP
617int ctf_packet_copy_context(FILE *err, const bt_packet *packet,
618 const bt_stream *writer_stream,
619 const bt_packet *writer_packet)
91b73004 620{
8eee8ea2 621 const bt_field *packet_context = NULL, *writer_packet_context = NULL;
674221e5 622 int ret = 0;
91b73004 623
839d52a5 624 packet_context = bt_packet_get_context(packet);
91b73004 625 if (!packet_context) {
60ef553b 626 goto end;
91b73004
JD
627 }
628
839d52a5 629 writer_packet_context = bt_field_copy(packet_context);
674221e5 630 if (!writer_packet_context) {
0f60f957 631 BT_LOGE_STR("Failed to copy field from packet context.");
9ae49d3d 632 goto error;
91b73004
JD
633 }
634
839d52a5 635 ret = bt_packet_set_context(writer_packet, writer_packet_context);
674221e5 636 if (ret) {
0f60f957 637 BT_LOGE_STR("Failed to set packet context.");
9ae49d3d 638 goto error;
91b73004
JD
639 }
640
9ae49d3d
JD
641 goto end;
642
643error:
674221e5 644 ret = -1;
9ae49d3d 645end:
8138bfe1
PP
646 bt_object_put_ref(writer_packet_context);
647 bt_object_put_ref(packet_context);
674221e5 648 return ret;
b2f1f465
JD
649}
650
9ac68eb1 651BT_HIDDEN
8eee8ea2
PP
652int ctf_copy_event_header(FILE *err, const bt_event *event,
653 const bt_event_class *writer_event_class,
654 const bt_event *writer_event,
655 const bt_field *event_header)
b2f1f465 656{
8eee8ea2 657 const bt_clock_class *clock_class = NULL, *writer_clock_class = NULL;
ecbb78c0 658 bt_clock_snapshot *clock_snapshot = NULL, *writer_clock_snapshot = NULL;
b2f1f465
JD
659
660 int ret;
8eee8ea2 661 const bt_field *writer_event_header = NULL;
0f29db56 662 uint64_t value;
b2f1f465 663
0f29db56
JD
664 clock_class = event_get_clock_class(err, event);
665 if (!clock_class) {
0f60f957 666 BT_LOGE_STR("Failed to get event clock_class.");
0f29db56
JD
667 goto error;
668 }
669
ecbb78c0 670 clock_snapshot = bt_event_get_clock_snapshot(event, clock_class);
8c6884d9 671 BT_CLOCK_CLASS_PUT_REF_AND_RESET(clock_class);
ecbb78c0 672 BT_ASSERT(clock_snapshot);
0f29db56 673
ecbb78c0
PP
674 ret = bt_clock_snapshot_get_value(clock_snapshot, &value);
675 BT_OBJECT_PUT_REF_AND_RESET(clock_snapshot);
0f29db56 676 if (ret) {
0f60f957 677 BT_LOGE_STR("Failed to get clock value.");
0f29db56 678 goto error;
b2f1f465
JD
679 }
680
681 writer_clock_class = event_get_clock_class(err, writer_event);
682 if (!writer_clock_class) {
0f60f957 683 BT_LOGE_STR("Failed to get event clock_class.");
b2f1f465
JD
684 goto error;
685 }
686
ecbb78c0 687 writer_clock_snapshot = bt_clock_snapshot_create(writer_clock_class, value);
8c6884d9 688 BT_CLOCK_CLASS_PUT_REF_AND_RESET(writer_clock_class);
ecbb78c0 689 if (!writer_clock_snapshot) {
0f60f957 690 BT_LOGE_STR("Failed to create clock value.");
9ae49d3d 691 goto error;
b2f1f465
JD
692 }
693
ecbb78c0
PP
694 ret = bt_event_set_clock_snapshot(writer_event, writer_clock_snapshot);
695 BT_OBJECT_PUT_REF_AND_RESET(writer_clock_snapshot);
b2f1f465 696 if (ret) {
0f60f957 697 BT_LOGE_STR("Failed to set clock value.");
b2f1f465
JD
698 goto error;
699 }
700
839d52a5 701 writer_event_header = bt_field_copy(event_header);
0f29db56 702 if (!writer_event_header) {
0f60f957 703 BT_LOGE_STR("Failed to copy event_header.");
0f29db56
JD
704 goto end;
705 }
706
839d52a5 707 ret = bt_event_set_header(writer_event, writer_event_header);
8138bfe1 708 BT_OBJECT_PUT_REF_AND_RESET(writer_event_header);
b2f1f465 709 if (ret < 0) {
0f60f957 710 BT_LOGE_STR("Failed to set event_header.");
b2f1f465
JD
711 goto error;
712 }
b2f1f465
JD
713
714 ret = 0;
715
716 goto end;
717
718error:
b2f1f465 719 ret = -1;
91b73004
JD
720end:
721 return ret;
722}
723
5171f417 724static
8eee8ea2
PP
725const bt_trace *event_class_get_trace(FILE *err,
726 const bt_event_class *event_class)
5171f417 727{
8eee8ea2
PP
728 const bt_trace *trace = NULL;
729 const bt_stream_class *stream_class = NULL;
5171f417 730
839d52a5 731 stream_class = bt_event_class_get_stream_class(event_class);
8b45963b 732 BT_ASSERT(stream_class);
5171f417 733
839d52a5 734 trace = bt_stream_class_get_trace(stream_class);
8b45963b 735 BT_ASSERT(trace);
5171f417 736
8c6884d9 737 bt_stream_class_put_ref(stream_class);
5171f417
JD
738 return trace;
739}
740
9ac68eb1 741BT_HIDDEN
8eee8ea2
PP
742const bt_event *ctf_copy_event(FILE *err, const bt_event *event,
743 const bt_event_class *writer_event_class,
b2f1f465 744 bool override_ts64)
91b73004 745{
8eee8ea2
PP
746 const bt_event *writer_event = NULL;
747 const bt_field *field = NULL, *copy_field = NULL;
748 const bt_trace *writer_trace = NULL;
91b73004
JD
749 int ret;
750
839d52a5 751 writer_event = bt_event_create(writer_event_class);
91b73004 752 if (!writer_event) {
0f60f957 753 BT_LOGE_STR("Failed to create event.");
5171f417
JD
754 goto error;
755 }
756
757 writer_trace = event_class_get_trace(err, writer_event_class);
758 if (!writer_trace) {
0f60f957 759 BT_LOGE_STR("Failed to get trace from event_class.");
5171f417 760 goto error;
91b73004
JD
761 }
762
839d52a5 763 field = bt_event_get_header(event);
93872409
JD
764 if (field) {
765 /*
5171f417
JD
766 * If override_ts64, we override all integer fields mapped to a
767 * clock to a uint64_t field type, otherwise, we just copy it as
768 * is.
93872409 769 */
839d52a5 770 ret = bt_trace_get_clock_class_count(writer_trace);
8b45963b 771 BT_ASSERT(ret >= 0);
0f60f957 772
5171f417 773 if (override_ts64 && ret > 0) {
839d52a5 774 copy_field = bt_event_get_header(writer_event);
8b45963b 775 BT_ASSERT(copy_field);
b2f1f465 776
93872409
JD
777 ret = copy_override_field(err, event, writer_event, field,
778 copy_field);
779 if (ret) {
0f60f957 780 BT_LOGE_STR("Failed to copy and override field.");
93872409
JD
781 goto error;
782 }
8138bfe1 783 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
93872409
JD
784 } else {
785 ret = ctf_copy_event_header(err, event, writer_event_class,
786 writer_event, field);
787 if (ret) {
0f60f957 788 BT_LOGE_STR("Failed to copy event_header.");
93872409
JD
789 goto error;
790 }
91b73004 791 }
8138bfe1 792 BT_OBJECT_PUT_REF_AND_RESET(field);
91b73004
JD
793 }
794
795 /* Optional field, so it can fail silently. */
839d52a5 796 field = bt_event_get_stream_event_context(event);
961ec227 797 if (field) {
839d52a5 798 copy_field = bt_field_copy(field);
961ec227 799 if (!copy_field) {
0f60f957 800 BT_LOGE_STR("Failed to copy field.");
961ec227
JD
801 goto error;
802 }
839d52a5 803 ret = bt_event_set_stream_event_context(writer_event,
91b73004 804 copy_field);
91b73004 805 if (ret < 0) {
0f60f957 806 BT_LOGE_STR("Failed to set stream_event_context.");
91b73004
JD
807 goto error;
808 }
8138bfe1
PP
809 BT_OBJECT_PUT_REF_AND_RESET(field);
810 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
91b73004
JD
811 }
812
813 /* Optional field, so it can fail silently. */
839d52a5 814 field = bt_event_get_event_context(event);
961ec227 815 if (field) {
839d52a5 816 copy_field = bt_field_copy(field);
961ec227 817 if (!copy_field) {
0f60f957 818 BT_LOGE_STR("Failed to copy field.");
961ec227
JD
819 goto error;
820 }
839d52a5 821 ret = bt_event_set_event_context(writer_event, copy_field);
91b73004 822 if (ret < 0) {
0f60f957 823 BT_LOGE_STR("Failed to set event_context.");
91b73004
JD
824 goto error;
825 }
8138bfe1
PP
826 BT_OBJECT_PUT_REF_AND_RESET(field);
827 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
91b73004
JD
828 }
829
839d52a5 830 field = bt_event_get_event_payload(event);
961ec227 831 if (field) {
839d52a5 832 copy_field = bt_field_copy(field);
961ec227 833 if (!copy_field) {
0f60f957 834 BT_LOGE_STR("Failed to copy field.");
961ec227
JD
835 goto error;
836 }
839d52a5 837 ret = bt_event_set_event_payload(writer_event, copy_field);
91b73004 838 if (ret < 0) {
0f60f957 839 BT_LOGE_STR("Failed to set event_payload.");
91b73004
JD
840 goto error;
841 }
8138bfe1
PP
842 BT_OBJECT_PUT_REF_AND_RESET(field);
843 BT_OBJECT_PUT_REF_AND_RESET(copy_field);
91b73004 844 }
9ae49d3d 845
91b73004
JD
846 goto end;
847
848error:
8138bfe1 849 BT_OBJECT_PUT_REF_AND_RESET(writer_event);
91b73004 850end:
8138bfe1
PP
851 bt_object_put_ref(field);
852 bt_object_put_ref(copy_field);
8c6884d9 853 bt_trace_put_ref(writer_trace);
91b73004
JD
854 return writer_event;
855}
856
9ac68eb1 857BT_HIDDEN
ee78f405 858bt_component_status ctf_copy_trace(FILE *err, const bt_trace *trace,
8eee8ea2 859 const bt_trace *writer_trace)
91b73004 860{
ee78f405 861 bt_component_status ret = BT_COMPONENT_STATUS_OK;
91b73004 862 int field_count, i, int_ret;
8eee8ea2 863 bt_field_type *header_type = NULL;
ee78f405 864 bt_byte_order order;
0ac862b4 865 const char *trace_name;
76d2721c 866 const unsigned char *trace_uuid;
91b73004 867
839d52a5 868 field_count = bt_trace_get_environment_field_count(trace);
91b73004
JD
869 for (i = 0; i < field_count; i++) {
870 int ret_int;
871 const char *name;
8eee8ea2 872 bt_value *value = NULL;
91b73004 873
839d52a5 874 name = bt_trace_get_environment_field_name_by_index(
9ac68eb1 875 trace, i);
8b45963b 876 BT_ASSERT(name);
0f60f957 877
839d52a5 878 value = bt_trace_get_environment_field_value_by_index(
9ac68eb1 879 trace, i);
8b45963b 880 BT_ASSERT(value);
91b73004 881
839d52a5 882 ret_int = bt_trace_set_environment_field(writer_trace,
91b73004 883 name, value);
8c6884d9 884 BT_VALUE_PUT_REF_AND_RESET(value);
91b73004 885 if (ret_int < 0) {
0f60f957 886 BT_LOGE("Failed to set environment: field-name=\"%s\"",
91b73004
JD
887 name);
888 ret = BT_COMPONENT_STATUS_ERROR;
9ae49d3d 889 goto end;
91b73004
JD
890 }
891 }
892
839d52a5 893 order = bt_trace_get_native_byte_order(trace);
8b45963b 894 BT_ASSERT(order != BT_BYTE_ORDER_UNKNOWN);
6468dbd6 895
d41cff38
PP
896 /*
897 * Only explicitly set the writer trace's native byte order if
898 * the original trace has a specific one. Otherwise leave what
899 * the CTF writer object chooses, which is the machine's native
900 * byte order.
901 */
839d52a5
PP
902 if (order != BT_BYTE_ORDER_UNSPECIFIED) {
903 ret = bt_trace_set_native_byte_order(writer_trace, order);
d41cff38 904 if (ret) {
0f60f957 905 BT_LOGE_STR("Failed to set native byte order.");
d41cff38
PP
906 ret = BT_COMPONENT_STATUS_ERROR;
907 goto end;
908 }
6468dbd6
JD
909 }
910
839d52a5 911 header_type = bt_trace_get_packet_header_type(trace);
944eed39 912 if (header_type) {
839d52a5 913 int_ret = bt_trace_set_packet_header_type(writer_trace, header_type);
8138bfe1 914 BT_OBJECT_PUT_REF_AND_RESET(header_type);
944eed39 915 if (int_ret < 0) {
0f60f957 916 BT_LOGE_STR("Failed to set packet header type.");
944eed39
JD
917 ret = BT_COMPONENT_STATUS_ERROR;
918 goto end;
919 }
91b73004
JD
920 }
921
839d52a5 922 trace_name = bt_trace_get_name(trace);
0ac862b4 923 if (trace_name) {
839d52a5 924 int_ret = bt_trace_set_name(writer_trace, trace_name);
0ac862b4 925 if (int_ret < 0) {
0f60f957 926 BT_LOGE_STR("Failed to set trace name.");
0ac862b4
JD
927 ret = BT_COMPONENT_STATUS_ERROR;
928 goto end;
929 }
930 }
931
839d52a5 932 trace_uuid = bt_trace_get_uuid(trace);
76d2721c 933 if (trace_uuid) {
839d52a5 934 int_ret = bt_trace_set_uuid(writer_trace, trace_uuid);
76d2721c 935 if (int_ret < 0) {
0f60f957 936 BT_LOGE_STR("Failed to set trace UUID.");
76d2721c
PP
937 ret = BT_COMPONENT_STATUS_ERROR;
938 goto end;
939 }
940 }
941
9ae49d3d 942end:
91b73004
JD
943 return ret;
944}
This page took 0.084101 seconds and 4 git commands to generate.