lib, plugins: use bt_field_class_type_is() where suitable
[babeltrace.git] / src / plugins / lttng-utils / debug-info / trace-ir-metadata-field-class-copy.c
CommitLineData
ca9f27f3
FD
1/*
2 * Babeltrace - Trace IR field copy
3 *
4 * Copyright (c) 2015-2019 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2018 Philippe Proulx <pproulx@efficios.com>
6 * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
91bc8451 27#define BT_COMP_LOG_SELF_COMP (md_maps->self_comp)
3a3d15f3 28#define BT_LOG_OUTPUT_LEVEL (md_maps->log_level)
350ad6c1 29#define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-META-FC-COPY"
d9c39b0a 30#include "logging/comp-logging.h"
ca9f27f3 31
578e048b
MJ
32#include "common/assert.h"
33#include "common/common.h"
34#include "compat/compiler.h"
3fadfbc0 35#include <babeltrace2/babeltrace.h>
ca9f27f3
FD
36
37#include "trace-ir-metadata-copy.h"
38#include "trace-ir-metadata-field-class-copy.h"
39
40/*
41 * This fonction walks througth the nested structures field class to resolve a
42 * field path object. A field path is made of indexes inside possibly nested
43 * structures ultimately leading to a field class.
44 */
45static
3a3d15f3
PP
46const bt_field_class *walk_field_path(struct trace_ir_metadata_maps *md_maps,
47 const bt_field_path *fp, const bt_field_class *fc)
ca9f27f3 48{
66ddcddf 49 uint64_t i, fp_item_count;
ca9f27f3
FD
50 const bt_field_class *curr_fc;
51
52 BT_ASSERT(bt_field_class_get_type(fc) == BT_FIELD_CLASS_TYPE_STRUCTURE);
91bc8451 53 BT_COMP_LOGD("Walking field path on field class: fp-addr=%p, fc-addr=%p",
bc463d34 54 fp, fc);
ca9f27f3 55
66ddcddf 56 fp_item_count = bt_field_path_get_item_count(fp);
ca9f27f3 57 curr_fc = fc;
66ddcddf 58 for (i = 0; i < fp_item_count; i++) {
ca9f27f3 59 bt_field_class_type fc_type = bt_field_class_get_type(curr_fc);
66ddcddf
PP
60 const bt_field_path_item *fp_item =
61 bt_field_path_borrow_item_by_index_const(fp, i);
ca9f27f3 62
ebdb6693 63 if (fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) {
66ddcddf
PP
64 const bt_field_class_structure_member *member;
65
66 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
67 BT_FIELD_PATH_ITEM_TYPE_INDEX);
68 member = bt_field_class_structure_borrow_member_by_index_const(
69 curr_fc,
70 bt_field_path_item_index_get_index(fp_item));
1e6fd1d7
PP
71 curr_fc = bt_field_class_structure_member_borrow_field_class_const(
72 member);
ebdb6693 73 } else if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_OPTION)) {
f29ef814
PP
74 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
75 BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
76 curr_fc = bt_field_class_option_borrow_field_class_const(
77 curr_fc);
ebdb6693
PP
78
79 } else if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_VARIANT)) {
66ddcddf
PP
80 const bt_field_class_variant_option *option;
81
82 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
83 BT_FIELD_PATH_ITEM_TYPE_INDEX);
84 option = bt_field_class_variant_borrow_option_by_index_const(
85 curr_fc,
86 bt_field_path_item_index_get_index(fp_item));
1e6fd1d7
PP
87 curr_fc = bt_field_class_variant_option_borrow_field_class_const(
88 option);
ca9f27f3 89 break;
ebdb6693 90 } else if (bt_field_class_type_is(fc_type, BT_FIELD_CLASS_TYPE_ARRAY)) {
66ddcddf
PP
91 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
92 BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
93 curr_fc = bt_field_class_array_borrow_element_field_class_const(
94 curr_fc);
95 break;
ebdb6693 96 } else {
ca9f27f3
FD
97 abort();
98 }
99 }
100
101 return curr_fc;
102}
103
104static
105const bt_field_class *resolve_field_path_to_field_class(const bt_field_path *fp,
106 struct trace_ir_metadata_maps *md_maps)
107{
108 struct field_class_resolving_context *fc_resolving_ctx;
109 const bt_field_class *fc;
e7ceb9df 110 bt_field_path_scope fp_scope;
ca9f27f3 111
91bc8451 112 BT_COMP_LOGD("Resolving field path: fp-addr=%p", fp);
ca9f27f3
FD
113
114 fc_resolving_ctx = md_maps->fc_resolving_ctx;
115 fp_scope = bt_field_path_get_root_scope(fp);
116
117 switch (fp_scope) {
e7ceb9df 118 case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
3a3d15f3
PP
119 fc = walk_field_path(md_maps, fp,
120 fc_resolving_ctx->packet_context);
ca9f27f3 121 break;
e7ceb9df 122 case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
3a3d15f3
PP
123 fc = walk_field_path(md_maps, fp,
124 fc_resolving_ctx->event_common_context);
ca9f27f3 125 break;
e7ceb9df 126 case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
3a3d15f3
PP
127 fc = walk_field_path(md_maps, fp,
128 fc_resolving_ctx->event_specific_context);
ca9f27f3 129 break;
e7ceb9df 130 case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
3a3d15f3
PP
131 fc = walk_field_path(md_maps, fp,
132 fc_resolving_ctx->event_payload);
ca9f27f3
FD
133 break;
134 default:
135 abort();
136 }
137
138 return fc;
139}
140
141static inline
142void field_class_integer_set_props(const bt_field_class *input_fc,
143 bt_field_class *output_fc)
144{
145 bt_field_class_integer_set_preferred_display_base(output_fc,
bc463d34 146 bt_field_class_integer_get_preferred_display_base(input_fc));
ca9f27f3 147 bt_field_class_integer_set_field_value_range(output_fc,
bc463d34 148 bt_field_class_integer_get_field_value_range(input_fc));
ca9f27f3
FD
149}
150
f7cfbcc3 151static inline
bc463d34 152int field_class_bool_copy(struct trace_ir_metadata_maps *md_maps,
f7cfbcc3
PP
153 const bt_field_class *in_field_class,
154 bt_field_class *out_field_class)
155{
156 BT_COMP_LOGD("Copying content of boolean field class: "
bc463d34
FD
157 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
158 /*
159 * There is no content to copy. Keep this function call anyway for
160 * logging purposes.
161 */
f7cfbcc3 162 BT_COMP_LOGD("Copied content of boolean field class: "
bc463d34 163 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f7cfbcc3
PP
164 return 0;
165}
166
dc7ac074
PP
167static inline
168int field_class_bit_array_copy(
169 struct trace_ir_metadata_maps *md_maps,
170 const bt_field_class *in_field_class,
171 bt_field_class *out_field_class)
172{
173 BT_COMP_LOGD("Copying content of bit array field class: "
bc463d34
FD
174 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
175 /*
176 * There is no content to copy. Keep this function call anyway for
177 * logging purposes.
178 */
dc7ac074 179 BT_COMP_LOGD("Copied content of bit array field class: "
bc463d34 180 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
dc7ac074
PP
181 return 0;
182}
183
ca9f27f3
FD
184static inline
185int field_class_unsigned_integer_copy(
186 struct trace_ir_metadata_maps *md_maps,
187 const bt_field_class *in_field_class,
188 bt_field_class *out_field_class)
189{
91bc8451 190 BT_COMP_LOGD("Copying content of unsigned integer field class: "
bc463d34 191 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
192
193 field_class_integer_set_props(in_field_class, out_field_class);
194
91bc8451 195 BT_COMP_LOGD("Copied content of unsigned integer field class: "
bc463d34 196 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
197 return 0;
198}
199
200static inline
201int field_class_signed_integer_copy(
202 struct trace_ir_metadata_maps *md_maps,
203 const bt_field_class *in_field_class,
204 bt_field_class *out_field_class)
205{
91bc8451 206 BT_COMP_LOGD("Copying content of signed integer field class: "
bc463d34 207 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
208
209 field_class_integer_set_props(in_field_class, out_field_class);
210
91bc8451 211 BT_COMP_LOGD("Copied content of signed integer field class: "
bc463d34 212 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
213 return 0;
214}
215
216BT_HIDDEN
217int field_class_unsigned_enumeration_copy(
218 struct trace_ir_metadata_maps *md_maps,
219 const bt_field_class *in_field_class,
220 bt_field_class *out_field_class)
221{
222 uint64_t i, enum_mapping_count;
223 int ret = 0;
224
91bc8451 225 BT_COMP_LOGD("Copying content of unsigned enumeration field class: "
bc463d34 226 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
227
228 /* Copy properties of the inner integer. */
229 field_class_integer_set_props(in_field_class, out_field_class);
230
231 /* Copy all enumeration entries. */
bc463d34
FD
232 enum_mapping_count = bt_field_class_enumeration_get_mapping_count(
233 in_field_class);
ca9f27f3
FD
234 for (i = 0; i < enum_mapping_count; i++) {
235 const char *label;
45c51519 236 const bt_integer_range_set_unsigned *range_set;
9c08c816 237 const bt_field_class_enumeration_unsigned_mapping *u_mapping;
8f3ccfbc 238 const bt_field_class_enumeration_mapping *mapping;
ca9f27f3 239
9c08c816 240 u_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
bc463d34 241 in_field_class, i);
9c08c816 242 mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(
8f3ccfbc 243 u_mapping);
45c51519 244 label = bt_field_class_enumeration_mapping_get_label(mapping);
9c08c816 245 range_set = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
45c51519 246 u_mapping);
9c08c816 247 ret = bt_field_class_enumeration_unsigned_add_mapping(
45c51519
PP
248 out_field_class, label, range_set);
249 if (ret) {
250 goto error;
ca9f27f3
FD
251 }
252 }
253
91bc8451 254 BT_COMP_LOGD("Copied content of unsigned enumeration field class: "
bc463d34 255 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
256
257error:
258 return ret;
259}
260
261static inline
262int field_class_signed_enumeration_copy(
263 struct trace_ir_metadata_maps *md_maps,
264 const bt_field_class *in_field_class,
265 bt_field_class *out_field_class)
266{
267 uint64_t i, enum_mapping_count;
268 int ret = 0;
269
91bc8451 270 BT_COMP_LOGD("Copying content of signed enumeration field class: "
bc463d34 271 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
272
273 /* Copy properties of the inner integer. */
274 field_class_integer_set_props(in_field_class, out_field_class);
275
276 /* Copy all enumeration entries. */
277 enum_mapping_count =
278 bt_field_class_enumeration_get_mapping_count(in_field_class);
279 for (i = 0; i < enum_mapping_count; i++) {
280 const char *label;
45c51519 281 const bt_integer_range_set_signed *range_set;
9c08c816 282 const bt_field_class_enumeration_signed_mapping *s_mapping;
8f3ccfbc 283 const bt_field_class_enumeration_mapping *mapping;
ca9f27f3 284
9c08c816 285 s_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
bc463d34 286 in_field_class, i);
9c08c816 287 mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(
45c51519
PP
288 s_mapping);
289 label = bt_field_class_enumeration_mapping_get_label(mapping);
9c08c816 290 range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
45c51519 291 s_mapping);
9c08c816 292 ret = bt_field_class_enumeration_signed_add_mapping(
45c51519
PP
293 out_field_class, label, range_set);
294 if (ret) {
295 goto error;
ca9f27f3
FD
296 }
297 }
298
91bc8451 299 BT_COMP_LOGD("Copied content of signed enumeration field class: "
bc463d34 300 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
301
302error:
303 return ret;
304}
305
306static inline
fe4df857 307int field_class_single_precision_real_copy(
ca9f27f3
FD
308 struct trace_ir_metadata_maps *md_maps,
309 const bt_field_class *in_field_class,
310 bt_field_class *out_field_class)
311{
fe4df857
FD
312 BT_COMP_LOGD("Copying content of single-precision real field class: "
313 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3 314
fe4df857
FD
315 BT_COMP_LOGD("Copied content single-precision real field class:"
316 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3 317
fe4df857
FD
318 return 0;
319}
320
321static inline
322int field_class_double_precision_real_copy(
323 struct trace_ir_metadata_maps *md_maps,
324 const bt_field_class *in_field_class,
325 bt_field_class *out_field_class)
326{
327 BT_COMP_LOGD("Copying content of double-precision real field class: "
328 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
329
330 BT_COMP_LOGD("Copied content double-precision real field class:"
331 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
332
333 return 0;
334}
335
336static inline
337int field_class_structure_copy(
338 struct trace_ir_metadata_maps *md_maps,
339 const bt_field_class *in_field_class,
340 bt_field_class *out_field_class)
341{
342 uint64_t i, struct_member_count;
ca9f27f3
FD
343 int ret = 0;
344
91bc8451 345 BT_COMP_LOGD("Copying content of structure field class: "
bc463d34 346 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
347 /* Get the number of member in that struct. */
348 struct_member_count =
349 bt_field_class_structure_get_member_count(in_field_class);
350
351 /* Iterate over all the members of the struct. */
352 for (i = 0; i < struct_member_count; i++) {
ce45f74a
PP
353 const bt_field_class_structure_member *in_member;
354 bt_field_class_structure_member *out_member;
ca9f27f3 355 const char *member_name;
ce45f74a 356 const bt_field_class *in_member_fc;
ca9f27f3
FD
357 bt_field_class *out_member_field_class;
358
ce45f74a 359 in_member = bt_field_class_structure_borrow_member_by_index_const(
1e6fd1d7 360 in_field_class, i);
ce45f74a
PP
361 in_member_fc = bt_field_class_structure_member_borrow_field_class_const(
362 in_member);
363 member_name = bt_field_class_structure_member_get_name(in_member);
91bc8451 364 BT_COMP_LOGD("Copying structure field class's field: "
bc463d34 365 "index=%" PRId64 ", member-fc-addr=%p, field-name=\"%s\"",
ce45f74a 366 i, in_member_fc, member_name);
ca9f27f3
FD
367
368 out_member_field_class = create_field_class_copy(md_maps,
ce45f74a 369 in_member_fc);
ca9f27f3 370 if (!out_member_field_class) {
91bc8451 371 BT_COMP_LOGE("Cannot copy structure field class's field: "
bc463d34 372 "index=%" PRId64 ", field-fc-addr=%p, field-name=\"%s\"",
ce45f74a 373 i, in_member_fc, member_name);
ca9f27f3
FD
374 ret = -1;
375 goto error;
376 }
ce45f74a 377 ret = copy_field_class_content(md_maps, in_member_fc,
ca9f27f3
FD
378 out_member_field_class);
379 if (ret) {
380 goto error;
381 }
382
d24d5663
PP
383 if (bt_field_class_structure_append_member(out_field_class,
384 member_name, out_member_field_class) !=
385 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
91bc8451 386 BT_COMP_LOGE("Cannot append structure field class's field: "
ca9f27f3
FD
387 "index=%" PRId64 ", "
388 "field-fc-addr=%p, field-name=\"%s\"",
ce45f74a 389 i, in_member_fc, member_name);
ca9f27f3
FD
390 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_member_field_class);
391 ret = -1;
392 goto error;
393 }
ce45f74a
PP
394
395 out_member = bt_field_class_structure_borrow_member_by_index(
396 out_field_class, i);
397 BT_ASSERT(out_member);
398
399 /*
400 * Safe to use the same value object because it's frozen
401 * at this point.
402 */
403 bt_field_class_structure_member_set_user_attributes(
404 out_member,
405 bt_field_class_structure_member_borrow_user_attributes_const(
406 in_member));
ca9f27f3
FD
407 }
408
91bc8451 409 BT_COMP_LOGD("Copied structure field class: original-fc-addr=%p, copy-fc-addr=%p",
ca9f27f3
FD
410 in_field_class, out_field_class);
411
412error:
413 return ret;
414}
415
416static inline
417int field_class_variant_copy(
418 struct trace_ir_metadata_maps *md_maps,
419 const bt_field_class *in_field_class,
420 bt_field_class *out_field_class)
421{
1ec009b2 422 bt_field_class *out_tag_field_class = NULL;
ca9f27f3 423 uint64_t i, variant_option_count;
45c51519 424 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
ca9f27f3
FD
425 int ret = 0;
426
91bc8451 427 BT_COMP_LOGD("Copying content of variant field class: "
bc463d34 428 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
429 variant_option_count =
430 bt_field_class_variant_get_option_count(in_field_class);
431 for (i = 0; i < variant_option_count; i++) {
ce45f74a 432 const bt_field_class *in_option_fc;
ca9f27f3
FD
433 const char *option_name;
434 bt_field_class *out_option_field_class;
ce45f74a
PP
435 const bt_field_class_variant_option *in_option;
436 bt_field_class_variant_option *out_option;
ca9f27f3 437
ce45f74a 438 in_option = bt_field_class_variant_borrow_option_by_index_const(
1e6fd1d7 439 in_field_class, i);
ce45f74a
PP
440 in_option_fc = bt_field_class_variant_option_borrow_field_class_const(
441 in_option);
442 option_name = bt_field_class_variant_option_get_name(in_option);
ca9f27f3 443 out_option_field_class = create_field_class_copy_internal(
ce45f74a 444 md_maps, in_option_fc);
ca9f27f3 445 if (!out_option_field_class) {
91bc8451 446 BT_COMP_LOGE_STR("Cannot copy field class.");
ca9f27f3
FD
447 ret = -1;
448 goto error;
449 }
ce45f74a 450 ret = copy_field_class_content_internal(md_maps, in_option_fc,
bc463d34 451 out_option_field_class);
ca9f27f3 452 if (ret) {
91bc8451 453 BT_COMP_LOGE_STR("Error copying content of option variant "
ca9f27f3
FD
454 "field class'");
455 goto error;
456 }
457
de821fe5
PP
458 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) {
459 const bt_field_class_variant_with_selector_field_integer_unsigned_option *spec_opt =
460 bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_index_const(
45c51519
PP
461 in_field_class, i);
462 const bt_integer_range_set_unsigned *ranges =
de821fe5 463 bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const(
45c51519
PP
464 spec_opt);
465
de821fe5 466 if (bt_field_class_variant_with_selector_field_integer_unsigned_append_option(
45c51519
PP
467 out_field_class, option_name,
468 out_option_field_class, ranges) !=
de821fe5 469 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_FIELD_APPEND_OPTION_STATUS_OK) {
fabfe034 470 BT_COMP_LOGE_STR("Cannot append option to variant field class with unsigned integer selector'");
45c51519
PP
471 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
472 ret = -1;
473 goto error;
474 }
de821fe5
PP
475 } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD) {
476 const bt_field_class_variant_with_selector_field_integer_signed_option *spec_opt =
477 bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_index_const(
45c51519
PP
478 in_field_class, i);
479 const bt_integer_range_set_signed *ranges =
de821fe5 480 bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const(
45c51519
PP
481 spec_opt);
482
de821fe5 483 if (bt_field_class_variant_with_selector_field_integer_signed_append_option(
45c51519
PP
484 out_field_class, option_name,
485 out_option_field_class, ranges) !=
de821fe5 486 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_FIELD_APPEND_OPTION_STATUS_OK) {
fabfe034 487 BT_COMP_LOGE_STR("Cannot append option to variant field class with signed integer selector'");
45c51519
PP
488 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
489 ret = -1;
490 goto error;
491 }
492 } else {
de821fe5 493 BT_ASSERT(fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD);
45c51519
PP
494
495 if (bt_field_class_variant_without_selector_append_option(
496 out_field_class, option_name,
497 out_option_field_class) !=
de821fe5 498 BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_FIELD_APPEND_OPTION_STATUS_OK) {
45c51519
PP
499 BT_COMP_LOGE_STR("Cannot append option to variant field class'");
500 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
501 ret = -1;
502 goto error;
503 }
ca9f27f3 504 }
ce45f74a
PP
505
506 out_option = bt_field_class_variant_borrow_option_by_index(
507 out_field_class, i);
508 BT_ASSERT(out_option);
509
510 /*
511 * Safe to use the same value object because it's frozen
512 * at this point.
513 */
514 bt_field_class_variant_option_set_user_attributes(
515 out_option,
516 bt_field_class_variant_option_borrow_user_attributes_const(
517 in_option));
ca9f27f3
FD
518 }
519
91bc8451 520 BT_COMP_LOGD("Copied content of variant field class: in-fc-addr=%p, "
ca9f27f3
FD
521 "out-fc-addr=%p", in_field_class, out_field_class);
522
523error:
524 return ret;
525}
526
527static inline
528int field_class_static_array_copy(
529 struct trace_ir_metadata_maps *md_maps,
530 const bt_field_class *in_field_class,
531 bt_field_class *out_field_class)
532{
91bc8451 533 BT_COMP_LOGD("Copying content of static array field class: in-fc-addr=%p, "
bc463d34 534 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
535 /*
536 * There is no content to copy. Keep this function call anyway for
537 * logging purposes.
538 */
91bc8451 539 BT_COMP_LOGD("Copied content of static array field class: in-fc-addr=%p, "
bc463d34 540 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
541
542 return 0;
543}
544
545static inline
546int field_class_dynamic_array_copy(
547 struct trace_ir_metadata_maps *md_maps,
548 const bt_field_class *in_field_class,
549 bt_field_class *out_field_class)
550{
91bc8451 551 BT_COMP_LOGD("Copying content of dynamic array field class: "
bc463d34 552 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
1367bc7c
PP
553 /*
554 * There is no content to copy. Keep this function call anyway for
555 * logging purposes.
556 */
bc463d34
FD
557 BT_COMP_LOGD("Copied content of dynamic array field class: "
558 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3 559
1367bc7c 560 return 0;
ca9f27f3
FD
561}
562
f29ef814
PP
563static inline
564int field_class_option_copy(
565 struct trace_ir_metadata_maps *md_maps,
566 const bt_field_class *in_field_class,
567 bt_field_class *out_field_class)
568{
569 BT_COMP_LOGD("Copying content of option field class: "
bc463d34 570 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f29ef814 571
0aa006b7 572 if (bt_field_class_get_type(out_field_class) ==
de821fe5
PP
573 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
574 bt_field_class_option_with_selector_field_bool_set_selector_is_reversed(
0aa006b7 575 out_field_class,
de821fe5 576 bt_field_class_option_with_selector_field_bool_selector_is_reversed(
0aa006b7
PP
577 in_field_class));
578 }
579
bc463d34
FD
580 BT_COMP_LOGD("Copied content of option field class: "
581 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f29ef814
PP
582
583 return 0;
584}
585
ca9f27f3
FD
586static inline
587int field_class_string_copy(struct trace_ir_metadata_maps *md_maps,
588 const bt_field_class *in_field_class,
589 bt_field_class *out_field_class)
590{
91bc8451 591 BT_COMP_LOGD("Copying content of string field class: in-fc-addr=%p, "
bc463d34 592 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
593 /*
594 * There is no content to copy. Keep this function call anyway for
595 * logging purposes.
596 */
91bc8451 597 BT_COMP_LOGD("Copied content of string field class: in-fc-addr=%p, "
bc463d34 598 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
599
600 return 0;
601}
602
603static
604bt_field_class *copy_field_class_array_element(struct trace_ir_metadata_maps *md_maps,
605 const bt_field_class *in_elem_fc)
606{
607 int ret;
608 bt_field_class *out_elem_fc =
609 create_field_class_copy_internal(md_maps, in_elem_fc);
610 if (!out_elem_fc) {
91bc8451 611 BT_COMP_LOGE("Error creating output elem field class "
bc463d34
FD
612 "from input elem field class for static array: "
613 "in-fc-addr=%p", in_elem_fc);
ca9f27f3
FD
614 goto error;
615 }
616
617 ret = copy_field_class_content_internal(md_maps, in_elem_fc, out_elem_fc);
618 if (ret) {
91bc8451 619 BT_COMP_LOGE("Error creating output elem field class "
bc463d34
FD
620 "from input elem field class for static array: "
621 "in-fc-addr=%p", in_elem_fc);
ca9f27f3
FD
622 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_elem_fc);
623 goto error;
624 }
625
626error:
627 return out_elem_fc;
628}
629
630BT_HIDDEN
631bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *md_maps,
632 const bt_field_class *in_field_class)
633{
634 bt_field_class *out_field_class = NULL;
45c51519 635 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
ca9f27f3 636
91bc8451 637 BT_COMP_LOGD("Creating bare field class based on field class: in-fc-addr=%p",
bc463d34 638 in_field_class);
ca9f27f3 639
45c51519 640 switch (fc_type) {
f7cfbcc3
PP
641 case BT_FIELD_CLASS_TYPE_BOOL:
642 out_field_class = bt_field_class_bool_create(
bc463d34 643 md_maps->output_trace_class);
f7cfbcc3 644 break;
dc7ac074
PP
645 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
646 out_field_class = bt_field_class_bit_array_create(
bc463d34
FD
647 md_maps->output_trace_class,
648 bt_field_class_bit_array_get_length(
649 in_field_class));
dc7ac074 650 break;
ca9f27f3 651 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
9c08c816 652 out_field_class = bt_field_class_integer_unsigned_create(
bc463d34 653 md_maps->output_trace_class);
ca9f27f3
FD
654 break;
655 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
9c08c816 656 out_field_class = bt_field_class_integer_signed_create(
bc463d34 657 md_maps->output_trace_class);
ca9f27f3
FD
658 break;
659 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
9c08c816 660 out_field_class = bt_field_class_enumeration_unsigned_create(
bc463d34 661 md_maps->output_trace_class);
ca9f27f3
FD
662 break;
663 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
9c08c816 664 out_field_class = bt_field_class_enumeration_signed_create(
bc463d34 665 md_maps->output_trace_class);
ca9f27f3 666 break;
fe4df857
FD
667 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
668 out_field_class = bt_field_class_real_single_precision_create(
bc463d34 669 md_maps->output_trace_class);
fe4df857
FD
670 break;
671 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
672 out_field_class = bt_field_class_real_double_precision_create(
bc463d34 673 md_maps->output_trace_class);
ca9f27f3
FD
674 break;
675 case BT_FIELD_CLASS_TYPE_STRING:
676 out_field_class = bt_field_class_string_create(
bc463d34 677 md_maps->output_trace_class);
ca9f27f3
FD
678 break;
679 case BT_FIELD_CLASS_TYPE_STRUCTURE:
680 out_field_class = bt_field_class_structure_create(
bc463d34 681 md_maps->output_trace_class);
ca9f27f3
FD
682 break;
683 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
684 {
685 const bt_field_class *in_elem_fc =
686 bt_field_class_array_borrow_element_field_class_const(
687 in_field_class);
bc463d34
FD
688 uint64_t array_len = bt_field_class_array_static_get_length(
689 in_field_class);
ca9f27f3
FD
690
691 bt_field_class *out_elem_fc = copy_field_class_array_element(
692 md_maps, in_elem_fc);
693 if (!out_elem_fc) {
694 out_field_class = NULL;
695 goto error;
696 }
697
9c08c816 698 out_field_class = bt_field_class_array_static_create(
bc463d34
FD
699 md_maps->output_trace_class,
700 out_elem_fc, array_len);
ca9f27f3
FD
701 break;
702 }
ebdb6693
PP
703 default:
704 break;
705 }
706
707 if (bt_field_class_type_is(fc_type,
708 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)) {
ca9f27f3
FD
709 const bt_field_class *in_elem_fc =
710 bt_field_class_array_borrow_element_field_class_const(
711 in_field_class);
1367bc7c 712 bt_field_class *out_length_fc = NULL;
ca9f27f3 713 bt_field_class *out_elem_fc = copy_field_class_array_element(
1367bc7c 714 md_maps, in_elem_fc);
81b8fa44 715
ca9f27f3
FD
716 if (!out_elem_fc) {
717 out_field_class = NULL;
718 goto error;
719 }
720
81b8fa44
PP
721 if (fc_type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) {
722 const bt_field_path *length_fp =
723 bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const(
724 in_field_class);
1367bc7c
PP
725 const bt_field_class *in_length_fc =
726 resolve_field_path_to_field_class(length_fp,
727 md_maps);
728
729 BT_ASSERT(in_length_fc);
730 out_length_fc = g_hash_table_lookup(md_maps->field_class_map,
731 in_length_fc);
732 BT_ASSERT(out_length_fc);
733 }
734
9c08c816 735 out_field_class = bt_field_class_array_dynamic_create(
bc463d34
FD
736 md_maps->output_trace_class,
737 out_elem_fc, out_length_fc);
ebdb6693
PP
738 } else if (bt_field_class_type_is(fc_type,
739 BT_FIELD_CLASS_TYPE_OPTION)) {
f29ef814
PP
740 const bt_field_class *in_content_fc =
741 bt_field_class_option_borrow_field_class_const(
bc463d34 742 in_field_class);
f29ef814
PP
743 bt_field_class *out_selector_fc = NULL;
744 bt_field_class *out_content_fc;
745 int ret;
746
747 out_content_fc = create_field_class_copy_internal(
bc463d34 748 md_maps, in_content_fc);
f29ef814
PP
749 if (!out_content_fc) {
750 BT_COMP_LOGE_STR("Cannot copy option's content field class.");
751 goto error;
752 }
753
754 ret = copy_field_class_content_internal(md_maps,
755 in_content_fc, out_content_fc);
756 if (ret) {
757 BT_COMP_LOGE_STR("Error copying content of option's "
758 "content field class");
759 goto error;
760 }
761
de821fe5 762 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD) {
0aa006b7
PP
763 out_field_class =
764 bt_field_class_option_without_selector_create(
765 md_maps->output_trace_class,
766 out_content_fc);
767 } else {
768 const bt_field_path *in_selector_fp =
de821fe5 769 bt_field_class_option_with_selector_field_borrow_selector_field_path_const(
0aa006b7
PP
770 in_field_class);
771 const bt_field_class *in_selector_fc;
f29ef814 772
0aa006b7
PP
773 BT_ASSERT(in_selector_fp);
774 in_selector_fc = resolve_field_path_to_field_class(
775 in_selector_fp, md_maps);
f29ef814
PP
776 BT_ASSERT(in_selector_fc);
777 out_selector_fc = g_hash_table_lookup(
778 md_maps->field_class_map, in_selector_fc);
779 BT_ASSERT(out_selector_fc);
0aa006b7 780
de821fe5 781 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
0aa006b7 782 out_field_class =
de821fe5 783 bt_field_class_option_with_selector_field_bool_create(
0aa006b7
PP
784 md_maps->output_trace_class,
785 out_content_fc, out_selector_fc);
de821fe5 786 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD) {
0aa006b7 787 const bt_integer_range_set_unsigned *ranges =
de821fe5 788 bt_field_class_option_with_selector_field_integer_unsigned_borrow_selector_ranges_const(
0aa006b7
PP
789 in_field_class);
790
791 BT_ASSERT(ranges);
792 out_field_class =
de821fe5 793 bt_field_class_option_with_selector_field_integer_unsigned_create(
0aa006b7
PP
794 md_maps->output_trace_class,
795 out_content_fc, out_selector_fc,
796 ranges);
de821fe5 797 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD) {
0aa006b7 798 const bt_integer_range_set_signed *ranges =
de821fe5 799 bt_field_class_option_with_selector_field_integer_signed_borrow_selector_ranges_const(
0aa006b7
PP
800 in_field_class);
801
802 BT_ASSERT(ranges);
803 out_field_class =
de821fe5 804 bt_field_class_option_with_selector_field_integer_signed_create(
0aa006b7
PP
805 md_maps->output_trace_class,
806 out_content_fc, out_selector_fc,
807 ranges);
808 }
f29ef814
PP
809 }
810
0aa006b7 811 BT_ASSERT(out_field_class);
ebdb6693
PP
812 } else if (bt_field_class_type_is(fc_type,
813 BT_FIELD_CLASS_TYPE_VARIANT)) {
45c51519
PP
814 bt_field_class *out_sel_fc = NULL;
815
ebdb6693
PP
816 if (bt_field_class_type_is(fc_type,
817 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SELECTOR_FIELD)) {
45c51519
PP
818 const bt_field_class *in_sel_fc;
819 const bt_field_path *sel_fp =
de821fe5 820 bt_field_class_variant_with_selector_field_borrow_selector_field_path_const(
45c51519
PP
821 in_field_class);
822
823 BT_ASSERT(sel_fp);
824 in_sel_fc = resolve_field_path_to_field_class(sel_fp,
825 md_maps);
826 BT_ASSERT(in_sel_fc);
827 out_sel_fc = g_hash_table_lookup(
828 md_maps->field_class_map, in_sel_fc);
829 BT_ASSERT(out_sel_fc);
830 }
831
ca9f27f3 832 out_field_class = bt_field_class_variant_create(
45c51519 833 md_maps->output_trace_class, out_sel_fc);
ca9f27f3
FD
834 }
835
836 /*
837 * Add mapping from in_field_class to out_field_class. This simplifies
838 * the resolution of field paths in variant and dynamic array field
839 * classes.
840 */
ebdb6693 841 BT_ASSERT(out_field_class);
ca9f27f3 842 g_hash_table_insert(md_maps->field_class_map,
bc463d34 843 (gpointer) in_field_class, out_field_class);
ca9f27f3
FD
844
845error:
846 if(out_field_class){
91bc8451 847 BT_COMP_LOGD("Created bare field class based on field class: in-fc-addr=%p, "
ca9f27f3
FD
848 "out-fc-addr=%p", in_field_class, out_field_class);
849 } else {
91bc8451 850 BT_COMP_LOGE("Error creating output field class from input field "
ca9f27f3
FD
851 "class: in-fc-addr=%p", in_field_class);
852 }
853
854 return out_field_class;
855}
856
857BT_HIDDEN
858int copy_field_class_content_internal(
859 struct trace_ir_metadata_maps *md_maps,
860 const bt_field_class *in_field_class,
861 bt_field_class *out_field_class)
862{
863 int ret = 0;
ebdb6693
PP
864 bt_field_class_type in_fc_type =
865 bt_field_class_get_type(in_field_class);
ce45f74a
PP
866
867 /*
868 * Safe to use the same value object because it's frozen at this
869 * point.
870 */
871 bt_field_class_set_user_attributes(out_field_class,
872 bt_field_class_borrow_user_attributes_const(in_field_class));
873
ebdb6693 874 if (in_fc_type == BT_FIELD_CLASS_TYPE_BOOL) {
f7cfbcc3
PP
875 ret = field_class_bool_copy(md_maps,
876 in_field_class, out_field_class);
ebdb6693 877 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_BIT_ARRAY) {
dc7ac074
PP
878 ret = field_class_bit_array_copy(md_maps,
879 in_field_class, out_field_class);
ebdb6693 880 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER) {
ca9f27f3
FD
881 ret = field_class_unsigned_integer_copy(md_maps,
882 in_field_class, out_field_class);
ebdb6693 883 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER) {
ca9f27f3
FD
884 ret = field_class_signed_integer_copy(md_maps,
885 in_field_class, out_field_class);
ebdb6693 886 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
ca9f27f3
FD
887 ret = field_class_unsigned_enumeration_copy(md_maps,
888 in_field_class, out_field_class);
ebdb6693 889 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) {
ca9f27f3
FD
890 ret = field_class_signed_enumeration_copy(md_maps,
891 in_field_class, out_field_class);
ebdb6693 892 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL) {
fe4df857
FD
893 ret = field_class_single_precision_real_copy(md_maps,
894 in_field_class, out_field_class);
ebdb6693 895 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL) {
fe4df857 896 ret = field_class_double_precision_real_copy(md_maps,
ca9f27f3 897 in_field_class, out_field_class);
ebdb6693 898 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_STRING) {
ca9f27f3
FD
899 ret = field_class_string_copy(md_maps,
900 in_field_class, out_field_class);
ebdb6693 901 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_STRUCTURE) {
ca9f27f3
FD
902 ret = field_class_structure_copy(md_maps,
903 in_field_class, out_field_class);
ebdb6693 904 } else if (in_fc_type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY) {
ca9f27f3
FD
905 ret = field_class_static_array_copy(md_maps,
906 in_field_class, out_field_class);
ebdb6693
PP
907 } else if (bt_field_class_type_is(in_fc_type,
908 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY)) {
ca9f27f3
FD
909 ret = field_class_dynamic_array_copy(md_maps,
910 in_field_class, out_field_class);
ebdb6693
PP
911 } else if (bt_field_class_type_is(in_fc_type,
912 BT_FIELD_CLASS_TYPE_OPTION)) {
f29ef814
PP
913 ret = field_class_option_copy(md_maps,
914 in_field_class, out_field_class);
ebdb6693
PP
915 } else if (bt_field_class_type_is(in_fc_type,
916 BT_FIELD_CLASS_TYPE_VARIANT)) {
ca9f27f3
FD
917 ret = field_class_variant_copy(md_maps,
918 in_field_class, out_field_class);
ebdb6693 919 } else {
ca9f27f3
FD
920 abort();
921 }
922
923 return ret;
924}
This page took 0.086356 seconds and 4 git commands to generate.