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/ctf-ir/field-types-internal.h>
33 #include <babeltrace/ctf-ir/field-path-internal.h>
34 #include <babeltrace/ctf-ir/utils.h>
35 #include <babeltrace/ref.h>
36 #include <babeltrace/ctf-ir/clock-class.h>
37 #include <babeltrace/ctf-ir/clock-class-internal.h>
38 #include <babeltrace/ctf-writer/writer-internal.h>
39 #include <babeltrace/object-internal.h>
40 #include <babeltrace/ref.h>
41 #include <babeltrace/compiler-internal.h>
42 #include <babeltrace/endian-internal.h>
47 struct range_overlap_query
{
62 void bt_field_type_destroy(struct bt_object
*);
64 void bt_field_type_integer_destroy(struct bt_field_type
*);
66 void bt_field_type_enumeration_destroy(struct bt_field_type
*);
68 void bt_field_type_floating_point_destroy(struct bt_field_type
*);
70 void bt_field_type_structure_destroy(struct bt_field_type
*);
72 void bt_field_type_variant_destroy(struct bt_field_type
*);
74 void bt_field_type_array_destroy(struct bt_field_type
*);
76 void bt_field_type_sequence_destroy(struct bt_field_type
*);
78 void bt_field_type_string_destroy(struct bt_field_type
*);
81 void (* const type_destroy_funcs
[])(struct bt_field_type
*) = {
82 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_destroy
,
83 [BT_FIELD_TYPE_ID_ENUM
] =
84 bt_field_type_enumeration_destroy
,
85 [BT_FIELD_TYPE_ID_FLOAT
] =
86 bt_field_type_floating_point_destroy
,
87 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_type_structure_destroy
,
88 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_destroy
,
89 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_destroy
,
90 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_destroy
,
91 [BT_FIELD_TYPE_ID_STRING
] = bt_field_type_string_destroy
,
95 void generic_field_type_freeze(struct bt_field_type
*);
97 void bt_field_type_integer_freeze(struct bt_field_type
*);
99 void bt_field_type_enumeration_freeze(struct bt_field_type
*);
101 void bt_field_type_structure_freeze(struct bt_field_type
*);
103 void bt_field_type_variant_freeze(struct bt_field_type
*);
105 void bt_field_type_array_freeze(struct bt_field_type
*);
107 void bt_field_type_sequence_freeze(struct bt_field_type
*);
110 type_freeze_func
const type_freeze_funcs
[] = {
111 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_freeze
,
112 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_type_enumeration_freeze
,
113 [BT_FIELD_TYPE_ID_FLOAT
] = generic_field_type_freeze
,
114 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_type_structure_freeze
,
115 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_freeze
,
116 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_freeze
,
117 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_freeze
,
118 [BT_FIELD_TYPE_ID_STRING
] = generic_field_type_freeze
,
122 int bt_field_type_integer_serialize(struct bt_field_type
*,
123 struct metadata_context
*);
125 int bt_field_type_enumeration_serialize(struct bt_field_type
*,
126 struct metadata_context
*);
128 int bt_field_type_floating_point_serialize(
129 struct bt_field_type
*, struct metadata_context
*);
131 int bt_field_type_structure_serialize(struct bt_field_type
*,
132 struct metadata_context
*);
134 int bt_field_type_variant_serialize(struct bt_field_type
*,
135 struct metadata_context
*);
137 int bt_field_type_array_serialize(struct bt_field_type
*,
138 struct metadata_context
*);
140 int bt_field_type_sequence_serialize(struct bt_field_type
*,
141 struct metadata_context
*);
143 int bt_field_type_string_serialize(struct bt_field_type
*,
144 struct metadata_context
*);
147 type_serialize_func
const type_serialize_funcs
[] = {
148 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_serialize
,
149 [BT_FIELD_TYPE_ID_ENUM
] =
150 bt_field_type_enumeration_serialize
,
151 [BT_FIELD_TYPE_ID_FLOAT
] =
152 bt_field_type_floating_point_serialize
,
153 [BT_FIELD_TYPE_ID_STRUCT
] =
154 bt_field_type_structure_serialize
,
155 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_serialize
,
156 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_serialize
,
157 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_serialize
,
158 [BT_FIELD_TYPE_ID_STRING
] = bt_field_type_string_serialize
,
162 void bt_field_type_integer_set_byte_order(struct bt_field_type
*,
163 enum bt_byte_order byte_order
);
165 void bt_field_type_enumeration_set_byte_order(struct bt_field_type
*,
166 enum bt_byte_order byte_order
);
168 void bt_field_type_floating_point_set_byte_order(
169 struct bt_field_type
*, enum bt_byte_order byte_order
);
171 void bt_field_type_structure_set_byte_order(struct bt_field_type
*,
172 enum bt_byte_order byte_order
);
174 void bt_field_type_variant_set_byte_order(struct bt_field_type
*,
175 enum bt_byte_order byte_order
);
177 void bt_field_type_array_set_byte_order(struct bt_field_type
*,
178 enum bt_byte_order byte_order
);
180 void bt_field_type_sequence_set_byte_order(struct bt_field_type
*,
181 enum bt_byte_order byte_order
);
184 void (* const set_byte_order_funcs
[])(struct bt_field_type
*,
185 enum bt_byte_order
) = {
186 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_set_byte_order
,
187 [BT_FIELD_TYPE_ID_ENUM
] =
188 bt_field_type_enumeration_set_byte_order
,
189 [BT_FIELD_TYPE_ID_FLOAT
] =
190 bt_field_type_floating_point_set_byte_order
,
191 [BT_FIELD_TYPE_ID_STRUCT
] =
192 bt_field_type_structure_set_byte_order
,
193 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_set_byte_order
,
194 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_set_byte_order
,
195 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_set_byte_order
,
196 [BT_FIELD_TYPE_ID_STRING
] = NULL
,
200 struct bt_field_type
*bt_field_type_integer_copy(
201 struct bt_field_type
*);
203 struct bt_field_type
*bt_field_type_enumeration_copy(
204 struct bt_field_type
*);
206 struct bt_field_type
*bt_field_type_floating_point_copy(
207 struct bt_field_type
*);
209 struct bt_field_type
*bt_field_type_structure_copy(
210 struct bt_field_type
*);
212 struct bt_field_type
*bt_field_type_variant_copy(
213 struct bt_field_type
*);
215 struct bt_field_type
*bt_field_type_array_copy(
216 struct bt_field_type
*);
218 struct bt_field_type
*bt_field_type_sequence_copy(
219 struct bt_field_type
*);
221 struct bt_field_type
*bt_field_type_string_copy(
222 struct bt_field_type
*);
225 struct bt_field_type
*(* const type_copy_funcs
[])(
226 struct bt_field_type
*) = {
227 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_copy
,
228 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_type_enumeration_copy
,
229 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_type_floating_point_copy
,
230 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_type_structure_copy
,
231 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_copy
,
232 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_copy
,
233 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_copy
,
234 [BT_FIELD_TYPE_ID_STRING
] = bt_field_type_string_copy
,
238 int bt_field_type_integer_compare(struct bt_field_type
*,
239 struct bt_field_type
*);
241 int bt_field_type_floating_point_compare(struct bt_field_type
*,
242 struct bt_field_type
*);
244 int bt_field_type_enumeration_compare(struct bt_field_type
*,
245 struct bt_field_type
*);
247 int bt_field_type_string_compare(struct bt_field_type
*,
248 struct bt_field_type
*);
250 int bt_field_type_structure_compare(struct bt_field_type
*,
251 struct bt_field_type
*);
253 int bt_field_type_variant_compare(struct bt_field_type
*,
254 struct bt_field_type
*);
256 int bt_field_type_array_compare(struct bt_field_type
*,
257 struct bt_field_type
*);
259 int bt_field_type_sequence_compare(struct bt_field_type
*,
260 struct bt_field_type
*);
263 int (* const type_compare_funcs
[])(struct bt_field_type
*,
264 struct bt_field_type
*) = {
265 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_compare
,
266 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_type_enumeration_compare
,
267 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_type_floating_point_compare
,
268 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_type_structure_compare
,
269 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_compare
,
270 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_compare
,
271 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_compare
,
272 [BT_FIELD_TYPE_ID_STRING
] = bt_field_type_string_compare
,
276 int bt_field_type_integer_validate(struct bt_field_type
*);
278 int bt_field_type_enumeration_validate(struct bt_field_type
*);
280 int bt_field_type_structure_validate(struct bt_field_type
*);
282 int bt_field_type_variant_validate(struct bt_field_type
*);
284 int bt_field_type_array_validate(struct bt_field_type
*);
286 int bt_field_type_sequence_validate(struct bt_field_type
*);
289 int (* const type_validate_funcs
[])(struct bt_field_type
*) = {
290 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_type_integer_validate
,
291 [BT_FIELD_TYPE_ID_FLOAT
] = NULL
,
292 [BT_FIELD_TYPE_ID_STRING
] = NULL
,
293 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_type_enumeration_validate
,
294 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_type_structure_validate
,
295 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_type_variant_validate
,
296 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_type_array_validate
,
297 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_type_sequence_validate
,
301 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
307 void destroy_structure_field(struct structure_field
*field
)
313 BT_LOGD("Destroying structure/variant field type's field object: "
314 "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
315 field
, field
->type
, g_quark_to_string(field
->name
));
316 BT_LOGD_STR("Putting field type.");
322 void check_ranges_overlap(gpointer element
, gpointer query
)
324 struct enumeration_mapping
*mapping
= element
;
325 struct range_overlap_query
*overlap_query
= query
;
327 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
328 && overlap_query
->range_start
._signed
<=
329 mapping
->range_end
._signed
) {
330 overlap_query
->overlaps
= 1;
331 overlap_query
->mapping_name
= mapping
->string
;
334 overlap_query
->overlaps
|=
335 mapping
->string
== overlap_query
->mapping_name
;
337 if (overlap_query
->overlaps
) {
338 BT_LOGV("Overlapping enumeration field type mappings: "
339 "mapping-name=\"%s\", "
340 "mapping-a-range-start=%" PRId64
", "
341 "mapping-a-range-end=%" PRId64
", "
342 "mapping-b-range-start=%" PRId64
", "
343 "mapping-b-range-end=%" PRId64
,
344 g_quark_to_string(mapping
->string
),
345 mapping
->range_start
._signed
,
346 mapping
->range_end
._signed
,
347 overlap_query
->range_start
._signed
,
348 overlap_query
->range_end
._signed
);
353 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
355 struct enumeration_mapping
*mapping
= element
;
356 struct range_overlap_query
*overlap_query
= query
;
358 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
359 && overlap_query
->range_start
._unsigned
<=
360 mapping
->range_end
._unsigned
) {
361 overlap_query
->overlaps
= 1;
362 overlap_query
->mapping_name
= mapping
->string
;
365 overlap_query
->overlaps
|=
366 mapping
->string
== overlap_query
->mapping_name
;
368 if (overlap_query
->overlaps
) {
369 BT_LOGW("Overlapping enumeration field type mappings: "
370 "mapping-name=\"%s\", "
371 "mapping-a-range-start=%" PRIu64
", "
372 "mapping-a-range-end=%" PRIu64
", "
373 "mapping-b-range-start=%" PRIu64
", "
374 "mapping-b-range-end=%" PRIu64
,
375 g_quark_to_string(mapping
->string
),
376 mapping
->range_start
._unsigned
,
377 mapping
->range_end
._unsigned
,
378 overlap_query
->range_start
._unsigned
,
379 overlap_query
->range_end
._unsigned
);
384 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
385 struct enumeration_mapping
**b
)
387 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
391 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
392 struct enumeration_mapping
**b
)
394 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
398 void bt_field_type_init(struct bt_field_type
*type
, bt_bool init_bo
)
400 assert(type
&& (type
->id
> BT_FIELD_TYPE_ID_UNKNOWN
) &&
401 (type
->id
< BT_FIELD_TYPE_ID_NR
));
403 bt_object_init(type
, bt_field_type_destroy
);
404 type
->freeze
= type_freeze_funcs
[type
->id
];
405 type
->serialize
= type_serialize_funcs
[type
->id
];
409 const enum bt_byte_order bo
= BT_BYTE_ORDER_NATIVE
;
411 BT_LOGD("Setting initial field type's byte order: bo=%s",
412 bt_byte_order_string(bo
));
413 ret
= bt_field_type_set_byte_order(type
, bo
);
421 int add_structure_field(GPtrArray
*fields
,
422 GHashTable
*field_name_to_index
,
423 struct bt_field_type
*field_type
,
424 const char *field_name
)
427 GQuark name_quark
= g_quark_from_string(field_name
);
428 GQuark underscore_name_quark
;
429 struct structure_field
*field
;
430 GString
*underscore_name
= g_string_new(NULL
);
432 if (!underscore_name
) {
433 BT_LOGE_STR("Failed to allocate a GString.");
438 g_string_assign(underscore_name
, "_");
439 g_string_append(underscore_name
, field_name
);
440 underscore_name_quark
= g_quark_from_string(underscore_name
->str
);
442 /* Make sure structure does not contain a field of the same name */
443 if (g_hash_table_lookup_extended(field_name_to_index
,
444 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
445 BT_LOGW("Structure or variant field type already contains a field type with this name: "
446 "field-name=\"%s\"", field_name
);
451 if (g_hash_table_lookup_extended(field_name_to_index
,
452 GUINT_TO_POINTER(underscore_name_quark
), NULL
, NULL
)) {
453 BT_LOGW("Structure or variant field type already contains a field type with this name: "
454 "field-name=\"%s\"", underscore_name
->str
);
459 field
= g_new0(struct structure_field
, 1);
461 BT_LOGE_STR("Failed to allocate one structure/variant field type field.");
467 field
->name
= name_quark
;
468 field
->type
= field_type
;
469 g_hash_table_insert(field_name_to_index
,
470 GUINT_TO_POINTER(name_quark
),
471 GUINT_TO_POINTER(fields
->len
));
472 g_hash_table_insert(field_name_to_index
,
473 GUINT_TO_POINTER(underscore_name_quark
),
474 GUINT_TO_POINTER(fields
->len
));
475 g_ptr_array_add(fields
, field
);
476 BT_LOGV("Added structure/variant field type field: field-ft-addr=%p, "
477 "field-name=\"%s\"", field_type
, field_name
);
479 g_string_free(underscore_name
, TRUE
);
484 void bt_field_type_destroy(struct bt_object
*obj
)
486 struct bt_field_type
*type
;
487 enum bt_field_type_id type_id
;
489 type
= container_of(obj
, struct bt_field_type
, base
);
491 assert(type_id
> BT_FIELD_TYPE_ID_UNKNOWN
&&
492 type_id
< BT_FIELD_TYPE_ID_NR
);
493 type_destroy_funcs
[type_id
](type
);
497 int bt_field_type_integer_validate(struct bt_field_type
*type
)
501 struct bt_field_type_integer
*integer
=
502 container_of(type
, struct bt_field_type_integer
,
505 if (integer
->mapped_clock
&& integer
->is_signed
) {
506 BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
507 "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
508 type
, integer
->mapped_clock
,
509 bt_clock_class_get_name(integer
->mapped_clock
));
519 struct enumeration_mapping
*get_enumeration_mapping(
520 struct bt_field_type
*type
, uint64_t index
)
522 struct enumeration_mapping
*mapping
= NULL
;
523 struct bt_field_type_enumeration
*enumeration
;
525 enumeration
= container_of(type
, struct bt_field_type_enumeration
,
527 if (index
>= enumeration
->entries
->len
) {
528 BT_LOGW("Invalid parameter: index is out of bounds: "
529 "addr=%p, index=%" PRIu64
", count=%u",
530 type
, index
, enumeration
->entries
->len
);
534 mapping
= g_ptr_array_index(enumeration
->entries
, index
);
540 * Note: This algorithm is O(n^2) vs number of enumeration mappings.
541 * Only used when freezing an enumeration.
544 void set_enumeration_range_overlap(
545 struct bt_field_type
*type
)
548 struct bt_field_type
*container_type
;
549 struct bt_field_type_enumeration
*enumeration_type
;
552 BT_LOGV("Setting enumeration field type's overlap flag: addr=%p",
554 enumeration_type
= container_of(type
,
555 struct bt_field_type_enumeration
, parent
);
557 len
= enumeration_type
->entries
->len
;
558 container_type
= enumeration_type
->container
;
559 is_signed
= bt_field_type_integer_is_signed(container_type
);
561 for (i
= 0; i
< len
; i
++) {
562 for (j
= i
+ 1; j
< len
; j
++) {
563 struct enumeration_mapping
*mapping
[2];
565 mapping
[0] = get_enumeration_mapping(type
, i
);
566 mapping
[1] = get_enumeration_mapping(type
, j
);
568 if (mapping
[0]->range_start
._signed
569 <= mapping
[1]->range_end
._signed
570 && mapping
[0]->range_end
._signed
571 >= mapping
[1]->range_start
._signed
) {
572 enumeration_type
->has_overlapping_ranges
= BT_TRUE
;
576 if (mapping
[0]->range_start
._unsigned
577 <= mapping
[1]->range_end
._unsigned
578 && mapping
[0]->range_end
._unsigned
579 >= mapping
[1]->range_start
._unsigned
) {
580 enumeration_type
->has_overlapping_ranges
= BT_TRUE
;
588 if (enumeration_type
->has_overlapping_ranges
) {
589 BT_LOGV_STR("Enumeration field type has overlapping ranges.");
591 BT_LOGV_STR("Enumeration field type has no overlapping ranges.");
596 int bt_field_type_enumeration_validate(struct bt_field_type
*type
)
600 struct bt_field_type_enumeration
*enumeration
=
601 container_of(type
, struct bt_field_type_enumeration
,
603 struct bt_field_type
*container_type
=
604 bt_field_type_enumeration_get_container_type(type
);
606 assert(container_type
);
607 ret
= bt_field_type_validate(container_type
);
609 BT_LOGW("Invalid enumeration field type: container type is invalid: "
610 "enum-ft-addr=%p, int-ft-addr=%p",
611 type
, container_type
);
615 /* Ensure enum has entries */
616 if (enumeration
->entries
->len
== 0) {
617 BT_LOGW("Invalid enumeration field type: no entries: "
624 BT_PUT(container_type
);
629 int bt_field_type_sequence_validate(struct bt_field_type
*type
)
632 struct bt_field_type
*element_type
= NULL
;
633 struct bt_field_type_sequence
*sequence
=
634 container_of(type
, struct bt_field_type_sequence
,
637 /* Length field name should be set at this point */
638 if (sequence
->length_field_name
->len
== 0) {
639 BT_LOGW("Invalid sequence field type: no length field name: "
645 element_type
= bt_field_type_sequence_get_element_type(type
);
646 assert(element_type
);
647 ret
= bt_field_type_validate(element_type
);
649 BT_LOGW("Invalid sequence field type: invalid element field type: "
650 "seq-ft-addr=%p, element-ft-add=%p",
655 BT_PUT(element_type
);
661 int bt_field_type_array_validate(struct bt_field_type
*type
)
664 struct bt_field_type
*element_type
= NULL
;
666 element_type
= bt_field_type_array_get_element_type(type
);
667 assert(element_type
);
668 ret
= bt_field_type_validate(element_type
);
670 BT_LOGW("Invalid array field type: invalid element field type: "
671 "array-ft-addr=%p, element-ft-add=%p",
675 BT_PUT(element_type
);
680 int bt_field_type_structure_validate(struct bt_field_type
*type
)
683 struct bt_field_type
*child_type
= NULL
;
684 int64_t field_count
= bt_field_type_structure_get_field_count(type
);
687 assert(field_count
>= 0);
689 for (i
= 0; i
< field_count
; ++i
) {
690 const char *field_name
;
692 ret
= bt_field_type_structure_get_field_by_index(type
,
693 &field_name
, &child_type
, i
);
695 ret
= bt_field_type_validate(child_type
);
697 BT_LOGW("Invalid structure field type: "
698 "a contained field type is invalid: "
699 "struct-ft-addr=%p, field-ft-addr=%p, "
700 "field-name=\"%s\", field-index=%" PRId64
,
701 type
, child_type
, field_name
, i
);
715 bt_bool
bt_field_type_enumeration_has_overlapping_ranges(
716 struct bt_field_type_enumeration
*enumeration_type
)
718 if (!enumeration_type
->parent
.frozen
) {
719 set_enumeration_range_overlap(&enumeration_type
->parent
);
721 return enumeration_type
->has_overlapping_ranges
;
725 int bt_field_type_variant_validate(struct bt_field_type
*type
)
729 struct bt_field_type
*child_type
= NULL
;
730 struct bt_field_type_variant
*variant
=
731 container_of(type
, struct bt_field_type_variant
,
735 if (variant
->tag_name
->len
== 0) {
736 BT_LOGW("Invalid variant field type: no tag field name: "
743 BT_LOGW("Invalid variant field type: no tag field type: "
744 "addr=%p, tag-field-name=\"%s\"", type
,
745 variant
->tag_name
->str
);
750 if (bt_field_type_enumeration_has_overlapping_ranges(
752 BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
753 "variant-ft-addr=%p, tag-field-name=\"%s\", "
754 "enum-ft-addr=%p", type
, variant
->tag_name
->str
,
761 * It is valid to have a variant field type which does not have
762 * the fields corresponding to each label in the associated
765 * It is also valid to have variant field type fields which
766 * cannot be selected because the variant field type tag has no
767 * mapping named as such. This scenario, while not ideal, cannot
770 * If a non-existing field happens to be selected by an
771 * enumeration while reading a variant field, an error will be
772 * generated at that point (while reading the stream).
774 field_count
= bt_field_type_variant_get_field_count(type
);
775 if (field_count
< 0) {
776 BT_LOGW("Invalid variant field type: no fields: "
777 "addr=%p, tag-field-name=\"%s\"",
778 type
, variant
->tag_name
->str
);
783 for (i
= 0; i
< field_count
; ++i
) {
784 const char *field_name
;
786 ret
= bt_field_type_variant_get_field_by_index(type
,
787 &field_name
, &child_type
, i
);
789 ret
= bt_field_type_validate(child_type
);
791 BT_LOGW("Invalid variant field type: "
792 "a contained field type is invalid: "
793 "variant-ft-addr=%p, tag-field-name=\"%s\", "
794 "field-ft-addr=%p, field-name=\"%s\", "
795 "field-index=%" PRId64
,
796 type
, variant
->tag_name
->str
, child_type
,
811 * This function validates a given field type without considering
812 * where this field type is located. It only validates the properties
813 * of the given field type and the properties of its children if
817 int bt_field_type_validate(struct bt_field_type
*type
)
820 enum bt_field_type_id id
= bt_field_type_get_type_id(type
);
825 /* Already marked as valid */
829 if (type_validate_funcs
[id
]) {
830 ret
= type_validate_funcs
[id
](type
);
833 if (!ret
&& type
->frozen
) {
834 /* Field type is valid */
835 BT_LOGV("Marking field type as valid: addr=%p", type
);
843 struct bt_field_type
*bt_field_type_integer_create(unsigned int size
)
845 struct bt_field_type_integer
*integer
=
846 g_new0(struct bt_field_type_integer
, 1);
848 BT_LOGD("Creating integer field type object: size=%u", size
);
851 BT_LOGE_STR("Failed to allocate one integer field type.");
855 if (size
== 0 || size
> 64) {
856 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
861 integer
->parent
.id
= BT_FIELD_TYPE_ID_INTEGER
;
862 integer
->size
= size
;
863 integer
->base
= BT_INTEGER_BASE_DECIMAL
;
864 integer
->encoding
= BT_STRING_ENCODING_NONE
;
865 bt_field_type_init(&integer
->parent
, TRUE
);
866 BT_LOGD("Created integer field type object: addr=%p, size=%u",
867 &integer
->parent
, size
);
868 return &integer
->parent
;
871 int bt_field_type_integer_get_size(struct bt_field_type
*type
)
874 struct bt_field_type_integer
*integer
;
877 BT_LOGW_STR("Invalid parameter: field type is NULL.");
882 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
883 BT_LOGW("Invalid parameter: field type is not an integer field type: "
884 "addr=%p, ft-id=%s", type
,
885 bt_field_type_id_string(type
->id
));
890 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
891 ret
= (int) integer
->size
;
896 int bt_ctf_field_type_integer_get_signed(struct bt_field_type
*type
)
899 struct bt_field_type_integer
*integer
;
902 BT_LOGW_STR("Invalid parameter: field type is NULL.");
907 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
908 BT_LOGW("Invalid parameter: field type is not an integer field type: "
909 "addr=%p, ft-id=%s", type
,
910 bt_field_type_id_string(type
->id
));
915 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
916 ret
= integer
->is_signed
;
921 bt_bool
bt_field_type_integer_is_signed(
922 struct bt_field_type
*int_field_type
)
924 return bt_ctf_field_type_integer_get_signed(int_field_type
) ?
928 int bt_field_type_integer_set_is_signed(struct bt_field_type
*type
,
932 struct bt_field_type_integer
*integer
;
935 BT_LOGW_STR("Invalid parameter: field type is NULL.");
941 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
947 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
948 BT_LOGW("Invalid parameter: field type is not an integer field type: "
949 "addr=%p, ft-id=%s", type
,
950 bt_field_type_id_string(type
->id
));
955 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
956 integer
->is_signed
= !!is_signed
;
957 BT_LOGV("Set integer field type's signedness: addr=%p, is-signed=%d",
963 int bt_field_type_integer_set_size(struct bt_field_type
*type
,
967 struct bt_field_type_integer
*integer
;
970 BT_LOGW_STR("Invalid parameter: field type is NULL.");
976 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
982 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
983 BT_LOGW("Invalid parameter: field type is not an integer field type: "
984 "addr=%p, ft-id=%s", type
,
985 bt_field_type_id_string(type
->id
));
990 if (size
== 0 || size
> 64) {
991 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
992 "addr=%p, size=%u", type
, size
);
997 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
998 integer
->size
= size
;
999 BT_LOGV("Set integer field type's size: addr=%p, size=%u",
1005 enum bt_integer_base
bt_field_type_integer_get_base(
1006 struct bt_field_type
*type
)
1008 enum bt_integer_base ret
= BT_INTEGER_BASE_UNKNOWN
;
1009 struct bt_field_type_integer
*integer
;
1012 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1016 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1017 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1018 "addr=%p, ft-id=%s", type
,
1019 bt_field_type_id_string(type
->id
));
1023 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
1024 ret
= integer
->base
;
1029 int bt_field_type_integer_set_base(struct bt_field_type
*type
,
1030 enum bt_integer_base base
)
1035 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1041 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1047 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1048 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1049 "addr=%p, ft-id=%s", type
,
1050 bt_field_type_id_string(type
->id
));
1056 case BT_INTEGER_BASE_UNSPECIFIED
:
1057 case BT_INTEGER_BASE_BINARY
:
1058 case BT_INTEGER_BASE_OCTAL
:
1059 case BT_INTEGER_BASE_DECIMAL
:
1060 case BT_INTEGER_BASE_HEXADECIMAL
:
1062 struct bt_field_type_integer
*integer
= container_of(type
,
1063 struct bt_field_type_integer
, parent
);
1064 integer
->base
= base
;
1068 BT_LOGW("Invalid parameter: unknown integer field type base: "
1069 "addr=%p, base=%d", type
, base
);
1073 BT_LOGV("Set integer field type's base: addr=%p, base=%s",
1074 type
, bt_integer_base_string(base
));
1080 enum bt_string_encoding
bt_field_type_integer_get_encoding(
1081 struct bt_field_type
*type
)
1083 enum bt_string_encoding ret
= BT_STRING_ENCODING_UNKNOWN
;
1084 struct bt_field_type_integer
*integer
;
1087 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1091 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1092 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1093 "addr=%p, ft-id=%s", type
,
1094 bt_field_type_id_string(type
->id
));
1098 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
1099 ret
= integer
->encoding
;
1104 int bt_field_type_integer_set_encoding(struct bt_field_type
*type
,
1105 enum bt_string_encoding encoding
)
1108 struct bt_field_type_integer
*integer
;
1111 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1117 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1123 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1124 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1125 "addr=%p, ft-id=%s", type
,
1126 bt_field_type_id_string(type
->id
));
1131 if (encoding
!= BT_STRING_ENCODING_UTF8
&&
1132 encoding
!= BT_STRING_ENCODING_ASCII
&&
1133 encoding
!= BT_STRING_ENCODING_NONE
) {
1134 BT_LOGW("Invalid parameter: unknown string encoding: "
1135 "addr=%p, encoding=%d", type
, encoding
);
1140 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
1141 integer
->encoding
= encoding
;
1142 BT_LOGV("Set integer field type's encoding: addr=%p, encoding=%s",
1143 type
, bt_string_encoding_string(encoding
));
1148 struct bt_clock_class
*bt_field_type_integer_get_mapped_clock_class(
1149 struct bt_field_type
*type
)
1151 struct bt_field_type_integer
*integer
;
1152 struct bt_clock_class
*clock_class
= NULL
;
1155 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1159 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
1160 clock_class
= integer
->mapped_clock
;
1161 bt_get(clock_class
);
1167 int bt_field_type_integer_set_mapped_clock_class_no_check(
1168 struct bt_field_type
*type
,
1169 struct bt_clock_class
*clock_class
)
1171 struct bt_field_type_integer
*integer
;
1175 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1181 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
1186 if (type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1187 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1188 "addr=%p, ft-id=%s", type
,
1189 bt_field_type_id_string(type
->id
));
1193 if (!bt_clock_class_is_valid(clock_class
)) {
1194 BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
1195 "clock-class-addr=%p, clock-class-name=\"%s\"",
1197 bt_clock_class_get_name(clock_class
));
1202 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
1203 bt_put(integer
->mapped_clock
);
1204 integer
->mapped_clock
= bt_get(clock_class
);
1205 BT_LOGV("Set integer field type's mapped clock class: ft-addr=%p, "
1206 "clock-class-addr=%p, clock-class-name=\"%s\"",
1207 type
, clock_class
, bt_clock_class_get_name(clock_class
));
1212 int bt_field_type_integer_set_mapped_clock_class(
1213 struct bt_field_type
*type
,
1214 struct bt_clock_class
*clock_class
)
1219 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1225 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1231 ret
= bt_field_type_integer_set_mapped_clock_class_no_check(
1239 void bt_field_type_enum_iter_destroy(struct bt_object
*obj
)
1241 struct bt_field_type_enumeration_mapping_iterator
*iter
=
1243 struct bt_field_type_enumeration_mapping_iterator
,
1246 BT_LOGD("Destroying enumeration field type mapping iterator: addr=%p",
1248 BT_LOGD_STR("Putting parent enumeration field type.");
1249 bt_put(&iter
->enumeration_type
->parent
);
1254 struct bt_field_type_enumeration_mapping_iterator
*
1255 bt_field_type_enumeration_find_mappings_type(
1256 struct bt_field_type
*type
,
1257 enum bt_field_type_enumeration_mapping_iterator_type iterator_type
)
1259 struct bt_field_type_enumeration
*enumeration_type
;
1260 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1263 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1267 if (type
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1268 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1269 "addr=%p, ft-id=%s", type
,
1270 bt_field_type_id_string(type
->id
));
1274 enumeration_type
= container_of(type
,
1275 struct bt_field_type_enumeration
, parent
);
1276 iter
= g_new0(struct bt_field_type_enumeration_mapping_iterator
, 1);
1278 BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
1282 bt_object_init(&iter
->base
, bt_field_type_enum_iter_destroy
);
1284 iter
->enumeration_type
= enumeration_type
;
1286 iter
->type
= iterator_type
;
1291 struct bt_field_type_enumeration_mapping_iterator
*
1292 bt_field_type_enumeration_find_mappings_by_name(
1293 struct bt_field_type
*type
, const char *name
)
1295 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1297 iter
= bt_field_type_enumeration_find_mappings_type(
1298 type
, ITERATOR_BY_NAME
);
1300 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1301 "ft-addr=%p, mapping-name=\"%s\"", type
, name
);
1305 iter
->u
.name_quark
= g_quark_try_string(name
);
1306 if (!iter
->u
.name_quark
) {
1308 * No results are possible, set the iterator's position at the
1311 iter
->index
= iter
->enumeration_type
->entries
->len
;
1319 int bt_field_type_enumeration_mapping_iterator_next(
1320 struct bt_field_type_enumeration_mapping_iterator
*iter
)
1322 struct bt_field_type_enumeration
*enumeration
;
1323 struct bt_field_type
*type
;
1324 int i
, ret
= 0, len
;
1327 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1332 enumeration
= iter
->enumeration_type
;
1333 type
= &enumeration
->parent
;
1334 len
= enumeration
->entries
->len
;
1335 for (i
= iter
->index
+ 1; i
< len
; i
++) {
1336 struct enumeration_mapping
*mapping
=
1337 get_enumeration_mapping(type
, i
);
1339 switch (iter
->type
) {
1340 case ITERATOR_BY_NAME
:
1341 if (mapping
->string
== iter
->u
.name_quark
) {
1346 case ITERATOR_BY_SIGNED_VALUE
:
1348 int64_t value
= iter
->u
.signed_value
;
1350 if (value
>= mapping
->range_start
._signed
&&
1351 value
<= mapping
->range_end
._signed
) {
1357 case ITERATOR_BY_UNSIGNED_VALUE
:
1359 uint64_t value
= iter
->u
.unsigned_value
;
1361 if (value
>= mapping
->range_start
._unsigned
&&
1362 value
<= mapping
->range_end
._unsigned
) {
1369 BT_LOGF("Invalid enumeration field type mapping iterator type: "
1370 "type=%d", iter
->type
);
1380 struct bt_field_type_enumeration_mapping_iterator
*
1381 bt_field_type_enumeration_find_mappings_by_signed_value(
1382 struct bt_field_type
*type
, int64_t value
)
1384 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1386 iter
= bt_field_type_enumeration_find_mappings_type(
1387 type
, ITERATOR_BY_SIGNED_VALUE
);
1389 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1390 "ft-addr=%p, value=%" PRId64
, type
, value
);
1394 if (bt_ctf_field_type_integer_get_signed(
1395 iter
->enumeration_type
->container
) != 1) {
1396 BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
1397 "enum-ft-addr=%p, int-ft-addr=%p",
1398 type
, iter
->enumeration_type
->container
);
1402 iter
->u
.signed_value
= value
;
1409 struct bt_field_type_enumeration_mapping_iterator
*
1410 bt_field_type_enumeration_find_mappings_by_unsigned_value(
1411 struct bt_field_type
*type
, uint64_t value
)
1413 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1415 iter
= bt_field_type_enumeration_find_mappings_type(
1416 type
, ITERATOR_BY_UNSIGNED_VALUE
);
1418 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1419 "ft-addr=%p, value=%" PRIu64
, type
, value
);
1423 if (bt_ctf_field_type_integer_get_signed(
1424 iter
->enumeration_type
->container
) != 0) {
1425 BT_LOGW("Invalid parameter: enumeration field type is signed: "
1426 "enum-ft-addr=%p, int-ft-addr=%p",
1427 type
, iter
->enumeration_type
->container
);
1430 iter
->u
.unsigned_value
= value
;
1437 int bt_field_type_enumeration_mapping_iterator_get_signed(
1438 struct bt_field_type_enumeration_mapping_iterator
*iter
,
1439 const char **mapping_name
, int64_t *range_begin
,
1445 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1450 if (iter
->index
== -1) {
1451 BT_LOGW_STR("Invalid enumeration field type mapping iterator access: position=-1");
1456 ret
= bt_field_type_enumeration_get_mapping_signed(
1457 &iter
->enumeration_type
->parent
, iter
->index
,
1458 mapping_name
, range_begin
, range_end
);
1463 int bt_field_type_enumeration_mapping_iterator_get_unsigned(
1464 struct bt_field_type_enumeration_mapping_iterator
*iter
,
1465 const char **mapping_name
, uint64_t *range_begin
,
1466 uint64_t *range_end
)
1471 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1476 if (iter
->index
== -1) {
1477 BT_LOGW_STR("Invalid enumeration field type mapping iterator access: position=-1");
1482 ret
= bt_field_type_enumeration_get_mapping_unsigned(
1483 &iter
->enumeration_type
->parent
, iter
->index
,
1484 mapping_name
, range_begin
, range_end
);
1489 int bt_field_type_enumeration_get_mapping_signed(
1490 struct bt_field_type
*enum_field_type
,
1491 uint64_t index
, const char **mapping_name
, int64_t *range_begin
,
1495 struct enumeration_mapping
*mapping
;
1497 if (!enum_field_type
) {
1498 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1503 mapping
= get_enumeration_mapping(enum_field_type
, index
);
1505 /* get_enumeration_mapping() reports any error */
1511 *mapping_name
= g_quark_to_string(mapping
->string
);
1512 assert(*mapping_name
);
1516 *range_begin
= mapping
->range_start
._signed
;
1520 *range_end
= mapping
->range_end
._signed
;
1526 int bt_field_type_enumeration_get_mapping_unsigned(
1527 struct bt_field_type
*enum_field_type
,
1529 const char **mapping_name
, uint64_t *range_begin
,
1530 uint64_t *range_end
)
1533 struct enumeration_mapping
*mapping
;
1535 if (!enum_field_type
) {
1536 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1541 mapping
= get_enumeration_mapping(enum_field_type
, index
);
1543 /* get_enumeration_mapping() reports any error */
1549 *mapping_name
= g_quark_to_string(mapping
->string
);
1550 assert(*mapping_name
);
1554 *range_begin
= mapping
->range_start
._unsigned
;
1558 *range_end
= mapping
->range_end
._unsigned
;
1564 struct bt_field_type
*bt_field_type_enumeration_create(
1565 struct bt_field_type
*integer_container_type
)
1567 struct bt_field_type_enumeration
*enumeration
= NULL
;
1569 BT_LOGD("Creating enumeration field type object: int-ft-addr=%p",
1570 integer_container_type
);
1572 if (!integer_container_type
) {
1573 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1577 if (integer_container_type
->id
!= BT_FIELD_TYPE_ID_INTEGER
) {
1578 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
1579 "container-ft-addr=%p, container-ft-id=%s",
1580 integer_container_type
,
1581 bt_field_type_id_string(integer_container_type
->id
));
1585 enumeration
= g_new0(struct bt_field_type_enumeration
, 1);
1587 BT_LOGE_STR("Failed to allocate one enumeration field type.");
1591 enumeration
->parent
.id
= BT_FIELD_TYPE_ID_ENUM
;
1592 bt_get(integer_container_type
);
1593 enumeration
->container
= integer_container_type
;
1594 enumeration
->entries
= g_ptr_array_new_with_free_func(
1595 (GDestroyNotify
)destroy_enumeration_mapping
);
1596 bt_field_type_init(&enumeration
->parent
, FALSE
);
1597 BT_LOGD("Created enumeration field type object: addr=%p, "
1598 "int-ft-addr=%p, int-ft-size=%u",
1599 &enumeration
->parent
, integer_container_type
,
1600 bt_field_type_integer_get_size(integer_container_type
));
1601 return &enumeration
->parent
;
1603 g_free(enumeration
);
1607 struct bt_field_type
*bt_field_type_enumeration_get_container_type(
1608 struct bt_field_type
*type
)
1610 struct bt_field_type
*container_type
= NULL
;
1611 struct bt_field_type_enumeration
*enumeration_type
;
1614 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1618 if (type
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1619 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1620 "addr=%p, ft-id=%s", type
,
1621 bt_field_type_id_string(type
->id
));
1625 enumeration_type
= container_of(type
,
1626 struct bt_field_type_enumeration
, parent
);
1627 container_type
= enumeration_type
->container
;
1628 bt_get(container_type
);
1630 return container_type
;
1633 int bt_field_type_enumeration_add_mapping_signed(
1634 struct bt_field_type
*type
, const char *string
,
1635 int64_t range_start
, int64_t range_end
)
1638 GQuark mapping_name
;
1639 struct enumeration_mapping
*mapping
;
1640 struct bt_field_type_enumeration
*enumeration
;
1641 char *escaped_string
;
1644 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1650 BT_LOGW_STR("Invalid parameter: string is NULL.");
1656 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1662 if (type
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1663 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1664 "addr=%p, ft-id=%s", type
,
1665 bt_field_type_id_string(type
->id
));
1670 if (range_end
< range_start
) {
1671 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1672 "addr=%p, range-start=%" PRId64
", range-end=%" PRId64
,
1673 type
, range_start
, range_end
);
1678 if (strlen(string
) == 0) {
1679 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1680 "enum-ft-addr=%p, mapping-name-addr=%p", type
,
1686 escaped_string
= g_strescape(string
, NULL
);
1687 if (!escaped_string
) {
1688 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1689 "mapping-name-addr=%p, mapping-name=\"%s\"",
1690 type
, string
, string
);
1695 mapping
= g_new(struct enumeration_mapping
, 1);
1697 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1701 mapping_name
= g_quark_from_string(escaped_string
);
1702 *mapping
= (struct enumeration_mapping
) {
1703 .range_start
._signed
= range_start
,
1704 .range_end
._signed
= range_end
,
1705 .string
= mapping_name
,
1707 enumeration
= container_of(type
, struct bt_field_type_enumeration
,
1709 g_ptr_array_add(enumeration
->entries
, mapping
);
1710 g_ptr_array_sort(enumeration
->entries
,
1711 (GCompareFunc
)compare_enumeration_mappings_signed
);
1712 BT_LOGV("Added mapping to signed enumeration field type: addr=%p, "
1713 "name=\"%s\", range-start=%" PRId64
", "
1714 "range-end=%" PRId64
,
1715 type
, string
, range_start
, range_end
);
1717 free(escaped_string
);
1722 int bt_field_type_enumeration_add_mapping_unsigned(
1723 struct bt_field_type
*type
, const char *string
,
1724 uint64_t range_start
, uint64_t range_end
)
1727 GQuark mapping_name
;
1728 struct enumeration_mapping
*mapping
;
1729 struct bt_field_type_enumeration
*enumeration
;
1730 char *escaped_string
;
1733 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1739 BT_LOGW_STR("Invalid parameter: string is NULL.");
1745 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1751 if (type
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1752 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1753 "addr=%p, ft-id=%s", type
,
1754 bt_field_type_id_string(type
->id
));
1759 if (range_end
< range_start
) {
1760 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1761 "addr=%p, range-start=%" PRIu64
", range-end=%" PRIu64
,
1762 type
, range_start
, range_end
);
1767 if (strlen(string
) == 0) {
1768 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1769 "enum-ft-addr=%p, mapping-name-addr=%p", type
,
1775 escaped_string
= g_strescape(string
, NULL
);
1776 if (!escaped_string
) {
1777 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1778 "mapping-name-addr=%p, mapping-name=\"%s\"",
1779 type
, string
, string
);
1784 mapping
= g_new(struct enumeration_mapping
, 1);
1786 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1790 mapping_name
= g_quark_from_string(escaped_string
);
1791 *mapping
= (struct enumeration_mapping
) {
1792 .range_start
._unsigned
= range_start
,
1793 .range_end
._unsigned
= range_end
,
1794 .string
= mapping_name
,
1796 enumeration
= container_of(type
, struct bt_field_type_enumeration
,
1798 g_ptr_array_add(enumeration
->entries
, mapping
);
1799 g_ptr_array_sort(enumeration
->entries
,
1800 (GCompareFunc
)compare_enumeration_mappings_unsigned
);
1801 BT_LOGV("Added mapping to unsigned enumeration field type: addr=%p, "
1802 "name=\"%s\", range-start=%" PRIu64
", "
1803 "range-end=%" PRIu64
,
1804 type
, string
, range_start
, range_end
);
1806 free(escaped_string
);
1811 int64_t bt_field_type_enumeration_get_mapping_count(
1812 struct bt_field_type
*type
)
1815 struct bt_field_type_enumeration
*enumeration
;
1818 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1823 if (type
->id
!= BT_FIELD_TYPE_ID_ENUM
) {
1824 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1825 "addr=%p, ft-id=%s", type
,
1826 bt_field_type_id_string(type
->id
));
1831 enumeration
= container_of(type
, struct bt_field_type_enumeration
,
1833 ret
= (int64_t) enumeration
->entries
->len
;
1838 struct bt_field_type
*bt_field_type_floating_point_create(void)
1840 struct bt_field_type_floating_point
*floating_point
=
1841 g_new0(struct bt_field_type_floating_point
, 1);
1843 BT_LOGD_STR("Creating floating point number field type object.");
1845 if (!floating_point
) {
1846 BT_LOGE_STR("Failed to allocate one floating point number field type.");
1850 floating_point
->parent
.id
= BT_FIELD_TYPE_ID_FLOAT
;
1851 floating_point
->exp_dig
= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
1852 floating_point
->mant_dig
= FLT_MANT_DIG
;
1853 bt_field_type_init(&floating_point
->parent
, TRUE
);
1854 BT_LOGD("Created floating point number field type object: addr=%p, "
1855 "exp-size=%u, mant-size=%u", &floating_point
->parent
,
1856 floating_point
->exp_dig
, floating_point
->mant_dig
);
1858 return floating_point
? &floating_point
->parent
: NULL
;
1861 int bt_field_type_floating_point_get_exponent_digits(
1862 struct bt_field_type
*type
)
1865 struct bt_field_type_floating_point
*floating_point
;
1868 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1873 if (type
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
1874 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1875 "addr=%p, ft-id=%s", type
,
1876 bt_field_type_id_string(type
->id
));
1881 floating_point
= container_of(type
,
1882 struct bt_field_type_floating_point
, parent
);
1883 ret
= (int) floating_point
->exp_dig
;
1888 int bt_field_type_floating_point_set_exponent_digits(
1889 struct bt_field_type
*type
,
1890 unsigned int exponent_digits
)
1893 struct bt_field_type_floating_point
*floating_point
;
1896 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1902 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1908 if (type
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
1909 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1910 "addr=%p, ft-id=%s", type
,
1911 bt_field_type_id_string(type
->id
));
1916 floating_point
= container_of(type
,
1917 struct bt_field_type_floating_point
, parent
);
1918 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
1919 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
1921 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
1922 BT_LOGW("Invalid parameter: invalid exponent size: "
1923 "addr=%p, exp-size=%u", type
, exponent_digits
);
1928 floating_point
->exp_dig
= exponent_digits
;
1929 BT_LOGV("Set floating point number field type's exponent size: addr=%p, "
1930 "exp-size=%u", type
, exponent_digits
);
1935 int bt_field_type_floating_point_get_mantissa_digits(
1936 struct bt_field_type
*type
)
1939 struct bt_field_type_floating_point
*floating_point
;
1942 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1947 if (type
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
1948 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1949 "addr=%p, ft-id=%s", type
,
1950 bt_field_type_id_string(type
->id
));
1955 floating_point
= container_of(type
,
1956 struct bt_field_type_floating_point
, parent
);
1957 ret
= (int) floating_point
->mant_dig
;
1962 int bt_field_type_floating_point_set_mantissa_digits(
1963 struct bt_field_type
*type
,
1964 unsigned int mantissa_digits
)
1967 struct bt_field_type_floating_point
*floating_point
;
1970 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1976 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1982 if (type
->id
!= BT_FIELD_TYPE_ID_FLOAT
) {
1983 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1984 "addr=%p, ft-id=%s", type
,
1985 bt_field_type_id_string(type
->id
));
1990 floating_point
= container_of(type
,
1991 struct bt_field_type_floating_point
, parent
);
1993 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
1994 (mantissa_digits
!= DBL_MANT_DIG
) &&
1995 (mantissa_digits
!= LDBL_MANT_DIG
)) {
1996 BT_LOGW("Invalid parameter: invalid mantissa size: "
1997 "addr=%p, mant-size=%u", type
, mantissa_digits
);
2002 floating_point
->mant_dig
= mantissa_digits
;
2003 BT_LOGV("Set floating point number field type's mantissa size: addr=%p, "
2004 "mant-size=%u", type
, mantissa_digits
);
2009 struct bt_field_type
*bt_field_type_structure_create(void)
2011 struct bt_field_type_structure
*structure
=
2012 g_new0(struct bt_field_type_structure
, 1);
2014 BT_LOGD_STR("Creating structure field type object.");
2017 BT_LOGE_STR("Failed to allocate one structure field type.");
2021 structure
->parent
.id
= BT_FIELD_TYPE_ID_STRUCT
;
2022 structure
->fields
= g_ptr_array_new_with_free_func(
2023 (GDestroyNotify
)destroy_structure_field
);
2024 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
2025 bt_field_type_init(&structure
->parent
, TRUE
);
2026 BT_LOGD("Created structure field type object: addr=%p",
2027 &structure
->parent
);
2028 return &structure
->parent
;
2033 int bt_field_type_structure_add_field(struct bt_field_type
*type
,
2034 struct bt_field_type
*field_type
,
2035 const char *field_name
)
2038 struct bt_field_type_structure
*structure
;
2041 * TODO: check that `field_type` does not contain `type`,
2045 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2051 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2057 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2063 if (type
->id
!= BT_FIELD_TYPE_ID_STRUCT
) {
2064 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2065 "addr=%p, ft-id=%s", type
,
2066 bt_field_type_id_string(type
->id
));
2071 if (type
== field_type
) {
2072 BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
2078 structure
= container_of(type
,
2079 struct bt_field_type_structure
, parent
);
2080 if (add_structure_field(structure
->fields
,
2081 structure
->field_name_to_index
, field_type
, field_name
)) {
2082 BT_LOGW("Cannot add field to structure field type: "
2083 "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2084 type
, field_type
, field_name
);
2089 BT_LOGV("Added structure field type field: struct-ft-addr=%p, "
2090 "field-ft-addr=%p, field-name=\"%s\"", type
,
2091 field_type
, field_name
);
2096 int64_t bt_field_type_structure_get_field_count(
2097 struct bt_field_type
*type
)
2100 struct bt_field_type_structure
*structure
;
2103 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2108 if (type
->id
!= BT_FIELD_TYPE_ID_STRUCT
) {
2109 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2110 "addr=%p, ft-id=%s", type
,
2111 bt_field_type_id_string(type
->id
));
2116 structure
= container_of(type
, struct bt_field_type_structure
,
2118 ret
= (int64_t) structure
->fields
->len
;
2123 int bt_field_type_structure_get_field_by_index(
2124 struct bt_field_type
*type
,
2125 const char **field_name
, struct bt_field_type
**field_type
,
2128 struct bt_field_type_structure
*structure
;
2129 struct structure_field
*field
;
2133 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2138 if (type
->id
!= BT_FIELD_TYPE_ID_STRUCT
) {
2139 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2140 "addr=%p, ft-id=%s", type
,
2141 bt_field_type_id_string(type
->id
));
2146 structure
= container_of(type
, struct bt_field_type_structure
,
2148 if (index
>= structure
->fields
->len
) {
2149 BT_LOGW("Invalid parameter: index is out of bounds: "
2150 "addr=%p, index=%" PRIu64
", count=%u",
2151 type
, index
, structure
->fields
->len
);
2156 field
= g_ptr_array_index(structure
->fields
, index
);
2158 *field_type
= field
->type
;
2159 bt_get(field
->type
);
2162 *field_name
= g_quark_to_string(field
->name
);
2163 assert(*field_name
);
2169 struct bt_field_type
*bt_field_type_structure_get_field_type_by_name(
2170 struct bt_field_type
*type
,
2175 struct structure_field
*field
;
2176 struct bt_field_type_structure
*structure
;
2177 struct bt_field_type
*field_type
= NULL
;
2180 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2185 BT_LOGW_STR("Invalid parameter: name is NULL.");
2189 name_quark
= g_quark_try_string(name
);
2191 BT_LOGV("No such structure field type field name: "
2192 "ft-addr=%p, field-name=\"%s\"",
2197 structure
= container_of(type
, struct bt_field_type_structure
,
2199 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
2200 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
2201 BT_LOGV("No such structure field type field name: "
2202 "ft-addr=%p, field-name=\"%s\"",
2207 field
= structure
->fields
->pdata
[index
];
2208 field_type
= field
->type
;
2214 struct bt_field_type
*bt_field_type_variant_create(
2215 struct bt_field_type
*enum_tag
, const char *tag_name
)
2217 struct bt_field_type_variant
*variant
= NULL
;
2219 BT_LOGD("Creating variant field type object: "
2220 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2221 enum_tag
, tag_name
);
2223 if (tag_name
&& bt_identifier_is_valid(tag_name
)) {
2224 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2225 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2226 enum_tag
, tag_name
);
2230 variant
= g_new0(struct bt_field_type_variant
, 1);
2232 BT_LOGE_STR("Failed to allocate one variant field type.");
2236 variant
->parent
.id
= BT_FIELD_TYPE_ID_VARIANT
;
2237 variant
->tag_name
= g_string_new(tag_name
);
2238 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
2239 variant
->fields
= g_ptr_array_new_with_free_func(
2240 (GDestroyNotify
) destroy_structure_field
);
2243 variant
->tag
= container_of(enum_tag
,
2244 struct bt_field_type_enumeration
, parent
);
2247 bt_field_type_init(&variant
->parent
, TRUE
);
2248 /* A variant's alignment is undefined */
2249 variant
->parent
.alignment
= 0;
2250 BT_LOGD("Created variant field type object: addr=%p, "
2251 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2252 &variant
->parent
, enum_tag
, tag_name
);
2253 return &variant
->parent
;
2258 struct bt_field_type
*bt_field_type_variant_get_tag_type(
2259 struct bt_field_type
*type
)
2261 struct bt_field_type_variant
*variant
;
2262 struct bt_field_type
*tag_type
= NULL
;
2265 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2269 if (type
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2270 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2271 "addr=%p, ft-id=%s", type
,
2272 bt_field_type_id_string(type
->id
));
2276 variant
= container_of(type
, struct bt_field_type_variant
, parent
);
2277 if (!variant
->tag
) {
2278 BT_LOGV("Variant field type has no tag field type: "
2283 tag_type
= &variant
->tag
->parent
;
2289 const char *bt_field_type_variant_get_tag_name(
2290 struct bt_field_type
*type
)
2292 struct bt_field_type_variant
*variant
;
2293 const char *tag_name
= NULL
;
2296 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2300 if (type
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2301 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2302 "addr=%p, ft-id=%s", type
,
2303 bt_field_type_id_string(type
->id
));
2307 variant
= container_of(type
, struct bt_field_type_variant
, parent
);
2308 if (variant
->tag_name
->len
== 0) {
2309 BT_LOGV("Variant field type has no tag field name: "
2314 tag_name
= variant
->tag_name
->str
;
2319 int bt_field_type_variant_set_tag_name(
2320 struct bt_field_type
*type
, const char *name
)
2323 struct bt_field_type_variant
*variant
;
2326 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2332 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2338 if (type
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2339 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2340 "addr=%p, ft-id=%s", type
,
2341 bt_field_type_id_string(type
->id
));
2346 if (bt_identifier_is_valid(name
)) {
2347 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2348 "variant-ft-addr=%p, tag-field-name=\"%s\"",
2354 variant
= container_of(type
, struct bt_field_type_variant
, parent
);
2355 g_string_assign(variant
->tag_name
, name
);
2356 BT_LOGV("Set variant field type's tag field name: addr=%p, "
2357 "tag-field-name=\"%s\"", type
, name
);
2362 int bt_field_type_variant_add_field(struct bt_field_type
*type
,
2363 struct bt_field_type
*field_type
,
2364 const char *field_name
)
2368 struct bt_field_type_variant
*variant
;
2369 GQuark field_name_quark
= g_quark_from_string(field_name
);
2372 * TODO: check that `field_type` does not contain `type`,
2376 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2382 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2388 if (type
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2389 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2390 "addr=%p, ft-id=%s", type
,
2391 bt_field_type_id_string(type
->id
));
2396 if (type
== field_type
) {
2397 BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
2403 variant
= container_of(type
, struct bt_field_type_variant
, parent
);
2405 /* The user has explicitly provided a tag; validate against it. */
2409 /* Make sure this name is present in the enum tag */
2410 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
2411 struct enumeration_mapping
*mapping
=
2412 g_ptr_array_index(variant
->tag
->entries
, i
);
2414 if (mapping
->string
== field_name_quark
) {
2421 /* Validation failed */
2422 BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
2423 "variant-ft-addr=%p, tag-ft-addr=%p, "
2424 "tag-field-name=\"%s\""
2425 "field-ft-addr=%p, field-name=\"%s\"",
2426 type
, variant
->tag
, variant
->tag_name
->str
,
2427 field_type
, field_name
);
2433 if (add_structure_field(variant
->fields
, variant
->field_name_to_index
,
2434 field_type
, field_name
)) {
2435 BT_LOGW("Cannot add field to variant field type: "
2436 "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2437 type
, field_type
, field_name
);
2442 BT_LOGV("Added variant field type field: variant-ft-addr=%p, "
2443 "field-ft-addr=%p, field-name=\"%s\"", type
,
2444 field_type
, field_name
);
2450 struct bt_field_type
*bt_field_type_variant_get_field_type_by_name(
2451 struct bt_field_type
*type
,
2452 const char *field_name
)
2456 struct structure_field
*field
;
2457 struct bt_field_type_variant
*variant
;
2458 struct bt_field_type
*field_type
= NULL
;
2461 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2466 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2470 name_quark
= g_quark_try_string(field_name
);
2472 BT_LOGV("No such variant field type field name: "
2473 "ft-addr=%p, field-name=\"%s\"",
2478 variant
= container_of(type
, struct bt_field_type_variant
, parent
);
2479 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
2480 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
2481 BT_LOGV("No such variant field type field name: "
2482 "ft-addr=%p, field-name=\"%s\"",
2487 field
= g_ptr_array_index(variant
->fields
, index
);
2488 field_type
= field
->type
;
2494 struct bt_field_type
*bt_field_type_variant_get_field_type_from_tag(
2495 struct bt_field_type
*type
,
2496 struct bt_field
*tag
)
2499 const char *enum_value
;
2500 struct bt_field_type
*field_type
= NULL
;
2501 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
2504 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
2509 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
2513 if (type
->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", type
,
2516 bt_field_type_id_string(type
->id
));
2520 iter
= bt_field_enumeration_get_mappings(tag
);
2521 ret
= bt_field_type_enumeration_mapping_iterator_next(iter
);
2523 BT_LOGE("Cannot get enumeration field type mapping iterator from enumeration field: "
2524 "enum-field-addr=%p", tag
);
2528 ret
= bt_field_type_enumeration_mapping_iterator_get_signed(iter
,
2529 &enum_value
, NULL
, NULL
);
2531 BT_LOGW("Cannot get enumeration field type mapping iterator's current mapping: "
2532 "iter-addr=%p", iter
);
2536 field_type
= bt_field_type_variant_get_field_type_by_name(
2543 int64_t bt_field_type_variant_get_field_count(struct bt_field_type
*type
)
2546 struct bt_field_type_variant
*variant
;
2549 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2554 if (type
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2555 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2556 "addr=%p, ft-id=%s", type
,
2557 bt_field_type_id_string(type
->id
));
2562 variant
= container_of(type
, struct bt_field_type_variant
,
2564 ret
= (int64_t) variant
->fields
->len
;
2570 int bt_field_type_variant_get_field_by_index(struct bt_field_type
*type
,
2571 const char **field_name
, struct bt_field_type
**field_type
,
2574 struct bt_field_type_variant
*variant
;
2575 struct structure_field
*field
;
2579 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2584 if (type
->id
!= BT_FIELD_TYPE_ID_VARIANT
) {
2585 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2586 "addr=%p, ft-id=%s", type
,
2587 bt_field_type_id_string(type
->id
));
2592 variant
= container_of(type
, struct bt_field_type_variant
,
2594 if (index
>= variant
->fields
->len
) {
2595 BT_LOGW("Invalid parameter: index is out of bounds: "
2596 "addr=%p, index=%" PRIu64
", count=%u",
2597 type
, index
, variant
->fields
->len
);
2602 field
= g_ptr_array_index(variant
->fields
, index
);
2604 *field_type
= field
->type
;
2605 bt_get(field
->type
);
2608 *field_name
= g_quark_to_string(field
->name
);
2609 assert(*field_name
);
2615 struct bt_field_type
*bt_field_type_array_create(
2616 struct bt_field_type
*element_type
,
2617 unsigned int length
)
2619 struct bt_field_type_array
*array
= NULL
;
2621 BT_LOGD("Creating array field type object: element-ft-addr=%p, "
2622 "length=%u", element_type
, length
);
2624 if (!element_type
) {
2625 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2630 BT_LOGW_STR("Invalid parameter: length is zero.");
2634 array
= g_new0(struct bt_field_type_array
, 1);
2636 BT_LOGE_STR("Failed to allocate one array field type.");
2640 array
->parent
.id
= BT_FIELD_TYPE_ID_ARRAY
;
2641 bt_get(element_type
);
2642 array
->element_type
= element_type
;
2643 array
->length
= length
;
2644 bt_field_type_init(&array
->parent
, FALSE
);
2645 BT_LOGD("Created array field type object: addr=%p, "
2646 "element-ft-addr=%p, length=%u",
2647 &array
->parent
, element_type
, length
);
2648 return &array
->parent
;
2653 struct bt_field_type
*bt_field_type_array_get_element_type(
2654 struct bt_field_type
*type
)
2656 struct bt_field_type
*ret
= NULL
;
2657 struct bt_field_type_array
*array
;
2660 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2664 if (type
->id
!= BT_FIELD_TYPE_ID_ARRAY
) {
2665 BT_LOGW("Invalid parameter: field type is not an array field type: "
2666 "addr=%p, ft-id=%s", type
,
2667 bt_field_type_id_string(type
->id
));
2671 array
= container_of(type
, struct bt_field_type_array
, parent
);
2672 ret
= array
->element_type
;
2679 int bt_field_type_array_set_element_type(struct bt_field_type
*type
,
2680 struct bt_field_type
*element_type
)
2683 struct bt_field_type_array
*array
;
2686 BT_LOGW_STR("Invalid parameter: array field type is NULL.");
2691 if (!element_type
) {
2692 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2697 if (type
->id
!= BT_FIELD_TYPE_ID_ARRAY
) {
2698 BT_LOGW("Invalid parameter: field type is not an array field type: "
2699 "addr=%p, ft-id=%s", type
,
2700 bt_field_type_id_string(type
->id
));
2705 array
= container_of(type
, struct bt_field_type_array
, parent
);
2707 if (array
->element_type
) {
2708 BT_PUT(array
->element_type
);
2711 array
->element_type
= element_type
;
2712 bt_get(array
->element_type
);
2713 BT_LOGV("Set array field type's element field type: array-ft-addr=%p, "
2714 "element-ft-addr=%p", type
, element_type
);
2720 int64_t bt_field_type_array_get_length(struct bt_field_type
*type
)
2723 struct bt_field_type_array
*array
;
2726 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2731 if (type
->id
!= BT_FIELD_TYPE_ID_ARRAY
) {
2732 BT_LOGW("Invalid parameter: field type is not an array field type: "
2733 "addr=%p, ft-id=%s", type
,
2734 bt_field_type_id_string(type
->id
));
2739 array
= container_of(type
, struct bt_field_type_array
, parent
);
2740 ret
= (int64_t) array
->length
;
2745 struct bt_field_type
*bt_field_type_sequence_create(
2746 struct bt_field_type
*element_type
,
2747 const char *length_field_name
)
2749 struct bt_field_type_sequence
*sequence
= NULL
;
2751 BT_LOGD("Creating sequence field type object: element-ft-addr=%p, "
2752 "length-field-name=\"%s\"", element_type
, length_field_name
);
2754 if (!element_type
) {
2755 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2759 if (bt_identifier_is_valid(length_field_name
)) {
2760 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
2761 "length-field-name=\"%s\"", length_field_name
);
2765 sequence
= g_new0(struct bt_field_type_sequence
, 1);
2767 BT_LOGE_STR("Failed to allocate one sequence field type.");
2771 sequence
->parent
.id
= BT_FIELD_TYPE_ID_SEQUENCE
;
2772 bt_get(element_type
);
2773 sequence
->element_type
= element_type
;
2774 sequence
->length_field_name
= g_string_new(length_field_name
);
2775 bt_field_type_init(&sequence
->parent
, FALSE
);
2776 BT_LOGD("Created sequence field type object: addr=%p, "
2777 "element-ft-addr=%p, length-field-name=\"%s\"",
2778 &sequence
->parent
, element_type
, length_field_name
);
2779 return &sequence
->parent
;
2784 struct bt_field_type
*bt_field_type_sequence_get_element_type(
2785 struct bt_field_type
*type
)
2787 struct bt_field_type
*ret
= NULL
;
2788 struct bt_field_type_sequence
*sequence
;
2791 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2795 if (type
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
2796 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2797 "addr=%p, ft-id=%s", type
,
2798 bt_field_type_id_string(type
->id
));
2802 sequence
= container_of(type
, struct bt_field_type_sequence
,
2804 ret
= sequence
->element_type
;
2811 int bt_field_type_sequence_set_element_type(struct bt_field_type
*type
,
2812 struct bt_field_type
*element_type
)
2815 struct bt_field_type_sequence
*sequence
;
2818 BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
2823 if (!element_type
) {
2824 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2829 if (type
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
2830 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2831 "addr=%p, ft-id=%s", type
,
2832 bt_field_type_id_string(type
->id
));
2837 sequence
= container_of(type
, struct bt_field_type_sequence
, parent
);
2838 if (sequence
->element_type
) {
2839 BT_PUT(sequence
->element_type
);
2842 sequence
->element_type
= element_type
;
2843 bt_get(sequence
->element_type
);
2844 BT_LOGV("Set sequence field type's element field type: sequence-ft-addr=%p, "
2845 "element-ft-addr=%p", type
, element_type
);
2851 const char *bt_field_type_sequence_get_length_field_name(
2852 struct bt_field_type
*type
)
2854 const char *ret
= NULL
;
2855 struct bt_field_type_sequence
*sequence
;
2858 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2862 if (type
->id
!= BT_FIELD_TYPE_ID_SEQUENCE
) {
2863 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2864 "addr=%p, ft-id=%s", type
,
2865 bt_field_type_id_string(type
->id
));
2869 sequence
= container_of(type
, struct bt_field_type_sequence
,
2871 ret
= sequence
->length_field_name
->str
;
2876 struct bt_field_type
*bt_field_type_string_create(void)
2878 struct bt_field_type_string
*string
=
2879 g_new0(struct bt_field_type_string
, 1);
2881 BT_LOGD_STR("Creating string field type object.");
2884 BT_LOGE_STR("Failed to allocate one string field type.");
2888 string
->parent
.id
= BT_FIELD_TYPE_ID_STRING
;
2889 bt_field_type_init(&string
->parent
, TRUE
);
2890 string
->encoding
= BT_STRING_ENCODING_UTF8
;
2891 string
->parent
.alignment
= CHAR_BIT
;
2892 BT_LOGD("Created string field type object: addr=%p", &string
->parent
);
2893 return &string
->parent
;
2896 enum bt_string_encoding
bt_field_type_string_get_encoding(
2897 struct bt_field_type
*type
)
2899 struct bt_field_type_string
*string
;
2900 enum bt_string_encoding ret
= BT_STRING_ENCODING_UNKNOWN
;
2903 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2907 if (type
->id
!= BT_FIELD_TYPE_ID_STRING
) {
2908 BT_LOGW("Invalid parameter: field type is not a string field type: "
2909 "addr=%p, ft-id=%s", type
,
2910 bt_field_type_id_string(type
->id
));
2914 string
= container_of(type
, struct bt_field_type_string
,
2916 ret
= string
->encoding
;
2921 int bt_field_type_string_set_encoding(struct bt_field_type
*type
,
2922 enum bt_string_encoding encoding
)
2925 struct bt_field_type_string
*string
;
2928 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2933 if (type
->id
!= BT_FIELD_TYPE_ID_STRING
) {
2934 BT_LOGW("Invalid parameter: field type is not a string field type: "
2935 "addr=%p, ft-id=%s", type
,
2936 bt_field_type_id_string(type
->id
));
2941 if (encoding
!= BT_STRING_ENCODING_UTF8
&&
2942 encoding
!= BT_STRING_ENCODING_ASCII
) {
2943 BT_LOGW("Invalid parameter: unknown string encoding: "
2944 "addr=%p, encoding=%d", type
, encoding
);
2949 string
= container_of(type
, struct bt_field_type_string
, parent
);
2950 string
->encoding
= encoding
;
2951 BT_LOGV("Set string field type's encoding: addr=%p, encoding=%s",
2952 type
, bt_string_encoding_string(encoding
));
2957 int bt_field_type_get_alignment(struct bt_field_type
*type
)
2960 enum bt_field_type_id type_id
;
2963 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2969 ret
= (int) type
->alignment
;
2973 type_id
= bt_field_type_get_type_id(type
);
2975 case BT_FIELD_TYPE_ID_SEQUENCE
:
2977 struct bt_field_type
*element
=
2978 bt_field_type_sequence_get_element_type(type
);
2981 ret
= bt_field_type_get_alignment(element
);
2985 case BT_FIELD_TYPE_ID_ARRAY
:
2987 struct bt_field_type
*element
=
2988 bt_field_type_array_get_element_type(type
);
2991 ret
= bt_field_type_get_alignment(element
);
2995 case BT_FIELD_TYPE_ID_STRUCT
:
2997 int64_t i
, element_count
;
2999 element_count
= bt_field_type_structure_get_field_count(
3001 assert(element_count
>= 0);
3003 for (i
= 0; i
< element_count
; i
++) {
3004 struct bt_field_type
*field
;
3005 int field_alignment
;
3007 ret
= bt_field_type_structure_get_field_by_index(
3008 type
, NULL
, &field
, i
);
3011 field_alignment
= bt_field_type_get_alignment(
3014 if (field_alignment
< 0) {
3015 ret
= field_alignment
;
3019 type
->alignment
= MAX(field_alignment
, type
->alignment
);
3021 ret
= (int) type
->alignment
;
3024 case BT_FIELD_TYPE_ID_UNKNOWN
:
3025 BT_LOGW("Invalid parameter: unknown field type ID: "
3026 "addr=%p, ft-id=%d", type
, type_id
);
3030 ret
= (int) type
->alignment
;
3038 int is_power_of_two(unsigned int value
)
3040 return ((value
& (value
- 1)) == 0) && value
> 0;
3043 int bt_field_type_set_alignment(struct bt_field_type
*type
,
3044 unsigned int alignment
)
3047 enum bt_field_type_id type_id
;
3049 /* Alignment must be a power of two */
3051 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3057 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3063 if (!is_power_of_two(alignment
)) {
3064 BT_LOGW("Invalid parameter: alignment is not a power of two: "
3065 "addr=%p, align=%u", type
, alignment
);
3070 type_id
= bt_field_type_get_type_id(type
);
3071 if (type_id
== BT_FIELD_TYPE_ID_UNKNOWN
) {
3072 BT_LOGW("Invalid parameter: unknown field type ID: "
3073 "addr=%p, ft-id=%d", type
, type_id
);
3078 if (type
->id
== BT_FIELD_TYPE_ID_STRING
&&
3079 alignment
!= CHAR_BIT
) {
3080 BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
3081 "addr=%p, align=%u", CHAR_BIT
, type
, alignment
);
3086 if (type_id
== BT_FIELD_TYPE_ID_VARIANT
||
3087 type_id
== BT_FIELD_TYPE_ID_SEQUENCE
||
3088 type_id
== BT_FIELD_TYPE_ID_ARRAY
) {
3089 /* Setting an alignment on these types makes no sense */
3090 BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
3091 "addr=%p, ft-id=%s", type
,
3092 bt_field_type_id_string(type
->id
));
3097 type
->alignment
= alignment
;
3099 BT_LOGV("Set field type's alignment: addr=%p, align=%u",
3105 enum bt_byte_order
bt_field_type_get_byte_order(
3106 struct bt_field_type
*type
)
3108 enum bt_byte_order ret
= BT_BYTE_ORDER_UNKNOWN
;
3111 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3116 case BT_FIELD_TYPE_ID_INTEGER
:
3118 struct bt_field_type_integer
*integer
= container_of(
3119 type
, struct bt_field_type_integer
, parent
);
3120 ret
= integer
->user_byte_order
;
3123 case BT_FIELD_TYPE_ID_ENUM
:
3125 struct bt_field_type_enumeration
*enum_ft
= container_of(
3126 type
, struct bt_field_type_enumeration
, parent
);
3127 ret
= bt_field_type_get_byte_order(enum_ft
->container
);
3130 case BT_FIELD_TYPE_ID_FLOAT
:
3132 struct bt_field_type_floating_point
*floating_point
=
3134 struct bt_field_type_floating_point
,
3136 ret
= floating_point
->user_byte_order
;
3140 BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
3141 "addr=%p, ft-id=%s", type
,
3142 bt_field_type_id_string(type
->id
));
3146 assert(ret
== BT_BYTE_ORDER_NATIVE
||
3147 ret
== BT_BYTE_ORDER_LITTLE_ENDIAN
||
3148 ret
== BT_BYTE_ORDER_BIG_ENDIAN
||
3149 ret
== BT_BYTE_ORDER_NETWORK
);
3155 int bt_field_type_set_byte_order(struct bt_field_type
*type
,
3156 enum bt_byte_order byte_order
)
3161 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3167 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3173 if (byte_order
!= BT_BYTE_ORDER_NATIVE
&&
3174 byte_order
!= BT_BYTE_ORDER_LITTLE_ENDIAN
&&
3175 byte_order
!= BT_BYTE_ORDER_BIG_ENDIAN
&&
3176 byte_order
!= BT_BYTE_ORDER_NETWORK
) {
3177 BT_LOGW("Invalid parameter: invalid byte order: "
3178 "addr=%p, bo=%s", type
,
3179 bt_byte_order_string(byte_order
));
3184 if (set_byte_order_funcs
[type
->id
]) {
3185 set_byte_order_funcs
[type
->id
](type
, byte_order
);
3188 BT_LOGV("Set field type's byte order: addr=%p, bo=%s",
3189 type
, bt_byte_order_string(byte_order
));
3195 enum bt_field_type_id
bt_field_type_get_type_id(
3196 struct bt_field_type
*type
)
3199 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3200 return BT_FIELD_TYPE_ID_UNKNOWN
;
3206 int bt_field_type_is_integer(struct bt_field_type
*type
)
3208 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_INTEGER
;
3211 int bt_field_type_is_floating_point(struct bt_field_type
*type
)
3213 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_FLOAT
;
3216 int bt_field_type_is_enumeration(struct bt_field_type
*type
)
3218 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_ENUM
;
3221 int bt_field_type_is_string(struct bt_field_type
*type
)
3223 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_STRING
;
3226 int bt_field_type_is_structure(struct bt_field_type
*type
)
3228 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_STRUCT
;
3231 int bt_field_type_is_array(struct bt_field_type
*type
)
3233 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_ARRAY
;
3236 int bt_field_type_is_sequence(struct bt_field_type
*type
)
3238 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_SEQUENCE
;
3241 int bt_field_type_is_variant(struct bt_field_type
*type
)
3243 return bt_field_type_get_type_id(type
) == BT_FIELD_TYPE_ID_VARIANT
;
3246 /* Pre-2.0 CTF writer backward compatibility */
3247 void bt_ctf_field_type_get(struct bt_field_type
*type
)
3252 /* Pre-2.0 CTF writer backward compatibility */
3253 void bt_ctf_field_type_put(struct bt_field_type
*type
)
3259 void bt_field_type_freeze(struct bt_field_type
*type
)
3261 if (!type
|| type
->frozen
) {
3269 struct bt_field_type
*bt_field_type_variant_get_field_type_signed(
3270 struct bt_field_type_variant
*variant
,
3273 struct bt_field_type
*type
= NULL
;
3274 GQuark field_name_quark
;
3276 struct structure_field
*field_entry
;
3277 struct range_overlap_query query
= {
3278 .range_start
._signed
= tag_value
,
3279 .range_end
._signed
= tag_value
,
3284 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
3286 if (!query
.overlaps
) {
3290 field_name_quark
= query
.mapping_name
;
3291 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
3292 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3296 field_entry
= g_ptr_array_index(variant
->fields
, (size_t) index
);
3297 type
= field_entry
->type
;
3303 struct bt_field_type
*bt_field_type_variant_get_field_type_unsigned(
3304 struct bt_field_type_variant
*variant
,
3307 struct bt_field_type
*type
= NULL
;
3308 GQuark field_name_quark
;
3310 struct structure_field
*field_entry
;
3311 struct range_overlap_query query
= {
3312 .range_start
._unsigned
= tag_value
,
3313 .range_end
._unsigned
= tag_value
,
3318 g_ptr_array_foreach(variant
->tag
->entries
,
3319 check_ranges_overlap_unsigned
,
3321 if (!query
.overlaps
) {
3325 field_name_quark
= query
.mapping_name
;
3326 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
3327 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3331 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
3332 type
= field_entry
->type
;
3338 int bt_field_type_serialize(struct bt_field_type
*type
,
3339 struct metadata_context
*context
)
3346 /* Make sure field type is valid before serializing it */
3347 ret
= bt_field_type_validate(type
);
3349 BT_LOGW("Cannot serialize field type's metadata: field type is invalid: "
3354 ret
= type
->serialize(type
, context
);
3359 struct bt_field_type
*bt_field_type_copy(struct bt_field_type
*type
)
3361 struct bt_field_type
*copy
= NULL
;
3364 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3368 copy
= type_copy_funcs
[type
->id
](type
);
3370 BT_LOGE_STR("Cannot copy field type.");
3374 copy
->alignment
= type
->alignment
;
3380 int bt_field_type_structure_get_field_name_index(
3381 struct bt_field_type
*type
, const char *name
)
3386 struct bt_field_type_structure
*structure
;
3389 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3395 BT_LOGW_STR("Invalid parameter: field name is NULL.");
3400 if (bt_field_type_get_type_id(type
) != BT_FIELD_TYPE_ID_STRUCT
) {
3401 BT_LOGW("Invalid parameter: field type is not a structure field type: "
3402 "addr=%p, ft-id=%s", type
,
3403 bt_field_type_id_string(type
->id
));
3408 name_quark
= g_quark_try_string(name
);
3410 BT_LOGV("No such structure field type field name: "
3411 "ft-addr=%p, field-name=\"%s\"",
3417 structure
= container_of(type
, struct bt_field_type_structure
,
3419 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
3420 GUINT_TO_POINTER(name_quark
),
3421 NULL
, (gpointer
*)&index
)) {
3422 BT_LOGV("No such structure field type field name: "
3423 "ft-addr=%p, field-name=\"%s\"",
3434 int bt_field_type_variant_get_field_name_index(
3435 struct bt_field_type
*type
, const char *name
)
3440 struct bt_field_type_variant
*variant
;
3443 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3449 BT_LOGW_STR("Invalid parameter: field name is NULL.");
3454 if (bt_field_type_get_type_id(type
) != BT_FIELD_TYPE_ID_VARIANT
) {
3455 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3456 "addr=%p, ft-id=%s", type
,
3457 bt_field_type_id_string(type
->id
));
3462 name_quark
= g_quark_try_string(name
);
3464 BT_LOGV("No such variant field type field name: "
3465 "ft-addr=%p, field-name=\"%s\"",
3471 variant
= container_of(type
, struct bt_field_type_variant
,
3473 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
3474 GUINT_TO_POINTER(name_quark
),
3475 NULL
, (gpointer
*)&index
)) {
3476 BT_LOGV("No such variant field type field name: "
3477 "ft-addr=%p, field-name=\"%s\"",
3488 int bt_field_type_sequence_set_length_field_path(
3489 struct bt_field_type
*type
,
3490 struct bt_field_path
*path
)
3493 struct bt_field_type_sequence
*sequence
;
3496 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3501 if (bt_field_type_get_type_id(type
) != BT_FIELD_TYPE_ID_SEQUENCE
) {
3502 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
3503 "addr=%p, ft-id=%s", type
,
3504 bt_field_type_id_string(type
->id
));
3509 sequence
= container_of(type
, struct bt_field_type_sequence
,
3512 BT_MOVE(sequence
->length_field_path
, path
);
3513 BT_LOGV("Set sequence field type's length field path: ft-addr=%p, "
3514 "field-path-addr=%p", type
, path
);
3520 int bt_field_type_variant_set_tag_field_path(struct bt_field_type
*type
,
3521 struct bt_field_path
*path
)
3524 struct bt_field_type_variant
*variant
;
3527 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3532 if (bt_field_type_get_type_id(type
) != BT_FIELD_TYPE_ID_VARIANT
) {
3533 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3534 "addr=%p, ft-id=%s", type
,
3535 bt_field_type_id_string(type
->id
));
3540 variant
= container_of(type
, struct bt_field_type_variant
,
3543 BT_MOVE(variant
->tag_field_path
, path
);
3544 BT_LOGV("Set variant field type's tag field path: ft-addr=%p, "
3545 "field-path-addr=%p", type
, path
);
3551 int bt_field_type_variant_set_tag_field_type(struct bt_field_type
*type
,
3552 struct bt_field_type
*tag
)
3555 struct bt_field_type_variant
*variant
;
3558 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3564 BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
3569 if (bt_field_type_get_type_id(tag
) != BT_FIELD_TYPE_ID_ENUM
) {
3570 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
3571 "addr=%p, ft-id=%s", type
,
3572 bt_field_type_id_string(type
->id
));
3577 variant
= container_of(type
, struct bt_field_type_variant
,
3581 bt_put(&variant
->tag
->parent
);
3583 variant
->tag
= container_of(tag
, struct bt_field_type_enumeration
,
3585 BT_LOGV("Set variant field type's tag field type: variant-ft-addr=%p, "
3586 "tag-ft-addr=%p", type
, tag
);
3592 void bt_field_type_integer_destroy(struct bt_field_type
*type
)
3594 struct bt_field_type_integer
*integer
=
3595 (struct bt_field_type_integer
*) type
;
3601 BT_LOGD("Destroying integer field type object: addr=%p", type
);
3602 BT_LOGD_STR("Putting mapped clock class.");
3603 bt_put(integer
->mapped_clock
);
3608 void bt_field_type_enumeration_destroy(struct bt_field_type
*type
)
3610 struct bt_field_type_enumeration
*enumeration
=
3611 (struct bt_field_type_enumeration
*) type
;
3617 BT_LOGD("Destroying enumeration field type object: addr=%p", type
);
3618 g_ptr_array_free(enumeration
->entries
, TRUE
);
3619 BT_LOGD_STR("Putting container field type.");
3620 bt_put(enumeration
->container
);
3621 g_free(enumeration
);
3625 void bt_field_type_floating_point_destroy(struct bt_field_type
*type
)
3627 struct bt_field_type_floating_point
*floating_point
=
3628 (struct bt_field_type_floating_point
*) type
;
3634 BT_LOGD("Destroying floating point number field type object: addr=%p", type
);
3635 g_free(floating_point
);
3639 void bt_field_type_structure_destroy(struct bt_field_type
*type
)
3641 struct bt_field_type_structure
*structure
=
3642 (struct bt_field_type_structure
*) type
;
3648 BT_LOGD("Destroying structure field type object: addr=%p", type
);
3649 g_ptr_array_free(structure
->fields
, TRUE
);
3650 g_hash_table_destroy(structure
->field_name_to_index
);
3655 void bt_field_type_variant_destroy(struct bt_field_type
*type
)
3657 struct bt_field_type_variant
*variant
=
3658 (struct bt_field_type_variant
*) type
;
3664 BT_LOGD("Destroying variant field type object: addr=%p", type
);
3665 g_ptr_array_free(variant
->fields
, TRUE
);
3666 g_hash_table_destroy(variant
->field_name_to_index
);
3667 g_string_free(variant
->tag_name
, TRUE
);
3668 BT_LOGD_STR("Putting tag field type.");
3669 bt_put(&variant
->tag
->parent
);
3670 BT_PUT(variant
->tag_field_path
);
3675 void bt_field_type_array_destroy(struct bt_field_type
*type
)
3677 struct bt_field_type_array
*array
=
3678 (struct bt_field_type_array
*) type
;
3684 BT_LOGD("Destroying array field type object: addr=%p", type
);
3685 BT_LOGD_STR("Putting element field type.");
3686 bt_put(array
->element_type
);
3691 void bt_field_type_sequence_destroy(struct bt_field_type
*type
)
3693 struct bt_field_type_sequence
*sequence
=
3694 (struct bt_field_type_sequence
*) type
;
3700 BT_LOGD("Destroying sequence field type object: addr=%p", type
);
3701 BT_LOGD_STR("Putting element field type.");
3702 bt_put(sequence
->element_type
);
3703 g_string_free(sequence
->length_field_name
, TRUE
);
3704 BT_LOGD_STR("Putting length field path.");
3705 BT_PUT(sequence
->length_field_path
);
3710 void bt_field_type_string_destroy(struct bt_field_type
*type
)
3712 struct bt_field_type_string
*string
=
3713 (struct bt_field_type_string
*) type
;
3719 BT_LOGD("Destroying string field type object: addr=%p", type
);
3724 void generic_field_type_freeze(struct bt_field_type
*type
)
3730 void bt_field_type_integer_freeze(struct bt_field_type
*type
)
3732 struct bt_field_type_integer
*integer_type
= container_of(
3733 type
, struct bt_field_type_integer
, parent
);
3735 BT_LOGD("Freezing integer field type object: addr=%p", type
);
3737 if (integer_type
->mapped_clock
) {
3738 BT_LOGD_STR("Freezing integer field type's mapped clock class.");
3739 bt_clock_class_freeze(integer_type
->mapped_clock
);
3742 generic_field_type_freeze(type
);
3746 void bt_field_type_enumeration_freeze(struct bt_field_type
*type
)
3748 struct bt_field_type_enumeration
*enumeration_type
= container_of(
3749 type
, struct bt_field_type_enumeration
, parent
);
3751 BT_LOGD("Freezing enumeration field type object: addr=%p", type
);
3752 set_enumeration_range_overlap(type
);
3753 generic_field_type_freeze(type
);
3754 BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
3755 enumeration_type
->container
);
3756 bt_field_type_freeze(enumeration_type
->container
);
3760 void freeze_structure_field(struct structure_field
*field
)
3762 BT_LOGD("Freezing structure/variant field type field: field-addr=%p, "
3763 "field-ft-addr=%p, field-name=\"%s\"", field
,
3764 field
->type
, g_quark_to_string(field
->name
));
3765 bt_field_type_freeze(field
->type
);
3769 void bt_field_type_structure_freeze(struct bt_field_type
*type
)
3771 struct bt_field_type_structure
*structure_type
= container_of(
3772 type
, struct bt_field_type_structure
, parent
);
3774 /* Cache the alignment */
3775 BT_LOGD("Freezing structure field type object: addr=%p", type
);
3776 type
->alignment
= bt_field_type_get_alignment(type
);
3777 generic_field_type_freeze(type
);
3778 g_ptr_array_foreach(structure_type
->fields
,
3779 (GFunc
) freeze_structure_field
, NULL
);
3783 void bt_field_type_variant_freeze(struct bt_field_type
*type
)
3785 struct bt_field_type_variant
*variant_type
= container_of(
3786 type
, struct bt_field_type_variant
, parent
);
3788 BT_LOGD("Freezing variant field type object: addr=%p", type
);
3789 generic_field_type_freeze(type
);
3790 g_ptr_array_foreach(variant_type
->fields
,
3791 (GFunc
) freeze_structure_field
, NULL
);
3795 void bt_field_type_array_freeze(struct bt_field_type
*type
)
3797 struct bt_field_type_array
*array_type
= container_of(
3798 type
, struct bt_field_type_array
, parent
);
3800 /* Cache the alignment */
3801 BT_LOGD("Freezing array field type object: addr=%p", type
);
3802 type
->alignment
= bt_field_type_get_alignment(type
);
3803 generic_field_type_freeze(type
);
3804 BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
3805 array_type
->element_type
);
3806 bt_field_type_freeze(array_type
->element_type
);
3810 void bt_field_type_sequence_freeze(struct bt_field_type
*type
)
3812 struct bt_field_type_sequence
*sequence_type
= container_of(
3813 type
, struct bt_field_type_sequence
, parent
);
3815 /* Cache the alignment */
3816 BT_LOGD("Freezing sequence field type object: addr=%p", type
);
3817 type
->alignment
= bt_field_type_get_alignment(type
);
3818 generic_field_type_freeze(type
);
3819 BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
3820 sequence_type
->element_type
);
3821 bt_field_type_freeze(sequence_type
->element_type
);
3825 const char *get_encoding_string(enum bt_string_encoding encoding
)
3827 const char *encoding_string
;
3830 case BT_STRING_ENCODING_NONE
:
3831 encoding_string
= "none";
3833 case BT_STRING_ENCODING_ASCII
:
3834 encoding_string
= "ASCII";
3836 case BT_STRING_ENCODING_UTF8
:
3837 encoding_string
= "UTF8";
3840 encoding_string
= "unknown";
3844 return encoding_string
;
3848 const char *get_integer_base_string(enum bt_integer_base base
)
3850 const char *base_string
;
3853 case BT_INTEGER_BASE_DECIMAL
:
3854 case BT_INTEGER_BASE_UNSPECIFIED
:
3855 base_string
= "decimal";
3857 case BT_INTEGER_BASE_HEXADECIMAL
:
3858 base_string
= "hexadecimal";
3860 case BT_INTEGER_BASE_OCTAL
:
3861 base_string
= "octal";
3863 case BT_INTEGER_BASE_BINARY
:
3864 base_string
= "binary";
3867 base_string
= "unknown";
3875 void append_field_name(struct metadata_context
*context
,
3878 g_string_append_c(context
->string
, ' ');
3880 if (bt_identifier_is_valid(name
) || *name
== '_') {
3881 g_string_append_c(context
->string
, '_');
3884 g_string_append(context
->string
, name
);
3888 int bt_field_type_integer_serialize(struct bt_field_type
*type
,
3889 struct metadata_context
*context
)
3891 struct bt_field_type_integer
*integer
= container_of(type
,
3892 struct bt_field_type_integer
, parent
);
3895 BT_LOGD("Serializing integer field type's metadata: "
3896 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
3897 g_string_append_printf(context
->string
,
3898 "integer { size = %u; align = %u; signed = %s; encoding = %s; base = %s; byte_order = %s",
3899 integer
->size
, type
->alignment
,
3900 (integer
->is_signed
? "true" : "false"),
3901 get_encoding_string(integer
->encoding
),
3902 get_integer_base_string(integer
->base
),
3903 get_byte_order_string(integer
->user_byte_order
));
3904 if (integer
->mapped_clock
) {
3905 const char *clock_name
= bt_clock_class_get_name(
3906 integer
->mapped_clock
);
3909 g_string_append_printf(context
->string
,
3910 "; map = clock.%s.value", clock_name
);
3913 g_string_append(context
->string
, "; }");
3918 int bt_field_type_enumeration_serialize(struct bt_field_type
*type
,
3919 struct metadata_context
*context
)
3923 struct bt_field_type_enumeration
*enumeration
= container_of(type
,
3924 struct bt_field_type_enumeration
, parent
);
3925 struct bt_field_type
*container_type
;
3926 int container_signed
;
3928 BT_LOGD("Serializing enumeration field type's metadata: "
3929 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
3930 container_type
= bt_field_type_enumeration_get_container_type(type
);
3931 assert(container_type
);
3932 container_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
3933 assert(container_signed
>= 0);
3934 g_string_append(context
->string
, "enum : ");
3935 BT_LOGD_STR("Serializing enumeration field type's container field type's metadata.");
3936 ret
= bt_field_type_serialize(enumeration
->container
, context
);
3938 BT_LOGW("Cannot serialize enumeration field type's container field type's metadata: "
3939 "container-ft-addr=%p", enumeration
->container
);
3943 g_string_append(context
->string
, " { ");
3944 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
3945 struct enumeration_mapping
*mapping
=
3946 enumeration
->entries
->pdata
[entry
];
3948 if (container_signed
) {
3949 if (mapping
->range_start
._signed
==
3950 mapping
->range_end
._signed
) {
3951 g_string_append_printf(context
->string
,
3952 "\"%s\" = %" PRId64
,
3953 g_quark_to_string(mapping
->string
),
3954 mapping
->range_start
._signed
);
3956 g_string_append_printf(context
->string
,
3957 "\"%s\" = %" PRId64
" ... %" PRId64
,
3958 g_quark_to_string(mapping
->string
),
3959 mapping
->range_start
._signed
,
3960 mapping
->range_end
._signed
);
3963 if (mapping
->range_start
._unsigned
==
3964 mapping
->range_end
._unsigned
) {
3965 g_string_append_printf(context
->string
,
3966 "\"%s\" = %" PRIu64
,
3967 g_quark_to_string(mapping
->string
),
3968 mapping
->range_start
._unsigned
);
3970 g_string_append_printf(context
->string
,
3971 "\"%s\" = %" PRIu64
" ... %" PRIu64
,
3972 g_quark_to_string(mapping
->string
),
3973 mapping
->range_start
._unsigned
,
3974 mapping
->range_end
._unsigned
);
3978 g_string_append(context
->string
,
3979 ((entry
!= (enumeration
->entries
->len
- 1)) ?
3983 if (context
->field_name
->len
) {
3984 append_field_name(context
,
3985 context
->field_name
->str
);
3986 g_string_assign(context
->field_name
, "");
3989 bt_put(container_type
);
3994 int bt_field_type_floating_point_serialize(struct bt_field_type
*type
,
3995 struct metadata_context
*context
)
3997 struct bt_field_type_floating_point
*floating_point
= container_of(
3998 type
, struct bt_field_type_floating_point
, parent
);
4000 BT_LOGD("Serializing floating point number field type's metadata: "
4001 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4002 g_string_append_printf(context
->string
,
4003 "floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
4004 floating_point
->exp_dig
,
4005 floating_point
->mant_dig
,
4006 get_byte_order_string(floating_point
->user_byte_order
),
4012 int bt_field_type_structure_serialize(struct bt_field_type
*type
,
4013 struct metadata_context
*context
)
4016 unsigned int indent
;
4018 struct bt_field_type_structure
*structure
= container_of(type
,
4019 struct bt_field_type_structure
, parent
);
4020 GString
*structure_field_name
= context
->field_name
;
4022 BT_LOGD("Serializing structure field type's metadata: "
4023 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4024 context
->field_name
= g_string_new("");
4026 context
->current_indentation_level
++;
4027 g_string_append(context
->string
, "struct {\n");
4029 for (i
= 0; i
< structure
->fields
->len
; i
++) {
4030 struct structure_field
*field
= structure
->fields
->pdata
[i
];
4032 BT_LOGD("Serializing structure field type's field metadata: "
4034 "field-ft-addr=%p, field-name=\"%s\"",
4035 i
, field
, g_quark_to_string(field
->name
));
4037 for (indent
= 0; indent
< context
->current_indentation_level
;
4039 g_string_append_c(context
->string
, '\t');
4042 g_string_assign(context
->field_name
,
4043 g_quark_to_string(field
->name
));
4044 ret
= bt_field_type_serialize(field
->type
, context
);
4046 BT_LOGW("Cannot serialize structure field type's field's metadata: "
4048 "field-ft-addr=%p, field-name=\"%s\"",
4050 g_quark_to_string(field
->name
));
4054 if (context
->field_name
->len
) {
4055 append_field_name(context
,
4056 context
->field_name
->str
);
4058 g_string_append(context
->string
, ";\n");
4061 context
->current_indentation_level
--;
4062 for (indent
= 0; indent
< context
->current_indentation_level
;
4064 g_string_append_c(context
->string
, '\t');
4067 g_string_append_printf(context
->string
, "} align(%u)",
4070 g_string_free(context
->field_name
, TRUE
);
4071 context
->field_name
= structure_field_name
;
4076 int bt_field_type_variant_serialize(struct bt_field_type
*type
,
4077 struct metadata_context
*context
)
4080 unsigned int indent
;
4082 struct bt_field_type_variant
*variant
= container_of(
4083 type
, struct bt_field_type_variant
, parent
);
4084 GString
*variant_field_name
= context
->field_name
;
4086 BT_LOGD("Serializing variant field type's metadata: "
4087 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4088 context
->field_name
= g_string_new("");
4089 if (variant
->tag_name
->len
> 0) {
4090 g_string_append(context
->string
, "variant <");
4091 append_field_name(context
, variant
->tag_name
->str
);
4092 g_string_append(context
->string
, "> {\n");
4094 g_string_append(context
->string
, "variant {\n");
4097 context
->current_indentation_level
++;
4098 for (i
= 0; i
< variant
->fields
->len
; i
++) {
4099 struct structure_field
*field
= variant
->fields
->pdata
[i
];
4101 BT_LOGD("Serializing variant field type's field metadata: "
4103 "field-ft-addr=%p, field-name=\"%s\"",
4104 i
, field
, g_quark_to_string(field
->name
));
4106 g_string_assign(context
->field_name
,
4107 g_quark_to_string(field
->name
));
4108 for (indent
= 0; indent
< context
->current_indentation_level
;
4110 g_string_append_c(context
->string
, '\t');
4113 g_string_assign(context
->field_name
,
4114 g_quark_to_string(field
->name
));
4115 ret
= bt_field_type_serialize(field
->type
, context
);
4117 BT_LOGW("Cannot serialize variant field type's field's metadata: "
4119 "field-ft-addr=%p, field-name=\"%s\"",
4121 g_quark_to_string(field
->name
));
4125 if (context
->field_name
->len
) {
4126 append_field_name(context
,
4127 context
->field_name
->str
);
4128 g_string_append_c(context
->string
, ';');
4131 g_string_append_c(context
->string
, '\n');
4134 context
->current_indentation_level
--;
4135 for (indent
= 0; indent
< context
->current_indentation_level
;
4137 g_string_append_c(context
->string
, '\t');
4140 g_string_append(context
->string
, "}");
4142 g_string_free(context
->field_name
, TRUE
);
4143 context
->field_name
= variant_field_name
;
4148 int bt_field_type_array_serialize(struct bt_field_type
*type
,
4149 struct metadata_context
*context
)
4152 struct bt_field_type_array
*array
= container_of(type
,
4153 struct bt_field_type_array
, parent
);
4155 BT_LOGD("Serializing array field type's metadata: "
4156 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4157 BT_LOGD_STR("Serializing array field type's element field type's metadata.");
4158 ret
= bt_field_type_serialize(array
->element_type
, context
);
4160 BT_LOGW("Cannot serialize array field type's element field type's metadata: "
4161 "element-ft-addr=%p", array
->element_type
);
4165 if (context
->field_name
->len
) {
4166 append_field_name(context
,
4167 context
->field_name
->str
);
4169 g_string_append_printf(context
->string
, "[%u]", array
->length
);
4170 g_string_assign(context
->field_name
, "");
4172 g_string_append_printf(context
->string
, "[%u]", array
->length
);
4179 int bt_field_type_sequence_serialize(struct bt_field_type
*type
,
4180 struct metadata_context
*context
)
4183 struct bt_field_type_sequence
*sequence
= container_of(
4184 type
, struct bt_field_type_sequence
, parent
);
4186 BT_LOGD("Serializing sequence field type's metadata: "
4187 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4188 BT_LOGD_STR("Serializing sequence field type's element field type's metadata.");
4189 ret
= bt_field_type_serialize(sequence
->element_type
, context
);
4191 BT_LOGW("Cannot serialize sequence field type's element field type's metadata: "
4192 "element-ft-addr=%p", sequence
->element_type
);
4196 if (context
->field_name
->len
) {
4197 append_field_name(context
, context
->field_name
->str
);
4198 g_string_assign(context
->field_name
, "");
4200 g_string_append(context
->string
, "[");
4201 append_field_name(context
, sequence
->length_field_name
->str
);
4202 g_string_append(context
->string
, "]");
4208 int bt_field_type_string_serialize(struct bt_field_type
*type
,
4209 struct metadata_context
*context
)
4211 struct bt_field_type_string
*string
= container_of(
4212 type
, struct bt_field_type_string
, parent
);
4214 BT_LOGD("Serializing string field type's metadata: "
4215 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4216 g_string_append_printf(context
->string
,
4217 "string { encoding = %s; }",
4218 get_encoding_string(string
->encoding
));
4223 void bt_field_type_integer_set_byte_order(struct bt_field_type
*type
,
4224 enum bt_byte_order byte_order
)
4226 struct bt_field_type_integer
*integer_type
= container_of(type
,
4227 struct bt_field_type_integer
, parent
);
4229 integer_type
->user_byte_order
= byte_order
;
4233 void bt_field_type_enumeration_set_byte_order(
4234 struct bt_field_type
*type
, enum bt_byte_order byte_order
)
4236 struct bt_field_type_enumeration
*enum_type
= container_of(type
,
4237 struct bt_field_type_enumeration
, parent
);
4239 /* Safe to assume that container is an integer */
4240 bt_field_type_integer_set_byte_order(enum_type
->container
,
4245 void bt_field_type_floating_point_set_byte_order(
4246 struct bt_field_type
*type
, enum bt_byte_order byte_order
)
4248 struct bt_field_type_floating_point
*floating_point_type
=
4249 container_of(type
, struct bt_field_type_floating_point
,
4252 floating_point_type
->user_byte_order
= byte_order
;
4256 void bt_field_type_structure_set_byte_order(struct bt_field_type
*type
,
4257 enum bt_byte_order byte_order
)
4260 struct bt_field_type_structure
*structure_type
=
4261 container_of(type
, struct bt_field_type_structure
,
4264 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
4265 struct structure_field
*field
= g_ptr_array_index(
4266 structure_type
->fields
, i
);
4267 struct bt_field_type
*field_type
= field
->type
;
4269 if (set_byte_order_funcs
[field_type
->id
]) {
4270 set_byte_order_funcs
[field_type
->id
](
4271 field_type
, byte_order
);
4277 void bt_field_type_variant_set_byte_order(struct bt_field_type
*type
,
4278 enum bt_byte_order byte_order
)
4281 struct bt_field_type_variant
*variant_type
=
4282 container_of(type
, struct bt_field_type_variant
,
4285 for (i
= 0; i
< variant_type
->fields
->len
; i
++) {
4286 struct structure_field
*field
= g_ptr_array_index(
4287 variant_type
->fields
, i
);
4288 struct bt_field_type
*field_type
= field
->type
;
4290 if (set_byte_order_funcs
[field_type
->id
]) {
4291 set_byte_order_funcs
[field_type
->id
](
4292 field_type
, byte_order
);
4298 void bt_field_type_array_set_byte_order(struct bt_field_type
*type
,
4299 enum bt_byte_order byte_order
)
4301 struct bt_field_type_array
*array_type
=
4302 container_of(type
, struct bt_field_type_array
,
4305 if (set_byte_order_funcs
[array_type
->element_type
->id
]) {
4306 set_byte_order_funcs
[array_type
->element_type
->id
](
4307 array_type
->element_type
, byte_order
);
4312 void bt_field_type_sequence_set_byte_order(struct bt_field_type
*type
,
4313 enum bt_byte_order byte_order
)
4315 struct bt_field_type_sequence
*sequence_type
=
4316 container_of(type
, struct bt_field_type_sequence
,
4319 if (set_byte_order_funcs
[
4320 sequence_type
->element_type
->id
]) {
4321 set_byte_order_funcs
[
4322 sequence_type
->element_type
->id
](
4323 sequence_type
->element_type
, byte_order
);
4328 struct bt_field_type
*bt_field_type_integer_copy(
4329 struct bt_field_type
*type
)
4331 struct bt_field_type
*copy
;
4332 struct bt_field_type_integer
*integer
, *copy_integer
;
4334 BT_LOGD("Copying integer field type's: addr=%p", type
);
4335 integer
= container_of(type
, struct bt_field_type_integer
, parent
);
4336 copy
= bt_field_type_integer_create(integer
->size
);
4338 BT_LOGE_STR("Cannot create integer field type.");
4342 copy_integer
= container_of(copy
, struct bt_field_type_integer
,
4344 copy_integer
->mapped_clock
= bt_get(integer
->mapped_clock
);
4345 copy_integer
->user_byte_order
= integer
->user_byte_order
;
4346 copy_integer
->is_signed
= integer
->is_signed
;
4347 copy_integer
->size
= integer
->size
;
4348 copy_integer
->base
= integer
->base
;
4349 copy_integer
->encoding
= integer
->encoding
;
4350 BT_LOGD("Copied integer field type: original-ft-addr=%p, copy-ft-addr=%p",
4358 struct bt_field_type
*bt_field_type_enumeration_copy(
4359 struct bt_field_type
*type
)
4362 struct bt_field_type
*copy
= NULL
, *copy_container
;
4363 struct bt_field_type_enumeration
*enumeration
, *copy_enumeration
;
4365 BT_LOGD("Copying enumeration field type's: addr=%p", type
);
4366 enumeration
= container_of(type
, struct bt_field_type_enumeration
,
4369 /* Copy the source enumeration's container */
4370 BT_LOGD_STR("Copying enumeration field type's container field type.");
4371 copy_container
= bt_field_type_copy(enumeration
->container
);
4372 if (!copy_container
) {
4373 BT_LOGE_STR("Cannot copy enumeration field type's container field type.");
4377 copy
= bt_field_type_enumeration_create(copy_container
);
4379 BT_LOGE_STR("Cannot create enumeration field type.");
4382 copy_enumeration
= container_of(copy
,
4383 struct bt_field_type_enumeration
, parent
);
4385 /* Copy all enumaration entries */
4386 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
4387 struct enumeration_mapping
*mapping
= g_ptr_array_index(
4388 enumeration
->entries
, i
);
4389 struct enumeration_mapping
*copy_mapping
= g_new0(
4390 struct enumeration_mapping
, 1);
4392 if (!copy_mapping
) {
4393 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
4397 *copy_mapping
= *mapping
;
4398 g_ptr_array_add(copy_enumeration
->entries
, copy_mapping
);
4401 BT_LOGD("Copied enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
4405 bt_put(copy_container
);
4408 bt_put(copy_container
);
4414 struct bt_field_type
*bt_field_type_floating_point_copy(
4415 struct bt_field_type
*type
)
4417 struct bt_field_type
*copy
;
4418 struct bt_field_type_floating_point
*floating_point
, *copy_float
;
4420 BT_LOGD("Copying floating point number field type's: addr=%p", type
);
4421 floating_point
= container_of(type
,
4422 struct bt_field_type_floating_point
, parent
);
4423 copy
= bt_field_type_floating_point_create();
4425 BT_LOGE_STR("Cannot create floating point number field type.");
4429 copy_float
= container_of(copy
,
4430 struct bt_field_type_floating_point
, parent
);
4431 copy_float
->user_byte_order
= floating_point
->user_byte_order
;
4432 copy_float
->exp_dig
= floating_point
->exp_dig
;
4433 copy_float
->mant_dig
= floating_point
->mant_dig
;
4434 BT_LOGD("Copied floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
4441 struct bt_field_type
*bt_field_type_structure_copy(
4442 struct bt_field_type
*type
)
4445 GHashTableIter iter
;
4446 gpointer key
, value
;
4447 struct bt_field_type
*copy
;
4448 struct bt_field_type_structure
*structure
, *copy_structure
;
4450 BT_LOGD("Copying structure field type's: addr=%p", type
);
4451 structure
= container_of(type
, struct bt_field_type_structure
,
4453 copy
= bt_field_type_structure_create();
4455 BT_LOGE_STR("Cannot create structure field type.");
4459 copy_structure
= container_of(copy
,
4460 struct bt_field_type_structure
, parent
);
4462 /* Copy field_name_to_index */
4463 g_hash_table_iter_init(&iter
, structure
->field_name_to_index
);
4464 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
4465 g_hash_table_insert(copy_structure
->field_name_to_index
,
4469 for (i
= 0; i
< structure
->fields
->len
; i
++) {
4470 struct structure_field
*entry
, *copy_entry
;
4471 struct bt_field_type
*copy_field
;
4473 entry
= g_ptr_array_index(structure
->fields
, i
);
4474 BT_LOGD("Copying structure field type's field: "
4475 "index=%" PRId64
", "
4476 "field-ft-addr=%p, field-name=\"%s\"",
4477 i
, entry
, g_quark_to_string(entry
->name
));
4478 copy_entry
= g_new0(struct structure_field
, 1);
4480 BT_LOGE_STR("Failed to allocate one structure field type field.");
4484 copy_field
= bt_field_type_copy(entry
->type
);
4486 BT_LOGE("Cannot copy structure field type's field: "
4487 "index=%" PRId64
", "
4488 "field-ft-addr=%p, field-name=\"%s\"",
4489 i
, entry
, g_quark_to_string(entry
->name
));
4494 copy_entry
->name
= entry
->name
;
4495 copy_entry
->type
= copy_field
;
4496 g_ptr_array_add(copy_structure
->fields
, copy_entry
);
4499 BT_LOGD("Copied structure field type: original-ft-addr=%p, copy-ft-addr=%p",
4510 struct bt_field_type
*bt_field_type_variant_copy(
4511 struct bt_field_type
*type
)
4514 GHashTableIter iter
;
4515 gpointer key
, value
;
4516 struct bt_field_type
*copy
= NULL
, *copy_tag
= NULL
;
4517 struct bt_field_type_variant
*variant
, *copy_variant
;
4519 BT_LOGD("Copying variant field type's: addr=%p", type
);
4520 variant
= container_of(type
, struct bt_field_type_variant
,
4523 BT_LOGD_STR("Copying variant field type's tag field type.");
4524 copy_tag
= bt_field_type_copy(&variant
->tag
->parent
);
4526 BT_LOGE_STR("Cannot copy variant field type's tag field type.");
4531 copy
= bt_field_type_variant_create(copy_tag
,
4532 variant
->tag_name
->len
? variant
->tag_name
->str
: NULL
);
4534 BT_LOGE_STR("Cannot create variant field type.");
4538 copy_variant
= container_of(copy
, struct bt_field_type_variant
,
4541 /* Copy field_name_to_index */
4542 g_hash_table_iter_init(&iter
, variant
->field_name_to_index
);
4543 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
4544 g_hash_table_insert(copy_variant
->field_name_to_index
,
4548 for (i
= 0; i
< variant
->fields
->len
; i
++) {
4549 struct structure_field
*entry
, *copy_entry
;
4550 struct bt_field_type
*copy_field
;
4552 entry
= g_ptr_array_index(variant
->fields
, i
);
4553 BT_LOGD("Copying variant field type's field: "
4554 "index=%" PRId64
", "
4555 "field-ft-addr=%p, field-name=\"%s\"",
4556 i
, entry
, g_quark_to_string(entry
->name
));
4557 copy_entry
= g_new0(struct structure_field
, 1);
4559 BT_LOGE_STR("Failed to allocate one variant field type field.");
4563 copy_field
= bt_field_type_copy(entry
->type
);
4565 BT_LOGE("Cannot copy variant field type's field: "
4566 "index=%" PRId64
", "
4567 "field-ft-addr=%p, field-name=\"%s\"",
4568 i
, entry
, g_quark_to_string(entry
->name
));
4573 copy_entry
->name
= entry
->name
;
4574 copy_entry
->type
= copy_field
;
4575 g_ptr_array_add(copy_variant
->fields
, copy_entry
);
4578 if (variant
->tag_field_path
) {
4579 BT_LOGD_STR("Copying variant field type's tag field path.");
4580 copy_variant
->tag_field_path
= bt_field_path_copy(
4581 variant
->tag_field_path
);
4582 if (!copy_variant
->tag_field_path
) {
4583 BT_LOGE_STR("Cannot copy variant field type's tag field path.");
4588 BT_LOGD("Copied variant field type: original-ft-addr=%p, copy-ft-addr=%p",
4601 struct bt_field_type
*bt_field_type_array_copy(
4602 struct bt_field_type
*type
)
4604 struct bt_field_type
*copy
= NULL
, *copy_element
;
4605 struct bt_field_type_array
*array
;
4607 BT_LOGD("Copying array field type's: addr=%p", type
);
4608 array
= container_of(type
, struct bt_field_type_array
,
4610 BT_LOGD_STR("Copying array field type's element field type.");
4611 copy_element
= bt_field_type_copy(array
->element_type
);
4612 if (!copy_element
) {
4613 BT_LOGE_STR("Cannot copy array field type's element field type.");
4617 copy
= bt_field_type_array_create(copy_element
, array
->length
);
4619 BT_LOGE_STR("Cannot create array field type.");
4623 BT_LOGD("Copied array field type: original-ft-addr=%p, copy-ft-addr=%p",
4627 bt_put(copy_element
);
4632 struct bt_field_type
*bt_field_type_sequence_copy(
4633 struct bt_field_type
*type
)
4635 struct bt_field_type
*copy
= NULL
, *copy_element
;
4636 struct bt_field_type_sequence
*sequence
, *copy_sequence
;
4638 BT_LOGD("Copying sequence field type's: addr=%p", type
);
4639 sequence
= container_of(type
, struct bt_field_type_sequence
,
4641 BT_LOGD_STR("Copying sequence field type's element field type.");
4642 copy_element
= bt_field_type_copy(sequence
->element_type
);
4643 if (!copy_element
) {
4644 BT_LOGE_STR("Cannot copy sequence field type's element field type.");
4648 copy
= bt_field_type_sequence_create(copy_element
,
4649 sequence
->length_field_name
->len
?
4650 sequence
->length_field_name
->str
: NULL
);
4652 BT_LOGE_STR("Cannot create sequence field type.");
4656 copy_sequence
= container_of(copy
, struct bt_field_type_sequence
,
4658 if (sequence
->length_field_path
) {
4659 BT_LOGD_STR("Copying sequence field type's length field path.");
4660 copy_sequence
->length_field_path
= bt_field_path_copy(
4661 sequence
->length_field_path
);
4662 if (!copy_sequence
->length_field_path
) {
4663 BT_LOGE_STR("Cannot copy sequence field type's length field path.");
4668 BT_LOGD("Copied sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
4672 bt_put(copy_element
);
4680 struct bt_field_type
*bt_field_type_string_copy(
4681 struct bt_field_type
*type
)
4683 struct bt_field_type
*copy
;
4685 BT_LOGD("Copying string field type's: addr=%p", type
);
4686 copy
= bt_field_type_string_create();
4688 BT_LOGE_STR("Cannot create string field type.");
4692 BT_LOGD("Copied string field type: original-ft-addr=%p, copy-ft-addr=%p",
4699 int bt_field_type_integer_compare(struct bt_field_type
*type_a
,
4700 struct bt_field_type
*type_b
)
4703 struct bt_field_type_integer
*int_type_a
;
4704 struct bt_field_type_integer
*int_type_b
;
4706 int_type_a
= container_of(type_a
, struct bt_field_type_integer
,
4708 int_type_b
= container_of(type_b
, struct bt_field_type_integer
,
4712 if (int_type_a
->size
!= int_type_b
->size
) {
4713 BT_LOGV("Integer field types differ: different sizes: "
4714 "ft-a-size=%u, ft-b-size=%u",
4715 int_type_a
->size
, int_type_b
->size
);
4720 if (int_type_a
->user_byte_order
!= int_type_b
->user_byte_order
) {
4721 BT_LOGV("Integer field types differ: different byte orders: "
4722 "ft-a-bo=%s, ft-b-bo=%s",
4723 bt_byte_order_string(int_type_a
->user_byte_order
),
4724 bt_byte_order_string(int_type_b
->user_byte_order
));
4729 if (int_type_a
->is_signed
!= int_type_b
->is_signed
) {
4730 BT_LOGV("Integer field types differ: different signedness: "
4731 "ft-a-is-signed=%d, ft-b-is-signed=%d",
4732 int_type_a
->is_signed
,
4733 int_type_b
->is_signed
);
4738 if (int_type_a
->base
!= int_type_b
->base
) {
4739 BT_LOGV("Integer field types differ: different bases: "
4740 "ft-a-base=%s, ft-b-base=%s",
4741 bt_integer_base_string(int_type_a
->base
),
4742 bt_integer_base_string(int_type_b
->base
));
4747 if (int_type_a
->encoding
!= int_type_b
->encoding
) {
4748 BT_LOGV("Integer field types differ: different encodings: "
4749 "ft-a-encoding=%s, ft-b-encoding=%s",
4750 bt_string_encoding_string(int_type_a
->encoding
),
4751 bt_string_encoding_string(int_type_b
->encoding
));
4756 if (int_type_a
->mapped_clock
!= int_type_b
->mapped_clock
) {
4757 BT_LOGV("Integer field types differ: different mapped clock classes: "
4758 "ft-a-mapped-clock-class-addr=%p, "
4759 "ft-b-mapped-clock-class-addr=%p, "
4760 "ft-a-mapped-clock-class-name=\"%s\", "
4761 "ft-b-mapped-clock-class-name=\"%s\"",
4762 int_type_a
->mapped_clock
, int_type_b
->mapped_clock
,
4763 int_type_a
->mapped_clock
? bt_clock_class_get_name(int_type_a
->mapped_clock
) : "",
4764 int_type_b
->mapped_clock
? bt_clock_class_get_name(int_type_b
->mapped_clock
) : "");
4776 int bt_field_type_floating_point_compare(struct bt_field_type
*type_a
,
4777 struct bt_field_type
*type_b
)
4780 struct bt_field_type_floating_point
*float_a
;
4781 struct bt_field_type_floating_point
*float_b
;
4783 float_a
= container_of(type_a
,
4784 struct bt_field_type_floating_point
, parent
);
4785 float_b
= container_of(type_b
,
4786 struct bt_field_type_floating_point
, parent
);
4789 if (float_a
->user_byte_order
!= float_b
->user_byte_order
) {
4790 BT_LOGV("Floating point number field types differ: different byte orders: "
4791 "ft-a-bo=%s, ft-b-bo=%s",
4792 bt_byte_order_string(float_a
->user_byte_order
),
4793 bt_byte_order_string(float_b
->user_byte_order
));
4797 /* Exponent length */
4798 if (float_a
->exp_dig
!= float_b
->exp_dig
) {
4799 BT_LOGV("Floating point number field types differ: different exponent sizes: "
4800 "ft-a-exp-size=%u, ft-b-exp-size=%u",
4801 float_a
->exp_dig
, float_b
->exp_dig
);
4805 /* Mantissa length */
4806 if (float_a
->mant_dig
!= float_b
->mant_dig
) {
4807 BT_LOGV("Floating point number field types differ: different mantissa sizes: "
4808 "ft-a-mant-size=%u, ft-b-mant-size=%u",
4809 float_a
->mant_dig
, float_b
->mant_dig
);
4821 int compare_enumeration_mappings(struct enumeration_mapping
*mapping_a
,
4822 struct enumeration_mapping
*mapping_b
)
4827 if (mapping_a
->string
!= mapping_b
->string
) {
4828 BT_LOGV("Enumeration field type mappings differ: different names: "
4829 "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
4830 g_quark_to_string(mapping_a
->string
),
4831 g_quark_to_string(mapping_b
->string
));
4836 if (mapping_a
->range_start
._unsigned
!=
4837 mapping_b
->range_start
._unsigned
) {
4838 BT_LOGV("Enumeration field type mappings differ: different starts of range: "
4839 "mapping-a-range-start-unsigned=%" PRIu64
", "
4840 "mapping-b-range-start-unsigned=%" PRIu64
,
4841 mapping_a
->range_start
._unsigned
,
4842 mapping_b
->range_start
._unsigned
);
4847 if (mapping_a
->range_end
._unsigned
!=
4848 mapping_b
->range_end
._unsigned
) {
4849 BT_LOGV("Enumeration field type mappings differ: different ends of range: "
4850 "mapping-a-range-end-unsigned=%" PRIu64
", "
4851 "mapping-b-range-end-unsigned=%" PRIu64
,
4852 mapping_a
->range_end
._unsigned
,
4853 mapping_b
->range_end
._unsigned
);
4865 int bt_field_type_enumeration_compare(struct bt_field_type
*type_a
,
4866 struct bt_field_type
*type_b
)
4870 struct bt_field_type_enumeration
*enum_a
;
4871 struct bt_field_type_enumeration
*enum_b
;
4873 enum_a
= container_of(type_a
,
4874 struct bt_field_type_enumeration
, parent
);
4875 enum_b
= container_of(type_b
,
4876 struct bt_field_type_enumeration
, parent
);
4878 /* Container field type */
4879 ret
= bt_field_type_compare(enum_a
->container
, enum_b
->container
);
4881 BT_LOGV("Enumeration field types differ: different container field types: "
4882 "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
4883 enum_a
->container
, enum_b
->container
);
4890 if (enum_a
->entries
->len
!= enum_b
->entries
->len
) {
4894 for (i
= 0; i
< enum_a
->entries
->len
; ++i
) {
4895 struct enumeration_mapping
*mapping_a
=
4896 g_ptr_array_index(enum_a
->entries
, i
);
4897 struct enumeration_mapping
*mapping_b
=
4898 g_ptr_array_index(enum_b
->entries
, i
);
4900 if (compare_enumeration_mappings(mapping_a
, mapping_b
)) {
4901 BT_LOGV("Enumeration field types differ: different mappings: "
4902 "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
4903 "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
4904 mapping_a
, mapping_b
,
4905 g_quark_to_string(mapping_a
->string
),
4906 g_quark_to_string(mapping_b
->string
));
4919 int bt_field_type_string_compare(struct bt_field_type
*type_a
,
4920 struct bt_field_type
*type_b
)
4923 struct bt_field_type_string
*string_a
;
4924 struct bt_field_type_string
*string_b
;
4926 string_a
= container_of(type_a
,
4927 struct bt_field_type_string
, parent
);
4928 string_b
= container_of(type_b
,
4929 struct bt_field_type_string
, parent
);
4932 if (string_a
->encoding
!= string_b
->encoding
) {
4933 BT_LOGV("String field types differ: different encodings: "
4934 "ft-a-encoding=%s, ft-b-encoding=%s",
4935 bt_string_encoding_string(string_a
->encoding
),
4936 bt_string_encoding_string(string_b
->encoding
));
4948 int compare_structure_fields(struct structure_field
*field_a
,
4949 struct structure_field
*field_b
)
4954 if (field_a
->name
!= field_b
->name
) {
4955 BT_LOGV("Structure/variant field type fields differ: different names: "
4956 "field-a-name=%s, field-b-name=%s",
4957 g_quark_to_string(field_a
->name
),
4958 g_quark_to_string(field_b
->name
));
4963 ret
= bt_field_type_compare(field_a
->type
, field_b
->type
);
4965 BT_LOGV("Structure/variant field type fields differ: different field types: "
4966 "field-name=\"%s\", field-a-ft-addr=%p, field-b-ft-addr=%p",
4967 g_quark_to_string(field_a
->name
),
4968 field_a
->type
, field_b
->type
);
4976 int bt_field_type_structure_compare(struct bt_field_type
*type_a
,
4977 struct bt_field_type
*type_b
)
4981 struct bt_field_type_structure
*struct_a
;
4982 struct bt_field_type_structure
*struct_b
;
4984 struct_a
= container_of(type_a
,
4985 struct bt_field_type_structure
, parent
);
4986 struct_b
= container_of(type_b
,
4987 struct bt_field_type_structure
, parent
);
4990 if (bt_field_type_get_alignment(type_a
) !=
4991 bt_field_type_get_alignment(type_b
)) {
4992 BT_LOGV("Structure field types differ: different alignments: "
4993 "ft-a-align=%u, ft-b-align=%u",
4994 bt_field_type_get_alignment(type_a
),
4995 bt_field_type_get_alignment(type_b
));
5000 if (struct_a
->fields
->len
!= struct_b
->fields
->len
) {
5001 BT_LOGV("Structure field types differ: different field counts: "
5002 "ft-a-field-count=%u, ft-b-field-count=%u",
5003 struct_a
->fields
->len
, struct_b
->fields
->len
);
5007 for (i
= 0; i
< struct_a
->fields
->len
; ++i
) {
5008 struct structure_field
*field_a
=
5009 g_ptr_array_index(struct_a
->fields
, i
);
5010 struct structure_field
*field_b
=
5011 g_ptr_array_index(struct_b
->fields
, i
);
5013 ret
= compare_structure_fields(field_a
, field_b
);
5015 /* compare_structure_fields() logs what differs */
5016 BT_LOGV_STR("Structure field types differ: different fields.");
5029 int bt_field_type_variant_compare(struct bt_field_type
*type_a
,
5030 struct bt_field_type
*type_b
)
5034 struct bt_field_type_variant
*variant_a
;
5035 struct bt_field_type_variant
*variant_b
;
5037 variant_a
= container_of(type_a
,
5038 struct bt_field_type_variant
, parent
);
5039 variant_b
= container_of(type_b
,
5040 struct bt_field_type_variant
, parent
);
5043 if (strcmp(variant_a
->tag_name
->str
, variant_b
->tag_name
->str
)) {
5044 BT_LOGV("Variant field types differ: different tag field names: "
5045 "ft-a-tag-field-name=\"%s\", ft-b-tag-field-name=\"%s\"",
5046 variant_a
->tag_name
->str
, variant_b
->tag_name
->str
);
5051 ret
= bt_field_type_compare(
5052 (struct bt_field_type
*) variant_a
->tag
,
5053 (struct bt_field_type
*) variant_b
->tag
);
5055 BT_LOGV("Variant field types differ: different tag field types: "
5056 "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
5057 variant_a
->tag
, variant_b
->tag
);
5064 if (variant_a
->fields
->len
!= variant_b
->fields
->len
) {
5065 BT_LOGV("Structure field types differ: different field counts: "
5066 "ft-a-field-count=%u, ft-b-field-count=%u",
5067 variant_a
->fields
->len
, variant_b
->fields
->len
);
5071 for (i
= 0; i
< variant_a
->fields
->len
; ++i
) {
5072 struct structure_field
*field_a
=
5073 g_ptr_array_index(variant_a
->fields
, i
);
5074 struct structure_field
*field_b
=
5075 g_ptr_array_index(variant_b
->fields
, i
);
5077 ret
= compare_structure_fields(field_a
, field_b
);
5079 /* compare_structure_fields() logs what differs */
5080 BT_LOGV_STR("Variant field types differ: different fields.");
5093 int bt_field_type_array_compare(struct bt_field_type
*type_a
,
5094 struct bt_field_type
*type_b
)
5097 struct bt_field_type_array
*array_a
;
5098 struct bt_field_type_array
*array_b
;
5100 array_a
= container_of(type_a
,
5101 struct bt_field_type_array
, parent
);
5102 array_b
= container_of(type_b
,
5103 struct bt_field_type_array
, parent
);
5106 if (array_a
->length
!= array_b
->length
) {
5107 BT_LOGV("Structure field types differ: different lengths: "
5108 "ft-a-length=%u, ft-b-length=%u",
5109 array_a
->length
, array_b
->length
);
5114 ret
= bt_field_type_compare(array_a
->element_type
,
5115 array_b
->element_type
);
5117 BT_LOGV("Array field types differ: different element field types: "
5118 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
5119 array_a
->element_type
, array_b
->element_type
);
5127 int bt_field_type_sequence_compare(struct bt_field_type
*type_a
,
5128 struct bt_field_type
*type_b
)
5131 struct bt_field_type_sequence
*sequence_a
;
5132 struct bt_field_type_sequence
*sequence_b
;
5134 sequence_a
= container_of(type_a
,
5135 struct bt_field_type_sequence
, parent
);
5136 sequence_b
= container_of(type_b
,
5137 struct bt_field_type_sequence
, parent
);
5140 if (strcmp(sequence_a
->length_field_name
->str
,
5141 sequence_b
->length_field_name
->str
)) {
5142 BT_LOGV("Sequence field types differ: different length field names: "
5143 "ft-a-length-field-name=\"%s\", "
5144 "ft-b-length-field-name=\"%s\"",
5145 sequence_a
->length_field_name
->str
,
5146 sequence_b
->length_field_name
->str
);
5151 ret
= bt_field_type_compare(sequence_a
->element_type
,
5152 sequence_b
->element_type
);
5154 BT_LOGV("Sequence field types differ: different element field types: "
5155 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
5156 sequence_a
->element_type
, sequence_b
->element_type
);
5163 int bt_field_type_compare(struct bt_field_type
*type_a
,
5164 struct bt_field_type
*type_b
)
5168 if (type_a
== type_b
) {
5169 /* Same reference: equal (even if both are NULL) */
5175 BT_LOGW_STR("Invalid parameter: field type A is NULL.");
5181 BT_LOGW_STR("Invalid parameter: field type B is NULL.");
5186 if (type_a
->id
!= type_b
->id
) {
5187 /* Different type IDs */
5188 BT_LOGV("Field types differ: different IDs: "
5189 "ft-a-addr=%p, ft-b-addr=%p, "
5190 "ft-a-id=%s, ft-b-id=%s",
5192 bt_field_type_id_string(type_a
->id
),
5193 bt_field_type_id_string(type_b
->id
));
5197 if (type_a
->id
== BT_FIELD_TYPE_ID_UNKNOWN
) {
5198 /* Both have unknown type IDs */
5199 BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
5203 ret
= type_compare_funcs
[type_a
->id
](type_a
, type_b
);
5205 BT_LOGV("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
5214 int64_t bt_field_type_get_field_count(struct bt_field_type
*field_type
)
5216 int64_t field_count
= -1;
5217 enum bt_field_type_id type_id
= bt_field_type_get_type_id(field_type
);
5220 case CTF_TYPE_STRUCT
:
5222 bt_field_type_structure_get_field_count(field_type
);
5224 case CTF_TYPE_VARIANT
:
5226 bt_field_type_variant_get_field_count(field_type
);
5228 case CTF_TYPE_ARRAY
:
5229 case CTF_TYPE_SEQUENCE
:
5231 * Array and sequence types always contain a single member
5232 * (the element type).
5244 struct bt_field_type
*bt_field_type_get_field_at_index(
5245 struct bt_field_type
*field_type
, int index
)
5247 struct bt_field_type
*field
= NULL
;
5248 enum bt_field_type_id type_id
= bt_field_type_get_type_id(field_type
);
5251 case CTF_TYPE_STRUCT
:
5253 int ret
= bt_field_type_structure_get_field_by_index(
5254 field_type
, NULL
, &field
, index
);
5261 case CTF_TYPE_VARIANT
:
5263 int ret
= bt_field_type_variant_get_field_by_index(
5264 field_type
, NULL
, &field
, index
);
5271 case CTF_TYPE_ARRAY
:
5272 field
= bt_field_type_array_get_element_type(field_type
);
5274 case CTF_TYPE_SEQUENCE
:
5275 field
= bt_field_type_sequence_get_element_type(field_type
);
5285 int bt_field_type_get_field_index(struct bt_field_type
*field_type
,
5288 int field_index
= -1;
5289 enum bt_field_type_id type_id
= bt_field_type_get_type_id(field_type
);
5292 case CTF_TYPE_STRUCT
:
5293 field_index
= bt_field_type_structure_get_field_name_index(
5296 case CTF_TYPE_VARIANT
:
5297 field_index
= bt_field_type_variant_get_field_name_index(
5307 struct bt_field_path
*bt_field_type_variant_get_tag_field_path(
5308 struct bt_field_type
*type
)
5310 struct bt_field_path
*field_path
= NULL
;
5311 struct bt_field_type_variant
*variant
;
5314 BT_LOGW_STR("Invalid parameter: field type is NULL.");
5318 if (!bt_field_type_is_variant(type
)) {
5319 BT_LOGW("Invalid parameter: field type is not a variant field type: "
5320 "addr=%p, ft-id=%s", type
,
5321 bt_field_type_id_string(type
->id
));
5325 variant
= container_of(type
, struct bt_field_type_variant
,
5327 field_path
= bt_get(variant
->tag_field_path
);
5332 struct bt_field_path
*bt_field_type_sequence_get_length_field_path(
5333 struct bt_field_type
*type
)
5335 struct bt_field_path
*field_path
= NULL
;
5336 struct bt_field_type_sequence
*sequence
;
5339 BT_LOGW_STR("Invalid parameter: field type is NULL.");
5343 if (!bt_field_type_is_sequence(type
)) {
5344 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
5345 "addr=%p, ft-id=%s", type
,
5346 bt_field_type_id_string(type
->id
));
5350 sequence
= container_of(type
, struct bt_field_type_sequence
,
5352 field_path
= bt_get(sequence
->length_field_path
);