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-ir/clock.h>
33 #include <babeltrace/ctf-writer/writer-internal.h>
34 #include <babeltrace/compiler.h>
35 #include <babeltrace/endian.h>
40 struct range_overlap_query
{
55 void bt_ctf_field_type_destroy(struct bt_ctf_ref
*);
57 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*);
59 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*);
61 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*);
63 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*);
65 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*);
67 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*);
69 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*);
71 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*);
74 void (* const type_destroy_funcs
[])(struct bt_ctf_ref
*) = {
75 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_destroy
,
77 bt_ctf_field_type_enumeration_destroy
,
79 bt_ctf_field_type_floating_point_destroy
,
80 [CTF_TYPE_STRUCT
] = bt_ctf_field_type_structure_destroy
,
81 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_destroy
,
82 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_destroy
,
83 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_destroy
,
84 [CTF_TYPE_STRING
] = bt_ctf_field_type_string_destroy
,
88 void generic_field_type_freeze(struct bt_ctf_field_type
*);
90 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*);
92 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*);
94 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*);
96 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*);
98 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*);
101 type_freeze_func
const type_freeze_funcs
[] = {
102 [CTF_TYPE_INTEGER
] = generic_field_type_freeze
,
103 [CTF_TYPE_ENUM
] = bt_ctf_field_type_enumeration_freeze
,
104 [CTF_TYPE_FLOAT
] = generic_field_type_freeze
,
105 [CTF_TYPE_STRUCT
] = bt_ctf_field_type_structure_freeze
,
106 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_freeze
,
107 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_freeze
,
108 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_freeze
,
109 [CTF_TYPE_STRING
] = generic_field_type_freeze
,
113 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*,
114 struct metadata_context
*);
116 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*,
117 struct metadata_context
*);
119 int bt_ctf_field_type_floating_point_serialize(
120 struct bt_ctf_field_type
*, struct metadata_context
*);
122 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*,
123 struct metadata_context
*);
125 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*,
126 struct metadata_context
*);
128 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*,
129 struct metadata_context
*);
131 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*,
132 struct metadata_context
*);
134 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*,
135 struct metadata_context
*);
138 type_serialize_func
const type_serialize_funcs
[] = {
139 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_serialize
,
141 bt_ctf_field_type_enumeration_serialize
,
143 bt_ctf_field_type_floating_point_serialize
,
145 bt_ctf_field_type_structure_serialize
,
146 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_serialize
,
147 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_serialize
,
148 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_serialize
,
149 [CTF_TYPE_STRING
] = bt_ctf_field_type_string_serialize
,
153 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*,
154 int byte_order
, int set_native
);
156 void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type
*,
157 int byte_order
, int set_native
);
159 void bt_ctf_field_type_floating_point_set_byte_order(
160 struct bt_ctf_field_type
*, int byte_order
, int set_native
);
162 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*,
163 int byte_order
, int set_native
);
165 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*,
166 int byte_order
, int set_native
);
168 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*,
169 int byte_order
, int set_native
);
171 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*,
172 int byte_order
, int set_native
);
174 /* The set_native flag only set the byte order if it is set to native */
176 void (* const set_byte_order_funcs
[])(struct bt_ctf_field_type
*,
177 int byte_order
, int set_native
) = {
178 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_set_byte_order
,
180 bt_ctf_field_type_enumeration_set_byte_order
,
182 bt_ctf_field_type_floating_point_set_byte_order
,
184 bt_ctf_field_type_structure_set_byte_order
,
185 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_set_byte_order
,
186 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_set_byte_order
,
187 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_set_byte_order
,
188 [CTF_TYPE_STRING
] = NULL
,
192 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
198 void destroy_structure_field(struct structure_field
*field
)
201 bt_ctf_field_type_put(field
->type
);
208 void check_ranges_overlap(gpointer element
, gpointer query
)
210 struct enumeration_mapping
*mapping
= element
;
211 struct range_overlap_query
*overlap_query
= query
;
213 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
214 && overlap_query
->range_start
._signed
<=
215 mapping
->range_end
._signed
) {
216 overlap_query
->overlaps
= 1;
217 overlap_query
->mapping_name
= mapping
->string
;
220 overlap_query
->overlaps
|=
221 mapping
->string
== overlap_query
->mapping_name
;
225 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
227 struct enumeration_mapping
*mapping
= element
;
228 struct range_overlap_query
*overlap_query
= query
;
230 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
231 && overlap_query
->range_start
._unsigned
<=
232 mapping
->range_end
._unsigned
) {
233 overlap_query
->overlaps
= 1;
234 overlap_query
->mapping_name
= mapping
->string
;
237 overlap_query
->overlaps
|=
238 mapping
->string
== overlap_query
->mapping_name
;
242 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
243 struct enumeration_mapping
**b
)
245 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
249 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
250 struct enumeration_mapping
**b
)
252 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
256 void bt_ctf_field_type_init(struct bt_ctf_field_type
*type
)
258 enum ctf_type_id type_id
= type
->declaration
->id
;
261 assert(type
&& (type_id
> CTF_TYPE_UNKNOWN
) &&
262 (type_id
< NR_CTF_TYPES
));
264 bt_ctf_ref_init(&type
->ref_count
);
265 type
->freeze
= type_freeze_funcs
[type_id
];
266 type
->serialize
= type_serialize_funcs
[type_id
];
267 ret
= bt_ctf_field_type_set_byte_order(type
, BT_CTF_BYTE_ORDER_NATIVE
);
269 type
->declaration
->alignment
= 1;
273 int add_structure_field(GPtrArray
*fields
,
274 GHashTable
*field_name_to_index
,
275 struct bt_ctf_field_type
*field_type
,
276 const char *field_name
)
279 GQuark name_quark
= g_quark_from_string(field_name
);
280 struct structure_field
*field
;
282 /* Make sure structure does not contain a field of the same name */
283 if (g_hash_table_lookup_extended(field_name_to_index
,
284 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
289 field
= g_new0(struct structure_field
, 1);
295 bt_ctf_field_type_get(field_type
);
296 field
->name
= name_quark
;
297 field
->type
= field_type
;
298 g_hash_table_insert(field_name_to_index
,
299 (gpointer
) (unsigned long) name_quark
,
300 (gpointer
) (unsigned long) fields
->len
);
301 g_ptr_array_add(fields
, field
);
302 bt_ctf_field_type_freeze(field_type
);
308 void bt_ctf_field_type_destroy(struct bt_ctf_ref
*ref
)
310 struct bt_ctf_field_type
*type
;
311 enum ctf_type_id type_id
;
317 type
= container_of(ref
, struct bt_ctf_field_type
, ref_count
);
318 type_id
= type
->declaration
->id
;
319 if (type_id
<= CTF_TYPE_UNKNOWN
||
320 type_id
>= NR_CTF_TYPES
) {
324 if (type
->alias_name
) {
325 g_string_free(type
->alias_name
, TRUE
);
327 type_destroy_funcs
[type_id
](ref
);
331 int bt_ctf_field_type_validate(struct bt_ctf_field_type
*type
)
340 switch (type
->declaration
->id
) {
343 struct bt_ctf_field_type_enumeration
*enumeration
=
344 container_of(type
, struct bt_ctf_field_type_enumeration
,
347 /* Ensure enum has entries */
348 ret
= enumeration
->entries
->len
? 0 : -1;
358 struct bt_ctf_field_type
*bt_ctf_field_type_integer_create(unsigned int size
)
360 struct bt_ctf_field_type_integer
*integer
=
361 g_new0(struct bt_ctf_field_type_integer
, 1);
363 if (!integer
|| size
== 0 || size
> 64) {
367 integer
->parent
.declaration
= &integer
->declaration
.p
;
368 integer
->parent
.declaration
->id
= CTF_TYPE_INTEGER
;
369 integer
->declaration
.len
= size
;
370 integer
->declaration
.base
= BT_CTF_INTEGER_BASE_DECIMAL
;
371 integer
->declaration
.encoding
= CTF_STRING_NONE
;
372 bt_ctf_field_type_init(&integer
->parent
);
373 return &integer
->parent
;
376 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type
*type
)
379 struct bt_ctf_field_type_integer
*integer
;
381 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
386 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
387 ret
= (int) integer
->declaration
.len
;
392 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type
*type
)
395 struct bt_ctf_field_type_integer
*integer
;
397 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
402 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
403 ret
= integer
->declaration
.signedness
;
408 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type
*type
,
412 struct bt_ctf_field_type_integer
*integer
;
414 if (!type
|| type
->frozen
||
415 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
420 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
421 integer
->declaration
.signedness
= !!is_signed
;
426 enum bt_ctf_integer_base
bt_ctf_field_type_integer_get_base(
427 struct bt_ctf_field_type
*type
)
429 enum bt_ctf_integer_base ret
= BT_CTF_INTEGER_BASE_UNKNOWN
;
430 struct bt_ctf_field_type_integer
*integer
;
432 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
436 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
437 ret
= integer
->declaration
.base
;
442 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type
*type
,
443 enum bt_ctf_integer_base base
)
447 if (!type
|| type
->frozen
||
448 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
454 case BT_CTF_INTEGER_BASE_BINARY
:
455 case BT_CTF_INTEGER_BASE_OCTAL
:
456 case BT_CTF_INTEGER_BASE_DECIMAL
:
457 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
459 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
460 struct bt_ctf_field_type_integer
, parent
);
461 integer
->declaration
.base
= base
;
471 enum ctf_string_encoding
bt_ctf_field_type_integer_get_encoding(
472 struct bt_ctf_field_type
*type
)
474 enum ctf_string_encoding ret
= CTF_STRING_UNKNOWN
;
475 struct bt_ctf_field_type_integer
*integer
;
477 if (!type
|| type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
481 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
482 ret
= integer
->declaration
.encoding
;
487 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type
*type
,
488 enum ctf_string_encoding encoding
)
491 struct bt_ctf_field_type_integer
*integer
;
493 if (!type
|| type
->frozen
||
494 (type
->declaration
->id
!= CTF_TYPE_INTEGER
) ||
495 (encoding
< CTF_STRING_NONE
) ||
496 (encoding
>= CTF_STRING_UNKNOWN
)) {
501 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
502 integer
->declaration
.encoding
= encoding
;
507 struct bt_ctf_clock
*bt_ctf_field_type_integer_get_mapped_clock(
508 struct bt_ctf_field_type
*type
)
510 struct bt_ctf_field_type_integer
*integer
;
511 struct bt_ctf_clock
*clock
= NULL
;
517 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
518 clock
= integer
->mapped_clock
;
520 bt_ctf_clock_get(clock
);
526 int bt_ctf_field_type_integer_set_mapped_clock(
527 struct bt_ctf_field_type
*type
,
528 struct bt_ctf_clock
*clock
)
530 struct bt_ctf_field_type_integer
*integer
;
533 if (!type
|| type
->frozen
) {
538 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
539 if (integer
->mapped_clock
) {
540 bt_ctf_clock_put(integer
->mapped_clock
);
544 bt_ctf_clock_get(clock
);
547 integer
->mapped_clock
= clock
;
552 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_create(
553 struct bt_ctf_field_type
*integer_container_type
)
555 struct bt_ctf_field_type_enumeration
*enumeration
= NULL
;
557 if (!integer_container_type
) {
561 if (integer_container_type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
565 enumeration
= g_new0(struct bt_ctf_field_type_enumeration
, 1);
570 enumeration
->parent
.declaration
= &enumeration
->declaration
.p
;
571 enumeration
->parent
.declaration
->id
= CTF_TYPE_ENUM
;
572 bt_ctf_field_type_get(integer_container_type
);
573 enumeration
->container
= integer_container_type
;
574 enumeration
->entries
= g_ptr_array_new_with_free_func(
575 (GDestroyNotify
)destroy_enumeration_mapping
);
576 bt_ctf_field_type_init(&enumeration
->parent
);
577 return &enumeration
->parent
;
583 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_get_container_type(
584 struct bt_ctf_field_type
*type
)
586 struct bt_ctf_field_type
*container_type
= NULL
;
587 struct bt_ctf_field_type_enumeration
*enumeration_type
;
593 if (type
->declaration
->id
!= CTF_TYPE_ENUM
) {
597 enumeration_type
= container_of(type
,
598 struct bt_ctf_field_type_enumeration
, parent
);
599 container_type
= enumeration_type
->container
;
600 bt_ctf_field_type_get(container_type
);
602 return container_type
;
605 int bt_ctf_field_type_enumeration_add_mapping(
606 struct bt_ctf_field_type
*type
, const char *string
,
607 int64_t range_start
, int64_t range_end
)
611 struct enumeration_mapping
*mapping
;
612 struct bt_ctf_field_type_enumeration
*enumeration
;
613 struct range_overlap_query query
;
614 char *escaped_string
;
616 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
618 (range_end
< range_start
)) {
623 if (!string
|| strlen(string
) == 0) {
628 escaped_string
= g_strescape(string
, NULL
);
629 if (!escaped_string
) {
634 mapping_name
= g_quark_from_string(escaped_string
);
635 query
= (struct range_overlap_query
) {
636 .range_start
._signed
= range_start
,
637 .range_end
._signed
= range_end
,
638 .mapping_name
= mapping_name
,
640 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
643 /* Check that the range does not overlap with one already present */
644 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap
, &query
);
645 if (query
.overlaps
) {
650 mapping
= g_new(struct enumeration_mapping
, 1);
656 *mapping
= (struct enumeration_mapping
) {
657 .range_start
._signed
= range_start
,
658 .range_end
._signed
= range_end
, .string
= mapping_name
};
659 g_ptr_array_add(enumeration
->entries
, mapping
);
660 g_ptr_array_sort(enumeration
->entries
,
661 (GCompareFunc
)compare_enumeration_mappings_signed
);
663 free(escaped_string
);
668 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
669 struct bt_ctf_field_type
*type
, const char *string
,
670 uint64_t range_start
, uint64_t range_end
)
674 struct enumeration_mapping
*mapping
;
675 struct bt_ctf_field_type_enumeration
*enumeration
;
676 struct range_overlap_query query
;
677 char *escaped_string
;
679 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
681 (range_end
< range_start
)) {
686 if (!string
|| strlen(string
) == 0) {
691 escaped_string
= g_strescape(string
, NULL
);
692 if (!escaped_string
) {
697 mapping_name
= g_quark_from_string(escaped_string
);
698 query
= (struct range_overlap_query
) {
699 .range_start
._unsigned
= range_start
,
700 .range_end
._unsigned
= range_end
,
701 .mapping_name
= mapping_name
,
703 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
706 /* Check that the range does not overlap with one already present */
707 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap_unsigned
,
709 if (query
.overlaps
) {
714 mapping
= g_new(struct enumeration_mapping
, 1);
720 *mapping
= (struct enumeration_mapping
) {
721 .range_start
._unsigned
= range_start
,
722 .range_end
._unsigned
= range_end
, .string
= mapping_name
};
723 g_ptr_array_add(enumeration
->entries
, mapping
);
724 g_ptr_array_sort(enumeration
->entries
,
725 (GCompareFunc
)compare_enumeration_mappings_unsigned
);
727 free(escaped_string
);
732 const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
733 struct bt_ctf_field_type_enumeration
*enumeration_type
,
736 const char *name
= NULL
;
737 struct range_overlap_query query
=
738 (struct range_overlap_query
) {
739 .range_start
._unsigned
= value
,
740 .range_end
._unsigned
= value
,
743 g_ptr_array_foreach(enumeration_type
->entries
,
744 check_ranges_overlap_unsigned
,
746 if (!query
.overlaps
) {
750 name
= g_quark_to_string(query
.mapping_name
);
755 const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
756 struct bt_ctf_field_type_enumeration
*enumeration_type
,
759 const char *name
= NULL
;
760 struct range_overlap_query query
=
761 (struct range_overlap_query
) {
762 .range_start
._signed
= value
,
763 .range_end
._signed
= value
,
766 g_ptr_array_foreach(enumeration_type
->entries
, check_ranges_overlap
,
768 if (!query
.overlaps
) {
772 name
= g_quark_to_string(query
.mapping_name
);
777 int bt_ctf_field_type_enumeration_get_mapping_count(
778 struct bt_ctf_field_type
*type
)
781 struct bt_ctf_field_type_enumeration
*enumeration
;
783 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
788 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
790 ret
= (int) enumeration
->entries
->len
;
796 struct enumeration_mapping
*get_enumeration_mapping(
797 struct bt_ctf_field_type
*type
, int index
)
799 struct enumeration_mapping
*mapping
= NULL
;
800 struct bt_ctf_field_type_enumeration
*enumeration
;
802 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
804 if (index
>= enumeration
->entries
->len
) {
808 mapping
= g_ptr_array_index(enumeration
->entries
, index
);
813 int bt_ctf_field_type_enumeration_get_mapping(
814 struct bt_ctf_field_type
*type
, int index
,
815 const char **string
, int64_t *range_start
, int64_t *range_end
)
817 struct enumeration_mapping
*mapping
;
820 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
821 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
826 mapping
= get_enumeration_mapping(type
, index
);
832 *string
= g_quark_to_string(mapping
->string
);
833 *range_start
= mapping
->range_start
._signed
;
834 *range_end
= mapping
->range_end
._signed
;
839 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
840 struct bt_ctf_field_type
*type
, int index
,
841 const char **string
, uint64_t *range_start
, uint64_t *range_end
)
843 struct enumeration_mapping
*mapping
;
846 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
847 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
852 mapping
= get_enumeration_mapping(type
, index
);
858 *string
= g_quark_to_string(mapping
->string
);
859 *range_start
= mapping
->range_start
._unsigned
;
860 *range_end
= mapping
->range_end
._unsigned
;
865 int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
866 struct bt_ctf_field_type
*type
, const char *name
)
869 struct bt_ctf_field_type_enumeration
*enumeration
;
872 if (!type
|| !name
||
873 (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
878 name_quark
= g_quark_try_string(name
);
884 enumeration
= container_of(type
,
885 struct bt_ctf_field_type_enumeration
, parent
);
886 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
887 struct enumeration_mapping
*mapping
=
888 get_enumeration_mapping(type
, i
);
890 if (mapping
->string
== name_quark
) {
901 int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
902 struct bt_ctf_field_type
*type
, int64_t value
)
904 struct bt_ctf_field_type_enumeration
*enumeration
;
907 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
912 enumeration
= container_of(type
,
913 struct bt_ctf_field_type_enumeration
, parent
);
914 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
915 struct enumeration_mapping
*mapping
=
916 get_enumeration_mapping(type
, i
);
918 if (value
>= mapping
->range_start
._signed
&&
919 value
<= mapping
->range_end
._signed
) {
930 int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
931 struct bt_ctf_field_type
*type
, uint64_t value
)
933 struct bt_ctf_field_type_enumeration
*enumeration
;
936 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
)) {
941 enumeration
= container_of(type
,
942 struct bt_ctf_field_type_enumeration
, parent
);
943 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
944 struct enumeration_mapping
*mapping
=
945 get_enumeration_mapping(type
, i
);
947 if (value
>= mapping
->range_start
._unsigned
&&
948 value
<= mapping
->range_end
._unsigned
) {
959 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_create(void)
961 struct bt_ctf_field_type_floating_point
*floating_point
=
962 g_new0(struct bt_ctf_field_type_floating_point
, 1);
964 if (!floating_point
) {
968 floating_point
->declaration
.sign
= &floating_point
->sign
;
969 floating_point
->declaration
.mantissa
= &floating_point
->mantissa
;
970 floating_point
->declaration
.exp
= &floating_point
->exp
;
971 floating_point
->sign
.len
= 1;
972 floating_point
->parent
.declaration
= &floating_point
->declaration
.p
;
973 floating_point
->parent
.declaration
->id
= CTF_TYPE_FLOAT
;
974 floating_point
->declaration
.exp
->len
=
975 sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
976 floating_point
->declaration
.mantissa
->len
= FLT_MANT_DIG
- 1;
977 floating_point
->sign
.p
.alignment
= 1;
978 floating_point
->mantissa
.p
.alignment
= 1;
979 floating_point
->exp
.p
.alignment
= 1;
981 bt_ctf_field_type_init(&floating_point
->parent
);
983 return floating_point
? &floating_point
->parent
: NULL
;
986 int bt_ctf_field_type_floating_point_get_exponent_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
->declaration
.exp
->len
;
1004 int bt_ctf_field_type_floating_point_set_exponent_digits(
1005 struct bt_ctf_field_type
*type
,
1006 unsigned int exponent_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
);
1019 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
1020 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
1022 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
1027 floating_point
->declaration
.exp
->len
= exponent_digits
;
1032 int bt_ctf_field_type_floating_point_get_mantissa_digits(
1033 struct bt_ctf_field_type
*type
)
1036 struct bt_ctf_field_type_floating_point
*floating_point
;
1038 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
1043 floating_point
= container_of(type
,
1044 struct bt_ctf_field_type_floating_point
, parent
);
1045 ret
= (int) floating_point
->mantissa
.len
+ 1;
1050 int bt_ctf_field_type_floating_point_set_mantissa_digits(
1051 struct bt_ctf_field_type
*type
,
1052 unsigned int mantissa_digits
)
1055 struct bt_ctf_field_type_floating_point
*floating_point
;
1057 if (!type
|| type
->frozen
||
1058 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
1063 floating_point
= container_of(type
,
1064 struct bt_ctf_field_type_floating_point
, parent
);
1066 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
1067 (mantissa_digits
!= DBL_MANT_DIG
) &&
1068 (mantissa_digits
!= LDBL_MANT_DIG
)) {
1073 floating_point
->declaration
.mantissa
->len
= mantissa_digits
- 1;
1078 struct bt_ctf_field_type
*bt_ctf_field_type_structure_create(void)
1080 struct bt_ctf_field_type_structure
*structure
=
1081 g_new0(struct bt_ctf_field_type_structure
, 1);
1087 structure
->parent
.declaration
= &structure
->declaration
.p
;
1088 structure
->parent
.declaration
->id
= CTF_TYPE_STRUCT
;
1089 structure
->fields
= g_ptr_array_new_with_free_func(
1090 (GDestroyNotify
)destroy_structure_field
);
1091 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1092 bt_ctf_field_type_init(&structure
->parent
);
1093 return &structure
->parent
;
1098 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type
*type
,
1099 struct bt_ctf_field_type
*field_type
,
1100 const char *field_name
)
1103 struct bt_ctf_field_type_structure
*structure
;
1105 if (!type
|| !field_type
|| type
->frozen
||
1106 bt_ctf_validate_identifier(field_name
) ||
1107 (type
->declaration
->id
!= CTF_TYPE_STRUCT
) ||
1108 bt_ctf_field_type_validate(field_type
)) {
1113 structure
= container_of(type
,
1114 struct bt_ctf_field_type_structure
, parent
);
1115 if (add_structure_field(structure
->fields
,
1116 structure
->field_name_to_index
, field_type
, field_name
)) {
1121 if (type
->declaration
->alignment
< field_type
->declaration
->alignment
) {
1122 type
->declaration
->alignment
=
1123 field_type
->declaration
->alignment
;
1129 int bt_ctf_field_type_structure_get_field_count(
1130 struct bt_ctf_field_type
*type
)
1133 struct bt_ctf_field_type_structure
*structure
;
1135 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_STRUCT
)) {
1140 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1142 ret
= (int) structure
->fields
->len
;
1147 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type
*type
,
1148 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1151 struct bt_ctf_field_type_structure
*structure
;
1152 struct structure_field
*field
;
1155 if (!type
|| index
< 0 || !field_name
|| !field_type
||
1156 (type
->declaration
->id
!= CTF_TYPE_STRUCT
)) {
1161 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1163 if (index
>= structure
->fields
->len
) {
1168 field
= g_ptr_array_index(structure
->fields
, index
);
1169 *field_type
= field
->type
;
1170 bt_ctf_field_type_get(field
->type
);
1171 *field_name
= g_quark_to_string(field
->name
);
1176 struct bt_ctf_field_type
*bt_ctf_field_type_structure_get_field_type_by_name(
1177 struct bt_ctf_field_type
*type
,
1182 struct structure_field
*field
;
1183 struct bt_ctf_field_type_structure
*structure
;
1184 struct bt_ctf_field_type
*field_type
= NULL
;
1186 if (!type
|| !name
) {
1190 name_quark
= g_quark_try_string(name
);
1195 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1197 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
1198 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1202 field
= structure
->fields
->pdata
[index
];
1203 field_type
= field
->type
;
1204 bt_ctf_field_type_get(field_type
);
1209 struct bt_ctf_field_type
*bt_ctf_field_type_variant_create(
1210 struct bt_ctf_field_type
*enum_tag
, const char *tag_name
)
1212 struct bt_ctf_field_type_variant
*variant
= NULL
;
1214 if (!enum_tag
|| bt_ctf_validate_identifier(tag_name
) ||
1215 (enum_tag
->declaration
->id
!= CTF_TYPE_ENUM
)) {
1219 variant
= g_new0(struct bt_ctf_field_type_variant
, 1);
1224 variant
->parent
.declaration
= &variant
->declaration
.p
;
1225 variant
->parent
.declaration
->id
= CTF_TYPE_VARIANT
;
1226 variant
->tag_name
= g_string_new(tag_name
);
1227 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1228 variant
->fields
= g_ptr_array_new_with_free_func(
1229 (GDestroyNotify
)destroy_structure_field
);
1230 bt_ctf_field_type_get(enum_tag
);
1231 variant
->tag
= container_of(enum_tag
,
1232 struct bt_ctf_field_type_enumeration
, parent
);
1233 bt_ctf_field_type_init(&variant
->parent
);
1234 return &variant
->parent
;
1239 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_tag_type(
1240 struct bt_ctf_field_type
*type
)
1242 struct bt_ctf_field_type_variant
*variant
;
1243 struct bt_ctf_field_type
*tag_type
= NULL
;
1245 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1249 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1250 tag_type
= &variant
->tag
->parent
;
1251 bt_ctf_field_type_get(tag_type
);
1256 const char *bt_ctf_field_type_variant_get_tag_name(
1257 struct bt_ctf_field_type
*type
)
1259 struct bt_ctf_field_type_variant
*variant
;
1260 const char *tag_name
= NULL
;
1262 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1266 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1267 tag_name
= variant
->tag_name
->str
;
1272 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type
*type
,
1273 struct bt_ctf_field_type
*field_type
,
1274 const char *field_name
)
1279 struct bt_ctf_field_type_variant
*variant
;
1280 GQuark field_name_quark
= g_quark_from_string(field_name
);
1282 if (!type
|| !field_type
|| type
->frozen
||
1283 bt_ctf_validate_identifier(field_name
) ||
1284 (type
->declaration
->id
!= CTF_TYPE_VARIANT
) ||
1285 bt_ctf_field_type_validate(field_type
)) {
1290 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1291 /* Make sure this name is present in the enum tag */
1292 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
1293 struct enumeration_mapping
*mapping
=
1294 g_ptr_array_index(variant
->tag
->entries
, i
);
1296 if (mapping
->string
== field_name_quark
) {
1302 if (!name_found
|| add_structure_field(variant
->fields
,
1303 variant
->field_name_to_index
, field_type
, field_name
)) {
1311 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_by_name(
1312 struct bt_ctf_field_type
*type
,
1313 const char *field_name
)
1317 struct structure_field
*field
;
1318 struct bt_ctf_field_type_variant
*variant
;
1319 struct bt_ctf_field_type
*field_type
= NULL
;
1321 if (!type
|| !field_name
) {
1325 name_quark
= g_quark_try_string(field_name
);
1330 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1331 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1332 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1336 field
= g_ptr_array_index(variant
->fields
, index
);
1337 field_type
= field
->type
;
1338 bt_ctf_field_type_get(field_type
);
1343 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_from_tag(
1344 struct bt_ctf_field_type
*type
,
1345 struct bt_ctf_field
*tag
)
1347 const char *enum_value
;
1348 struct bt_ctf_field_type
*field_type
= NULL
;
1350 if (!type
|| !tag
|| type
->declaration
->id
!= CTF_TYPE_VARIANT
) {
1354 enum_value
= bt_ctf_field_enumeration_get_mapping_name(tag
);
1359 /* Already increments field_type's reference count */
1360 field_type
= bt_ctf_field_type_variant_get_field_type_by_name(
1366 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type
*type
)
1369 struct bt_ctf_field_type_variant
*variant
;
1371 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1376 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1378 ret
= (int) variant
->fields
->len
;
1384 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type
*type
,
1385 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1388 struct bt_ctf_field_type_variant
*variant
;
1389 struct structure_field
*field
;
1392 if (!type
|| index
< 0 || !field_name
|| !field_type
||
1393 (type
->declaration
->id
!= CTF_TYPE_VARIANT
)) {
1398 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1400 if (index
>= variant
->fields
->len
) {
1405 field
= g_ptr_array_index(variant
->fields
, index
);
1406 *field_type
= field
->type
;
1407 bt_ctf_field_type_get(field
->type
);
1408 *field_name
= g_quark_to_string(field
->name
);
1413 struct bt_ctf_field_type
*bt_ctf_field_type_array_create(
1414 struct bt_ctf_field_type
*element_type
,
1415 unsigned int length
)
1417 struct bt_ctf_field_type_array
*array
= NULL
;
1419 if (!element_type
|| length
== 0 ||
1420 bt_ctf_field_type_validate(element_type
)) {
1424 array
= g_new0(struct bt_ctf_field_type_array
, 1);
1429 array
->parent
.declaration
= &array
->declaration
.p
;
1430 array
->parent
.declaration
->id
= CTF_TYPE_ARRAY
;
1432 bt_ctf_field_type_get(element_type
);
1433 array
->element_type
= element_type
;
1434 array
->length
= length
;
1435 bt_ctf_field_type_init(&array
->parent
);
1436 array
->parent
.declaration
->alignment
=
1437 element_type
->declaration
->alignment
;
1438 return &array
->parent
;
1443 struct bt_ctf_field_type
*bt_ctf_field_type_array_get_element_type(
1444 struct bt_ctf_field_type
*type
)
1446 struct bt_ctf_field_type
*ret
= NULL
;
1447 struct bt_ctf_field_type_array
*array
;
1449 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ARRAY
)) {
1453 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1454 ret
= array
->element_type
;
1455 bt_ctf_field_type_get(ret
);
1460 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type
*type
)
1463 struct bt_ctf_field_type_array
*array
;
1465 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ARRAY
)) {
1470 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1471 ret
= (int64_t) array
->length
;
1476 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_create(
1477 struct bt_ctf_field_type
*element_type
,
1478 const char *length_field_name
)
1480 struct bt_ctf_field_type_sequence
*sequence
= NULL
;
1482 if (!element_type
|| bt_ctf_validate_identifier(length_field_name
) ||
1483 bt_ctf_field_type_validate(element_type
)) {
1487 sequence
= g_new0(struct bt_ctf_field_type_sequence
, 1);
1492 sequence
->parent
.declaration
= &sequence
->declaration
.p
;
1493 sequence
->parent
.declaration
->id
= CTF_TYPE_SEQUENCE
;
1494 bt_ctf_field_type_get(element_type
);
1495 sequence
->element_type
= element_type
;
1496 sequence
->length_field_name
= g_string_new(length_field_name
);
1497 bt_ctf_field_type_init(&sequence
->parent
);
1498 sequence
->parent
.declaration
->alignment
=
1499 element_type
->declaration
->alignment
;
1500 return &sequence
->parent
;
1505 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_get_element_type(
1506 struct bt_ctf_field_type
*type
)
1508 struct bt_ctf_field_type
*ret
= NULL
;
1509 struct bt_ctf_field_type_sequence
*sequence
;
1511 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_SEQUENCE
)) {
1515 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1517 ret
= sequence
->element_type
;
1518 bt_ctf_field_type_get(ret
);
1523 const char *bt_ctf_field_type_sequence_get_length_field_name(
1524 struct bt_ctf_field_type
*type
)
1526 const char *ret
= NULL
;
1527 struct bt_ctf_field_type_sequence
*sequence
;
1529 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_SEQUENCE
)) {
1533 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1535 ret
= sequence
->length_field_name
->str
;
1540 struct bt_ctf_field_type
*bt_ctf_field_type_string_create(void)
1542 struct bt_ctf_field_type_string
*string
=
1543 g_new0(struct bt_ctf_field_type_string
, 1);
1549 string
->parent
.declaration
= &string
->declaration
.p
;
1550 string
->parent
.declaration
->id
= CTF_TYPE_STRING
;
1551 bt_ctf_field_type_init(&string
->parent
);
1552 string
->declaration
.encoding
= CTF_STRING_UTF8
;
1553 string
->parent
.declaration
->alignment
= CHAR_BIT
;
1554 return &string
->parent
;
1557 enum ctf_string_encoding
bt_ctf_field_type_string_get_encoding(
1558 struct bt_ctf_field_type
*type
)
1560 struct bt_ctf_field_type_string
*string
;
1561 enum ctf_string_encoding ret
= CTF_STRING_UNKNOWN
;
1563 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_STRING
)) {
1567 string
= container_of(type
, struct bt_ctf_field_type_string
,
1569 ret
= string
->declaration
.encoding
;
1574 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type
*type
,
1575 enum ctf_string_encoding encoding
)
1578 struct bt_ctf_field_type_string
*string
;
1580 if (!type
|| type
->declaration
->id
!= CTF_TYPE_STRING
||
1581 (encoding
!= CTF_STRING_UTF8
&&
1582 encoding
!= CTF_STRING_ASCII
)) {
1587 string
= container_of(type
, struct bt_ctf_field_type_string
, parent
);
1588 string
->declaration
.encoding
= encoding
;
1593 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type
*type
)
1602 ret
= (int) type
->declaration
->alignment
;
1607 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type
*type
,
1608 unsigned int alignment
)
1612 /* Alignment must be bit-aligned (1) or byte aligned */
1613 if (!type
|| type
->frozen
|| (alignment
!= 1 && (alignment
& 0x7))) {
1618 if (type
->declaration
->id
== CTF_TYPE_STRING
&&
1619 alignment
!= CHAR_BIT
) {
1624 type
->declaration
->alignment
= alignment
;
1630 enum bt_ctf_byte_order
bt_ctf_field_type_get_byte_order(
1631 struct bt_ctf_field_type
*type
)
1633 enum bt_ctf_byte_order ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1634 int internal_byte_order
= -1;
1640 switch (type
->declaration
->id
) {
1641 case CTF_TYPE_INTEGER
:
1643 struct bt_ctf_field_type_integer
*integer
= container_of(
1644 type
, struct bt_ctf_field_type_integer
, parent
);
1645 internal_byte_order
= integer
->declaration
.byte_order
;
1648 case CTF_TYPE_FLOAT
:
1650 struct bt_ctf_field_type_floating_point
*floating_point
=
1652 struct bt_ctf_field_type_floating_point
,
1654 internal_byte_order
= floating_point
->declaration
.byte_order
;
1661 switch (internal_byte_order
) {
1663 ret
= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
;
1666 ret
= BT_CTF_BYTE_ORDER_BIG_ENDIAN
;
1669 ret
= BT_CTF_BYTE_ORDER_NATIVE
;
1672 ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1678 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type
*type
,
1679 enum bt_ctf_byte_order byte_order
)
1682 int internal_byte_order
;
1683 enum ctf_type_id type_id
;
1685 if (!type
|| type
->frozen
) {
1690 type_id
= type
->declaration
->id
;
1691 switch (byte_order
) {
1692 case BT_CTF_BYTE_ORDER_NATIVE
:
1693 /* Leave unset. Will be initialized by parent. */
1694 internal_byte_order
= 0;
1696 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
1697 internal_byte_order
= LITTLE_ENDIAN
;
1699 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
1700 case BT_CTF_BYTE_ORDER_NETWORK
:
1701 internal_byte_order
= BIG_ENDIAN
;
1708 if (set_byte_order_funcs
[type_id
]) {
1709 set_byte_order_funcs
[type_id
](type
, internal_byte_order
, 0);
1715 enum ctf_type_id
bt_ctf_field_type_get_type_id(
1716 struct bt_ctf_field_type
*type
)
1719 return CTF_TYPE_UNKNOWN
;
1722 return type
->declaration
->id
;
1725 const char *bt_ctf_field_type_get_alias_name(
1726 struct bt_ctf_field_type
*type
)
1728 const char *name
= NULL
;
1730 if (!type
|| !type
->alias_name
) {
1734 name
= type
->alias_name
->str
;
1739 void bt_ctf_field_type_get(struct bt_ctf_field_type
*type
)
1745 bt_ctf_ref_get(&type
->ref_count
);
1748 void bt_ctf_field_type_put(struct bt_ctf_field_type
*type
)
1754 bt_ctf_ref_put(&type
->ref_count
, bt_ctf_field_type_destroy
);
1758 void bt_ctf_field_type_freeze(struct bt_ctf_field_type
*type
)
1768 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_signed(
1769 struct bt_ctf_field_type_variant
*variant
,
1772 struct bt_ctf_field_type
*type
= NULL
;
1773 GQuark field_name_quark
;
1775 struct structure_field
*field_entry
;
1776 struct range_overlap_query query
= {
1777 .range_start
._signed
= tag_value
,
1778 .range_end
._signed
= tag_value
,
1779 .mapping_name
= 0, .overlaps
= 0};
1781 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
1783 if (!query
.overlaps
) {
1787 field_name_quark
= query
.mapping_name
;
1788 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1789 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
1793 field_entry
= g_ptr_array_index(variant
->fields
, (size_t) index
);
1794 type
= field_entry
->type
;
1800 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_unsigned(
1801 struct bt_ctf_field_type_variant
*variant
,
1804 struct bt_ctf_field_type
*type
= NULL
;
1805 GQuark field_name_quark
;
1807 struct structure_field
*field_entry
;
1808 struct range_overlap_query query
= {
1809 .range_start
._unsigned
= tag_value
,
1810 .range_end
._unsigned
= tag_value
,
1811 .mapping_name
= 0, .overlaps
= 0};
1813 g_ptr_array_foreach(variant
->tag
->entries
,
1814 check_ranges_overlap_unsigned
,
1816 if (!query
.overlaps
) {
1820 field_name_quark
= query
.mapping_name
;
1821 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1822 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
1826 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
1827 type
= field_entry
->type
;
1833 int bt_ctf_field_type_serialize(struct bt_ctf_field_type
*type
,
1834 struct metadata_context
*context
)
1838 if (!type
|| !context
) {
1843 ret
= type
->serialize(type
, context
);
1849 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type
*type
,
1856 assert(byte_order
== LITTLE_ENDIAN
|| byte_order
== BIG_ENDIAN
);
1857 if (set_byte_order_funcs
[type
->declaration
->id
]) {
1858 set_byte_order_funcs
[type
->declaration
->id
](type
,
1864 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*ref
)
1866 struct bt_ctf_field_type_integer
*integer
;
1872 integer
= container_of(
1873 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1874 struct bt_ctf_field_type_integer
, parent
);
1875 bt_ctf_clock_put(integer
->mapped_clock
);
1880 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*ref
)
1882 struct bt_ctf_field_type_enumeration
*enumeration
;
1888 enumeration
= container_of(
1889 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1890 struct bt_ctf_field_type_enumeration
, parent
);
1891 g_ptr_array_free(enumeration
->entries
, TRUE
);
1892 bt_ctf_field_type_put(enumeration
->container
);
1893 g_free(enumeration
);
1897 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*ref
)
1899 struct bt_ctf_field_type_floating_point
*floating_point
;
1905 floating_point
= container_of(
1906 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1907 struct bt_ctf_field_type_floating_point
, parent
);
1908 g_free(floating_point
);
1912 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*ref
)
1914 struct bt_ctf_field_type_structure
*structure
;
1920 structure
= container_of(
1921 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1922 struct bt_ctf_field_type_structure
, parent
);
1923 g_ptr_array_free(structure
->fields
, TRUE
);
1924 g_hash_table_destroy(structure
->field_name_to_index
);
1929 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*ref
)
1931 struct bt_ctf_field_type_variant
*variant
;
1937 variant
= container_of(
1938 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1939 struct bt_ctf_field_type_variant
, parent
);
1940 g_ptr_array_free(variant
->fields
, TRUE
);
1941 g_hash_table_destroy(variant
->field_name_to_index
);
1942 g_string_free(variant
->tag_name
, TRUE
);
1943 bt_ctf_field_type_put(&variant
->tag
->parent
);
1948 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*ref
)
1950 struct bt_ctf_field_type_array
*array
;
1956 array
= container_of(
1957 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1958 struct bt_ctf_field_type_array
, parent
);
1959 bt_ctf_field_type_put(array
->element_type
);
1964 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*ref
)
1966 struct bt_ctf_field_type_sequence
*sequence
;
1972 sequence
= container_of(
1973 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1974 struct bt_ctf_field_type_sequence
, parent
);
1975 bt_ctf_field_type_put(sequence
->element_type
);
1976 g_string_free(sequence
->length_field_name
, TRUE
);
1981 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*ref
)
1983 struct bt_ctf_field_type_string
*string
;
1989 string
= container_of(
1990 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1991 struct bt_ctf_field_type_string
, parent
);
1996 void generic_field_type_freeze(struct bt_ctf_field_type
*type
)
2002 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*type
)
2004 struct bt_ctf_field_type_enumeration
*enumeration_type
= container_of(
2005 type
, struct bt_ctf_field_type_enumeration
, parent
);
2007 generic_field_type_freeze(type
);
2008 bt_ctf_field_type_freeze(enumeration_type
->container
);
2012 void freeze_structure_field(struct structure_field
*field
)
2014 bt_ctf_field_type_freeze(field
->type
);
2018 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*type
)
2020 struct bt_ctf_field_type_structure
*structure_type
= container_of(
2021 type
, struct bt_ctf_field_type_structure
, parent
);
2023 generic_field_type_freeze(type
);
2024 g_ptr_array_foreach(structure_type
->fields
, (GFunc
)freeze_structure_field
,
2029 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*type
)
2031 struct bt_ctf_field_type_variant
*variant_type
= container_of(
2032 type
, struct bt_ctf_field_type_variant
, parent
);
2034 generic_field_type_freeze(type
);
2035 g_ptr_array_foreach(variant_type
->fields
, (GFunc
)freeze_structure_field
,
2040 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*type
)
2042 struct bt_ctf_field_type_array
*array_type
= container_of(
2043 type
, struct bt_ctf_field_type_array
, parent
);
2045 generic_field_type_freeze(type
);
2046 bt_ctf_field_type_freeze(array_type
->element_type
);
2050 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*type
)
2052 struct bt_ctf_field_type_sequence
*sequence_type
= container_of(
2053 type
, struct bt_ctf_field_type_sequence
, parent
);
2055 generic_field_type_freeze(type
);
2056 bt_ctf_field_type_freeze(sequence_type
->element_type
);
2060 const char *get_encoding_string(enum ctf_string_encoding encoding
)
2062 const char *encoding_string
;
2065 case CTF_STRING_NONE
:
2066 encoding_string
= "none";
2068 case CTF_STRING_ASCII
:
2069 encoding_string
= "ASCII";
2071 case CTF_STRING_UTF8
:
2072 encoding_string
= "UTF8";
2075 encoding_string
= "unknown";
2079 return encoding_string
;
2083 const char *get_integer_base_string(enum bt_ctf_integer_base base
)
2085 const char *base_string
;
2088 case BT_CTF_INTEGER_BASE_DECIMAL
:
2089 base_string
= "decimal";
2091 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
2092 base_string
= "hexadecimal";
2094 case BT_CTF_INTEGER_BASE_OCTAL
:
2095 base_string
= "octal";
2097 case BT_CTF_INTEGER_BASE_BINARY
:
2098 base_string
= "binary";
2101 base_string
= "unknown";
2109 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*type
,
2110 struct metadata_context
*context
)
2112 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
2113 struct bt_ctf_field_type_integer
, parent
);
2116 g_string_append_printf(context
->string
,
2117 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2118 integer
->declaration
.len
, type
->declaration
->alignment
,
2119 (integer
->declaration
.signedness
? "true" : "false"),
2120 get_encoding_string(integer
->declaration
.encoding
),
2121 get_integer_base_string(integer
->declaration
.base
),
2122 get_byte_order_string(integer
->declaration
.byte_order
));
2123 if (integer
->mapped_clock
) {
2124 const char *clock_name
= bt_ctf_clock_get_name(
2125 integer
->mapped_clock
);
2132 g_string_append_printf(context
->string
,
2133 ", map = clock.%s.value", clock_name
);
2136 g_string_append(context
->string
, "; }");
2142 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*type
,
2143 struct metadata_context
*context
)
2147 struct bt_ctf_field_type_enumeration
*enumeration
= container_of(type
,
2148 struct bt_ctf_field_type_enumeration
, parent
);
2149 struct bt_ctf_field_type
*container_type
;
2150 int container_signed
;
2152 ret
= bt_ctf_field_type_validate(type
);
2157 container_type
= bt_ctf_field_type_enumeration_get_container_type(type
);
2158 if (!container_type
) {
2163 container_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
2164 if (container_signed
< 0) {
2165 ret
= container_signed
;
2166 goto error_put_container_type
;
2169 g_string_append(context
->string
, "enum : ");
2170 ret
= bt_ctf_field_type_serialize(enumeration
->container
, context
);
2172 goto error_put_container_type
;
2175 g_string_append(context
->string
, " { ");
2176 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
2177 struct enumeration_mapping
*mapping
=
2178 enumeration
->entries
->pdata
[entry
];
2180 if (container_signed
) {
2181 if (mapping
->range_start
._signed
==
2182 mapping
->range_end
._signed
) {
2183 g_string_append_printf(context
->string
,
2184 "\"%s\" = %" PRId64
,
2185 g_quark_to_string(mapping
->string
),
2186 mapping
->range_start
._signed
);
2188 g_string_append_printf(context
->string
,
2189 "\"%s\" = %" PRId64
" ... %" PRId64
,
2190 g_quark_to_string(mapping
->string
),
2191 mapping
->range_start
._signed
,
2192 mapping
->range_end
._signed
);
2195 if (mapping
->range_start
._unsigned
==
2196 mapping
->range_end
._unsigned
) {
2197 g_string_append_printf(context
->string
,
2198 "\"%s\" = %" PRIu64
,
2199 g_quark_to_string(mapping
->string
),
2200 mapping
->range_start
._unsigned
);
2202 g_string_append_printf(context
->string
,
2203 "\"%s\" = %" PRIu64
" ... %" PRIu64
,
2204 g_quark_to_string(mapping
->string
),
2205 mapping
->range_start
._unsigned
,
2206 mapping
->range_end
._unsigned
);
2210 g_string_append(context
->string
,
2211 ((entry
!= (enumeration
->entries
->len
- 1)) ?
2215 if (context
->field_name
->len
) {
2216 g_string_append_printf(context
->string
, " %s",
2217 context
->field_name
->str
);
2218 g_string_assign(context
->field_name
, "");
2220 error_put_container_type
:
2221 bt_ctf_field_type_put(container_type
);
2227 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type
*type
,
2228 struct metadata_context
*context
)
2230 struct bt_ctf_field_type_floating_point
*floating_point
= container_of(
2231 type
, struct bt_ctf_field_type_floating_point
, parent
);
2233 g_string_append_printf(context
->string
,
2234 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2235 floating_point
->declaration
.exp
->len
,
2236 floating_point
->declaration
.mantissa
->len
+ 1,
2237 get_byte_order_string(floating_point
->declaration
.byte_order
),
2238 type
->declaration
->alignment
);
2243 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*type
,
2244 struct metadata_context
*context
)
2247 unsigned int indent
;
2249 struct bt_ctf_field_type_structure
*structure
= container_of(type
,
2250 struct bt_ctf_field_type_structure
, parent
);
2251 GString
*structure_field_name
= context
->field_name
;
2253 context
->field_name
= g_string_new("");
2255 context
->current_indentation_level
++;
2256 g_string_append(context
->string
, "struct {\n");
2258 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2259 struct structure_field
*field
;
2261 for (indent
= 0; indent
< context
->current_indentation_level
;
2263 g_string_append_c(context
->string
, '\t');
2266 field
= structure
->fields
->pdata
[i
];
2267 g_string_assign(context
->field_name
,
2268 g_quark_to_string(field
->name
));
2269 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
2274 if (context
->field_name
->len
) {
2275 g_string_append_printf(context
->string
, " %s",
2276 context
->field_name
->str
);
2278 g_string_append(context
->string
, ";\n");
2281 context
->current_indentation_level
--;
2282 for (indent
= 0; indent
< context
->current_indentation_level
;
2284 g_string_append_c(context
->string
, '\t');
2287 g_string_append_printf(context
->string
, "} align(%zu)",
2288 type
->declaration
->alignment
);
2290 g_string_free(context
->field_name
, TRUE
);
2291 context
->field_name
= structure_field_name
;
2296 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*type
,
2297 struct metadata_context
*context
)
2300 unsigned int indent
;
2302 struct bt_ctf_field_type_variant
*variant
= container_of(
2303 type
, struct bt_ctf_field_type_variant
, parent
);
2304 GString
*variant_field_name
= context
->field_name
;
2306 context
->field_name
= g_string_new("");
2307 g_string_append_printf(context
->string
,
2308 "variant <%s> {\n", variant
->tag_name
->str
);
2309 context
->current_indentation_level
++;
2310 for (i
= 0; i
< variant
->fields
->len
; i
++) {
2311 struct structure_field
*field
= variant
->fields
->pdata
[i
];
2313 g_string_assign(context
->field_name
,
2314 g_quark_to_string(field
->name
));
2315 for (indent
= 0; indent
< context
->current_indentation_level
;
2317 g_string_append_c(context
->string
, '\t');
2320 g_string_assign(context
->field_name
,
2321 g_quark_to_string(field
->name
));
2322 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
2327 if (context
->field_name
->len
) {
2328 g_string_append_printf(context
->string
, " %s;",
2329 context
->field_name
->str
);
2332 g_string_append_c(context
->string
, '\n');
2335 context
->current_indentation_level
--;
2336 for (indent
= 0; indent
< context
->current_indentation_level
;
2338 g_string_append_c(context
->string
, '\t');
2341 g_string_append(context
->string
, "}");
2343 g_string_free(context
->field_name
, TRUE
);
2344 context
->field_name
= variant_field_name
;
2349 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*type
,
2350 struct metadata_context
*context
)
2353 struct bt_ctf_field_type_array
*array
= container_of(type
,
2354 struct bt_ctf_field_type_array
, parent
);
2356 ret
= bt_ctf_field_type_serialize(array
->element_type
, context
);
2361 if (context
->field_name
->len
) {
2362 g_string_append_printf(context
->string
, " %s[%u]",
2363 context
->field_name
->str
, array
->length
);
2364 g_string_assign(context
->field_name
, "");
2366 g_string_append_printf(context
->string
, "[%u]", array
->length
);
2373 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*type
,
2374 struct metadata_context
*context
)
2377 struct bt_ctf_field_type_sequence
*sequence
= container_of(
2378 type
, struct bt_ctf_field_type_sequence
, parent
);
2380 ret
= bt_ctf_field_type_serialize(sequence
->element_type
, context
);
2385 if (context
->field_name
->len
) {
2386 g_string_append_printf(context
->string
, " %s[%s]",
2387 context
->field_name
->str
,
2388 sequence
->length_field_name
->str
);
2389 g_string_assign(context
->field_name
, "");
2391 g_string_append_printf(context
->string
, "[%s]",
2392 sequence
->length_field_name
->str
);
2399 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*type
,
2400 struct metadata_context
*context
)
2402 struct bt_ctf_field_type_string
*string
= container_of(
2403 type
, struct bt_ctf_field_type_string
, parent
);
2405 g_string_append_printf(context
->string
,
2406 "string { encoding = %s; }",
2407 get_encoding_string(string
->declaration
.encoding
));
2412 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*type
,
2413 int byte_order
, int set_native
)
2415 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
2416 struct bt_ctf_field_type_integer
, parent
);
2419 integer_type
->declaration
.byte_order
=
2420 integer_type
->declaration
.byte_order
== 0 ?
2421 byte_order
: integer_type
->declaration
.byte_order
;
2423 integer_type
->declaration
.byte_order
= byte_order
;
2428 void bt_ctf_field_type_enumeration_set_byte_order(
2429 struct bt_ctf_field_type
*type
, int byte_order
, int set_native
)
2431 struct bt_ctf_field_type_enumeration
*enum_type
= container_of(type
,
2432 struct bt_ctf_field_type_enumeration
, parent
);
2434 /* Safe to assume that container is an integer */
2435 bt_ctf_field_type_integer_set_byte_order(enum_type
->container
,
2436 byte_order
, set_native
);
2440 void bt_ctf_field_type_floating_point_set_byte_order(
2441 struct bt_ctf_field_type
*type
, int byte_order
, int set_native
)
2443 struct bt_ctf_field_type_floating_point
*floating_point_type
=
2444 container_of(type
, struct bt_ctf_field_type_floating_point
,
2448 floating_point_type
->declaration
.byte_order
=
2449 floating_point_type
->declaration
.byte_order
== 0 ?
2451 floating_point_type
->declaration
.byte_order
;
2452 floating_point_type
->sign
.byte_order
=
2453 floating_point_type
->sign
.byte_order
== 0 ?
2454 byte_order
: floating_point_type
->sign
.byte_order
;
2455 floating_point_type
->mantissa
.byte_order
=
2456 floating_point_type
->mantissa
.byte_order
== 0 ?
2457 byte_order
: floating_point_type
->mantissa
.byte_order
;
2458 floating_point_type
->exp
.byte_order
=
2459 floating_point_type
->exp
.byte_order
== 0 ?
2460 byte_order
: floating_point_type
->exp
.byte_order
;
2462 floating_point_type
->declaration
.byte_order
= byte_order
;
2463 floating_point_type
->sign
.byte_order
= byte_order
;
2464 floating_point_type
->mantissa
.byte_order
= byte_order
;
2465 floating_point_type
->exp
.byte_order
= byte_order
;
2470 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*type
,
2471 int byte_order
, int set_native
)
2474 struct bt_ctf_field_type_structure
*structure_type
=
2475 container_of(type
, struct bt_ctf_field_type_structure
,
2478 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
2479 struct structure_field
*field
= g_ptr_array_index(
2480 structure_type
->fields
, i
);
2481 struct bt_ctf_field_type
*field_type
= field
->type
;
2483 if (set_byte_order_funcs
[field_type
->declaration
->id
]) {
2484 set_byte_order_funcs
[field_type
->declaration
->id
](
2485 field_type
, byte_order
, set_native
);
2491 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*type
,
2492 int byte_order
, int set_native
)
2495 struct bt_ctf_field_type_variant
*variant_type
=
2496 container_of(type
, struct bt_ctf_field_type_variant
,
2499 for (i
= 0; i
< variant_type
->fields
->len
; i
++) {
2500 struct structure_field
*field
= g_ptr_array_index(
2501 variant_type
->fields
, i
);
2502 struct bt_ctf_field_type
*field_type
= field
->type
;
2504 if (set_byte_order_funcs
[field_type
->declaration
->id
]) {
2505 set_byte_order_funcs
[field_type
->declaration
->id
](
2506 field_type
, byte_order
, set_native
);
2512 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*type
,
2513 int byte_order
, int set_native
)
2515 struct bt_ctf_field_type_array
*array_type
=
2516 container_of(type
, struct bt_ctf_field_type_array
,
2519 if (set_byte_order_funcs
[array_type
->element_type
->declaration
->id
]) {
2520 set_byte_order_funcs
[array_type
->element_type
->declaration
->id
](
2521 array_type
->element_type
, byte_order
, set_native
);
2526 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*type
,
2527 int byte_order
, int set_native
)
2529 struct bt_ctf_field_type_sequence
*sequence_type
=
2530 container_of(type
, struct bt_ctf_field_type_sequence
,
2533 if (set_byte_order_funcs
[
2534 sequence_type
->element_type
->declaration
->id
]) {
2535 set_byte_order_funcs
[
2536 sequence_type
->element_type
->declaration
->id
](
2537 sequence_type
->element_type
, byte_order
, set_native
);