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