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