lib: add bit array field class and field types
[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",
ca9f27f3
FD
54 fp, fc);
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
FD
62
63 switch (fc_type) {
64 case BT_FIELD_CLASS_TYPE_STRUCTURE:
1e6fd1d7 65 {
66ddcddf
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));
1e6fd1d7
PP
73 curr_fc = bt_field_class_structure_member_borrow_field_class_const(
74 member);
ca9f27f3 75 break;
1e6fd1d7 76 }
f29ef814
PP
77 case BT_FIELD_CLASS_TYPE_OPTION:
78 {
79 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
80 BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
81 curr_fc = bt_field_class_option_borrow_field_class_const(
82 curr_fc);
83 break;
84 }
45c51519
PP
85 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
86 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
87 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
1e6fd1d7 88 {
66ddcddf
PP
89 const bt_field_class_variant_option *option;
90
91 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
92 BT_FIELD_PATH_ITEM_TYPE_INDEX);
93 option = bt_field_class_variant_borrow_option_by_index_const(
94 curr_fc,
95 bt_field_path_item_index_get_index(fp_item));
1e6fd1d7
PP
96 curr_fc = bt_field_class_variant_option_borrow_field_class_const(
97 option);
ca9f27f3 98 break;
1e6fd1d7 99 }
66ddcddf
PP
100 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
101 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
102 {
103 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
104 BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
105 curr_fc = bt_field_class_array_borrow_element_field_class_const(
106 curr_fc);
107 break;
108 }
ca9f27f3
FD
109 default:
110 abort();
111 }
112 }
113
114 return curr_fc;
115}
116
117static
118const bt_field_class *resolve_field_path_to_field_class(const bt_field_path *fp,
119 struct trace_ir_metadata_maps *md_maps)
120{
121 struct field_class_resolving_context *fc_resolving_ctx;
122 const bt_field_class *fc;
e7ceb9df 123 bt_field_path_scope fp_scope;
ca9f27f3 124
91bc8451 125 BT_COMP_LOGD("Resolving field path: fp-addr=%p", fp);
ca9f27f3
FD
126
127 fc_resolving_ctx = md_maps->fc_resolving_ctx;
128 fp_scope = bt_field_path_get_root_scope(fp);
129
130 switch (fp_scope) {
e7ceb9df 131 case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
3a3d15f3
PP
132 fc = walk_field_path(md_maps, fp,
133 fc_resolving_ctx->packet_context);
ca9f27f3 134 break;
e7ceb9df 135 case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
3a3d15f3
PP
136 fc = walk_field_path(md_maps, fp,
137 fc_resolving_ctx->event_common_context);
ca9f27f3 138 break;
e7ceb9df 139 case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
3a3d15f3
PP
140 fc = walk_field_path(md_maps, fp,
141 fc_resolving_ctx->event_specific_context);
ca9f27f3 142 break;
e7ceb9df 143 case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
3a3d15f3
PP
144 fc = walk_field_path(md_maps, fp,
145 fc_resolving_ctx->event_payload);
ca9f27f3
FD
146 break;
147 default:
148 abort();
149 }
150
151 return fc;
152}
153
154static inline
155void field_class_integer_set_props(const bt_field_class *input_fc,
156 bt_field_class *output_fc)
157{
158 bt_field_class_integer_set_preferred_display_base(output_fc,
159 bt_field_class_integer_get_preferred_display_base(input_fc));
160 bt_field_class_integer_set_field_value_range(output_fc,
161 bt_field_class_integer_get_field_value_range(input_fc));
162}
163
f7cfbcc3
PP
164static inline
165int field_class_bool_copy(
166 struct trace_ir_metadata_maps *md_maps,
167 const bt_field_class *in_field_class,
168 bt_field_class *out_field_class)
169{
170 BT_COMP_LOGD("Copying content of boolean field class: "
171 "in-fc-addr=%p, out-fc-addr=%p",
172 in_field_class, out_field_class);
173 BT_COMP_LOGD("Copied content of boolean field class: "
174 "in-fc-addr=%p, out-fc-addr=%p",
175 in_field_class, out_field_class);
176 return 0;
177}
178
ca9f27f3
FD
179static inline
180int field_class_unsigned_integer_copy(
181 struct trace_ir_metadata_maps *md_maps,
182 const bt_field_class *in_field_class,
183 bt_field_class *out_field_class)
184{
91bc8451 185 BT_COMP_LOGD("Copying content of unsigned integer field class: "
ca9f27f3
FD
186 "in-fc-addr=%p, out-fc-addr=%p",
187 in_field_class, out_field_class);
188
189 field_class_integer_set_props(in_field_class, out_field_class);
190
91bc8451 191 BT_COMP_LOGD("Copied content of unsigned integer field class: "
ca9f27f3
FD
192 "in-fc-addr=%p, out-fc-addr=%p",
193 in_field_class, out_field_class);
194 return 0;
195}
196
197static inline
198int field_class_signed_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{
91bc8451 203 BT_COMP_LOGD("Copying content of signed integer field class: "
ca9f27f3
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
91bc8451 209 BT_COMP_LOGD("Copied content of signed integer field class: "
ca9f27f3
FD
210 "in-fc-addr=%p, out-fc-addr=%p",
211 in_field_class, out_field_class);
212 return 0;
213}
214
215BT_HIDDEN
216int field_class_unsigned_enumeration_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{
221 uint64_t i, enum_mapping_count;
222 int ret = 0;
223
91bc8451 224 BT_COMP_LOGD("Copying content of unsigned enumeration field class: "
ca9f27f3
FD
225 "in-fc-addr=%p, out-fc-addr=%p",
226 in_field_class, out_field_class);
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. */
232 enum_mapping_count = bt_field_class_enumeration_get_mapping_count(in_field_class);
233 for (i = 0; i < enum_mapping_count; i++) {
234 const char *label;
45c51519 235 const bt_integer_range_set_unsigned *range_set;
9c08c816 236 const bt_field_class_enumeration_unsigned_mapping *u_mapping;
8f3ccfbc 237 const bt_field_class_enumeration_mapping *mapping;
ca9f27f3 238
9c08c816 239 u_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
8f3ccfbc 240 in_field_class, i);
9c08c816 241 mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(
8f3ccfbc 242 u_mapping);
45c51519 243 label = bt_field_class_enumeration_mapping_get_label(mapping);
9c08c816 244 range_set = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
45c51519 245 u_mapping);
9c08c816 246 ret = bt_field_class_enumeration_unsigned_add_mapping(
45c51519
PP
247 out_field_class, label, range_set);
248 if (ret) {
249 goto error;
ca9f27f3
FD
250 }
251 }
252
91bc8451 253 BT_COMP_LOGD("Copied content of unsigned enumeration field class: "
ca9f27f3
FD
254 "in-fc-addr=%p, out-fc-addr=%p",
255 in_field_class, out_field_class);
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: "
ca9f27f3
FD
271 "in-fc-addr=%p, out-fc-addr=%p",
272 in_field_class, out_field_class);
273
274 /* Copy properties of the inner integer. */
275 field_class_integer_set_props(in_field_class, out_field_class);
276
277 /* Copy all enumeration entries. */
278 enum_mapping_count =
279 bt_field_class_enumeration_get_mapping_count(in_field_class);
280 for (i = 0; i < enum_mapping_count; i++) {
281 const char *label;
45c51519 282 const bt_integer_range_set_signed *range_set;
9c08c816 283 const bt_field_class_enumeration_signed_mapping *s_mapping;
8f3ccfbc 284 const bt_field_class_enumeration_mapping *mapping;
ca9f27f3 285
9c08c816 286 s_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
8f3ccfbc 287 in_field_class, i);
9c08c816 288 mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(
45c51519
PP
289 s_mapping);
290 label = bt_field_class_enumeration_mapping_get_label(mapping);
9c08c816 291 range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
45c51519 292 s_mapping);
9c08c816 293 ret = bt_field_class_enumeration_signed_add_mapping(
45c51519
PP
294 out_field_class, label, range_set);
295 if (ret) {
296 goto error;
ca9f27f3
FD
297 }
298 }
299
91bc8451 300 BT_COMP_LOGD("Copied content of signed enumeration field class: "
ca9f27f3
FD
301 "in-fc-addr=%p, out-fc-addr=%p",
302 in_field_class, out_field_class);
303
304error:
305 return ret;
306}
307
308static inline
309int field_class_real_copy(
310 struct trace_ir_metadata_maps *md_maps,
311 const bt_field_class *in_field_class,
312 bt_field_class *out_field_class)
313{
91bc8451 314 BT_COMP_LOGD("Copying content of real field class: "
ca9f27f3
FD
315 "in-fc-addr=%p, out-fc-addr=%p",
316 in_field_class, out_field_class);
317
318 bt_field_class_real_set_is_single_precision(out_field_class,
319 bt_field_class_real_is_single_precision(in_field_class));
320
91bc8451 321 BT_COMP_LOGD("Copied content real field class: in-fc-addr=%p, "
ca9f27f3
FD
322 "out-fc-addr=%p", in_field_class, out_field_class);
323
324 return 0;
325}
326
327static inline
328int field_class_structure_copy(
329 struct trace_ir_metadata_maps *md_maps,
330 const bt_field_class *in_field_class,
331 bt_field_class *out_field_class)
332{
333 uint64_t i, struct_member_count;
ca9f27f3
FD
334 int ret = 0;
335
91bc8451 336 BT_COMP_LOGD("Copying content of structure field class: "
ca9f27f3
FD
337 "in-fc-addr=%p, out-fc-addr=%p",
338 in_field_class, out_field_class);
339 /* Get the number of member in that struct. */
340 struct_member_count =
341 bt_field_class_structure_get_member_count(in_field_class);
342
343 /* Iterate over all the members of the struct. */
344 for (i = 0; i < struct_member_count; i++) {
1e6fd1d7 345 const bt_field_class_structure_member *member;
ca9f27f3
FD
346 const char *member_name;
347 const bt_field_class *member_fc;
348 bt_field_class *out_member_field_class;
349
1e6fd1d7
PP
350 member = bt_field_class_structure_borrow_member_by_index_const(
351 in_field_class, i);
352 member_fc = bt_field_class_structure_member_borrow_field_class_const(
353 member);
354 member_name = bt_field_class_structure_member_get_name(member);
91bc8451 355 BT_COMP_LOGD("Copying structure field class's field: "
ca9f27f3
FD
356 "index=%" PRId64 ", "
357 "member-fc-addr=%p, field-name=\"%s\"",
358 i, member_fc, member_name);
359
360 out_member_field_class = create_field_class_copy(md_maps,
361 member_fc);
362 if (!out_member_field_class) {
91bc8451 363 BT_COMP_LOGE("Cannot copy structure field class's field: "
ca9f27f3
FD
364 "index=%" PRId64 ", "
365 "field-fc-addr=%p, field-name=\"%s\"",
366 i, member_fc, member_name);
367 ret = -1;
368 goto error;
369 }
370 ret = copy_field_class_content(md_maps, member_fc,
371 out_member_field_class);
372 if (ret) {
373 goto error;
374 }
375
d24d5663
PP
376 if (bt_field_class_structure_append_member(out_field_class,
377 member_name, out_member_field_class) !=
378 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
91bc8451 379 BT_COMP_LOGE("Cannot append structure field class's field: "
ca9f27f3
FD
380 "index=%" PRId64 ", "
381 "field-fc-addr=%p, field-name=\"%s\"",
382 i, member_fc, member_name);
383 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_member_field_class);
384 ret = -1;
385 goto error;
386 }
387 }
388
91bc8451 389 BT_COMP_LOGD("Copied structure field class: original-fc-addr=%p, copy-fc-addr=%p",
ca9f27f3
FD
390 in_field_class, out_field_class);
391
392error:
393 return ret;
394}
395
396static inline
397int field_class_variant_copy(
398 struct trace_ir_metadata_maps *md_maps,
399 const bt_field_class *in_field_class,
400 bt_field_class *out_field_class)
401{
1ec009b2 402 bt_field_class *out_tag_field_class = NULL;
ca9f27f3 403 uint64_t i, variant_option_count;
45c51519 404 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
ca9f27f3
FD
405 int ret = 0;
406
91bc8451 407 BT_COMP_LOGD("Copying content of variant field class: "
ca9f27f3
FD
408 "in-fc-addr=%p, out-fc-addr=%p",
409 in_field_class, out_field_class);
ca9f27f3
FD
410 variant_option_count =
411 bt_field_class_variant_get_option_count(in_field_class);
412 for (i = 0; i < variant_option_count; i++) {
1e6fd1d7 413 const bt_field_class *option_fc;
ca9f27f3
FD
414 const char *option_name;
415 bt_field_class *out_option_field_class;
1e6fd1d7 416 const bt_field_class_variant_option *option;
ca9f27f3 417
1e6fd1d7
PP
418 option = bt_field_class_variant_borrow_option_by_index_const(
419 in_field_class, i);
420 option_fc = bt_field_class_variant_option_borrow_field_class_const(
421 option);
422 option_name = bt_field_class_variant_option_get_name(option);
ca9f27f3 423 out_option_field_class = create_field_class_copy_internal(
1e6fd1d7 424 md_maps, option_fc);
ca9f27f3 425 if (!out_option_field_class) {
91bc8451 426 BT_COMP_LOGE_STR("Cannot copy field class.");
ca9f27f3
FD
427 ret = -1;
428 goto error;
429 }
1e6fd1d7 430 ret = copy_field_class_content_internal(md_maps, option_fc,
ca9f27f3
FD
431 out_option_field_class);
432 if (ret) {
91bc8451 433 BT_COMP_LOGE_STR("Error copying content of option variant "
ca9f27f3
FD
434 "field class'");
435 goto error;
436 }
437
45c51519 438 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) {
9c08c816
PP
439 const bt_field_class_variant_with_selector_unsigned_option *spec_opt =
440 bt_field_class_variant_with_selector_unsigned_borrow_option_by_index_const(
45c51519
PP
441 in_field_class, i);
442 const bt_integer_range_set_unsigned *ranges =
9c08c816 443 bt_field_class_variant_with_selector_unsigned_option_borrow_ranges_const(
45c51519
PP
444 spec_opt);
445
9c08c816 446 if (bt_field_class_variant_with_selector_unsigned_append_option(
45c51519
PP
447 out_field_class, option_name,
448 out_option_field_class, ranges) !=
449 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
450 BT_COMP_LOGE_STR("Cannot append option to variant field class with unsigned selector'");
451 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
452 ret = -1;
453 goto error;
454 }
455 } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
9c08c816
PP
456 const bt_field_class_variant_with_selector_signed_option *spec_opt =
457 bt_field_class_variant_with_selector_signed_borrow_option_by_index_const(
45c51519
PP
458 in_field_class, i);
459 const bt_integer_range_set_signed *ranges =
9c08c816 460 bt_field_class_variant_with_selector_signed_option_borrow_ranges_const(
45c51519
PP
461 spec_opt);
462
9c08c816 463 if (bt_field_class_variant_with_selector_signed_append_option(
45c51519
PP
464 out_field_class, option_name,
465 out_option_field_class, ranges) !=
466 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
467 BT_COMP_LOGE_STR("Cannot append option to variant field class with signed selector'");
468 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
469 ret = -1;
470 goto error;
471 }
472 } else {
473 BT_ASSERT(fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR);
474
475 if (bt_field_class_variant_without_selector_append_option(
476 out_field_class, option_name,
477 out_option_field_class) !=
478 BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_OK) {
479 BT_COMP_LOGE_STR("Cannot append option to variant field class'");
480 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
481 ret = -1;
482 goto error;
483 }
ca9f27f3
FD
484 }
485 }
486
91bc8451 487 BT_COMP_LOGD("Copied content of variant field class: in-fc-addr=%p, "
ca9f27f3
FD
488 "out-fc-addr=%p", in_field_class, out_field_class);
489
490error:
491 return ret;
492}
493
494static inline
495int field_class_static_array_copy(
496 struct trace_ir_metadata_maps *md_maps,
497 const bt_field_class *in_field_class,
498 bt_field_class *out_field_class)
499{
91bc8451 500 BT_COMP_LOGD("Copying content of static array field class: in-fc-addr=%p, "
ca9f27f3
FD
501 "out-fc-addr=%p", in_field_class, out_field_class);
502 /*
503 * There is no content to copy. Keep this function call anyway for
504 * logging purposes.
505 */
91bc8451 506 BT_COMP_LOGD("Copied content of static array field class: in-fc-addr=%p, "
ca9f27f3
FD
507 "out-fc-addr=%p", in_field_class, out_field_class);
508
509 return 0;
510}
511
512static inline
513int field_class_dynamic_array_copy(
514 struct trace_ir_metadata_maps *md_maps,
515 const bt_field_class *in_field_class,
516 bt_field_class *out_field_class)
517{
91bc8451 518 BT_COMP_LOGD("Copying content of dynamic array field class: "
ca9f27f3
FD
519 "in-fc-addr=%p, out-fc-addr=%p",
520 in_field_class, out_field_class);
521
1367bc7c
PP
522 /*
523 * There is no content to copy. Keep this function call anyway for
524 * logging purposes.
525 */
91bc8451 526 BT_COMP_LOGD("Copied dynamic array field class: in-fc-addr=%p, "
ca9f27f3
FD
527 "out-fc-addr=%p", in_field_class, out_field_class);
528
1367bc7c 529 return 0;
ca9f27f3
FD
530}
531
f29ef814
PP
532static inline
533int field_class_option_copy(
534 struct trace_ir_metadata_maps *md_maps,
535 const bt_field_class *in_field_class,
536 bt_field_class *out_field_class)
537{
538 BT_COMP_LOGD("Copying content of option field class: "
539 "in-fc-addr=%p, out-fc-addr=%p",
540 in_field_class, out_field_class);
541
542 /*
543 * There is no content to copy. Keep this function call anyway for
544 * logging purposes.
545 */
546 BT_COMP_LOGD("Copied option field class: in-fc-addr=%p, "
547 "out-fc-addr=%p", in_field_class, out_field_class);
548
549 return 0;
550}
551
ca9f27f3
FD
552static inline
553int field_class_string_copy(struct trace_ir_metadata_maps *md_maps,
554 const bt_field_class *in_field_class,
555 bt_field_class *out_field_class)
556{
91bc8451 557 BT_COMP_LOGD("Copying content of string field class: in-fc-addr=%p, "
ca9f27f3
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 */
91bc8451 563 BT_COMP_LOGD("Copied content of string field class: in-fc-addr=%p, "
ca9f27f3
FD
564 "out-fc-addr=%p", in_field_class, out_field_class);
565
566 return 0;
567}
568
569static
570bt_field_class *copy_field_class_array_element(struct trace_ir_metadata_maps *md_maps,
571 const bt_field_class *in_elem_fc)
572{
573 int ret;
574 bt_field_class *out_elem_fc =
575 create_field_class_copy_internal(md_maps, in_elem_fc);
576 if (!out_elem_fc) {
91bc8451 577 BT_COMP_LOGE("Error creating output elem field class "
ca9f27f3
FD
578 "from input elem field class for static array: "
579 "in-fc-addr=%p", in_elem_fc);
580 goto error;
581 }
582
583 ret = copy_field_class_content_internal(md_maps, in_elem_fc, out_elem_fc);
584 if (ret) {
91bc8451 585 BT_COMP_LOGE("Error creating output elem field class "
ca9f27f3
FD
586 "from input elem field class for static array: "
587 "in-fc-addr=%p", in_elem_fc);
588 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_elem_fc);
589 goto error;
590 }
591
592error:
593 return out_elem_fc;
594}
595
596BT_HIDDEN
597bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *md_maps,
598 const bt_field_class *in_field_class)
599{
600 bt_field_class *out_field_class = NULL;
45c51519 601 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
ca9f27f3 602
91bc8451 603 BT_COMP_LOGD("Creating bare field class based on field class: in-fc-addr=%p",
ca9f27f3
FD
604 in_field_class);
605
45c51519 606 switch (fc_type) {
f7cfbcc3
PP
607 case BT_FIELD_CLASS_TYPE_BOOL:
608 out_field_class = bt_field_class_bool_create(
609 md_maps->output_trace_class);
610 break;
ca9f27f3 611 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
9c08c816 612 out_field_class = bt_field_class_integer_unsigned_create(
ca9f27f3
FD
613 md_maps->output_trace_class);
614 break;
615 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
9c08c816 616 out_field_class = bt_field_class_integer_signed_create(
ca9f27f3
FD
617 md_maps->output_trace_class);
618 break;
619 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
9c08c816 620 out_field_class = bt_field_class_enumeration_unsigned_create(
ca9f27f3
FD
621 md_maps->output_trace_class);
622 break;
623 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
9c08c816 624 out_field_class = bt_field_class_enumeration_signed_create(
ca9f27f3
FD
625 md_maps->output_trace_class);
626 break;
627 case BT_FIELD_CLASS_TYPE_REAL:
628 out_field_class = bt_field_class_real_create(
629 md_maps->output_trace_class);
630 break;
631 case BT_FIELD_CLASS_TYPE_STRING:
632 out_field_class = bt_field_class_string_create(
633 md_maps->output_trace_class);
634 break;
635 case BT_FIELD_CLASS_TYPE_STRUCTURE:
636 out_field_class = bt_field_class_structure_create(
637 md_maps->output_trace_class);
638 break;
639 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
640 {
641 const bt_field_class *in_elem_fc =
642 bt_field_class_array_borrow_element_field_class_const(
643 in_field_class);
644 uint64_t array_len =
9c08c816 645 bt_field_class_array_static_get_length(in_field_class);
ca9f27f3
FD
646
647 bt_field_class *out_elem_fc = copy_field_class_array_element(
648 md_maps, in_elem_fc);
649 if (!out_elem_fc) {
650 out_field_class = NULL;
651 goto error;
652 }
653
9c08c816 654 out_field_class = bt_field_class_array_static_create(
ca9f27f3
FD
655 md_maps->output_trace_class,
656 out_elem_fc, array_len);
657 break;
658 }
659 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
660 {
661 const bt_field_class *in_elem_fc =
662 bt_field_class_array_borrow_element_field_class_const(
663 in_field_class);
1367bc7c 664 const bt_field_path *length_fp =
9c08c816 665 bt_field_class_array_dynamic_borrow_length_field_path_const(
1367bc7c
PP
666 in_field_class);
667 bt_field_class *out_length_fc = NULL;
ca9f27f3
FD
668
669 bt_field_class *out_elem_fc = copy_field_class_array_element(
1367bc7c 670 md_maps, in_elem_fc);
ca9f27f3
FD
671 if (!out_elem_fc) {
672 out_field_class = NULL;
673 goto error;
674 }
675
1367bc7c
PP
676 if (length_fp) {
677 const bt_field_class *in_length_fc =
678 resolve_field_path_to_field_class(length_fp,
679 md_maps);
680
681 BT_ASSERT(in_length_fc);
682 out_length_fc = g_hash_table_lookup(md_maps->field_class_map,
683 in_length_fc);
684 BT_ASSERT(out_length_fc);
685 }
686
9c08c816 687 out_field_class = bt_field_class_array_dynamic_create(
ca9f27f3 688 md_maps->output_trace_class,
1367bc7c 689 out_elem_fc, out_length_fc);
ca9f27f3
FD
690 break;
691 }
f29ef814
PP
692 case BT_FIELD_CLASS_TYPE_OPTION:
693 {
694 const bt_field_class *in_content_fc =
695 bt_field_class_option_borrow_field_class_const(
696 in_field_class);
697 const bt_field_path *in_selector_fp =
698 bt_field_class_option_borrow_selector_field_path_const(
699 in_field_class);
700 bt_field_class *out_selector_fc = NULL;
701 bt_field_class *out_content_fc;
702 int ret;
703
704 out_content_fc = create_field_class_copy_internal(
705 md_maps, in_content_fc);
706 if (!out_content_fc) {
707 BT_COMP_LOGE_STR("Cannot copy option's content field class.");
708 goto error;
709 }
710
711 ret = copy_field_class_content_internal(md_maps,
712 in_content_fc, out_content_fc);
713 if (ret) {
714 BT_COMP_LOGE_STR("Error copying content of option's "
715 "content field class");
716 goto error;
717 }
718
719 if (in_selector_fp) {
720 const bt_field_class *in_selector_fc =
721 resolve_field_path_to_field_class(
722 in_selector_fp, md_maps);
723
724 BT_ASSERT(in_selector_fc);
725 out_selector_fc = g_hash_table_lookup(
726 md_maps->field_class_map, in_selector_fc);
727 BT_ASSERT(out_selector_fc);
728 }
729
730 out_field_class = bt_field_class_option_create(
731 md_maps->output_trace_class,
732 out_content_fc, out_selector_fc);
733 break;
734 }
45c51519
PP
735 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
736 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
737 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
738 {
739 bt_field_class *out_sel_fc = NULL;
740
741 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
742 fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
743 const bt_field_class *in_sel_fc;
744 const bt_field_path *sel_fp =
745 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
746 in_field_class);
747
748 BT_ASSERT(sel_fp);
749 in_sel_fc = resolve_field_path_to_field_class(sel_fp,
750 md_maps);
751 BT_ASSERT(in_sel_fc);
752 out_sel_fc = g_hash_table_lookup(
753 md_maps->field_class_map, in_sel_fc);
754 BT_ASSERT(out_sel_fc);
755 }
756
ca9f27f3 757 out_field_class = bt_field_class_variant_create(
45c51519 758 md_maps->output_trace_class, out_sel_fc);
ca9f27f3 759 break;
45c51519 760 }
ca9f27f3
FD
761 default:
762 abort();
763 }
764
765 /*
766 * Add mapping from in_field_class to out_field_class. This simplifies
767 * the resolution of field paths in variant and dynamic array field
768 * classes.
769 */
770 g_hash_table_insert(md_maps->field_class_map,
771 (gpointer) in_field_class, out_field_class);
772
773error:
774 if(out_field_class){
91bc8451 775 BT_COMP_LOGD("Created bare field class based on field class: in-fc-addr=%p, "
ca9f27f3
FD
776 "out-fc-addr=%p", in_field_class, out_field_class);
777 } else {
91bc8451 778 BT_COMP_LOGE("Error creating output field class from input field "
ca9f27f3
FD
779 "class: in-fc-addr=%p", in_field_class);
780 }
781
782 return out_field_class;
783}
784
785BT_HIDDEN
786int copy_field_class_content_internal(
787 struct trace_ir_metadata_maps *md_maps,
788 const bt_field_class *in_field_class,
789 bt_field_class *out_field_class)
790{
791 int ret = 0;
792 switch(bt_field_class_get_type(in_field_class)) {
f7cfbcc3
PP
793 case BT_FIELD_CLASS_TYPE_BOOL:
794 ret = field_class_bool_copy(md_maps,
795 in_field_class, out_field_class);
796 break;
ca9f27f3
FD
797 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
798 ret = field_class_unsigned_integer_copy(md_maps,
799 in_field_class, out_field_class);
800 break;
801 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
802 ret = field_class_signed_integer_copy(md_maps,
803 in_field_class, out_field_class);
804 break;
805 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
806 ret = field_class_unsigned_enumeration_copy(md_maps,
807 in_field_class, out_field_class);
808 break;
809 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
810 ret = field_class_signed_enumeration_copy(md_maps,
811 in_field_class, out_field_class);
812 break;
813 case BT_FIELD_CLASS_TYPE_REAL:
814 ret = field_class_real_copy(md_maps,
815 in_field_class, out_field_class);
816 break;
817 case BT_FIELD_CLASS_TYPE_STRING:
818 ret = field_class_string_copy(md_maps,
819 in_field_class, out_field_class);
820 break;
821 case BT_FIELD_CLASS_TYPE_STRUCTURE:
822 ret = field_class_structure_copy(md_maps,
823 in_field_class, out_field_class);
824 break;
825 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
826 ret = field_class_static_array_copy(md_maps,
827 in_field_class, out_field_class);
828 break;
829 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
830 ret = field_class_dynamic_array_copy(md_maps,
831 in_field_class, out_field_class);
832 break;
f29ef814
PP
833 case BT_FIELD_CLASS_TYPE_OPTION:
834 ret = field_class_option_copy(md_maps,
835 in_field_class, out_field_class);
836 break;
45c51519
PP
837 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
838 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
839 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
ca9f27f3
FD
840 ret = field_class_variant_copy(md_maps,
841 in_field_class, out_field_class);
842 break;
843 default:
844 abort();
845 }
846
847 return ret;
848}
This page took 0.073999 seconds and 4 git commands to generate.