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) { | |
72f347b4 | 602 | ret = -1; |
0f60f957 | 603 | BT_LOGE_STR("Failed to get array field."); |
9ae49d3d | 604 | goto error; |
b2f1f465 JD |
605 | } |
606 | ||
607 | entry_copy = bt_ctf_field_array_get_field(copy_field, i); | |
0f60f957 | 608 | assert(entry_copy); |
b2f1f465 JD |
609 | |
610 | ret = copy_override_field(err, event, writer_event, entry_field, | |
611 | entry_copy); | |
b2f1f465 JD |
612 | if (ret) { |
613 | ret = -1; | |
0f60f957 | 614 | BT_LOGE_STR("Failed to override field in array."); |
9ae49d3d | 615 | goto error; |
b2f1f465 | 616 | } |
9ae49d3d JD |
617 | BT_PUT(entry_field); |
618 | BT_PUT(entry_copy); | |
b2f1f465 JD |
619 | } |
620 | ||
b2f1f465 | 621 | ret = 0; |
9ae49d3d JD |
622 | goto end; |
623 | ||
624 | error: | |
625 | bt_put(entry_field); | |
626 | bt_put(entry_copy); | |
b2f1f465 JD |
627 | |
628 | end: | |
629 | return ret; | |
630 | } | |
631 | ||
632 | static | |
633 | int copy_find_clock_struct_field(FILE *err, | |
634 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
635 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
636 | struct bt_ctf_field *copy_field) | |
637 | { | |
638 | int count, i, ret; | |
9ae49d3d JD |
639 | struct bt_ctf_field_type *entry_type = NULL; |
640 | struct bt_ctf_field *entry_field = NULL, *entry_copy = NULL; | |
b2f1f465 JD |
641 | |
642 | count = bt_ctf_field_type_structure_get_field_count(type); | |
643 | for (i = 0; i < count; i++) { | |
b2f1f465 | 644 | const char *entry_name; |
b2f1f465 JD |
645 | |
646 | entry_field = bt_ctf_field_structure_get_field_by_index(field, i); | |
647 | if (!entry_field) { | |
0f60f957 | 648 | BT_LOGE_STR("Failed to get struct field."); |
9ae49d3d | 649 | goto error; |
b2f1f465 JD |
650 | } |
651 | ||
652 | ret = bt_ctf_field_type_structure_get_field(type, &entry_name, | |
653 | &entry_type, i); | |
654 | if (ret) { | |
0f60f957 | 655 | BT_LOGE_STR("Failed to get struct field."); |
9ae49d3d | 656 | goto error; |
b2f1f465 JD |
657 | } |
658 | ||
659 | entry_copy = bt_ctf_field_structure_get_field_by_index(copy_field, i); | |
0f60f957 | 660 | assert(entry_copy); |
b2f1f465 JD |
661 | |
662 | ret = copy_override_field(err, event, writer_event, entry_field, | |
663 | entry_copy); | |
b2f1f465 | 664 | if (ret) { |
0f60f957 | 665 | BT_LOGE_STR("Failed to override field in struct."); |
9ae49d3d | 666 | goto error; |
b2f1f465 | 667 | } |
9ae49d3d JD |
668 | BT_PUT(entry_copy); |
669 | BT_PUT(entry_field); | |
670 | BT_PUT(entry_type); | |
b2f1f465 JD |
671 | } |
672 | ||
673 | ret = 0; | |
9ae49d3d | 674 | goto end; |
b2f1f465 | 675 | |
9ae49d3d JD |
676 | error: |
677 | bt_put(entry_type); | |
678 | bt_put(entry_field); | |
679 | bt_put(entry_copy); | |
680 | ret = -1; | |
b2f1f465 JD |
681 | end: |
682 | return ret; | |
683 | } | |
684 | ||
685 | static | |
686 | int set_int_value(FILE *err, struct bt_ctf_field *field, | |
687 | struct bt_ctf_field *copy_field, | |
688 | struct bt_ctf_field_type *type) | |
689 | { | |
690 | uint64_t uvalue; | |
691 | int64_t value; | |
692 | int ret; | |
693 | ||
694 | if (bt_ctf_field_type_integer_get_signed(type)) { | |
695 | ret = bt_ctf_field_signed_integer_get_value(field, &value); | |
696 | if (ret) { | |
0f60f957 JD |
697 | BT_LOGE("Failed to get value."); |
698 | goto error; | |
b2f1f465 | 699 | } |
0f60f957 | 700 | |
b2f1f465 JD |
701 | ret = bt_ctf_field_signed_integer_set_value(copy_field, value); |
702 | if (ret) { | |
703 | ret = -1; | |
0f60f957 | 704 | BT_LOGE_STR("Failed to set signed integer value."); |
b2f1f465 JD |
705 | goto end; |
706 | } | |
707 | } else { | |
708 | ret = bt_ctf_field_unsigned_integer_get_value(field, | |
709 | &uvalue); | |
710 | if (ret) { | |
0f60f957 JD |
711 | BT_LOGE("Failed to get value."); |
712 | goto error; | |
b2f1f465 | 713 | } |
0f60f957 | 714 | |
b2f1f465 JD |
715 | ret = bt_ctf_field_unsigned_integer_set_value(copy_field, uvalue); |
716 | if (ret) { | |
717 | ret = -1; | |
0f60f957 | 718 | BT_LOGE_STR("Failed to set unsigned integer value."); |
b2f1f465 JD |
719 | goto end; |
720 | } | |
721 | } | |
722 | ret = 0; | |
0f60f957 | 723 | goto end; |
b2f1f465 | 724 | |
0f60f957 JD |
725 | error: |
726 | ret = -1; | |
b2f1f465 JD |
727 | end: |
728 | return ret; | |
729 | } | |
730 | ||
731 | struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err, | |
732 | struct bt_ctf_stream_class *stream_class) | |
733 | { | |
9ae49d3d | 734 | struct bt_ctf_trace *trace = NULL; |
b2f1f465 JD |
735 | struct bt_ctf_clock_class *clock_class = NULL; |
736 | ||
737 | trace = bt_ctf_stream_class_get_trace(stream_class); | |
0f60f957 | 738 | assert(trace); |
b2f1f465 JD |
739 | |
740 | /* FIXME multi-clock? */ | |
9ac68eb1 | 741 | clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0); |
b2f1f465 JD |
742 | |
743 | bt_put(trace); | |
0f60f957 | 744 | |
b2f1f465 JD |
745 | return clock_class; |
746 | } | |
747 | ||
748 | struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event) | |
749 | { | |
9ae49d3d JD |
750 | struct bt_ctf_event_class *event_class = NULL; |
751 | struct bt_ctf_stream_class *stream_class = NULL; | |
b2f1f465 JD |
752 | struct bt_ctf_clock_class *clock_class = NULL; |
753 | ||
754 | event_class = bt_ctf_event_get_class(event); | |
0f60f957 | 755 | assert(event_class); |
b2f1f465 JD |
756 | |
757 | stream_class = bt_ctf_event_class_get_stream_class(event_class); | |
9ae49d3d | 758 | BT_PUT(event_class); |
0f60f957 | 759 | assert(stream_class); |
b2f1f465 JD |
760 | |
761 | clock_class = stream_class_get_clock_class(err, stream_class); | |
762 | bt_put(stream_class); | |
763 | ||
b2f1f465 JD |
764 | return clock_class; |
765 | } | |
766 | ||
767 | static | |
768 | int copy_find_clock_int_field(FILE *err, | |
769 | struct bt_ctf_event *event, struct bt_ctf_event *writer_event, | |
770 | struct bt_ctf_field *field, struct bt_ctf_field_type *type, | |
771 | struct bt_ctf_field *copy_field) | |
772 | { | |
9ae49d3d JD |
773 | struct bt_ctf_clock_class *clock_class = NULL, *writer_clock_class = NULL; |
774 | struct bt_ctf_clock_value *clock_value = NULL, *writer_clock_value = NULL; | |
b2f1f465 JD |
775 | uint64_t value; |
776 | int ret; | |
777 | ||
778 | clock_class = bt_ctf_field_type_integer_get_mapped_clock_class(type); | |
779 | if (!clock_class) { | |
780 | return set_int_value(err, field, copy_field, type); | |
781 | } | |
782 | ||
783 | clock_value = bt_ctf_event_get_clock_value(event, clock_class); | |
9ae49d3d | 784 | BT_PUT(clock_class); |
0f60f957 | 785 | assert(clock_value); |
b2f1f465 JD |
786 | |
787 | ret = bt_ctf_clock_value_get_value(clock_value, &value); | |
9ae49d3d | 788 | BT_PUT(clock_value); |
b2f1f465 | 789 | if (ret) { |
0f60f957 | 790 | BT_LOGE("Failed to get clock value."); |
9ae49d3d | 791 | goto error; |
b2f1f465 JD |
792 | } |
793 | ||
794 | ret = bt_ctf_field_unsigned_integer_set_value(copy_field, value); | |
795 | if (ret) { | |
0f60f957 | 796 | BT_LOGE_STR("Failed to set unsigned integer value."); |
9ae49d3d | 797 | goto error; |
b2f1f465 JD |
798 | } |
799 | ||
800 | writer_clock_class = event_get_clock_class(err, writer_event); | |
0f60f957 | 801 | assert(writer_clock_class); |
b2f1f465 JD |
802 | |
803 | writer_clock_value = bt_ctf_clock_value_create(writer_clock_class, value); | |
9ae49d3d | 804 | BT_PUT(writer_clock_class); |
b2f1f465 | 805 | if (!writer_clock_value) { |
0f60f957 | 806 | BT_LOGE_STR("Failed to create clock value."); |
9ae49d3d | 807 | goto error; |
b2f1f465 JD |
808 | } |
809 | ||
810 | ret = bt_ctf_event_set_clock_value(writer_event, writer_clock_value); | |
9ae49d3d | 811 | BT_PUT(writer_clock_value); |
b2f1f465 | 812 | if (ret) { |
0f60f957 | 813 | BT_LOGE_STR("Failed to set clock value."); |
9ae49d3d | 814 | goto error; |
b2f1f465 JD |
815 | } |
816 | ||
817 | ret = 0; | |
9ae49d3d | 818 | goto end; |
b2f1f465 | 819 | |
9ae49d3d JD |
820 | error: |
821 | ret = -1; | |
b2f1f465 JD |
822 | end: |
823 | return ret; | |
824 | } | |
825 |