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