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 #include <babeltrace/ctf-writer/event-types.h>
30 #include <babeltrace/ctf-ir/event-types-internal.h>
31 #include <babeltrace/ctf-ir/utils.h>
32 #include <babeltrace/ctf-writer/writer-internal.h>
33 #include <babeltrace/compiler.h>
34 #include <babeltrace/endian.h>
39 struct range_overlap_query
{
54 void bt_ctf_field_type_destroy(struct bt_ctf_ref
*);
56 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*);
58 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*);
60 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*);
62 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*);
64 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*);
66 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*);
68 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*);
70 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*);
73 void (* const type_destroy_funcs
[])(struct bt_ctf_ref
*) = {
74 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_destroy
,
76 bt_ctf_field_type_enumeration_destroy
,
78 bt_ctf_field_type_floating_point_destroy
,
79 [CTF_TYPE_STRUCT
] = bt_ctf_field_type_structure_destroy
,
80 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_destroy
,
81 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_destroy
,
82 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_destroy
,
83 [CTF_TYPE_STRING
] = bt_ctf_field_type_string_destroy
,
87 void generic_field_type_freeze(struct bt_ctf_field_type
*);
89 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*);
91 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*);
93 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*);
95 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*);
97 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*);
100 type_freeze_func
const type_freeze_funcs
[] = {
101 [CTF_TYPE_INTEGER
] = generic_field_type_freeze
,
102 [CTF_TYPE_ENUM
] = bt_ctf_field_type_enumeration_freeze
,
103 [CTF_TYPE_FLOAT
] = generic_field_type_freeze
,
104 [CTF_TYPE_STRUCT
] = bt_ctf_field_type_structure_freeze
,
105 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_freeze
,
106 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_freeze
,
107 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_freeze
,
108 [CTF_TYPE_STRING
] = generic_field_type_freeze
,
112 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*,
113 struct metadata_context
*);
115 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*,
116 struct metadata_context
*);
118 int bt_ctf_field_type_floating_point_serialize(
119 struct bt_ctf_field_type
*, struct metadata_context
*);
121 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*,
122 struct metadata_context
*);
124 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*,
125 struct metadata_context
*);
127 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*,
128 struct metadata_context
*);
130 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*,
131 struct metadata_context
*);
133 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*,
134 struct metadata_context
*);
137 type_serialize_func
const type_serialize_funcs
[] = {
138 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_serialize
,
140 bt_ctf_field_type_enumeration_serialize
,
142 bt_ctf_field_type_floating_point_serialize
,
144 bt_ctf_field_type_structure_serialize
,
145 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_serialize
,
146 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_serialize
,
147 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_serialize
,
148 [CTF_TYPE_STRING
] = bt_ctf_field_type_string_serialize
,
152 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*,
155 void bt_ctf_field_type_floating_point_set_byte_order(
156 struct bt_ctf_field_type
*, int byte_order
);
159 void (* const set_byte_order_funcs
[])(struct bt_ctf_field_type
*,
162 bt_ctf_field_type_integer_set_byte_order
,
164 bt_ctf_field_type_floating_point_set_byte_order
,
165 [CTF_TYPE_ENUM
... CTF_TYPE_SEQUENCE
] = NULL
,
169 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
175 void destroy_structure_field(struct structure_field
*field
)
178 bt_ctf_field_type_put(field
->type
);
185 void check_ranges_overlap(gpointer element
, gpointer query
)
187 struct enumeration_mapping
*mapping
= element
;
188 struct range_overlap_query
*overlap_query
= query
;
190 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
191 && overlap_query
->range_start
._signed
<=
192 mapping
->range_end
._signed
) {
193 overlap_query
->overlaps
= 1;
194 overlap_query
->mapping_name
= mapping
->string
;
197 overlap_query
->overlaps
|=
198 mapping
->string
== overlap_query
->mapping_name
;
202 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
204 struct enumeration_mapping
*mapping
= element
;
205 struct range_overlap_query
*overlap_query
= query
;
207 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
208 && overlap_query
->range_start
._unsigned
<=
209 mapping
->range_end
._unsigned
) {
210 overlap_query
->overlaps
= 1;
211 overlap_query
->mapping_name
= mapping
->string
;
214 overlap_query
->overlaps
|=
215 mapping
->string
== overlap_query
->mapping_name
;
219 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
220 struct enumeration_mapping
**b
)
222 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
226 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
227 struct enumeration_mapping
**b
)
229 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
233 void bt_ctf_field_type_init(struct bt_ctf_field_type
*type
)
235 enum ctf_type_id type_id
= type
->declaration
->id
;
238 assert(type
&& (type_id
> CTF_TYPE_UNKNOWN
) &&
239 (type_id
< NR_CTF_TYPES
));
241 bt_ctf_ref_init(&type
->ref_count
);
242 type
->freeze
= type_freeze_funcs
[type_id
];
243 type
->serialize
= type_serialize_funcs
[type_id
];
244 ret
= bt_ctf_field_type_set_byte_order(type
, BT_CTF_BYTE_ORDER_NATIVE
);
246 type
->declaration
->alignment
= 1;
250 int add_structure_field(GPtrArray
*fields
,
251 GHashTable
*field_name_to_index
,
252 struct bt_ctf_field_type
*field_type
,
253 const char *field_name
)
256 GQuark name_quark
= g_quark_from_string(field_name
);
257 struct structure_field
*field
;
259 /* Make sure structure does not contain a field of the same name */
260 if (g_hash_table_lookup_extended(field_name_to_index
,
261 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
266 field
= g_new0(struct structure_field
, 1);
272 bt_ctf_field_type_get(field_type
);
273 field
->name
= name_quark
;
274 field
->type
= field_type
;
275 g_hash_table_insert(field_name_to_index
,
276 (gpointer
) (unsigned long) name_quark
,
277 (gpointer
) (unsigned long) fields
->len
);
278 g_ptr_array_add(fields
, field
);
279 bt_ctf_field_type_freeze(field_type
);
285 void bt_ctf_field_type_destroy(struct bt_ctf_ref
*ref
)
287 struct bt_ctf_field_type
*type
;
288 enum ctf_type_id type_id
;
294 type
= container_of(ref
, struct bt_ctf_field_type
, ref_count
);
295 type_id
= type
->declaration
->id
;
296 if (type_id
<= CTF_TYPE_UNKNOWN
||
297 type_id
>= NR_CTF_TYPES
) {
301 if (type
->alias_name
) {
302 g_string_free(type
->alias_name
, TRUE
);
304 type_destroy_funcs
[type_id
](ref
);
308 int bt_ctf_field_type_validate(struct bt_ctf_field_type
*type
)
317 if (type
->declaration
->id
== CTF_TYPE_ENUM
) {
318 struct bt_ctf_field_type_enumeration
*enumeration
=
319 container_of(type
, struct bt_ctf_field_type_enumeration
,
322 ret
= enumeration
->entries
->len
? 0 : -1;
328 struct bt_ctf_field_type
*bt_ctf_field_type_integer_create(unsigned int size
)
330 struct bt_ctf_field_type_integer
*integer
=
331 g_new0(struct bt_ctf_field_type_integer
, 1);
333 if (!integer
|| size
> 64) {
337 integer
->parent
.declaration
= &integer
->declaration
.p
;
338 integer
->parent
.declaration
->id
= CTF_TYPE_INTEGER
;
339 integer
->declaration
.len
= size
;
340 integer
->declaration
.base
= BT_CTF_INTEGER_BASE_DECIMAL
;
341 integer
->declaration
.encoding
= CTF_STRING_NONE
;
342 bt_ctf_field_type_init(&integer
->parent
);
343 return &integer
->parent
;
346 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type
*type
)
349 struct bt_ctf_field_type_integer
*integer
;
351 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
356 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
357 ret
= (int) integer
->declaration
.len
;
362 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type
*type
)
365 struct bt_ctf_field_type_integer
*integer
;
367 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
372 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
373 ret
= integer
->declaration
.signedness
;
378 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type
*type
,
382 struct bt_ctf_field_type_integer
*integer
;
384 if (!type
|| type
->frozen
||
385 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
390 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
391 if (is_signed
&& integer
->declaration
.len
<= 1) {
396 integer
->declaration
.signedness
= !!is_signed
;
401 enum bt_ctf_integer_base
bt_ctf_field_type_integer_get_base(
402 struct bt_ctf_field_type
*type
)
404 enum bt_ctf_integer_base ret
= BT_CTF_INTEGER_BASE_UNKNOWN
;
405 struct bt_ctf_field_type_integer
*integer
;
407 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
411 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
412 ret
= integer
->declaration
.base
;
417 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type
*type
,
418 enum bt_ctf_integer_base base
)
422 if (!type
|| type
->frozen
||
423 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
429 case BT_CTF_INTEGER_BASE_BINARY
:
430 case BT_CTF_INTEGER_BASE_OCTAL
:
431 case BT_CTF_INTEGER_BASE_DECIMAL
:
432 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
434 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
435 struct bt_ctf_field_type_integer
, parent
);
436 integer
->declaration
.base
= base
;
446 enum ctf_string_encoding
bt_ctf_field_type_integer_get_encoding(
447 struct bt_ctf_field_type
*type
)
449 enum ctf_string_encoding ret
= CTF_STRING_UNKNOWN
;
450 struct bt_ctf_field_type_integer
*integer
;
452 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
456 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
457 ret
= integer
->declaration
.encoding
;
462 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type
*type
,
463 enum ctf_string_encoding encoding
)
466 struct bt_ctf_field_type_integer
*integer
;
468 if (!type
|| type
->frozen
||
469 (type
->declaration
->id
!= CTF_TYPE_INTEGER
) ||
470 (encoding
< CTF_STRING_NONE
) ||
471 (encoding
>= CTF_STRING_UNKNOWN
)) {
476 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
477 integer
->declaration
.encoding
= encoding
;
482 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_create(
483 struct bt_ctf_field_type
*integer_container_type
)
485 struct bt_ctf_field_type_enumeration
*enumeration
= NULL
;
487 if (!integer_container_type
) {
491 if (integer_container_type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
495 enumeration
= g_new0(struct bt_ctf_field_type_enumeration
, 1);
500 enumeration
->parent
.declaration
= &enumeration
->declaration
.p
;
501 enumeration
->parent
.declaration
->id
= CTF_TYPE_ENUM
;
502 bt_ctf_field_type_get(integer_container_type
);
503 enumeration
->container
= integer_container_type
;
504 enumeration
->entries
= g_ptr_array_new_with_free_func(
505 (GDestroyNotify
)destroy_enumeration_mapping
);
506 bt_ctf_field_type_init(&enumeration
->parent
);
507 return &enumeration
->parent
;
513 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_get_container_type(
514 struct bt_ctf_field_type
*type
)
516 struct bt_ctf_field_type
*container_type
= NULL
;
517 struct bt_ctf_field_type_enumeration
*enumeration_type
;
523 if (type
->declaration
->id
!= CTF_TYPE_ENUM
) {
527 enumeration_type
= container_of(type
,
528 struct bt_ctf_field_type_enumeration
, parent
);
529 container_type
= enumeration_type
->container
;
530 bt_ctf_field_type_get(container_type
);
532 return container_type
;
535 int bt_ctf_field_type_enumeration_add_mapping(
536 struct bt_ctf_field_type
*type
, const char *string
,
537 int64_t range_start
, int64_t range_end
)
541 struct enumeration_mapping
*mapping
;
542 struct bt_ctf_field_type_enumeration
*enumeration
;
543 struct range_overlap_query query
;
544 char *escaped_string
;
546 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
548 (range_end
< range_start
)) {
553 if (!string
|| strlen(string
) == 0) {
558 escaped_string
= g_strescape(string
, NULL
);
559 if (!escaped_string
) {
564 mapping_name
= g_quark_from_string(escaped_string
);
565 query
= (struct range_overlap_query
) {
566 .range_start
._signed
= range_start
,
567 .range_end
._signed
= range_end
,
568 .mapping_name
= mapping_name
,
570 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
573 /* Check that the range does not overlap with one already present */
574 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap
, &query
);
575 if (query
.overlaps
) {
580 mapping
= g_new(struct enumeration_mapping
, 1);
586 *mapping
= (struct enumeration_mapping
) {
587 .range_start
._signed
= range_start
,
588 .range_end
._signed
= range_end
, .string
= mapping_name
};
589 g_ptr_array_add(enumeration
->entries
, mapping
);
590 g_ptr_array_sort(enumeration
->entries
,
591 (GCompareFunc
)compare_enumeration_mappings_signed
);
593 free(escaped_string
);
598 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
599 struct bt_ctf_field_type
*type
, const char *string
,
600 uint64_t range_start
, uint64_t range_end
)
604 struct enumeration_mapping
*mapping
;
605 struct bt_ctf_field_type_enumeration
*enumeration
;
606 struct range_overlap_query query
;
607 char *escaped_string
;
609 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
611 (range_end
< range_start
)) {
616 if (!string
|| strlen(string
) == 0) {
621 escaped_string
= g_strescape(string
, NULL
);
622 if (!escaped_string
) {
627 mapping_name
= g_quark_from_string(escaped_string
);
628 query
= (struct range_overlap_query
) {
629 .range_start
._unsigned
= range_start
,
630 .range_end
._unsigned
= range_end
,
631 .mapping_name
= mapping_name
,
633 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
636 /* Check that the range does not overlap with one already present */
637 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap_unsigned
,
639 if (query
.overlaps
) {
644 mapping
= g_new(struct enumeration_mapping
, 1);
650 *mapping
= (struct enumeration_mapping
) {
651 .range_start
._unsigned
= range_start
,
652 .range_end
._unsigned
= range_end
, .string
= mapping_name
};
653 g_ptr_array_add(enumeration
->entries
, mapping
);
654 g_ptr_array_sort(enumeration
->entries
,
655 (GCompareFunc
)compare_enumeration_mappings_unsigned
);
657 free(escaped_string
);
662 const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
663 struct bt_ctf_field_type_enumeration
*enumeration_type
,
666 const char *name
= NULL
;
667 struct range_overlap_query query
=
668 (struct range_overlap_query
) {
669 .range_start
._unsigned
= value
,
670 .range_end
._unsigned
= value
,
673 g_ptr_array_foreach(enumeration_type
->entries
,
674 check_ranges_overlap_unsigned
,
676 if (!query
.overlaps
) {
680 name
= g_quark_to_string(query
.mapping_name
);
685 const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
686 struct bt_ctf_field_type_enumeration
*enumeration_type
,
689 const char *name
= NULL
;
690 struct range_overlap_query query
=
691 (struct range_overlap_query
) {
692 .range_start
._signed
= value
,
693 .range_end
._signed
= value
,
696 g_ptr_array_foreach(enumeration_type
->entries
, check_ranges_overlap
,
698 if (!query
.overlaps
) {
702 name
= g_quark_to_string(query
.mapping_name
);
707 int bt_ctf_field_type_enumeration_get_mapping_count(
708 struct bt_ctf_field_type
*type
)
711 struct bt_ctf_field_type_enumeration
*enumeration
;
713 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
718 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
720 ret
= (int) enumeration
->entries
->len
;
726 struct enumeration_mapping
*get_enumeration_mapping(
727 struct bt_ctf_field_type
*type
, int index
)
729 struct enumeration_mapping
*mapping
= NULL
;
730 struct bt_ctf_field_type_enumeration
*enumeration
;
732 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
734 if (index
>= enumeration
->entries
->len
) {
738 mapping
= g_ptr_array_index(enumeration
->entries
, index
);
743 int bt_ctf_field_type_enumeration_get_mapping(
744 struct bt_ctf_field_type
*type
, int index
,
745 const char **string
, int64_t *range_start
, int64_t *range_end
)
747 struct enumeration_mapping
*mapping
;
750 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
751 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
756 mapping
= get_enumeration_mapping(type
, index
);
762 *string
= g_quark_to_string(mapping
->string
);
763 *range_start
= mapping
->range_start
._signed
;
764 *range_end
= mapping
->range_end
._signed
;
769 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
770 struct bt_ctf_field_type
*type
, int index
,
771 const char **string
, uint64_t *range_start
, uint64_t *range_end
)
773 struct enumeration_mapping
*mapping
;
776 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
777 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
782 mapping
= get_enumeration_mapping(type
, index
);
788 *string
= g_quark_to_string(mapping
->string
);
789 *range_start
= mapping
->range_start
._unsigned
;
790 *range_end
= mapping
->range_end
._unsigned
;
795 int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
796 struct bt_ctf_field_type
*type
, const char *name
)
799 struct bt_ctf_field_type_enumeration
*enumeration
;
802 if (!type
|| !name
||
803 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
808 name_quark
= g_quark_try_string(name
);
814 enumeration
= container_of(type
,
815 struct bt_ctf_field_type_enumeration
, parent
);
816 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
817 struct enumeration_mapping
*mapping
=
818 get_enumeration_mapping(type
, i
);
820 if (mapping
->string
== name_quark
) {
831 int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
832 struct bt_ctf_field_type
*type
, int64_t value
)
834 struct bt_ctf_field_type_enumeration
*enumeration
;
837 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
842 enumeration
= container_of(type
,
843 struct bt_ctf_field_type_enumeration
, parent
);
844 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
845 struct enumeration_mapping
*mapping
=
846 get_enumeration_mapping(type
, i
);
848 if (value
>= mapping
->range_start
._signed
&&
849 value
<= mapping
->range_end
._signed
) {
860 int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
861 struct bt_ctf_field_type
*type
, uint64_t value
)
863 struct bt_ctf_field_type_enumeration
*enumeration
;
866 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
871 enumeration
= container_of(type
,
872 struct bt_ctf_field_type_enumeration
, parent
);
873 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
874 struct enumeration_mapping
*mapping
=
875 get_enumeration_mapping(type
, i
);
877 if (value
>= mapping
->range_start
._unsigned
&&
878 value
<= mapping
->range_end
._unsigned
) {
889 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_create(void)
891 struct bt_ctf_field_type_floating_point
*floating_point
=
892 g_new0(struct bt_ctf_field_type_floating_point
, 1);
894 if (!floating_point
) {
898 floating_point
->declaration
.sign
= &floating_point
->sign
;
899 floating_point
->declaration
.mantissa
= &floating_point
->mantissa
;
900 floating_point
->declaration
.exp
= &floating_point
->exp
;
901 floating_point
->sign
.len
= 1;
902 floating_point
->parent
.declaration
= &floating_point
->declaration
.p
;
903 floating_point
->parent
.declaration
->id
= CTF_TYPE_FLOAT
;
904 floating_point
->declaration
.exp
->len
=
905 sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
906 floating_point
->declaration
.mantissa
->len
= FLT_MANT_DIG
- 1;
907 floating_point
->sign
.p
.alignment
= 1;
908 floating_point
->mantissa
.p
.alignment
= 1;
909 floating_point
->exp
.p
.alignment
= 1;
911 bt_ctf_field_type_init(&floating_point
->parent
);
913 return floating_point
? &floating_point
->parent
: NULL
;
916 int bt_ctf_field_type_floating_point_get_exponent_digits(
917 struct bt_ctf_field_type
*type
)
920 struct bt_ctf_field_type_floating_point
*floating_point
;
922 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
927 floating_point
= container_of(type
,
928 struct bt_ctf_field_type_floating_point
, parent
);
929 ret
= (int) floating_point
->declaration
.exp
->len
;
934 int bt_ctf_field_type_floating_point_set_exponent_digits(
935 struct bt_ctf_field_type
*type
,
936 unsigned int exponent_digits
)
939 struct bt_ctf_field_type_floating_point
*floating_point
;
941 if (!type
|| type
->frozen
||
942 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
947 floating_point
= container_of(type
,
948 struct bt_ctf_field_type_floating_point
, parent
);
949 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
950 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
952 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
957 floating_point
->declaration
.exp
->len
= exponent_digits
;
962 int bt_ctf_field_type_floating_point_get_mantissa_digits(
963 struct bt_ctf_field_type
*type
)
966 struct bt_ctf_field_type_floating_point
*floating_point
;
968 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
973 floating_point
= container_of(type
,
974 struct bt_ctf_field_type_floating_point
, parent
);
975 ret
= (int) floating_point
->mantissa
.len
+ 1;
980 int bt_ctf_field_type_floating_point_set_mantissa_digits(
981 struct bt_ctf_field_type
*type
,
982 unsigned int mantissa_digits
)
985 struct bt_ctf_field_type_floating_point
*floating_point
;
987 if (!type
|| type
->frozen
||
988 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
993 floating_point
= container_of(type
,
994 struct bt_ctf_field_type_floating_point
, parent
);
996 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
997 (mantissa_digits
!= DBL_MANT_DIG
) &&
998 (mantissa_digits
!= LDBL_MANT_DIG
)) {
1003 floating_point
->declaration
.mantissa
->len
= mantissa_digits
- 1;
1008 struct bt_ctf_field_type
*bt_ctf_field_type_structure_create(void)
1010 struct bt_ctf_field_type_structure
*structure
=
1011 g_new0(struct bt_ctf_field_type_structure
, 1);
1017 structure
->parent
.declaration
= &structure
->declaration
.p
;
1018 structure
->parent
.declaration
->id
= CTF_TYPE_STRUCT
;
1019 bt_ctf_field_type_init(&structure
->parent
);
1020 structure
->fields
= g_ptr_array_new_with_free_func(
1021 (GDestroyNotify
)destroy_structure_field
);
1022 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1023 return &structure
->parent
;
1028 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type
*type
,
1029 struct bt_ctf_field_type
*field_type
,
1030 const char *field_name
)
1033 struct bt_ctf_field_type_structure
*structure
;
1035 if (!type
|| !field_type
|| type
->frozen
||
1036 bt_ctf_validate_identifier(field_name
) ||
1037 (type
->declaration
->id
!= CTF_TYPE_STRUCT
) ||
1038 bt_ctf_field_type_validate(field_type
)) {
1043 structure
= container_of(type
,
1044 struct bt_ctf_field_type_structure
, parent
);
1045 if (add_structure_field(structure
->fields
,
1046 structure
->field_name_to_index
, field_type
, field_name
)) {
1051 if (type
->declaration
->alignment
< field_type
->declaration
->alignment
) {
1052 type
->declaration
->alignment
=
1053 field_type
->declaration
->alignment
;
1059 int bt_ctf_field_type_structure_get_field_count(
1060 struct bt_ctf_field_type
*type
)
1063 struct bt_ctf_field_type_structure
*structure
;
1065 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_STRUCT
)) {
1070 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1072 ret
= (int) structure
->fields
->len
;
1077 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type
*type
,
1078 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1081 struct bt_ctf_field_type_structure
*structure
;
1082 struct structure_field
*field
;
1085 if (!type
|| index
< 0 || !field_name
|| !field_type
||
1086 (type
->declaration
->id
!= CTF_TYPE_STRUCT
)) {
1091 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1093 if (index
>= structure
->fields
->len
) {
1098 field
= g_ptr_array_index(structure
->fields
, index
);
1099 *field_type
= field
->type
;
1100 bt_ctf_field_type_get(field
->type
);
1101 *field_name
= g_quark_to_string(field
->name
);
1106 struct bt_ctf_field_type
*bt_ctf_field_type_structure_get_field_type_by_name(
1107 struct bt_ctf_field_type
*type
,
1112 struct structure_field
*field
;
1113 struct bt_ctf_field_type_structure
*structure
;
1114 struct bt_ctf_field_type
*field_type
= NULL
;
1116 if (!type
|| !name
) {
1120 name_quark
= g_quark_try_string(name
);
1125 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1127 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
1128 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1132 field
= structure
->fields
->pdata
[index
];
1133 field_type
= field
->type
;
1134 bt_ctf_field_type_get(field_type
);
1139 struct bt_ctf_field_type
*bt_ctf_field_type_variant_create(
1140 struct bt_ctf_field_type
*enum_tag
, const char *tag_name
)
1142 struct bt_ctf_field_type_variant
*variant
= NULL
;
1144 if (!enum_tag
|| bt_ctf_validate_identifier(tag_name
) ||
1145 (enum_tag
->declaration
->id
!= CTF_TYPE_ENUM
)) {
1149 variant
= g_new0(struct bt_ctf_field_type_variant
, 1);
1154 variant
->parent
.declaration
= &variant
->declaration
.p
;
1155 variant
->parent
.declaration
->id
= CTF_TYPE_VARIANT
;
1156 variant
->tag_name
= g_string_new(tag_name
);
1157 bt_ctf_field_type_init(&variant
->parent
);
1158 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1159 variant
->fields
= g_ptr_array_new_with_free_func(
1160 (GDestroyNotify
)destroy_structure_field
);
1161 bt_ctf_field_type_get(enum_tag
);
1162 variant
->tag
= container_of(enum_tag
,
1163 struct bt_ctf_field_type_enumeration
, parent
);
1164 return &variant
->parent
;
1169 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_tag_type(
1170 struct bt_ctf_field_type
*type
)
1172 struct bt_ctf_field_type_variant
*variant
;
1173 struct bt_ctf_field_type
*tag_type
= NULL
;
1175 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1179 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1180 tag_type
= &variant
->tag
->parent
;
1181 bt_ctf_field_type_get(tag_type
);
1186 const char *bt_ctf_field_type_variant_get_tag_name(
1187 struct bt_ctf_field_type
*type
)
1189 struct bt_ctf_field_type_variant
*variant
;
1190 const char *tag_name
= NULL
;
1192 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1196 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1197 tag_name
= variant
->tag_name
->str
;
1202 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type
*type
,
1203 struct bt_ctf_field_type
*field_type
,
1204 const char *field_name
)
1209 struct bt_ctf_field_type_variant
*variant
;
1210 GQuark field_name_quark
= g_quark_from_string(field_name
);
1212 if (!type
|| !field_type
|| type
->frozen
||
1213 bt_ctf_validate_identifier(field_name
) ||
1214 (type
->declaration
->id
!= CTF_TYPE_VARIANT
) ||
1215 bt_ctf_field_type_validate(field_type
)) {
1220 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1221 /* Make sure this name is present in the enum tag */
1222 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
1223 struct enumeration_mapping
*mapping
=
1224 g_ptr_array_index(variant
->tag
->entries
, i
);
1226 if (mapping
->string
== field_name_quark
) {
1232 if (!name_found
|| add_structure_field(variant
->fields
,
1233 variant
->field_name_to_index
, field_type
, field_name
)) {
1241 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_by_name(
1242 struct bt_ctf_field_type
*type
,
1243 const char *field_name
)
1247 struct structure_field
*field
;
1248 struct bt_ctf_field_type_variant
*variant
;
1249 struct bt_ctf_field_type
*field_type
= NULL
;
1251 if (!type
|| !field_name
) {
1255 name_quark
= g_quark_try_string(field_name
);
1260 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1261 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1262 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1266 field
= g_ptr_array_index(variant
->fields
, index
);
1267 field_type
= field
->type
;
1268 bt_ctf_field_type_get(field_type
);
1273 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_from_tag(
1274 struct bt_ctf_field_type
*type
,
1275 struct bt_ctf_field
*tag
)
1277 const char *enum_value
;
1278 struct bt_ctf_field_type
*field_type
= NULL
;
1280 if (!type
|| !tag
|| type
->declaration
->id
!= CTF_TYPE_VARIANT
) {
1284 enum_value
= bt_ctf_field_enumeration_get_mapping_name(tag
);
1289 /* Already increments field_type's reference count */
1290 field_type
= bt_ctf_field_type_variant_get_field_type_by_name(
1296 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type
*type
)
1299 struct bt_ctf_field_type_variant
*variant
;
1301 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1306 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1308 ret
= (int) variant
->fields
->len
;
1314 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type
*type
,
1315 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1318 struct bt_ctf_field_type_variant
*variant
;
1319 struct structure_field
*field
;
1322 if (!type
|| index
< 0 || !field_name
|| !field_type
||
1323 (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1328 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1330 if (index
>= variant
->fields
->len
) {
1335 field
= g_ptr_array_index(variant
->fields
, index
);
1336 *field_type
= field
->type
;
1337 bt_ctf_field_type_get(field
->type
);
1338 *field_name
= g_quark_to_string(field
->name
);
1343 struct bt_ctf_field_type
*bt_ctf_field_type_array_create(
1344 struct bt_ctf_field_type
*element_type
,
1345 unsigned int length
)
1347 struct bt_ctf_field_type_array
*array
= NULL
;
1349 if (!element_type
|| length
== 0 ||
1350 bt_ctf_field_type_validate(element_type
)) {
1354 array
= g_new0(struct bt_ctf_field_type_array
, 1);
1359 array
->parent
.declaration
= &array
->declaration
.p
;
1360 array
->parent
.declaration
->id
= CTF_TYPE_ARRAY
;
1361 bt_ctf_field_type_init(&array
->parent
);
1362 bt_ctf_field_type_get(element_type
);
1363 array
->element_type
= element_type
;
1364 array
->length
= length
;
1365 array
->parent
.declaration
->alignment
=
1366 element_type
->declaration
->alignment
;
1367 return &array
->parent
;
1372 struct bt_ctf_field_type
*bt_ctf_field_type_array_get_element_type(
1373 struct bt_ctf_field_type
*type
)
1375 struct bt_ctf_field_type
*ret
= NULL
;
1376 struct bt_ctf_field_type_array
*array
;
1378 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ARRAY
)) {
1382 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1383 ret
= array
->element_type
;
1384 bt_ctf_field_type_get(ret
);
1389 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type
*type
)
1392 struct bt_ctf_field_type_array
*array
;
1394 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ARRAY
)) {
1399 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1400 ret
= (int64_t) array
->length
;
1405 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_create(
1406 struct bt_ctf_field_type
*element_type
,
1407 const char *length_field_name
)
1409 struct bt_ctf_field_type_sequence
*sequence
= NULL
;
1411 if (!element_type
|| bt_ctf_validate_identifier(length_field_name
) ||
1412 bt_ctf_field_type_validate(element_type
)) {
1416 sequence
= g_new0(struct bt_ctf_field_type_sequence
, 1);
1421 sequence
->parent
.declaration
= &sequence
->declaration
.p
;
1422 sequence
->parent
.declaration
->id
= CTF_TYPE_SEQUENCE
;
1423 bt_ctf_field_type_init(&sequence
->parent
);
1424 bt_ctf_field_type_get(element_type
);
1425 sequence
->element_type
= element_type
;
1426 sequence
->length_field_name
= g_string_new(length_field_name
);
1427 sequence
->parent
.declaration
->alignment
=
1428 element_type
->declaration
->alignment
;
1429 return &sequence
->parent
;
1434 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_get_element_type(
1435 struct bt_ctf_field_type
*type
)
1437 struct bt_ctf_field_type
*ret
= NULL
;
1438 struct bt_ctf_field_type_sequence
*sequence
;
1440 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_SEQUENCE
)) {
1444 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1446 ret
= sequence
->element_type
;
1447 bt_ctf_field_type_get(ret
);
1452 const char *bt_ctf_field_type_sequence_get_length_field_name(
1453 struct bt_ctf_field_type
*type
)
1455 const char *ret
= NULL
;
1456 struct bt_ctf_field_type_sequence
*sequence
;
1458 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_SEQUENCE
)) {
1462 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1464 ret
= sequence
->length_field_name
->str
;
1469 struct bt_ctf_field_type
*bt_ctf_field_type_string_create(void)
1471 struct bt_ctf_field_type_string
*string
=
1472 g_new0(struct bt_ctf_field_type_string
, 1);
1478 string
->parent
.declaration
= &string
->declaration
.p
;
1479 string
->parent
.declaration
->id
= CTF_TYPE_STRING
;
1480 bt_ctf_field_type_init(&string
->parent
);
1481 string
->declaration
.encoding
= CTF_STRING_UTF8
;
1482 string
->parent
.declaration
->alignment
= CHAR_BIT
;
1483 return &string
->parent
;
1486 enum ctf_string_encoding
bt_ctf_field_type_string_get_encoding(
1487 struct bt_ctf_field_type
*type
)
1489 struct bt_ctf_field_type_string
*string
;
1490 enum ctf_string_encoding ret
= CTF_STRING_UNKNOWN
;
1492 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_STRING
)) {
1496 string
= container_of(type
, struct bt_ctf_field_type_string
,
1498 ret
= string
->declaration
.encoding
;
1503 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type
*type
,
1504 enum ctf_string_encoding encoding
)
1507 struct bt_ctf_field_type_string
*string
;
1509 if (!type
|| type
->declaration
->id
!= CTF_TYPE_STRING
||
1510 (encoding
!= CTF_STRING_UTF8
&&
1511 encoding
!= CTF_STRING_ASCII
)) {
1516 string
= container_of(type
, struct bt_ctf_field_type_string
, parent
);
1517 string
->declaration
.encoding
= encoding
;
1522 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type
*type
)
1531 ret
= (int) type
->declaration
->alignment
;
1536 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type
*type
,
1537 unsigned int alignment
)
1541 /* Alignment must be bit-aligned (1) or byte aligned */
1542 if (!type
|| type
->frozen
|| (alignment
!= 1 && (alignment
& 0x7))) {
1547 if (type
->declaration
->id
== CTF_TYPE_STRING
&&
1548 alignment
!= CHAR_BIT
) {
1553 type
->declaration
->alignment
= alignment
;
1559 enum bt_ctf_byte_order
bt_ctf_field_type_get_byte_order(
1560 struct bt_ctf_field_type
*type
)
1562 enum bt_ctf_byte_order ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1568 switch (type
->declaration
->id
) {
1569 case CTF_TYPE_INTEGER
:
1571 struct bt_ctf_field_type_integer
*integer
= container_of(
1572 type
, struct bt_ctf_field_type_integer
, parent
);
1573 ret
= integer
->declaration
.byte_order
== LITTLE_ENDIAN
?
1574 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
1575 BT_CTF_BYTE_ORDER_BIG_ENDIAN
;
1578 case CTF_TYPE_FLOAT
:
1580 struct bt_ctf_field_type_floating_point
*floating_point
=
1582 struct bt_ctf_field_type_floating_point
,
1584 ret
= floating_point
->declaration
.byte_order
== LITTLE_ENDIAN
?
1585 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
1586 BT_CTF_BYTE_ORDER_BIG_ENDIAN
;
1596 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type
*type
,
1597 enum bt_ctf_byte_order byte_order
)
1600 int internal_byte_order
;
1601 enum ctf_type_id type_id
;
1603 if (!type
|| type
->frozen
) {
1608 type_id
= type
->declaration
->id
;
1609 switch (byte_order
) {
1610 case BT_CTF_BYTE_ORDER_NATIVE
:
1611 internal_byte_order
= (G_BYTE_ORDER
== G_LITTLE_ENDIAN
?
1612 LITTLE_ENDIAN
: BIG_ENDIAN
);
1614 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
1615 internal_byte_order
= LITTLE_ENDIAN
;
1617 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
1618 case BT_CTF_BYTE_ORDER_NETWORK
:
1619 internal_byte_order
= BIG_ENDIAN
;
1626 if (set_byte_order_funcs
[type_id
]) {
1627 set_byte_order_funcs
[type_id
](type
, internal_byte_order
);
1633 enum ctf_type_id
bt_ctf_field_type_get_type_id(
1634 struct bt_ctf_field_type
*type
)
1637 return CTF_TYPE_UNKNOWN
;
1640 return type
->declaration
->id
;
1643 const char *bt_ctf_field_type_get_alias_name(
1644 struct bt_ctf_field_type
*type
)
1646 const char *name
= NULL
;
1648 if (!type
|| !type
->alias_name
) {
1652 name
= type
->alias_name
->str
;
1657 void bt_ctf_field_type_get(struct bt_ctf_field_type
*type
)
1663 bt_ctf_ref_get(&type
->ref_count
);
1666 void bt_ctf_field_type_put(struct bt_ctf_field_type
*type
)
1672 bt_ctf_ref_put(&type
->ref_count
, bt_ctf_field_type_destroy
);
1676 void bt_ctf_field_type_freeze(struct bt_ctf_field_type
*type
)
1686 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_signed(
1687 struct bt_ctf_field_type_variant
*variant
,
1690 struct bt_ctf_field_type
*type
= NULL
;
1691 GQuark field_name_quark
;
1693 struct structure_field
*field_entry
;
1694 struct range_overlap_query query
= {
1695 .range_start
._signed
= tag_value
,
1696 .range_end
._signed
= tag_value
,
1697 .mapping_name
= 0, .overlaps
= 0};
1699 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
1701 if (!query
.overlaps
) {
1705 field_name_quark
= query
.mapping_name
;
1706 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1707 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
1711 field_entry
= g_ptr_array_index(variant
->fields
, (size_t) index
);
1712 type
= field_entry
->type
;
1718 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_unsigned(
1719 struct bt_ctf_field_type_variant
*variant
,
1722 struct bt_ctf_field_type
*type
= NULL
;
1723 GQuark field_name_quark
;
1725 struct structure_field
*field_entry
;
1726 struct range_overlap_query query
= {
1727 .range_start
._unsigned
= tag_value
,
1728 .range_end
._unsigned
= tag_value
,
1729 .mapping_name
= 0, .overlaps
= 0};
1731 g_ptr_array_foreach(variant
->tag
->entries
,
1732 check_ranges_overlap_unsigned
,
1734 if (!query
.overlaps
) {
1738 field_name_quark
= query
.mapping_name
;
1739 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1740 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
1744 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
1745 type
= field_entry
->type
;
1751 int bt_ctf_field_type_serialize(struct bt_ctf_field_type
*type
,
1752 struct metadata_context
*context
)
1756 if (!type
|| !context
) {
1761 ret
= type
->serialize(type
, context
);
1767 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*ref
)
1769 struct bt_ctf_field_type_integer
*integer
;
1775 integer
= container_of(
1776 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1777 struct bt_ctf_field_type_integer
, parent
);
1782 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*ref
)
1784 struct bt_ctf_field_type_enumeration
*enumeration
;
1790 enumeration
= container_of(
1791 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1792 struct bt_ctf_field_type_enumeration
, parent
);
1793 g_ptr_array_free(enumeration
->entries
, TRUE
);
1794 bt_ctf_field_type_put(enumeration
->container
);
1795 g_free(enumeration
);
1799 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*ref
)
1801 struct bt_ctf_field_type_floating_point
*floating_point
;
1807 floating_point
= container_of(
1808 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1809 struct bt_ctf_field_type_floating_point
, parent
);
1810 g_free(floating_point
);
1814 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*ref
)
1816 struct bt_ctf_field_type_structure
*structure
;
1822 structure
= container_of(
1823 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1824 struct bt_ctf_field_type_structure
, parent
);
1825 g_ptr_array_free(structure
->fields
, TRUE
);
1826 g_hash_table_destroy(structure
->field_name_to_index
);
1831 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*ref
)
1833 struct bt_ctf_field_type_variant
*variant
;
1839 variant
= container_of(
1840 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1841 struct bt_ctf_field_type_variant
, parent
);
1842 g_ptr_array_free(variant
->fields
, TRUE
);
1843 g_hash_table_destroy(variant
->field_name_to_index
);
1844 g_string_free(variant
->tag_name
, TRUE
);
1845 bt_ctf_field_type_put(&variant
->tag
->parent
);
1850 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*ref
)
1852 struct bt_ctf_field_type_array
*array
;
1858 array
= container_of(
1859 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1860 struct bt_ctf_field_type_array
, parent
);
1861 bt_ctf_field_type_put(array
->element_type
);
1866 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*ref
)
1868 struct bt_ctf_field_type_sequence
*sequence
;
1874 sequence
= container_of(
1875 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1876 struct bt_ctf_field_type_sequence
, parent
);
1877 bt_ctf_field_type_put(sequence
->element_type
);
1878 g_string_free(sequence
->length_field_name
, TRUE
);
1883 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*ref
)
1885 struct bt_ctf_field_type_string
*string
;
1891 string
= container_of(
1892 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1893 struct bt_ctf_field_type_string
, parent
);
1898 void generic_field_type_freeze(struct bt_ctf_field_type
*type
)
1904 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*type
)
1906 struct bt_ctf_field_type_enumeration
*enumeration_type
= container_of(
1907 type
, struct bt_ctf_field_type_enumeration
, parent
);
1909 generic_field_type_freeze(type
);
1910 bt_ctf_field_type_freeze(enumeration_type
->container
);
1914 void freeze_structure_field(struct structure_field
*field
)
1916 bt_ctf_field_type_freeze(field
->type
);
1920 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*type
)
1922 struct bt_ctf_field_type_structure
*structure_type
= container_of(
1923 type
, struct bt_ctf_field_type_structure
, parent
);
1925 generic_field_type_freeze(type
);
1926 g_ptr_array_foreach(structure_type
->fields
, (GFunc
)freeze_structure_field
,
1931 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*type
)
1933 struct bt_ctf_field_type_variant
*variant_type
= container_of(
1934 type
, struct bt_ctf_field_type_variant
, parent
);
1936 generic_field_type_freeze(type
);
1937 g_ptr_array_foreach(variant_type
->fields
, (GFunc
)freeze_structure_field
,
1942 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*type
)
1944 struct bt_ctf_field_type_array
*array_type
= container_of(
1945 type
, struct bt_ctf_field_type_array
, parent
);
1947 generic_field_type_freeze(type
);
1948 bt_ctf_field_type_freeze(array_type
->element_type
);
1952 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*type
)
1954 struct bt_ctf_field_type_sequence
*sequence_type
= container_of(
1955 type
, struct bt_ctf_field_type_sequence
, parent
);
1957 generic_field_type_freeze(type
);
1958 bt_ctf_field_type_freeze(sequence_type
->element_type
);
1962 const char *get_encoding_string(enum ctf_string_encoding encoding
)
1964 const char *encoding_string
;
1967 case CTF_STRING_NONE
:
1968 encoding_string
= "none";
1970 case CTF_STRING_ASCII
:
1971 encoding_string
= "ASCII";
1973 case CTF_STRING_UTF8
:
1974 encoding_string
= "UTF8";
1977 encoding_string
= "unknown";
1981 return encoding_string
;
1985 const char *get_integer_base_string(enum bt_ctf_integer_base base
)
1987 const char *base_string
;
1990 case BT_CTF_INTEGER_BASE_DECIMAL
:
1991 base_string
= "decimal";
1993 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
1994 base_string
= "hexadecimal";
1996 case BT_CTF_INTEGER_BASE_OCTAL
:
1997 base_string
= "octal";
1999 case BT_CTF_INTEGER_BASE_BINARY
:
2000 base_string
= "binary";
2003 base_string
= "unknown";
2011 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*type
,
2012 struct metadata_context
*context
)
2014 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
2015 struct bt_ctf_field_type_integer
, parent
);
2017 g_string_append_printf(context
->string
,
2018 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
2019 integer
->declaration
.len
, type
->declaration
->alignment
,
2020 (integer
->declaration
.signedness
? "true" : "false"),
2021 get_encoding_string(integer
->declaration
.encoding
),
2022 get_integer_base_string(integer
->declaration
.base
),
2023 get_byte_order_string(integer
->declaration
.byte_order
));
2028 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*type
,
2029 struct metadata_context
*context
)
2033 struct bt_ctf_field_type_enumeration
*enumeration
= container_of(type
,
2034 struct bt_ctf_field_type_enumeration
, parent
);
2035 struct bt_ctf_field_type
*container_type
;
2036 int container_signed
;
2038 ret
= bt_ctf_field_type_validate(type
);
2043 container_type
= bt_ctf_field_type_enumeration_get_container_type(type
);
2044 if (!container_type
) {
2049 container_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
2050 if (container_signed
< 0) {
2051 ret
= container_signed
;
2052 goto error_put_container_type
;
2055 g_string_append(context
->string
, "enum : ");
2056 ret
= bt_ctf_field_type_serialize(enumeration
->container
, context
);
2058 goto error_put_container_type
;
2061 g_string_append(context
->string
, " { ");
2062 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
2063 struct enumeration_mapping
*mapping
=
2064 enumeration
->entries
->pdata
[entry
];
2066 if (container_signed
) {
2067 if (mapping
->range_start
._signed
==
2068 mapping
->range_end
._signed
) {
2069 g_string_append_printf(context
->string
,
2070 "\"%s\" = %" PRId64
,
2071 g_quark_to_string(mapping
->string
),
2072 mapping
->range_start
._signed
);
2074 g_string_append_printf(context
->string
,
2075 "\"%s\" = %" PRId64
" ... %" PRId64
,
2076 g_quark_to_string(mapping
->string
),
2077 mapping
->range_start
._signed
,
2078 mapping
->range_end
._signed
);
2081 if (mapping
->range_start
._unsigned
==
2082 mapping
->range_end
._unsigned
) {
2083 g_string_append_printf(context
->string
,
2084 "\"%s\" = %" PRIu64
,
2085 g_quark_to_string(mapping
->string
),
2086 mapping
->range_start
._unsigned
);
2088 g_string_append_printf(context
->string
,
2089 "\"%s\" = %" PRIu64
" ... %" PRIu64
,
2090 g_quark_to_string(mapping
->string
),
2091 mapping
->range_start
._unsigned
,
2092 mapping
->range_end
._unsigned
);
2096 g_string_append(context
->string
,
2097 ((entry
!= (enumeration
->entries
->len
- 1)) ?
2101 if (context
->field_name
->len
) {
2102 g_string_append_printf(context
->string
, " %s",
2103 context
->field_name
->str
);
2104 g_string_assign(context
->field_name
, "");
2106 error_put_container_type
:
2107 bt_ctf_field_type_put(container_type
);
2113 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type
*type
,
2114 struct metadata_context
*context
)
2116 struct bt_ctf_field_type_floating_point
*floating_point
= container_of(
2117 type
, struct bt_ctf_field_type_floating_point
, parent
);
2119 g_string_append_printf(context
->string
,
2120 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2121 floating_point
->declaration
.exp
->len
,
2122 floating_point
->declaration
.mantissa
->len
+ 1,
2123 get_byte_order_string(floating_point
->declaration
.byte_order
),
2124 type
->declaration
->alignment
);
2129 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*type
,
2130 struct metadata_context
*context
)
2133 unsigned int indent
;
2135 struct bt_ctf_field_type_structure
*structure
= container_of(type
,
2136 struct bt_ctf_field_type_structure
, parent
);
2137 GString
*structure_field_name
= context
->field_name
;
2139 context
->field_name
= g_string_new("");
2141 context
->current_indentation_level
++;
2142 g_string_append(context
->string
, "struct {\n");
2144 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2145 struct structure_field
*field
;
2147 for (indent
= 0; indent
< context
->current_indentation_level
;
2149 g_string_append_c(context
->string
, '\t');
2152 field
= structure
->fields
->pdata
[i
];
2153 g_string_assign(context
->field_name
,
2154 g_quark_to_string(field
->name
));
2155 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
2160 if (context
->field_name
->len
) {
2161 g_string_append_printf(context
->string
, " %s",
2162 context
->field_name
->str
);
2164 g_string_append(context
->string
, ";\n");
2167 context
->current_indentation_level
--;
2168 for (indent
= 0; indent
< context
->current_indentation_level
;
2170 g_string_append_c(context
->string
, '\t');
2173 g_string_append_printf(context
->string
, "} align(%zu)",
2174 type
->declaration
->alignment
);
2176 g_string_free(context
->field_name
, TRUE
);
2177 context
->field_name
= structure_field_name
;
2182 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*type
,
2183 struct metadata_context
*context
)
2186 unsigned int indent
;
2188 struct bt_ctf_field_type_variant
*variant
= container_of(
2189 type
, struct bt_ctf_field_type_variant
, parent
);
2190 GString
*variant_field_name
= context
->field_name
;
2192 context
->field_name
= g_string_new("");
2193 g_string_append_printf(context
->string
,
2194 "variant <%s> {\n", variant
->tag_name
->str
);
2195 context
->current_indentation_level
++;
2196 for (i
= 0; i
< variant
->fields
->len
; i
++) {
2197 struct structure_field
*field
= variant
->fields
->pdata
[i
];
2199 g_string_assign(context
->field_name
,
2200 g_quark_to_string(field
->name
));
2201 for (indent
= 0; indent
< context
->current_indentation_level
;
2203 g_string_append_c(context
->string
, '\t');
2206 g_string_assign(context
->field_name
,
2207 g_quark_to_string(field
->name
));
2208 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
2213 if (context
->field_name
->len
) {
2214 g_string_append_printf(context
->string
, " %s;",
2215 context
->field_name
->str
);
2218 g_string_append_c(context
->string
, '\n');
2221 context
->current_indentation_level
--;
2222 for (indent
= 0; indent
< context
->current_indentation_level
;
2224 g_string_append_c(context
->string
, '\t');
2227 g_string_append(context
->string
, "}");
2229 g_string_free(context
->field_name
, TRUE
);
2230 context
->field_name
= variant_field_name
;
2235 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*type
,
2236 struct metadata_context
*context
)
2239 struct bt_ctf_field_type_array
*array
= container_of(type
,
2240 struct bt_ctf_field_type_array
, parent
);
2242 ret
= bt_ctf_field_type_serialize(array
->element_type
, context
);
2247 if (context
->field_name
->len
) {
2248 g_string_append_printf(context
->string
, " %s[%u]",
2249 context
->field_name
->str
, array
->length
);
2250 g_string_assign(context
->field_name
, "");
2252 g_string_append_printf(context
->string
, "[%u]", array
->length
);
2259 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*type
,
2260 struct metadata_context
*context
)
2263 struct bt_ctf_field_type_sequence
*sequence
= container_of(
2264 type
, struct bt_ctf_field_type_sequence
, parent
);
2266 ret
= bt_ctf_field_type_serialize(sequence
->element_type
, context
);
2271 if (context
->field_name
->len
) {
2272 g_string_append_printf(context
->string
, " %s[%s]",
2273 context
->field_name
->str
,
2274 sequence
->length_field_name
->str
);
2275 g_string_assign(context
->field_name
, "");
2277 g_string_append_printf(context
->string
, "[%s]",
2278 sequence
->length_field_name
->str
);
2285 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*type
,
2286 struct metadata_context
*context
)
2288 struct bt_ctf_field_type_string
*string
= container_of(
2289 type
, struct bt_ctf_field_type_string
, parent
);
2291 g_string_append_printf(context
->string
,
2292 "string { encoding = %s; }",
2293 get_encoding_string(string
->declaration
.encoding
));
2298 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*type
,
2301 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
2302 struct bt_ctf_field_type_integer
, parent
);
2304 integer_type
->declaration
.byte_order
= byte_order
;
2308 void bt_ctf_field_type_floating_point_set_byte_order(
2309 struct bt_ctf_field_type
*type
, int byte_order
)
2311 struct bt_ctf_field_type_floating_point
*floating_point_type
=
2312 container_of(type
, struct bt_ctf_field_type_floating_point
,
2315 floating_point_type
->declaration
.byte_order
= byte_order
;
2316 floating_point_type
->sign
.byte_order
= byte_order
;
2317 floating_point_type
->mantissa
.byte_order
= byte_order
;
2318 floating_point_type
->exp
.byte_order
= byte_order
;