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
*,
153 int byte_order
, int set_native
);
155 void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type
*,
156 int byte_order
, int set_native
);
158 void bt_ctf_field_type_floating_point_set_byte_order(
159 struct bt_ctf_field_type
*, int byte_order
, int set_native
);
161 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*,
162 int byte_order
, int set_native
);
164 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*,
165 int byte_order
, int set_native
);
167 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*,
168 int byte_order
, int set_native
);
170 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*,
171 int byte_order
, int set_native
);
173 /* The set_native flag only set the byte order if it is set to native */
175 void (* const set_byte_order_funcs
[])(struct bt_ctf_field_type
*,
176 int byte_order
, int set_native
) = {
177 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_set_byte_order
,
179 bt_ctf_field_type_enumeration_set_byte_order
,
181 bt_ctf_field_type_floating_point_set_byte_order
,
183 bt_ctf_field_type_structure_set_byte_order
,
184 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_set_byte_order
,
185 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_set_byte_order
,
186 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_set_byte_order
,
187 [CTF_TYPE_STRING
] = NULL
,
191 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
197 void destroy_structure_field(struct structure_field
*field
)
200 bt_ctf_field_type_put(field
->type
);
207 void check_ranges_overlap(gpointer element
, gpointer query
)
209 struct enumeration_mapping
*mapping
= element
;
210 struct range_overlap_query
*overlap_query
= query
;
212 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
213 && overlap_query
->range_start
._signed
<=
214 mapping
->range_end
._signed
) {
215 overlap_query
->overlaps
= 1;
216 overlap_query
->mapping_name
= mapping
->string
;
219 overlap_query
->overlaps
|=
220 mapping
->string
== overlap_query
->mapping_name
;
224 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
226 struct enumeration_mapping
*mapping
= element
;
227 struct range_overlap_query
*overlap_query
= query
;
229 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
230 && overlap_query
->range_start
._unsigned
<=
231 mapping
->range_end
._unsigned
) {
232 overlap_query
->overlaps
= 1;
233 overlap_query
->mapping_name
= mapping
->string
;
236 overlap_query
->overlaps
|=
237 mapping
->string
== overlap_query
->mapping_name
;
241 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
242 struct enumeration_mapping
**b
)
244 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
248 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
249 struct enumeration_mapping
**b
)
251 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
255 void bt_ctf_field_type_init(struct bt_ctf_field_type
*type
)
257 enum ctf_type_id type_id
= type
->declaration
->id
;
260 assert(type
&& (type_id
> CTF_TYPE_UNKNOWN
) &&
261 (type_id
< NR_CTF_TYPES
));
263 bt_ctf_ref_init(&type
->ref_count
);
264 type
->freeze
= type_freeze_funcs
[type_id
];
265 type
->serialize
= type_serialize_funcs
[type_id
];
266 ret
= bt_ctf_field_type_set_byte_order(type
, BT_CTF_BYTE_ORDER_NATIVE
);
268 type
->declaration
->alignment
= 1;
272 int add_structure_field(GPtrArray
*fields
,
273 GHashTable
*field_name_to_index
,
274 struct bt_ctf_field_type
*field_type
,
275 const char *field_name
)
278 GQuark name_quark
= g_quark_from_string(field_name
);
279 struct structure_field
*field
;
281 /* Make sure structure does not contain a field of the same name */
282 if (g_hash_table_lookup_extended(field_name_to_index
,
283 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
288 field
= g_new0(struct structure_field
, 1);
294 bt_ctf_field_type_get(field_type
);
295 field
->name
= name_quark
;
296 field
->type
= field_type
;
297 g_hash_table_insert(field_name_to_index
,
298 (gpointer
) (unsigned long) name_quark
,
299 (gpointer
) (unsigned long) fields
->len
);
300 g_ptr_array_add(fields
, field
);
301 bt_ctf_field_type_freeze(field_type
);
307 void bt_ctf_field_type_destroy(struct bt_ctf_ref
*ref
)
309 struct bt_ctf_field_type
*type
;
310 enum ctf_type_id type_id
;
316 type
= container_of(ref
, struct bt_ctf_field_type
, ref_count
);
317 type_id
= type
->declaration
->id
;
318 if (type_id
<= CTF_TYPE_UNKNOWN
||
319 type_id
>= NR_CTF_TYPES
) {
323 if (type
->alias_name
) {
324 g_string_free(type
->alias_name
, TRUE
);
326 type_destroy_funcs
[type_id
](ref
);
330 int bt_ctf_field_type_validate(struct bt_ctf_field_type
*type
)
339 switch (type
->declaration
->id
) {
342 struct bt_ctf_field_type_enumeration
*enumeration
=
343 container_of(type
, struct bt_ctf_field_type_enumeration
,
346 /* Ensure enum has entries */
347 ret
= enumeration
->entries
->len
? 0 : -1;
357 struct bt_ctf_field_type
*bt_ctf_field_type_integer_create(unsigned int size
)
359 struct bt_ctf_field_type_integer
*integer
=
360 g_new0(struct bt_ctf_field_type_integer
, 1);
362 if (!integer
|| size
== 0 || size
> 64) {
366 integer
->parent
.declaration
= &integer
->declaration
.p
;
367 integer
->parent
.declaration
->id
= CTF_TYPE_INTEGER
;
368 integer
->declaration
.len
= size
;
369 integer
->declaration
.base
= BT_CTF_INTEGER_BASE_DECIMAL
;
370 integer
->declaration
.encoding
= CTF_STRING_NONE
;
371 bt_ctf_field_type_init(&integer
->parent
);
372 return &integer
->parent
;
375 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type
*type
)
378 struct bt_ctf_field_type_integer
*integer
;
380 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
385 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
386 ret
= (int) integer
->declaration
.len
;
391 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type
*type
)
394 struct bt_ctf_field_type_integer
*integer
;
396 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
401 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
402 ret
= integer
->declaration
.signedness
;
407 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type
*type
,
411 struct bt_ctf_field_type_integer
*integer
;
413 if (!type
|| type
->frozen
||
414 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
419 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
420 integer
->declaration
.signedness
= !!is_signed
;
425 enum bt_ctf_integer_base
bt_ctf_field_type_integer_get_base(
426 struct bt_ctf_field_type
*type
)
428 enum bt_ctf_integer_base ret
= BT_CTF_INTEGER_BASE_UNKNOWN
;
429 struct bt_ctf_field_type_integer
*integer
;
431 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
435 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
436 ret
= integer
->declaration
.base
;
441 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type
*type
,
442 enum bt_ctf_integer_base base
)
446 if (!type
|| type
->frozen
||
447 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
453 case BT_CTF_INTEGER_BASE_BINARY
:
454 case BT_CTF_INTEGER_BASE_OCTAL
:
455 case BT_CTF_INTEGER_BASE_DECIMAL
:
456 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
458 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
459 struct bt_ctf_field_type_integer
, parent
);
460 integer
->declaration
.base
= base
;
470 enum ctf_string_encoding
bt_ctf_field_type_integer_get_encoding(
471 struct bt_ctf_field_type
*type
)
473 enum ctf_string_encoding ret
= CTF_STRING_UNKNOWN
;
474 struct bt_ctf_field_type_integer
*integer
;
476 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
480 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
481 ret
= integer
->declaration
.encoding
;
486 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type
*type
,
487 enum ctf_string_encoding encoding
)
490 struct bt_ctf_field_type_integer
*integer
;
492 if (!type
|| type
->frozen
||
493 (type
->declaration
->id
!= CTF_TYPE_INTEGER
) ||
494 (encoding
< CTF_STRING_NONE
) ||
495 (encoding
>= CTF_STRING_UNKNOWN
)) {
500 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
501 integer
->declaration
.encoding
= encoding
;
506 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_create(
507 struct bt_ctf_field_type
*integer_container_type
)
509 struct bt_ctf_field_type_enumeration
*enumeration
= NULL
;
511 if (!integer_container_type
) {
515 if (integer_container_type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
519 enumeration
= g_new0(struct bt_ctf_field_type_enumeration
, 1);
524 enumeration
->parent
.declaration
= &enumeration
->declaration
.p
;
525 enumeration
->parent
.declaration
->id
= CTF_TYPE_ENUM
;
526 bt_ctf_field_type_get(integer_container_type
);
527 enumeration
->container
= integer_container_type
;
528 enumeration
->entries
= g_ptr_array_new_with_free_func(
529 (GDestroyNotify
)destroy_enumeration_mapping
);
530 bt_ctf_field_type_init(&enumeration
->parent
);
531 return &enumeration
->parent
;
537 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_get_container_type(
538 struct bt_ctf_field_type
*type
)
540 struct bt_ctf_field_type
*container_type
= NULL
;
541 struct bt_ctf_field_type_enumeration
*enumeration_type
;
547 if (type
->declaration
->id
!= CTF_TYPE_ENUM
) {
551 enumeration_type
= container_of(type
,
552 struct bt_ctf_field_type_enumeration
, parent
);
553 container_type
= enumeration_type
->container
;
554 bt_ctf_field_type_get(container_type
);
556 return container_type
;
559 int bt_ctf_field_type_enumeration_add_mapping(
560 struct bt_ctf_field_type
*type
, const char *string
,
561 int64_t range_start
, int64_t range_end
)
565 struct enumeration_mapping
*mapping
;
566 struct bt_ctf_field_type_enumeration
*enumeration
;
567 struct range_overlap_query query
;
568 char *escaped_string
;
570 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
572 (range_end
< range_start
)) {
577 if (!string
|| strlen(string
) == 0) {
582 escaped_string
= g_strescape(string
, NULL
);
583 if (!escaped_string
) {
588 mapping_name
= g_quark_from_string(escaped_string
);
589 query
= (struct range_overlap_query
) {
590 .range_start
._signed
= range_start
,
591 .range_end
._signed
= range_end
,
592 .mapping_name
= mapping_name
,
594 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
597 /* Check that the range does not overlap with one already present */
598 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap
, &query
);
599 if (query
.overlaps
) {
604 mapping
= g_new(struct enumeration_mapping
, 1);
610 *mapping
= (struct enumeration_mapping
) {
611 .range_start
._signed
= range_start
,
612 .range_end
._signed
= range_end
, .string
= mapping_name
};
613 g_ptr_array_add(enumeration
->entries
, mapping
);
614 g_ptr_array_sort(enumeration
->entries
,
615 (GCompareFunc
)compare_enumeration_mappings_signed
);
617 free(escaped_string
);
622 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
623 struct bt_ctf_field_type
*type
, const char *string
,
624 uint64_t range_start
, uint64_t range_end
)
628 struct enumeration_mapping
*mapping
;
629 struct bt_ctf_field_type_enumeration
*enumeration
;
630 struct range_overlap_query query
;
631 char *escaped_string
;
633 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
635 (range_end
< range_start
)) {
640 if (!string
|| strlen(string
) == 0) {
645 escaped_string
= g_strescape(string
, NULL
);
646 if (!escaped_string
) {
651 mapping_name
= g_quark_from_string(escaped_string
);
652 query
= (struct range_overlap_query
) {
653 .range_start
._unsigned
= range_start
,
654 .range_end
._unsigned
= range_end
,
655 .mapping_name
= mapping_name
,
657 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
660 /* Check that the range does not overlap with one already present */
661 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap_unsigned
,
663 if (query
.overlaps
) {
668 mapping
= g_new(struct enumeration_mapping
, 1);
674 *mapping
= (struct enumeration_mapping
) {
675 .range_start
._unsigned
= range_start
,
676 .range_end
._unsigned
= range_end
, .string
= mapping_name
};
677 g_ptr_array_add(enumeration
->entries
, mapping
);
678 g_ptr_array_sort(enumeration
->entries
,
679 (GCompareFunc
)compare_enumeration_mappings_unsigned
);
681 free(escaped_string
);
686 const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
687 struct bt_ctf_field_type_enumeration
*enumeration_type
,
690 const char *name
= NULL
;
691 struct range_overlap_query query
=
692 (struct range_overlap_query
) {
693 .range_start
._unsigned
= value
,
694 .range_end
._unsigned
= value
,
697 g_ptr_array_foreach(enumeration_type
->entries
,
698 check_ranges_overlap_unsigned
,
700 if (!query
.overlaps
) {
704 name
= g_quark_to_string(query
.mapping_name
);
709 const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
710 struct bt_ctf_field_type_enumeration
*enumeration_type
,
713 const char *name
= NULL
;
714 struct range_overlap_query query
=
715 (struct range_overlap_query
) {
716 .range_start
._signed
= value
,
717 .range_end
._signed
= value
,
720 g_ptr_array_foreach(enumeration_type
->entries
, check_ranges_overlap
,
722 if (!query
.overlaps
) {
726 name
= g_quark_to_string(query
.mapping_name
);
731 int bt_ctf_field_type_enumeration_get_mapping_count(
732 struct bt_ctf_field_type
*type
)
735 struct bt_ctf_field_type_enumeration
*enumeration
;
737 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
742 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
744 ret
= (int) enumeration
->entries
->len
;
750 struct enumeration_mapping
*get_enumeration_mapping(
751 struct bt_ctf_field_type
*type
, int index
)
753 struct enumeration_mapping
*mapping
= NULL
;
754 struct bt_ctf_field_type_enumeration
*enumeration
;
756 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
758 if (index
>= enumeration
->entries
->len
) {
762 mapping
= g_ptr_array_index(enumeration
->entries
, index
);
767 int bt_ctf_field_type_enumeration_get_mapping(
768 struct bt_ctf_field_type
*type
, int index
,
769 const char **string
, int64_t *range_start
, int64_t *range_end
)
771 struct enumeration_mapping
*mapping
;
774 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
775 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
780 mapping
= get_enumeration_mapping(type
, index
);
786 *string
= g_quark_to_string(mapping
->string
);
787 *range_start
= mapping
->range_start
._signed
;
788 *range_end
= mapping
->range_end
._signed
;
793 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
794 struct bt_ctf_field_type
*type
, int index
,
795 const char **string
, uint64_t *range_start
, uint64_t *range_end
)
797 struct enumeration_mapping
*mapping
;
800 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
801 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
806 mapping
= get_enumeration_mapping(type
, index
);
812 *string
= g_quark_to_string(mapping
->string
);
813 *range_start
= mapping
->range_start
._unsigned
;
814 *range_end
= mapping
->range_end
._unsigned
;
819 int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
820 struct bt_ctf_field_type
*type
, const char *name
)
823 struct bt_ctf_field_type_enumeration
*enumeration
;
826 if (!type
|| !name
||
827 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
832 name_quark
= g_quark_try_string(name
);
838 enumeration
= container_of(type
,
839 struct bt_ctf_field_type_enumeration
, parent
);
840 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
841 struct enumeration_mapping
*mapping
=
842 get_enumeration_mapping(type
, i
);
844 if (mapping
->string
== name_quark
) {
855 int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
856 struct bt_ctf_field_type
*type
, int64_t value
)
858 struct bt_ctf_field_type_enumeration
*enumeration
;
861 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
866 enumeration
= container_of(type
,
867 struct bt_ctf_field_type_enumeration
, parent
);
868 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
869 struct enumeration_mapping
*mapping
=
870 get_enumeration_mapping(type
, i
);
872 if (value
>= mapping
->range_start
._signed
&&
873 value
<= mapping
->range_end
._signed
) {
884 int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
885 struct bt_ctf_field_type
*type
, uint64_t value
)
887 struct bt_ctf_field_type_enumeration
*enumeration
;
890 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
895 enumeration
= container_of(type
,
896 struct bt_ctf_field_type_enumeration
, parent
);
897 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
898 struct enumeration_mapping
*mapping
=
899 get_enumeration_mapping(type
, i
);
901 if (value
>= mapping
->range_start
._unsigned
&&
902 value
<= mapping
->range_end
._unsigned
) {
913 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_create(void)
915 struct bt_ctf_field_type_floating_point
*floating_point
=
916 g_new0(struct bt_ctf_field_type_floating_point
, 1);
918 if (!floating_point
) {
922 floating_point
->declaration
.sign
= &floating_point
->sign
;
923 floating_point
->declaration
.mantissa
= &floating_point
->mantissa
;
924 floating_point
->declaration
.exp
= &floating_point
->exp
;
925 floating_point
->sign
.len
= 1;
926 floating_point
->parent
.declaration
= &floating_point
->declaration
.p
;
927 floating_point
->parent
.declaration
->id
= CTF_TYPE_FLOAT
;
928 floating_point
->declaration
.exp
->len
=
929 sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
930 floating_point
->declaration
.mantissa
->len
= FLT_MANT_DIG
- 1;
931 floating_point
->sign
.p
.alignment
= 1;
932 floating_point
->mantissa
.p
.alignment
= 1;
933 floating_point
->exp
.p
.alignment
= 1;
935 bt_ctf_field_type_init(&floating_point
->parent
);
937 return floating_point
? &floating_point
->parent
: NULL
;
940 int bt_ctf_field_type_floating_point_get_exponent_digits(
941 struct bt_ctf_field_type
*type
)
944 struct bt_ctf_field_type_floating_point
*floating_point
;
946 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
951 floating_point
= container_of(type
,
952 struct bt_ctf_field_type_floating_point
, parent
);
953 ret
= (int) floating_point
->declaration
.exp
->len
;
958 int bt_ctf_field_type_floating_point_set_exponent_digits(
959 struct bt_ctf_field_type
*type
,
960 unsigned int exponent_digits
)
963 struct bt_ctf_field_type_floating_point
*floating_point
;
965 if (!type
|| type
->frozen
||
966 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
971 floating_point
= container_of(type
,
972 struct bt_ctf_field_type_floating_point
, parent
);
973 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
974 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
976 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
981 floating_point
->declaration
.exp
->len
= exponent_digits
;
986 int bt_ctf_field_type_floating_point_get_mantissa_digits(
987 struct bt_ctf_field_type
*type
)
990 struct bt_ctf_field_type_floating_point
*floating_point
;
992 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
997 floating_point
= container_of(type
,
998 struct bt_ctf_field_type_floating_point
, parent
);
999 ret
= (int) floating_point
->mantissa
.len
+ 1;
1004 int bt_ctf_field_type_floating_point_set_mantissa_digits(
1005 struct bt_ctf_field_type
*type
,
1006 unsigned int mantissa_digits
)
1009 struct bt_ctf_field_type_floating_point
*floating_point
;
1011 if (!type
|| type
->frozen
||
1012 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
1017 floating_point
= container_of(type
,
1018 struct bt_ctf_field_type_floating_point
, parent
);
1020 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
1021 (mantissa_digits
!= DBL_MANT_DIG
) &&
1022 (mantissa_digits
!= LDBL_MANT_DIG
)) {
1027 floating_point
->declaration
.mantissa
->len
= mantissa_digits
- 1;
1032 struct bt_ctf_field_type
*bt_ctf_field_type_structure_create(void)
1034 struct bt_ctf_field_type_structure
*structure
=
1035 g_new0(struct bt_ctf_field_type_structure
, 1);
1041 structure
->parent
.declaration
= &structure
->declaration
.p
;
1042 structure
->parent
.declaration
->id
= CTF_TYPE_STRUCT
;
1043 structure
->fields
= g_ptr_array_new_with_free_func(
1044 (GDestroyNotify
)destroy_structure_field
);
1045 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1046 bt_ctf_field_type_init(&structure
->parent
);
1047 return &structure
->parent
;
1052 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type
*type
,
1053 struct bt_ctf_field_type
*field_type
,
1054 const char *field_name
)
1057 struct bt_ctf_field_type_structure
*structure
;
1059 if (!type
|| !field_type
|| type
->frozen
||
1060 bt_ctf_validate_identifier(field_name
) ||
1061 (type
->declaration
->id
!= CTF_TYPE_STRUCT
) ||
1062 bt_ctf_field_type_validate(field_type
)) {
1067 structure
= container_of(type
,
1068 struct bt_ctf_field_type_structure
, parent
);
1069 if (add_structure_field(structure
->fields
,
1070 structure
->field_name_to_index
, field_type
, field_name
)) {
1075 if (type
->declaration
->alignment
< field_type
->declaration
->alignment
) {
1076 type
->declaration
->alignment
=
1077 field_type
->declaration
->alignment
;
1083 int bt_ctf_field_type_structure_get_field_count(
1084 struct bt_ctf_field_type
*type
)
1087 struct bt_ctf_field_type_structure
*structure
;
1089 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_STRUCT
)) {
1094 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1096 ret
= (int) structure
->fields
->len
;
1101 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type
*type
,
1102 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1105 struct bt_ctf_field_type_structure
*structure
;
1106 struct structure_field
*field
;
1109 if (!type
|| index
< 0 || !field_name
|| !field_type
||
1110 (type
->declaration
->id
!= CTF_TYPE_STRUCT
)) {
1115 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1117 if (index
>= structure
->fields
->len
) {
1122 field
= g_ptr_array_index(structure
->fields
, index
);
1123 *field_type
= field
->type
;
1124 bt_ctf_field_type_get(field
->type
);
1125 *field_name
= g_quark_to_string(field
->name
);
1130 struct bt_ctf_field_type
*bt_ctf_field_type_structure_get_field_type_by_name(
1131 struct bt_ctf_field_type
*type
,
1136 struct structure_field
*field
;
1137 struct bt_ctf_field_type_structure
*structure
;
1138 struct bt_ctf_field_type
*field_type
= NULL
;
1140 if (!type
|| !name
) {
1144 name_quark
= g_quark_try_string(name
);
1149 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1151 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
1152 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1156 field
= structure
->fields
->pdata
[index
];
1157 field_type
= field
->type
;
1158 bt_ctf_field_type_get(field_type
);
1163 struct bt_ctf_field_type
*bt_ctf_field_type_variant_create(
1164 struct bt_ctf_field_type
*enum_tag
, const char *tag_name
)
1166 struct bt_ctf_field_type_variant
*variant
= NULL
;
1168 if (!enum_tag
|| bt_ctf_validate_identifier(tag_name
) ||
1169 (enum_tag
->declaration
->id
!= CTF_TYPE_ENUM
)) {
1173 variant
= g_new0(struct bt_ctf_field_type_variant
, 1);
1178 variant
->parent
.declaration
= &variant
->declaration
.p
;
1179 variant
->parent
.declaration
->id
= CTF_TYPE_VARIANT
;
1180 variant
->tag_name
= g_string_new(tag_name
);
1181 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1182 variant
->fields
= g_ptr_array_new_with_free_func(
1183 (GDestroyNotify
)destroy_structure_field
);
1184 bt_ctf_field_type_get(enum_tag
);
1185 variant
->tag
= container_of(enum_tag
,
1186 struct bt_ctf_field_type_enumeration
, parent
);
1187 bt_ctf_field_type_init(&variant
->parent
);
1188 return &variant
->parent
;
1193 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_tag_type(
1194 struct bt_ctf_field_type
*type
)
1196 struct bt_ctf_field_type_variant
*variant
;
1197 struct bt_ctf_field_type
*tag_type
= NULL
;
1199 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1203 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1204 tag_type
= &variant
->tag
->parent
;
1205 bt_ctf_field_type_get(tag_type
);
1210 const char *bt_ctf_field_type_variant_get_tag_name(
1211 struct bt_ctf_field_type
*type
)
1213 struct bt_ctf_field_type_variant
*variant
;
1214 const char *tag_name
= NULL
;
1216 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1220 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1221 tag_name
= variant
->tag_name
->str
;
1226 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type
*type
,
1227 struct bt_ctf_field_type
*field_type
,
1228 const char *field_name
)
1233 struct bt_ctf_field_type_variant
*variant
;
1234 GQuark field_name_quark
= g_quark_from_string(field_name
);
1236 if (!type
|| !field_type
|| type
->frozen
||
1237 bt_ctf_validate_identifier(field_name
) ||
1238 (type
->declaration
->id
!= CTF_TYPE_VARIANT
) ||
1239 bt_ctf_field_type_validate(field_type
)) {
1244 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1245 /* Make sure this name is present in the enum tag */
1246 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
1247 struct enumeration_mapping
*mapping
=
1248 g_ptr_array_index(variant
->tag
->entries
, i
);
1250 if (mapping
->string
== field_name_quark
) {
1256 if (!name_found
|| add_structure_field(variant
->fields
,
1257 variant
->field_name_to_index
, field_type
, field_name
)) {
1265 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_by_name(
1266 struct bt_ctf_field_type
*type
,
1267 const char *field_name
)
1271 struct structure_field
*field
;
1272 struct bt_ctf_field_type_variant
*variant
;
1273 struct bt_ctf_field_type
*field_type
= NULL
;
1275 if (!type
|| !field_name
) {
1279 name_quark
= g_quark_try_string(field_name
);
1284 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1285 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1286 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1290 field
= g_ptr_array_index(variant
->fields
, index
);
1291 field_type
= field
->type
;
1292 bt_ctf_field_type_get(field_type
);
1297 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_from_tag(
1298 struct bt_ctf_field_type
*type
,
1299 struct bt_ctf_field
*tag
)
1301 const char *enum_value
;
1302 struct bt_ctf_field_type
*field_type
= NULL
;
1304 if (!type
|| !tag
|| type
->declaration
->id
!= CTF_TYPE_VARIANT
) {
1308 enum_value
= bt_ctf_field_enumeration_get_mapping_name(tag
);
1313 /* Already increments field_type's reference count */
1314 field_type
= bt_ctf_field_type_variant_get_field_type_by_name(
1320 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type
*type
)
1323 struct bt_ctf_field_type_variant
*variant
;
1325 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1330 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1332 ret
= (int) variant
->fields
->len
;
1338 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type
*type
,
1339 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1342 struct bt_ctf_field_type_variant
*variant
;
1343 struct structure_field
*field
;
1346 if (!type
|| index
< 0 || !field_name
|| !field_type
||
1347 (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1352 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1354 if (index
>= variant
->fields
->len
) {
1359 field
= g_ptr_array_index(variant
->fields
, index
);
1360 *field_type
= field
->type
;
1361 bt_ctf_field_type_get(field
->type
);
1362 *field_name
= g_quark_to_string(field
->name
);
1367 struct bt_ctf_field_type
*bt_ctf_field_type_array_create(
1368 struct bt_ctf_field_type
*element_type
,
1369 unsigned int length
)
1371 struct bt_ctf_field_type_array
*array
= NULL
;
1373 if (!element_type
|| length
== 0 ||
1374 bt_ctf_field_type_validate(element_type
)) {
1378 array
= g_new0(struct bt_ctf_field_type_array
, 1);
1383 array
->parent
.declaration
= &array
->declaration
.p
;
1384 array
->parent
.declaration
->id
= CTF_TYPE_ARRAY
;
1386 bt_ctf_field_type_get(element_type
);
1387 array
->element_type
= element_type
;
1388 array
->length
= length
;
1389 bt_ctf_field_type_init(&array
->parent
);
1390 array
->parent
.declaration
->alignment
=
1391 element_type
->declaration
->alignment
;
1392 return &array
->parent
;
1397 struct bt_ctf_field_type
*bt_ctf_field_type_array_get_element_type(
1398 struct bt_ctf_field_type
*type
)
1400 struct bt_ctf_field_type
*ret
= NULL
;
1401 struct bt_ctf_field_type_array
*array
;
1403 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ARRAY
)) {
1407 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1408 ret
= array
->element_type
;
1409 bt_ctf_field_type_get(ret
);
1414 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type
*type
)
1417 struct bt_ctf_field_type_array
*array
;
1419 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ARRAY
)) {
1424 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1425 ret
= (int64_t) array
->length
;
1430 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_create(
1431 struct bt_ctf_field_type
*element_type
,
1432 const char *length_field_name
)
1434 struct bt_ctf_field_type_sequence
*sequence
= NULL
;
1436 if (!element_type
|| bt_ctf_validate_identifier(length_field_name
) ||
1437 bt_ctf_field_type_validate(element_type
)) {
1441 sequence
= g_new0(struct bt_ctf_field_type_sequence
, 1);
1446 sequence
->parent
.declaration
= &sequence
->declaration
.p
;
1447 sequence
->parent
.declaration
->id
= CTF_TYPE_SEQUENCE
;
1448 bt_ctf_field_type_get(element_type
);
1449 sequence
->element_type
= element_type
;
1450 sequence
->length_field_name
= g_string_new(length_field_name
);
1451 bt_ctf_field_type_init(&sequence
->parent
);
1452 sequence
->parent
.declaration
->alignment
=
1453 element_type
->declaration
->alignment
;
1454 return &sequence
->parent
;
1459 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_get_element_type(
1460 struct bt_ctf_field_type
*type
)
1462 struct bt_ctf_field_type
*ret
= NULL
;
1463 struct bt_ctf_field_type_sequence
*sequence
;
1465 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_SEQUENCE
)) {
1469 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1471 ret
= sequence
->element_type
;
1472 bt_ctf_field_type_get(ret
);
1477 const char *bt_ctf_field_type_sequence_get_length_field_name(
1478 struct bt_ctf_field_type
*type
)
1480 const char *ret
= NULL
;
1481 struct bt_ctf_field_type_sequence
*sequence
;
1483 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_SEQUENCE
)) {
1487 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1489 ret
= sequence
->length_field_name
->str
;
1494 struct bt_ctf_field_type
*bt_ctf_field_type_string_create(void)
1496 struct bt_ctf_field_type_string
*string
=
1497 g_new0(struct bt_ctf_field_type_string
, 1);
1503 string
->parent
.declaration
= &string
->declaration
.p
;
1504 string
->parent
.declaration
->id
= CTF_TYPE_STRING
;
1505 bt_ctf_field_type_init(&string
->parent
);
1506 string
->declaration
.encoding
= CTF_STRING_UTF8
;
1507 string
->parent
.declaration
->alignment
= CHAR_BIT
;
1508 return &string
->parent
;
1511 enum ctf_string_encoding
bt_ctf_field_type_string_get_encoding(
1512 struct bt_ctf_field_type
*type
)
1514 struct bt_ctf_field_type_string
*string
;
1515 enum ctf_string_encoding ret
= CTF_STRING_UNKNOWN
;
1517 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_STRING
)) {
1521 string
= container_of(type
, struct bt_ctf_field_type_string
,
1523 ret
= string
->declaration
.encoding
;
1528 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type
*type
,
1529 enum ctf_string_encoding encoding
)
1532 struct bt_ctf_field_type_string
*string
;
1534 if (!type
|| type
->declaration
->id
!= CTF_TYPE_STRING
||
1535 (encoding
!= CTF_STRING_UTF8
&&
1536 encoding
!= CTF_STRING_ASCII
)) {
1541 string
= container_of(type
, struct bt_ctf_field_type_string
, parent
);
1542 string
->declaration
.encoding
= encoding
;
1547 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type
*type
)
1556 ret
= (int) type
->declaration
->alignment
;
1561 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type
*type
,
1562 unsigned int alignment
)
1566 /* Alignment must be bit-aligned (1) or byte aligned */
1567 if (!type
|| type
->frozen
|| (alignment
!= 1 && (alignment
& 0x7))) {
1572 if (type
->declaration
->id
== CTF_TYPE_STRING
&&
1573 alignment
!= CHAR_BIT
) {
1578 type
->declaration
->alignment
= alignment
;
1584 enum bt_ctf_byte_order
bt_ctf_field_type_get_byte_order(
1585 struct bt_ctf_field_type
*type
)
1587 enum bt_ctf_byte_order ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1588 int internal_byte_order
= -1;
1594 switch (type
->declaration
->id
) {
1595 case CTF_TYPE_INTEGER
:
1597 struct bt_ctf_field_type_integer
*integer
= container_of(
1598 type
, struct bt_ctf_field_type_integer
, parent
);
1599 internal_byte_order
= integer
->declaration
.byte_order
;
1602 case CTF_TYPE_FLOAT
:
1604 struct bt_ctf_field_type_floating_point
*floating_point
=
1606 struct bt_ctf_field_type_floating_point
,
1608 internal_byte_order
= floating_point
->declaration
.byte_order
;
1615 switch (internal_byte_order
) {
1617 ret
= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
;
1620 ret
= BT_CTF_BYTE_ORDER_BIG_ENDIAN
;
1623 ret
= BT_CTF_BYTE_ORDER_NATIVE
;
1626 ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1632 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type
*type
,
1633 enum bt_ctf_byte_order byte_order
)
1636 int internal_byte_order
;
1637 enum ctf_type_id type_id
;
1639 if (!type
|| type
->frozen
) {
1644 type_id
= type
->declaration
->id
;
1645 switch (byte_order
) {
1646 case BT_CTF_BYTE_ORDER_NATIVE
:
1647 /* Leave unset. Will be initialized by parent. */
1648 internal_byte_order
= 0;
1650 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
1651 internal_byte_order
= LITTLE_ENDIAN
;
1653 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
1654 case BT_CTF_BYTE_ORDER_NETWORK
:
1655 internal_byte_order
= BIG_ENDIAN
;
1662 if (set_byte_order_funcs
[type_id
]) {
1663 set_byte_order_funcs
[type_id
](type
, internal_byte_order
, 0);
1669 enum ctf_type_id
bt_ctf_field_type_get_type_id(
1670 struct bt_ctf_field_type
*type
)
1673 return CTF_TYPE_UNKNOWN
;
1676 return type
->declaration
->id
;
1679 const char *bt_ctf_field_type_get_alias_name(
1680 struct bt_ctf_field_type
*type
)
1682 const char *name
= NULL
;
1684 if (!type
|| !type
->alias_name
) {
1688 name
= type
->alias_name
->str
;
1693 void bt_ctf_field_type_get(struct bt_ctf_field_type
*type
)
1699 bt_ctf_ref_get(&type
->ref_count
);
1702 void bt_ctf_field_type_put(struct bt_ctf_field_type
*type
)
1708 bt_ctf_ref_put(&type
->ref_count
, bt_ctf_field_type_destroy
);
1712 void bt_ctf_field_type_freeze(struct bt_ctf_field_type
*type
)
1722 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_signed(
1723 struct bt_ctf_field_type_variant
*variant
,
1726 struct bt_ctf_field_type
*type
= NULL
;
1727 GQuark field_name_quark
;
1729 struct structure_field
*field_entry
;
1730 struct range_overlap_query query
= {
1731 .range_start
._signed
= tag_value
,
1732 .range_end
._signed
= tag_value
,
1733 .mapping_name
= 0, .overlaps
= 0};
1735 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
1737 if (!query
.overlaps
) {
1741 field_name_quark
= query
.mapping_name
;
1742 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1743 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
1747 field_entry
= g_ptr_array_index(variant
->fields
, (size_t) index
);
1748 type
= field_entry
->type
;
1754 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_unsigned(
1755 struct bt_ctf_field_type_variant
*variant
,
1758 struct bt_ctf_field_type
*type
= NULL
;
1759 GQuark field_name_quark
;
1761 struct structure_field
*field_entry
;
1762 struct range_overlap_query query
= {
1763 .range_start
._unsigned
= tag_value
,
1764 .range_end
._unsigned
= tag_value
,
1765 .mapping_name
= 0, .overlaps
= 0};
1767 g_ptr_array_foreach(variant
->tag
->entries
,
1768 check_ranges_overlap_unsigned
,
1770 if (!query
.overlaps
) {
1774 field_name_quark
= query
.mapping_name
;
1775 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1776 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
1780 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
1781 type
= field_entry
->type
;
1787 int bt_ctf_field_type_serialize(struct bt_ctf_field_type
*type
,
1788 struct metadata_context
*context
)
1792 if (!type
|| !context
) {
1797 ret
= type
->serialize(type
, context
);
1803 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type
*type
,
1810 assert(byte_order
== LITTLE_ENDIAN
|| byte_order
== BIG_ENDIAN
);
1811 if (set_byte_order_funcs
[type
->declaration
->id
]) {
1812 set_byte_order_funcs
[type
->declaration
->id
](type
,
1818 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*ref
)
1820 struct bt_ctf_field_type_integer
*integer
;
1826 integer
= container_of(
1827 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1828 struct bt_ctf_field_type_integer
, parent
);
1833 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*ref
)
1835 struct bt_ctf_field_type_enumeration
*enumeration
;
1841 enumeration
= container_of(
1842 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1843 struct bt_ctf_field_type_enumeration
, parent
);
1844 g_ptr_array_free(enumeration
->entries
, TRUE
);
1845 bt_ctf_field_type_put(enumeration
->container
);
1846 g_free(enumeration
);
1850 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*ref
)
1852 struct bt_ctf_field_type_floating_point
*floating_point
;
1858 floating_point
= container_of(
1859 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1860 struct bt_ctf_field_type_floating_point
, parent
);
1861 g_free(floating_point
);
1865 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*ref
)
1867 struct bt_ctf_field_type_structure
*structure
;
1873 structure
= container_of(
1874 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1875 struct bt_ctf_field_type_structure
, parent
);
1876 g_ptr_array_free(structure
->fields
, TRUE
);
1877 g_hash_table_destroy(structure
->field_name_to_index
);
1882 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*ref
)
1884 struct bt_ctf_field_type_variant
*variant
;
1890 variant
= container_of(
1891 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1892 struct bt_ctf_field_type_variant
, parent
);
1893 g_ptr_array_free(variant
->fields
, TRUE
);
1894 g_hash_table_destroy(variant
->field_name_to_index
);
1895 g_string_free(variant
->tag_name
, TRUE
);
1896 bt_ctf_field_type_put(&variant
->tag
->parent
);
1901 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*ref
)
1903 struct bt_ctf_field_type_array
*array
;
1909 array
= container_of(
1910 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1911 struct bt_ctf_field_type_array
, parent
);
1912 bt_ctf_field_type_put(array
->element_type
);
1917 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*ref
)
1919 struct bt_ctf_field_type_sequence
*sequence
;
1925 sequence
= container_of(
1926 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1927 struct bt_ctf_field_type_sequence
, parent
);
1928 bt_ctf_field_type_put(sequence
->element_type
);
1929 g_string_free(sequence
->length_field_name
, TRUE
);
1934 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*ref
)
1936 struct bt_ctf_field_type_string
*string
;
1942 string
= container_of(
1943 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1944 struct bt_ctf_field_type_string
, parent
);
1949 void generic_field_type_freeze(struct bt_ctf_field_type
*type
)
1955 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*type
)
1957 struct bt_ctf_field_type_enumeration
*enumeration_type
= container_of(
1958 type
, struct bt_ctf_field_type_enumeration
, parent
);
1960 generic_field_type_freeze(type
);
1961 bt_ctf_field_type_freeze(enumeration_type
->container
);
1965 void freeze_structure_field(struct structure_field
*field
)
1967 bt_ctf_field_type_freeze(field
->type
);
1971 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*type
)
1973 struct bt_ctf_field_type_structure
*structure_type
= container_of(
1974 type
, struct bt_ctf_field_type_structure
, parent
);
1976 generic_field_type_freeze(type
);
1977 g_ptr_array_foreach(structure_type
->fields
, (GFunc
)freeze_structure_field
,
1982 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*type
)
1984 struct bt_ctf_field_type_variant
*variant_type
= container_of(
1985 type
, struct bt_ctf_field_type_variant
, parent
);
1987 generic_field_type_freeze(type
);
1988 g_ptr_array_foreach(variant_type
->fields
, (GFunc
)freeze_structure_field
,
1993 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*type
)
1995 struct bt_ctf_field_type_array
*array_type
= container_of(
1996 type
, struct bt_ctf_field_type_array
, parent
);
1998 generic_field_type_freeze(type
);
1999 bt_ctf_field_type_freeze(array_type
->element_type
);
2003 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*type
)
2005 struct bt_ctf_field_type_sequence
*sequence_type
= container_of(
2006 type
, struct bt_ctf_field_type_sequence
, parent
);
2008 generic_field_type_freeze(type
);
2009 bt_ctf_field_type_freeze(sequence_type
->element_type
);
2013 const char *get_encoding_string(enum ctf_string_encoding encoding
)
2015 const char *encoding_string
;
2018 case CTF_STRING_NONE
:
2019 encoding_string
= "none";
2021 case CTF_STRING_ASCII
:
2022 encoding_string
= "ASCII";
2024 case CTF_STRING_UTF8
:
2025 encoding_string
= "UTF8";
2028 encoding_string
= "unknown";
2032 return encoding_string
;
2036 const char *get_integer_base_string(enum bt_ctf_integer_base base
)
2038 const char *base_string
;
2041 case BT_CTF_INTEGER_BASE_DECIMAL
:
2042 base_string
= "decimal";
2044 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
2045 base_string
= "hexadecimal";
2047 case BT_CTF_INTEGER_BASE_OCTAL
:
2048 base_string
= "octal";
2050 case BT_CTF_INTEGER_BASE_BINARY
:
2051 base_string
= "binary";
2054 base_string
= "unknown";
2062 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*type
,
2063 struct metadata_context
*context
)
2065 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
2066 struct bt_ctf_field_type_integer
, parent
);
2068 g_string_append_printf(context
->string
,
2069 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
2070 integer
->declaration
.len
, type
->declaration
->alignment
,
2071 (integer
->declaration
.signedness
? "true" : "false"),
2072 get_encoding_string(integer
->declaration
.encoding
),
2073 get_integer_base_string(integer
->declaration
.base
),
2074 get_byte_order_string(integer
->declaration
.byte_order
));
2079 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*type
,
2080 struct metadata_context
*context
)
2084 struct bt_ctf_field_type_enumeration
*enumeration
= container_of(type
,
2085 struct bt_ctf_field_type_enumeration
, parent
);
2086 struct bt_ctf_field_type
*container_type
;
2087 int container_signed
;
2089 ret
= bt_ctf_field_type_validate(type
);
2094 container_type
= bt_ctf_field_type_enumeration_get_container_type(type
);
2095 if (!container_type
) {
2100 container_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
2101 if (container_signed
< 0) {
2102 ret
= container_signed
;
2103 goto error_put_container_type
;
2106 g_string_append(context
->string
, "enum : ");
2107 ret
= bt_ctf_field_type_serialize(enumeration
->container
, context
);
2109 goto error_put_container_type
;
2112 g_string_append(context
->string
, " { ");
2113 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
2114 struct enumeration_mapping
*mapping
=
2115 enumeration
->entries
->pdata
[entry
];
2117 if (container_signed
) {
2118 if (mapping
->range_start
._signed
==
2119 mapping
->range_end
._signed
) {
2120 g_string_append_printf(context
->string
,
2121 "\"%s\" = %" PRId64
,
2122 g_quark_to_string(mapping
->string
),
2123 mapping
->range_start
._signed
);
2125 g_string_append_printf(context
->string
,
2126 "\"%s\" = %" PRId64
" ... %" PRId64
,
2127 g_quark_to_string(mapping
->string
),
2128 mapping
->range_start
._signed
,
2129 mapping
->range_end
._signed
);
2132 if (mapping
->range_start
._unsigned
==
2133 mapping
->range_end
._unsigned
) {
2134 g_string_append_printf(context
->string
,
2135 "\"%s\" = %" PRIu64
,
2136 g_quark_to_string(mapping
->string
),
2137 mapping
->range_start
._unsigned
);
2139 g_string_append_printf(context
->string
,
2140 "\"%s\" = %" PRIu64
" ... %" PRIu64
,
2141 g_quark_to_string(mapping
->string
),
2142 mapping
->range_start
._unsigned
,
2143 mapping
->range_end
._unsigned
);
2147 g_string_append(context
->string
,
2148 ((entry
!= (enumeration
->entries
->len
- 1)) ?
2152 if (context
->field_name
->len
) {
2153 g_string_append_printf(context
->string
, " %s",
2154 context
->field_name
->str
);
2155 g_string_assign(context
->field_name
, "");
2157 error_put_container_type
:
2158 bt_ctf_field_type_put(container_type
);
2164 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type
*type
,
2165 struct metadata_context
*context
)
2167 struct bt_ctf_field_type_floating_point
*floating_point
= container_of(
2168 type
, struct bt_ctf_field_type_floating_point
, parent
);
2170 g_string_append_printf(context
->string
,
2171 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2172 floating_point
->declaration
.exp
->len
,
2173 floating_point
->declaration
.mantissa
->len
+ 1,
2174 get_byte_order_string(floating_point
->declaration
.byte_order
),
2175 type
->declaration
->alignment
);
2180 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*type
,
2181 struct metadata_context
*context
)
2184 unsigned int indent
;
2186 struct bt_ctf_field_type_structure
*structure
= container_of(type
,
2187 struct bt_ctf_field_type_structure
, parent
);
2188 GString
*structure_field_name
= context
->field_name
;
2190 context
->field_name
= g_string_new("");
2192 context
->current_indentation_level
++;
2193 g_string_append(context
->string
, "struct {\n");
2195 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2196 struct structure_field
*field
;
2198 for (indent
= 0; indent
< context
->current_indentation_level
;
2200 g_string_append_c(context
->string
, '\t');
2203 field
= structure
->fields
->pdata
[i
];
2204 g_string_assign(context
->field_name
,
2205 g_quark_to_string(field
->name
));
2206 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
2211 if (context
->field_name
->len
) {
2212 g_string_append_printf(context
->string
, " %s",
2213 context
->field_name
->str
);
2215 g_string_append(context
->string
, ";\n");
2218 context
->current_indentation_level
--;
2219 for (indent
= 0; indent
< context
->current_indentation_level
;
2221 g_string_append_c(context
->string
, '\t');
2224 g_string_append_printf(context
->string
, "} align(%zu)",
2225 type
->declaration
->alignment
);
2227 g_string_free(context
->field_name
, TRUE
);
2228 context
->field_name
= structure_field_name
;
2233 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*type
,
2234 struct metadata_context
*context
)
2237 unsigned int indent
;
2239 struct bt_ctf_field_type_variant
*variant
= container_of(
2240 type
, struct bt_ctf_field_type_variant
, parent
);
2241 GString
*variant_field_name
= context
->field_name
;
2243 context
->field_name
= g_string_new("");
2244 g_string_append_printf(context
->string
,
2245 "variant <%s> {\n", variant
->tag_name
->str
);
2246 context
->current_indentation_level
++;
2247 for (i
= 0; i
< variant
->fields
->len
; i
++) {
2248 struct structure_field
*field
= variant
->fields
->pdata
[i
];
2250 g_string_assign(context
->field_name
,
2251 g_quark_to_string(field
->name
));
2252 for (indent
= 0; indent
< context
->current_indentation_level
;
2254 g_string_append_c(context
->string
, '\t');
2257 g_string_assign(context
->field_name
,
2258 g_quark_to_string(field
->name
));
2259 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
2264 if (context
->field_name
->len
) {
2265 g_string_append_printf(context
->string
, " %s;",
2266 context
->field_name
->str
);
2269 g_string_append_c(context
->string
, '\n');
2272 context
->current_indentation_level
--;
2273 for (indent
= 0; indent
< context
->current_indentation_level
;
2275 g_string_append_c(context
->string
, '\t');
2278 g_string_append(context
->string
, "}");
2280 g_string_free(context
->field_name
, TRUE
);
2281 context
->field_name
= variant_field_name
;
2286 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*type
,
2287 struct metadata_context
*context
)
2290 struct bt_ctf_field_type_array
*array
= container_of(type
,
2291 struct bt_ctf_field_type_array
, parent
);
2293 ret
= bt_ctf_field_type_serialize(array
->element_type
, context
);
2298 if (context
->field_name
->len
) {
2299 g_string_append_printf(context
->string
, " %s[%u]",
2300 context
->field_name
->str
, array
->length
);
2301 g_string_assign(context
->field_name
, "");
2303 g_string_append_printf(context
->string
, "[%u]", array
->length
);
2310 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*type
,
2311 struct metadata_context
*context
)
2314 struct bt_ctf_field_type_sequence
*sequence
= container_of(
2315 type
, struct bt_ctf_field_type_sequence
, parent
);
2317 ret
= bt_ctf_field_type_serialize(sequence
->element_type
, context
);
2322 if (context
->field_name
->len
) {
2323 g_string_append_printf(context
->string
, " %s[%s]",
2324 context
->field_name
->str
,
2325 sequence
->length_field_name
->str
);
2326 g_string_assign(context
->field_name
, "");
2328 g_string_append_printf(context
->string
, "[%s]",
2329 sequence
->length_field_name
->str
);
2336 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*type
,
2337 struct metadata_context
*context
)
2339 struct bt_ctf_field_type_string
*string
= container_of(
2340 type
, struct bt_ctf_field_type_string
, parent
);
2342 g_string_append_printf(context
->string
,
2343 "string { encoding = %s; }",
2344 get_encoding_string(string
->declaration
.encoding
));
2349 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*type
,
2350 int byte_order
, int set_native
)
2352 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
2353 struct bt_ctf_field_type_integer
, parent
);
2356 integer_type
->declaration
.byte_order
=
2357 integer_type
->declaration
.byte_order
== 0 ?
2358 byte_order
: integer_type
->declaration
.byte_order
;
2360 integer_type
->declaration
.byte_order
= byte_order
;
2365 void bt_ctf_field_type_enumeration_set_byte_order(
2366 struct bt_ctf_field_type
*type
, int byte_order
, int set_native
)
2368 struct bt_ctf_field_type_enumeration
*enum_type
= container_of(type
,
2369 struct bt_ctf_field_type_enumeration
, parent
);
2371 /* Safe to assume that container is an integer */
2372 bt_ctf_field_type_integer_set_byte_order(enum_type
->container
,
2373 byte_order
, set_native
);
2377 void bt_ctf_field_type_floating_point_set_byte_order(
2378 struct bt_ctf_field_type
*type
, int byte_order
, int set_native
)
2380 struct bt_ctf_field_type_floating_point
*floating_point_type
=
2381 container_of(type
, struct bt_ctf_field_type_floating_point
,
2385 floating_point_type
->declaration
.byte_order
=
2386 floating_point_type
->declaration
.byte_order
== 0 ?
2388 floating_point_type
->declaration
.byte_order
;
2389 floating_point_type
->sign
.byte_order
=
2390 floating_point_type
->sign
.byte_order
== 0 ?
2391 byte_order
: floating_point_type
->sign
.byte_order
;
2392 floating_point_type
->mantissa
.byte_order
=
2393 floating_point_type
->mantissa
.byte_order
== 0 ?
2394 byte_order
: floating_point_type
->mantissa
.byte_order
;
2395 floating_point_type
->exp
.byte_order
=
2396 floating_point_type
->exp
.byte_order
== 0 ?
2397 byte_order
: floating_point_type
->exp
.byte_order
;
2399 floating_point_type
->declaration
.byte_order
= byte_order
;
2400 floating_point_type
->sign
.byte_order
= byte_order
;
2401 floating_point_type
->mantissa
.byte_order
= byte_order
;
2402 floating_point_type
->exp
.byte_order
= byte_order
;
2407 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*type
,
2408 int byte_order
, int set_native
)
2411 struct bt_ctf_field_type_structure
*structure_type
=
2412 container_of(type
, struct bt_ctf_field_type_structure
,
2415 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
2416 struct structure_field
*field
= g_ptr_array_index(
2417 structure_type
->fields
, i
);
2418 struct bt_ctf_field_type
*field_type
= field
->type
;
2420 if (set_byte_order_funcs
[field_type
->declaration
->id
]) {
2421 set_byte_order_funcs
[field_type
->declaration
->id
](
2422 field_type
, byte_order
, set_native
);
2428 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*type
,
2429 int byte_order
, int set_native
)
2432 struct bt_ctf_field_type_variant
*variant_type
=
2433 container_of(type
, struct bt_ctf_field_type_variant
,
2436 for (i
= 0; i
< variant_type
->fields
->len
; i
++) {
2437 struct structure_field
*field
= g_ptr_array_index(
2438 variant_type
->fields
, i
);
2439 struct bt_ctf_field_type
*field_type
= field
->type
;
2441 if (set_byte_order_funcs
[field_type
->declaration
->id
]) {
2442 set_byte_order_funcs
[field_type
->declaration
->id
](
2443 field_type
, byte_order
, set_native
);
2449 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*type
,
2450 int byte_order
, int set_native
)
2452 struct bt_ctf_field_type_array
*array_type
=
2453 container_of(type
, struct bt_ctf_field_type_array
,
2456 if (set_byte_order_funcs
[array_type
->element_type
->declaration
->id
]) {
2457 set_byte_order_funcs
[array_type
->element_type
->declaration
->id
](
2458 array_type
->element_type
, byte_order
, set_native
);
2463 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*type
,
2464 int byte_order
, int set_native
)
2466 struct bt_ctf_field_type_sequence
*sequence_type
=
2467 container_of(type
, struct bt_ctf_field_type_sequence
,
2470 if (set_byte_order_funcs
[
2471 sequence_type
->element_type
->declaration
->id
]) {
2472 set_byte_order_funcs
[
2473 sequence_type
->element_type
->declaration
->id
](
2474 sequence_type
->element_type
, byte_order
, set_native
);