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 destroy_structure_field_common(struct structure_field_common
*field
)
167 BT_LOGD("Destroying structure/variant field type's field object: "
168 "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
169 field
, field
->type
, g_quark_to_string(field
->name
));
170 BT_LOGD_STR("Putting field type.");
176 void bt_field_type_common_initialize(struct bt_field_type_common
*ft
,
177 bool init_bo
, bt_object_release_func release_func
,
178 struct bt_field_type_common_methods
*methods
)
180 BT_ASSERT(ft
&& (ft
->id
> BT_FIELD_TYPE_ID_UNKNOWN
) &&
181 (ft
->id
< BT_FIELD_TYPE_ID_NR
));
183 bt_object_init(ft
, release_func
);
184 ft
->methods
= methods
;
188 const enum bt_byte_order bo
= BT_BYTE_ORDER_NATIVE
;
190 BT_LOGD("Setting initial field type's byte order: bo=%s",
191 bt_common_byte_order_string(bo
));
192 ret
= bt_field_type_common_set_byte_order(ft
, bo
);
200 void bt_field_type_common_integer_initialize(
201 struct bt_field_type_common
*ft
,
202 unsigned int size
, bt_object_release_func release_func
,
203 struct bt_field_type_common_methods
*methods
)
205 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
208 BT_LOGD("Initializing common integer field type object: size=%u",
210 ft
->id
= BT_FIELD_TYPE_ID_INTEGER
;
212 int_ft
->base
= BT_INTEGER_BASE_DECIMAL
;
213 int_ft
->encoding
= BT_STRING_ENCODING_NONE
;
214 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
215 BT_LOGD("Initialized common integer field type object: addr=%p, size=%u",
220 void bt_field_type_common_floating_point_initialize(
221 struct bt_field_type_common
*ft
,
222 bt_object_release_func release_func
,
223 struct bt_field_type_common_methods
*methods
)
225 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
227 BT_LOGD_STR("Initializing common floating point number field type object.");
228 ft
->id
= BT_FIELD_TYPE_ID_FLOAT
;
229 flt_ft
->exp_dig
= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
230 flt_ft
->mant_dig
= FLT_MANT_DIG
;
231 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
232 BT_LOGD("Initialized common floating point number field type object: addr=%p, "
233 "exp-size=%u, mant-size=%u", ft
, flt_ft
->exp_dig
,
238 void bt_field_type_common_enumeration_initialize(
239 struct bt_field_type_common
*ft
,
240 struct bt_field_type_common
*container_ft
,
241 bt_object_release_func release_func
,
242 struct bt_field_type_common_methods
*methods
)
244 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
246 BT_ASSERT(container_ft
);
247 BT_LOGD("Initializing common enumeration field type object: int-ft-addr=%p",
249 ft
->id
= BT_FIELD_TYPE_ID_ENUM
;
250 enum_ft
->container_ft
= bt_get(container_ft
);
251 enum_ft
->entries
= g_ptr_array_new_with_free_func(
252 (GDestroyNotify
) destroy_enumeration_mapping
);
253 bt_field_type_common_initialize(ft
, false, release_func
, methods
);
254 BT_LOGD("Initialized common enumeration field type object: addr=%p, "
255 "int-ft-addr=%p, int-ft-size=%u", ft
, container_ft
,
256 bt_field_type_common_integer_get_size(container_ft
));
260 void bt_field_type_common_string_initialize(
261 struct bt_field_type_common
*ft
,
262 bt_object_release_func release_func
,
263 struct bt_field_type_common_methods
*methods
)
265 struct bt_field_type_common_string
*string_ft
= BT_FROM_COMMON(ft
);
267 BT_LOGD_STR("Initializing common string field type object.");
268 ft
->id
= BT_FIELD_TYPE_ID_STRING
;
269 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
270 string_ft
->encoding
= BT_STRING_ENCODING_UTF8
;
271 ft
->alignment
= CHAR_BIT
;
272 BT_LOGD("Initialized common string field type object: addr=%p", ft
);
276 void bt_field_type_common_structure_initialize(
277 struct bt_field_type_common
*ft
,
278 bt_object_release_func release_func
,
279 struct bt_field_type_common_methods
*methods
)
281 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
283 BT_LOGD_STR("Initializing common structure field type object.");
284 ft
->id
= BT_FIELD_TYPE_ID_STRUCT
;
285 struct_ft
->fields
= g_ptr_array_new_with_free_func(
286 (GDestroyNotify
) destroy_structure_field_common
);
287 struct_ft
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
288 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
289 BT_LOGD("Initialized common structure field type object: addr=%p", ft
);
293 void bt_field_type_common_array_initialize(
294 struct bt_field_type_common
*ft
,
295 struct bt_field_type_common
*element_ft
,
296 unsigned int length
, bt_object_release_func release_func
,
297 struct bt_field_type_common_methods
*methods
)
299 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
301 BT_ASSERT(element_ft
);
302 BT_LOGD("Initializing common array field type object: element-ft-addr=%p, "
303 "length=%u", element_ft
, length
);
304 ft
->id
= BT_FIELD_TYPE_ID_ARRAY
;
305 array_ft
->element_ft
= bt_get(element_ft
);
306 array_ft
->length
= length
;
307 bt_field_type_common_initialize(ft
, false, release_func
, methods
);
308 BT_LOGD("Initialized common array field type object: addr=%p, "
309 "element-ft-addr=%p, length=%u", ft
, element_ft
, length
);
313 void bt_field_type_common_sequence_initialize(
314 struct bt_field_type_common
*ft
,
315 struct bt_field_type_common
*element_ft
,
316 const char *length_field_name
,
317 bt_object_release_func release_func
,
318 struct bt_field_type_common_methods
*methods
)
320 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
322 BT_ASSERT(element_ft
);
323 BT_ASSERT(length_field_name
);
324 BT_ASSERT(bt_identifier_is_valid(length_field_name
));
325 BT_LOGD("Initializing common sequence field type object: element-ft-addr=%p, "
326 "length-field-name=\"%s\"", element_ft
, length_field_name
);
327 ft
->id
= BT_FIELD_TYPE_ID_SEQUENCE
;
328 seq_ft
->element_ft
= bt_get(element_ft
);
329 seq_ft
->length_field_name
= g_string_new(length_field_name
);
330 bt_field_type_common_initialize(ft
, false, release_func
, methods
);
331 BT_LOGD("Initialized common sequence field type object: addr=%p, "
332 "element-ft-addr=%p, length-field-name=\"%s\"",
333 ft
, element_ft
, length_field_name
);
337 void bt_field_type_common_variant_initialize(
338 struct bt_field_type_common
*ft
,
339 struct bt_field_type_common
*tag_ft
,
340 const char *tag_name
,
341 bt_object_release_func release_func
,
342 struct bt_field_type_common_methods
*methods
)
344 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
346 BT_ASSERT(!tag_name
|| bt_identifier_is_valid(tag_name
));
347 BT_LOGD("Initializing common variant field type object: "
348 "tag-ft-addr=%p, tag-field-name=\"%s\"",
350 ft
->id
= BT_FIELD_TYPE_ID_VARIANT
;
351 var_ft
->tag_name
= g_string_new(tag_name
);
352 var_ft
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
353 var_ft
->fields
= g_ptr_array_new_with_free_func(
354 (GDestroyNotify
) destroy_structure_field_common
);
357 var_ft
->tag_ft
= bt_get(tag_ft
);
360 bt_field_type_common_initialize(ft
, true, release_func
, methods
);
361 /* A variant's alignment is undefined */
363 BT_LOGD("Initialized common variant field type object: addr=%p, "
364 "tag-ft-addr=%p, tag-field-name=\"%s\"",
365 ft
, tag_ft
, tag_name
);
369 void bt_field_type_common_integer_destroy(struct bt_object
*obj
)
371 struct bt_field_type_common_integer
*ft
= (void *) obj
;
377 BT_LOGD("Destroying integer field type object: addr=%p", ft
);
378 BT_LOGD_STR("Putting mapped clock class.");
379 bt_put(ft
->mapped_clock_class
);
384 void bt_field_type_common_floating_point_destroy(struct bt_object
*obj
)
386 struct bt_field_type_common_floating_point
*ft
= (void *) obj
;
392 BT_LOGD("Destroying floating point number field type object: addr=%p", ft
);
397 void bt_field_type_common_enumeration_destroy_recursive(struct bt_object
*obj
)
399 struct bt_field_type_common_enumeration
*ft
= (void *) obj
;
405 BT_LOGD("Destroying enumeration field type object: addr=%p", ft
);
406 g_ptr_array_free(ft
->entries
, TRUE
);
407 BT_LOGD_STR("Putting container field type.");
408 bt_put(ft
->container_ft
);
413 void bt_field_type_common_string_destroy(struct bt_object
*obj
)
415 struct bt_field_type_common_string
*ft
= (void *) obj
;
421 BT_LOGD("Destroying string field type object: addr=%p", ft
);
427 void bt_field_type_common_structure_destroy_recursive(struct bt_object
*obj
)
429 struct bt_field_type_common_structure
*ft
= (void *) obj
;
435 BT_LOGD("Destroying structure field type object: addr=%p", ft
);
436 g_ptr_array_free(ft
->fields
, TRUE
);
437 g_hash_table_destroy(ft
->field_name_to_index
);
442 void bt_field_type_common_array_destroy_recursive(struct bt_object
*obj
)
444 struct bt_field_type_common_array
*ft
= (void *) obj
;
450 BT_LOGD("Destroying array field type object: addr=%p", ft
);
451 BT_LOGD_STR("Putting element field type.");
452 bt_put(ft
->element_ft
);
457 void bt_field_type_common_sequence_destroy_recursive(struct bt_object
*obj
)
459 struct bt_field_type_common_sequence
*ft
= (void *) obj
;
465 BT_LOGD("Destroying sequence field type object: addr=%p", ft
);
466 BT_LOGD_STR("Putting element field type.");
467 bt_put(ft
->element_ft
);
468 g_string_free(ft
->length_field_name
, TRUE
);
469 BT_LOGD_STR("Putting length field path.");
470 bt_put(ft
->length_field_path
);
475 void bt_field_type_common_variant_destroy_recursive(struct bt_object
*obj
)
477 struct bt_field_type_common_variant
*ft
= (void *) obj
;
483 BT_LOGD("Destroying variant field type object: addr=%p", ft
);
484 g_ptr_array_free(ft
->fields
, TRUE
);
485 g_hash_table_destroy(ft
->field_name_to_index
);
486 g_string_free(ft
->tag_name
, TRUE
);
487 BT_LOGD_STR("Putting tag field type.");
489 BT_LOGD_STR("Putting tag field path.");
490 bt_put(ft
->tag_field_path
);
494 struct range_overlap_query
{
509 void check_ranges_overlap(gpointer element
, gpointer query
)
511 struct enumeration_mapping
*mapping
= element
;
512 struct range_overlap_query
*overlap_query
= query
;
514 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
515 && overlap_query
->range_start
._signed
<=
516 mapping
->range_end
._signed
) {
517 overlap_query
->overlaps
= 1;
518 overlap_query
->mapping_name
= mapping
->string
;
521 overlap_query
->overlaps
|=
522 mapping
->string
== overlap_query
->mapping_name
;
524 if (overlap_query
->overlaps
) {
525 BT_LOGV("Overlapping enumeration field type mappings: "
526 "mapping-name=\"%s\", "
527 "mapping-a-range-start=%" PRId64
", "
528 "mapping-a-range-end=%" PRId64
", "
529 "mapping-b-range-start=%" PRId64
", "
530 "mapping-b-range-end=%" PRId64
,
531 g_quark_to_string(mapping
->string
),
532 mapping
->range_start
._signed
,
533 mapping
->range_end
._signed
,
534 overlap_query
->range_start
._signed
,
535 overlap_query
->range_end
._signed
);
540 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
542 struct enumeration_mapping
*mapping
= element
;
543 struct range_overlap_query
*overlap_query
= query
;
545 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
546 && overlap_query
->range_start
._unsigned
<=
547 mapping
->range_end
._unsigned
) {
548 overlap_query
->overlaps
= 1;
549 overlap_query
->mapping_name
= mapping
->string
;
552 overlap_query
->overlaps
|=
553 mapping
->string
== overlap_query
->mapping_name
;
555 if (overlap_query
->overlaps
) {
556 BT_LOGW("Overlapping enumeration field type mappings: "
557 "mapping-name=\"%s\", "
558 "mapping-a-range-start=%" PRIu64
", "
559 "mapping-a-range-end=%" PRIu64
", "
560 "mapping-b-range-start=%" PRIu64
", "
561 "mapping-b-range-end=%" PRIu64
,
562 g_quark_to_string(mapping
->string
),
563 mapping
->range_start
._unsigned
,
564 mapping
->range_end
._unsigned
,
565 overlap_query
->range_start
._unsigned
,
566 overlap_query
->range_end
._unsigned
);
571 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
572 struct enumeration_mapping
**b
)
574 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
578 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
579 struct enumeration_mapping
**b
)
581 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
585 int add_structure_field(GPtrArray
*fields
,
586 GHashTable
*field_name_to_index
,
587 struct bt_field_type_common
*field_type
, const char *field_name
)
590 GQuark name_quark
= g_quark_from_string(field_name
);
591 struct structure_field_common
*field
;
593 /* Make sure structure does not contain a field of the same name */
594 if (g_hash_table_lookup_extended(field_name_to_index
,
595 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
596 BT_LOGW("Structure or variant field type already contains a field type with this name: "
597 "field-name=\"%s\"", field_name
);
602 field
= g_new0(struct structure_field_common
, 1);
604 BT_LOGE_STR("Failed to allocate one structure/variant field type field.");
610 field
->name
= name_quark
;
611 field
->type
= field_type
;
612 g_hash_table_insert(field_name_to_index
,
613 GUINT_TO_POINTER(name_quark
), GUINT_TO_POINTER(fields
->len
));
614 g_ptr_array_add(fields
, field
);
615 BT_LOGV("Added structure/variant field type field: field-ft-addr=%p, "
616 "field-name=\"%s\"", field_type
, field_name
);
622 int bt_field_type_common_integer_validate(struct bt_field_type_common
*ft
)
625 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
627 if (int_ft
->mapped_clock_class
&& int_ft
->is_signed
) {
628 BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
629 "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
630 ft
, int_ft
->mapped_clock_class
,
631 bt_clock_class_get_name(int_ft
->mapped_clock_class
));
641 struct enumeration_mapping
*bt_field_type_common_enumeration_get_mapping_by_index(
642 struct bt_field_type_common
*ft
, uint64_t index
)
644 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
645 struct enumeration_mapping
*mapping
= NULL
;
647 if (index
>= enum_ft
->entries
->len
) {
648 BT_LOGW("Invalid parameter: index is out of bounds: "
649 "addr=%p, index=%" PRIu64
", count=%u",
650 ft
, index
, enum_ft
->entries
->len
);
654 mapping
= g_ptr_array_index(enum_ft
->entries
, index
);
661 * Note: This algorithm is O(n^2) vs number of enumeration mappings.
662 * Only used when freezing an enumeration.
665 void bt_field_type_common_enumeration_set_range_overlap(
666 struct bt_field_type_common_enumeration
*ft
)
671 BT_LOGV("Setting enumeration field type's overlap flag: addr=%p",
673 len
= ft
->entries
->len
;
674 is_signed
= bt_field_type_common_integer_is_signed(
675 BT_TO_COMMON(ft
->container_ft
));
677 for (i
= 0; i
< len
; i
++) {
678 for (j
= i
+ 1; j
< len
; j
++) {
679 struct enumeration_mapping
*mapping
[2];
681 mapping
[0] = bt_field_type_common_enumeration_get_mapping_by_index(
682 BT_TO_COMMON(ft
), i
);
683 mapping
[1] = bt_field_type_common_enumeration_get_mapping_by_index(
684 BT_TO_COMMON(ft
), j
);
686 if (mapping
[0]->range_start
._signed
687 <= mapping
[1]->range_end
._signed
688 && mapping
[0]->range_end
._signed
689 >= mapping
[1]->range_start
._signed
) {
690 ft
->has_overlapping_ranges
= BT_TRUE
;
694 if (mapping
[0]->range_start
._unsigned
695 <= mapping
[1]->range_end
._unsigned
696 && mapping
[0]->range_end
._unsigned
697 >= mapping
[1]->range_start
._unsigned
) {
698 ft
->has_overlapping_ranges
= BT_TRUE
;
706 if (ft
->has_overlapping_ranges
) {
707 BT_LOGV_STR("Enumeration field type has overlapping ranges.");
709 BT_LOGV_STR("Enumeration field type has no overlapping ranges.");
714 int bt_field_type_common_enumeration_validate_recursive(
715 struct bt_field_type_common
*ft
)
718 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
720 ret
= bt_field_type_common_integer_validate(
721 BT_TO_COMMON(enum_ft
->container_ft
));
723 BT_LOGW("Invalid enumeration field type: container type is invalid: "
724 "enum-ft-addr=%p, int-ft-addr=%p",
725 ft
, enum_ft
->container_ft
);
729 /* Ensure enum has entries */
730 if (enum_ft
->entries
->len
== 0) {
731 BT_LOGW("Invalid enumeration field type: no entries: "
742 int bt_field_type_common_sequence_validate_recursive(
743 struct bt_field_type_common
*ft
)
746 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
748 /* Length field name should be set at this point */
749 if (seq_ft
->length_field_name
->len
== 0) {
750 BT_LOGW("Invalid sequence field type: no length field name: "
756 ret
= bt_field_type_common_validate(seq_ft
->element_ft
);
758 BT_LOGW("Invalid sequence field type: invalid element field type: "
759 "seq-ft-addr=%p, element-ft-add=%p",
760 ft
, seq_ft
->element_ft
);
768 int bt_field_type_common_array_validate_recursive(
769 struct bt_field_type_common
*ft
)
772 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
774 ret
= bt_field_type_common_validate(array_ft
->element_ft
);
776 BT_LOGW("Invalid array field type: invalid element field type: "
777 "array-ft-addr=%p, element-ft-add=%p",
778 ft
, array_ft
->element_ft
);
785 int bt_field_type_common_structure_validate_recursive(
786 struct bt_field_type_common
*ft
)
789 struct bt_field_type_common
*child_ft
= NULL
;
790 int64_t field_count
=
791 bt_field_type_common_structure_get_field_count(ft
);
794 BT_ASSERT(field_count
>= 0);
796 for (i
= 0; i
< field_count
; ++i
) {
797 const char *field_name
;
799 ret
= bt_field_type_common_structure_get_field_by_index(ft
,
800 &field_name
, &child_ft
, i
);
802 ret
= bt_field_type_common_validate(child_ft
);
804 BT_LOGW("Invalid structure field type: "
805 "a contained field type is invalid: "
806 "struct-ft-addr=%p, field-ft-addr=%p, "
807 "field-name=\"%s\", field-index=%" PRId64
,
808 ft
, child_ft
, field_name
, i
);
821 bt_bool
bt_field_type_common_enumeration_has_overlapping_ranges(
822 struct bt_field_type_common_enumeration
*enum_ft
)
824 if (!enum_ft
->common
.frozen
) {
825 bt_field_type_common_enumeration_set_range_overlap(enum_ft
);
828 return enum_ft
->has_overlapping_ranges
;
832 int bt_field_type_common_variant_validate_recursive(
833 struct bt_field_type_common
*ft
)
837 struct bt_field_type_common
*child_ft
= NULL
;
838 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
841 if (var_ft
->tag_name
->len
== 0) {
842 BT_LOGW("Invalid variant field type: no tag field name: "
848 if (!var_ft
->tag_ft
) {
849 BT_LOGW("Invalid variant field type: no tag field type: "
850 "addr=%p, tag-field-name=\"%s\"", var_ft
,
851 var_ft
->tag_name
->str
);
856 if (bt_field_type_common_enumeration_has_overlapping_ranges(var_ft
->tag_ft
)) {
857 BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
858 "variant-ft-addr=%p, tag-field-name=\"%s\", "
859 "enum-ft-addr=%p", ft
, var_ft
->tag_name
->str
,
866 * It is valid to have a variant field type which does not have
867 * the fields corresponding to each label in the associated
870 * It is also valid to have variant field type fields which
871 * cannot be selected because the variant field type tag has no
872 * mapping named as such. This scenario, while not ideal, cannot
875 * If a non-existing field happens to be selected by an
876 * enumeration while reading a variant field, an error will be
877 * generated at that point (while reading the stream).
879 field_count
= bt_field_type_common_variant_get_field_count(ft
);
880 if (field_count
< 0) {
881 BT_LOGW("Invalid variant field type: no fields: "
882 "addr=%p, tag-field-name=\"%s\"",
883 ft
, var_ft
->tag_name
->str
);
888 for (i
= 0; i
< field_count
; ++i
) {
889 const char *field_name
;
891 ret
= bt_field_type_common_variant_get_field_by_index(ft
,
892 &field_name
, &child_ft
, i
);
894 ret
= bt_field_type_common_validate(child_ft
);
896 BT_LOGW("Invalid variant field type: "
897 "a contained field type is invalid: "
898 "variant-ft-addr=%p, tag-field-name=\"%s\", "
899 "field-ft-addr=%p, field-name=\"%s\", "
900 "field-index=%" PRId64
,
901 ft
, var_ft
->tag_name
->str
, child_ft
,
915 * This function validates a given field type without considering
916 * where this field type is located. It only validates the properties
917 * of the given field type and the properties of its children if
921 int bt_field_type_common_validate(struct bt_field_type_common
*ft
)
928 /* Already marked as valid */
932 if (ft
->methods
->validate
) {
933 ret
= ft
->methods
->validate(ft
);
936 if (ret
== 0 && ft
->frozen
) {
937 /* Field type is valid */
938 BT_LOGV("Marking field type as valid: addr=%p", ft
);
946 struct bt_field_type
*bt_field_type_integer_create(unsigned int size
)
948 struct bt_field_type_common_integer
*integer
= NULL
;
950 BT_LOGD("Creating integer field type object: size=%u", size
);
952 if (size
== 0 || size
> 64) {
953 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
958 integer
= g_new0(struct bt_field_type_common_integer
, 1);
960 BT_LOGE_STR("Failed to allocate one integer field type.");
964 bt_field_type_common_integer_initialize(BT_TO_COMMON(integer
),
965 size
, bt_field_type_common_integer_destroy
,
966 &bt_field_type_integer_methods
);
967 BT_LOGD("Created integer field type object: addr=%p, size=%u",
975 return (void *) integer
;
979 int bt_field_type_common_integer_get_size(struct bt_field_type_common
*ft
)
981 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
983 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
984 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
986 return (int) int_ft
->size
;
989 int bt_field_type_integer_get_size(struct bt_field_type
*ft
)
991 return bt_field_type_common_integer_get_size((void *) ft
);
995 bt_bool
bt_field_type_common_integer_is_signed(struct bt_field_type_common
*ft
)
997 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
999 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1000 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1002 return int_ft
->is_signed
;
1005 bt_bool
bt_field_type_integer_is_signed(struct bt_field_type
*ft
)
1007 return bt_field_type_common_integer_is_signed((void *) ft
);
1011 int bt_field_type_common_integer_set_is_signed(struct bt_field_type_common
*ft
,
1015 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1018 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1024 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1030 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1031 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1032 "addr=%p, ft-id=%s", ft
,
1033 bt_common_field_type_id_string(ft
->id
));
1038 int_ft
->is_signed
= !!is_signed
;
1039 BT_LOGV("Set integer field type's signedness: addr=%p, is-signed=%d",
1046 int bt_field_type_integer_set_is_signed(struct bt_field_type
*ft
,
1049 return bt_field_type_common_integer_set_is_signed((void *) ft
,
1054 int bt_field_type_common_integer_set_size(struct bt_field_type_common
*ft
,
1058 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1061 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1067 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1073 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1074 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1075 "addr=%p, ft-id=%s", ft
,
1076 bt_common_field_type_id_string(ft
->id
));
1081 if (size
== 0 || size
> 64) {
1082 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
1083 "addr=%p, size=%u", ft
, size
);
1088 int_ft
->size
= size
;
1089 BT_LOGV("Set integer field type's size: addr=%p, size=%u",
1096 int bt_field_type_integer_set_size(struct bt_field_type
*ft
,
1099 return bt_field_type_common_integer_set_size((void *) ft
, size
);
1103 enum bt_integer_base
bt_field_type_common_integer_get_base(
1104 struct bt_field_type_common
*ft
)
1106 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1108 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1109 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1111 return int_ft
->base
;
1114 enum bt_integer_base
bt_field_type_integer_get_base(
1115 struct bt_field_type
*ft
)
1117 return bt_field_type_common_integer_get_base((void *) ft
);
1121 int bt_field_type_common_integer_set_base(struct bt_field_type_common
*ft
,
1122 enum bt_integer_base base
)
1125 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1128 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1134 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1140 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1141 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1142 "addr=%p, ft-id=%s", ft
,
1143 bt_common_field_type_id_string(ft
->id
));
1149 case BT_INTEGER_BASE_UNSPECIFIED
:
1150 case BT_INTEGER_BASE_BINARY
:
1151 case BT_INTEGER_BASE_OCTAL
:
1152 case BT_INTEGER_BASE_DECIMAL
:
1153 case BT_INTEGER_BASE_HEXADECIMAL
:
1155 int_ft
->base
= base
;
1159 BT_LOGW("Invalid parameter: unknown integer field type base: "
1160 "addr=%p, base=%d", ft
, base
);
1164 BT_LOGV("Set integer field type's base: addr=%p, base=%s",
1165 ft
, bt_common_integer_base_string(base
));
1171 int bt_field_type_integer_set_base(struct bt_field_type
*ft
,
1172 enum bt_integer_base base
)
1174 return bt_field_type_common_integer_set_base((void *) ft
, base
);
1178 enum bt_string_encoding
bt_field_type_common_integer_get_encoding(
1179 struct bt_field_type_common
*ft
)
1181 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1183 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1184 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1186 return int_ft
->encoding
;
1189 enum bt_string_encoding
bt_field_type_integer_get_encoding(
1190 struct bt_field_type
*ft
)
1192 return bt_field_type_common_integer_get_encoding((void *) ft
);
1196 int bt_field_type_common_integer_set_encoding(struct bt_field_type_common
*ft
,
1197 enum bt_string_encoding encoding
)
1200 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1203 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1209 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1215 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1216 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1217 "addr=%p, ft-id=%s", ft
,
1218 bt_common_field_type_id_string(ft
->id
));
1223 if (encoding
!= BT_STRING_ENCODING_UTF8
&&
1224 encoding
!= BT_STRING_ENCODING_ASCII
&&
1225 encoding
!= BT_STRING_ENCODING_NONE
) {
1226 BT_LOGW("Invalid parameter: unknown string encoding: "
1227 "addr=%p, encoding=%d", ft
, encoding
);
1232 int_ft
->encoding
= encoding
;
1233 BT_LOGV("Set integer field type's encoding: addr=%p, encoding=%s",
1234 ft
, bt_common_string_encoding_string(encoding
));
1240 int bt_field_type_integer_set_encoding(struct bt_field_type
*ft
,
1241 enum bt_string_encoding encoding
)
1243 return bt_field_type_common_integer_set_encoding((void *) ft
, encoding
);
1247 struct bt_clock_class
*bt_field_type_common_integer_get_mapped_clock_class(
1248 struct bt_field_type_common
*ft
)
1250 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1252 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1253 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_INTEGER
,
1255 return bt_get(int_ft
->mapped_clock_class
);
1258 struct bt_clock_class
*bt_field_type_integer_get_mapped_clock_class(
1259 struct bt_field_type
*ft
)
1261 return bt_field_type_common_integer_get_mapped_clock_class((void *) ft
);
1265 int bt_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
1266 struct bt_field_type_common
*ft
,
1267 struct bt_clock_class
*clock_class
)
1269 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
1273 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
1278 if (ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1279 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1280 "addr=%p, ft-id=%s", ft
,
1281 bt_common_field_type_id_string(ft
->id
));
1285 if (!bt_clock_class_is_valid(clock_class
)) {
1286 BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
1287 "clock-class-addr=%p, clock-class-name=\"%s\"",
1289 bt_clock_class_get_name(clock_class
));
1294 bt_put(int_ft
->mapped_clock_class
);
1295 int_ft
->mapped_clock_class
= bt_get(clock_class
);
1296 BT_LOGV("Set integer field type's mapped clock class: ft-addr=%p, "
1297 "clock-class-addr=%p, clock-class-name=\"%s\"",
1298 ft
, clock_class
, bt_clock_class_get_name(clock_class
));
1305 int bt_field_type_common_integer_set_mapped_clock_class(
1306 struct bt_field_type_common
*ft
,
1307 struct bt_clock_class
*clock_class
)
1312 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1318 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1324 ret
= bt_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
1331 int bt_field_type_integer_set_mapped_clock_class(struct bt_field_type
*ft
,
1332 struct bt_clock_class
*clock_class
)
1334 return bt_field_type_common_integer_set_mapped_clock_class((void *) ft
,
1339 void bt_field_type_enum_iter_destroy(struct bt_object
*obj
)
1341 struct bt_field_type_enumeration_mapping_iterator
*iter
=
1343 struct bt_field_type_enumeration_mapping_iterator
,
1346 BT_LOGD("Destroying enumeration field type mapping iterator: addr=%p",
1348 BT_LOGD_STR("Putting parent enumeration field type.");
1349 bt_put(iter
->enumeration_ft
);
1354 struct bt_field_type_enumeration_mapping_iterator
*
1355 bt_field_type_common_enumeration_find_mappings_type(
1356 struct bt_field_type_common
*ft
,
1357 enum bt_field_type_enumeration_mapping_iterator_type iterator_type
)
1359 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1361 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1362 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
,
1364 iter
= g_new0(struct bt_field_type_enumeration_mapping_iterator
, 1);
1366 BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
1370 bt_object_init(&iter
->base
, bt_field_type_enum_iter_destroy
);
1371 iter
->enumeration_ft
= bt_get(ft
);
1373 iter
->type
= iterator_type
;
1380 struct bt_field_type_enumeration_mapping_iterator
*
1381 bt_field_type_common_enumeration_find_mappings_by_name(
1382 struct bt_field_type_common
*ft
, const char *name
)
1384 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1386 iter
= bt_field_type_common_enumeration_find_mappings_type(
1387 ft
, ITERATOR_BY_NAME
);
1389 BT_LOGW("Cannot create enumeration field type mapping iterator: "
1390 "ft-addr=%p, mapping-name=\"%s\"", ft
, name
);
1394 iter
->u
.name_quark
= g_quark_try_string(name
);
1395 if (!iter
->u
.name_quark
) {
1397 * No results are possible, set the iterator's position at the
1400 iter
->index
= iter
->enumeration_ft
->entries
->len
;
1410 struct bt_field_type_enumeration_mapping_iterator
*
1411 bt_field_type_enumeration_find_mappings_by_name(
1412 struct bt_field_type
*ft
, const char *name
)
1414 return bt_field_type_common_enumeration_find_mappings_by_name(
1418 int bt_field_type_enumeration_mapping_iterator_next(
1419 struct bt_field_type_enumeration_mapping_iterator
*iter
)
1421 struct bt_field_type_common_enumeration
*enum_ft
= iter
->enumeration_ft
;
1422 int i
, ret
= 0, len
;
1424 BT_ASSERT_PRE_NON_NULL(iter
, "Enumeration field type mapping iterator");
1425 len
= enum_ft
->entries
->len
;
1426 for (i
= iter
->index
+ 1; i
< len
; i
++) {
1427 struct enumeration_mapping
*mapping
=
1428 bt_field_type_common_enumeration_get_mapping_by_index(
1429 BT_TO_COMMON(enum_ft
), i
);
1431 switch (iter
->type
) {
1432 case ITERATOR_BY_NAME
:
1433 if (mapping
->string
== iter
->u
.name_quark
) {
1438 case ITERATOR_BY_SIGNED_VALUE
:
1440 int64_t value
= iter
->u
.signed_value
;
1442 if (value
>= mapping
->range_start
._signed
&&
1443 value
<= mapping
->range_end
._signed
) {
1449 case ITERATOR_BY_UNSIGNED_VALUE
:
1451 uint64_t value
= iter
->u
.unsigned_value
;
1453 if (value
>= mapping
->range_start
._unsigned
&&
1454 value
<= mapping
->range_end
._unsigned
) {
1461 BT_LOGF("Invalid enumeration field type mapping iterator type: "
1462 "type=%d", iter
->type
);
1474 struct bt_field_type_enumeration_mapping_iterator
*
1475 bt_field_type_common_enumeration_signed_find_mappings_by_value(
1476 struct bt_field_type_common
*ft
, int64_t value
)
1478 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1480 iter
= bt_field_type_common_enumeration_find_mappings_type(
1481 ft
, ITERATOR_BY_SIGNED_VALUE
);
1483 BT_LOGW("Cannot create enumeration field type mapping iterator: "
1484 "ft-addr=%p, value=%" PRId64
, ft
, value
);
1488 if (bt_field_type_common_integer_is_signed(
1489 BT_TO_COMMON(iter
->enumeration_ft
->container_ft
)) != 1) {
1490 BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
1491 "enum-ft-addr=%p, int-ft-addr=%p",
1492 ft
, iter
->enumeration_ft
->container_ft
);
1496 iter
->u
.signed_value
= value
;
1504 struct bt_field_type_enumeration_mapping_iterator
*
1505 bt_field_type_enumeration_signed_find_mappings_by_value(
1506 struct bt_field_type
*ft
, int64_t value
)
1508 return bt_field_type_common_enumeration_signed_find_mappings_by_value(
1509 (void *) ft
, value
);
1513 struct bt_field_type_enumeration_mapping_iterator
*
1514 bt_field_type_common_enumeration_unsigned_find_mappings_by_value(
1515 struct bt_field_type_common
*ft
, uint64_t value
)
1517 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1519 iter
= bt_field_type_common_enumeration_find_mappings_type(
1520 ft
, ITERATOR_BY_UNSIGNED_VALUE
);
1522 BT_LOGW("Cannot create enumeration field type mapping iterator: "
1523 "ft-addr=%p, value=%" PRIu64
, ft
, value
);
1527 if (bt_field_type_common_integer_is_signed(
1528 BT_TO_COMMON(iter
->enumeration_ft
->container_ft
)) != 0) {
1529 BT_LOGW("Invalid parameter: enumeration field type is signed: "
1530 "enum-ft-addr=%p, int-ft-addr=%p",
1531 ft
, iter
->enumeration_ft
->container_ft
);
1535 iter
->u
.unsigned_value
= value
;
1543 struct bt_field_type_enumeration_mapping_iterator
*
1544 bt_field_type_enumeration_unsigned_find_mappings_by_value(
1545 struct bt_field_type
*ft
, uint64_t value
)
1547 return bt_field_type_common_enumeration_unsigned_find_mappings_by_value(
1548 (void *) ft
, value
);
1551 int bt_field_type_enumeration_mapping_iterator_signed_get(
1552 struct bt_field_type_enumeration_mapping_iterator
*iter
,
1553 const char **mapping_name
, int64_t *range_begin
,
1556 BT_ASSERT_PRE_NON_NULL(iter
, "Enumeration field type mapping iterator");
1557 BT_ASSERT_PRE(iter
->index
!= -1,
1558 "Invalid enumeration field type mapping iterator access: "
1559 "addr=%p, position=-1", iter
);
1560 return bt_field_type_common_enumeration_signed_get_mapping_by_index(
1561 (void *) iter
->enumeration_ft
, iter
->index
,
1562 mapping_name
, range_begin
, range_end
);
1565 int bt_field_type_enumeration_mapping_iterator_unsigned_get(
1566 struct bt_field_type_enumeration_mapping_iterator
*iter
,
1567 const char **mapping_name
, uint64_t *range_begin
,
1568 uint64_t *range_end
)
1570 BT_ASSERT_PRE_NON_NULL(iter
, "Enumeration field type mapping iterator");
1571 BT_ASSERT_PRE(iter
->index
!= -1,
1572 "Invalid enumeration field type mapping iterator access: "
1573 "addr=%p, position=-1", iter
);
1574 return bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
1575 (void *) iter
->enumeration_ft
, iter
->index
,
1576 mapping_name
, range_begin
, range_end
);
1580 int bt_field_type_common_enumeration_signed_get_mapping_by_index(
1581 struct bt_field_type_common
*ft
, uint64_t index
,
1582 const char **mapping_name
, int64_t *range_begin
,
1586 struct enumeration_mapping
*mapping
;
1588 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1589 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
,
1590 BT_FIELD_TYPE_ID_ENUM
, "Field type");
1591 mapping
= bt_field_type_common_enumeration_get_mapping_by_index(ft
,
1594 /* bt_field_type_common_enumeration_get_mapping_by_index() logs errors */
1600 *mapping_name
= g_quark_to_string(mapping
->string
);
1601 BT_ASSERT(*mapping_name
);
1605 *range_begin
= mapping
->range_start
._signed
;
1609 *range_end
= mapping
->range_end
._signed
;
1616 int bt_field_type_enumeration_signed_get_mapping_by_index(
1617 struct bt_field_type
*ft
, uint64_t index
,
1618 const char **mapping_name
, int64_t *range_begin
,
1621 return bt_field_type_common_enumeration_signed_get_mapping_by_index(
1622 (void *) ft
, index
, mapping_name
, range_begin
, range_end
);
1626 int bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
1627 struct bt_field_type_common
*ft
, uint64_t index
,
1628 const char **mapping_name
, uint64_t *range_begin
,
1629 uint64_t *range_end
)
1632 struct enumeration_mapping
*mapping
;
1634 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1635 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
, "Field type");
1636 mapping
= bt_field_type_common_enumeration_get_mapping_by_index(
1639 /* bt_field_type_common_enumeration_get_mapping_by_index() reports any error */
1645 *mapping_name
= g_quark_to_string(mapping
->string
);
1646 BT_ASSERT(*mapping_name
);
1650 *range_begin
= mapping
->range_start
._unsigned
;
1654 *range_end
= mapping
->range_end
._unsigned
;
1661 int bt_field_type_enumeration_unsigned_get_mapping_by_index(
1662 struct bt_field_type
*ft
, uint64_t index
,
1663 const char **mapping_name
, uint64_t *range_begin
,
1664 uint64_t *range_end
)
1666 return bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
1667 (void *) ft
, index
, mapping_name
, range_begin
, range_end
);
1670 struct bt_field_type
*bt_field_type_enumeration_create(
1671 struct bt_field_type
*container_ft
)
1673 struct bt_field_type_common_enumeration
*enumeration
= NULL
;
1674 struct bt_field_type_common
*int_ft
= (void *) container_ft
;
1676 BT_LOGD("Creating enumeration field type object: int-ft-addr=%p",
1679 if (!container_ft
) {
1680 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1684 if (int_ft
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1685 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
1686 "container-ft-addr=%p, container-ft-id=%s",
1687 container_ft
, bt_common_field_type_id_string(int_ft
->id
));
1691 enumeration
= g_new0(struct bt_field_type_common_enumeration
, 1);
1693 BT_LOGE_STR("Failed to allocate one enumeration field type.");
1697 bt_field_type_common_enumeration_initialize(BT_TO_COMMON(enumeration
),
1698 int_ft
, bt_field_type_common_enumeration_destroy_recursive
,
1699 &bt_field_type_enumeration_methods
);
1700 BT_LOGD("Created enumeration field type object: addr=%p, "
1701 "int-ft-addr=%p, int-ft-size=%u",
1702 enumeration
, container_ft
,
1703 bt_field_type_integer_get_size(container_ft
));
1707 BT_PUT(enumeration
);
1710 return (void *) enumeration
;
1714 struct bt_field_type_common
*bt_field_type_common_enumeration_get_container_field_type(
1715 struct bt_field_type_common
*ft
)
1717 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1719 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1720 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
, "Field type");
1721 return bt_get(enum_ft
->container_ft
);
1724 struct bt_field_type
*bt_field_type_enumeration_get_container_field_type(
1725 struct bt_field_type
*ft
)
1727 return (void *) bt_field_type_common_enumeration_get_container_field_type(
1732 int bt_field_type_common_enumeration_signed_add_mapping(
1733 struct bt_field_type_common
*ft
, const char *string
,
1734 int64_t range_start
, int64_t range_end
)
1737 GQuark mapping_name
;
1738 struct enumeration_mapping
*mapping
;
1739 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1740 char *escaped_string
;
1743 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1749 BT_LOGW_STR("Invalid parameter: string is NULL.");
1755 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1761 if (ft
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1762 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1763 "addr=%p, ft-id=%s", ft
,
1764 bt_common_field_type_id_string(ft
->id
));
1769 if (range_end
< range_start
) {
1770 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1771 "addr=%p, range-start=%" PRId64
", range-end=%" PRId64
,
1772 ft
, range_start
, range_end
);
1777 if (strlen(string
) == 0) {
1778 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1779 "enum-ft-addr=%p, mapping-name-addr=%p", ft
,
1785 escaped_string
= g_strescape(string
, NULL
);
1786 if (!escaped_string
) {
1787 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1788 "mapping-name-addr=%p, mapping-name=\"%s\"",
1789 ft
, string
, string
);
1794 mapping
= g_new(struct enumeration_mapping
, 1);
1796 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1800 mapping_name
= g_quark_from_string(escaped_string
);
1801 *mapping
= (struct enumeration_mapping
) {
1802 .range_start
._signed
= range_start
,
1803 .range_end
._signed
= range_end
,
1804 .string
= mapping_name
,
1806 g_ptr_array_add(enum_ft
->entries
, mapping
);
1807 g_ptr_array_sort(enum_ft
->entries
,
1808 (GCompareFunc
) compare_enumeration_mappings_signed
);
1809 BT_LOGV("Added mapping to signed enumeration field type: addr=%p, "
1810 "name=\"%s\", range-start=%" PRId64
", "
1811 "range-end=%" PRId64
,
1812 ft
, string
, range_start
, range_end
);
1815 free(escaped_string
);
1821 int bt_field_type_enumeration_signed_add_mapping(
1822 struct bt_field_type
*ft
, const char *string
,
1823 int64_t range_start
, int64_t range_end
)
1825 return bt_field_type_common_enumeration_signed_add_mapping(
1826 (void *) ft
, string
, range_start
, range_end
);
1830 int bt_field_type_common_enumeration_unsigned_add_mapping(
1831 struct bt_field_type_common
*ft
, const char *string
,
1832 uint64_t range_start
, uint64_t range_end
)
1835 GQuark mapping_name
;
1836 struct enumeration_mapping
*mapping
;
1837 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1838 char *escaped_string
;
1841 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1847 BT_LOGW_STR("Invalid parameter: string is NULL.");
1853 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1859 if (ft
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1860 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1861 "addr=%p, ft-id=%s", ft
,
1862 bt_common_field_type_id_string(ft
->id
));
1867 if (range_end
< range_start
) {
1868 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1869 "addr=%p, range-start=%" PRIu64
", range-end=%" PRIu64
,
1870 ft
, range_start
, range_end
);
1875 if (strlen(string
) == 0) {
1876 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1877 "enum-ft-addr=%p, mapping-name-addr=%p", ft
,
1883 escaped_string
= g_strescape(string
, NULL
);
1884 if (!escaped_string
) {
1885 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1886 "mapping-name-addr=%p, mapping-name=\"%s\"",
1887 ft
, string
, string
);
1892 mapping
= g_new(struct enumeration_mapping
, 1);
1894 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1898 mapping_name
= g_quark_from_string(escaped_string
);
1899 *mapping
= (struct enumeration_mapping
) {
1900 .range_start
._unsigned
= range_start
,
1901 .range_end
._unsigned
= range_end
,
1902 .string
= mapping_name
,
1904 g_ptr_array_add(enum_ft
->entries
, mapping
);
1905 g_ptr_array_sort(enum_ft
->entries
,
1906 (GCompareFunc
) compare_enumeration_mappings_unsigned
);
1907 BT_LOGV("Added mapping to unsigned enumeration field type: addr=%p, "
1908 "name=\"%s\", range-start=%" PRIu64
", "
1909 "range-end=%" PRIu64
,
1910 ft
, string
, range_start
, range_end
);
1913 free(escaped_string
);
1919 int bt_field_type_enumeration_unsigned_add_mapping(
1920 struct bt_field_type
*ft
, const char *string
,
1921 uint64_t range_start
, uint64_t range_end
)
1923 return bt_field_type_common_enumeration_unsigned_add_mapping(
1924 (void *) ft
, string
, range_start
, range_end
);
1928 int64_t bt_field_type_common_enumeration_get_mapping_count(
1929 struct bt_field_type_common
*ft
)
1931 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
1933 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1934 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ENUM
, "Field type");
1935 return (int64_t) enum_ft
->entries
->len
;
1938 int64_t bt_field_type_enumeration_get_mapping_count(
1939 struct bt_field_type
*ft
)
1941 return bt_field_type_common_enumeration_get_mapping_count((void *) ft
);
1944 struct bt_field_type
*bt_field_type_floating_point_create(void)
1946 struct bt_field_type_common_floating_point
*floating_point
=
1947 g_new0(struct bt_field_type_common_floating_point
, 1);
1949 BT_LOGD_STR("Creating floating point number field type object.");
1951 if (!floating_point
) {
1952 BT_LOGE_STR("Failed to allocate one floating point number field type.");
1956 bt_field_type_common_floating_point_initialize(
1957 BT_TO_COMMON(floating_point
),
1958 bt_field_type_common_floating_point_destroy
,
1959 &bt_field_type_floating_point_methods
);
1960 BT_LOGD("Created floating point number field type object: addr=%p, "
1961 "exp-size=%u, mant-size=%u", floating_point
,
1962 floating_point
->exp_dig
, floating_point
->mant_dig
);
1965 return (void *) floating_point
;
1969 int bt_field_type_common_floating_point_get_exponent_digits(
1970 struct bt_field_type_common
*ft
)
1972 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
1974 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1975 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_FLOAT
,
1977 return (int) flt_ft
->exp_dig
;
1980 int bt_field_type_floating_point_get_exponent_digits(
1981 struct bt_field_type
*ft
)
1983 return bt_field_type_common_floating_point_get_exponent_digits(
1988 int bt_field_type_common_floating_point_set_exponent_digits(
1989 struct bt_field_type_common
*ft
,
1990 unsigned int exponent_digits
)
1993 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
1996 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2002 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2008 if (ft
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
2009 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
2010 "addr=%p, ft-id=%s", ft
,
2011 bt_common_field_type_id_string(ft
->id
));
2016 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
2017 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
2019 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
2020 BT_LOGW("Invalid parameter: invalid exponent size: "
2021 "addr=%p, exp-size=%u", ft
, exponent_digits
);
2026 flt_ft
->exp_dig
= exponent_digits
;
2027 BT_LOGV("Set floating point number field type's exponent size: addr=%p, "
2028 "exp-size=%u", ft
, exponent_digits
);
2034 int bt_field_type_floating_point_set_exponent_digits(
2035 struct bt_field_type
*ft
, unsigned int exponent_digits
)
2037 return bt_field_type_common_floating_point_set_exponent_digits(
2038 (void *) ft
, exponent_digits
);
2042 int bt_field_type_common_floating_point_get_mantissa_digits(
2043 struct bt_field_type_common
*ft
)
2045 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
2047 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2048 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_FLOAT
,
2050 return (int) flt_ft
->mant_dig
;
2053 int bt_field_type_floating_point_get_mantissa_digits(
2054 struct bt_field_type
*ft
)
2056 return bt_field_type_common_floating_point_get_mantissa_digits(
2061 int bt_field_type_common_floating_point_set_mantissa_digits(
2062 struct bt_field_type_common
*ft
, unsigned int mantissa_digits
)
2065 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
2068 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2074 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2080 if (ft
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
2081 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
2082 "addr=%p, ft-id=%s", ft
,
2083 bt_common_field_type_id_string(ft
->id
));
2088 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
2089 (mantissa_digits
!= DBL_MANT_DIG
) &&
2090 (mantissa_digits
!= LDBL_MANT_DIG
)) {
2091 BT_LOGW("Invalid parameter: invalid mantissa size: "
2092 "addr=%p, mant-size=%u", ft
, mantissa_digits
);
2097 flt_ft
->mant_dig
= mantissa_digits
;
2098 BT_LOGV("Set floating point number field type's mantissa size: addr=%p, "
2099 "mant-size=%u", ft
, mantissa_digits
);
2105 int bt_field_type_floating_point_set_mantissa_digits(
2106 struct bt_field_type
*ft
, unsigned int mantissa_digits
)
2108 return bt_field_type_common_floating_point_set_mantissa_digits(
2109 (void *) ft
, mantissa_digits
);
2112 struct bt_field_type
*bt_field_type_structure_create(void)
2114 struct bt_field_type_common_structure
*structure
=
2115 g_new0(struct bt_field_type_common_structure
, 1);
2117 BT_LOGD_STR("Creating structure field type object.");
2120 BT_LOGE_STR("Failed to allocate one structure field type.");
2124 bt_field_type_common_structure_initialize(BT_TO_COMMON(structure
),
2125 bt_field_type_common_structure_destroy_recursive
,
2126 &bt_field_type_structure_methods
);
2127 BT_LOGD("Created structure field type object: addr=%p",
2135 return (void *) structure
;
2139 int bt_field_type_common_structure_replace_field(
2140 struct bt_field_type_common
*ft
,
2141 const char *field_name
,
2142 struct bt_field_type_common
*field_type
)
2145 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2150 BT_ASSERT(field_name
);
2151 BT_ASSERT(field_type
);
2152 BT_ASSERT(ft
->id
== BT_FIELD_TYPE_ID_STRUCT
);
2153 name_quark
= g_quark_from_string(field_name
);
2155 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
2156 struct structure_field_common
*field
= g_ptr_array_index(
2157 struct_ft
->fields
, i
);
2159 if (field
->name
== name_quark
) {
2160 bt_put(field
->type
);
2161 field
->type
= bt_get(field_type
);
2169 int bt_field_type_common_structure_add_field(struct bt_field_type_common
*ft
,
2170 struct bt_field_type_common
*field_type
,
2171 const char *field_name
)
2174 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2177 * TODO: check that `field_type` does not contain `type`,
2181 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2187 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2193 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2199 if (ft
->id
!= BT_FIELD_TYPE_ID_STRUCT
) {
2200 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2201 "addr=%p, ft-id=%s", ft
,
2202 bt_common_field_type_id_string(ft
->id
));
2207 if (ft
== field_type
) {
2208 BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
2214 if (add_structure_field(struct_ft
->fields
,
2215 struct_ft
->field_name_to_index
, field_type
, field_name
)) {
2216 BT_LOGW("Cannot add field to structure field type: "
2217 "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2218 ft
, field_type
, field_name
);
2223 BT_LOGV("Added structure field type field: struct-ft-addr=%p, "
2224 "field-ft-addr=%p, field-name=\"%s\"", ft
,
2225 field_type
, field_name
);
2231 int bt_field_type_structure_add_field(struct bt_field_type
*ft
,
2232 struct bt_field_type
*field_type
,
2233 const char *field_name
)
2235 return bt_field_type_common_structure_add_field((void *) ft
,
2236 (void *) field_type
, field_name
);
2240 int64_t bt_field_type_common_structure_get_field_count(
2241 struct bt_field_type_common
*ft
)
2243 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2245 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2246 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
2248 return (int64_t) struct_ft
->fields
->len
;
2251 int64_t bt_field_type_structure_get_field_count(struct bt_field_type
*ft
)
2253 return bt_field_type_common_structure_get_field_count((void *) ft
);
2257 int bt_field_type_common_structure_get_field_by_index(
2258 struct bt_field_type_common
*ft
,
2259 const char **field_name
,
2260 struct bt_field_type_common
**field_type
, uint64_t index
)
2262 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2263 struct structure_field_common
*field
;
2265 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2266 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
2268 BT_ASSERT_PRE(index
< struct_ft
->fields
->len
,
2269 "Index is out of bounds: index=%" PRIu64
", "
2270 "count=%u, %![ft-]+_F",
2271 index
, struct_ft
->fields
->len
, ft
);
2272 field
= g_ptr_array_index(struct_ft
->fields
, index
);
2275 *field_type
= field
->type
;
2276 bt_get(field
->type
);
2280 *field_name
= g_quark_to_string(field
->name
);
2281 BT_ASSERT(*field_name
);
2287 int bt_field_type_structure_get_field_by_index(
2288 struct bt_field_type
*ft
,
2289 const char **field_name
,
2290 struct bt_field_type
**field_type
, uint64_t index
)
2292 return bt_field_type_common_structure_get_field_by_index(
2293 (void *) ft
, field_name
, (void *) field_type
, index
);
2297 struct bt_field_type_common
*bt_field_type_common_structure_get_field_type_by_name(
2298 struct bt_field_type_common
*ft
, const char *name
)
2302 struct structure_field_common
*field
;
2303 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
2304 struct bt_field_type_common
*field_type
= NULL
;
2306 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2307 BT_ASSERT_PRE_NON_NULL(name
, "Name");
2308 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
2310 name_quark
= g_quark_try_string(name
);
2312 BT_LOGV("No such structure field type field name: "
2313 "ft-addr=%p, field-name=\"%s\"",
2318 if (!g_hash_table_lookup_extended(struct_ft
->field_name_to_index
,
2319 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*) &index
)) {
2320 BT_LOGV("No such structure field type field name: "
2321 "ft-addr=%p, field-name=\"%s\"",
2326 field
= struct_ft
->fields
->pdata
[index
];
2327 field_type
= field
->type
;
2334 struct bt_field_type
*bt_field_type_structure_get_field_type_by_name(
2335 struct bt_field_type
*ft
, const char *name
)
2337 return (void *) bt_field_type_common_structure_get_field_type_by_name(
2341 struct bt_field_type
*bt_field_type_variant_create(
2342 struct bt_field_type
*tag_ft
, const char *tag_name
)
2344 struct bt_field_type_common_variant
*var_ft
= NULL
;
2346 BT_LOGD("Creating variant field type object: "
2347 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2350 if (tag_name
&& !bt_identifier_is_valid(tag_name
)) {
2351 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2352 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2357 var_ft
= g_new0(struct bt_field_type_common_variant
, 1);
2359 BT_LOGE_STR("Failed to allocate one variant field type.");
2363 bt_field_type_common_variant_initialize(BT_TO_COMMON(var_ft
),
2364 (void *) tag_ft
, tag_name
,
2365 bt_field_type_common_variant_destroy_recursive
,
2366 &bt_field_type_variant_methods
);
2367 BT_LOGD("Created variant field type object: addr=%p, "
2368 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2369 var_ft
, tag_ft
, tag_name
);
2376 return (void *) var_ft
;
2380 struct bt_field_type_common
*bt_field_type_common_variant_get_tag_field_type(
2381 struct bt_field_type_common
*ft
)
2383 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2384 struct bt_field_type_common
*tag_ft
= NULL
;
2386 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2387 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2390 if (!var_ft
->tag_ft
) {
2391 BT_LOGV("Variant field type has no tag field type: "
2396 tag_ft
= bt_get(var_ft
->tag_ft
);
2402 struct bt_field_type
*bt_field_type_variant_get_tag_field_type(
2403 struct bt_field_type
*ft
)
2405 return (void *) bt_field_type_common_variant_get_tag_field_type(
2410 const char *bt_field_type_common_variant_get_tag_name(
2411 struct bt_field_type_common
*ft
)
2413 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2414 const char *tag_name
= NULL
;
2416 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2417 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2420 if (var_ft
->tag_name
->len
== 0) {
2421 BT_LOGV("Variant field type has no tag field name: "
2426 tag_name
= var_ft
->tag_name
->str
;
2432 const char *bt_field_type_variant_get_tag_name(struct bt_field_type
*ft
)
2434 return bt_field_type_common_variant_get_tag_name((void *) ft
);
2438 int bt_field_type_common_variant_set_tag_name(
2439 struct bt_field_type_common
*ft
, const char *name
)
2442 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2445 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2451 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2457 if (ft
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2458 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2459 "addr=%p, ft-id=%s", ft
, bt_common_field_type_id_string(ft
->id
));
2464 if (!bt_identifier_is_valid(name
)) {
2465 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2466 "variant-ft-addr=%p, tag-field-name=\"%s\"",
2472 g_string_assign(var_ft
->tag_name
, name
);
2473 BT_LOGV("Set variant field type's tag field name: addr=%p, "
2474 "tag-field-name=\"%s\"", ft
, name
);
2480 int bt_field_type_variant_set_tag_name(
2481 struct bt_field_type
*ft
, const char *name
)
2483 return bt_field_type_common_variant_set_tag_name((void *) ft
, name
);
2487 int bt_field_type_common_variant_add_field(struct bt_field_type_common
*ft
,
2488 struct bt_field_type_common
*field_type
,
2489 const char *field_name
)
2493 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2494 GQuark field_name_quark
= g_quark_from_string(field_name
);
2497 * TODO: check that `field_type` does not contain `type`,
2501 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2507 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2513 if (ft
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2514 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2515 "addr=%p, ft-id=%s", ft
,
2516 bt_common_field_type_id_string(ft
->id
));
2521 if (ft
== field_type
) {
2522 BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
2528 /* The user has explicitly provided a tag; validate against it. */
2529 if (var_ft
->tag_ft
) {
2532 /* Make sure this name is present in the enum tag */
2533 for (i
= 0; i
< var_ft
->tag_ft
->entries
->len
; i
++) {
2534 struct enumeration_mapping
*mapping
=
2535 g_ptr_array_index(var_ft
->tag_ft
->entries
, i
);
2537 if (mapping
->string
== field_name_quark
) {
2544 /* Validation failed */
2545 BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
2546 "variant-ft-addr=%p, tag-ft-addr=%p, "
2547 "tag-field-name=\"%s\""
2548 "field-ft-addr=%p, field-name=\"%s\"",
2549 ft
, var_ft
->tag_ft
, var_ft
->tag_name
->str
,
2550 field_type
, field_name
);
2556 if (add_structure_field(var_ft
->fields
, var_ft
->field_name_to_index
,
2557 field_type
, field_name
)) {
2558 BT_LOGW("Cannot add field to variant field type: "
2559 "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2560 ft
, field_type
, field_name
);
2565 BT_LOGV("Added variant field type field: variant-ft-addr=%p, "
2566 "field-ft-addr=%p, field-name=\"%s\"", ft
,
2567 field_type
, field_name
);
2573 int bt_field_type_variant_add_field(struct bt_field_type
*ft
,
2574 struct bt_field_type
*field_type
,
2575 const char *field_name
)
2577 return bt_field_type_common_variant_add_field((void *) ft
,
2578 (void *) field_type
, field_name
);
2582 struct bt_field_type_common
*bt_field_type_common_variant_get_field_type_by_name(
2583 struct bt_field_type_common
*ft
,
2584 const char *field_name
)
2588 struct structure_field_common
*field
;
2589 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2590 struct bt_field_type_common
*field_type
= NULL
;
2592 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2593 BT_ASSERT_PRE_NON_NULL(field_name
, "Name");
2594 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2596 name_quark
= g_quark_try_string(field_name
);
2598 BT_LOGV("No such variant field type field name: "
2599 "ft-addr=%p, field-name=\"%s\"",
2604 if (!g_hash_table_lookup_extended(var_ft
->field_name_to_index
,
2605 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*) &index
)) {
2606 BT_LOGV("No such variant field type field name: "
2607 "ft-addr=%p, field-name=\"%s\"",
2612 field
= g_ptr_array_index(var_ft
->fields
, index
);
2613 field_type
= field
->type
;
2620 struct bt_field_type
*bt_field_type_variant_get_field_type_by_name(
2621 struct bt_field_type
*ft
,
2622 const char *field_name
)
2624 return (void *) bt_field_type_common_variant_get_field_type_by_name(
2625 (void *) ft
, field_name
);
2629 struct bt_field_type_common
*bt_field_type_common_variant_get_field_type_from_tag(
2630 struct bt_field_type_common
*ft
,
2631 struct bt_field_common
*tag_field
,
2632 bt_field_common_create_func field_create_func
)
2635 const char *enum_value
;
2636 struct bt_field_type_common
*field_type
= NULL
;
2637 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
2639 BT_ASSERT_PRE_NON_NULL(ft
, "Variant field type");
2640 BT_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
2641 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2643 iter
= bt_field_common_enumeration_get_mappings(tag_field
,
2645 ret
= bt_field_type_enumeration_mapping_iterator_next(iter
);
2647 BT_LOGW("Cannot get enumeration field type mapping iterator from enumeration field: "
2648 "enum-field-addr=%p", tag_field
);
2652 ret
= bt_field_type_enumeration_mapping_iterator_signed_get(iter
,
2653 &enum_value
, NULL
, NULL
);
2655 BT_LOGW("Cannot get enumeration field type mapping iterator's current mapping: "
2656 "iter-addr=%p", iter
);
2660 field_type
= bt_field_type_common_variant_get_field_type_by_name(
2668 struct bt_field_type
*bt_field_type_variant_get_field_type_from_tag(
2669 struct bt_field_type
*ft
,
2670 struct bt_field
*tag_field
)
2672 return (void *) bt_field_type_common_variant_get_field_type_from_tag(
2673 (void *) ft
, (void *) tag_field
,
2674 (bt_field_common_create_func
) bt_field_create
);
2678 int64_t bt_field_type_common_variant_get_field_count(
2679 struct bt_field_type_common
*ft
)
2681 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2683 BT_ASSERT_PRE_NON_NULL(ft
, "Variant field type");
2684 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2686 return (int64_t) var_ft
->fields
->len
;
2689 int64_t bt_field_type_variant_get_field_count(struct bt_field_type
*ft
)
2691 return bt_field_type_common_variant_get_field_count((void *) ft
);
2695 int bt_field_type_common_variant_get_field_by_index(
2696 struct bt_field_type_common
*ft
,
2697 const char **field_name
,
2698 struct bt_field_type_common
**field_type
, uint64_t index
)
2700 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
2701 struct structure_field_common
*field
;
2703 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2704 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
2706 BT_ASSERT_PRE(index
< var_ft
->fields
->len
,
2707 "Index is out of bounds: index=%" PRIu64
", "
2708 "count=%u, %![ft-]+_F",
2709 index
, var_ft
->fields
->len
, ft
);
2710 field
= g_ptr_array_index(var_ft
->fields
, index
);
2713 *field_type
= field
->type
;
2714 bt_get(field
->type
);
2718 *field_name
= g_quark_to_string(field
->name
);
2719 BT_ASSERT(*field_name
);
2725 int bt_field_type_variant_get_field_by_index(struct bt_field_type
*ft
,
2726 const char **field_name
, struct bt_field_type
**field_type
,
2729 return bt_field_type_common_variant_get_field_by_index((void *) ft
,
2730 field_name
, (void *) field_type
, index
);
2733 struct bt_field_type
*bt_field_type_array_create(
2734 struct bt_field_type
*element_ft
, unsigned int length
)
2736 struct bt_field_type_common_array
*array
= NULL
;
2738 BT_LOGD("Creating array field type object: element-ft-addr=%p, "
2739 "length=%u", element_ft
, length
);
2742 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2747 BT_LOGW_STR("Invalid parameter: length is zero.");
2751 array
= g_new0(struct bt_field_type_common_array
, 1);
2753 BT_LOGE_STR("Failed to allocate one array field type.");
2757 bt_field_type_common_array_initialize(BT_TO_COMMON(array
),
2758 (void *) element_ft
, length
,
2759 bt_field_type_common_array_destroy_recursive
,
2760 &bt_field_type_array_methods
);
2761 BT_LOGD("Created array field type object: addr=%p, "
2762 "element-ft-addr=%p, length=%u",
2763 array
, element_ft
, length
);
2770 return (void *) array
;
2774 struct bt_field_type_common
*bt_field_type_common_array_get_element_field_type(
2775 struct bt_field_type_common
*ft
)
2777 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
2779 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2780 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ARRAY
,
2782 BT_ASSERT(array_ft
&& array_ft
->element_ft
);
2783 return bt_get(array_ft
->element_ft
);
2786 struct bt_field_type
*bt_field_type_array_get_element_field_type(
2787 struct bt_field_type
*ft
)
2789 return (void *) bt_field_type_common_array_get_element_field_type(
2794 int bt_field_type_common_array_set_element_field_type(
2795 struct bt_field_type_common
*ft
,
2796 struct bt_field_type_common
*element_ft
)
2799 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
2802 BT_LOGW_STR("Invalid parameter: array field type is NULL.");
2808 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2813 if (ft
->id
!= BT_FIELD_TYPE_ID_ARRAY
) {
2814 BT_LOGW("Invalid parameter: field type is not an array field type: "
2815 "addr=%p, ft-id=%s", ft
,
2816 bt_common_field_type_id_string(ft
->id
));
2821 if (array_ft
->element_ft
) {
2822 BT_PUT(array_ft
->element_ft
);
2825 array_ft
->element_ft
= bt_get(element_ft
);
2826 BT_LOGV("Set array field type's element field type: array-ft-addr=%p, "
2827 "element-ft-addr=%p", ft
, element_ft
);
2834 int64_t bt_field_type_common_array_get_length(struct bt_field_type_common
*ft
)
2836 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
2838 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2839 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_ARRAY
,
2841 return (int64_t) array_ft
->length
;
2844 int64_t bt_field_type_array_get_length(struct bt_field_type
*ft
)
2846 return bt_field_type_common_array_get_length((void *) ft
);
2849 struct bt_field_type
*bt_field_type_sequence_create(
2850 struct bt_field_type
*element_ft
,
2851 const char *length_field_name
)
2853 struct bt_field_type_common_sequence
*sequence
= NULL
;
2855 BT_LOGD("Creating sequence field type object: element-ft-addr=%p, "
2856 "length-field-name=\"%s\"", element_ft
, length_field_name
);
2859 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2863 if (!bt_identifier_is_valid(length_field_name
)) {
2864 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
2865 "length-field-name=\"%s\"", length_field_name
);
2869 sequence
= g_new0(struct bt_field_type_common_sequence
, 1);
2871 BT_LOGE_STR("Failed to allocate one sequence field type.");
2875 bt_field_type_common_sequence_initialize(BT_TO_COMMON(sequence
),
2876 (void *) element_ft
, length_field_name
,
2877 bt_field_type_common_sequence_destroy_recursive
,
2878 &bt_field_type_sequence_methods
);
2879 BT_LOGD("Created sequence field type object: addr=%p, "
2880 "element-ft-addr=%p, length-field-name=\"%s\"",
2881 sequence
, element_ft
, length_field_name
);
2888 return (void *) sequence
;
2892 struct bt_field_type_common
*bt_field_type_common_sequence_get_element_field_type(
2893 struct bt_field_type_common
*ft
)
2895 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
2897 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2898 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_SEQUENCE
,
2900 return bt_get(seq_ft
->element_ft
);
2903 struct bt_field_type
*bt_field_type_sequence_get_element_field_type(
2904 struct bt_field_type
*ft
)
2906 return (void *) bt_field_type_common_sequence_get_element_field_type(
2911 int bt_field_type_common_sequence_set_element_field_type(
2912 struct bt_field_type_common
*ft
,
2913 struct bt_field_type_common
*element_ft
)
2916 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
2919 BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
2925 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2930 if (ft
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
2931 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2932 "addr=%p, ft-id=%s", ft
,
2933 bt_common_field_type_id_string(ft
->id
));
2938 if (seq_ft
->element_ft
) {
2939 BT_PUT(seq_ft
->element_ft
);
2942 seq_ft
->element_ft
= element_ft
;
2943 bt_get(seq_ft
->element_ft
);
2944 BT_LOGV("Set sequence field type's element field type: sequence-ft-addr=%p, "
2945 "element-ft-addr=%p", ft
, element_ft
);
2952 const char *bt_field_type_common_sequence_get_length_field_name(
2953 struct bt_field_type_common
*ft
)
2955 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
2957 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2958 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_SEQUENCE
,
2960 return seq_ft
->length_field_name
?
2961 seq_ft
->length_field_name
->str
: NULL
;
2964 const char *bt_field_type_sequence_get_length_field_name(
2965 struct bt_field_type
*ft
)
2967 return bt_field_type_common_sequence_get_length_field_name((void *) ft
);
2970 struct bt_field_type
*bt_field_type_string_create(void)
2972 struct bt_field_type_common_string
*string
=
2973 g_new0(struct bt_field_type_common_string
, 1);
2975 BT_LOGD_STR("Creating string field type object.");
2978 BT_LOGE_STR("Failed to allocate one string field type.");
2982 bt_field_type_common_string_initialize(BT_TO_COMMON(string
),
2983 bt_field_type_common_string_destroy
,
2984 &bt_field_type_string_methods
);
2985 BT_LOGD("Created string field type object: addr=%p", string
);
2986 return (void *) string
;
2990 enum bt_string_encoding
bt_field_type_common_string_get_encoding(
2991 struct bt_field_type_common
*ft
)
2993 struct bt_field_type_common_string
*string_ft
= BT_FROM_COMMON(ft
);
2995 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
2996 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRING
,
2998 return string_ft
->encoding
;
3001 enum bt_string_encoding
bt_field_type_string_get_encoding(
3002 struct bt_field_type
*ft
)
3004 return bt_field_type_common_string_get_encoding((void *) ft
);
3008 int bt_field_type_common_string_set_encoding(struct bt_field_type_common
*ft
,
3009 enum bt_string_encoding encoding
)
3012 struct bt_field_type_common_string
*string_ft
= BT_FROM_COMMON(ft
);
3015 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3020 if (ft
->id
!= BT_FIELD_TYPE_ID_STRING
) {
3021 BT_LOGW("Invalid parameter: field type is not a string field type: "
3022 "addr=%p, ft-id=%s", ft
,
3023 bt_common_field_type_id_string(ft
->id
));
3028 if (encoding
!= BT_STRING_ENCODING_UTF8
&&
3029 encoding
!= BT_STRING_ENCODING_ASCII
) {
3030 BT_LOGW("Invalid parameter: unknown string encoding: "
3031 "addr=%p, encoding=%d", ft
, encoding
);
3036 string_ft
->encoding
= encoding
;
3037 BT_LOGV("Set string field type's encoding: addr=%p, encoding=%s",
3038 ft
, bt_common_string_encoding_string(encoding
));
3044 int bt_field_type_string_set_encoding(struct bt_field_type
*ft
,
3045 enum bt_string_encoding encoding
)
3047 return bt_field_type_common_string_set_encoding((void *) ft
, encoding
);
3051 int bt_field_type_common_get_alignment(struct bt_field_type_common
*ft
)
3054 enum bt_field_type_id type_id
;
3056 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3059 ret
= (int) ft
->alignment
;
3063 type_id
= bt_field_type_common_get_type_id(ft
);
3065 case BT_FIELD_TYPE_ID_SEQUENCE
:
3067 struct bt_field_type_common
*element_ft
=
3068 bt_field_type_common_sequence_get_element_field_type(ft
);
3070 BT_ASSERT(element_ft
);
3071 ret
= bt_field_type_common_get_alignment(element_ft
);
3075 case BT_FIELD_TYPE_ID_ARRAY
:
3077 struct bt_field_type_common
*element_ft
=
3078 bt_field_type_common_array_get_element_field_type(ft
);
3080 BT_ASSERT(element_ft
);
3081 ret
= bt_field_type_common_get_alignment(element_ft
);
3085 case BT_FIELD_TYPE_ID_STRUCT
:
3087 int64_t i
, element_count
;
3089 element_count
= bt_field_type_common_structure_get_field_count(
3091 BT_ASSERT(element_count
>= 0);
3093 for (i
= 0; i
< element_count
; i
++) {
3094 struct bt_field_type_common
*field
= NULL
;
3095 int field_alignment
;
3097 ret
= bt_field_type_common_structure_get_field_by_index(
3098 ft
, NULL
, &field
, i
);
3099 BT_ASSERT(ret
== 0);
3101 field_alignment
= bt_field_type_common_get_alignment(
3104 if (field_alignment
< 0) {
3105 ret
= field_alignment
;
3109 ft
->alignment
= MAX(field_alignment
, ft
->alignment
);
3111 ret
= (int) ft
->alignment
;
3114 case BT_FIELD_TYPE_ID_UNKNOWN
:
3115 BT_LOGW("Invalid parameter: unknown field type ID: "
3116 "addr=%p, ft-id=%d", ft
, type_id
);
3120 ret
= (int) ft
->alignment
;
3128 int bt_field_type_get_alignment(struct bt_field_type
*ft
)
3130 return bt_field_type_common_get_alignment((void *) ft
);
3134 int is_power_of_two(unsigned int value
)
3136 return ((value
& (value
- 1)) == 0) && value
> 0;
3140 int bt_field_type_common_set_alignment(struct bt_field_type_common
*ft
,
3141 unsigned int alignment
)
3144 enum bt_field_type_id type_id
;
3146 /* Alignment must be a power of two */
3148 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3154 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3160 if (!is_power_of_two(alignment
)) {
3161 BT_LOGW("Invalid parameter: alignment is not a power of two: "
3162 "addr=%p, align=%u", ft
, alignment
);
3167 type_id
= bt_field_type_common_get_type_id(ft
);
3168 if (type_id
== BT_FIELD_TYPE_ID_UNKNOWN
) {
3169 BT_LOGW("Invalid parameter: unknown field type ID: "
3170 "addr=%p, ft-id=%d", ft
, type_id
);
3175 if (ft
->id
== BT_FIELD_TYPE_ID_STRING
&& alignment
!= CHAR_BIT
) {
3176 BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
3177 "addr=%p, align=%u", CHAR_BIT
, ft
, alignment
);
3182 if (type_id
== BT_FIELD_TYPE_ID_VARIANT
||
3183 type_id
== BT_FIELD_TYPE_ID_SEQUENCE
||
3184 type_id
== BT_FIELD_TYPE_ID_ARRAY
) {
3185 /* Setting an alignment on these types makes no sense */
3186 BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
3187 "addr=%p, ft-id=%s", ft
,
3188 bt_common_field_type_id_string(ft
->id
));
3193 ft
->alignment
= alignment
;
3195 BT_LOGV("Set field type's alignment: addr=%p, align=%u",
3202 int bt_field_type_set_alignment(struct bt_field_type
*ft
,
3203 unsigned int alignment
)
3205 return bt_field_type_common_set_alignment((void *) ft
, alignment
);
3209 enum bt_byte_order
bt_field_type_common_get_byte_order(
3210 struct bt_field_type_common
*ft
)
3212 enum bt_byte_order ret
= BT_BYTE_ORDER_UNKNOWN
;
3214 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3217 case BT_FIELD_TYPE_ID_INTEGER
:
3219 struct bt_field_type_common_integer
*integer
=
3222 ret
= integer
->user_byte_order
;
3225 case BT_FIELD_TYPE_ID_ENUM
:
3227 struct bt_field_type_common_enumeration
*enum_ft
=
3230 ret
= bt_field_type_common_get_byte_order(
3231 BT_TO_COMMON(enum_ft
->container_ft
));
3234 case BT_FIELD_TYPE_ID_FLOAT
:
3236 struct bt_field_type_common_floating_point
*floating_point
=
3238 ret
= floating_point
->user_byte_order
;
3242 BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
3243 "addr=%p, ft-id=%s", ft
,
3244 bt_common_field_type_id_string(ft
->id
));
3248 BT_ASSERT(ret
== BT_BYTE_ORDER_NATIVE
||
3249 ret
== BT_BYTE_ORDER_LITTLE_ENDIAN
||
3250 ret
== BT_BYTE_ORDER_BIG_ENDIAN
||
3251 ret
== BT_BYTE_ORDER_NETWORK
);
3257 enum bt_byte_order
bt_field_type_get_byte_order(struct bt_field_type
*ft
)
3259 return bt_field_type_common_get_byte_order((void *) ft
);
3263 int bt_field_type_common_set_byte_order(struct bt_field_type_common
*ft
,
3264 enum bt_byte_order byte_order
)
3269 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3275 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3281 if (byte_order
!= BT_BYTE_ORDER_NATIVE
&&
3282 byte_order
!= BT_BYTE_ORDER_LITTLE_ENDIAN
&&
3283 byte_order
!= BT_BYTE_ORDER_BIG_ENDIAN
&&
3284 byte_order
!= BT_BYTE_ORDER_NETWORK
) {
3285 BT_LOGW("Invalid parameter: invalid byte order: "
3286 "addr=%p, bo=%s", ft
,
3287 bt_common_byte_order_string(byte_order
));
3292 if (ft
->methods
->set_byte_order
) {
3293 ft
->methods
->set_byte_order(ft
, byte_order
);
3296 BT_LOGV("Set field type's byte order: addr=%p, bo=%s",
3297 ft
, bt_common_byte_order_string(byte_order
));
3303 int bt_field_type_set_byte_order(struct bt_field_type
*ft
,
3304 enum bt_byte_order byte_order
)
3306 return bt_field_type_common_set_byte_order((void *) ft
, byte_order
);
3310 enum bt_field_type_id
bt_field_type_common_get_type_id(
3311 struct bt_field_type_common
*ft
)
3313 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3317 enum bt_field_type_id
bt_field_type_get_type_id(struct bt_field_type
*ft
)
3319 return bt_field_type_common_get_type_id((void *) ft
);
3322 int bt_field_type_is_integer(struct bt_field_type
*type
)
3324 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_INTEGER
;
3327 int bt_field_type_is_floating_point(struct bt_field_type
*type
)
3329 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_FLOAT
;
3332 int bt_field_type_is_enumeration(struct bt_field_type
*type
)
3334 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_ENUM
;
3337 int bt_field_type_is_string(struct bt_field_type
*type
)
3339 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_STRING
;
3342 int bt_field_type_is_structure(struct bt_field_type
*type
)
3344 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_STRUCT
;
3347 int bt_field_type_is_array(struct bt_field_type
*type
)
3349 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_ARRAY
;
3352 int bt_field_type_is_sequence(struct bt_field_type
*type
)
3354 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_SEQUENCE
;
3357 int bt_field_type_is_variant(struct bt_field_type
*type
)
3359 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_VARIANT
;
3363 void _bt_field_type_common_freeze(struct bt_field_type_common
*ft
)
3365 if (!ft
|| ft
->frozen
) {
3369 BT_ASSERT(ft
->methods
->freeze
);
3370 ft
->methods
->freeze(ft
);
3374 void _bt_field_type_freeze(struct bt_field_type
*ft
)
3376 _bt_field_type_common_freeze((void *) ft
);
3380 struct bt_field_type_common
*bt_field_type_common_variant_get_field_type_signed(
3381 struct bt_field_type_common_variant
*var_ft
,
3384 struct bt_field_type_common
*field_type
= NULL
;
3385 GQuark field_name_quark
;
3387 struct structure_field_common
*field_entry
;
3388 struct range_overlap_query query
= {
3389 .range_start
._signed
= tag_value
,
3390 .range_end
._signed
= tag_value
,
3395 g_ptr_array_foreach(var_ft
->tag_ft
->entries
, check_ranges_overlap
,
3397 if (!query
.overlaps
) {
3401 field_name_quark
= query
.mapping_name
;
3402 if (!g_hash_table_lookup_extended(var_ft
->field_name_to_index
,
3403 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3407 field_entry
= g_ptr_array_index(var_ft
->fields
, (size_t) index
);
3408 field_type
= field_entry
->type
;
3415 struct bt_field_type_common
*bt_field_type_common_variant_get_field_type_unsigned(
3416 struct bt_field_type_common_variant
*var_ft
,
3419 struct bt_field_type_common
*field_type
= NULL
;
3420 GQuark field_name_quark
;
3422 struct structure_field_common
*field_entry
;
3423 struct range_overlap_query query
= {
3424 .range_start
._unsigned
= tag_value
,
3425 .range_end
._unsigned
= tag_value
,
3430 g_ptr_array_foreach(var_ft
->tag_ft
->entries
,
3431 check_ranges_overlap_unsigned
, &query
);
3432 if (!query
.overlaps
) {
3436 field_name_quark
= query
.mapping_name
;
3437 if (!g_hash_table_lookup_extended(var_ft
->field_name_to_index
,
3438 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3442 field_entry
= g_ptr_array_index(var_ft
->fields
, (size_t) index
);
3443 field_type
= field_entry
->type
;
3449 struct bt_field_type_common
*bt_field_type_common_copy(
3450 struct bt_field_type_common
*ft
)
3452 struct bt_field_type_common
*ft_copy
= NULL
;
3454 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3455 BT_ASSERT(ft
->methods
->copy
);
3456 ft_copy
= ft
->methods
->copy(ft
);
3458 BT_LOGE_STR("Cannot copy field type.");
3462 ft_copy
->alignment
= ft
->alignment
;
3468 struct bt_field_type
*bt_field_type_copy(struct bt_field_type
*ft
)
3470 return (void *) bt_field_type_common_copy((void *) ft
);
3474 int bt_field_type_common_structure_get_field_name_index(
3475 struct bt_field_type_common
*ft
, const char *name
)
3480 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
3482 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3483 BT_ASSERT_PRE_NON_NULL(name
, "Name");
3484 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCT
,
3487 name_quark
= g_quark_try_string(name
);
3489 BT_LOGV("No such structure field type field name: "
3490 "ft-addr=%p, field-name=\"%s\"",
3496 if (!g_hash_table_lookup_extended(struct_ft
->field_name_to_index
,
3497 GUINT_TO_POINTER(name_quark
),
3498 NULL
, (gpointer
*) &index
)) {
3499 BT_LOGV("No such structure field type field name: "
3500 "ft-addr=%p, field-name=\"%s\"",
3513 int bt_field_type_common_variant_get_field_name_index(
3514 struct bt_field_type_common
*ft
, const char *name
)
3519 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3521 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
3522 BT_ASSERT_PRE_NON_NULL(name
, "Name");
3523 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
3525 name_quark
= g_quark_try_string(name
);
3527 BT_LOGV("No such variant field type field name: "
3528 "ft-addr=%p, field-name=\"%s\"",
3534 if (!g_hash_table_lookup_extended(var_ft
->field_name_to_index
,
3535 GUINT_TO_POINTER(name_quark
),
3536 NULL
, (gpointer
*) &index
)) {
3537 BT_LOGV("No such variant field type field name: "
3538 "ft-addr=%p, field-name=\"%s\"",
3551 int bt_field_type_common_sequence_set_length_field_path(
3552 struct bt_field_type_common
*ft
, struct bt_field_path
*path
)
3555 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3558 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3563 if (ft
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
3564 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
3565 "addr=%p, ft-id=%s", ft
,
3566 bt_common_field_type_id_string(ft
->id
));
3572 BT_MOVE(seq_ft
->length_field_path
, path
);
3573 BT_LOGV("Set sequence field type's length field path: ft-addr=%p, "
3574 "field-path-addr=%p", ft
, path
);
3581 int bt_field_type_common_variant_set_tag_field_path(
3582 struct bt_field_type_common
*ft
,
3583 struct bt_field_path
*path
)
3586 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3589 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3594 if (ft
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
3595 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3596 "addr=%p, ft-id=%s", ft
,
3597 bt_common_field_type_id_string(ft
->id
));
3603 BT_MOVE(var_ft
->tag_field_path
, path
);
3604 BT_LOGV("Set variant field type's tag field path: ft-addr=%p, "
3605 "field-path-addr=%p", ft
, path
);
3612 int bt_field_type_common_variant_set_tag_field_type(
3613 struct bt_field_type_common
*ft
,
3614 struct bt_field_type_common
*tag_ft
)
3617 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3620 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3626 BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
3631 if (tag_ft
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
3632 BT_LOGW("Invalid parameter: tag field type is not an enumeration field type: "
3633 "addr=%p, ft-id=%s", tag_ft
,
3634 bt_common_field_type_id_string(tag_ft
->id
));
3639 bt_put(var_ft
->tag_ft
);
3640 var_ft
->tag_ft
= bt_get(tag_ft
);
3641 BT_LOGV("Set variant field type's tag field type: variant-ft-addr=%p, "
3642 "tag-ft-addr=%p", ft
, tag_ft
);
3649 void bt_field_type_common_generic_freeze(struct bt_field_type_common
*ft
)
3655 void bt_field_type_common_enumeration_freeze_recursive(
3656 struct bt_field_type_common
*ft
)
3658 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
3660 BT_LOGD("Freezing enumeration field type object: addr=%p", ft
);
3661 bt_field_type_common_enumeration_set_range_overlap(enum_ft
);
3662 bt_field_type_common_generic_freeze(ft
);
3663 BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
3664 enum_ft
->container_ft
);
3665 bt_field_type_common_freeze(BT_TO_COMMON(enum_ft
->container_ft
));
3669 void freeze_structure_field(struct structure_field_common
*field
)
3671 BT_LOGD("Freezing structure/variant field type field: field-addr=%p, "
3672 "field-ft-addr=%p, field-name=\"%s\"", field
,
3673 field
->type
, g_quark_to_string(field
->name
));
3674 bt_field_type_common_freeze(field
->type
);
3678 void bt_field_type_common_structure_freeze_recursive(
3679 struct bt_field_type_common
*ft
)
3681 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
3683 /* Cache the alignment */
3684 BT_LOGD("Freezing structure field type object: addr=%p", ft
);
3685 ft
->alignment
= bt_field_type_common_get_alignment(ft
);
3686 bt_field_type_common_generic_freeze(ft
);
3687 g_ptr_array_foreach(struct_ft
->fields
,
3688 (GFunc
) freeze_structure_field
, NULL
);
3692 void bt_field_type_common_variant_freeze_recursive(
3693 struct bt_field_type_common
*ft
)
3695 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3697 BT_LOGD("Freezing variant field type object: addr=%p", ft
);
3698 bt_field_type_common_generic_freeze(ft
);
3699 g_ptr_array_foreach(var_ft
->fields
,
3700 (GFunc
) freeze_structure_field
, NULL
);
3704 void bt_field_type_common_array_freeze_recursive(
3705 struct bt_field_type_common
*ft
)
3707 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
3709 /* Cache the alignment */
3710 BT_LOGD("Freezing array field type object: addr=%p", ft
);
3711 ft
->alignment
= bt_field_type_common_get_alignment(ft
);
3712 bt_field_type_common_generic_freeze(ft
);
3713 BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
3714 array_ft
->element_ft
);
3715 bt_field_type_common_freeze(array_ft
->element_ft
);
3719 void bt_field_type_common_sequence_freeze_recursive(
3720 struct bt_field_type_common
*ft
)
3722 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3724 /* Cache the alignment */
3725 BT_LOGD("Freezing sequence field type object: addr=%p", ft
);
3726 ft
->alignment
= bt_field_type_common_get_alignment(ft
);
3727 bt_field_type_common_generic_freeze(ft
);
3728 BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
3729 seq_ft
->element_ft
);
3730 bt_field_type_common_freeze(seq_ft
->element_ft
);
3734 void bt_field_type_common_integer_set_byte_order(
3735 struct bt_field_type_common
*ft
, enum bt_byte_order byte_order
)
3737 struct bt_field_type_common_integer
*int_ft
= BT_FROM_COMMON(ft
);
3739 int_ft
->user_byte_order
= byte_order
;
3743 void bt_field_type_common_enumeration_set_byte_order_recursive(
3744 struct bt_field_type_common
*ft
, enum bt_byte_order byte_order
)
3746 struct bt_field_type_common_enumeration
*enum_ft
= BT_FROM_COMMON(ft
);
3748 bt_field_type_common_set_byte_order(BT_TO_COMMON(enum_ft
->container_ft
),
3753 void bt_field_type_common_floating_point_set_byte_order(
3754 struct bt_field_type_common
*ft
, enum bt_byte_order byte_order
)
3756 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
3758 flt_ft
->user_byte_order
= byte_order
;
3762 void bt_field_type_common_structure_set_byte_order_recursive(
3763 struct bt_field_type_common
*ft
,
3764 enum bt_byte_order byte_order
)
3767 struct bt_field_type_common_structure
*struct_ft
= BT_FROM_COMMON(ft
);
3769 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
3770 struct structure_field_common
*field
= g_ptr_array_index(
3771 struct_ft
->fields
, i
);
3772 struct bt_field_type_common
*field_type
= field
->type
;
3774 bt_field_type_common_set_byte_order(field_type
, byte_order
);
3779 void bt_field_type_common_variant_set_byte_order_recursive(
3780 struct bt_field_type_common
*ft
,
3781 enum bt_byte_order byte_order
)
3784 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
3786 for (i
= 0; i
< var_ft
->fields
->len
; i
++) {
3787 struct structure_field_common
*field
= g_ptr_array_index(
3789 struct bt_field_type_common
*field_type
= field
->type
;
3791 bt_field_type_common_set_byte_order(field_type
, byte_order
);
3796 void bt_field_type_common_array_set_byte_order_recursive(
3797 struct bt_field_type_common
*ft
,
3798 enum bt_byte_order byte_order
)
3800 struct bt_field_type_common_array
*array_ft
= BT_FROM_COMMON(ft
);
3802 bt_field_type_common_set_byte_order(array_ft
->element_ft
, byte_order
);
3806 void bt_field_type_common_sequence_set_byte_order_recursive(
3807 struct bt_field_type_common
*ft
,
3808 enum bt_byte_order byte_order
)
3810 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
3812 bt_field_type_common_set_byte_order(seq_ft
->element_ft
, byte_order
);
3817 int bt_field_type_common_integer_compare(struct bt_field_type_common
*ft_a
,
3818 struct bt_field_type_common
*ft_b
)
3821 struct bt_field_type_common_integer
*int_ft_a
= BT_FROM_COMMON(ft_a
);
3822 struct bt_field_type_common_integer
*int_ft_b
= BT_FROM_COMMON(ft_b
);
3825 if (int_ft_a
->size
!= int_ft_b
->size
) {
3826 BT_LOGV("Integer field types differ: different sizes: "
3827 "ft-a-size=%u, ft-b-size=%u",
3828 int_ft_a
->size
, int_ft_b
->size
);
3833 if (int_ft_a
->user_byte_order
!= int_ft_b
->user_byte_order
) {
3834 BT_LOGV("Integer field types differ: different byte orders: "
3835 "ft-a-bo=%s, ft-b-bo=%s",
3836 bt_common_byte_order_string(int_ft_a
->user_byte_order
),
3837 bt_common_byte_order_string(int_ft_b
->user_byte_order
));
3842 if (int_ft_a
->is_signed
!= int_ft_b
->is_signed
) {
3843 BT_LOGV("Integer field types differ: different signedness: "
3844 "ft-a-is-signed=%d, ft-b-is-signed=%d",
3845 int_ft_a
->is_signed
,
3846 int_ft_b
->is_signed
);
3851 if (int_ft_a
->base
!= int_ft_b
->base
) {
3852 BT_LOGV("Integer field types differ: different bases: "
3853 "ft-a-base=%s, ft-b-base=%s",
3854 bt_common_integer_base_string(int_ft_a
->base
),
3855 bt_common_integer_base_string(int_ft_b
->base
));
3860 if (int_ft_a
->encoding
!= int_ft_b
->encoding
) {
3861 BT_LOGV("Integer field types differ: different encodings: "
3862 "ft-a-encoding=%s, ft-b-encoding=%s",
3863 bt_common_string_encoding_string(int_ft_a
->encoding
),
3864 bt_common_string_encoding_string(int_ft_b
->encoding
));
3868 /* Mapped clock class */
3869 if (int_ft_a
->mapped_clock_class
) {
3870 if (!int_ft_b
->mapped_clock_class
) {
3871 BT_LOGV_STR("Integer field types differ: field type A "
3872 "has a mapped clock class, but field type B "
3877 if (bt_clock_class_compare(int_ft_a
->mapped_clock_class
,
3878 int_ft_b
->mapped_clock_class
) != 0) {
3879 BT_LOGV_STR("Integer field types differ: different "
3880 "mapped clock classes.");
3883 if (int_ft_b
->mapped_clock_class
) {
3884 BT_LOGV_STR("Integer field types differ: field type A "
3885 "has no description, but field type B has one.");
3898 int bt_field_type_common_floating_point_compare(
3899 struct bt_field_type_common
*ft_a
,
3900 struct bt_field_type_common
*ft_b
)
3903 struct bt_field_type_common_floating_point
*flt_ft_a
=
3904 BT_FROM_COMMON(ft_a
);
3905 struct bt_field_type_common_floating_point
*flt_ft_b
=
3906 BT_FROM_COMMON(ft_b
);
3909 if (flt_ft_a
->user_byte_order
!= flt_ft_b
->user_byte_order
) {
3910 BT_LOGV("Floating point number field types differ: different byte orders: "
3911 "ft-a-bo=%s, ft-b-bo=%s",
3912 bt_common_byte_order_string(flt_ft_a
->user_byte_order
),
3913 bt_common_byte_order_string(flt_ft_b
->user_byte_order
));
3917 /* Exponent length */
3918 if (flt_ft_a
->exp_dig
!= flt_ft_b
->exp_dig
) {
3919 BT_LOGV("Floating point number field types differ: different exponent sizes: "
3920 "ft-a-exp-size=%u, ft-b-exp-size=%u",
3921 flt_ft_a
->exp_dig
, flt_ft_b
->exp_dig
);
3925 /* Mantissa length */
3926 if (flt_ft_a
->mant_dig
!= flt_ft_b
->mant_dig
) {
3927 BT_LOGV("Floating point number field types differ: different mantissa sizes: "
3928 "ft-a-mant-size=%u, ft-b-mant-size=%u",
3929 flt_ft_a
->mant_dig
, flt_ft_b
->mant_dig
);
3941 int compare_enumeration_mappings(struct enumeration_mapping
*mapping_a
,
3942 struct enumeration_mapping
*mapping_b
)
3947 if (mapping_a
->string
!= mapping_b
->string
) {
3948 BT_LOGV("Enumeration field type mappings differ: different names: "
3949 "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
3950 g_quark_to_string(mapping_a
->string
),
3951 g_quark_to_string(mapping_b
->string
));
3956 if (mapping_a
->range_start
._unsigned
!=
3957 mapping_b
->range_start
._unsigned
) {
3958 BT_LOGV("Enumeration field type mappings differ: different starts of range: "
3959 "mapping-a-range-start-unsigned=%" PRIu64
", "
3960 "mapping-b-range-start-unsigned=%" PRIu64
,
3961 mapping_a
->range_start
._unsigned
,
3962 mapping_b
->range_start
._unsigned
);
3967 if (mapping_a
->range_end
._unsigned
!=
3968 mapping_b
->range_end
._unsigned
) {
3969 BT_LOGV("Enumeration field type mappings differ: different ends of range: "
3970 "mapping-a-range-end-unsigned=%" PRIu64
", "
3971 "mapping-b-range-end-unsigned=%" PRIu64
,
3972 mapping_a
->range_end
._unsigned
,
3973 mapping_b
->range_end
._unsigned
);
3985 int bt_field_type_common_enumeration_compare_recursive(
3986 struct bt_field_type_common
*ft_a
,
3987 struct bt_field_type_common
*ft_b
)
3991 struct bt_field_type_common_enumeration
*enum_ft_a
=
3992 BT_FROM_COMMON(ft_a
);
3993 struct bt_field_type_common_enumeration
*enum_ft_b
=
3994 BT_FROM_COMMON(ft_b
);
3996 /* Container field type */
3997 ret
= bt_field_type_common_compare(
3998 BT_TO_COMMON(enum_ft_a
->container_ft
),
3999 BT_TO_COMMON(enum_ft_b
->container_ft
));
4001 BT_LOGV("Enumeration field types differ: different container field types: "
4002 "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
4003 enum_ft_a
->container_ft
, enum_ft_b
->container_ft
);
4010 if (enum_ft_a
->entries
->len
!= enum_ft_b
->entries
->len
) {
4014 for (i
= 0; i
< enum_ft_a
->entries
->len
; ++i
) {
4015 struct enumeration_mapping
*mapping_a
=
4016 g_ptr_array_index(enum_ft_a
->entries
, i
);
4017 struct enumeration_mapping
*mapping_b
=
4018 g_ptr_array_index(enum_ft_b
->entries
, i
);
4020 if (compare_enumeration_mappings(mapping_a
, mapping_b
)) {
4021 BT_LOGV("Enumeration field types differ: different mappings: "
4022 "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
4023 "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
4024 mapping_a
, mapping_b
,
4025 g_quark_to_string(mapping_a
->string
),
4026 g_quark_to_string(mapping_b
->string
));
4039 int bt_field_type_common_string_compare(struct bt_field_type_common
*ft_a
,
4040 struct bt_field_type_common
*ft_b
)
4043 struct bt_field_type_common_string
*string_ft_a
= BT_FROM_COMMON(ft_a
);
4044 struct bt_field_type_common_string
*string_ft_b
= BT_FROM_COMMON(ft_b
);
4047 if (string_ft_a
->encoding
!= string_ft_b
->encoding
) {
4048 BT_LOGV("String field types differ: different encodings: "
4049 "ft-a-encoding=%s, ft-b-encoding=%s",
4050 bt_common_string_encoding_string(string_ft_a
->encoding
),
4051 bt_common_string_encoding_string(string_ft_b
->encoding
));
4063 int compare_structure_fields(struct structure_field_common
*field_a
,
4064 struct structure_field_common
*field_b
)
4069 if (field_a
->name
!= field_b
->name
) {
4070 BT_LOGV("Structure/variant field type fields differ: different names: "
4071 "field-a-name=%s, field-b-name=%s",
4072 g_quark_to_string(field_a
->name
),
4073 g_quark_to_string(field_b
->name
));
4078 ret
= bt_field_type_common_compare(field_a
->type
, field_b
->type
);
4080 BT_LOGV("Structure/variant field type fields differ: different field types: "
4081 "field-name=\"%s\", field-a-ft-addr=%p, field-b-ft-addr=%p",
4082 g_quark_to_string(field_a
->name
),
4083 field_a
->type
, field_b
->type
);
4091 int bt_field_type_common_structure_compare_recursive(
4092 struct bt_field_type_common
*ft_a
,
4093 struct bt_field_type_common
*ft_b
)
4097 struct bt_field_type_common_structure
*struct_ft_a
=
4098 BT_FROM_COMMON(ft_a
);
4099 struct bt_field_type_common_structure
*struct_ft_b
=
4100 BT_FROM_COMMON(ft_b
);
4103 if (bt_field_type_common_get_alignment(ft_a
) !=
4104 bt_field_type_common_get_alignment(ft_b
)) {
4105 BT_LOGV("Structure field types differ: different alignments: "
4106 "ft-a-align=%u, ft-b-align=%u",
4107 bt_field_type_common_get_alignment(ft_a
),
4108 bt_field_type_common_get_alignment(ft_b
));
4113 if (struct_ft_a
->fields
->len
!= struct_ft_b
->fields
->len
) {
4114 BT_LOGV("Structure field types differ: different field counts: "
4115 "ft-a-field-count=%u, ft-b-field-count=%u",
4116 struct_ft_a
->fields
->len
, struct_ft_b
->fields
->len
);
4120 for (i
= 0; i
< struct_ft_a
->fields
->len
; ++i
) {
4121 struct structure_field_common
*field_a
=
4122 g_ptr_array_index(struct_ft_a
->fields
, i
);
4123 struct structure_field_common
*field_b
=
4124 g_ptr_array_index(struct_ft_b
->fields
, i
);
4126 ret
= compare_structure_fields(field_a
, field_b
);
4128 /* compare_structure_fields() logs what differs */
4129 BT_LOGV_STR("Structure field types differ: different fields.");
4142 int bt_field_type_common_variant_compare_recursive(
4143 struct bt_field_type_common
*ft_a
,
4144 struct bt_field_type_common
*ft_b
)
4148 struct bt_field_type_common_variant
*var_ft_a
= BT_FROM_COMMON(ft_a
);
4149 struct bt_field_type_common_variant
*var_ft_b
= BT_FROM_COMMON(ft_b
);
4152 if (strcmp(var_ft_a
->tag_name
->str
, var_ft_b
->tag_name
->str
)) {
4153 BT_LOGV("Variant field types differ: different tag field names: "
4154 "ft-a-tag-field-name=\"%s\", ft-b-tag-field-name=\"%s\"",
4155 var_ft_a
->tag_name
->str
, var_ft_b
->tag_name
->str
);
4160 ret
= bt_field_type_common_compare(BT_TO_COMMON(var_ft_a
->tag_ft
),
4161 BT_TO_COMMON(var_ft_b
->tag_ft
));
4163 BT_LOGV("Variant field types differ: different tag field types: "
4164 "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
4165 var_ft_a
->tag_ft
, var_ft_b
->tag_ft
);
4172 if (var_ft_a
->fields
->len
!= var_ft_b
->fields
->len
) {
4173 BT_LOGV("Structure field types differ: different field counts: "
4174 "ft-a-field-count=%u, ft-b-field-count=%u",
4175 var_ft_a
->fields
->len
, var_ft_b
->fields
->len
);
4179 for (i
= 0; i
< var_ft_a
->fields
->len
; ++i
) {
4180 struct structure_field_common
*field_a
=
4181 g_ptr_array_index(var_ft_a
->fields
, i
);
4182 struct structure_field_common
*field_b
=
4183 g_ptr_array_index(var_ft_b
->fields
, i
);
4185 ret
= compare_structure_fields(field_a
, field_b
);
4187 /* compare_structure_fields() logs what differs */
4188 BT_LOGV_STR("Variant field types differ: different fields.");
4201 int bt_field_type_common_array_compare_recursive(
4202 struct bt_field_type_common
*ft_a
,
4203 struct bt_field_type_common
*ft_b
)
4206 struct bt_field_type_common_array
*array_ft_a
= BT_FROM_COMMON(ft_a
);
4207 struct bt_field_type_common_array
*array_ft_b
= BT_FROM_COMMON(ft_b
);
4210 if (array_ft_a
->length
!= array_ft_b
->length
) {
4211 BT_LOGV("Structure field types differ: different lengths: "
4212 "ft-a-length=%u, ft-b-length=%u",
4213 array_ft_a
->length
, array_ft_b
->length
);
4218 ret
= bt_field_type_common_compare(array_ft_a
->element_ft
,
4219 array_ft_b
->element_ft
);
4221 BT_LOGV("Array field types differ: different element field types: "
4222 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
4223 array_ft_a
->element_ft
, array_ft_b
->element_ft
);
4231 int bt_field_type_common_sequence_compare_recursive(
4232 struct bt_field_type_common
*ft_a
,
4233 struct bt_field_type_common
*ft_b
)
4236 struct bt_field_type_common_sequence
*seq_ft_a
= BT_FROM_COMMON(ft_a
);
4237 struct bt_field_type_common_sequence
*seq_ft_b
= BT_FROM_COMMON(ft_b
);
4240 if (strcmp(seq_ft_a
->length_field_name
->str
,
4241 seq_ft_b
->length_field_name
->str
)) {
4242 BT_LOGV("Sequence field types differ: different length field names: "
4243 "ft-a-length-field-name=\"%s\", "
4244 "ft-b-length-field-name=\"%s\"",
4245 seq_ft_a
->length_field_name
->str
,
4246 seq_ft_b
->length_field_name
->str
);
4251 ret
= bt_field_type_common_compare(seq_ft_a
->element_ft
,
4252 seq_ft_b
->element_ft
);
4254 BT_LOGV("Sequence field types differ: different element field types: "
4255 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
4256 seq_ft_a
->element_ft
, seq_ft_b
->element_ft
);
4264 int bt_field_type_common_compare(struct bt_field_type_common
*ft_a
,
4265 struct bt_field_type_common
*ft_b
)
4269 BT_ASSERT_PRE_NON_NULL(ft_a
, "Field type A");
4270 BT_ASSERT_PRE_NON_NULL(ft_b
, "Field type B");
4273 /* Same reference: equal (even if both are NULL) */
4279 BT_LOGW_STR("Invalid parameter: field type A is NULL.");
4285 BT_LOGW_STR("Invalid parameter: field type B is NULL.");
4290 if (ft_a
->id
!= ft_b
->id
) {
4291 /* Different type IDs */
4292 BT_LOGV("Field types differ: different IDs: "
4293 "ft-a-addr=%p, ft-b-addr=%p, "
4294 "ft-a-id=%s, ft-b-id=%s",
4296 bt_common_field_type_id_string(ft_a
->id
),
4297 bt_common_field_type_id_string(ft_b
->id
));
4301 if (ft_a
->id
== BT_FIELD_TYPE_ID_UNKNOWN
) {
4302 /* Both have unknown type IDs */
4303 BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
4307 BT_ASSERT(ft_a
->methods
->compare
);
4308 ret
= ft_a
->methods
->compare(ft_a
, ft_b
);
4310 BT_LOGV("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
4318 int bt_field_type_compare(struct bt_field_type
*ft_a
,
4319 struct bt_field_type
*ft_b
)
4321 return bt_field_type_common_compare((void *) ft_a
, (void *) ft_b
);
4325 int64_t bt_field_type_common_get_field_count(struct bt_field_type_common
*ft
)
4327 int64_t field_count
= -1;
4330 case BT_FIELD_TYPE_ID_STRUCT
:
4332 bt_field_type_common_structure_get_field_count(ft
);
4334 case BT_FIELD_TYPE_ID_VARIANT
:
4336 bt_field_type_common_variant_get_field_count(ft
);
4338 case BT_FIELD_TYPE_ID_ARRAY
:
4339 case BT_FIELD_TYPE_ID_SEQUENCE
:
4341 * Array and sequence types always contain a single member
4342 * (the element type).
4354 struct bt_field_type_common
*bt_field_type_common_get_field_at_index(
4355 struct bt_field_type_common
*ft
, int index
)
4357 struct bt_field_type_common
*field_type
= NULL
;
4360 case BT_FIELD_TYPE_ID_STRUCT
:
4362 int ret
= bt_field_type_common_structure_get_field_by_index(
4363 ft
, NULL
, &field_type
, index
);
4370 case BT_FIELD_TYPE_ID_VARIANT
:
4372 int ret
= bt_field_type_common_variant_get_field_by_index(
4373 ft
, NULL
, &field_type
, index
);
4380 case BT_FIELD_TYPE_ID_ARRAY
:
4381 field_type
= bt_field_type_common_array_get_element_field_type(ft
);
4383 case BT_FIELD_TYPE_ID_SEQUENCE
:
4384 field_type
= bt_field_type_common_sequence_get_element_field_type(ft
);
4395 int bt_field_type_common_get_field_index(struct bt_field_type_common
*ft
,
4398 int field_index
= -1;
4401 case BT_FIELD_TYPE_ID_STRUCT
:
4402 field_index
= bt_field_type_common_structure_get_field_name_index(
4405 case BT_FIELD_TYPE_ID_VARIANT
:
4406 field_index
= bt_field_type_common_variant_get_field_name_index(
4417 struct bt_field_path
*bt_field_type_common_variant_get_tag_field_path(
4418 struct bt_field_type_common
*ft
)
4420 struct bt_field_type_common_variant
*var_ft
= BT_FROM_COMMON(ft
);
4422 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
4423 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
4425 return bt_get(var_ft
->tag_field_path
);
4428 struct bt_field_path
*bt_field_type_variant_get_tag_field_path(
4429 struct bt_field_type
*ft
)
4431 return bt_field_type_common_variant_get_tag_field_path((void *) ft
);
4435 struct bt_field_path
*bt_field_type_common_sequence_get_length_field_path(
4436 struct bt_field_type_common
*ft
)
4438 struct bt_field_type_common_sequence
*seq_ft
= BT_FROM_COMMON(ft
);
4440 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
4441 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft
, BT_FIELD_TYPE_ID_SEQUENCE
,
4443 return bt_get(seq_ft
->length_field_path
);
4446 struct bt_field_path
*bt_field_type_sequence_get_length_field_path(
4447 struct bt_field_type
*ft
)
4449 return bt_field_type_common_sequence_get_length_field_path((void *) ft
);
4453 int bt_field_type_common_validate_single_clock_class(
4454 struct bt_field_type_common
*ft
,
4455 struct bt_clock_class
**expected_clock_class
)
4463 BT_ASSERT(expected_clock_class
);
4466 case BT_FIELD_TYPE_ID_INTEGER
:
4468 struct bt_clock_class
*mapped_clock_class
=
4469 bt_field_type_common_integer_get_mapped_clock_class(ft
);
4471 if (!mapped_clock_class
) {
4475 if (!*expected_clock_class
) {
4476 /* Move reference to output parameter */
4477 *expected_clock_class
= mapped_clock_class
;
4478 mapped_clock_class
= NULL
;
4479 BT_LOGV("Setting expected clock class: "
4480 "expected-clock-class-addr=%p",
4481 *expected_clock_class
);
4483 if (mapped_clock_class
!= *expected_clock_class
) {
4484 BT_LOGW("Integer field type is not mapped to "
4485 "the expected clock class: "
4486 "mapped-clock-class-addr=%p, "
4487 "mapped-clock-class-name=\"%s\", "
4488 "expected-clock-class-addr=%p, "
4489 "expected-clock-class-name=\"%s\"",
4491 bt_clock_class_get_name(mapped_clock_class
),
4492 *expected_clock_class
,
4493 bt_clock_class_get_name(*expected_clock_class
));
4494 bt_put(mapped_clock_class
);
4500 bt_put(mapped_clock_class
);
4503 case BT_FIELD_TYPE_ID_ENUM
:
4504 case BT_FIELD_TYPE_ID_ARRAY
:
4505 case BT_FIELD_TYPE_ID_SEQUENCE
:
4507 struct bt_field_type_common
*sub_ft
= NULL
;
4510 case BT_FIELD_TYPE_ID_ENUM
:
4511 sub_ft
= bt_field_type_common_enumeration_get_container_field_type(
4514 case BT_FIELD_TYPE_ID_ARRAY
:
4515 sub_ft
= bt_field_type_common_array_get_element_field_type(
4518 case BT_FIELD_TYPE_ID_SEQUENCE
:
4519 sub_ft
= bt_field_type_common_sequence_get_element_field_type(
4523 BT_LOGF("Unexpected field type ID: id=%d", ft
->id
);
4528 ret
= bt_field_type_common_validate_single_clock_class(sub_ft
,
4529 expected_clock_class
);
4533 case BT_FIELD_TYPE_ID_STRUCT
:
4536 int64_t count
= bt_field_type_common_structure_get_field_count(
4539 for (i
= 0; i
< count
; i
++) {
4541 struct bt_field_type_common
*member_type
;
4543 ret
= bt_field_type_common_structure_get_field_by_index(
4544 ft
, &name
, &member_type
, i
);
4545 BT_ASSERT(ret
== 0);
4546 ret
= bt_field_type_common_validate_single_clock_class(
4547 member_type
, expected_clock_class
);
4548 bt_put(member_type
);
4550 BT_LOGW("Structure field type's field's type "
4551 "is not recursively mapped to the "
4552 "expected clock class: "
4553 "field-ft-addr=%p, field-name=\"%s\"",
4560 case BT_FIELD_TYPE_ID_VARIANT
:
4563 int64_t count
= bt_field_type_common_variant_get_field_count(
4566 for (i
= 0; i
< count
; i
++) {
4568 struct bt_field_type_common
*member_type
;
4570 ret
= bt_field_type_common_variant_get_field_by_index(
4571 ft
, &name
, &member_type
, i
);
4572 BT_ASSERT(ret
== 0);
4573 ret
= bt_field_type_common_validate_single_clock_class(
4574 member_type
, expected_clock_class
);
4575 bt_put(member_type
);
4577 BT_LOGW("Variant field type's field's type "
4578 "is not recursively mapped to the "
4579 "expected clock class: "
4580 "field-ft-addr=%p, field-name=\"%s\"",
4596 struct bt_field_type
*bt_field_type_integer_copy(
4597 struct bt_field_type
*ft
)
4599 struct bt_field_type_common_integer
*int_ft
= (void *) ft
;
4600 struct bt_field_type_common_integer
*copy_ft
;
4602 BT_LOGD("Copying CTF writer integer field type's: addr=%p", ft
);
4603 copy_ft
= (void *) bt_field_type_integer_create(int_ft
->size
);
4605 BT_LOGE_STR("Cannot create CTF writer integer field type.");
4609 copy_ft
->mapped_clock_class
= bt_get(int_ft
->mapped_clock_class
);
4610 copy_ft
->user_byte_order
= int_ft
->user_byte_order
;
4611 copy_ft
->is_signed
= int_ft
->is_signed
;
4612 copy_ft
->size
= int_ft
->size
;
4613 copy_ft
->base
= int_ft
->base
;
4614 copy_ft
->encoding
= int_ft
->encoding
;
4615 BT_LOGD("Copied CTF writer integer field type: original-ft-addr=%p, copy-ft-addr=%p",
4619 return (void *) copy_ft
;
4623 struct bt_field_type
*bt_field_type_enumeration_copy_recursive(
4624 struct bt_field_type
*ft
)
4627 struct bt_field_type_common_enumeration
*enum_ft
= (void *) ft
;
4628 struct bt_field_type_common_enumeration
*copy_ft
= NULL
;
4629 struct bt_field_type_common_enumeration
*container_copy_ft
;
4631 BT_LOGD("Copying CTF writer enumeration field type's: addr=%p", ft
);
4633 /* Copy the source enumeration's container */
4634 BT_LOGD_STR("Copying CTF writer enumeration field type's container field type.");
4635 container_copy_ft
= BT_FROM_COMMON(bt_field_type_common_copy(
4636 BT_TO_COMMON(enum_ft
->container_ft
)));
4637 if (!container_copy_ft
) {
4638 BT_LOGE_STR("Cannot copy CTF writer enumeration field type's container field type.");
4642 copy_ft
= (void *) bt_field_type_enumeration_create(
4643 (void *) container_copy_ft
);
4645 BT_LOGE_STR("Cannot create CTF writer enumeration field type.");
4649 /* Copy all enumaration entries */
4650 for (i
= 0; i
< enum_ft
->entries
->len
; i
++) {
4651 struct enumeration_mapping
*mapping
= g_ptr_array_index(
4652 enum_ft
->entries
, i
);
4653 struct enumeration_mapping
*copy_mapping
= g_new0(
4654 struct enumeration_mapping
, 1);
4656 if (!copy_mapping
) {
4657 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
4661 *copy_mapping
= *mapping
;
4662 g_ptr_array_add(copy_ft
->entries
, copy_mapping
);
4665 BT_LOGD("Copied CTF writer enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
4669 bt_put(container_copy_ft
);
4670 return (void *) copy_ft
;
4673 bt_put(container_copy_ft
);
4675 return (void *) copy_ft
;
4679 struct bt_field_type
*bt_field_type_floating_point_copy(
4680 struct bt_field_type
*ft
)
4682 struct bt_field_type_common_floating_point
*flt_ft
= BT_FROM_COMMON(ft
);
4683 struct bt_field_type_common_floating_point
*copy_ft
;
4685 BT_LOGD("Copying CTF writer floating point number field type's: addr=%p", ft
);
4686 copy_ft
= (void *) bt_field_type_floating_point_create();
4688 BT_LOGE_STR("Cannot create CTF writer floating point number field type.");
4692 copy_ft
->user_byte_order
= flt_ft
->user_byte_order
;
4693 copy_ft
->exp_dig
= flt_ft
->exp_dig
;
4694 copy_ft
->mant_dig
= flt_ft
->mant_dig
;
4695 BT_LOGD("Copied CTF writer floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
4699 return (void *) copy_ft
;
4703 struct bt_field_type
*bt_field_type_structure_copy_recursive(
4704 struct bt_field_type
*ft
)
4707 GHashTableIter iter
;
4708 gpointer key
, value
;
4709 struct bt_field_type_common_structure
*struct_ft
= (void *) ft
;
4710 struct bt_field_type_common_structure
*copy_ft
;
4712 BT_LOGD("Copying CTF writer structure field type's: addr=%p", ft
);
4713 copy_ft
= (void *) bt_field_type_structure_create();
4715 BT_LOGE_STR("Cannot create CTF writer structure field type.");
4719 /* Copy field_name_to_index */
4720 g_hash_table_iter_init(&iter
, struct_ft
->field_name_to_index
);
4721 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
4722 g_hash_table_insert(copy_ft
->field_name_to_index
,
4726 for (i
= 0; i
< struct_ft
->fields
->len
; i
++) {
4727 struct structure_field_common
*entry
, *copy_entry
;
4728 struct bt_field_type_common
*field_ft_copy
;
4730 entry
= g_ptr_array_index(struct_ft
->fields
, i
);
4731 BT_LOGD("Copying CTF writer structure field type's field: "
4732 "index=%" PRId64
", "
4733 "field-ft-addr=%p, field-name=\"%s\"",
4734 i
, entry
, g_quark_to_string(entry
->name
));
4735 copy_entry
= g_new0(struct structure_field_common
, 1);
4737 BT_LOGE_STR("Failed to allocate one structure field type field.");
4741 field_ft_copy
= (void *) bt_field_type_copy(
4742 (void *) entry
->type
);
4743 if (!field_ft_copy
) {
4744 BT_LOGE("Cannot copy CTF writer structure field type's field: "
4745 "index=%" PRId64
", "
4746 "field-ft-addr=%p, field-name=\"%s\"",
4747 i
, entry
, g_quark_to_string(entry
->name
));
4752 copy_entry
->name
= entry
->name
;
4753 copy_entry
->type
= field_ft_copy
;
4754 g_ptr_array_add(copy_ft
->fields
, copy_entry
);
4757 BT_LOGD("Copied CTF writer structure field type: original-ft-addr=%p, copy-ft-addr=%p",
4761 return (void *) copy_ft
;
4769 struct bt_field_type
*bt_field_type_variant_copy_recursive(
4770 struct bt_field_type
*ft
)
4773 GHashTableIter iter
;
4774 gpointer key
, value
;
4775 struct bt_field_type_common
*tag_ft_copy
= NULL
;
4776 struct bt_field_type_common_variant
*var_ft
= (void *) ft
;
4777 struct bt_field_type_common_variant
*copy_ft
= NULL
;
4779 BT_LOGD("Copying CTF writer variant field type's: addr=%p", ft
);
4780 if (var_ft
->tag_ft
) {
4781 BT_LOGD_STR("Copying CTF writer variant field type's tag field type.");
4782 tag_ft_copy
= bt_field_type_common_copy(
4783 BT_TO_COMMON(var_ft
->tag_ft
));
4785 BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field type.");
4790 copy_ft
= (void *) bt_field_type_variant_create(
4791 (void *) tag_ft_copy
,
4792 var_ft
->tag_name
->len
? var_ft
->tag_name
->str
: NULL
);
4794 BT_LOGE_STR("Cannot create CTF writer variant field type.");
4798 /* Copy field_name_to_index */
4799 g_hash_table_iter_init(&iter
, var_ft
->field_name_to_index
);
4800 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
4801 g_hash_table_insert(copy_ft
->field_name_to_index
,
4805 for (i
= 0; i
< var_ft
->fields
->len
; i
++) {
4806 struct structure_field_common
*entry
, *copy_entry
;
4807 struct bt_field_type_common
*field_ft_copy
;
4809 entry
= g_ptr_array_index(var_ft
->fields
, i
);
4810 BT_LOGD("Copying CTF writer variant field type's field: "
4811 "index=%" PRId64
", "
4812 "field-ft-addr=%p, field-name=\"%s\"",
4813 i
, entry
, g_quark_to_string(entry
->name
));
4814 copy_entry
= g_new0(struct structure_field_common
, 1);
4816 BT_LOGE_STR("Failed to allocate one variant field type field.");
4820 field_ft_copy
= (void *) bt_field_type_copy(
4821 (void *) entry
->type
);
4822 if (!field_ft_copy
) {
4823 BT_LOGE("Cannot copy CTF writer variant field type's field: "
4824 "index=%" PRId64
", "
4825 "field-ft-addr=%p, field-name=\"%s\"",
4826 i
, entry
, g_quark_to_string(entry
->name
));
4831 copy_entry
->name
= entry
->name
;
4832 copy_entry
->type
= field_ft_copy
;
4833 g_ptr_array_add(copy_ft
->fields
, copy_entry
);
4836 if (var_ft
->tag_field_path
) {
4837 BT_LOGD_STR("Copying CTF writer variant field type's tag field path.");
4838 copy_ft
->tag_field_path
= bt_field_path_copy(
4839 var_ft
->tag_field_path
);
4840 if (!copy_ft
->tag_field_path
) {
4841 BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field path.");
4846 BT_LOGD("Copied variant field type: original-ft-addr=%p, copy-ft-addr=%p",
4850 bt_put(tag_ft_copy
);
4851 return (void *) copy_ft
;
4854 bt_put(tag_ft_copy
);
4860 struct bt_field_type
*bt_field_type_array_copy_recursive(
4861 struct bt_field_type
*ft
)
4863 struct bt_field_type_common
*container_ft_copy
= NULL
;
4864 struct bt_field_type_common_array
*array_ft
= (void *) ft
;
4865 struct bt_field_type_common_array
*copy_ft
= NULL
;
4867 BT_LOGD("Copying CTF writer array field type's: addr=%p", ft
);
4868 BT_LOGD_STR("Copying CTF writer array field type's element field type.");
4869 container_ft_copy
= bt_field_type_common_copy(array_ft
->element_ft
);
4870 if (!container_ft_copy
) {
4871 BT_LOGE_STR("Cannot copy CTF writer array field type's element field type.");
4875 copy_ft
= (void *) bt_field_type_array_create(
4876 (void *) container_ft_copy
, array_ft
->length
);
4878 BT_LOGE_STR("Cannot create CTF writer array field type.");
4882 BT_LOGD("Copied CTF writer array field type: original-ft-addr=%p, copy-ft-addr=%p",
4886 bt_put(container_ft_copy
);
4887 return (void *) copy_ft
;
4891 struct bt_field_type
*bt_field_type_sequence_copy_recursive(
4892 struct bt_field_type
*ft
)
4894 struct bt_field_type_common
*container_ft_copy
= NULL
;
4895 struct bt_field_type_common_sequence
*seq_ft
= (void *) ft
;
4896 struct bt_field_type_common_sequence
*copy_ft
= NULL
;
4898 BT_LOGD("Copying CTF writer sequence field type's: addr=%p", ft
);
4899 BT_LOGD_STR("Copying CTF writer sequence field type's element field type.");
4900 container_ft_copy
= bt_field_type_common_copy(seq_ft
->element_ft
);
4901 if (!container_ft_copy
) {
4902 BT_LOGE_STR("Cannot copy CTF writer sequence field type's element field type.");
4906 copy_ft
= (void *) bt_field_type_sequence_create(
4907 (void *) container_ft_copy
,
4908 seq_ft
->length_field_name
->len
?
4909 seq_ft
->length_field_name
->str
: NULL
);
4911 BT_LOGE_STR("Cannot create CTF writer sequence field type.");
4915 if (seq_ft
->length_field_path
) {
4916 BT_LOGD_STR("Copying CTF writer sequence field type's length field path.");
4917 copy_ft
->length_field_path
= bt_field_path_copy(
4918 seq_ft
->length_field_path
);
4919 if (!copy_ft
->length_field_path
) {
4920 BT_LOGE_STR("Cannot copy CTF writer sequence field type's length field path.");
4925 BT_LOGD("Copied CTF writer sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
4929 bt_put(container_ft_copy
);
4930 return (void *) copy_ft
;
4932 bt_put(container_ft_copy
);
4938 struct bt_field_type
*bt_field_type_string_copy(struct bt_field_type
*ft
)
4940 struct bt_field_type_common_string
*string_ft
= (void *) ft
;
4941 struct bt_field_type_common_string
*copy_ft
= NULL
;
4943 BT_LOGD("Copying CTF writer string field type's: addr=%p", ft
);
4944 copy_ft
= (void *) bt_field_type_string_create();
4946 BT_LOGE_STR("Cannot create CTF writer string field type.");
4950 copy_ft
->encoding
= string_ft
->encoding
;
4951 BT_LOGD("Copied CTF writer string field type: original-ft-addr=%p, copy-ft-addr=%p",
4955 return (void *) copy_ft
;