4 * Babeltrace CTF IR - Event Types
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #define BT_LOG_TAG "FIELD-TYPES"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/assert-pre-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/field-path-internal.h>
35 #include <babeltrace/ctf-ir/fields-internal.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-ir/utils.h>
38 #include <babeltrace/ctf-ir/utils-internal.h>
39 #include <babeltrace/ref.h>
40 #include <babeltrace/ctf-ir/clock-class.h>
41 #include <babeltrace/ctf-ir/clock-class-internal.h>
42 #include <babeltrace/object-internal.h>
43 #include <babeltrace/ref.h>
44 #include <babeltrace/compiler-internal.h>
45 #include <babeltrace/endian-internal.h>
46 #include <babeltrace/assert-internal.h>
52 struct bt_field_type
*bt_field_type_integer_copy(
53 struct bt_field_type
*ft
);
56 struct bt_field_type
*bt_field_type_enumeration_copy_recursive(
57 struct bt_field_type
*ft
);
60 struct bt_field_type
*bt_field_type_floating_point_copy(
61 struct bt_field_type
*ft
);
64 struct bt_field_type
*bt_field_type_structure_copy_recursive(
65 struct bt_field_type
*ft
);
68 struct bt_field_type
*bt_field_type_variant_copy_recursive(
69 struct bt_field_type
*ft
);
72 struct bt_field_type
*bt_field_type_array_copy_recursive(
73 struct bt_field_type
*ft
);
76 struct bt_field_type
*bt_field_type_sequence_copy_recursive(
77 struct bt_field_type
*type
);
80 struct bt_field_type
*bt_field_type_string_copy(struct bt_field_type
*ft
);
82 static struct bt_field_type_common_methods bt_field_type_integer_methods
= {
83 .freeze
= bt_field_type_common_generic_freeze
,
84 .validate
= bt_field_type_common_integer_validate
,
85 .set_byte_order
= bt_field_type_common_integer_set_byte_order
,
86 .copy
= (bt_field_type_common_method_copy
)
87 bt_field_type_integer_copy
,
88 .compare
= bt_field_type_common_integer_compare
,
91 static struct bt_field_type_common_methods bt_field_type_floating_point_methods
= {
92 .freeze
= bt_field_type_common_generic_freeze
,
94 .set_byte_order
= bt_field_type_common_floating_point_set_byte_order
,
95 .copy
= (bt_field_type_common_method_copy
)
96 bt_field_type_floating_point_copy
,
97 .compare
= bt_field_type_common_floating_point_compare
,
100 static struct bt_field_type_common_methods bt_field_type_enumeration_methods
= {
101 .freeze
= bt_field_type_common_enumeration_freeze_recursive
,
102 .validate
= bt_field_type_common_enumeration_validate_recursive
,
103 .set_byte_order
= bt_field_type_common_enumeration_set_byte_order_recursive
,
104 .copy
= (bt_field_type_common_method_copy
)
105 bt_field_type_enumeration_copy_recursive
,
106 .compare
= bt_field_type_common_enumeration_compare_recursive
,
109 static struct bt_field_type_common_methods bt_field_type_string_methods
= {
110 .freeze
= bt_field_type_common_generic_freeze
,
112 .set_byte_order
= NULL
,
113 .copy
= (bt_field_type_common_method_copy
)
114 bt_field_type_string_copy
,
115 .compare
= bt_field_type_common_string_compare
,
118 static struct bt_field_type_common_methods bt_field_type_array_methods
= {
119 .freeze
= bt_field_type_common_array_freeze_recursive
,
120 .validate
= bt_field_type_common_array_validate_recursive
,
121 .set_byte_order
= bt_field_type_common_array_set_byte_order_recursive
,
122 .copy
= (bt_field_type_common_method_copy
)
123 bt_field_type_array_copy_recursive
,
124 .compare
= bt_field_type_common_array_compare_recursive
,
127 static struct bt_field_type_common_methods bt_field_type_sequence_methods
= {
128 .freeze
= bt_field_type_common_sequence_freeze_recursive
,
129 .validate
= bt_field_type_common_sequence_validate_recursive
,
130 .set_byte_order
= bt_field_type_common_sequence_set_byte_order_recursive
,
131 .copy
= (bt_field_type_common_method_copy
)
132 bt_field_type_sequence_copy_recursive
,
133 .compare
= bt_field_type_common_sequence_compare_recursive
,
136 static struct bt_field_type_common_methods bt_field_type_structure_methods
= {
137 .freeze
= bt_field_type_common_structure_freeze_recursive
,
138 .validate
= bt_field_type_common_structure_validate_recursive
,
139 .set_byte_order
= bt_field_type_common_structure_set_byte_order_recursive
,
140 .copy
= (bt_field_type_common_method_copy
)
141 bt_field_type_structure_copy_recursive
,
142 .compare
= bt_field_type_common_structure_compare_recursive
,
145 static struct bt_field_type_common_methods bt_field_type_variant_methods
= {
146 .freeze
= bt_field_type_common_variant_freeze_recursive
,
147 .validate
= bt_field_type_common_variant_validate_recursive
,
148 .set_byte_order
= bt_field_type_common_variant_set_byte_order_recursive
,
149 .copy
= (bt_field_type_common_method_copy
)
150 bt_field_type_variant_copy_recursive
,
151 .compare
= bt_field_type_common_variant_compare_recursive
,
155 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
161 void bt_field_type_common_initialize(struct bt_field_type_common
*ft
,
162 bool init_bo
, bt_object_release_func release_func
,
163 struct bt_field_type_common_methods
*methods
)
165 BT_ASSERT(ft
&& (ft
->id
> BT_FIELD_TYPE_ID_UNKNOWN
) &&
166 (ft
->id
< BT_FIELD_TYPE_ID_NR
));
168 bt_object_init_shared(&ft
->base
, release_func
);
169 ft
->methods
= methods
;
173 const enum bt_byte_order bo
= BT_BYTE_ORDER_NATIVE
;
175 BT_LOGD("Setting initial field type's byte order: bo=%s",
176 bt_common_byte_order_string(bo
));
177 ret
= bt_field_type_common_set_byte_order(ft
, bo
);
185 void bt_field_type_common_integer_initialize(
186 struct bt_field_type_common
*ft
,
187 unsigned int size
, bt_object_release_func release_func
,
188 struct bt_field_type_common_methods
*methods
)
190 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
193 BT_LOGD("Initializing common integer field type object: size=%u",
195 ft
->id
= BT_FIELD_TYPE_ID_INTEGER
;
197 int_ft
->base
= BT_INTEGER_BASE_DECIMAL
;
198 int_ft
->encoding
= BT_STRING_ENCODING_NONE
;
199 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
200 BT_LOGD("Initialized common integer field type object: addr=%p, size=%u",
205 void bt_field_type_common_floating_point_initialize(
206 struct bt_field_type_common
*ft
,
207 bt_object_release_func release_func
,
208 struct bt_field_type_common_methods
*methods
)
210 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
212 BT_LOGD_STR("Initializing common floating point number field type object.");
213 ft
->id
= BT_FIELD_TYPE_ID_FLOAT
;
214 flt_ft
->exp_dig
= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
215 flt_ft
->mant_dig
= FLT_MANT_DIG
;
216 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
217 BT_LOGD("Initialized common floating point number field type object: addr=%p, "
218 "exp-size=%u, mant-size=%u", ft
, flt_ft
->exp_dig
,
223 void bt_field_type_common_enumeration_initialize(
224 struct bt_field_type_common
*ft
,
225 struct bt_field_type_common
*container_ft
,
226 bt_object_release_func release_func
,
227 struct bt_field_type_common_methods
*methods
)
229 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
231 BT_ASSERT(container_ft
);
232 BT_LOGD("Initializing common enumeration field type object: int-ft-addr=%p",
234 ft
->id
= BT_FIELD_TYPE_ID_ENUM
;
235 enum_ft
->container_ft
= bt_get(container_ft
);
236 enum_ft
->entries
= g_ptr_array_new_with_free_func(
237 (GDestroyNotify
) destroy_enumeration_mapping
);
238 bt_field_type_common_initialize(ft
, false, release_func
, methods
);
239 BT_LOGD("Initialized common enumeration field type object: addr=%p, "
240 "int-ft-addr=%p, int-ft-size=%u", ft
, container_ft
,
241 bt_field_type_common_integer_get_size(container_ft
));
245 void bt_field_type_common_string_initialize(
246 struct bt_field_type_common
*ft
,
247 bt_object_release_func release_func
,
248 struct bt_field_type_common_methods
*methods
)
250 struct bt_field_type_common_string
*string_ft
= BT_FROM_COMMON(ft
);
252 BT_LOGD_STR("Initializing common string field type object.");
253 ft
->id
= BT_FIELD_TYPE_ID_STRING
;
254 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
255 string_ft
->encoding
= BT_STRING_ENCODING_UTF8
;
256 ft
->alignment
= CHAR_BIT
;
257 BT_LOGD("Initialized common string field type object: addr=%p", ft
);
261 void bt_field_type_common_structure_initialize(
262 struct bt_field_type_common
*ft
,
263 bt_object_release_func release_func
,
264 struct bt_field_type_common_methods
*methods
)
266 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
268 BT_LOGD_STR("Initializing common structure field type object.");
269 ft
->id
= BT_FIELD_TYPE_ID_STRUCT
;
270 struct_ft
->fields
= g_array_new(FALSE
, TRUE
,
271 sizeof(struct bt_field_type_common_structure_field
));
272 struct_ft
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
273 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
274 BT_LOGD("Initialized common structure field type object: addr=%p", ft
);
278 void bt_field_type_common_array_initialize(
279 struct bt_field_type_common
*ft
,
280 struct bt_field_type_common
*element_ft
,
281 unsigned int length
, bt_object_release_func release_func
,
282 struct bt_field_type_common_methods
*methods
)
284 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
286 BT_ASSERT(element_ft
);
287 BT_LOGD("Initializing common array field type object: element-ft-addr=%p, "
288 "length=%u", element_ft
, length
);
289 ft
->id
= BT_FIELD_TYPE_ID_ARRAY
;
290 array_ft
->element_ft
= bt_get(element_ft
);
291 array_ft
->length
= length
;
292 bt_field_type_common_initialize(ft
, false, release_func
, methods
);
293 BT_LOGD("Initialized common array field type object: addr=%p, "
294 "element-ft-addr=%p, length=%u", ft
, element_ft
, length
);
298 void bt_field_type_common_sequence_initialize(
299 struct bt_field_type_common
*ft
,
300 struct bt_field_type_common
*element_ft
,
301 const char *length_field_name
,
302 bt_object_release_func release_func
,
303 struct bt_field_type_common_methods
*methods
)
305 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
307 BT_ASSERT(element_ft
);
308 BT_ASSERT(length_field_name
);
309 BT_ASSERT(bt_identifier_is_valid(length_field_name
));
310 BT_LOGD("Initializing common sequence field type object: element-ft-addr=%p, "
311 "length-field-name=\"%s\"", element_ft
, length_field_name
);
312 ft
->id
= BT_FIELD_TYPE_ID_SEQUENCE
;
313 seq_ft
->element_ft
= bt_get(element_ft
);
314 seq_ft
->length_field_name
= g_string_new(length_field_name
);
315 bt_field_type_common_initialize(ft
, false, release_func
, methods
);
316 BT_LOGD("Initialized common sequence field type object: addr=%p, "
317 "element-ft-addr=%p, length-field-name=\"%s\"",
318 ft
, element_ft
, length_field_name
);
322 void bt_field_type_common_variant_initialize(
323 struct bt_field_type_common
*ft
,
324 struct bt_field_type_common
*tag_ft
,
325 const char *tag_name
,
326 bt_object_release_func release_func
,
327 struct bt_field_type_common_methods
*methods
)
329 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
331 BT_ASSERT(!tag_name
|| bt_identifier_is_valid(tag_name
));
332 BT_LOGD("Initializing common variant field type object: "
333 "tag-ft-addr=%p, tag-field-name=\"%s\"",
335 ft
->id
= BT_FIELD_TYPE_ID_VARIANT
;
336 var_ft
->tag_name
= g_string_new(tag_name
);
337 var_ft
->choice_name_to_index
= g_hash_table_new(NULL
, NULL
);
338 var_ft
->choices
= g_array_new(FALSE
, TRUE
,
339 sizeof(struct bt_field_type_common_variant_choice
));
342 var_ft
->tag_ft
= bt_get(tag_ft
);
345 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
346 /* A variant's alignment is undefined */
348 BT_LOGD("Initialized common variant field type object: addr=%p, "
349 "tag-ft-addr=%p, tag-field-name=\"%s\"",
350 ft
, tag_ft
, tag_name
);
354 void bt_field_type_common_integer_destroy(struct bt_object
*obj
)
356 struct bt_field_type_common_integer
*ft
= (void *) obj
;
362 BT_LOGD("Destroying integer field type object: addr=%p", ft
);
363 BT_LOGD_STR("Putting mapped clock class.");
364 bt_put(ft
->mapped_clock_class
);
369 void bt_field_type_common_floating_point_destroy(struct bt_object
*obj
)
371 struct bt_field_type_common_floating_point
*ft
= (void *) obj
;
377 BT_LOGD("Destroying floating point number field type object: addr=%p", ft
);
382 void bt_field_type_common_enumeration_destroy_recursive(struct bt_object
*obj
)
384 struct bt_field_type_common_enumeration
*ft
= (void *) obj
;
390 BT_LOGD("Destroying enumeration field type object: addr=%p", ft
);
391 g_ptr_array_free(ft
->entries
, TRUE
);
392 BT_LOGD_STR("Putting container field type.");
393 bt_put(ft
->container_ft
);
398 void bt_field_type_common_string_destroy(struct bt_object
*obj
)
400 struct bt_field_type_common_string
*ft
= (void *) obj
;
406 BT_LOGD("Destroying string field type object: addr=%p", ft
);
411 void bt_field_type_common_structure_field_finalize(
412 struct bt_field_type_common_structure_field
*field
)
418 BT_LOGD("Finalizing structure field type's field: "
419 "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
420 field
, field
->type
, g_quark_to_string(field
->name
));
421 BT_LOGD_STR("Putting field type.");
426 void bt_field_type_common_structure_destroy_recursive(struct bt_object
*obj
)
428 struct bt_field_type_common_structure
*ft
= (void *) obj
;
435 BT_LOGD("Destroying structure field type object: addr=%p", ft
);
438 for (i
= 0; i
< ft
->fields
->len
; i
++) {
439 bt_field_type_common_structure_field_finalize(
440 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
444 g_array_free(ft
->fields
, TRUE
);
447 if (ft
->field_name_to_index
) {
448 g_hash_table_destroy(ft
->field_name_to_index
);
455 void bt_field_type_common_array_destroy_recursive(struct bt_object
*obj
)
457 struct bt_field_type_common_array
*ft
= (void *) obj
;
463 BT_LOGD("Destroying array field type object: addr=%p", ft
);
464 BT_LOGD_STR("Putting element field type.");
465 bt_put(ft
->element_ft
);
470 void bt_field_type_common_sequence_destroy_recursive(struct bt_object
*obj
)
472 struct bt_field_type_common_sequence
*ft
= (void *) obj
;
478 BT_LOGD("Destroying sequence field type object: addr=%p", ft
);
479 BT_LOGD_STR("Putting element field type.");
480 bt_put(ft
->element_ft
);
481 g_string_free(ft
->length_field_name
, TRUE
);
482 BT_LOGD_STR("Putting length field path.");
483 bt_put(ft
->length_field_path
);
488 void bt_field_type_common_variant_choice_finalize(
489 struct bt_field_type_common_variant_choice
*choice
)
495 BT_LOGD("Finalizing variant field type's choice: "
496 "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
497 choice
, choice
->type
, g_quark_to_string(choice
->name
));
498 BT_LOGD_STR("Putting field type.");
499 bt_put(choice
->type
);
501 if (choice
->ranges
) {
502 g_array_free(choice
->ranges
, TRUE
);
507 void bt_field_type_common_variant_destroy_recursive(struct bt_object
*obj
)
509 struct bt_field_type_common_variant
*ft
= (void *) obj
;
516 BT_LOGD("Destroying variant field type object: addr=%p", ft
);
519 for (i
= 0; i
< ft
->choices
->len
; i
++) {
520 bt_field_type_common_variant_choice_finalize(
521 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
525 g_array_free(ft
->choices
, TRUE
);
528 if (ft
->choice_name_to_index
) {
529 g_hash_table_destroy(ft
->choice_name_to_index
);
533 g_string_free(ft
->tag_name
, TRUE
);
536 BT_LOGD_STR("Putting tag field type.");
538 BT_LOGD_STR("Putting tag field path.");
539 bt_put(ft
->tag_field_path
);
543 struct range_overlap_query
{
558 void check_ranges_overlap(gpointer element
, gpointer query
)
560 struct enumeration_mapping
*mapping
= element
;
561 struct range_overlap_query
*overlap_query
= query
;
563 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
564 && overlap_query
->range_start
._signed
<=
565 mapping
->range_end
._signed
) {
566 overlap_query
->overlaps
= 1;
567 overlap_query
->mapping_name
= mapping
->string
;
570 overlap_query
->overlaps
|=
571 mapping
->string
== overlap_query
->mapping_name
;
573 if (overlap_query
->overlaps
) {
574 BT_LOGV("Overlapping enumeration field type mappings: "
575 "mapping-name=\"%s\", "
576 "mapping-a-range-start=%" PRId64
", "
577 "mapping-a-range-end=%" PRId64
", "
578 "mapping-b-range-start=%" PRId64
", "
579 "mapping-b-range-end=%" PRId64
,
580 g_quark_to_string(mapping
->string
),
581 mapping
->range_start
._signed
,
582 mapping
->range_end
._signed
,
583 overlap_query
->range_start
._signed
,
584 overlap_query
->range_end
._signed
);
589 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
591 struct enumeration_mapping
*mapping
= element
;
592 struct range_overlap_query
*overlap_query
= query
;
594 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
595 && overlap_query
->range_start
._unsigned
<=
596 mapping
->range_end
._unsigned
) {
597 overlap_query
->overlaps
= 1;
598 overlap_query
->mapping_name
= mapping
->string
;
601 overlap_query
->overlaps
|=
602 mapping
->string
== overlap_query
->mapping_name
;
604 if (overlap_query
->overlaps
) {
605 BT_LOGW("Overlapping enumeration field type mappings: "
606 "mapping-name=\"%s\", "
607 "mapping-a-range-start=%" PRIu64
", "
608 "mapping-a-range-end=%" PRIu64
", "
609 "mapping-b-range-start=%" PRIu64
", "
610 "mapping-b-range-end=%" PRIu64
,
611 g_quark_to_string(mapping
->string
),
612 mapping
->range_start
._unsigned
,
613 mapping
->range_end
._unsigned
,
614 overlap_query
->range_start
._unsigned
,
615 overlap_query
->range_end
._unsigned
);
620 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
621 struct enumeration_mapping
**b
)
623 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
627 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
628 struct enumeration_mapping
**b
)
630 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
634 int add_structure_variant_member(GArray
*members
,
635 GHashTable
*field_name_to_index
,
636 struct bt_field_type_common
*field_type
, const char *field_name
,
640 GQuark name_quark
= g_quark_from_string(field_name
);
641 struct bt_field_type_common
**member_ft
;
644 /* Make sure structure does not contain a field of the same name */
645 if (g_hash_table_lookup_extended(field_name_to_index
,
646 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
647 BT_LOGW("Structure or variant field type already contains a field type with this name: "
648 "field-name=\"%s\"", field_name
);
653 g_array_set_size(members
, members
->len
+ 1);
656 struct bt_field_type_common_variant_choice
*choice
=
657 &g_array_index(members
,
658 struct bt_field_type_common_variant_choice
,
661 member_ft
= &choice
->type
;
662 member_name
= &choice
->name
;
663 BT_ASSERT(!choice
->ranges
);
664 choice
->ranges
= g_array_new(FALSE
, TRUE
,
665 sizeof(struct bt_field_type_common_variant_choice_range
));
666 BT_ASSERT(choice
->ranges
);
668 struct bt_field_type_common_structure_field
*field
=
669 &g_array_index(members
,
670 struct bt_field_type_common_structure_field
,
673 member_ft
= &field
->type
;
674 member_name
= &field
->name
;
677 *member_name
= name_quark
;
678 *member_ft
= bt_get(field_type
);
679 g_hash_table_insert(field_name_to_index
,
680 GUINT_TO_POINTER(name_quark
),
681 GUINT_TO_POINTER(members
->len
- 1));
682 BT_LOGV("Added structure/variant field type member: member-ft-addr=%p, "
683 "member-name=\"%s\"", field_type
, field_name
);
690 int bt_field_type_common_integer_validate(struct bt_field_type_common
*ft
)
693 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
695 if (int_ft
->mapped_clock_class
&& int_ft
->is_signed
) {
696 BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
697 "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
698 ft
, int_ft
->mapped_clock_class
,
699 bt_clock_class_get_name(int_ft
->mapped_clock_class
));
709 struct enumeration_mapping
*bt_field_type_common_enumeration_get_mapping_by_index(
710 struct bt_field_type_common
*ft
, uint64_t index
)
712 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
713 struct enumeration_mapping
*mapping
= NULL
;
715 if (index
>= enum_ft
->entries
->len
) {
716 BT_LOGW("Invalid parameter: index is out of bounds: "
717 "addr=%p, index=%" PRIu64
", count=%u",
718 ft
, index
, enum_ft
->entries
->len
);
722 mapping
= g_ptr_array_index(enum_ft
->entries
, index
);
729 * Note: This algorithm is O(n^2) vs number of enumeration mappings.
730 * Only used when freezing an enumeration.
733 void bt_field_type_common_enumeration_set_range_overlap(
734 struct bt_field_type_common_enumeration
*ft
)
739 BT_LOGV("Setting enumeration field type's overlap flag: addr=%p",
741 len
= ft
->entries
->len
;
742 is_signed
= bt_field_type_common_integer_is_signed(
743 BT_TO_COMMON(ft
->container_ft
));
745 for (i
= 0; i
< len
; i
++) {
746 for (j
= i
+ 1; j
< len
; j
++) {
747 struct enumeration_mapping
*mapping
[2];
749 mapping
[0] = bt_field_type_common_enumeration_get_mapping_by_index(
750 BT_TO_COMMON(ft
), i
);
751 mapping
[1] = bt_field_type_common_enumeration_get_mapping_by_index(
752 BT_TO_COMMON(ft
), j
);
754 if (mapping
[0]->range_start
._signed
755 <= mapping
[1]->range_end
._signed
756 && mapping
[0]->range_end
._signed
757 >= mapping
[1]->range_start
._signed
) {
758 ft
->has_overlapping_ranges
= BT_TRUE
;
762 if (mapping
[0]->range_start
._unsigned
763 <= mapping
[1]->range_end
._unsigned
764 && mapping
[0]->range_end
._unsigned
765 >= mapping
[1]->range_start
._unsigned
) {
766 ft
->has_overlapping_ranges
= BT_TRUE
;
774 if (ft
->has_overlapping_ranges
) {
775 BT_LOGV_STR("Enumeration field type has overlapping ranges.");
777 BT_LOGV_STR("Enumeration field type has no overlapping ranges.");
782 int bt_field_type_common_enumeration_validate_recursive(
783 struct bt_field_type_common
*ft
)
786 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
788 ret
= bt_field_type_common_integer_validate(
789 BT_TO_COMMON(enum_ft
->container_ft
));
791 BT_LOGW("Invalid enumeration field type: container type is invalid: "
792 "enum-ft-addr=%p, int-ft-addr=%p",
793 ft
, enum_ft
->container_ft
);
797 /* Ensure enum has entries */
798 if (enum_ft
->entries
->len
== 0) {
799 BT_LOGW("Invalid enumeration field type: no entries: "
810 int bt_field_type_common_sequence_validate_recursive(
811 struct bt_field_type_common
*ft
)
814 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
816 /* Length field name should be set at this point */
817 if (seq_ft
->length_field_name
->len
== 0) {
818 BT_LOGW("Invalid sequence field type: no length field name: "
824 ret
= bt_field_type_common_validate(seq_ft
->element_ft
);
826 BT_LOGW("Invalid sequence field type: invalid element field type: "
827 "seq-ft-addr=%p, element-ft-add=%p",
828 ft
, seq_ft
->element_ft
);
836 int bt_field_type_common_array_validate_recursive(
837 struct bt_field_type_common
*ft
)
840 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
842 ret
= bt_field_type_common_validate(array_ft
->element_ft
);
844 BT_LOGW("Invalid array field type: invalid element field type: "
845 "array-ft-addr=%p, element-ft-add=%p",
846 ft
, array_ft
->element_ft
);
853 int bt_field_type_common_structure_validate_recursive(
854 struct bt_field_type_common
*ft
)
857 struct bt_field_type_common
*child_ft
= NULL
;
858 int64_t field_count
=
859 bt_field_type_common_structure_get_field_count(ft
);
862 BT_ASSERT(field_count
>= 0);
864 for (i
= 0; i
< field_count
; ++i
) {
865 const char *field_name
;
867 ret
= bt_field_type_common_structure_borrow_field_by_index(ft
,
868 &field_name
, &child_ft
, i
);
870 ret
= bt_field_type_common_validate(child_ft
);
872 BT_LOGW("Invalid structure field type: "
873 "a contained field type is invalid: "
874 "struct-ft-addr=%p, field-ft-addr=%p, "
875 "field-name=\"%s\", field-index=%" PRId64
,
876 ft
, child_ft
, field_name
, i
);
886 bt_bool
bt_field_type_common_enumeration_has_overlapping_ranges(
887 struct bt_field_type_common_enumeration
*enum_ft
)
889 if (!enum_ft
->common
.frozen
) {
890 bt_field_type_common_enumeration_set_range_overlap(enum_ft
);
893 return enum_ft
->has_overlapping_ranges
;
897 int bt_field_type_common_variant_validate_recursive(
898 struct bt_field_type_common
*ft
)
902 struct bt_field_type_common
*child_ft
= NULL
;
903 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
906 if (var_ft
->tag_name
->len
== 0) {
907 BT_LOGW("Invalid variant field type: no tag field name: "
913 if (!var_ft
->tag_ft
) {
914 BT_LOGW("Invalid variant field type: no tag field type: "
915 "addr=%p, tag-field-name=\"%s\"", var_ft
,
916 var_ft
->tag_name
->str
);
921 if (bt_field_type_common_enumeration_has_overlapping_ranges(var_ft
->tag_ft
)) {
922 BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
923 "variant-ft-addr=%p, tag-field-name=\"%s\", "
924 "enum-ft-addr=%p", ft
, var_ft
->tag_name
->str
,
931 * It is valid to have a variant field type which does not have
932 * the fields corresponding to each label in the associated
935 * It is also valid to have variant field type fields which
936 * cannot be selected because the variant field type tag has no
937 * mapping named as such. This scenario, while not ideal, cannot
940 * If a non-existing field happens to be selected by an
941 * enumeration while reading a variant field, an error will be
942 * generated at that point (while reading the stream).
944 field_count
= bt_field_type_common_variant_get_field_count(ft
);
945 if (field_count
< 0) {
946 BT_LOGW("Invalid variant field type: no fields: "
947 "addr=%p, tag-field-name=\"%s\"",
948 ft
, var_ft
->tag_name
->str
);
953 for (i
= 0; i
< field_count
; ++i
) {
954 const char *field_name
;
956 ret
= bt_field_type_common_variant_borrow_field_by_index(ft
,
957 &field_name
, &child_ft
, i
);
959 ret
= bt_field_type_common_validate(child_ft
);
961 BT_LOGW("Invalid variant field type: "
962 "a contained field type is invalid: "
963 "variant-ft-addr=%p, tag-field-name=\"%s\", "
964 "field-ft-addr=%p, field-name=\"%s\", "
965 "field-index=%" PRId64
,
966 ft
, var_ft
->tag_name
->str
, child_ft
,
977 * This function validates a given field type without considering
978 * where this field type is located. It only validates the properties
979 * of the given field type and the properties of its children if
983 int bt_field_type_common_validate(struct bt_field_type_common
*ft
)
990 /* Already marked as valid */
994 if (ft
->methods
->validate
) {
995 ret
= ft
->methods
->validate(ft
);
998 if (ret
== 0 && ft
->frozen
) {
999 /* Field type is valid */
1000 BT_LOGV("Marking field type as valid: addr=%p", ft
);
1008 struct bt_field_type
*bt_field_type_integer_create(unsigned int size
)
1010 struct bt_field_type_common_integer
*integer
= NULL
;
1012 BT_LOGD("Creating integer field type object: size=%u", size
);
1014 if (size
== 0 || size
> 64) {
1015 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
1020 integer
= g_new0(struct bt_field_type_common_integer
, 1);
1022 BT_LOGE_STR("Failed to allocate one integer field type.");
1026 bt_field_type_common_integer_initialize(BT_TO_COMMON(integer
),
1027 size
, bt_field_type_common_integer_destroy
,
1028 &bt_field_type_integer_methods
);
1029 BT_LOGD("Created integer field type object: addr=%p, size=%u",
1037 return (void *) integer
;
1041 int bt_field_type_common_integer_get_size(struct bt_field_type_common
*ft
)
1043 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1045 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1046 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1048 return (int) int_ft
->size
;
1051 int bt_field_type_integer_get_size(struct bt_field_type
*ft
)
1053 return bt_field_type_common_integer_get_size((void *) ft
);
1057 bt_bool
bt_field_type_common_integer_is_signed(struct bt_field_type_common
*ft
)
1059 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1061 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1062 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1064 return int_ft
->is_signed
;
1067 bt_bool
bt_field_type_integer_is_signed(struct bt_field_type
*ft
)
1069 return bt_field_type_common_integer_is_signed((void *) ft
);
1073 int bt_field_type_common_integer_set_is_signed(struct bt_field_type_common
*ft
,
1077 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1080 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1086 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1092 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1093 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1094 "addr=%p, ft-id=%s", ft
,
1095 bt_common_field_type_id_string(ft
->id
));
1100 int_ft
->is_signed
= !!is_signed
;
1101 BT_LOGV("Set integer field type's signedness: addr=%p, is-signed=%d",
1108 int bt_field_type_integer_set_is_signed(struct bt_field_type
*ft
,
1111 return bt_field_type_common_integer_set_is_signed((void *) ft
,
1116 int bt_field_type_common_integer_set_size(struct bt_field_type_common
*ft
,
1120 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1123 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1129 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1135 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1136 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1137 "addr=%p, ft-id=%s", ft
,
1138 bt_common_field_type_id_string(ft
->id
));
1143 if (size
== 0 || size
> 64) {
1144 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
1145 "addr=%p, size=%u", ft
, size
);
1150 int_ft
->size
= size
;
1151 BT_LOGV("Set integer field type's size: addr=%p, size=%u",
1158 int bt_field_type_integer_set_size(struct bt_field_type
*ft
,
1161 return bt_field_type_common_integer_set_size((void *) ft
, size
);
1165 enum bt_integer_base
bt_field_type_common_integer_get_base(
1166 struct bt_field_type_common
*ft
)
1168 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1170 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1171 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1173 return int_ft
->base
;
1176 enum bt_integer_base
bt_field_type_integer_get_base(
1177 struct bt_field_type
*ft
)
1179 return bt_field_type_common_integer_get_base((void *) ft
);
1183 int bt_field_type_common_integer_set_base(struct bt_field_type_common
*ft
,
1184 enum bt_integer_base base
)
1187 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1190 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1196 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1202 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1203 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1204 "addr=%p, ft-id=%s", ft
,
1205 bt_common_field_type_id_string(ft
->id
));
1211 case BT_INTEGER_BASE_UNSPECIFIED
:
1212 case BT_INTEGER_BASE_BINARY
:
1213 case BT_INTEGER_BASE_OCTAL
:
1214 case BT_INTEGER_BASE_DECIMAL
:
1215 case BT_INTEGER_BASE_HEXADECIMAL
:
1217 int_ft
->base
= base
;
1221 BT_LOGW("Invalid parameter: unknown integer field type base: "
1222 "addr=%p, base=%d", ft
, base
);
1226 BT_LOGV("Set integer field type's base: addr=%p, base=%s",
1227 ft
, bt_common_integer_base_string(base
));
1233 int bt_field_type_integer_set_base(struct bt_field_type
*ft
,
1234 enum bt_integer_base base
)
1236 return bt_field_type_common_integer_set_base((void *) ft
, base
);
1240 enum bt_string_encoding
bt_field_type_common_integer_get_encoding(
1241 struct bt_field_type_common
*ft
)
1243 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1245 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1246 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1248 return int_ft
->encoding
;
1251 enum bt_string_encoding
bt_field_type_integer_get_encoding(
1252 struct bt_field_type
*ft
)
1254 return bt_field_type_common_integer_get_encoding((void *) ft
);
1258 int bt_field_type_common_integer_set_encoding(struct bt_field_type_common
*ft
,
1259 enum bt_string_encoding encoding
)
1262 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1265 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1271 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1277 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1278 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1279 "addr=%p, ft-id=%s", ft
,
1280 bt_common_field_type_id_string(ft
->id
));
1285 if (encoding
!= BT_STRING_ENCODING_UTF8
&&
1286 encoding
!= BT_STRING_ENCODING_ASCII
&&
1287 encoding
!= BT_STRING_ENCODING_NONE
) {
1288 BT_LOGW("Invalid parameter: unknown string encoding: "
1289 "addr=%p, encoding=%d", ft
, encoding
);
1294 int_ft
->encoding
= encoding
;
1295 BT_LOGV("Set integer field type's encoding: addr=%p, encoding=%s",
1296 ft
, bt_common_string_encoding_string(encoding
));
1302 int bt_field_type_integer_set_encoding(struct bt_field_type
*ft
,
1303 enum bt_string_encoding encoding
)
1305 return bt_field_type_common_integer_set_encoding((void *) ft
, encoding
);
1309 struct bt_clock_class
*bt_field_type_common_integer_borrow_mapped_clock_class(
1310 struct bt_field_type_common
*ft
)
1312 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1314 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1315 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1317 return int_ft
->mapped_clock_class
;
1320 struct bt_clock_class
*bt_field_type_integer_borrow_mapped_clock_class(
1321 struct bt_field_type
*ft
)
1323 return bt_field_type_common_integer_borrow_mapped_clock_class(
1328 int bt_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
1329 struct bt_field_type_common
*ft
,
1330 struct bt_clock_class
*clock_class
)
1332 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1336 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
1341 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1342 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1343 "addr=%p, ft-id=%s", ft
,
1344 bt_common_field_type_id_string(ft
->id
));
1348 if (!bt_clock_class_is_valid(clock_class
)) {
1349 BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
1350 "clock-class-addr=%p, clock-class-name=\"%s\"",
1352 bt_clock_class_get_name(clock_class
));
1357 bt_put(int_ft
->mapped_clock_class
);
1358 int_ft
->mapped_clock_class
= bt_get(clock_class
);
1359 BT_LOGV("Set integer field type's mapped clock class: ft-addr=%p, "
1360 "clock-class-addr=%p, clock-class-name=\"%s\"",
1361 ft
, clock_class
, bt_clock_class_get_name(clock_class
));
1368 int bt_field_type_common_integer_set_mapped_clock_class(
1369 struct bt_field_type_common
*ft
,
1370 struct bt_clock_class
*clock_class
)
1375 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1381 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1387 ret
= bt_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
1394 int bt_field_type_integer_set_mapped_clock_class(struct bt_field_type
*ft
,
1395 struct bt_clock_class
*clock_class
)
1397 return bt_field_type_common_integer_set_mapped_clock_class((void *) ft
,
1402 void bt_field_type_enum_iter_destroy(struct bt_object
*obj
)
1404 struct bt_field_type_enumeration_mapping_iterator
*iter
=
1406 struct bt_field_type_enumeration_mapping_iterator
,
1409 BT_LOGD("Destroying enumeration field type mapping iterator: addr=%p",
1411 BT_LOGD_STR("Putting parent enumeration field type.");
1412 bt_put(iter
->enumeration_ft
);
1417 struct bt_field_type_enumeration_mapping_iterator
*
1418 bt_field_type_common_enumeration_find_mappings_type(
1419 struct bt_field_type_common
*ft
,
1420 enum bt_field_type_enumeration_mapping_iterator_type iterator_type
)
1422 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1424 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1425 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
,
1427 iter
= g_new0(struct bt_field_type_enumeration_mapping_iterator
, 1);
1429 BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
1433 bt_object_init_shared(&iter
->base
, bt_field_type_enum_iter_destroy
);
1434 iter
->enumeration_ft
= bt_get(ft
);
1436 iter
->type
= iterator_type
;
1443 struct bt_field_type_enumeration_mapping_iterator
*
1444 bt_field_type_common_enumeration_find_mappings_by_name(
1445 struct bt_field_type_common
*ft
, const char *name
)
1447 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1449 iter
= bt_field_type_common_enumeration_find_mappings_type(
1450 ft
, ITERATOR_BY_NAME
);
1452 BT_LOGW("Cannot create enumeration field type mapping iterator: "
1453 "ft-addr=%p, mapping-name=\"%s\"", ft
, name
);
1457 iter
->u
.name_quark
= g_quark_try_string(name
);
1458 if (!iter
->u
.name_quark
) {
1460 * No results are possible, set the iterator's position at the
1463 iter
->index
= iter
->enumeration_ft
->entries
->len
;
1473 struct bt_field_type_enumeration_mapping_iterator
*
1474 bt_field_type_enumeration_find_mappings_by_name(
1475 struct bt_field_type
*ft
, const char *name
)
1477 return bt_field_type_common_enumeration_find_mappings_by_name(
1481 int bt_field_type_enumeration_mapping_iterator_next(
1482 struct bt_field_type_enumeration_mapping_iterator
*iter
)
1484 struct bt_field_type_common_enumeration
*enum_ft
= iter
->enumeration_ft
;
1485 int i
, ret
= 0, len
;
1487 BT_ASSERT_PRE_NON_NULL(iter
, "Enumeration field type mapping iterator");
1488 len
= enum_ft
->entries
->len
;
1489 for (i
= iter
->index
+ 1; i
< len
; i
++) {
1490 struct enumeration_mapping
*mapping
=
1491 bt_field_type_common_enumeration_get_mapping_by_index(
1492 BT_TO_COMMON(enum_ft
), i
);
1494 switch (iter
->type
) {
1495 case ITERATOR_BY_NAME
:
1496 if (mapping
->string
== iter
->u
.name_quark
) {
1501 case ITERATOR_BY_SIGNED_VALUE
:
1503 int64_t value
= iter
->u
.signed_value
;
1505 if (value
>= mapping
->range_start
._signed
&&
1506 value
<= mapping
->range_end
._signed
) {
1512 case ITERATOR_BY_UNSIGNED_VALUE
:
1514 uint64_t value
= iter
->u
.unsigned_value
;
1516 if (value
>= mapping
->range_start
._unsigned
&&
1517 value
<= mapping
->range_end
._unsigned
) {
1524 BT_LOGF("Invalid enumeration field type mapping iterator type: "
1525 "type=%d", iter
->type
);
1537 struct bt_field_type_enumeration_mapping_iterator
*
1538 bt_field_type_common_enumeration_signed_find_mappings_by_value(
1539 struct bt_field_type_common
*ft
, int64_t value
)
1541 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1543 iter
= bt_field_type_common_enumeration_find_mappings_type(
1544 ft
, ITERATOR_BY_SIGNED_VALUE
);
1546 BT_LOGW("Cannot create enumeration field type mapping iterator: "
1547 "ft-addr=%p, value=%" PRId64
, ft
, value
);
1551 if (bt_field_type_common_integer_is_signed(
1552 BT_TO_COMMON(iter
->enumeration_ft
->container_ft
)) != 1) {
1553 BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
1554 "enum-ft-addr=%p, int-ft-addr=%p",
1555 ft
, iter
->enumeration_ft
->container_ft
);
1559 iter
->u
.signed_value
= value
;
1567 struct bt_field_type_enumeration_mapping_iterator
*
1568 bt_field_type_enumeration_signed_find_mappings_by_value(
1569 struct bt_field_type
*ft
, int64_t value
)
1571 return bt_field_type_common_enumeration_signed_find_mappings_by_value(
1572 (void *) ft
, value
);
1576 struct bt_field_type_enumeration_mapping_iterator
*
1577 bt_field_type_common_enumeration_unsigned_find_mappings_by_value(
1578 struct bt_field_type_common
*ft
, uint64_t value
)
1580 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1582 iter
= bt_field_type_common_enumeration_find_mappings_type(
1583 ft
, ITERATOR_BY_UNSIGNED_VALUE
);
1585 BT_LOGW("Cannot create enumeration field type mapping iterator: "
1586 "ft-addr=%p, value=%" PRIu64
, ft
, value
);
1590 if (bt_field_type_common_integer_is_signed(
1591 BT_TO_COMMON(iter
->enumeration_ft
->container_ft
)) != 0) {
1592 BT_LOGW("Invalid parameter: enumeration field type is signed: "
1593 "enum-ft-addr=%p, int-ft-addr=%p",
1594 ft
, iter
->enumeration_ft
->container_ft
);
1598 iter
->u
.unsigned_value
= value
;
1606 struct bt_field_type_enumeration_mapping_iterator
*
1607 bt_field_type_enumeration_unsigned_find_mappings_by_value(
1608 struct bt_field_type
*ft
, uint64_t value
)
1610 return bt_field_type_common_enumeration_unsigned_find_mappings_by_value(
1611 (void *) ft
, value
);
1614 int bt_field_type_enumeration_mapping_iterator_signed_get(
1615 struct bt_field_type_enumeration_mapping_iterator
*iter
,
1616 const char **mapping_name
, int64_t *range_begin
,
1619 BT_ASSERT_PRE_NON_NULL(iter
, "Enumeration field type mapping iterator");
1620 BT_ASSERT_PRE(iter
->index
!= -1,
1621 "Invalid enumeration field type mapping iterator access: "
1622 "addr=%p, position=-1", iter
);
1623 return bt_field_type_common_enumeration_signed_get_mapping_by_index(
1624 (void *) iter
->enumeration_ft
, iter
->index
,
1625 mapping_name
, range_begin
, range_end
);
1628 int bt_field_type_enumeration_mapping_iterator_unsigned_get(
1629 struct bt_field_type_enumeration_mapping_iterator
*iter
,
1630 const char **mapping_name
, uint64_t *range_begin
,
1631 uint64_t *range_end
)
1633 BT_ASSERT_PRE_NON_NULL(iter
, "Enumeration field type mapping iterator");
1634 BT_ASSERT_PRE(iter
->index
!= -1,
1635 "Invalid enumeration field type mapping iterator access: "
1636 "addr=%p, position=-1", iter
);
1637 return bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
1638 (void *) iter
->enumeration_ft
, iter
->index
,
1639 mapping_name
, range_begin
, range_end
);
1643 int bt_field_type_common_enumeration_signed_get_mapping_by_index(
1644 struct bt_field_type_common
*ft
, uint64_t index
,
1645 const char **mapping_name
, int64_t *range_begin
,
1649 struct enumeration_mapping
*mapping
;
1651 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1652 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
,
1653 BT_FIELD_TYPE_ID_ENUM
, "Field type");
1654 mapping
= bt_field_type_common_enumeration_get_mapping_by_index(ft
,
1657 /* bt_field_type_common_enumeration_get_mapping_by_index() logs errors */
1663 *mapping_name
= g_quark_to_string(mapping
->string
);
1664 BT_ASSERT(*mapping_name
);
1668 *range_begin
= mapping
->range_start
._signed
;
1672 *range_end
= mapping
->range_end
._signed
;
1679 int bt_field_type_enumeration_signed_get_mapping_by_index(
1680 struct bt_field_type
*ft
, uint64_t index
,
1681 const char **mapping_name
, int64_t *range_begin
,
1684 return bt_field_type_common_enumeration_signed_get_mapping_by_index(
1685 (void *) ft
, index
, mapping_name
, range_begin
, range_end
);
1689 int bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
1690 struct bt_field_type_common
*ft
, uint64_t index
,
1691 const char **mapping_name
, uint64_t *range_begin
,
1692 uint64_t *range_end
)
1695 struct enumeration_mapping
*mapping
;
1697 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1698 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
, "Field type");
1699 mapping
= bt_field_type_common_enumeration_get_mapping_by_index(
1702 /* bt_field_type_common_enumeration_get_mapping_by_index() reports any error */
1708 *mapping_name
= g_quark_to_string(mapping
->string
);
1709 BT_ASSERT(*mapping_name
);
1713 *range_begin
= mapping
->range_start
._unsigned
;
1717 *range_end
= mapping
->range_end
._unsigned
;
1724 int bt_field_type_enumeration_unsigned_get_mapping_by_index(
1725 struct bt_field_type
*ft
, uint64_t index
,
1726 const char **mapping_name
, uint64_t *range_begin
,
1727 uint64_t *range_end
)
1729 return bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
1730 (void *) ft
, index
, mapping_name
, range_begin
, range_end
);
1733 struct bt_field_type
*bt_field_type_enumeration_create(
1734 struct bt_field_type
*container_ft
)
1736 struct bt_field_type_common_enumeration
*enumeration
= NULL
;
1737 struct bt_field_type_common
*int_ft
= (void *) container_ft
;
1739 BT_LOGD("Creating enumeration field type object: int-ft-addr=%p",
1742 if (!container_ft
) {
1743 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1747 if (int_ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1748 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
1749 "container-ft-addr=%p, container-ft-id=%s",
1750 container_ft
, bt_common_field_type_id_string(int_ft
->id
));
1754 enumeration
= g_new0(struct bt_field_type_common_enumeration
, 1);
1756 BT_LOGE_STR("Failed to allocate one enumeration field type.");
1760 bt_field_type_common_enumeration_initialize(BT_TO_COMMON(enumeration
),
1761 int_ft
, bt_field_type_common_enumeration_destroy_recursive
,
1762 &bt_field_type_enumeration_methods
);
1763 BT_LOGD("Created enumeration field type object: addr=%p, "
1764 "int-ft-addr=%p, int-ft-size=%u",
1765 enumeration
, container_ft
,
1766 bt_field_type_integer_get_size(container_ft
));
1770 BT_PUT(enumeration
);
1773 return (void *) enumeration
;
1777 struct bt_field_type_common
*
1778 bt_field_type_common_enumeration_borrow_container_field_type(
1779 struct bt_field_type_common
*ft
)
1781 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1783 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1784 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
, "Field type");
1785 return BT_TO_COMMON(enum_ft
->container_ft
);
1788 struct bt_field_type
*bt_field_type_enumeration_borrow_container_field_type(
1789 struct bt_field_type
*ft
)
1791 return (void *) bt_field_type_common_enumeration_borrow_container_field_type(
1796 int bt_field_type_common_enumeration_signed_add_mapping(
1797 struct bt_field_type_common
*ft
, const char *string
,
1798 int64_t range_start
, int64_t range_end
)
1801 GQuark mapping_name
;
1802 struct enumeration_mapping
*mapping
;
1803 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1804 char *escaped_string
;
1807 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1813 BT_LOGW_STR("Invalid parameter: string is NULL.");
1819 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1825 if (ft
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1826 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1827 "addr=%p, ft-id=%s", ft
,
1828 bt_common_field_type_id_string(ft
->id
));
1833 if (range_end
< range_start
) {
1834 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1835 "addr=%p, range-start=%" PRId64
", range-end=%" PRId64
,
1836 ft
, range_start
, range_end
);
1841 if (strlen(string
) == 0) {
1842 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1843 "enum-ft-addr=%p, mapping-name-addr=%p", ft
,
1849 escaped_string
= g_strescape(string
, NULL
);
1850 if (!escaped_string
) {
1851 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1852 "mapping-name-addr=%p, mapping-name=\"%s\"",
1853 ft
, string
, string
);
1858 mapping
= g_new(struct enumeration_mapping
, 1);
1860 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1864 mapping_name
= g_quark_from_string(escaped_string
);
1865 *mapping
= (struct enumeration_mapping
) {
1866 .range_start
._signed
= range_start
,
1867 .range_end
._signed
= range_end
,
1868 .string
= mapping_name
,
1870 g_ptr_array_add(enum_ft
->entries
, mapping
);
1871 g_ptr_array_sort(enum_ft
->entries
,
1872 (GCompareFunc
) compare_enumeration_mappings_signed
);
1873 BT_LOGV("Added mapping to signed enumeration field type: addr=%p, "
1874 "name=\"%s\", range-start=%" PRId64
", "
1875 "range-end=%" PRId64
,
1876 ft
, string
, range_start
, range_end
);
1879 free(escaped_string
);
1885 int bt_field_type_enumeration_signed_add_mapping(
1886 struct bt_field_type
*ft
, const char *string
,
1887 int64_t range_start
, int64_t range_end
)
1889 return bt_field_type_common_enumeration_signed_add_mapping(
1890 (void *) ft
, string
, range_start
, range_end
);
1894 int bt_field_type_common_enumeration_unsigned_add_mapping(
1895 struct bt_field_type_common
*ft
, const char *string
,
1896 uint64_t range_start
, uint64_t range_end
)
1899 GQuark mapping_name
;
1900 struct enumeration_mapping
*mapping
;
1901 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1902 char *escaped_string
;
1905 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1911 BT_LOGW_STR("Invalid parameter: string is NULL.");
1917 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1923 if (ft
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1924 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1925 "addr=%p, ft-id=%s", ft
,
1926 bt_common_field_type_id_string(ft
->id
));
1931 if (range_end
< range_start
) {
1932 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1933 "addr=%p, range-start=%" PRIu64
", range-end=%" PRIu64
,
1934 ft
, range_start
, range_end
);
1939 if (strlen(string
) == 0) {
1940 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1941 "enum-ft-addr=%p, mapping-name-addr=%p", ft
,
1947 escaped_string
= g_strescape(string
, NULL
);
1948 if (!escaped_string
) {
1949 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1950 "mapping-name-addr=%p, mapping-name=\"%s\"",
1951 ft
, string
, string
);
1956 mapping
= g_new(struct enumeration_mapping
, 1);
1958 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1962 mapping_name
= g_quark_from_string(escaped_string
);
1963 *mapping
= (struct enumeration_mapping
) {
1964 .range_start
._unsigned
= range_start
,
1965 .range_end
._unsigned
= range_end
,
1966 .string
= mapping_name
,
1968 g_ptr_array_add(enum_ft
->entries
, mapping
);
1969 g_ptr_array_sort(enum_ft
->entries
,
1970 (GCompareFunc
) compare_enumeration_mappings_unsigned
);
1971 BT_LOGV("Added mapping to unsigned enumeration field type: addr=%p, "
1972 "name=\"%s\", range-start=%" PRIu64
", "
1973 "range-end=%" PRIu64
,
1974 ft
, string
, range_start
, range_end
);
1977 free(escaped_string
);
1983 int bt_field_type_enumeration_unsigned_add_mapping(
1984 struct bt_field_type
*ft
, const char *string
,
1985 uint64_t range_start
, uint64_t range_end
)
1987 return bt_field_type_common_enumeration_unsigned_add_mapping(
1988 (void *) ft
, string
, range_start
, range_end
);
1992 int64_t bt_field_type_common_enumeration_get_mapping_count(
1993 struct bt_field_type_common
*ft
)
1995 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1997 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1998 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
, "Field type");
1999 return (int64_t) enum_ft
->entries
->len
;
2002 int64_t bt_field_type_enumeration_get_mapping_count(
2003 struct bt_field_type
*ft
)
2005 return bt_field_type_common_enumeration_get_mapping_count((void *) ft
);
2008 struct bt_field_type
*bt_field_type_floating_point_create(void)
2010 struct bt_field_type_common_floating_point
*floating_point
=
2011 g_new0(struct bt_field_type_common_floating_point
, 1);
2013 BT_LOGD_STR("Creating floating point number field type object.");
2015 if (!floating_point
) {
2016 BT_LOGE_STR("Failed to allocate one floating point number field type.");
2020 bt_field_type_common_floating_point_initialize(
2021 BT_TO_COMMON(floating_point
),
2022 bt_field_type_common_floating_point_destroy
,
2023 &bt_field_type_floating_point_methods
);
2024 BT_LOGD("Created floating point number field type object: addr=%p, "
2025 "exp-size=%u, mant-size=%u", floating_point
,
2026 floating_point
->exp_dig
, floating_point
->mant_dig
);
2029 return (void *) floating_point
;
2033 int bt_field_type_common_floating_point_get_exponent_digits(
2034 struct bt_field_type_common
*ft
)
2036 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
2038 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2039 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_FLOAT
,
2041 return (int) flt_ft
->exp_dig
;
2044 int bt_field_type_floating_point_get_exponent_digits(
2045 struct bt_field_type
*ft
)
2047 return bt_field_type_common_floating_point_get_exponent_digits(
2052 int bt_field_type_common_floating_point_set_exponent_digits(
2053 struct bt_field_type_common
*ft
,
2054 unsigned int exponent_digits
)
2057 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
2060 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2066 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2072 if (ft
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
2073 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
2074 "addr=%p, ft-id=%s", ft
,
2075 bt_common_field_type_id_string(ft
->id
));
2080 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
2081 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
2083 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
2084 BT_LOGW("Invalid parameter: invalid exponent size: "
2085 "addr=%p, exp-size=%u", ft
, exponent_digits
);
2090 flt_ft
->exp_dig
= exponent_digits
;
2091 BT_LOGV("Set floating point number field type's exponent size: addr=%p, "
2092 "exp-size=%u", ft
, exponent_digits
);
2098 int bt_field_type_floating_point_set_exponent_digits(
2099 struct bt_field_type
*ft
, unsigned int exponent_digits
)
2101 return bt_field_type_common_floating_point_set_exponent_digits(
2102 (void *) ft
, exponent_digits
);
2106 int bt_field_type_common_floating_point_get_mantissa_digits(
2107 struct bt_field_type_common
*ft
)
2109 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
2111 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2112 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_FLOAT
,
2114 return (int) flt_ft
->mant_dig
;
2117 int bt_field_type_floating_point_get_mantissa_digits(
2118 struct bt_field_type
*ft
)
2120 return bt_field_type_common_floating_point_get_mantissa_digits(
2125 int bt_field_type_common_floating_point_set_mantissa_digits(
2126 struct bt_field_type_common
*ft
, unsigned int mantissa_digits
)
2129 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
2132 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2138 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2144 if (ft
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
2145 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
2146 "addr=%p, ft-id=%s", ft
,
2147 bt_common_field_type_id_string(ft
->id
));
2152 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
2153 (mantissa_digits
!= DBL_MANT_DIG
) &&
2154 (mantissa_digits
!= LDBL_MANT_DIG
)) {
2155 BT_LOGW("Invalid parameter: invalid mantissa size: "
2156 "addr=%p, mant-size=%u", ft
, mantissa_digits
);
2161 flt_ft
->mant_dig
= mantissa_digits
;
2162 BT_LOGV("Set floating point number field type's mantissa size: addr=%p, "
2163 "mant-size=%u", ft
, mantissa_digits
);
2169 int bt_field_type_floating_point_set_mantissa_digits(
2170 struct bt_field_type
*ft
, unsigned int mantissa_digits
)
2172 return bt_field_type_common_floating_point_set_mantissa_digits(
2173 (void *) ft
, mantissa_digits
);
2176 struct bt_field_type
*bt_field_type_structure_create(void)
2178 struct bt_field_type_common_structure
*structure
=
2179 g_new0(struct bt_field_type_common_structure
, 1);
2181 BT_LOGD_STR("Creating structure field type object.");
2184 BT_LOGE_STR("Failed to allocate one structure field type.");
2188 bt_field_type_common_structure_initialize(BT_TO_COMMON(structure
),
2189 bt_field_type_common_structure_destroy_recursive
,
2190 &bt_field_type_structure_methods
);
2191 BT_LOGD("Created structure field type object: addr=%p",
2199 return (void *) structure
;
2203 int bt_field_type_common_structure_replace_field(
2204 struct bt_field_type_common
*ft
,
2205 const char *field_name
,
2206 struct bt_field_type_common
*field_type
)
2209 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2214 BT_ASSERT(field_name
);
2215 BT_ASSERT(field_type
);
2216 BT_ASSERT(ft
->id
== BT_FIELD_TYPE_ID_STRUCT
);
2217 name_quark
= g_quark_from_string(field_name
);
2219 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
2220 struct bt_field_type_common_structure_field
*field
=
2221 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft
, i
);
2223 if (field
->name
== name_quark
) {
2224 bt_put(field
->type
);
2225 field
->type
= bt_get(field_type
);
2233 int bt_field_type_common_structure_add_field(struct bt_field_type_common
*ft
,
2234 struct bt_field_type_common
*field_type
,
2235 const char *field_name
)
2238 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2241 * TODO: check that `field_type` does not contain `type`,
2245 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2251 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2257 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2263 if (ft
->id
!= BT_FIELD_TYPE_ID_STRUCT
) {
2264 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2265 "addr=%p, ft-id=%s", ft
,
2266 bt_common_field_type_id_string(ft
->id
));
2271 if (ft
== field_type
) {
2272 BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
2278 if (add_structure_variant_member(struct_ft
->fields
,
2279 struct_ft
->field_name_to_index
, field_type
, field_name
,
2281 BT_LOGW("Cannot add field to structure field type: "
2282 "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2283 ft
, field_type
, field_name
);
2288 BT_LOGV("Added structure field type field: struct-ft-addr=%p, "
2289 "field-ft-addr=%p, field-name=\"%s\"", ft
,
2290 field_type
, field_name
);
2296 int bt_field_type_structure_add_field(struct bt_field_type
*ft
,
2297 struct bt_field_type
*field_type
,
2298 const char *field_name
)
2300 return bt_field_type_common_structure_add_field((void *) ft
,
2301 (void *) field_type
, field_name
);
2305 int64_t bt_field_type_common_structure_get_field_count(
2306 struct bt_field_type_common
*ft
)
2308 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2310 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2311 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
2313 return (int64_t) struct_ft
->fields
->len
;
2316 int64_t bt_field_type_structure_get_field_count(struct bt_field_type
*ft
)
2318 return bt_field_type_common_structure_get_field_count((void *) ft
);
2322 int bt_field_type_common_structure_borrow_field_by_index(
2323 struct bt_field_type_common
*ft
,
2324 const char **field_name
,
2325 struct bt_field_type_common
**field_type
, uint64_t index
)
2327 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2328 struct bt_field_type_common_structure_field
*field
;
2330 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2331 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
2333 BT_ASSERT_PRE(index
< struct_ft
->fields
->len
,
2334 "Index is out of bounds: index=%" PRIu64
", "
2335 "count=%u, %![ft-]+_F",
2336 index
, struct_ft
->fields
->len
, ft
);
2337 field
= BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(struct_ft
, index
);
2340 *field_type
= field
->type
;
2344 *field_name
= g_quark_to_string(field
->name
);
2345 BT_ASSERT(*field_name
);
2351 int bt_field_type_structure_borrow_field_by_index(
2352 struct bt_field_type
*ft
,
2353 const char **field_name
,
2354 struct bt_field_type
**field_type
, uint64_t index
)
2356 return bt_field_type_common_structure_borrow_field_by_index(
2357 (void *) ft
, field_name
, (void *) field_type
, index
);
2361 struct bt_field_type_common
*
2362 bt_field_type_common_structure_borrow_field_type_by_name(
2363 struct bt_field_type_common
*ft
, const char *name
)
2367 struct bt_field_type_common_structure_field
*field
;
2368 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2369 struct bt_field_type_common
*field_type
= NULL
;
2371 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2372 BT_ASSERT_PRE_NON_NULL(name
, "Name");
2373 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
2375 name_quark
= g_quark_try_string(name
);
2377 BT_LOGV("No such structure field type field name: "
2378 "ft-addr=%p, field-name=\"%s\"",
2383 if (!g_hash_table_lookup_extended(struct_ft
->field_name_to_index
,
2384 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*) &index
)) {
2385 BT_LOGV("No such structure field type field name: "
2386 "ft-addr=%p, field-name=\"%s\"",
2391 field
= BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft
, index
);
2392 field_type
= field
->type
;
2398 struct bt_field_type
*bt_field_type_structure_borrow_field_type_by_name(
2399 struct bt_field_type
*ft
, const char *name
)
2401 return (void *) bt_field_type_common_structure_borrow_field_type_by_name(
2405 struct bt_field_type
*bt_field_type_variant_create(
2406 struct bt_field_type
*tag_ft
, const char *tag_name
)
2408 struct bt_field_type_common_variant
*var_ft
= NULL
;
2410 BT_LOGD("Creating variant field type object: "
2411 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2414 if (tag_name
&& !bt_identifier_is_valid(tag_name
)) {
2415 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2416 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2421 var_ft
= g_new0(struct bt_field_type_common_variant
, 1);
2423 BT_LOGE_STR("Failed to allocate one variant field type.");
2427 bt_field_type_common_variant_initialize(BT_TO_COMMON(var_ft
),
2428 (void *) tag_ft
, tag_name
,
2429 bt_field_type_common_variant_destroy_recursive
,
2430 &bt_field_type_variant_methods
);
2431 BT_LOGD("Created variant field type object: addr=%p, "
2432 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2433 var_ft
, tag_ft
, tag_name
);
2440 return (void *) var_ft
;
2444 struct bt_field_type_common
*
2445 bt_field_type_common_variant_borrow_tag_field_type(
2446 struct bt_field_type_common
*ft
)
2448 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2449 struct bt_field_type_common
*tag_ft
= NULL
;
2451 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2452 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2455 if (!var_ft
->tag_ft
) {
2456 BT_LOGV("Variant field type has no tag field type: "
2461 tag_ft
= BT_TO_COMMON(var_ft
->tag_ft
);
2467 struct bt_field_type
*bt_field_type_variant_borrow_tag_field_type(
2468 struct bt_field_type
*ft
)
2470 return (void *) bt_field_type_common_variant_borrow_tag_field_type(
2475 const char *bt_field_type_common_variant_get_tag_name(
2476 struct bt_field_type_common
*ft
)
2478 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2479 const char *tag_name
= NULL
;
2481 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2482 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2485 if (var_ft
->tag_name
->len
== 0) {
2486 BT_LOGV("Variant field type has no tag field name: "
2491 tag_name
= var_ft
->tag_name
->str
;
2497 const char *bt_field_type_variant_get_tag_name(struct bt_field_type
*ft
)
2499 return bt_field_type_common_variant_get_tag_name((void *) ft
);
2503 int bt_field_type_common_variant_set_tag_name(
2504 struct bt_field_type_common
*ft
, const char *name
)
2507 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2510 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2516 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2522 if (ft
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2523 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2524 "addr=%p, ft-id=%s", ft
, bt_common_field_type_id_string(ft
->id
));
2529 if (!bt_identifier_is_valid(name
)) {
2530 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2531 "variant-ft-addr=%p, tag-field-name=\"%s\"",
2537 g_string_assign(var_ft
->tag_name
, name
);
2538 BT_LOGV("Set variant field type's tag field name: addr=%p, "
2539 "tag-field-name=\"%s\"", ft
, name
);
2545 int bt_field_type_variant_set_tag_name(
2546 struct bt_field_type
*ft
, const char *name
)
2548 return bt_field_type_common_variant_set_tag_name((void *) ft
, name
);
2552 int bt_field_type_common_variant_add_field(struct bt_field_type_common
*ft
,
2553 struct bt_field_type_common
*field_type
,
2554 const char *field_name
)
2558 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2559 GQuark field_name_quark
= g_quark_from_string(field_name
);
2562 * TODO: check that `field_type` does not contain `type`,
2566 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2572 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2578 if (ft
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2579 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2580 "addr=%p, ft-id=%s", ft
,
2581 bt_common_field_type_id_string(ft
->id
));
2586 if (ft
== field_type
) {
2587 BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
2593 /* The user has explicitly provided a tag; validate against it. */
2594 if (var_ft
->tag_ft
) {
2597 /* Make sure this name is present in the enum tag */
2598 for (i
= 0; i
< var_ft
->tag_ft
->entries
->len
; i
++) {
2599 struct enumeration_mapping
*mapping
=
2600 g_ptr_array_index(var_ft
->tag_ft
->entries
, i
);
2602 if (mapping
->string
== field_name_quark
) {
2609 /* Validation failed */
2610 BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
2611 "variant-ft-addr=%p, tag-ft-addr=%p, "
2612 "tag-field-name=\"%s\""
2613 "field-ft-addr=%p, field-name=\"%s\"",
2614 ft
, var_ft
->tag_ft
, var_ft
->tag_name
->str
,
2615 field_type
, field_name
);
2621 if (add_structure_variant_member(var_ft
->choices
,
2622 var_ft
->choice_name_to_index
, field_type
,
2623 field_name
, true)) {
2624 BT_LOGW("Cannot add field to variant field type: "
2625 "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2626 ft
, field_type
, field_name
);
2631 BT_LOGV("Added variant field type field: variant-ft-addr=%p, "
2632 "field-ft-addr=%p, field-name=\"%s\"", ft
,
2633 field_type
, field_name
);
2639 int bt_field_type_variant_add_field(struct bt_field_type
*ft
,
2640 struct bt_field_type
*field_type
,
2641 const char *field_name
)
2643 return bt_field_type_common_variant_add_field((void *) ft
,
2644 (void *) field_type
, field_name
);
2648 struct bt_field_type_common
*
2649 bt_field_type_common_variant_borrow_field_type_by_name(
2650 struct bt_field_type_common
*ft
,
2651 const char *field_name
)
2655 struct bt_field_type_common_variant_choice
*choice
;
2656 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2657 struct bt_field_type_common
*field_type
= NULL
;
2659 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2660 BT_ASSERT_PRE_NON_NULL(field_name
, "Name");
2661 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2663 name_quark
= g_quark_try_string(field_name
);
2665 BT_LOGV("No such variant field type field name: "
2666 "ft-addr=%p, field-name=\"%s\"",
2671 if (!g_hash_table_lookup_extended(var_ft
->choice_name_to_index
,
2672 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*) &index
)) {
2673 BT_LOGV("No such variant field type field name: "
2674 "ft-addr=%p, field-name=\"%s\"",
2679 choice
= BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft
, index
);
2680 field_type
= choice
->type
;
2686 struct bt_field_type
*bt_field_type_variant_borrow_field_type_by_name(
2687 struct bt_field_type
*ft
,
2688 const char *field_name
)
2690 return (void *) bt_field_type_common_variant_borrow_field_type_by_name(
2691 (void *) ft
, field_name
);
2695 int64_t bt_field_type_common_variant_get_field_count(
2696 struct bt_field_type_common
*ft
)
2698 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2700 BT_ASSERT_PRE_NON_NULL(ft
, "Variant field type");
2701 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2703 return (int64_t) var_ft
->choices
->len
;
2706 int64_t bt_field_type_variant_get_field_count(struct bt_field_type
*ft
)
2708 return bt_field_type_common_variant_get_field_count((void *) ft
);
2712 int bt_field_type_common_variant_borrow_field_by_index(
2713 struct bt_field_type_common
*ft
,
2714 const char **field_name
,
2715 struct bt_field_type_common
**field_type
, uint64_t index
)
2717 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2718 struct bt_field_type_common_variant_choice
*choice
;
2720 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2721 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2723 BT_ASSERT_PRE(index
< var_ft
->choices
->len
,
2724 "Index is out of bounds: index=%" PRIu64
", "
2725 "count=%u, %![ft-]+_F",
2726 index
, var_ft
->choices
->len
, ft
);
2727 choice
= BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft
, index
);
2730 *field_type
= choice
->type
;
2734 *field_name
= g_quark_to_string(choice
->name
);
2735 BT_ASSERT(*field_name
);
2741 int bt_field_type_variant_borrow_field_by_index(struct bt_field_type
*ft
,
2742 const char **field_name
, struct bt_field_type
**field_type
,
2745 return bt_field_type_common_variant_borrow_field_by_index((void *) ft
,
2746 field_name
, (void *) field_type
, index
);
2750 int64_t bt_field_type_common_variant_find_choice_index(
2751 struct bt_field_type_common
*ft
, uint64_t uval
,
2756 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2759 BT_ASSERT(ft
->id
== BT_FIELD_TYPE_ID_VARIANT
);
2761 if (bt_field_type_common_variant_update_choices(ft
)) {
2766 for (i
= 0; i
< var_ft
->choices
->len
; i
++) {
2768 struct bt_field_type_common_variant_choice
*choice
=
2769 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
2772 for (range_i
= 0; range_i
< choice
->ranges
->len
; range_i
++) {
2773 struct bt_field_type_common_variant_choice_range
*range
=
2776 struct bt_field_type_common_variant_choice_range
,
2780 int64_t tag_ival
= (int64_t) uval
;
2782 if (tag_ival
>= range
->lower
.i
&&
2783 tag_ival
<= range
->upper
.i
) {
2787 if (uval
>= range
->lower
.u
&&
2788 uval
<= range
->upper
.u
) {
2795 /* Range not found */
2806 struct bt_field_type
*bt_field_type_array_create(
2807 struct bt_field_type
*element_ft
, unsigned int length
)
2809 struct bt_field_type_common_array
*array
= NULL
;
2811 BT_LOGD("Creating array field type object: element-ft-addr=%p, "
2812 "length=%u", element_ft
, length
);
2815 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2820 BT_LOGW_STR("Invalid parameter: length is zero.");
2824 array
= g_new0(struct bt_field_type_common_array
, 1);
2826 BT_LOGE_STR("Failed to allocate one array field type.");
2830 bt_field_type_common_array_initialize(BT_TO_COMMON(array
),
2831 (void *) element_ft
, length
,
2832 bt_field_type_common_array_destroy_recursive
,
2833 &bt_field_type_array_methods
);
2834 BT_LOGD("Created array field type object: addr=%p, "
2835 "element-ft-addr=%p, length=%u",
2836 array
, element_ft
, length
);
2843 return (void *) array
;
2847 struct bt_field_type_common
*
2848 bt_field_type_common_array_borrow_element_field_type(
2849 struct bt_field_type_common
*ft
)
2851 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
2853 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2854 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ARRAY
,
2856 BT_ASSERT(array_ft
&& array_ft
->element_ft
);
2857 return array_ft
->element_ft
;
2860 struct bt_field_type
*bt_field_type_array_borrow_element_field_type(
2861 struct bt_field_type
*ft
)
2863 return (void *) bt_field_type_common_array_borrow_element_field_type(
2868 int bt_field_type_common_array_set_element_field_type(
2869 struct bt_field_type_common
*ft
,
2870 struct bt_field_type_common
*element_ft
)
2873 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
2876 BT_LOGW_STR("Invalid parameter: array field type is NULL.");
2882 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2887 if (ft
->id
!= BT_FIELD_TYPE_ID_ARRAY
) {
2888 BT_LOGW("Invalid parameter: field type is not an array field type: "
2889 "addr=%p, ft-id=%s", ft
,
2890 bt_common_field_type_id_string(ft
->id
));
2895 if (array_ft
->element_ft
) {
2896 BT_PUT(array_ft
->element_ft
);
2899 array_ft
->element_ft
= bt_get(element_ft
);
2900 BT_LOGV("Set array field type's element field type: array-ft-addr=%p, "
2901 "element-ft-addr=%p", ft
, element_ft
);
2908 int64_t bt_field_type_common_array_get_length(struct bt_field_type_common
*ft
)
2910 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
2912 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2913 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ARRAY
,
2915 return (int64_t) array_ft
->length
;
2918 int64_t bt_field_type_array_get_length(struct bt_field_type
*ft
)
2920 return bt_field_type_common_array_get_length((void *) ft
);
2923 struct bt_field_type
*bt_field_type_sequence_create(
2924 struct bt_field_type
*element_ft
,
2925 const char *length_field_name
)
2927 struct bt_field_type_common_sequence
*sequence
= NULL
;
2929 BT_LOGD("Creating sequence field type object: element-ft-addr=%p, "
2930 "length-field-name=\"%s\"", element_ft
, length_field_name
);
2933 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2937 if (!bt_identifier_is_valid(length_field_name
)) {
2938 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
2939 "length-field-name=\"%s\"", length_field_name
);
2943 sequence
= g_new0(struct bt_field_type_common_sequence
, 1);
2945 BT_LOGE_STR("Failed to allocate one sequence field type.");
2949 bt_field_type_common_sequence_initialize(BT_TO_COMMON(sequence
),
2950 (void *) element_ft
, length_field_name
,
2951 bt_field_type_common_sequence_destroy_recursive
,
2952 &bt_field_type_sequence_methods
);
2953 BT_LOGD("Created sequence field type object: addr=%p, "
2954 "element-ft-addr=%p, length-field-name=\"%s\"",
2955 sequence
, element_ft
, length_field_name
);
2962 return (void *) sequence
;
2966 struct bt_field_type_common
*bt_field_type_common_sequence_borrow_element_field_type(
2967 struct bt_field_type_common
*ft
)
2969 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
2971 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2972 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_SEQUENCE
,
2974 return seq_ft
->element_ft
;
2977 struct bt_field_type
*bt_field_type_sequence_borrow_element_field_type(
2978 struct bt_field_type
*ft
)
2980 return (void *) bt_field_type_common_sequence_borrow_element_field_type(
2985 int bt_field_type_common_sequence_set_element_field_type(
2986 struct bt_field_type_common
*ft
,
2987 struct bt_field_type_common
*element_ft
)
2990 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
2993 BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
2999 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
3004 if (ft
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
3005 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
3006 "addr=%p, ft-id=%s", ft
,
3007 bt_common_field_type_id_string(ft
->id
));
3012 if (seq_ft
->element_ft
) {
3013 BT_PUT(seq_ft
->element_ft
);
3016 seq_ft
->element_ft
= element_ft
;
3017 bt_get(seq_ft
->element_ft
);
3018 BT_LOGV("Set sequence field type's element field type: sequence-ft-addr=%p, "
3019 "element-ft-addr=%p", ft
, element_ft
);
3026 const char *bt_field_type_common_sequence_get_length_field_name(
3027 struct bt_field_type_common
*ft
)
3029 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3031 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3032 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_SEQUENCE
,
3034 return seq_ft
->length_field_name
?
3035 seq_ft
->length_field_name
->str
: NULL
;
3038 const char *bt_field_type_sequence_get_length_field_name(
3039 struct bt_field_type
*ft
)
3041 return bt_field_type_common_sequence_get_length_field_name((void *) ft
);
3044 struct bt_field_type
*bt_field_type_string_create(void)
3046 struct bt_field_type_common_string
*string
=
3047 g_new0(struct bt_field_type_common_string
, 1);
3049 BT_LOGD_STR("Creating string field type object.");
3052 BT_LOGE_STR("Failed to allocate one string field type.");
3056 bt_field_type_common_string_initialize(BT_TO_COMMON(string
),
3057 bt_field_type_common_string_destroy
,
3058 &bt_field_type_string_methods
);
3059 BT_LOGD("Created string field type object: addr=%p", string
);
3060 return (void *) string
;
3064 enum bt_string_encoding
bt_field_type_common_string_get_encoding(
3065 struct bt_field_type_common
*ft
)
3067 struct bt_field_type_common_string
*string_ft
= BT_FROM_COMMON(ft
);
3069 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3070 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRING
,
3072 return string_ft
->encoding
;
3075 enum bt_string_encoding
bt_field_type_string_get_encoding(
3076 struct bt_field_type
*ft
)
3078 return bt_field_type_common_string_get_encoding((void *) ft
);
3082 int bt_field_type_common_string_set_encoding(struct bt_field_type_common
*ft
,
3083 enum bt_string_encoding encoding
)
3086 struct bt_field_type_common_string
*string_ft
= BT_FROM_COMMON(ft
);
3089 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3094 if (ft
->id
!= BT_FIELD_TYPE_ID_STRING
) {
3095 BT_LOGW("Invalid parameter: field type is not a string field type: "
3096 "addr=%p, ft-id=%s", ft
,
3097 bt_common_field_type_id_string(ft
->id
));
3102 if (encoding
!= BT_STRING_ENCODING_UTF8
&&
3103 encoding
!= BT_STRING_ENCODING_ASCII
) {
3104 BT_LOGW("Invalid parameter: unknown string encoding: "
3105 "addr=%p, encoding=%d", ft
, encoding
);
3110 string_ft
->encoding
= encoding
;
3111 BT_LOGV("Set string field type's encoding: addr=%p, encoding=%s",
3112 ft
, bt_common_string_encoding_string(encoding
));
3118 int bt_field_type_string_set_encoding(struct bt_field_type
*ft
,
3119 enum bt_string_encoding encoding
)
3121 return bt_field_type_common_string_set_encoding((void *) ft
, encoding
);
3125 int bt_field_type_common_get_alignment(struct bt_field_type_common
*ft
)
3128 enum bt_field_type_id type_id
;
3130 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3133 ret
= (int) ft
->alignment
;
3137 type_id
= bt_field_type_common_get_type_id(ft
);
3139 case BT_FIELD_TYPE_ID_SEQUENCE
:
3141 struct bt_field_type_common
*element_ft
=
3142 bt_field_type_common_sequence_borrow_element_field_type(ft
);
3144 BT_ASSERT(element_ft
);
3145 ret
= bt_field_type_common_get_alignment(element_ft
);
3148 case BT_FIELD_TYPE_ID_ARRAY
:
3150 struct bt_field_type_common
*element_ft
=
3151 bt_field_type_common_array_borrow_element_field_type(ft
);
3153 BT_ASSERT(element_ft
);
3154 ret
= bt_field_type_common_get_alignment(element_ft
);
3157 case BT_FIELD_TYPE_ID_STRUCT
:
3159 int64_t i
, element_count
;
3161 element_count
= bt_field_type_common_structure_get_field_count(
3163 BT_ASSERT(element_count
>= 0);
3165 for (i
= 0; i
< element_count
; i
++) {
3166 struct bt_field_type_common
*field
= NULL
;
3167 int field_alignment
;
3169 ret
= bt_field_type_common_structure_borrow_field_by_index(
3170 ft
, NULL
, &field
, i
);
3171 BT_ASSERT(ret
== 0);
3173 field_alignment
= bt_field_type_common_get_alignment(
3175 if (field_alignment
< 0) {
3176 ret
= field_alignment
;
3180 ft
->alignment
= MAX(field_alignment
, ft
->alignment
);
3182 ret
= (int) ft
->alignment
;
3185 case BT_FIELD_TYPE_ID_UNKNOWN
:
3186 BT_LOGW("Invalid parameter: unknown field type ID: "
3187 "addr=%p, ft-id=%d", ft
, type_id
);
3191 ret
= (int) ft
->alignment
;
3199 int bt_field_type_get_alignment(struct bt_field_type
*ft
)
3201 return bt_field_type_common_get_alignment((void *) ft
);
3205 int is_power_of_two(unsigned int value
)
3207 return ((value
& (value
- 1)) == 0) && value
> 0;
3211 int bt_field_type_common_set_alignment(struct bt_field_type_common
*ft
,
3212 unsigned int alignment
)
3215 enum bt_field_type_id type_id
;
3217 /* Alignment must be a power of two */
3219 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3225 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3231 if (!is_power_of_two(alignment
)) {
3232 BT_LOGW("Invalid parameter: alignment is not a power of two: "
3233 "addr=%p, align=%u", ft
, alignment
);
3238 type_id
= bt_field_type_common_get_type_id(ft
);
3239 if (type_id
== BT_FIELD_TYPE_ID_UNKNOWN
) {
3240 BT_LOGW("Invalid parameter: unknown field type ID: "
3241 "addr=%p, ft-id=%d", ft
, type_id
);
3246 if (ft
->id
== BT_FIELD_TYPE_ID_STRING
&& alignment
!= CHAR_BIT
) {
3247 BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
3248 "addr=%p, align=%u", CHAR_BIT
, ft
, alignment
);
3253 if (type_id
== BT_FIELD_TYPE_ID_VARIANT
||
3254 type_id
== BT_FIELD_TYPE_ID_SEQUENCE
||
3255 type_id
== BT_FIELD_TYPE_ID_ARRAY
) {
3256 /* Setting an alignment on these types makes no sense */
3257 BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
3258 "addr=%p, ft-id=%s", ft
,
3259 bt_common_field_type_id_string(ft
->id
));
3264 ft
->alignment
= alignment
;
3266 BT_LOGV("Set field type's alignment: addr=%p, align=%u",
3273 int bt_field_type_set_alignment(struct bt_field_type
*ft
,
3274 unsigned int alignment
)
3276 return bt_field_type_common_set_alignment((void *) ft
, alignment
);
3280 enum bt_byte_order
bt_field_type_common_get_byte_order(
3281 struct bt_field_type_common
*ft
)
3283 enum bt_byte_order ret
= BT_BYTE_ORDER_UNKNOWN
;
3285 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3288 case BT_FIELD_TYPE_ID_INTEGER
:
3290 struct bt_field_type_common_integer
*integer
=
3293 ret
= integer
->user_byte_order
;
3296 case BT_FIELD_TYPE_ID_ENUM
:
3298 struct bt_field_type_common_enumeration
*enum_ft
=
3301 ret
= bt_field_type_common_get_byte_order(
3302 BT_TO_COMMON(enum_ft
->container_ft
));
3305 case BT_FIELD_TYPE_ID_FLOAT
:
3307 struct bt_field_type_common_floating_point
*floating_point
=
3309 ret
= floating_point
->user_byte_order
;
3313 BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
3314 "addr=%p, ft-id=%s", ft
,
3315 bt_common_field_type_id_string(ft
->id
));
3319 BT_ASSERT(ret
== BT_BYTE_ORDER_NATIVE
||
3320 ret
== BT_BYTE_ORDER_LITTLE_ENDIAN
||
3321 ret
== BT_BYTE_ORDER_BIG_ENDIAN
||
3322 ret
== BT_BYTE_ORDER_NETWORK
);
3328 enum bt_byte_order
bt_field_type_get_byte_order(struct bt_field_type
*ft
)
3330 return bt_field_type_common_get_byte_order((void *) ft
);
3334 int bt_field_type_common_set_byte_order(struct bt_field_type_common
*ft
,
3335 enum bt_byte_order byte_order
)
3340 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3346 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3352 if (byte_order
!= BT_BYTE_ORDER_NATIVE
&&
3353 byte_order
!= BT_BYTE_ORDER_LITTLE_ENDIAN
&&
3354 byte_order
!= BT_BYTE_ORDER_BIG_ENDIAN
&&
3355 byte_order
!= BT_BYTE_ORDER_NETWORK
) {
3356 BT_LOGW("Invalid parameter: invalid byte order: "
3357 "addr=%p, bo=%s", ft
,
3358 bt_common_byte_order_string(byte_order
));
3363 if (ft
->methods
->set_byte_order
) {
3364 ft
->methods
->set_byte_order(ft
, byte_order
);
3367 BT_LOGV("Set field type's byte order: addr=%p, bo=%s",
3368 ft
, bt_common_byte_order_string(byte_order
));
3374 int bt_field_type_set_byte_order(struct bt_field_type
*ft
,
3375 enum bt_byte_order byte_order
)
3377 return bt_field_type_common_set_byte_order((void *) ft
, byte_order
);
3381 enum bt_field_type_id
bt_field_type_common_get_type_id(
3382 struct bt_field_type_common
*ft
)
3384 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3388 enum bt_field_type_id
bt_field_type_get_type_id(struct bt_field_type
*ft
)
3390 return bt_field_type_common_get_type_id((void *) ft
);
3394 void bt_field_type_common_freeze(struct bt_field_type_common
*ft
)
3396 if (!ft
|| ft
->frozen
) {
3400 BT_ASSERT(ft
->methods
->freeze
);
3401 ft
->methods
->freeze(ft
);
3405 void bt_field_type_freeze(struct bt_field_type
*ft
)
3407 bt_field_type_common_freeze((void *) ft
);
3411 struct bt_field_type_common
*
3412 bt_field_type_common_variant_borrow_field_type_signed(
3413 struct bt_field_type_common_variant
*var_ft
,
3416 struct bt_field_type_common
*field_type
= NULL
;
3417 GQuark field_name_quark
;
3419 struct bt_field_type_common_variant_choice
*choice
;
3420 struct range_overlap_query query
= {
3421 .range_start
._signed
= tag_value
,
3422 .range_end
._signed
= tag_value
,
3427 g_ptr_array_foreach(var_ft
->tag_ft
->entries
, check_ranges_overlap
,
3429 if (!query
.overlaps
) {
3433 field_name_quark
= query
.mapping_name
;
3434 if (!g_hash_table_lookup_extended(var_ft
->choice_name_to_index
,
3435 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3439 choice
= BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft
,
3441 field_type
= choice
->type
;
3448 struct bt_field_type_common
*
3449 bt_field_type_common_variant_borrow_field_type_unsigned(
3450 struct bt_field_type_common_variant
*var_ft
,
3453 struct bt_field_type_common
*field_type
= NULL
;
3454 GQuark field_name_quark
;
3456 struct bt_field_type_common_variant_choice
*choice
;
3457 struct range_overlap_query query
= {
3458 .range_start
._unsigned
= tag_value
,
3459 .range_end
._unsigned
= tag_value
,
3464 g_ptr_array_foreach(var_ft
->tag_ft
->entries
,
3465 check_ranges_overlap_unsigned
, &query
);
3466 if (!query
.overlaps
) {
3470 field_name_quark
= query
.mapping_name
;
3471 if (!g_hash_table_lookup_extended(var_ft
->choice_name_to_index
,
3472 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3476 choice
= BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft
,
3478 field_type
= choice
->type
;
3485 struct bt_field_type_common
*bt_field_type_common_copy(
3486 struct bt_field_type_common
*ft
)
3488 struct bt_field_type_common
*ft_copy
= NULL
;
3490 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3491 BT_ASSERT(ft
->methods
->copy
);
3492 ft_copy
= ft
->methods
->copy(ft
);
3494 BT_LOGE_STR("Cannot copy field type.");
3498 ft_copy
->alignment
= ft
->alignment
;
3504 struct bt_field_type
*bt_field_type_copy(struct bt_field_type
*ft
)
3506 return (void *) bt_field_type_common_copy((void *) ft
);
3510 int bt_field_type_common_structure_get_field_name_index(
3511 struct bt_field_type_common
*ft
, const char *name
)
3516 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
3518 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3519 BT_ASSERT_PRE_NON_NULL(name
, "Name");
3520 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
3523 name_quark
= g_quark_try_string(name
);
3525 BT_LOGV("No such structure field type field name: "
3526 "ft-addr=%p, field-name=\"%s\"",
3532 if (!g_hash_table_lookup_extended(struct_ft
->field_name_to_index
,
3533 GUINT_TO_POINTER(name_quark
),
3534 NULL
, (gpointer
*) &index
)) {
3535 BT_LOGV("No such structure field type field name: "
3536 "ft-addr=%p, field-name=\"%s\"",
3549 int bt_field_type_common_variant_get_field_name_index(
3550 struct bt_field_type_common
*ft
, const char *name
)
3555 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3557 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3558 BT_ASSERT_PRE_NON_NULL(name
, "Name");
3559 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
3561 name_quark
= g_quark_try_string(name
);
3563 BT_LOGV("No such variant field type field name: "
3564 "ft-addr=%p, field-name=\"%s\"",
3570 if (!g_hash_table_lookup_extended(var_ft
->choice_name_to_index
,
3571 GUINT_TO_POINTER(name_quark
),
3572 NULL
, (gpointer
*) &index
)) {
3573 BT_LOGV("No such variant field type field name: "
3574 "ft-addr=%p, field-name=\"%s\"",
3587 int bt_field_type_common_sequence_set_length_field_path(
3588 struct bt_field_type_common
*ft
, struct bt_field_path
*path
)
3591 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3594 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3599 if (ft
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
3600 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
3601 "addr=%p, ft-id=%s", ft
,
3602 bt_common_field_type_id_string(ft
->id
));
3608 BT_MOVE(seq_ft
->length_field_path
, path
);
3609 BT_LOGV("Set sequence field type's length field path: ft-addr=%p, "
3610 "field-path-addr=%p", ft
, path
);
3617 int bt_field_type_common_variant_set_tag_field_path(
3618 struct bt_field_type_common
*ft
,
3619 struct bt_field_path
*path
)
3622 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3625 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3630 if (ft
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
3631 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3632 "addr=%p, ft-id=%s", ft
,
3633 bt_common_field_type_id_string(ft
->id
));
3639 BT_MOVE(var_ft
->tag_field_path
, path
);
3640 BT_LOGV("Set variant field type's tag field path: ft-addr=%p, "
3641 "field-path-addr=%p", ft
, path
);
3648 int bt_field_type_common_variant_set_tag_field_type(
3649 struct bt_field_type_common
*ft
,
3650 struct bt_field_type_common
*tag_ft
)
3653 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3656 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3662 BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
3667 if (tag_ft
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
3668 BT_LOGW("Invalid parameter: tag field type is not an enumeration field type: "
3669 "addr=%p, ft-id=%s", tag_ft
,
3670 bt_common_field_type_id_string(tag_ft
->id
));
3675 bt_put(var_ft
->tag_ft
);
3676 var_ft
->tag_ft
= bt_get(tag_ft
);
3677 BT_LOGV("Set variant field type's tag field type: variant-ft-addr=%p, "
3678 "tag-ft-addr=%p", ft
, tag_ft
);
3685 void bt_field_type_common_generic_freeze(struct bt_field_type_common
*ft
)
3691 void bt_field_type_common_enumeration_freeze_recursive(
3692 struct bt_field_type_common
*ft
)
3694 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
3696 BT_LOGD("Freezing enumeration field type object: addr=%p", ft
);
3697 bt_field_type_common_enumeration_set_range_overlap(enum_ft
);
3698 bt_field_type_common_generic_freeze(ft
);
3699 BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
3700 enum_ft
->container_ft
);
3701 bt_field_type_common_freeze(BT_TO_COMMON(enum_ft
->container_ft
));
3705 void bt_field_type_common_structure_freeze_recursive(
3706 struct bt_field_type_common
*ft
)
3708 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
3711 /* Cache the alignment */
3712 BT_LOGD("Freezing structure field type object: addr=%p", ft
);
3713 ft
->alignment
= bt_field_type_common_get_alignment(ft
);
3714 bt_field_type_common_generic_freeze(ft
);
3716 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
3717 struct bt_field_type_common_structure_field
*field
=
3718 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft
, i
);
3720 BT_LOGD("Freezing structure field type field: "
3721 "ft-addr=%p, name=\"%s\"",
3722 field
->type
, g_quark_to_string(field
->name
));
3723 bt_field_type_common_freeze(field
->type
);
3728 int bt_field_type_common_variant_update_choices(struct bt_field_type_common
*ft
)
3730 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3735 if (ft
->frozen
&& var_ft
->choices_up_to_date
) {
3739 BT_ASSERT(var_ft
->tag_ft
);
3740 is_signed
= !!var_ft
->tag_ft
->container_ft
->is_signed
;
3742 for (i
= 0; i
< var_ft
->choices
->len
; i
++) {
3743 struct bt_field_type_common_variant_choice
*choice
=
3744 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft
, i
);
3745 const char *choice_name
= g_quark_to_string(choice
->name
);
3746 struct bt_field_type_enumeration_mapping_iterator
*iter
=
3747 bt_field_type_common_enumeration_find_mappings_by_name(
3748 BT_TO_COMMON(var_ft
->tag_ft
), choice_name
);
3755 BT_ASSERT(choice
->ranges
);
3756 g_array_set_size(choice
->ranges
, 0);
3758 while (bt_field_type_enumeration_mapping_iterator_next(iter
) == 0) {
3759 struct bt_field_type_common_variant_choice_range range
;
3762 ret
= bt_field_type_enumeration_mapping_iterator_signed_get(
3764 &range
.lower
.i
, &range
.upper
.i
);
3766 ret
= bt_field_type_enumeration_mapping_iterator_unsigned_get(
3768 &range
.lower
.u
, &range
.upper
.u
);
3771 BT_ASSERT(ret
== 0);
3772 g_array_append_val(choice
->ranges
, range
);
3778 var_ft
->choices_up_to_date
= true;
3785 void bt_field_type_common_variant_freeze_recursive(
3786 struct bt_field_type_common
*ft
)
3788 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3791 BT_LOGD("Freezing variant field type object: addr=%p", ft
);
3792 bt_field_type_common_generic_freeze(ft
);
3794 for (i
= 0; i
< var_ft
->choices
->len
; i
++) {
3795 struct bt_field_type_common_variant_choice
*choice
=
3796 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft
, i
);
3798 BT_LOGD("Freezing variant field type member: "
3799 "ft-addr=%p, name=\"%s\"",
3800 choice
->type
, g_quark_to_string(choice
->name
));
3801 bt_field_type_common_freeze(choice
->type
);
3806 void bt_field_type_common_array_freeze_recursive(
3807 struct bt_field_type_common
*ft
)
3809 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
3811 /* Cache the alignment */
3812 BT_LOGD("Freezing array field type object: addr=%p", ft
);
3813 ft
->alignment
= bt_field_type_common_get_alignment(ft
);
3814 bt_field_type_common_generic_freeze(ft
);
3815 BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
3816 array_ft
->element_ft
);
3817 bt_field_type_common_freeze(array_ft
->element_ft
);
3821 void bt_field_type_common_sequence_freeze_recursive(
3822 struct bt_field_type_common
*ft
)
3824 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3826 /* Cache the alignment */
3827 BT_LOGD("Freezing sequence field type object: addr=%p", ft
);
3828 ft
->alignment
= bt_field_type_common_get_alignment(ft
);
3829 bt_field_type_common_generic_freeze(ft
);
3830 BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
3831 seq_ft
->element_ft
);
3832 bt_field_type_common_freeze(seq_ft
->element_ft
);
3836 void bt_field_type_common_integer_set_byte_order(
3837 struct bt_field_type_common
*ft
, enum bt_byte_order byte_order
)
3839 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
3841 int_ft
->user_byte_order
= byte_order
;
3845 void bt_field_type_common_enumeration_set_byte_order_recursive(
3846 struct bt_field_type_common
*ft
, enum bt_byte_order byte_order
)
3848 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
3850 bt_field_type_common_set_byte_order(BT_TO_COMMON(enum_ft
->container_ft
),
3855 void bt_field_type_common_floating_point_set_byte_order(
3856 struct bt_field_type_common
*ft
, enum bt_byte_order byte_order
)
3858 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
3860 flt_ft
->user_byte_order
= byte_order
;
3864 void bt_field_type_common_structure_set_byte_order_recursive(
3865 struct bt_field_type_common
*ft
,
3866 enum bt_byte_order byte_order
)
3869 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
3871 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
3872 struct bt_field_type_common_structure_field
*field
=
3873 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
3875 struct bt_field_type_common
*field_type
= field
->type
;
3877 bt_field_type_common_set_byte_order(field_type
, byte_order
);
3882 void bt_field_type_common_variant_set_byte_order_recursive(
3883 struct bt_field_type_common
*ft
,
3884 enum bt_byte_order byte_order
)
3887 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3889 for (i
= 0; i
< var_ft
->choices
->len
; i
++) {
3890 struct bt_field_type_common_variant_choice
*choice
=
3891 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
3893 struct bt_field_type_common
*field_type
= choice
->type
;
3895 bt_field_type_common_set_byte_order(field_type
, byte_order
);
3900 void bt_field_type_common_array_set_byte_order_recursive(
3901 struct bt_field_type_common
*ft
,
3902 enum bt_byte_order byte_order
)
3904 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
3906 bt_field_type_common_set_byte_order(array_ft
->element_ft
, byte_order
);
3910 void bt_field_type_common_sequence_set_byte_order_recursive(
3911 struct bt_field_type_common
*ft
,
3912 enum bt_byte_order byte_order
)
3914 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3916 bt_field_type_common_set_byte_order(seq_ft
->element_ft
, byte_order
);
3921 int bt_field_type_common_integer_compare(struct bt_field_type_common
*ft_a
,
3922 struct bt_field_type_common
*ft_b
)
3925 struct bt_field_type_common_integer
*int_ft_a
= BT_FROM_COMMON(ft_a
);
3926 struct bt_field_type_common_integer
*int_ft_b
= BT_FROM_COMMON(ft_b
);
3929 if (int_ft_a
->size
!= int_ft_b
->size
) {
3930 BT_LOGV("Integer field types differ: different sizes: "
3931 "ft-a-size=%u, ft-b-size=%u",
3932 int_ft_a
->size
, int_ft_b
->size
);
3937 if (int_ft_a
->user_byte_order
!= int_ft_b
->user_byte_order
) {
3938 BT_LOGV("Integer field types differ: different byte orders: "
3939 "ft-a-bo=%s, ft-b-bo=%s",
3940 bt_common_byte_order_string(int_ft_a
->user_byte_order
),
3941 bt_common_byte_order_string(int_ft_b
->user_byte_order
));
3946 if (int_ft_a
->is_signed
!= int_ft_b
->is_signed
) {
3947 BT_LOGV("Integer field types differ: different signedness: "
3948 "ft-a-is-signed=%d, ft-b-is-signed=%d",
3949 int_ft_a
->is_signed
,
3950 int_ft_b
->is_signed
);
3955 if (int_ft_a
->base
!= int_ft_b
->base
) {
3956 BT_LOGV("Integer field types differ: different bases: "
3957 "ft-a-base=%s, ft-b-base=%s",
3958 bt_common_integer_base_string(int_ft_a
->base
),
3959 bt_common_integer_base_string(int_ft_b
->base
));
3964 if (int_ft_a
->encoding
!= int_ft_b
->encoding
) {
3965 BT_LOGV("Integer field types differ: different encodings: "
3966 "ft-a-encoding=%s, ft-b-encoding=%s",
3967 bt_common_string_encoding_string(int_ft_a
->encoding
),
3968 bt_common_string_encoding_string(int_ft_b
->encoding
));
3972 /* Mapped clock class */
3973 if (int_ft_a
->mapped_clock_class
) {
3974 if (!int_ft_b
->mapped_clock_class
) {
3975 BT_LOGV_STR("Integer field types differ: field type A "
3976 "has a mapped clock class, but field type B "
3981 if (bt_clock_class_compare(int_ft_a
->mapped_clock_class
,
3982 int_ft_b
->mapped_clock_class
) != 0) {
3983 BT_LOGV_STR("Integer field types differ: different "
3984 "mapped clock classes.");
3987 if (int_ft_b
->mapped_clock_class
) {
3988 BT_LOGV_STR("Integer field types differ: field type A "
3989 "has no description, but field type B has one.");
4002 int bt_field_type_common_floating_point_compare(
4003 struct bt_field_type_common
*ft_a
,
4004 struct bt_field_type_common
*ft_b
)
4007 struct bt_field_type_common_floating_point
*flt_ft_a
=
4008 BT_FROM_COMMON(ft_a
);
4009 struct bt_field_type_common_floating_point
*flt_ft_b
=
4010 BT_FROM_COMMON(ft_b
);
4013 if (flt_ft_a
->user_byte_order
!= flt_ft_b
->user_byte_order
) {
4014 BT_LOGV("Floating point number field types differ: different byte orders: "
4015 "ft-a-bo=%s, ft-b-bo=%s",
4016 bt_common_byte_order_string(flt_ft_a
->user_byte_order
),
4017 bt_common_byte_order_string(flt_ft_b
->user_byte_order
));
4021 /* Exponent length */
4022 if (flt_ft_a
->exp_dig
!= flt_ft_b
->exp_dig
) {
4023 BT_LOGV("Floating point number field types differ: different exponent sizes: "
4024 "ft-a-exp-size=%u, ft-b-exp-size=%u",
4025 flt_ft_a
->exp_dig
, flt_ft_b
->exp_dig
);
4029 /* Mantissa length */
4030 if (flt_ft_a
->mant_dig
!= flt_ft_b
->mant_dig
) {
4031 BT_LOGV("Floating point number field types differ: different mantissa sizes: "
4032 "ft-a-mant-size=%u, ft-b-mant-size=%u",
4033 flt_ft_a
->mant_dig
, flt_ft_b
->mant_dig
);
4045 int compare_enumeration_mappings(struct enumeration_mapping
*mapping_a
,
4046 struct enumeration_mapping
*mapping_b
)
4051 if (mapping_a
->string
!= mapping_b
->string
) {
4052 BT_LOGV("Enumeration field type mappings differ: different names: "
4053 "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
4054 g_quark_to_string(mapping_a
->string
),
4055 g_quark_to_string(mapping_b
->string
));
4060 if (mapping_a
->range_start
._unsigned
!=
4061 mapping_b
->range_start
._unsigned
) {
4062 BT_LOGV("Enumeration field type mappings differ: different starts of range: "
4063 "mapping-a-range-start-unsigned=%" PRIu64
", "
4064 "mapping-b-range-start-unsigned=%" PRIu64
,
4065 mapping_a
->range_start
._unsigned
,
4066 mapping_b
->range_start
._unsigned
);
4071 if (mapping_a
->range_end
._unsigned
!=
4072 mapping_b
->range_end
._unsigned
) {
4073 BT_LOGV("Enumeration field type mappings differ: different ends of range: "
4074 "mapping-a-range-end-unsigned=%" PRIu64
", "
4075 "mapping-b-range-end-unsigned=%" PRIu64
,
4076 mapping_a
->range_end
._unsigned
,
4077 mapping_b
->range_end
._unsigned
);
4089 int bt_field_type_common_enumeration_compare_recursive(
4090 struct bt_field_type_common
*ft_a
,
4091 struct bt_field_type_common
*ft_b
)
4095 struct bt_field_type_common_enumeration
*enum_ft_a
=
4096 BT_FROM_COMMON(ft_a
);
4097 struct bt_field_type_common_enumeration
*enum_ft_b
=
4098 BT_FROM_COMMON(ft_b
);
4100 /* Container field type */
4101 ret
= bt_field_type_common_compare(
4102 BT_TO_COMMON(enum_ft_a
->container_ft
),
4103 BT_TO_COMMON(enum_ft_b
->container_ft
));
4105 BT_LOGV("Enumeration field types differ: different container field types: "
4106 "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
4107 enum_ft_a
->container_ft
, enum_ft_b
->container_ft
);
4114 if (enum_ft_a
->entries
->len
!= enum_ft_b
->entries
->len
) {
4118 for (i
= 0; i
< enum_ft_a
->entries
->len
; ++i
) {
4119 struct enumeration_mapping
*mapping_a
=
4120 g_ptr_array_index(enum_ft_a
->entries
, i
);
4121 struct enumeration_mapping
*mapping_b
=
4122 g_ptr_array_index(enum_ft_b
->entries
, i
);
4124 if (compare_enumeration_mappings(mapping_a
, mapping_b
)) {
4125 BT_LOGV("Enumeration field types differ: different mappings: "
4126 "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
4127 "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
4128 mapping_a
, mapping_b
,
4129 g_quark_to_string(mapping_a
->string
),
4130 g_quark_to_string(mapping_b
->string
));
4143 int bt_field_type_common_string_compare(struct bt_field_type_common
*ft_a
,
4144 struct bt_field_type_common
*ft_b
)
4147 struct bt_field_type_common_string
*string_ft_a
= BT_FROM_COMMON(ft_a
);
4148 struct bt_field_type_common_string
*string_ft_b
= BT_FROM_COMMON(ft_b
);
4151 if (string_ft_a
->encoding
!= string_ft_b
->encoding
) {
4152 BT_LOGV("String field types differ: different encodings: "
4153 "ft-a-encoding=%s, ft-b-encoding=%s",
4154 bt_common_string_encoding_string(string_ft_a
->encoding
),
4155 bt_common_string_encoding_string(string_ft_b
->encoding
));
4167 int compare_structure_variant_members(
4168 struct bt_field_type_common
*member_a_ft
,
4169 struct bt_field_type_common
*member_b_ft
,
4170 GQuark member_a_name
, GQuark member_b_name
)
4175 if (member_a_name
!= member_b_name
) {
4176 BT_LOGV("Structure/variant field type fields differ: different names: "
4177 "field-a-name=%s, field-b-name=%s",
4178 g_quark_to_string(member_a_name
),
4179 g_quark_to_string(member_b_name
));
4184 ret
= bt_field_type_common_compare(member_a_ft
, member_b_ft
);
4186 BT_LOGV("Structure/variant field type fields differ: different field types: "
4187 "field-name=\"%s\", field-a-ft-addr=%p, field-b-ft-addr=%p",
4188 g_quark_to_string(member_a_name
),
4189 member_a_ft
, member_b_ft
);
4197 int bt_field_type_common_structure_compare_recursive(
4198 struct bt_field_type_common
*ft_a
,
4199 struct bt_field_type_common
*ft_b
)
4203 struct bt_field_type_common_structure
*struct_ft_a
=
4204 BT_FROM_COMMON(ft_a
);
4205 struct bt_field_type_common_structure
*struct_ft_b
=
4206 BT_FROM_COMMON(ft_b
);
4209 if (bt_field_type_common_get_alignment(ft_a
) !=
4210 bt_field_type_common_get_alignment(ft_b
)) {
4211 BT_LOGV("Structure field types differ: different alignments: "
4212 "ft-a-align=%u, ft-b-align=%u",
4213 bt_field_type_common_get_alignment(ft_a
),
4214 bt_field_type_common_get_alignment(ft_b
));
4219 if (struct_ft_a
->fields
->len
!= struct_ft_b
->fields
->len
) {
4220 BT_LOGV("Structure field types differ: different field counts: "
4221 "ft-a-field-count=%u, ft-b-field-count=%u",
4222 struct_ft_a
->fields
->len
, struct_ft_b
->fields
->len
);
4226 for (i
= 0; i
< struct_ft_a
->fields
->len
; ++i
) {
4227 struct bt_field_type_common_structure_field
*field_a
=
4228 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
4230 struct bt_field_type_common_structure_field
*field_b
=
4231 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
4234 ret
= compare_structure_variant_members(field_a
->type
,
4235 field_b
->type
, field_a
->name
, field_b
->name
);
4237 /* compare_structure_variant_members() logs what differs */
4238 BT_LOGV_STR("Structure field types differ: different fields.");
4251 int bt_field_type_common_variant_compare_recursive(
4252 struct bt_field_type_common
*ft_a
,
4253 struct bt_field_type_common
*ft_b
)
4257 struct bt_field_type_common_variant
*var_ft_a
= BT_FROM_COMMON(ft_a
);
4258 struct bt_field_type_common_variant
*var_ft_b
= BT_FROM_COMMON(ft_b
);
4261 if (strcmp(var_ft_a
->tag_name
->str
, var_ft_b
->tag_name
->str
)) {
4262 BT_LOGV("Variant field types differ: different tag field names: "
4263 "ft-a-tag-field-name=\"%s\", ft-b-tag-field-name=\"%s\"",
4264 var_ft_a
->tag_name
->str
, var_ft_b
->tag_name
->str
);
4269 ret
= bt_field_type_common_compare(BT_TO_COMMON(var_ft_a
->tag_ft
),
4270 BT_TO_COMMON(var_ft_b
->tag_ft
));
4272 BT_LOGV("Variant field types differ: different tag field types: "
4273 "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
4274 var_ft_a
->tag_ft
, var_ft_b
->tag_ft
);
4281 if (var_ft_a
->choices
->len
!= var_ft_b
->choices
->len
) {
4282 BT_LOGV("Variant field types differ: different field counts: "
4283 "ft-a-field-count=%u, ft-b-field-count=%u",
4284 var_ft_a
->choices
->len
, var_ft_b
->choices
->len
);
4288 for (i
= 0; i
< var_ft_a
->choices
->len
; ++i
) {
4289 struct bt_field_type_common_variant_choice
*choice_a
=
4290 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
4292 struct bt_field_type_common_variant_choice
*choice_b
=
4293 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
4296 ret
= compare_structure_variant_members(choice_a
->type
,
4297 choice_b
->type
, choice_a
->name
, choice_b
->name
);
4299 /* compare_structure_variant_members() logs what differs */
4300 BT_LOGV_STR("Variant field types differ: different fields.");
4313 int bt_field_type_common_array_compare_recursive(
4314 struct bt_field_type_common
*ft_a
,
4315 struct bt_field_type_common
*ft_b
)
4318 struct bt_field_type_common_array
*array_ft_a
= BT_FROM_COMMON(ft_a
);
4319 struct bt_field_type_common_array
*array_ft_b
= BT_FROM_COMMON(ft_b
);
4322 if (array_ft_a
->length
!= array_ft_b
->length
) {
4323 BT_LOGV("Structure field types differ: different lengths: "
4324 "ft-a-length=%u, ft-b-length=%u",
4325 array_ft_a
->length
, array_ft_b
->length
);
4330 ret
= bt_field_type_common_compare(array_ft_a
->element_ft
,
4331 array_ft_b
->element_ft
);
4333 BT_LOGV("Array field types differ: different element field types: "
4334 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
4335 array_ft_a
->element_ft
, array_ft_b
->element_ft
);
4343 int bt_field_type_common_sequence_compare_recursive(
4344 struct bt_field_type_common
*ft_a
,
4345 struct bt_field_type_common
*ft_b
)
4348 struct bt_field_type_common_sequence
*seq_ft_a
= BT_FROM_COMMON(ft_a
);
4349 struct bt_field_type_common_sequence
*seq_ft_b
= BT_FROM_COMMON(ft_b
);
4352 if (strcmp(seq_ft_a
->length_field_name
->str
,
4353 seq_ft_b
->length_field_name
->str
)) {
4354 BT_LOGV("Sequence field types differ: different length field names: "
4355 "ft-a-length-field-name=\"%s\", "
4356 "ft-b-length-field-name=\"%s\"",
4357 seq_ft_a
->length_field_name
->str
,
4358 seq_ft_b
->length_field_name
->str
);
4363 ret
= bt_field_type_common_compare(seq_ft_a
->element_ft
,
4364 seq_ft_b
->element_ft
);
4366 BT_LOGV("Sequence field types differ: different element field types: "
4367 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
4368 seq_ft_a
->element_ft
, seq_ft_b
->element_ft
);
4376 int bt_field_type_common_compare(struct bt_field_type_common
*ft_a
,
4377 struct bt_field_type_common
*ft_b
)
4381 BT_ASSERT_PRE_NON_NULL(ft_a
, "Field type A");
4382 BT_ASSERT_PRE_NON_NULL(ft_b
, "Field type B");
4385 /* Same reference: equal (even if both are NULL) */
4391 BT_LOGW_STR("Invalid parameter: field type A is NULL.");
4397 BT_LOGW_STR("Invalid parameter: field type B is NULL.");
4402 if (ft_a
->id
!= ft_b
->id
) {
4403 /* Different type IDs */
4404 BT_LOGV("Field types differ: different IDs: "
4405 "ft-a-addr=%p, ft-b-addr=%p, "
4406 "ft-a-id=%s, ft-b-id=%s",
4408 bt_common_field_type_id_string(ft_a
->id
),
4409 bt_common_field_type_id_string(ft_b
->id
));
4413 if (ft_a
->id
== BT_FIELD_TYPE_ID_UNKNOWN
) {
4414 /* Both have unknown type IDs */
4415 BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
4419 BT_ASSERT(ft_a
->methods
->compare
);
4420 ret
= ft_a
->methods
->compare(ft_a
, ft_b
);
4422 BT_LOGV("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
4430 int bt_field_type_compare(struct bt_field_type
*ft_a
,
4431 struct bt_field_type
*ft_b
)
4433 return bt_field_type_common_compare((void *) ft_a
, (void *) ft_b
);
4437 int64_t bt_field_type_common_get_field_count(struct bt_field_type_common
*ft
)
4439 int64_t field_count
= -1;
4442 case BT_FIELD_TYPE_ID_STRUCT
:
4444 bt_field_type_common_structure_get_field_count(ft
);
4446 case BT_FIELD_TYPE_ID_VARIANT
:
4448 bt_field_type_common_variant_get_field_count(ft
);
4450 case BT_FIELD_TYPE_ID_ARRAY
:
4451 case BT_FIELD_TYPE_ID_SEQUENCE
:
4453 * Array and sequence types always contain a single member
4454 * (the element type).
4466 struct bt_field_type_common
*bt_field_type_common_borrow_field_at_index(
4467 struct bt_field_type_common
*ft
, int index
)
4469 struct bt_field_type_common
*field_type
= NULL
;
4472 case BT_FIELD_TYPE_ID_STRUCT
:
4474 int ret
= bt_field_type_common_structure_borrow_field_by_index(
4475 ft
, NULL
, &field_type
, index
);
4482 case BT_FIELD_TYPE_ID_VARIANT
:
4484 int ret
= bt_field_type_common_variant_borrow_field_by_index(
4485 ft
, NULL
, &field_type
, index
);
4492 case BT_FIELD_TYPE_ID_ARRAY
:
4494 bt_field_type_common_array_borrow_element_field_type(ft
);
4496 case BT_FIELD_TYPE_ID_SEQUENCE
:
4498 bt_field_type_common_sequence_borrow_element_field_type(ft
);
4509 int bt_field_type_common_get_field_index(struct bt_field_type_common
*ft
,
4512 int field_index
= -1;
4515 case BT_FIELD_TYPE_ID_STRUCT
:
4516 field_index
= bt_field_type_common_structure_get_field_name_index(
4519 case BT_FIELD_TYPE_ID_VARIANT
:
4520 field_index
= bt_field_type_common_variant_get_field_name_index(
4531 struct bt_field_path
*bt_field_type_common_variant_borrow_tag_field_path(
4532 struct bt_field_type_common
*ft
)
4534 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
4536 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
4537 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
4539 return var_ft
->tag_field_path
;
4542 struct bt_field_path
*bt_field_type_variant_borrow_tag_field_path(
4543 struct bt_field_type
*ft
)
4545 return bt_field_type_common_variant_borrow_tag_field_path((void *) ft
);
4549 struct bt_field_path
*bt_field_type_common_sequence_borrow_length_field_path(
4550 struct bt_field_type_common
*ft
)
4552 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
4554 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
4555 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_SEQUENCE
,
4557 return seq_ft
->length_field_path
;
4560 struct bt_field_path
*bt_field_type_sequence_borrow_length_field_path(
4561 struct bt_field_type
*ft
)
4563 return bt_field_type_common_sequence_borrow_length_field_path(
4568 int bt_field_type_common_validate_single_clock_class(
4569 struct bt_field_type_common
*ft
,
4570 struct bt_clock_class
**expected_clock_class
)
4578 BT_ASSERT(expected_clock_class
);
4581 case BT_FIELD_TYPE_ID_INTEGER
:
4583 struct bt_clock_class
*mapped_clock_class
=
4584 bt_field_type_common_integer_borrow_mapped_clock_class(ft
);
4586 if (!mapped_clock_class
) {
4590 if (!*expected_clock_class
) {
4591 /* Move reference to output parameter */
4592 *expected_clock_class
= bt_get(mapped_clock_class
);
4593 mapped_clock_class
= NULL
;
4594 BT_LOGV("Setting expected clock class: "
4595 "expected-clock-class-addr=%p",
4596 *expected_clock_class
);
4598 if (mapped_clock_class
!= *expected_clock_class
) {
4599 BT_LOGW("Integer field type is not mapped to "
4600 "the expected clock class: "
4601 "mapped-clock-class-addr=%p, "
4602 "mapped-clock-class-name=\"%s\", "
4603 "expected-clock-class-addr=%p, "
4604 "expected-clock-class-name=\"%s\"",
4606 bt_clock_class_get_name(mapped_clock_class
),
4607 *expected_clock_class
,
4608 bt_clock_class_get_name(*expected_clock_class
));
4609 bt_put(mapped_clock_class
);
4617 case BT_FIELD_TYPE_ID_ENUM
:
4618 case BT_FIELD_TYPE_ID_ARRAY
:
4619 case BT_FIELD_TYPE_ID_SEQUENCE
:
4621 struct bt_field_type_common
*sub_ft
= NULL
;
4624 case BT_FIELD_TYPE_ID_ENUM
:
4625 sub_ft
= bt_field_type_common_enumeration_borrow_container_field_type(
4628 case BT_FIELD_TYPE_ID_ARRAY
:
4629 sub_ft
= bt_field_type_common_array_borrow_element_field_type(
4632 case BT_FIELD_TYPE_ID_SEQUENCE
:
4633 sub_ft
= bt_field_type_common_sequence_borrow_element_field_type(
4637 BT_LOGF("Unexpected field type ID: id=%d", ft
->id
);
4642 ret
= bt_field_type_common_validate_single_clock_class(sub_ft
,
4643 expected_clock_class
);
4646 case BT_FIELD_TYPE_ID_STRUCT
:
4649 int64_t count
= bt_field_type_common_structure_get_field_count(
4652 for (i
= 0; i
< count
; i
++) {
4654 struct bt_field_type_common
*member_type
;
4656 ret
= bt_field_type_common_structure_borrow_field_by_index(
4657 ft
, &name
, &member_type
, i
);
4658 BT_ASSERT(ret
== 0);
4659 ret
= bt_field_type_common_validate_single_clock_class(
4660 member_type
, expected_clock_class
);
4662 BT_LOGW("Structure field type's field's type "
4663 "is not recursively mapped to the "
4664 "expected clock class: "
4665 "field-ft-addr=%p, field-name=\"%s\"",
4672 case BT_FIELD_TYPE_ID_VARIANT
:
4675 int64_t count
= bt_field_type_common_variant_get_field_count(
4678 for (i
= 0; i
< count
; i
++) {
4680 struct bt_field_type_common
*member_type
;
4682 ret
= bt_field_type_common_variant_borrow_field_by_index(
4683 ft
, &name
, &member_type
, i
);
4684 BT_ASSERT(ret
== 0);
4685 ret
= bt_field_type_common_validate_single_clock_class(
4686 member_type
, expected_clock_class
);
4688 BT_LOGW("Variant field type's field's type "
4689 "is not recursively mapped to the "
4690 "expected clock class: "
4691 "field-ft-addr=%p, field-name=\"%s\"",
4707 struct bt_field_type
*bt_field_type_integer_copy(
4708 struct bt_field_type
*ft
)
4710 struct bt_field_type_common_integer
*int_ft
= (void *) ft
;
4711 struct bt_field_type_common_integer
*copy_ft
;
4713 BT_LOGD("Copying integer field type's: addr=%p", ft
);
4714 copy_ft
= (void *) bt_field_type_integer_create(int_ft
->size
);
4716 BT_LOGE_STR("Cannot create integer field type.");
4720 copy_ft
->mapped_clock_class
= bt_get(int_ft
->mapped_clock_class
);
4721 copy_ft
->user_byte_order
= int_ft
->user_byte_order
;
4722 copy_ft
->is_signed
= int_ft
->is_signed
;
4723 copy_ft
->size
= int_ft
->size
;
4724 copy_ft
->base
= int_ft
->base
;
4725 copy_ft
->encoding
= int_ft
->encoding
;
4726 BT_LOGD("Copied integer field type: original-ft-addr=%p, copy-ft-addr=%p",
4730 return (void *) copy_ft
;
4734 struct bt_field_type
*bt_field_type_enumeration_copy_recursive(
4735 struct bt_field_type
*ft
)
4738 struct bt_field_type_common_enumeration
*enum_ft
= (void *) ft
;
4739 struct bt_field_type_common_enumeration
*copy_ft
= NULL
;
4740 struct bt_field_type_common_enumeration
*container_copy_ft
;
4742 BT_LOGD("Copying enumeration field type's: addr=%p", ft
);
4744 /* Copy the source enumeration's container */
4745 BT_LOGD_STR("Copying enumeration field type's container field type.");
4746 container_copy_ft
= BT_FROM_COMMON(bt_field_type_common_copy(
4747 BT_TO_COMMON(enum_ft
->container_ft
)));
4748 if (!container_copy_ft
) {
4749 BT_LOGE_STR("Cannot copy enumeration field type's container field type.");
4753 copy_ft
= (void *) bt_field_type_enumeration_create(
4754 (void *) container_copy_ft
);
4756 BT_LOGE_STR("Cannot create enumeration field type.");
4760 /* Copy all enumaration entries */
4761 for (i
= 0; i
< enum_ft
->entries
->len
; i
++) {
4762 struct enumeration_mapping
*mapping
= g_ptr_array_index(
4763 enum_ft
->entries
, i
);
4764 struct enumeration_mapping
*copy_mapping
= g_new0(
4765 struct enumeration_mapping
, 1);
4767 if (!copy_mapping
) {
4768 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
4772 *copy_mapping
= *mapping
;
4773 g_ptr_array_add(copy_ft
->entries
, copy_mapping
);
4776 BT_LOGD("Copied enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
4780 bt_put(container_copy_ft
);
4781 return (void *) copy_ft
;
4784 bt_put(container_copy_ft
);
4786 return (void *) copy_ft
;
4790 struct bt_field_type
*bt_field_type_floating_point_copy(
4791 struct bt_field_type
*ft
)
4793 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
4794 struct bt_field_type_common_floating_point
*copy_ft
;
4796 BT_LOGD("Copying floating point number field type's: addr=%p", ft
);
4797 copy_ft
= (void *) bt_field_type_floating_point_create();
4799 BT_LOGE_STR("Cannot create floating point number field type.");
4803 copy_ft
->user_byte_order
= flt_ft
->user_byte_order
;
4804 copy_ft
->exp_dig
= flt_ft
->exp_dig
;
4805 copy_ft
->mant_dig
= flt_ft
->mant_dig
;
4806 BT_LOGD("Copied floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
4810 return (void *) copy_ft
;
4814 struct bt_field_type
*bt_field_type_structure_copy_recursive(
4815 struct bt_field_type
*ft
)
4818 GHashTableIter iter
;
4819 gpointer key
, value
;
4820 struct bt_field_type_common_structure
*struct_ft
= (void *) ft
;
4821 struct bt_field_type_common_structure
*copy_ft
;
4823 BT_LOGD("Copying structure field type's: addr=%p", ft
);
4824 copy_ft
= (void *) bt_field_type_structure_create();
4826 BT_LOGE_STR("Cannot create structure field type.");
4830 /* Copy field_name_to_index */
4831 g_hash_table_iter_init(&iter
, struct_ft
->field_name_to_index
);
4832 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
4833 g_hash_table_insert(copy_ft
->field_name_to_index
,
4837 g_array_set_size(copy_ft
->fields
, struct_ft
->fields
->len
);
4839 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
4840 struct bt_field_type_common_structure_field
*entry
, *copy_entry
;
4841 struct bt_field_type_common
*field_ft_copy
;
4843 entry
= BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
4845 copy_entry
= BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
4847 BT_LOGD("Copying structure field type's field: "
4848 "index=%" PRId64
", "
4849 "field-ft-addr=%p, field-name=\"%s\"",
4850 i
, entry
, g_quark_to_string(entry
->name
));
4852 field_ft_copy
= (void *) bt_field_type_copy(
4853 (void *) entry
->type
);
4854 if (!field_ft_copy
) {
4855 BT_LOGE("Cannot copy structure field type's field: "
4856 "index=%" PRId64
", "
4857 "field-ft-addr=%p, field-name=\"%s\"",
4858 i
, entry
, g_quark_to_string(entry
->name
));
4862 copy_entry
->name
= entry
->name
;
4863 copy_entry
->type
= field_ft_copy
;
4866 BT_LOGD("Copied structure field type: original-ft-addr=%p, copy-ft-addr=%p",
4870 return (void *) copy_ft
;
4878 struct bt_field_type
*bt_field_type_variant_copy_recursive(
4879 struct bt_field_type
*ft
)
4882 GHashTableIter iter
;
4883 gpointer key
, value
;
4884 struct bt_field_type_common
*tag_ft_copy
= NULL
;
4885 struct bt_field_type_common_variant
*var_ft
= (void *) ft
;
4886 struct bt_field_type_common_variant
*copy_ft
= NULL
;
4888 BT_LOGD("Copying variant field type's: addr=%p", ft
);
4889 if (var_ft
->tag_ft
) {
4890 BT_LOGD_STR("Copying variant field type's tag field type.");
4891 tag_ft_copy
= bt_field_type_common_copy(
4892 BT_TO_COMMON(var_ft
->tag_ft
));
4894 BT_LOGE_STR("Cannot copy variant field type's tag field type.");
4899 copy_ft
= (void *) bt_field_type_variant_create(
4900 (void *) tag_ft_copy
,
4901 var_ft
->tag_name
->len
? var_ft
->tag_name
->str
: NULL
);
4903 BT_LOGE_STR("Cannot create variant field type.");
4907 /* Copy field_name_to_index */
4908 g_hash_table_iter_init(&iter
, var_ft
->choice_name_to_index
);
4909 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
4910 g_hash_table_insert(copy_ft
->choice_name_to_index
,
4914 g_array_set_size(copy_ft
->choices
, var_ft
->choices
->len
);
4916 for (i
= 0; i
< var_ft
->choices
->len
; i
++) {
4917 struct bt_field_type_common_variant_choice
*entry
, *copy_entry
;
4918 struct bt_field_type_common
*field_ft_copy
;
4921 entry
= BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft
, i
);
4922 copy_entry
= BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
4924 BT_LOGD("Copying variant field type's field: "
4925 "index=%" PRId64
", "
4926 "field-ft-addr=%p, field-name=\"%s\"",
4927 i
, entry
, g_quark_to_string(entry
->name
));
4929 field_ft_copy
= (void *) bt_field_type_copy(
4930 (void *) entry
->type
);
4931 if (!field_ft_copy
) {
4932 BT_LOGE("Cannot copy variant field type's field: "
4933 "index=%" PRId64
", "
4934 "field-ft-addr=%p, field-name=\"%s\"",
4935 i
, entry
, g_quark_to_string(entry
->name
));
4940 copy_entry
->name
= entry
->name
;
4941 copy_entry
->type
= field_ft_copy
;
4944 copy_entry
->ranges
= g_array_new(FALSE
, TRUE
,
4945 sizeof(struct bt_field_type_common_variant_choice_range
));
4946 BT_ASSERT(copy_entry
->ranges
);
4947 g_array_set_size(copy_entry
->ranges
, entry
->ranges
->len
);
4949 for (range_i
= 0; range_i
< entry
->ranges
->len
; range_i
++) {
4950 copy_entry
->ranges
[range_i
] = entry
->ranges
[range_i
];
4954 if (var_ft
->tag_field_path
) {
4955 BT_LOGD_STR("Copying variant field type's tag field path.");
4956 copy_ft
->tag_field_path
= bt_field_path_copy(
4957 var_ft
->tag_field_path
);
4958 if (!copy_ft
->tag_field_path
) {
4959 BT_LOGE_STR("Cannot copy variant field type's tag field path.");
4964 copy_ft
->choices_up_to_date
= var_ft
->choices_up_to_date
;
4965 BT_LOGD("Copied variant field type: original-ft-addr=%p, copy-ft-addr=%p",
4969 bt_put(tag_ft_copy
);
4970 return (void *) copy_ft
;
4973 bt_put(tag_ft_copy
);
4979 struct bt_field_type
*bt_field_type_array_copy_recursive(
4980 struct bt_field_type
*ft
)
4982 struct bt_field_type_common
*container_ft_copy
= NULL
;
4983 struct bt_field_type_common_array
*array_ft
= (void *) ft
;
4984 struct bt_field_type_common_array
*copy_ft
= NULL
;
4986 BT_LOGD("Copying array field type's: addr=%p", ft
);
4987 BT_LOGD_STR("Copying array field type's element field type.");
4988 container_ft_copy
= bt_field_type_common_copy(array_ft
->element_ft
);
4989 if (!container_ft_copy
) {
4990 BT_LOGE_STR("Cannot copy array field type's element field type.");
4994 copy_ft
= (void *) bt_field_type_array_create(
4995 (void *) container_ft_copy
, array_ft
->length
);
4997 BT_LOGE_STR("Cannot create array field type.");
5001 BT_LOGD("Copied array field type: original-ft-addr=%p, copy-ft-addr=%p",
5005 bt_put(container_ft_copy
);
5006 return (void *) copy_ft
;
5010 struct bt_field_type
*bt_field_type_sequence_copy_recursive(
5011 struct bt_field_type
*ft
)
5013 struct bt_field_type_common
*container_ft_copy
= NULL
;
5014 struct bt_field_type_common_sequence
*seq_ft
= (void *) ft
;
5015 struct bt_field_type_common_sequence
*copy_ft
= NULL
;
5017 BT_LOGD("Copying sequence field type's: addr=%p", ft
);
5018 BT_LOGD_STR("Copying sequence field type's element field type.");
5019 container_ft_copy
= bt_field_type_common_copy(seq_ft
->element_ft
);
5020 if (!container_ft_copy
) {
5021 BT_LOGE_STR("Cannot copy sequence field type's element field type.");
5025 copy_ft
= (void *) bt_field_type_sequence_create(
5026 (void *) container_ft_copy
,
5027 seq_ft
->length_field_name
->len
?
5028 seq_ft
->length_field_name
->str
: NULL
);
5030 BT_LOGE_STR("Cannot create sequence field type.");
5034 if (seq_ft
->length_field_path
) {
5035 BT_LOGD_STR("Copying sequence field type's length field path.");
5036 copy_ft
->length_field_path
= bt_field_path_copy(
5037 seq_ft
->length_field_path
);
5038 if (!copy_ft
->length_field_path
) {
5039 BT_LOGE_STR("Cannot copy sequence field type's length field path.");
5044 BT_LOGD("Copied sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
5048 bt_put(container_ft_copy
);
5049 return (void *) copy_ft
;
5051 bt_put(container_ft_copy
);
5057 struct bt_field_type
*bt_field_type_string_copy(struct bt_field_type
*ft
)
5059 struct bt_field_type_common_string
*string_ft
= (void *) ft
;
5060 struct bt_field_type_common_string
*copy_ft
= NULL
;
5062 BT_LOGD("Copying string field type's: addr=%p", ft
);
5063 copy_ft
= (void *) bt_field_type_string_create();
5065 BT_LOGE_STR("Cannot create string field type.");
5069 copy_ft
->encoding
= string_ft
->encoding
;
5070 BT_LOGD("Copied string field type: original-ft-addr=%p, copy-ft-addr=%p",
5074 return (void *) copy_ft
;