Commit | Line | Data |
---|---|---|
b2f1f465 JD |
1 | /* |
2 | * clock-fields.c | |
3 | * | |
4 | * Babeltrace - Update clock fields to write uint64 values | |
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-CLOCK-FIELDS" |
30 | #include "logging.h" | |
31 | ||
b2f1f465 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 <babeltrace/ctf-ir/field-types.h> | |
41 | #include <assert.h> | |
42 | #include <stdio.h> | |
43 | ||
44 | #include "clock-fields.h" | |
45 | ||
46 | static | |
47 | int find_update_struct_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
48 | struct bt_ctf_clock_class *writer_clock_class); | |
49 | static | |
50 | int find_update_array_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
51 | struct bt_ctf_clock_class *writer_clock_class); | |
52 | static | |
53 | int find_update_enum_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
54 | struct bt_ctf_clock_class *writer_clock_class); | |
55 | static | |
56 | int find_update_sequence_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
57 | struct bt_ctf_clock_class *writer_clock_class); | |
58 | static | |
59 | int find_update_variant_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
60 | struct bt_ctf_clock_class *writer_clock_class); | |
61 | ||
62 | static | |
63 | int copy_find_clock_int_field(FILE *err, | |
64 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
65 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
66 | struct bt_ctf_field *copy_field); | |
67 | static | |
68 | int copy_find_clock_struct_field(FILE *err, | |
69 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
70 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
71 | struct bt_ctf_field *copy_field); | |
72 | static | |
73 | int copy_find_clock_array_field(FILE *err, | |
74 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
75 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
76 | struct bt_ctf_field *copy_field); | |
77 | static | |
78 | int copy_find_clock_sequence_field(FILE *err, | |
79 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
80 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
81 | struct bt_ctf_field *copy_field); | |
82 | static | |
83 | int copy_find_clock_variant_field(FILE *err, struct bt_ctf_event *event, | |
84 | struct bt_ctf_event *writer_event, struct bt_ctf_field *field, | |
85 | struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field); | |
86 | static | |
87 | int copy_find_clock_enum_field(FILE *err, struct bt_ctf_event *event, | |
88 | struct bt_ctf_event *writer_event, struct bt_ctf_field *field, | |
89 | struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field); | |
90 | ||
91 | static | |
92 | int update_header_clock_int_field_type(FILE *err, struct bt_ctf_field_type *type, | |
93 | struct bt_ctf_clock_class *writer_clock_class) | |
94 | { | |
9ae49d3d | 95 | struct bt_ctf_clock_class *clock = NULL; |
b2f1f465 JD |
96 | int ret; |
97 | ||
98 | clock = bt_ctf_field_type_integer_get_mapped_clock_class(type); | |
99 | if (!clock) { | |
100 | return 0; | |
101 | } | |
9ae49d3d | 102 | BT_PUT(clock); |
b2f1f465 JD |
103 | |
104 | ret = bt_ctf_field_type_integer_set_size(type, 64); | |
105 | if (ret) { | |
0f60f957 | 106 | BT_LOGE_STR("Failed to set integer size to 64."); |
b2f1f465 JD |
107 | goto end; |
108 | } | |
109 | ||
110 | ret = bt_ctf_field_type_integer_set_mapped_clock_class(type, | |
111 | writer_clock_class); | |
112 | if (ret) { | |
0f60f957 | 113 | BT_LOGE_STR("Failed to map integer to clock_class."); |
b2f1f465 JD |
114 | goto end; |
115 | } | |
116 | ||
117 | end: | |
118 | return ret; | |
119 | } | |
120 | ||
121 | static | |
122 | int find_update_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
123 | struct bt_ctf_clock_class *writer_clock_class) | |
124 | { | |
125 | int ret; | |
126 | ||
127 | switch (bt_ctf_field_type_get_type_id(type)) { | |
1487a16a | 128 | case BT_CTF_FIELD_TYPE_ID_INTEGER: |
b2f1f465 JD |
129 | return update_header_clock_int_field_type(err, type, |
130 | writer_clock_class); | |
1487a16a | 131 | case BT_CTF_FIELD_TYPE_ID_STRUCT: |
b2f1f465 JD |
132 | return find_update_struct_clock_fields(err, type, |
133 | writer_clock_class); | |
1487a16a | 134 | case BT_CTF_FIELD_TYPE_ID_ARRAY: |
b2f1f465 JD |
135 | return find_update_array_clock_fields(err, type, |
136 | writer_clock_class); | |
1487a16a | 137 | case BT_CTF_FIELD_TYPE_ID_SEQUENCE: |
b2f1f465 JD |
138 | return find_update_sequence_clock_fields(err, type, |
139 | writer_clock_class); | |
1487a16a | 140 | case BT_CTF_FIELD_TYPE_ID_VARIANT: |
b2f1f465 JD |
141 | return find_update_variant_clock_fields(err, type, |
142 | writer_clock_class); | |
1487a16a | 143 | case BT_CTF_FIELD_TYPE_ID_ENUM: |
b2f1f465 JD |
144 | return find_update_enum_clock_fields(err, type, |
145 | writer_clock_class); | |
146 | break; | |
147 | default: | |
148 | break; | |
149 | } | |
150 | ||
151 | ret = 0; | |
152 | ||
153 | return ret; | |
154 | } | |
155 | ||
156 | static | |
157 | int find_update_variant_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
158 | struct bt_ctf_clock_class *writer_clock_class) | |
159 | { | |
160 | int count, i, ret; | |
9ae49d3d | 161 | struct bt_ctf_field_type *entry_type = NULL; |
b2f1f465 JD |
162 | |
163 | count = bt_ctf_field_type_variant_get_field_count(type); | |
164 | for (i = 0; i < count; i++) { | |
b2f1f465 JD |
165 | const char *entry_name; |
166 | ||
167 | ret = bt_ctf_field_type_variant_get_field(type, | |
168 | &entry_name, &entry_type, i); | |
169 | if (ret) { | |
0f60f957 | 170 | BT_LOGE_STR("Failed to get variant field."); |
9ae49d3d | 171 | goto error; |
b2f1f465 | 172 | } |
0f60f957 | 173 | |
b2f1f465 JD |
174 | ret = find_update_clock_fields(err, entry_type, |
175 | writer_clock_class); | |
b2f1f465 | 176 | if (ret) { |
0f60f957 | 177 | BT_LOGE_STR("Failed to find clock fields."); |
9ae49d3d | 178 | goto error; |
b2f1f465 | 179 | } |
9ae49d3d | 180 | BT_PUT(entry_type); |
b2f1f465 JD |
181 | } |
182 | ||
183 | ret = 0; | |
9ae49d3d | 184 | goto end; |
b2f1f465 | 185 | |
9ae49d3d JD |
186 | error: |
187 | ret = -1; | |
b2f1f465 | 188 | end: |
9ae49d3d | 189 | bt_put(entry_type); |
b2f1f465 JD |
190 | return ret; |
191 | } | |
192 | ||
193 | static | |
194 | int find_update_struct_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
195 | struct bt_ctf_clock_class *writer_clock_class) | |
196 | { | |
197 | int count, i, ret; | |
9ae49d3d | 198 | struct bt_ctf_field_type *entry_type = NULL; |
b2f1f465 JD |
199 | |
200 | count = bt_ctf_field_type_structure_get_field_count(type); | |
201 | for (i = 0; i < count; i++) { | |
b2f1f465 JD |
202 | const char *entry_name; |
203 | ||
204 | ret = bt_ctf_field_type_structure_get_field(type, | |
205 | &entry_name, &entry_type, i); | |
206 | if (ret) { | |
0f60f957 | 207 | BT_LOGE_STR("Failed to get struct field."); |
9ae49d3d | 208 | goto error; |
b2f1f465 | 209 | } |
0f60f957 | 210 | |
b2f1f465 JD |
211 | ret = find_update_clock_fields(err, entry_type, |
212 | writer_clock_class); | |
b2f1f465 | 213 | if (ret) { |
0f60f957 | 214 | BT_LOGE_STR("Failed to find clock fields."); |
9ae49d3d | 215 | goto error; |
b2f1f465 | 216 | } |
9ae49d3d | 217 | BT_PUT(entry_type); |
b2f1f465 JD |
218 | } |
219 | ||
220 | ret = 0; | |
9ae49d3d | 221 | goto end; |
b2f1f465 | 222 | |
9ae49d3d JD |
223 | error: |
224 | bt_put(entry_type); | |
b2f1f465 JD |
225 | end: |
226 | return ret; | |
227 | } | |
228 | ||
229 | static | |
230 | int find_update_sequence_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
231 | struct bt_ctf_clock_class *writer_clock_class) | |
232 | { | |
233 | int ret; | |
9ae49d3d | 234 | struct bt_ctf_field_type *entry_type = NULL; |
b2f1f465 JD |
235 | |
236 | entry_type = bt_ctf_field_type_sequence_get_element_type(type); | |
0f60f957 JD |
237 | assert(entry_type); |
238 | ||
b2f1f465 | 239 | ret = find_update_clock_fields(err, entry_type, writer_clock_class); |
9ae49d3d | 240 | BT_PUT(entry_type); |
b2f1f465 | 241 | if (ret) { |
0f60f957 | 242 | BT_LOGE_STR("Failed to find clock fields."); |
9ae49d3d | 243 | goto error; |
b2f1f465 JD |
244 | } |
245 | ||
246 | ret = 0; | |
9ae49d3d | 247 | goto end; |
b2f1f465 | 248 | |
9ae49d3d JD |
249 | error: |
250 | ret = -1; | |
b2f1f465 JD |
251 | end: |
252 | return ret; | |
253 | } | |
254 | ||
255 | static | |
256 | int find_update_array_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
257 | struct bt_ctf_clock_class *writer_clock_class) | |
258 | { | |
0f60f957 | 259 | int ret = 0; |
9ae49d3d | 260 | struct bt_ctf_field_type *entry_type = NULL; |
b2f1f465 JD |
261 | |
262 | entry_type = bt_ctf_field_type_array_get_element_type(type); | |
0f60f957 JD |
263 | assert(entry_type); |
264 | ||
b2f1f465 | 265 | ret = find_update_clock_fields(err, entry_type, writer_clock_class); |
9ae49d3d | 266 | BT_PUT(entry_type); |
b2f1f465 | 267 | if (ret) { |
0f60f957 | 268 | BT_LOGE_STR("Failed to find clock fields."); |
b2f1f465 JD |
269 | ret = -1; |
270 | goto end; | |
271 | } | |
272 | ||
b2f1f465 JD |
273 | end: |
274 | return ret; | |
275 | } | |
276 | ||
277 | static | |
278 | int find_update_enum_clock_fields(FILE *err, struct bt_ctf_field_type *type, | |
279 | struct bt_ctf_clock_class *writer_clock_class) | |
280 | { | |
281 | int ret; | |
9ae49d3d | 282 | struct bt_ctf_field_type *entry_type = NULL; |
b2f1f465 JD |
283 | |
284 | entry_type = bt_ctf_field_type_enumeration_get_container_type(type); | |
0f60f957 JD |
285 | assert(entry_type); |
286 | ||
b2f1f465 | 287 | ret = find_update_clock_fields(err, entry_type, writer_clock_class); |
9ae49d3d | 288 | BT_PUT(entry_type); |
b2f1f465 | 289 | if (ret) { |
0f60f957 | 290 | BT_LOGE_STR("Failed to find clock fields."); |
9ae49d3d | 291 | goto error; |
b2f1f465 JD |
292 | } |
293 | ||
294 | ret = 0; | |
9ae49d3d | 295 | goto end; |
b2f1f465 | 296 | |
9ae49d3d JD |
297 | error: |
298 | ret = -1; | |
b2f1f465 JD |
299 | end: |
300 | return ret; | |
301 | } | |
302 | ||
303 | BT_HIDDEN | |
304 | struct bt_ctf_field_type *override_header_type(FILE *err, | |
305 | struct bt_ctf_field_type *type, | |
306 | struct bt_ctf_trace *writer_trace) | |
307 | { | |
308 | struct bt_ctf_field_type *new_type = NULL; | |
9ae49d3d | 309 | struct bt_ctf_clock_class *writer_clock_class = NULL; |
b2f1f465 | 310 | int ret; |
b2f1f465 JD |
311 | |
312 | /* FIXME multi-clock? */ | |
9ac68eb1 | 313 | writer_clock_class = bt_ctf_trace_get_clock_class_by_index(writer_trace, 0); |
0f60f957 | 314 | assert(writer_clock_class); |
b2f1f465 JD |
315 | |
316 | new_type = bt_ctf_field_type_copy(type); | |
317 | if (!new_type) { | |
0f60f957 | 318 | BT_LOGE_STR("Failed to copy field type."); |
9ae49d3d | 319 | goto error; |
b2f1f465 JD |
320 | } |
321 | ||
1487a16a | 322 | if (bt_ctf_field_type_get_type_id(new_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) { |
0f60f957 JD |
323 | BT_LOGE("Expected header field type to be struct: type=%d", |
324 | bt_ctf_field_type_get_type_id(new_type)); | |
b2f1f465 JD |
325 | goto error; |
326 | } | |
327 | ||
328 | ret = find_update_struct_clock_fields(err, new_type, writer_clock_class); | |
329 | if (ret) { | |
0f60f957 | 330 | BT_LOGE_STR("Failed to find clock fields in struct."); |
b2f1f465 JD |
331 | goto error; |
332 | } | |
9ae49d3d | 333 | BT_PUT(writer_clock_class); |
b2f1f465 | 334 | |
9ae49d3d | 335 | goto end; |
b2f1f465 JD |
336 | |
337 | error: | |
b2f1f465 | 338 | bt_put(writer_clock_class); |
9ae49d3d | 339 | BT_PUT(new_type); |
b2f1f465 JD |
340 | end: |
341 | return new_type; | |
342 | } | |
343 | ||
344 | static | |
345 | int copy_float_field(FILE *err, struct bt_ctf_field *field, | |
346 | struct bt_ctf_field_type *type, | |
347 | struct bt_ctf_field *copy_field) | |
348 | { | |
349 | double value; | |
350 | int ret; | |
351 | ||
352 | ret = bt_ctf_field_floating_point_get_value(field, &value); | |
353 | if (ret) { | |
0f60f957 JD |
354 | BT_LOGE_STR("Failed to get value."); |
355 | goto error; | |
b2f1f465 | 356 | } |
0f60f957 | 357 | |
b2f1f465 JD |
358 | ret = bt_ctf_field_floating_point_set_value(copy_field, value); |
359 | if (ret) { | |
360 | ret = -1; | |
0f60f957 | 361 | BT_LOGE_STR("Failed to set floating point value."); |
b2f1f465 JD |
362 | goto end; |
363 | } | |
364 | ||
365 | ret = 0; | |
0f60f957 | 366 | goto end; |
b2f1f465 | 367 | |
0f60f957 JD |
368 | error: |
369 | ret = -1; | |
b2f1f465 JD |
370 | end: |
371 | return ret; | |
372 | } | |
373 | ||
374 | static | |
375 | int copy_string_field(FILE *err, struct bt_ctf_field *field, | |
376 | struct bt_ctf_field_type *type, | |
377 | struct bt_ctf_field *copy_field) | |
378 | { | |
379 | const char *value; | |
380 | int ret; | |
381 | ||
382 | value = bt_ctf_field_string_get_value(field); | |
383 | if (!value) { | |
0f60f957 JD |
384 | BT_LOGE_STR("Failed to get value."); |
385 | goto error; | |
b2f1f465 | 386 | } |
0f60f957 | 387 | |
b2f1f465 JD |
388 | ret = bt_ctf_field_string_set_value(copy_field, value); |
389 | if (ret) { | |
390 | ret = -1; | |
0f60f957 | 391 | BT_LOGE_STR("Failed to set string value."); |
b2f1f465 JD |
392 | goto end; |
393 | } | |
394 | ||
395 | ret = 0; | |
0f60f957 | 396 | goto end; |
b2f1f465 | 397 | |
0f60f957 JD |
398 | error: |
399 | ret = -1; | |
b2f1f465 JD |
400 | end: |
401 | return ret; | |
402 | } | |
403 | ||
404 | BT_HIDDEN | |
405 | int copy_override_field(FILE *err, struct bt_ctf_event *event, | |
406 | struct bt_ctf_event *writer_event, struct bt_ctf_field *field, | |
407 | struct bt_ctf_field *copy_field) | |
408 | { | |
9ae49d3d | 409 | struct bt_ctf_field_type *type = NULL; |
0f60f957 | 410 | int ret = 0; |
b2f1f465 JD |
411 | |
412 | type = bt_ctf_field_get_type(field); | |
0f60f957 | 413 | assert(type); |
b2f1f465 JD |
414 | |
415 | switch (bt_ctf_field_type_get_type_id(type)) { | |
1487a16a | 416 | case BT_CTF_FIELD_TYPE_ID_INTEGER: |
b2f1f465 JD |
417 | ret = copy_find_clock_int_field(err, event, writer_event, |
418 | field, type, copy_field); | |
419 | break; | |
1487a16a | 420 | case BT_CTF_FIELD_TYPE_ID_STRUCT: |
b2f1f465 JD |
421 | ret = copy_find_clock_struct_field(err, event, writer_event, |
422 | field, type, copy_field); | |
423 | break; | |
1487a16a | 424 | case BT_CTF_FIELD_TYPE_ID_FLOAT: |
b2f1f465 JD |
425 | ret = copy_float_field(err, field, type, copy_field); |
426 | break; | |
1487a16a | 427 | case BT_CTF_FIELD_TYPE_ID_ENUM: |
b2f1f465 JD |
428 | ret = copy_find_clock_enum_field(err, event, writer_event, |
429 | field, type, copy_field); | |
430 | break; | |
1487a16a | 431 | case BT_CTF_FIELD_TYPE_ID_STRING: |
b2f1f465 JD |
432 | ret = copy_string_field(err, field, type, copy_field); |
433 | break; | |
1487a16a | 434 | case BT_CTF_FIELD_TYPE_ID_ARRAY: |
b2f1f465 JD |
435 | ret = copy_find_clock_array_field(err, event, writer_event, |
436 | field, type, copy_field); | |
437 | break; | |
1487a16a | 438 | case BT_CTF_FIELD_TYPE_ID_SEQUENCE: |
b2f1f465 JD |
439 | ret = copy_find_clock_sequence_field(err, event, writer_event, |
440 | field, type, copy_field); | |
441 | break; | |
1487a16a | 442 | case BT_CTF_FIELD_TYPE_ID_VARIANT: |
b2f1f465 JD |
443 | ret = copy_find_clock_variant_field(err, event, writer_event, |
444 | field, type, copy_field); | |
445 | break; | |
446 | /* No default, we want to catch missing field types. */ | |
1487a16a | 447 | case BT_CTF_FIELD_TYPE_ID_UNKNOWN: |
b2f1f465 JD |
448 | case BT_CTF_NR_TYPE_IDS: |
449 | break; | |
450 | } | |
451 | ||
9ae49d3d | 452 | BT_PUT(type); |
b2f1f465 | 453 | |
b2f1f465 JD |
454 | return ret; |
455 | } | |
456 | ||
457 | static | |
458 | int copy_find_clock_enum_field(FILE *err, struct bt_ctf_event *event, | |
459 | struct bt_ctf_event *writer_event, struct bt_ctf_field *field, | |
460 | struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field) | |
461 | { | |
462 | int ret; | |
9ae49d3d | 463 | struct bt_ctf_field *container = NULL, *copy_container = NULL; |
b2f1f465 JD |
464 | |
465 | container = bt_ctf_field_enumeration_get_container(field); | |
0f60f957 | 466 | assert(container); |
b2f1f465 JD |
467 | |
468 | copy_container = bt_ctf_field_enumeration_get_container(copy_field); | |
0f60f957 | 469 | assert(copy_container); |
b2f1f465 JD |
470 | |
471 | ret = copy_override_field(err, event, writer_event, container, | |
472 | copy_container); | |
473 | if (ret) { | |
474 | ret = -1; | |
0f60f957 | 475 | BT_LOGE_STR("Failed to override enum field."); |
9ae49d3d | 476 | goto error; |
b2f1f465 | 477 | } |
9ac68eb1 | 478 | |
9ae49d3d JD |
479 | ret = 0; |
480 | goto end; | |
b2f1f465 | 481 | |
9ae49d3d JD |
482 | error: |
483 | ret = -1; | |
484 | end: | |
b2f1f465 | 485 | bt_put(copy_container); |
b2f1f465 | 486 | bt_put(container); |
b2f1f465 JD |
487 | return ret; |
488 | } | |
489 | ||
490 | static | |
491 | int copy_find_clock_variant_field(FILE *err, struct bt_ctf_event *event, | |
492 | struct bt_ctf_event *writer_event, struct bt_ctf_field *field, | |
493 | struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field) | |
494 | { | |
495 | int ret; | |
9ae49d3d JD |
496 | struct bt_ctf_field *tag = NULL; |
497 | struct bt_ctf_field *variant_field = NULL, *copy_variant_field = NULL; | |
b2f1f465 JD |
498 | |
499 | tag = bt_ctf_field_variant_get_tag(field); | |
0f60f957 | 500 | assert(tag); |
b2f1f465 JD |
501 | |
502 | variant_field = bt_ctf_field_variant_get_field(field, tag); | |
503 | if (!variant_field) { | |
0f60f957 | 504 | BT_LOGE_STR("Failed to get variant field."); |
9ae49d3d | 505 | goto error; |
b2f1f465 JD |
506 | } |
507 | ||
508 | copy_variant_field = bt_ctf_field_variant_get_field(copy_field, tag); | |
0f60f957 | 509 | assert(copy_variant_field); |
b2f1f465 JD |
510 | |
511 | ret = copy_override_field(err, event, writer_event, variant_field, | |
512 | copy_variant_field); | |
513 | if (ret) { | |
0f60f957 | 514 | BT_LOGE_STR("Failed to override variant field."); |
9ae49d3d | 515 | goto error; |
b2f1f465 JD |
516 | } |
517 | ||
518 | ret = 0; | |
9ae49d3d | 519 | goto end; |
b2f1f465 | 520 | |
9ae49d3d JD |
521 | error: |
522 | ret = -1; | |
523 | end: | |
b2f1f465 | 524 | bt_put(copy_variant_field); |
b2f1f465 | 525 | bt_put(variant_field); |
b2f1f465 | 526 | bt_put(tag); |
b2f1f465 JD |
527 | return ret; |
528 | } | |
529 | ||
530 | static | |
531 | int copy_find_clock_sequence_field(FILE *err, | |
532 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
533 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
534 | struct bt_ctf_field *copy_field) | |
535 | { | |
536 | int ret; | |
537 | uint64_t i, count; | |
9ae49d3d JD |
538 | struct bt_ctf_field *length_field = NULL; |
539 | struct bt_ctf_field *entry_field = NULL, *entry_copy = NULL; | |
b2f1f465 JD |
540 | |
541 | length_field = bt_ctf_field_sequence_get_length(field); | |
0f60f957 | 542 | assert(length_field); |
b2f1f465 JD |
543 | |
544 | ret = bt_ctf_field_unsigned_integer_get_value(length_field, &count); | |
545 | if (ret) { | |
0f60f957 | 546 | BT_LOGE("Failed to get value."); |
9ae49d3d | 547 | goto error; |
b2f1f465 JD |
548 | } |
549 | ||
550 | ret = bt_ctf_field_sequence_set_length(copy_field, length_field); | |
b2f1f465 | 551 | if (ret) { |
0f60f957 | 552 | BT_LOGE_STR("Failed to set sequence length."); |
9ae49d3d | 553 | goto error; |
b2f1f465 | 554 | } |
9ae49d3d | 555 | BT_PUT(length_field); |
b2f1f465 JD |
556 | |
557 | for (i = 0; i < count; i++) { | |
b2f1f465 JD |
558 | entry_field = bt_ctf_field_sequence_get_field(field, i); |
559 | if (!entry_field) { | |
0f60f957 | 560 | BT_LOGE_STR("Failed to get sequence field."); |
9ae49d3d | 561 | goto error; |
b2f1f465 JD |
562 | } |
563 | ||
564 | entry_copy = bt_ctf_field_sequence_get_field(copy_field, i); | |
0f60f957 | 565 | assert(entry_copy); |
b2f1f465 JD |
566 | |
567 | ret = copy_override_field(err, event, writer_event, entry_field, | |
568 | entry_copy); | |
b2f1f465 | 569 | if (ret) { |
0f60f957 | 570 | BT_LOGE_STR("Faield to override field in sequence."); |
9ae49d3d | 571 | goto error; |
b2f1f465 | 572 | } |
9ae49d3d JD |
573 | BT_PUT(entry_field); |
574 | BT_PUT(entry_copy); | |
b2f1f465 JD |
575 | } |
576 | ||
b2f1f465 | 577 | ret = 0; |
9ae49d3d | 578 | goto end; |
b2f1f465 | 579 | |
9ae49d3d JD |
580 | error: |
581 | bt_put(length_field); | |
582 | bt_put(entry_field); | |
583 | bt_put(entry_copy); | |
584 | ret = -1; | |
b2f1f465 JD |
585 | end: |
586 | return ret; | |
587 | } | |
588 | ||
589 | static | |
590 | int copy_find_clock_array_field(FILE *err, | |
591 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
592 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
593 | struct bt_ctf_field *copy_field) | |
594 | { | |
595 | int ret, count, i; | |
9ae49d3d | 596 | struct bt_ctf_field *entry_field = NULL, *entry_copy = NULL; |
b2f1f465 JD |
597 | |
598 | count = bt_ctf_field_type_array_get_length(type); | |
b2f1f465 | 599 | for (i = 0; i < count; i++) { |
b2f1f465 JD |
600 | entry_field = bt_ctf_field_array_get_field(field, i); |
601 | if (!entry_field) { | |
0f60f957 | 602 | BT_LOGE_STR("Failed to get array field."); |
9ae49d3d | 603 | goto error; |
b2f1f465 JD |
604 | } |
605 | ||
606 | entry_copy = bt_ctf_field_array_get_field(copy_field, i); | |
0f60f957 | 607 | assert(entry_copy); |
b2f1f465 JD |
608 | |
609 | ret = copy_override_field(err, event, writer_event, entry_field, | |
610 | entry_copy); | |
b2f1f465 JD |
611 | if (ret) { |
612 | ret = -1; | |
0f60f957 | 613 | BT_LOGE_STR("Failed to override field in array."); |
9ae49d3d | 614 | goto error; |
b2f1f465 | 615 | } |
9ae49d3d JD |
616 | BT_PUT(entry_field); |
617 | BT_PUT(entry_copy); | |
b2f1f465 JD |
618 | } |
619 | ||
b2f1f465 | 620 | ret = 0; |
9ae49d3d JD |
621 | goto end; |
622 | ||
623 | error: | |
624 | bt_put(entry_field); | |
625 | bt_put(entry_copy); | |
b2f1f465 JD |
626 | |
627 | end: | |
628 | return ret; | |
629 | } | |
630 | ||
631 | static | |
632 | int copy_find_clock_struct_field(FILE *err, | |
633 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
634 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
635 | struct bt_ctf_field *copy_field) | |
636 | { | |
637 | int count, i, ret; | |
9ae49d3d JD |
638 | struct bt_ctf_field_type *entry_type = NULL; |
639 | struct bt_ctf_field *entry_field = NULL, *entry_copy = NULL; | |
b2f1f465 JD |
640 | |
641 | count = bt_ctf_field_type_structure_get_field_count(type); | |
642 | for (i = 0; i < count; i++) { | |
b2f1f465 | 643 | const char *entry_name; |
b2f1f465 JD |
644 | |
645 | entry_field = bt_ctf_field_structure_get_field_by_index(field, i); | |
646 | if (!entry_field) { | |
0f60f957 | 647 | BT_LOGE_STR("Failed to get struct field."); |
9ae49d3d | 648 | goto error; |
b2f1f465 JD |
649 | } |
650 | ||
651 | ret = bt_ctf_field_type_structure_get_field(type, &entry_name, | |
652 | &entry_type, i); | |
653 | if (ret) { | |
0f60f957 | 654 | BT_LOGE_STR("Failed to get struct field."); |
9ae49d3d | 655 | goto error; |
b2f1f465 JD |
656 | } |
657 | ||
658 | entry_copy = bt_ctf_field_structure_get_field_by_index(copy_field, i); | |
0f60f957 | 659 | assert(entry_copy); |
b2f1f465 JD |
660 | |
661 | ret = copy_override_field(err, event, writer_event, entry_field, | |
662 | entry_copy); | |
b2f1f465 | 663 | if (ret) { |
0f60f957 | 664 | BT_LOGE_STR("Failed to override field in struct."); |
9ae49d3d | 665 | goto error; |
b2f1f465 | 666 | } |
9ae49d3d JD |
667 | BT_PUT(entry_copy); |
668 | BT_PUT(entry_field); | |
669 | BT_PUT(entry_type); | |
b2f1f465 JD |
670 | } |
671 | ||
672 | ret = 0; | |
9ae49d3d | 673 | goto end; |
b2f1f465 | 674 | |
9ae49d3d JD |
675 | error: |
676 | bt_put(entry_type); | |
677 | bt_put(entry_field); | |
678 | bt_put(entry_copy); | |
679 | ret = -1; | |
b2f1f465 JD |
680 | end: |
681 | return ret; | |
682 | } | |
683 | ||
684 | static | |
685 | int set_int_value(FILE *err, struct bt_ctf_field *field, | |
686 | struct bt_ctf_field *copy_field, | |
687 | struct bt_ctf_field_type *type) | |
688 | { | |
689 | uint64_t uvalue; | |
690 | int64_t value; | |
691 | int ret; | |
692 | ||
693 | if (bt_ctf_field_type_integer_get_signed(type)) { | |
694 | ret = bt_ctf_field_signed_integer_get_value(field, &value); | |
695 | if (ret) { | |
0f60f957 JD |
696 | BT_LOGE("Failed to get value."); |
697 | goto error; | |
b2f1f465 | 698 | } |
0f60f957 | 699 | |
b2f1f465 JD |
700 | ret = bt_ctf_field_signed_integer_set_value(copy_field, value); |
701 | if (ret) { | |
702 | ret = -1; | |
0f60f957 | 703 | BT_LOGE_STR("Failed to set signed integer value."); |
b2f1f465 JD |
704 | goto end; |
705 | } | |
706 | } else { | |
707 | ret = bt_ctf_field_unsigned_integer_get_value(field, | |
708 | &uvalue); | |
709 | if (ret) { | |
0f60f957 JD |
710 | BT_LOGE("Failed to get value."); |
711 | goto error; | |
b2f1f465 | 712 | } |
0f60f957 | 713 | |
b2f1f465 JD |
714 | ret = bt_ctf_field_unsigned_integer_set_value(copy_field, uvalue); |
715 | if (ret) { | |
716 | ret = -1; | |
0f60f957 | 717 | BT_LOGE_STR("Failed to set unsigned integer value."); |
b2f1f465 JD |
718 | goto end; |
719 | } | |
720 | } | |
721 | ret = 0; | |
0f60f957 | 722 | goto end; |
b2f1f465 | 723 | |
0f60f957 JD |
724 | error: |
725 | ret = -1; | |
b2f1f465 JD |
726 | end: |
727 | return ret; | |
728 | } | |
729 | ||
730 | struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err, | |
731 | struct bt_ctf_stream_class *stream_class) | |
732 | { | |
9ae49d3d | 733 | struct bt_ctf_trace *trace = NULL; |
b2f1f465 JD |
734 | struct bt_ctf_clock_class *clock_class = NULL; |
735 | ||
736 | trace = bt_ctf_stream_class_get_trace(stream_class); | |
0f60f957 | 737 | assert(trace); |
b2f1f465 JD |
738 | |
739 | /* FIXME multi-clock? */ | |
9ac68eb1 | 740 | clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0); |
b2f1f465 JD |
741 | |
742 | bt_put(trace); | |
0f60f957 | 743 | |
b2f1f465 JD |
744 | return clock_class; |
745 | } | |
746 | ||
747 | struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event) | |
748 | { | |
9ae49d3d JD |
749 | struct bt_ctf_event_class *event_class = NULL; |
750 | struct bt_ctf_stream_class *stream_class = NULL; | |
b2f1f465 JD |
751 | struct bt_ctf_clock_class *clock_class = NULL; |
752 | ||
753 | event_class = bt_ctf_event_get_class(event); | |
0f60f957 | 754 | assert(event_class); |
b2f1f465 JD |
755 | |
756 | stream_class = bt_ctf_event_class_get_stream_class(event_class); | |
9ae49d3d | 757 | BT_PUT(event_class); |
0f60f957 | 758 | assert(stream_class); |
b2f1f465 JD |
759 | |
760 | clock_class = stream_class_get_clock_class(err, stream_class); | |
761 | bt_put(stream_class); | |
762 | ||
b2f1f465 JD |
763 | return clock_class; |
764 | } | |
765 | ||
766 | static | |
767 | int copy_find_clock_int_field(FILE *err, | |
768 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
769 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
770 | struct bt_ctf_field *copy_field) | |
771 | { | |
9ae49d3d JD |
772 | struct bt_ctf_clock_class *clock_class = NULL, *writer_clock_class = NULL; |
773 | struct bt_ctf_clock_value *clock_value = NULL, *writer_clock_value = NULL; | |
b2f1f465 JD |
774 | uint64_t value; |
775 | int ret; | |
776 | ||
777 | clock_class = bt_ctf_field_type_integer_get_mapped_clock_class(type); | |
778 | if (!clock_class) { | |
779 | return set_int_value(err, field, copy_field, type); | |
780 | } | |
781 | ||
782 | clock_value = bt_ctf_event_get_clock_value(event, clock_class); | |
9ae49d3d | 783 | BT_PUT(clock_class); |
0f60f957 | 784 | assert(clock_value); |
b2f1f465 JD |
785 | |
786 | ret = bt_ctf_clock_value_get_value(clock_value, &value); | |
9ae49d3d | 787 | BT_PUT(clock_value); |
b2f1f465 | 788 | if (ret) { |
0f60f957 | 789 | BT_LOGE("Failed to get clock value."); |
9ae49d3d | 790 | goto error; |
b2f1f465 JD |
791 | } |
792 | ||
793 | ret = bt_ctf_field_unsigned_integer_set_value(copy_field, value); | |
794 | if (ret) { | |
0f60f957 | 795 | BT_LOGE_STR("Failed to set unsigned integer value."); |
9ae49d3d | 796 | goto error; |
b2f1f465 JD |
797 | } |
798 | ||
799 | writer_clock_class = event_get_clock_class(err, writer_event); | |
0f60f957 | 800 | assert(writer_clock_class); |
b2f1f465 JD |
801 | |
802 | writer_clock_value = bt_ctf_clock_value_create(writer_clock_class, value); | |
9ae49d3d | 803 | BT_PUT(writer_clock_class); |
b2f1f465 | 804 | if (!writer_clock_value) { |
0f60f957 | 805 | BT_LOGE_STR("Failed to create clock value."); |
9ae49d3d | 806 | goto error; |
b2f1f465 JD |
807 | } |
808 | ||
809 | ret = bt_ctf_event_set_clock_value(writer_event, writer_clock_value); | |
9ae49d3d | 810 | BT_PUT(writer_clock_value); |
b2f1f465 | 811 | if (ret) { |
0f60f957 | 812 | BT_LOGE_STR("Failed to set clock value."); |
9ae49d3d | 813 | goto error; |
b2f1f465 JD |
814 | } |
815 | ||
816 | ret = 0; | |
9ae49d3d | 817 | goto end; |
b2f1f465 | 818 | |
9ae49d3d JD |
819 | error: |
820 | ret = -1; | |
b2f1f465 JD |
821 | end: |
822 | return ret; | |
823 | } | |
824 |