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