lib: have dedicated "dynamic array FC with/without length field" types
[babeltrace.git] / src / plugins / lttng-utils / debug-info / trace-ir-metadata-field-class-copy.c
CommitLineData
58f6d595
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
475e740e 27#define BT_COMP_LOG_SELF_COMP (md_maps->self_comp)
a07aba4f 28#define BT_LOG_OUTPUT_LEVEL (md_maps->log_level)
b03487ab 29#define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-META-FC-COPY"
3fa1b6a3 30#include "logging/comp-logging.h"
58f6d595 31
57952005
MJ
32#include "common/assert.h"
33#include "common/common.h"
34#include "compat/compiler.h"
71c5da58 35#include <babeltrace2/babeltrace.h>
58f6d595
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
a07aba4f
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)
58f6d595 48{
1d4afa5f 49 uint64_t i, fp_item_count;
58f6d595
FD
50 const bt_field_class *curr_fc;
51
52 BT_ASSERT(bt_field_class_get_type(fc) == BT_FIELD_CLASS_TYPE_STRUCTURE);
475e740e 53 BT_COMP_LOGD("Walking field path on field class: fp-addr=%p, fc-addr=%p",
9a51bfb2 54 fp, fc);
58f6d595 55
1d4afa5f 56 fp_item_count = bt_field_path_get_item_count(fp);
58f6d595 57 curr_fc = fc;
1d4afa5f 58 for (i = 0; i < fp_item_count; i++) {
58f6d595 59 bt_field_class_type fc_type = bt_field_class_get_type(curr_fc);
1d4afa5f
PP
60 const bt_field_path_item *fp_item =
61 bt_field_path_borrow_item_by_index_const(fp, i);
58f6d595
FD
62
63 switch (fc_type) {
64 case BT_FIELD_CLASS_TYPE_STRUCTURE:
e24f271a 65 {
1d4afa5f
PP
66 const bt_field_class_structure_member *member;
67
68 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
69 BT_FIELD_PATH_ITEM_TYPE_INDEX);
70 member = bt_field_class_structure_borrow_member_by_index_const(
71 curr_fc,
72 bt_field_path_item_index_get_index(fp_item));
e24f271a
PP
73 curr_fc = bt_field_class_structure_member_borrow_field_class_const(
74 member);
58f6d595 75 break;
e24f271a 76 }
467673c1
PP
77 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
78 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
79 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
80 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
978237e9
PP
81 {
82 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
83 BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
84 curr_fc = bt_field_class_option_borrow_field_class_const(
85 curr_fc);
86 break;
87 }
02b61fe0 88 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
0822832b
PP
89 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
90 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
e24f271a 91 {
1d4afa5f
PP
92 const bt_field_class_variant_option *option;
93
94 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
95 BT_FIELD_PATH_ITEM_TYPE_INDEX);
96 option = bt_field_class_variant_borrow_option_by_index_const(
97 curr_fc,
98 bt_field_path_item_index_get_index(fp_item));
e24f271a
PP
99 curr_fc = bt_field_class_variant_option_borrow_field_class_const(
100 option);
58f6d595 101 break;
e24f271a 102 }
1d4afa5f 103 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
b8ddb4f0
PP
104 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD:
105 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD:
1d4afa5f
PP
106 {
107 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
108 BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
109 curr_fc = bt_field_class_array_borrow_element_field_class_const(
110 curr_fc);
111 break;
112 }
58f6d595
FD
113 default:
114 abort();
115 }
116 }
117
118 return curr_fc;
119}
120
121static
122const bt_field_class *resolve_field_path_to_field_class(const bt_field_path *fp,
123 struct trace_ir_metadata_maps *md_maps)
124{
125 struct field_class_resolving_context *fc_resolving_ctx;
126 const bt_field_class *fc;
056995e5 127 bt_field_path_scope fp_scope;
58f6d595 128
475e740e 129 BT_COMP_LOGD("Resolving field path: fp-addr=%p", fp);
58f6d595
FD
130
131 fc_resolving_ctx = md_maps->fc_resolving_ctx;
132 fp_scope = bt_field_path_get_root_scope(fp);
133
134 switch (fp_scope) {
056995e5 135 case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
a07aba4f
PP
136 fc = walk_field_path(md_maps, fp,
137 fc_resolving_ctx->packet_context);
58f6d595 138 break;
056995e5 139 case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
a07aba4f
PP
140 fc = walk_field_path(md_maps, fp,
141 fc_resolving_ctx->event_common_context);
58f6d595 142 break;
056995e5 143 case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
a07aba4f
PP
144 fc = walk_field_path(md_maps, fp,
145 fc_resolving_ctx->event_specific_context);
58f6d595 146 break;
056995e5 147 case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
a07aba4f
PP
148 fc = walk_field_path(md_maps, fp,
149 fc_resolving_ctx->event_payload);
58f6d595
FD
150 break;
151 default:
152 abort();
153 }
154
155 return fc;
156}
157
158static inline
159void field_class_integer_set_props(const bt_field_class *input_fc,
160 bt_field_class *output_fc)
161{
162 bt_field_class_integer_set_preferred_display_base(output_fc,
9a51bfb2 163 bt_field_class_integer_get_preferred_display_base(input_fc));
58f6d595 164 bt_field_class_integer_set_field_value_range(output_fc,
9a51bfb2 165 bt_field_class_integer_get_field_value_range(input_fc));
58f6d595
FD
166}
167
41bdd7c1 168static inline
9a51bfb2 169int field_class_bool_copy(struct trace_ir_metadata_maps *md_maps,
41bdd7c1
PP
170 const bt_field_class *in_field_class,
171 bt_field_class *out_field_class)
172{
173 BT_COMP_LOGD("Copying content of boolean field class: "
9a51bfb2
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 */
41bdd7c1 179 BT_COMP_LOGD("Copied content of boolean field class: "
9a51bfb2 180 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
41bdd7c1
PP
181 return 0;
182}
183
f5f2c882
PP
184static inline
185int field_class_bit_array_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{
190 BT_COMP_LOGD("Copying content of bit array field class: "
9a51bfb2
FD
191 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
192 /*
193 * There is no content to copy. Keep this function call anyway for
194 * logging purposes.
195 */
f5f2c882 196 BT_COMP_LOGD("Copied content of bit array field class: "
9a51bfb2 197 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f5f2c882
PP
198 return 0;
199}
200
58f6d595
FD
201static inline
202int field_class_unsigned_integer_copy(
203 struct trace_ir_metadata_maps *md_maps,
204 const bt_field_class *in_field_class,
205 bt_field_class *out_field_class)
206{
475e740e 207 BT_COMP_LOGD("Copying content of unsigned integer field class: "
9a51bfb2 208 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
209
210 field_class_integer_set_props(in_field_class, out_field_class);
211
475e740e 212 BT_COMP_LOGD("Copied content of unsigned integer field class: "
9a51bfb2 213 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
214 return 0;
215}
216
217static inline
218int field_class_signed_integer_copy(
219 struct trace_ir_metadata_maps *md_maps,
220 const bt_field_class *in_field_class,
221 bt_field_class *out_field_class)
222{
475e740e 223 BT_COMP_LOGD("Copying content of signed integer field class: "
9a51bfb2 224 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
225
226 field_class_integer_set_props(in_field_class, out_field_class);
227
475e740e 228 BT_COMP_LOGD("Copied content of signed integer field class: "
9a51bfb2 229 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
230 return 0;
231}
232
233BT_HIDDEN
234int field_class_unsigned_enumeration_copy(
235 struct trace_ir_metadata_maps *md_maps,
236 const bt_field_class *in_field_class,
237 bt_field_class *out_field_class)
238{
239 uint64_t i, enum_mapping_count;
240 int ret = 0;
241
475e740e 242 BT_COMP_LOGD("Copying content of unsigned enumeration field class: "
9a51bfb2 243 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
244
245 /* Copy properties of the inner integer. */
246 field_class_integer_set_props(in_field_class, out_field_class);
247
248 /* Copy all enumeration entries. */
9a51bfb2
FD
249 enum_mapping_count = bt_field_class_enumeration_get_mapping_count(
250 in_field_class);
58f6d595
FD
251 for (i = 0; i < enum_mapping_count; i++) {
252 const char *label;
02b61fe0 253 const bt_integer_range_set_unsigned *range_set;
60bbfc7c 254 const bt_field_class_enumeration_unsigned_mapping *u_mapping;
b6baf3bb 255 const bt_field_class_enumeration_mapping *mapping;
58f6d595 256
60bbfc7c 257 u_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
9a51bfb2 258 in_field_class, i);
60bbfc7c 259 mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(
b6baf3bb 260 u_mapping);
02b61fe0 261 label = bt_field_class_enumeration_mapping_get_label(mapping);
60bbfc7c 262 range_set = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
02b61fe0 263 u_mapping);
60bbfc7c 264 ret = bt_field_class_enumeration_unsigned_add_mapping(
02b61fe0
PP
265 out_field_class, label, range_set);
266 if (ret) {
267 goto error;
58f6d595
FD
268 }
269 }
270
475e740e 271 BT_COMP_LOGD("Copied content of unsigned enumeration field class: "
9a51bfb2 272 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
273
274error:
275 return ret;
276}
277
278static inline
279int field_class_signed_enumeration_copy(
280 struct trace_ir_metadata_maps *md_maps,
281 const bt_field_class *in_field_class,
282 bt_field_class *out_field_class)
283{
284 uint64_t i, enum_mapping_count;
285 int ret = 0;
286
475e740e 287 BT_COMP_LOGD("Copying content of signed enumeration field class: "
9a51bfb2 288 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
289
290 /* Copy properties of the inner integer. */
291 field_class_integer_set_props(in_field_class, out_field_class);
292
293 /* Copy all enumeration entries. */
294 enum_mapping_count =
295 bt_field_class_enumeration_get_mapping_count(in_field_class);
296 for (i = 0; i < enum_mapping_count; i++) {
297 const char *label;
02b61fe0 298 const bt_integer_range_set_signed *range_set;
60bbfc7c 299 const bt_field_class_enumeration_signed_mapping *s_mapping;
b6baf3bb 300 const bt_field_class_enumeration_mapping *mapping;
58f6d595 301
60bbfc7c 302 s_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
9a51bfb2 303 in_field_class, i);
60bbfc7c 304 mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(
02b61fe0
PP
305 s_mapping);
306 label = bt_field_class_enumeration_mapping_get_label(mapping);
60bbfc7c 307 range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
02b61fe0 308 s_mapping);
60bbfc7c 309 ret = bt_field_class_enumeration_signed_add_mapping(
02b61fe0
PP
310 out_field_class, label, range_set);
311 if (ret) {
312 goto error;
58f6d595
FD
313 }
314 }
315
475e740e 316 BT_COMP_LOGD("Copied content of signed enumeration field class: "
9a51bfb2 317 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
318
319error:
320 return ret;
321}
322
323static inline
76276a81 324int field_class_single_precision_real_copy(
58f6d595
FD
325 struct trace_ir_metadata_maps *md_maps,
326 const bt_field_class *in_field_class,
327 bt_field_class *out_field_class)
328{
76276a81
FD
329 BT_COMP_LOGD("Copying content of single-precision real field class: "
330 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595 331
76276a81
FD
332 BT_COMP_LOGD("Copied content single-precision real field class:"
333 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595 334
76276a81
FD
335 return 0;
336}
337
338static inline
339int field_class_double_precision_real_copy(
340 struct trace_ir_metadata_maps *md_maps,
341 const bt_field_class *in_field_class,
342 bt_field_class *out_field_class)
343{
344 BT_COMP_LOGD("Copying content of double-precision real field class: "
345 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
346
347 BT_COMP_LOGD("Copied content double-precision real field class:"
348 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
349
350 return 0;
351}
352
353static inline
354int field_class_structure_copy(
355 struct trace_ir_metadata_maps *md_maps,
356 const bt_field_class *in_field_class,
357 bt_field_class *out_field_class)
358{
359 uint64_t i, struct_member_count;
58f6d595
FD
360 int ret = 0;
361
475e740e 362 BT_COMP_LOGD("Copying content of structure field class: "
9a51bfb2 363 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
364 /* Get the number of member in that struct. */
365 struct_member_count =
366 bt_field_class_structure_get_member_count(in_field_class);
367
368 /* Iterate over all the members of the struct. */
369 for (i = 0; i < struct_member_count; i++) {
84ff66df
PP
370 const bt_field_class_structure_member *in_member;
371 bt_field_class_structure_member *out_member;
58f6d595 372 const char *member_name;
84ff66df 373 const bt_field_class *in_member_fc;
58f6d595
FD
374 bt_field_class *out_member_field_class;
375
84ff66df 376 in_member = bt_field_class_structure_borrow_member_by_index_const(
e24f271a 377 in_field_class, i);
84ff66df
PP
378 in_member_fc = bt_field_class_structure_member_borrow_field_class_const(
379 in_member);
380 member_name = bt_field_class_structure_member_get_name(in_member);
475e740e 381 BT_COMP_LOGD("Copying structure field class's field: "
9a51bfb2 382 "index=%" PRId64 ", member-fc-addr=%p, field-name=\"%s\"",
84ff66df 383 i, in_member_fc, member_name);
58f6d595
FD
384
385 out_member_field_class = create_field_class_copy(md_maps,
84ff66df 386 in_member_fc);
58f6d595 387 if (!out_member_field_class) {
475e740e 388 BT_COMP_LOGE("Cannot copy structure field class's field: "
9a51bfb2 389 "index=%" PRId64 ", field-fc-addr=%p, field-name=\"%s\"",
84ff66df 390 i, in_member_fc, member_name);
58f6d595
FD
391 ret = -1;
392 goto error;
393 }
84ff66df 394 ret = copy_field_class_content(md_maps, in_member_fc,
58f6d595
FD
395 out_member_field_class);
396 if (ret) {
397 goto error;
398 }
399
fb25b9e3
PP
400 if (bt_field_class_structure_append_member(out_field_class,
401 member_name, out_member_field_class) !=
402 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
475e740e 403 BT_COMP_LOGE("Cannot append structure field class's field: "
58f6d595
FD
404 "index=%" PRId64 ", "
405 "field-fc-addr=%p, field-name=\"%s\"",
84ff66df 406 i, in_member_fc, member_name);
58f6d595
FD
407 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_member_field_class);
408 ret = -1;
409 goto error;
410 }
84ff66df
PP
411
412 out_member = bt_field_class_structure_borrow_member_by_index(
413 out_field_class, i);
414 BT_ASSERT(out_member);
415
416 /*
417 * Safe to use the same value object because it's frozen
418 * at this point.
419 */
420 bt_field_class_structure_member_set_user_attributes(
421 out_member,
422 bt_field_class_structure_member_borrow_user_attributes_const(
423 in_member));
58f6d595
FD
424 }
425
475e740e 426 BT_COMP_LOGD("Copied structure field class: original-fc-addr=%p, copy-fc-addr=%p",
58f6d595
FD
427 in_field_class, out_field_class);
428
429error:
430 return ret;
431}
432
433static inline
434int field_class_variant_copy(
435 struct trace_ir_metadata_maps *md_maps,
436 const bt_field_class *in_field_class,
437 bt_field_class *out_field_class)
438{
98d2f974 439 bt_field_class *out_tag_field_class = NULL;
58f6d595 440 uint64_t i, variant_option_count;
02b61fe0 441 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
58f6d595
FD
442 int ret = 0;
443
475e740e 444 BT_COMP_LOGD("Copying content of variant field class: "
9a51bfb2 445 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
446 variant_option_count =
447 bt_field_class_variant_get_option_count(in_field_class);
448 for (i = 0; i < variant_option_count; i++) {
84ff66df 449 const bt_field_class *in_option_fc;
58f6d595
FD
450 const char *option_name;
451 bt_field_class *out_option_field_class;
84ff66df
PP
452 const bt_field_class_variant_option *in_option;
453 bt_field_class_variant_option *out_option;
58f6d595 454
84ff66df 455 in_option = bt_field_class_variant_borrow_option_by_index_const(
e24f271a 456 in_field_class, i);
84ff66df
PP
457 in_option_fc = bt_field_class_variant_option_borrow_field_class_const(
458 in_option);
459 option_name = bt_field_class_variant_option_get_name(in_option);
58f6d595 460 out_option_field_class = create_field_class_copy_internal(
84ff66df 461 md_maps, in_option_fc);
58f6d595 462 if (!out_option_field_class) {
475e740e 463 BT_COMP_LOGE_STR("Cannot copy field class.");
58f6d595
FD
464 ret = -1;
465 goto error;
466 }
84ff66df 467 ret = copy_field_class_content_internal(md_maps, in_option_fc,
9a51bfb2 468 out_option_field_class);
58f6d595 469 if (ret) {
475e740e 470 BT_COMP_LOGE_STR("Error copying content of option variant "
58f6d595
FD
471 "field class'");
472 goto error;
473 }
474
0822832b
PP
475 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR) {
476 const bt_field_class_variant_with_selector_integer_unsigned_option *spec_opt =
477 bt_field_class_variant_with_selector_integer_unsigned_borrow_option_by_index_const(
02b61fe0
PP
478 in_field_class, i);
479 const bt_integer_range_set_unsigned *ranges =
0822832b 480 bt_field_class_variant_with_selector_integer_unsigned_option_borrow_ranges_const(
02b61fe0
PP
481 spec_opt);
482
0822832b 483 if (bt_field_class_variant_with_selector_integer_unsigned_append_option(
02b61fe0
PP
484 out_field_class, option_name,
485 out_option_field_class, ranges) !=
486 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
0822832b 487 BT_COMP_LOGE_STR("Cannot append option to variant field class with unsigned integer selector'");
02b61fe0
PP
488 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
489 ret = -1;
490 goto error;
491 }
0822832b
PP
492 } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR) {
493 const bt_field_class_variant_with_selector_integer_signed_option *spec_opt =
494 bt_field_class_variant_with_selector_integer_signed_borrow_option_by_index_const(
02b61fe0
PP
495 in_field_class, i);
496 const bt_integer_range_set_signed *ranges =
0822832b 497 bt_field_class_variant_with_selector_integer_signed_option_borrow_ranges_const(
02b61fe0
PP
498 spec_opt);
499
0822832b 500 if (bt_field_class_variant_with_selector_integer_signed_append_option(
02b61fe0
PP
501 out_field_class, option_name,
502 out_option_field_class, ranges) !=
503 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
0822832b 504 BT_COMP_LOGE_STR("Cannot append option to variant field class with signed integer selector'");
02b61fe0
PP
505 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
506 ret = -1;
507 goto error;
508 }
509 } else {
510 BT_ASSERT(fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR);
511
512 if (bt_field_class_variant_without_selector_append_option(
513 out_field_class, option_name,
514 out_option_field_class) !=
515 BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_OK) {
516 BT_COMP_LOGE_STR("Cannot append option to variant field class'");
517 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
518 ret = -1;
519 goto error;
520 }
58f6d595 521 }
84ff66df
PP
522
523 out_option = bt_field_class_variant_borrow_option_by_index(
524 out_field_class, i);
525 BT_ASSERT(out_option);
526
527 /*
528 * Safe to use the same value object because it's frozen
529 * at this point.
530 */
531 bt_field_class_variant_option_set_user_attributes(
532 out_option,
533 bt_field_class_variant_option_borrow_user_attributes_const(
534 in_option));
58f6d595
FD
535 }
536
475e740e 537 BT_COMP_LOGD("Copied content of variant field class: in-fc-addr=%p, "
58f6d595
FD
538 "out-fc-addr=%p", in_field_class, out_field_class);
539
540error:
541 return ret;
542}
543
544static inline
545int field_class_static_array_copy(
546 struct trace_ir_metadata_maps *md_maps,
547 const bt_field_class *in_field_class,
548 bt_field_class *out_field_class)
549{
475e740e 550 BT_COMP_LOGD("Copying content of static array field class: in-fc-addr=%p, "
9a51bfb2 551 "out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
552 /*
553 * There is no content to copy. Keep this function call anyway for
554 * logging purposes.
555 */
475e740e 556 BT_COMP_LOGD("Copied content of static array field class: in-fc-addr=%p, "
9a51bfb2 557 "out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
558
559 return 0;
560}
561
562static inline
563int field_class_dynamic_array_copy(
564 struct trace_ir_metadata_maps *md_maps,
565 const bt_field_class *in_field_class,
566 bt_field_class *out_field_class)
567{
475e740e 568 BT_COMP_LOGD("Copying content of dynamic array field class: "
9a51bfb2 569 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
93d7d5d1
PP
570 /*
571 * There is no content to copy. Keep this function call anyway for
572 * logging purposes.
573 */
9a51bfb2
FD
574 BT_COMP_LOGD("Copied content of dynamic array field class: "
575 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
58f6d595 576
93d7d5d1 577 return 0;
58f6d595
FD
578}
579
978237e9
PP
580static inline
581int field_class_option_copy(
582 struct trace_ir_metadata_maps *md_maps,
583 const bt_field_class *in_field_class,
584 bt_field_class *out_field_class)
585{
586 BT_COMP_LOGD("Copying content of option field class: "
9a51bfb2 587 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
978237e9 588
467673c1
PP
589 if (bt_field_class_get_type(out_field_class) ==
590 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
591 bt_field_class_option_with_selector_bool_set_selector_is_reversed(
592 out_field_class,
593 bt_field_class_option_with_selector_bool_selector_is_reversed(
594 in_field_class));
595 }
596
9a51bfb2
FD
597 BT_COMP_LOGD("Copied content of option field class: "
598 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
978237e9
PP
599
600 return 0;
601}
602
58f6d595
FD
603static inline
604int field_class_string_copy(struct trace_ir_metadata_maps *md_maps,
605 const bt_field_class *in_field_class,
606 bt_field_class *out_field_class)
607{
475e740e 608 BT_COMP_LOGD("Copying content of string field class: in-fc-addr=%p, "
9a51bfb2 609 "out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
610 /*
611 * There is no content to copy. Keep this function call anyway for
612 * logging purposes.
613 */
475e740e 614 BT_COMP_LOGD("Copied content of string field class: in-fc-addr=%p, "
9a51bfb2 615 "out-fc-addr=%p", in_field_class, out_field_class);
58f6d595
FD
616
617 return 0;
618}
619
620static
621bt_field_class *copy_field_class_array_element(struct trace_ir_metadata_maps *md_maps,
622 const bt_field_class *in_elem_fc)
623{
624 int ret;
625 bt_field_class *out_elem_fc =
626 create_field_class_copy_internal(md_maps, in_elem_fc);
627 if (!out_elem_fc) {
475e740e 628 BT_COMP_LOGE("Error creating output elem field class "
9a51bfb2
FD
629 "from input elem field class for static array: "
630 "in-fc-addr=%p", in_elem_fc);
58f6d595
FD
631 goto error;
632 }
633
634 ret = copy_field_class_content_internal(md_maps, in_elem_fc, out_elem_fc);
635 if (ret) {
475e740e 636 BT_COMP_LOGE("Error creating output elem field class "
9a51bfb2
FD
637 "from input elem field class for static array: "
638 "in-fc-addr=%p", in_elem_fc);
58f6d595
FD
639 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_elem_fc);
640 goto error;
641 }
642
643error:
644 return out_elem_fc;
645}
646
647BT_HIDDEN
648bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *md_maps,
649 const bt_field_class *in_field_class)
650{
651 bt_field_class *out_field_class = NULL;
02b61fe0 652 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
58f6d595 653
475e740e 654 BT_COMP_LOGD("Creating bare field class based on field class: in-fc-addr=%p",
9a51bfb2 655 in_field_class);
58f6d595 656
02b61fe0 657 switch (fc_type) {
41bdd7c1
PP
658 case BT_FIELD_CLASS_TYPE_BOOL:
659 out_field_class = bt_field_class_bool_create(
9a51bfb2 660 md_maps->output_trace_class);
41bdd7c1 661 break;
f5f2c882
PP
662 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
663 out_field_class = bt_field_class_bit_array_create(
9a51bfb2
FD
664 md_maps->output_trace_class,
665 bt_field_class_bit_array_get_length(
666 in_field_class));
f5f2c882 667 break;
58f6d595 668 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
60bbfc7c 669 out_field_class = bt_field_class_integer_unsigned_create(
9a51bfb2 670 md_maps->output_trace_class);
58f6d595
FD
671 break;
672 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
60bbfc7c 673 out_field_class = bt_field_class_integer_signed_create(
9a51bfb2 674 md_maps->output_trace_class);
58f6d595
FD
675 break;
676 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
60bbfc7c 677 out_field_class = bt_field_class_enumeration_unsigned_create(
9a51bfb2 678 md_maps->output_trace_class);
58f6d595
FD
679 break;
680 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
60bbfc7c 681 out_field_class = bt_field_class_enumeration_signed_create(
9a51bfb2 682 md_maps->output_trace_class);
58f6d595 683 break;
76276a81
FD
684 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
685 out_field_class = bt_field_class_real_single_precision_create(
9a51bfb2 686 md_maps->output_trace_class);
76276a81
FD
687 break;
688 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
689 out_field_class = bt_field_class_real_double_precision_create(
9a51bfb2 690 md_maps->output_trace_class);
58f6d595
FD
691 break;
692 case BT_FIELD_CLASS_TYPE_STRING:
693 out_field_class = bt_field_class_string_create(
9a51bfb2 694 md_maps->output_trace_class);
58f6d595
FD
695 break;
696 case BT_FIELD_CLASS_TYPE_STRUCTURE:
697 out_field_class = bt_field_class_structure_create(
9a51bfb2 698 md_maps->output_trace_class);
58f6d595
FD
699 break;
700 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
701 {
702 const bt_field_class *in_elem_fc =
703 bt_field_class_array_borrow_element_field_class_const(
704 in_field_class);
9a51bfb2
FD
705 uint64_t array_len = bt_field_class_array_static_get_length(
706 in_field_class);
58f6d595
FD
707
708 bt_field_class *out_elem_fc = copy_field_class_array_element(
709 md_maps, in_elem_fc);
710 if (!out_elem_fc) {
711 out_field_class = NULL;
712 goto error;
713 }
714
60bbfc7c 715 out_field_class = bt_field_class_array_static_create(
9a51bfb2
FD
716 md_maps->output_trace_class,
717 out_elem_fc, array_len);
58f6d595
FD
718 break;
719 }
b8ddb4f0
PP
720 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD:
721 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD:
58f6d595
FD
722 {
723 const bt_field_class *in_elem_fc =
724 bt_field_class_array_borrow_element_field_class_const(
725 in_field_class);
93d7d5d1 726 bt_field_class *out_length_fc = NULL;
58f6d595 727 bt_field_class *out_elem_fc = copy_field_class_array_element(
93d7d5d1 728 md_maps, in_elem_fc);
b8ddb4f0 729
58f6d595
FD
730 if (!out_elem_fc) {
731 out_field_class = NULL;
732 goto error;
733 }
734
b8ddb4f0
PP
735 if (fc_type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) {
736 const bt_field_path *length_fp =
737 bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const(
738 in_field_class);
93d7d5d1
PP
739 const bt_field_class *in_length_fc =
740 resolve_field_path_to_field_class(length_fp,
741 md_maps);
742
743 BT_ASSERT(in_length_fc);
744 out_length_fc = g_hash_table_lookup(md_maps->field_class_map,
745 in_length_fc);
746 BT_ASSERT(out_length_fc);
747 }
748
60bbfc7c 749 out_field_class = bt_field_class_array_dynamic_create(
9a51bfb2
FD
750 md_maps->output_trace_class,
751 out_elem_fc, out_length_fc);
58f6d595
FD
752 break;
753 }
467673c1
PP
754 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
755 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
756 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
757 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
978237e9
PP
758 {
759 const bt_field_class *in_content_fc =
760 bt_field_class_option_borrow_field_class_const(
9a51bfb2 761 in_field_class);
978237e9
PP
762 bt_field_class *out_selector_fc = NULL;
763 bt_field_class *out_content_fc;
764 int ret;
765
766 out_content_fc = create_field_class_copy_internal(
9a51bfb2 767 md_maps, in_content_fc);
978237e9
PP
768 if (!out_content_fc) {
769 BT_COMP_LOGE_STR("Cannot copy option's content field class.");
770 goto error;
771 }
772
773 ret = copy_field_class_content_internal(md_maps,
774 in_content_fc, out_content_fc);
775 if (ret) {
776 BT_COMP_LOGE_STR("Error copying content of option's "
777 "content field class");
778 goto error;
779 }
780
467673c1
PP
781 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
782 out_field_class =
783 bt_field_class_option_without_selector_create(
784 md_maps->output_trace_class,
785 out_content_fc);
786 } else {
787 const bt_field_path *in_selector_fp =
788 bt_field_class_option_with_selector_borrow_selector_field_path_const(
789 in_field_class);
790 const bt_field_class *in_selector_fc;
978237e9 791
467673c1
PP
792 BT_ASSERT(in_selector_fp);
793 in_selector_fc = resolve_field_path_to_field_class(
794 in_selector_fp, md_maps);
978237e9
PP
795 BT_ASSERT(in_selector_fc);
796 out_selector_fc = g_hash_table_lookup(
797 md_maps->field_class_map, in_selector_fc);
798 BT_ASSERT(out_selector_fc);
467673c1
PP
799
800 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
801 out_field_class =
802 bt_field_class_option_with_selector_bool_create(
803 md_maps->output_trace_class,
804 out_content_fc, out_selector_fc);
805 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR) {
806 const bt_integer_range_set_unsigned *ranges =
807 bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(
808 in_field_class);
809
810 BT_ASSERT(ranges);
811 out_field_class =
812 bt_field_class_option_with_selector_integer_unsigned_create(
813 md_maps->output_trace_class,
814 out_content_fc, out_selector_fc,
815 ranges);
816 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR) {
817 const bt_integer_range_set_signed *ranges =
818 bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(
819 in_field_class);
820
821 BT_ASSERT(ranges);
822 out_field_class =
823 bt_field_class_option_with_selector_integer_signed_create(
824 md_maps->output_trace_class,
825 out_content_fc, out_selector_fc,
826 ranges);
827 }
978237e9
PP
828 }
829
467673c1 830 BT_ASSERT(out_field_class);
978237e9
PP
831 break;
832 }
02b61fe0 833 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
0822832b
PP
834 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
835 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
02b61fe0
PP
836 {
837 bt_field_class *out_sel_fc = NULL;
838
0822832b
PP
839 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR ||
840 fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR) {
02b61fe0
PP
841 const bt_field_class *in_sel_fc;
842 const bt_field_path *sel_fp =
843 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
844 in_field_class);
845
846 BT_ASSERT(sel_fp);
847 in_sel_fc = resolve_field_path_to_field_class(sel_fp,
848 md_maps);
849 BT_ASSERT(in_sel_fc);
850 out_sel_fc = g_hash_table_lookup(
851 md_maps->field_class_map, in_sel_fc);
852 BT_ASSERT(out_sel_fc);
853 }
854
58f6d595 855 out_field_class = bt_field_class_variant_create(
02b61fe0 856 md_maps->output_trace_class, out_sel_fc);
58f6d595 857 break;
02b61fe0 858 }
58f6d595
FD
859 default:
860 abort();
861 }
862
863 /*
864 * Add mapping from in_field_class to out_field_class. This simplifies
865 * the resolution of field paths in variant and dynamic array field
866 * classes.
867 */
868 g_hash_table_insert(md_maps->field_class_map,
9a51bfb2 869 (gpointer) in_field_class, out_field_class);
58f6d595
FD
870
871error:
872 if(out_field_class){
475e740e 873 BT_COMP_LOGD("Created bare field class based on field class: in-fc-addr=%p, "
58f6d595
FD
874 "out-fc-addr=%p", in_field_class, out_field_class);
875 } else {
475e740e 876 BT_COMP_LOGE("Error creating output field class from input field "
58f6d595
FD
877 "class: in-fc-addr=%p", in_field_class);
878 }
879
880 return out_field_class;
881}
882
883BT_HIDDEN
884int copy_field_class_content_internal(
885 struct trace_ir_metadata_maps *md_maps,
886 const bt_field_class *in_field_class,
887 bt_field_class *out_field_class)
888{
889 int ret = 0;
84ff66df
PP
890
891 /*
892 * Safe to use the same value object because it's frozen at this
893 * point.
894 */
895 bt_field_class_set_user_attributes(out_field_class,
896 bt_field_class_borrow_user_attributes_const(in_field_class));
897
58f6d595 898 switch(bt_field_class_get_type(in_field_class)) {
41bdd7c1
PP
899 case BT_FIELD_CLASS_TYPE_BOOL:
900 ret = field_class_bool_copy(md_maps,
901 in_field_class, out_field_class);
902 break;
f5f2c882
PP
903 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
904 ret = field_class_bit_array_copy(md_maps,
905 in_field_class, out_field_class);
906 break;
58f6d595
FD
907 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
908 ret = field_class_unsigned_integer_copy(md_maps,
909 in_field_class, out_field_class);
910 break;
911 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
912 ret = field_class_signed_integer_copy(md_maps,
913 in_field_class, out_field_class);
914 break;
915 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
916 ret = field_class_unsigned_enumeration_copy(md_maps,
917 in_field_class, out_field_class);
918 break;
919 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
920 ret = field_class_signed_enumeration_copy(md_maps,
921 in_field_class, out_field_class);
922 break;
76276a81
FD
923 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
924 ret = field_class_single_precision_real_copy(md_maps,
925 in_field_class, out_field_class);
926 break;
927 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
928 ret = field_class_double_precision_real_copy(md_maps,
58f6d595
FD
929 in_field_class, out_field_class);
930 break;
931 case BT_FIELD_CLASS_TYPE_STRING:
932 ret = field_class_string_copy(md_maps,
933 in_field_class, out_field_class);
934 break;
935 case BT_FIELD_CLASS_TYPE_STRUCTURE:
936 ret = field_class_structure_copy(md_maps,
937 in_field_class, out_field_class);
938 break;
939 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
940 ret = field_class_static_array_copy(md_maps,
941 in_field_class, out_field_class);
942 break;
b8ddb4f0
PP
943 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD:
944 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD:
58f6d595
FD
945 ret = field_class_dynamic_array_copy(md_maps,
946 in_field_class, out_field_class);
947 break;
467673c1
PP
948 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
949 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
950 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
951 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
978237e9
PP
952 ret = field_class_option_copy(md_maps,
953 in_field_class, out_field_class);
954 break;
02b61fe0 955 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
0822832b
PP
956 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
957 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
58f6d595
FD
958 ret = field_class_variant_copy(md_maps,
959 in_field_class, out_field_class);
960 break;
961 default:
962 abort();
963 }
964
965 return ret;
966}
This page took 0.082933 seconds and 4 git commands to generate.