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 | ||
e0831b38 | 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 |
839d52a5 PP |
39 | struct bt_clock_class *ctf_copy_clock_class(FILE *err, |
40 | struct bt_clock_class *clock_class) | |
91b73004 JD |
41 | { |
42 | int64_t offset, offset_s; | |
43 | int int_ret; | |
44 | uint64_t u64_ret; | |
45 | const char *name, *description; | |
839d52a5 | 46 | struct bt_clock_class *writer_clock_class = NULL; |
91b73004 JD |
47 | |
48 | assert(err && clock_class); | |
49 | ||
839d52a5 | 50 | name = bt_clock_class_get_name(clock_class); |
0f60f957 | 51 | assert(name); |
91b73004 | 52 | |
839d52a5 PP |
53 | writer_clock_class = bt_clock_class_create(name, |
54 | bt_clock_class_get_frequency(clock_class)); | |
91b73004 | 55 | if (!writer_clock_class) { |
0f60f957 | 56 | BT_LOGE_STR("Failed to create clock class."); |
91b73004 JD |
57 | goto end; |
58 | } | |
59 | ||
839d52a5 | 60 | description = bt_clock_class_get_description(clock_class); |
16cd0c80 | 61 | if (description) { |
839d52a5 | 62 | int_ret = bt_clock_class_set_description(writer_clock_class, |
16cd0c80 | 63 | description); |
0f60f957 | 64 | assert(!int_ret); |
91b73004 JD |
65 | } |
66 | ||
839d52a5 | 67 | u64_ret = bt_clock_class_get_precision(clock_class); |
0f60f957 JD |
68 | assert(u64_ret != -1ULL); |
69 | ||
839d52a5 | 70 | int_ret = bt_clock_class_set_precision(writer_clock_class, |
91b73004 | 71 | u64_ret); |
0f60f957 | 72 | assert(!int_ret); |
91b73004 | 73 | |
839d52a5 | 74 | int_ret = bt_clock_class_get_offset_s(clock_class, &offset_s); |
0f60f957 | 75 | assert(!int_ret); |
91b73004 | 76 | |
839d52a5 | 77 | int_ret = bt_clock_class_set_offset_s(writer_clock_class, offset_s); |
0f60f957 | 78 | assert(!int_ret); |
91b73004 | 79 | |
839d52a5 | 80 | int_ret = bt_clock_class_get_offset_cycles(clock_class, &offset); |
0f60f957 | 81 | assert(!int_ret); |
91b73004 | 82 | |
839d52a5 | 83 | int_ret = bt_clock_class_set_offset_cycles(writer_clock_class, offset); |
0f60f957 | 84 | assert(!int_ret); |
91b73004 | 85 | |
839d52a5 | 86 | int_ret = bt_clock_class_is_absolute(clock_class); |
0f60f957 | 87 | assert(int_ret >= 0); |
91b73004 | 88 | |
839d52a5 | 89 | int_ret = bt_clock_class_set_is_absolute(writer_clock_class, int_ret); |
0f60f957 | 90 | assert(!int_ret); |
91b73004 | 91 | |
91b73004 JD |
92 | end: |
93 | return writer_clock_class; | |
94 | } | |
95 | ||
9ac68eb1 | 96 | BT_HIDDEN |
91b73004 | 97 | enum bt_component_status ctf_copy_clock_classes(FILE *err, |
839d52a5 PP |
98 | struct bt_trace *writer_trace, |
99 | struct bt_stream_class *writer_stream_class, | |
100 | struct bt_trace *trace) | |
91b73004 JD |
101 | { |
102 | enum bt_component_status ret; | |
91b73004 JD |
103 | int int_ret, clock_class_count, i; |
104 | ||
839d52a5 | 105 | clock_class_count = bt_trace_get_clock_class_count(trace); |
91b73004 JD |
106 | |
107 | for (i = 0; i < clock_class_count; i++) { | |
839d52a5 PP |
108 | struct bt_clock_class *writer_clock_class; |
109 | struct bt_clock_class *clock_class = | |
110 | bt_trace_get_clock_class_by_index(trace, i); | |
91b73004 | 111 | |
0f60f957 | 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) { | |
0f60f957 | 117 | BT_LOGE_STR("Failed to copy clock class."); |
91b73004 JD |
118 | ret = BT_COMPONENT_STATUS_ERROR; |
119 | goto end; | |
120 | } | |
121 | ||
839d52a5 | 122 | int_ret = bt_trace_add_clock_class(writer_trace, writer_clock_class); |
91b73004 JD |
123 | if (int_ret != 0) { |
124 | BT_PUT(writer_clock_class); | |
0f60f957 | 125 | BT_LOGE_STR("Failed to add clock class."); |
91b73004 JD |
126 | ret = BT_COMPONENT_STATUS_ERROR; |
127 | goto end; | |
128 | } | |
129 | ||
130 | /* | |
b2f1f465 | 131 | * Ownership transferred to the trace. |
91b73004 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 |
839d52a5 PP |
143 | struct bt_event_class *ctf_copy_event_class(FILE *err, |
144 | struct bt_event_class *event_class) | |
91b73004 | 145 | { |
839d52a5 PP |
146 | struct bt_event_class *writer_event_class = NULL; |
147 | struct bt_field_type *context, *payload_type; | |
91b73004 | 148 | const char *name; |
9cf5d083 PP |
149 | int ret; |
150 | int64_t id; | |
839d52a5 | 151 | enum bt_event_class_log_level log_level; |
9cf5d083 | 152 | const char *emf_uri; |
91b73004 | 153 | |
839d52a5 | 154 | name = bt_event_class_get_name(event_class); |
91b73004 | 155 | |
839d52a5 | 156 | writer_event_class = bt_event_class_create(name); |
0f60f957 | 157 | assert(writer_event_class); |
91b73004 | 158 | |
839d52a5 | 159 | id = bt_event_class_get_id(event_class); |
0f60f957 | 160 | assert(id >= 0); |
91b73004 | 161 | |
839d52a5 | 162 | ret = bt_event_class_set_id(writer_event_class, id); |
9cf5d083 | 163 | if (ret) { |
0f60f957 | 164 | BT_LOGE_STR("Failed to set event_class id."); |
9cf5d083 PP |
165 | goto error; |
166 | } | |
91b73004 | 167 | |
839d52a5 | 168 | log_level = bt_event_class_get_log_level(event_class); |
9cf5d083 | 169 | if (log_level < 0) { |
0f60f957 | 170 | BT_LOGE_STR("Failed to get log_level."); |
9cf5d083 PP |
171 | goto error; |
172 | } | |
173 | ||
839d52a5 | 174 | ret = bt_event_class_set_log_level(writer_event_class, log_level); |
9cf5d083 | 175 | if (ret) { |
0f60f957 | 176 | BT_LOGE_STR("Failed to set log_level."); |
9cf5d083 PP |
177 | goto error; |
178 | } | |
179 | ||
839d52a5 | 180 | emf_uri = bt_event_class_get_emf_uri(event_class); |
9cf5d083 | 181 | if (emf_uri) { |
839d52a5 | 182 | ret = bt_event_class_set_emf_uri(writer_event_class, |
9cf5d083 PP |
183 | emf_uri); |
184 | if (ret) { | |
0f60f957 | 185 | BT_LOGE_STR("Failed to set emf uri."); |
9ae49d3d | 186 | goto error; |
91b73004 JD |
187 | } |
188 | } | |
189 | ||
839d52a5 | 190 | payload_type = bt_event_class_get_payload_type(event_class); |
f87fb9b4 | 191 | if (payload_type) { |
839d52a5 | 192 | ret = bt_event_class_set_payload_type(writer_event_class, |
f87fb9b4 | 193 | payload_type); |
91b73004 | 194 | if (ret < 0) { |
0f60f957 | 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 | ||
839d52a5 | 201 | context = bt_event_class_get_context_type(event_class); |
279c77d0 | 202 | if (context) { |
839d52a5 | 203 | ret = bt_event_class_set_context_type( |
279c77d0 JD |
204 | writer_event_class, context); |
205 | BT_PUT(context); | |
206 | if (ret < 0) { | |
0f60f957 | 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 | 221 | enum bt_component_status ctf_copy_event_classes(FILE *err, |
839d52a5 PP |
222 | struct bt_stream_class *stream_class, |
223 | struct bt_stream_class *writer_stream_class) | |
91b73004 JD |
224 | { |
225 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
839d52a5 | 226 | struct bt_event_class *event_class = NULL, *writer_event_class = NULL; |
91b73004 JD |
227 | int count, i; |
228 | ||
839d52a5 | 229 | count = bt_stream_class_get_event_class_count(stream_class); |
0f60f957 | 230 | assert(count >= 0); |
91b73004 JD |
231 | |
232 | for (i = 0; i < count; i++) { | |
91b73004 JD |
233 | int int_ret; |
234 | ||
839d52a5 | 235 | event_class = bt_stream_class_get_event_class_by_index( |
91b73004 | 236 | stream_class, i); |
0f60f957 JD |
237 | assert(event_class); |
238 | ||
839d52a5 PP |
239 | if (i < bt_stream_class_get_event_class_count(writer_stream_class)) { |
240 | writer_event_class = bt_stream_class_get_event_class_by_index( | |
cb0a5cf8 JD |
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) { | |
0f60f957 | 257 | BT_LOGE_STR("Failed to copy event_class."); |
91b73004 | 258 | ret = BT_COMPONENT_STATUS_ERROR; |
9ae49d3d | 259 | goto error; |
91b73004 JD |
260 | } |
261 | ||
839d52a5 | 262 | int_ret = bt_stream_class_add_event_class(writer_stream_class, |
91b73004 JD |
263 | writer_event_class); |
264 | if (int_ret < 0) { | |
0f60f957 | 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 |
839d52a5 PP |
283 | struct bt_stream_class *ctf_copy_stream_class(FILE *err, |
284 | struct bt_stream_class *stream_class, | |
285 | struct bt_trace *writer_trace, | |
b2f1f465 | 286 | bool override_ts64) |
91b73004 | 287 | { |
839d52a5 PP |
288 | struct bt_field_type *type = NULL; |
289 | struct bt_stream_class *writer_stream_class = NULL; | |
91b73004 | 290 | int ret_int; |
839d52a5 | 291 | const char *name = bt_stream_class_get_name(stream_class); |
91b73004 | 292 | |
839d52a5 | 293 | writer_stream_class = bt_stream_class_create_empty(name); |
0f60f957 | 294 | assert(writer_stream_class); |
91b73004 | 295 | |
839d52a5 | 296 | type = bt_stream_class_get_packet_context_type(stream_class); |
2ca6de5c | 297 | if (type) { |
839d52a5 | 298 | ret_int = bt_stream_class_set_packet_context_type( |
2ca6de5c JD |
299 | writer_stream_class, type); |
300 | if (ret_int < 0) { | |
0f60f957 | 301 | BT_LOGE_STR("Failed to set packet_context type."); |
2ca6de5c JD |
302 | goto error; |
303 | } | |
304 | BT_PUT(type); | |
91b73004 JD |
305 | } |
306 | ||
839d52a5 | 307 | type = bt_stream_class_get_event_header_type(stream_class); |
93872409 | 308 | if (type) { |
839d52a5 | 309 | ret_int = bt_trace_get_clock_class_count(writer_trace); |
0f60f957 | 310 | assert(ret_int >= 0); |
5171f417 | 311 | if (override_ts64 && ret_int > 0) { |
839d52a5 | 312 | struct bt_field_type *new_event_header_type; |
93872409 JD |
313 | |
314 | new_event_header_type = override_header_type(err, type, | |
315 | writer_trace); | |
316 | if (!new_event_header_type) { | |
0f60f957 | 317 | BT_LOGE_STR("Failed to override header type."); |
93872409 JD |
318 | goto error; |
319 | } | |
839d52a5 | 320 | ret_int = bt_stream_class_set_event_header_type( |
93872409 JD |
321 | writer_stream_class, new_event_header_type); |
322 | BT_PUT(new_event_header_type); | |
323 | if (ret_int < 0) { | |
0f60f957 | 324 | BT_LOGE_STR("Failed to set event_header type."); |
93872409 JD |
325 | goto error; |
326 | } | |
327 | } else { | |
839d52a5 | 328 | ret_int = bt_stream_class_set_event_header_type( |
93872409 JD |
329 | writer_stream_class, type); |
330 | if (ret_int < 0) { | |
0f60f957 | 331 | BT_LOGE_STR("Failed to set event_header type."); |
93872409 JD |
332 | goto error; |
333 | } | |
0f29db56 | 334 | } |
93872409 | 335 | BT_PUT(type); |
91b73004 JD |
336 | } |
337 | ||
839d52a5 | 338 | type = bt_stream_class_get_event_context_type(stream_class); |
91b73004 | 339 | if (type) { |
839d52a5 | 340 | ret_int = bt_stream_class_set_event_context_type( |
91b73004 | 341 | writer_stream_class, type); |
91b73004 | 342 | if (ret_int < 0) { |
0f60f957 | 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 | ||
c8cb4c2a | 358 | BT_HIDDEN |
839d52a5 PP |
359 | int ctf_stream_copy_packet_header(FILE *err, struct bt_packet *packet, |
360 | struct bt_stream *writer_stream) | |
c8cb4c2a | 361 | { |
839d52a5 | 362 | struct bt_field *packet_header = NULL, *writer_packet_header = NULL; |
c8cb4c2a JD |
363 | int ret = 0; |
364 | ||
839d52a5 | 365 | packet_header = bt_packet_get_header(packet); |
c8cb4c2a JD |
366 | if (!packet_header) { |
367 | goto end; | |
368 | } | |
369 | ||
839d52a5 | 370 | writer_packet_header = bt_field_copy(packet_header); |
c8cb4c2a | 371 | if (!writer_packet_header) { |
0f60f957 | 372 | BT_LOGE_STR("Failed to copy field from stream packet header."); |
c8cb4c2a JD |
373 | goto error; |
374 | } | |
375 | ||
839d52a5 | 376 | ret = bt_stream_set_packet_header(writer_stream, |
c8cb4c2a JD |
377 | writer_packet_header); |
378 | if (ret) { | |
0f60f957 | 379 | BT_LOGE_STR("Failed to set stream packet header."); |
c8cb4c2a 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 | |
839d52a5 PP |
394 | int ctf_packet_copy_header(FILE *err, struct bt_packet *packet, |
395 | struct bt_packet *writer_packet) | |
c8cb4c2a | 396 | { |
839d52a5 | 397 | struct bt_field *packet_header = NULL, *writer_packet_header = NULL; |
c8cb4c2a JD |
398 | int ret = 0; |
399 | ||
839d52a5 | 400 | packet_header = bt_packet_get_header(packet); |
c8cb4c2a JD |
401 | if (!packet_header) { |
402 | goto end; | |
403 | } | |
404 | ||
839d52a5 | 405 | writer_packet_header = bt_field_copy(packet_header); |
c8cb4c2a | 406 | if (!writer_packet_header) { |
0f60f957 | 407 | BT_LOGE_STR("Failed to copy field from packet header."); |
c8cb4c2a JD |
408 | goto error; |
409 | } | |
410 | ||
839d52a5 | 411 | ret = bt_packet_set_header(writer_packet, writer_packet_header); |
c8cb4c2a | 412 | if (ret) { |
0f60f957 | 413 | BT_LOGE_STR("Failed to set packet header."); |
c8cb4c2a 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 |
839d52a5 PP |
428 | int ctf_stream_copy_packet_context(FILE *err, struct bt_packet *packet, |
429 | struct bt_stream *writer_stream) | |
91b73004 | 430 | { |
839d52a5 | 431 | struct bt_field *packet_context = NULL, *writer_packet_context = NULL; |
674221e5 | 432 | int ret = 0; |
91b73004 | 433 | |
839d52a5 | 434 | packet_context = bt_packet_get_context(packet); |
674221e5 | 435 | if (!packet_context) { |
91b73004 JD |
436 | goto end; |
437 | } | |
438 | ||
839d52a5 | 439 | writer_packet_context = bt_field_copy(packet_context); |
674221e5 | 440 | if (!writer_packet_context) { |
0f60f957 | 441 | BT_LOGE_STR("Failed to copy field from stream packet context."); |
674221e5 | 442 | goto error; |
91b73004 JD |
443 | } |
444 | ||
839d52a5 | 445 | ret = bt_stream_set_packet_context(writer_stream, |
674221e5 JD |
446 | writer_packet_context); |
447 | if (ret) { | |
0f60f957 | 448 | BT_LOGE_STR("Failed to set stream packet context."); |
674221e5 | 449 | goto error; |
91b73004 JD |
450 | } |
451 | ||
9ae49d3d JD |
452 | goto end; |
453 | ||
454 | error: | |
674221e5 | 455 | ret = -1; |
91b73004 | 456 | end: |
674221e5 JD |
457 | bt_put(packet_context); |
458 | bt_put(writer_packet_context); | |
91b73004 JD |
459 | return ret; |
460 | } | |
461 | ||
9ac68eb1 | 462 | BT_HIDDEN |
839d52a5 PP |
463 | int ctf_packet_copy_context(FILE *err, struct bt_packet *packet, |
464 | struct bt_stream *writer_stream, | |
465 | struct bt_packet *writer_packet) | |
91b73004 | 466 | { |
839d52a5 | 467 | struct bt_field *packet_context = NULL, *writer_packet_context = NULL; |
674221e5 | 468 | int ret = 0; |
91b73004 | 469 | |
839d52a5 | 470 | packet_context = bt_packet_get_context(packet); |
91b73004 | 471 | if (!packet_context) { |
60ef553b | 472 | goto end; |
91b73004 JD |
473 | } |
474 | ||
839d52a5 | 475 | writer_packet_context = bt_field_copy(packet_context); |
674221e5 | 476 | if (!writer_packet_context) { |
0f60f957 | 477 | BT_LOGE_STR("Failed to copy field from packet context."); |
9ae49d3d | 478 | goto error; |
91b73004 JD |
479 | } |
480 | ||
839d52a5 | 481 | ret = bt_packet_set_context(writer_packet, writer_packet_context); |
674221e5 | 482 | if (ret) { |
0f60f957 | 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: | |
674221e5 | 490 | ret = -1; |
9ae49d3d | 491 | end: |
674221e5 | 492 | bt_put(writer_packet_context); |
91b73004 | 493 | bt_put(packet_context); |
674221e5 | 494 | return ret; |
b2f1f465 JD |
495 | } |
496 | ||
9ac68eb1 | 497 | BT_HIDDEN |
839d52a5 PP |
498 | int ctf_copy_event_header(FILE *err, struct bt_event *event, |
499 | struct bt_event_class *writer_event_class, | |
500 | struct bt_event *writer_event, | |
501 | struct bt_field *event_header) | |
b2f1f465 | 502 | { |
839d52a5 PP |
503 | struct bt_clock_class *clock_class = NULL, *writer_clock_class = NULL; |
504 | struct bt_clock_value *clock_value = NULL, *writer_clock_value = NULL; | |
b2f1f465 JD |
505 | |
506 | int ret; | |
839d52a5 | 507 | struct bt_field *writer_event_header = NULL; |
0f29db56 | 508 | uint64_t value; |
b2f1f465 | 509 | |
0f29db56 JD |
510 | clock_class = event_get_clock_class(err, event); |
511 | if (!clock_class) { | |
0f60f957 | 512 | BT_LOGE_STR("Failed to get event clock_class."); |
0f29db56 JD |
513 | goto error; |
514 | } | |
515 | ||
839d52a5 | 516 | clock_value = bt_event_get_clock_value(event, clock_class); |
9ae49d3d | 517 | BT_PUT(clock_class); |
0f60f957 | 518 | assert(clock_value); |
0f29db56 | 519 | |
839d52a5 | 520 | ret = bt_clock_value_get_value(clock_value, &value); |
9ae49d3d | 521 | BT_PUT(clock_value); |
0f29db56 | 522 | if (ret) { |
0f60f957 | 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) { | |
0f60f957 | 529 | BT_LOGE_STR("Failed to get event clock_class."); |
b2f1f465 JD |
530 | goto error; |
531 | } | |
532 | ||
839d52a5 | 533 | writer_clock_value = bt_clock_value_create(writer_clock_class, value); |
9ae49d3d | 534 | BT_PUT(writer_clock_class); |
0f29db56 | 535 | if (!writer_clock_value) { |
0f60f957 | 536 | BT_LOGE_STR("Failed to create clock value."); |
9ae49d3d | 537 | goto error; |
b2f1f465 JD |
538 | } |
539 | ||
839d52a5 | 540 | ret = bt_event_set_clock_value(writer_event, writer_clock_value); |
9ae49d3d | 541 | BT_PUT(writer_clock_value); |
b2f1f465 | 542 | if (ret) { |
0f60f957 | 543 | BT_LOGE_STR("Failed to set clock value."); |
b2f1f465 JD |
544 | goto error; |
545 | } | |
546 | ||
839d52a5 | 547 | writer_event_header = bt_field_copy(event_header); |
0f29db56 | 548 | if (!writer_event_header) { |
0f60f957 | 549 | BT_LOGE_STR("Failed to copy event_header."); |
0f29db56 JD |
550 | goto end; |
551 | } | |
552 | ||
839d52a5 | 553 | ret = bt_event_set_header(writer_event, writer_event_header); |
9ae49d3d | 554 | BT_PUT(writer_event_header); |
b2f1f465 | 555 | if (ret < 0) { |
0f60f957 | 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 | ||
5171f417 | 570 | static |
839d52a5 PP |
571 | struct bt_trace *event_class_get_trace(FILE *err, |
572 | struct bt_event_class *event_class) | |
5171f417 | 573 | { |
839d52a5 PP |
574 | struct bt_trace *trace = NULL; |
575 | struct bt_stream_class *stream_class = NULL; | |
5171f417 | 576 | |
839d52a5 | 577 | stream_class = bt_event_class_get_stream_class(event_class); |
0f60f957 | 578 | assert(stream_class); |
5171f417 | 579 | |
839d52a5 | 580 | trace = bt_stream_class_get_trace(stream_class); |
0f60f957 | 581 | assert(trace); |
5171f417 | 582 | |
5171f417 JD |
583 | bt_put(stream_class); |
584 | return trace; | |
585 | } | |
586 | ||
9ac68eb1 | 587 | BT_HIDDEN |
839d52a5 PP |
588 | struct bt_event *ctf_copy_event(FILE *err, struct bt_event *event, |
589 | struct bt_event_class *writer_event_class, | |
b2f1f465 | 590 | bool override_ts64) |
91b73004 | 591 | { |
839d52a5 PP |
592 | struct bt_event *writer_event = NULL; |
593 | struct bt_field *field = NULL, *copy_field = NULL; | |
594 | struct bt_trace *writer_trace = NULL; | |
91b73004 JD |
595 | int ret; |
596 | ||
839d52a5 | 597 | writer_event = bt_event_create(writer_event_class); |
91b73004 | 598 | if (!writer_event) { |
0f60f957 | 599 | BT_LOGE_STR("Failed to create event."); |
5171f417 JD |
600 | goto error; |
601 | } | |
602 | ||
603 | writer_trace = event_class_get_trace(err, writer_event_class); | |
604 | if (!writer_trace) { | |
0f60f957 | 605 | BT_LOGE_STR("Failed to get trace from event_class."); |
5171f417 | 606 | goto error; |
91b73004 JD |
607 | } |
608 | ||
839d52a5 | 609 | field = bt_event_get_header(event); |
93872409 JD |
610 | if (field) { |
611 | /* | |
5171f417 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. | |
93872409 | 615 | */ |
839d52a5 | 616 | ret = bt_trace_get_clock_class_count(writer_trace); |
0f60f957 JD |
617 | assert(ret >= 0); |
618 | ||
5171f417 | 619 | if (override_ts64 && ret > 0) { |
839d52a5 | 620 | copy_field = bt_event_get_header(writer_event); |
0f60f957 | 621 | assert(copy_field); |
b2f1f465 | 622 | |
93872409 JD |
623 | ret = copy_override_field(err, event, writer_event, field, |
624 | copy_field); | |
625 | if (ret) { | |
0f60f957 | 626 | BT_LOGE_STR("Failed to copy and override field."); |
93872409 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) { | |
0f60f957 | 634 | BT_LOGE_STR("Failed to copy event_header."); |
93872409 JD |
635 | goto error; |
636 | } | |
91b73004 | 637 | } |
93872409 | 638 | BT_PUT(field); |
91b73004 JD |
639 | } |
640 | ||
641 | /* Optional field, so it can fail silently. */ | |
839d52a5 | 642 | field = bt_event_get_stream_event_context(event); |
961ec227 | 643 | if (field) { |
839d52a5 | 644 | copy_field = bt_field_copy(field); |
961ec227 | 645 | if (!copy_field) { |
0f60f957 | 646 | BT_LOGE_STR("Failed to copy field."); |
961ec227 JD |
647 | goto error; |
648 | } | |
839d52a5 | 649 | ret = bt_event_set_stream_event_context(writer_event, |
91b73004 | 650 | copy_field); |
91b73004 | 651 | if (ret < 0) { |
0f60f957 | 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. */ | |
839d52a5 | 660 | field = bt_event_get_event_context(event); |
961ec227 | 661 | if (field) { |
839d52a5 | 662 | copy_field = bt_field_copy(field); |
961ec227 | 663 | if (!copy_field) { |
0f60f957 | 664 | BT_LOGE_STR("Failed to copy field."); |
961ec227 JD |
665 | goto error; |
666 | } | |
839d52a5 | 667 | ret = bt_event_set_event_context(writer_event, copy_field); |
91b73004 | 668 | if (ret < 0) { |
0f60f957 | 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 | ||
839d52a5 | 676 | field = bt_event_get_event_payload(event); |
961ec227 | 677 | if (field) { |
839d52a5 | 678 | copy_field = bt_field_copy(field); |
961ec227 | 679 | if (!copy_field) { |
0f60f957 | 680 | BT_LOGE_STR("Failed to copy field."); |
961ec227 JD |
681 | goto error; |
682 | } | |
839d52a5 | 683 | ret = bt_event_set_event_payload(writer_event, copy_field); |
91b73004 | 684 | if (ret < 0) { |
0f60f957 | 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); | |
5171f417 | 699 | bt_put(writer_trace); |
91b73004 JD |
700 | return writer_event; |
701 | } | |
702 | ||
9ac68eb1 | 703 | BT_HIDDEN |
839d52a5 PP |
704 | enum bt_component_status ctf_copy_trace(FILE *err, struct bt_trace *trace, |
705 | struct bt_trace *writer_trace) | |
91b73004 JD |
706 | { |
707 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
708 | int field_count, i, int_ret; | |
839d52a5 PP |
709 | struct bt_field_type *header_type = NULL; |
710 | enum bt_byte_order order; | |
0ac862b4 | 711 | const char *trace_name; |
76d2721c | 712 | const unsigned char *trace_uuid; |
91b73004 | 713 | |
839d52a5 | 714 | field_count = bt_trace_get_environment_field_count(trace); |
91b73004 JD |
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 | |
839d52a5 | 720 | name = bt_trace_get_environment_field_name_by_index( |
9ac68eb1 | 721 | trace, i); |
0f60f957 JD |
722 | assert(name); |
723 | ||
839d52a5 | 724 | value = bt_trace_get_environment_field_value_by_index( |
9ac68eb1 | 725 | trace, i); |
0f60f957 | 726 | assert(value); |
91b73004 | 727 | |
839d52a5 | 728 | ret_int = bt_trace_set_environment_field(writer_trace, |
91b73004 | 729 | name, value); |
9ae49d3d | 730 | BT_PUT(value); |
91b73004 | 731 | if (ret_int < 0) { |
0f60f957 | 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 | ||
839d52a5 PP |
739 | order = bt_trace_get_native_byte_order(trace); |
740 | assert(order != BT_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 | */ | |
839d52a5 PP |
748 | if (order != BT_BYTE_ORDER_UNSPECIFIED) { |
749 | ret = bt_trace_set_native_byte_order(writer_trace, order); | |
d41cff38 | 750 | if (ret) { |
0f60f957 | 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 | ||
839d52a5 | 757 | header_type = bt_trace_get_packet_header_type(trace); |
944eed39 | 758 | if (header_type) { |
839d52a5 | 759 | int_ret = bt_trace_set_packet_header_type(writer_trace, header_type); |
944eed39 JD |
760 | BT_PUT(header_type); |
761 | if (int_ret < 0) { | |
0f60f957 | 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 | ||
839d52a5 | 768 | trace_name = bt_trace_get_name(trace); |
0ac862b4 | 769 | if (trace_name) { |
839d52a5 | 770 | int_ret = bt_trace_set_name(writer_trace, trace_name); |
0ac862b4 | 771 | if (int_ret < 0) { |
0f60f957 | 772 | BT_LOGE_STR("Failed to set trace name."); |
0ac862b4 JD |
773 | ret = BT_COMPONENT_STATUS_ERROR; |
774 | goto end; | |
775 | } | |
776 | } | |
777 | ||
839d52a5 | 778 | trace_uuid = bt_trace_get_uuid(trace); |
76d2721c | 779 | if (trace_uuid) { |
839d52a5 | 780 | int_ret = bt_trace_set_uuid(writer_trace, trace_uuid); |
76d2721c | 781 | if (int_ret < 0) { |
0f60f957 | 782 | BT_LOGE_STR("Failed to set trace UUID."); |
76d2721c PP |
783 | ret = BT_COMPONENT_STATUS_ERROR; |
784 | goto end; | |
785 | } | |
786 | } | |
787 | ||
9ae49d3d | 788 | end: |
91b73004 JD |
789 | return ret; |
790 | } |