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