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-ir/field-types-internal.h>
30 #include <babeltrace/ctf-ir/field-path-internal.h>
31 #include <babeltrace/ctf-ir/utils.h>
32 #include <babeltrace/ref.h>
33 #include <babeltrace/ctf-ir/clock-class.h>
34 #include <babeltrace/ctf-ir/clock-class-internal.h>
35 #include <babeltrace/ctf-writer/writer-internal.h>
36 #include <babeltrace/object-internal.h>
37 #include <babeltrace/ref.h>
38 #include <babeltrace/compiler.h>
39 #include <babeltrace/endian.h>
44 struct range_overlap_query
{
59 void bt_ctf_field_type_destroy(struct bt_object
*);
61 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type
*);
63 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type
*);
65 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type
*);
67 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type
*);
69 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type
*);
71 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type
*);
73 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type
*);
75 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type
*);
78 void (* const type_destroy_funcs
[])(struct bt_ctf_field_type
*) = {
79 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_destroy
,
80 [BT_CTF_TYPE_ID_ENUM
] =
81 bt_ctf_field_type_enumeration_destroy
,
82 [BT_CTF_TYPE_ID_FLOAT
] =
83 bt_ctf_field_type_floating_point_destroy
,
84 [BT_CTF_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_destroy
,
85 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_destroy
,
86 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_destroy
,
87 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_destroy
,
88 [BT_CTF_TYPE_ID_STRING
] = bt_ctf_field_type_string_destroy
,
92 void generic_field_type_freeze(struct bt_ctf_field_type
*);
94 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type
*);
96 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*);
98 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*);
100 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*);
102 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*);
104 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*);
107 type_freeze_func
const type_freeze_funcs
[] = {
108 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_freeze
,
109 [BT_CTF_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_freeze
,
110 [BT_CTF_TYPE_ID_FLOAT
] = generic_field_type_freeze
,
111 [BT_CTF_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_freeze
,
112 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_freeze
,
113 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_freeze
,
114 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_freeze
,
115 [BT_CTF_TYPE_ID_STRING
] = generic_field_type_freeze
,
119 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*,
120 struct metadata_context
*);
122 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*,
123 struct metadata_context
*);
125 int bt_ctf_field_type_floating_point_serialize(
126 struct bt_ctf_field_type
*, struct metadata_context
*);
128 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*,
129 struct metadata_context
*);
131 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*,
132 struct metadata_context
*);
134 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*,
135 struct metadata_context
*);
137 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*,
138 struct metadata_context
*);
140 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*,
141 struct metadata_context
*);
144 type_serialize_func
const type_serialize_funcs
[] = {
145 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_serialize
,
146 [BT_CTF_TYPE_ID_ENUM
] =
147 bt_ctf_field_type_enumeration_serialize
,
148 [BT_CTF_TYPE_ID_FLOAT
] =
149 bt_ctf_field_type_floating_point_serialize
,
150 [BT_CTF_TYPE_ID_STRUCT
] =
151 bt_ctf_field_type_structure_serialize
,
152 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_serialize
,
153 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_serialize
,
154 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_serialize
,
155 [BT_CTF_TYPE_ID_STRING
] = bt_ctf_field_type_string_serialize
,
159 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*,
160 int byte_order
, int set_native
);
162 void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type
*,
163 int byte_order
, int set_native
);
165 void bt_ctf_field_type_floating_point_set_byte_order(
166 struct bt_ctf_field_type
*, int byte_order
, int set_native
);
168 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*,
169 int byte_order
, int set_native
);
171 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*,
172 int byte_order
, int set_native
);
174 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*,
175 int byte_order
, int set_native
);
177 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*,
178 int byte_order
, int set_native
);
180 /* The set_native flag only set the byte order if it is set to native */
182 void (* const set_byte_order_funcs
[])(struct bt_ctf_field_type
*,
183 int byte_order
, int set_native
) = {
184 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_set_byte_order
,
185 [BT_CTF_TYPE_ID_ENUM
] =
186 bt_ctf_field_type_enumeration_set_byte_order
,
187 [BT_CTF_TYPE_ID_FLOAT
] =
188 bt_ctf_field_type_floating_point_set_byte_order
,
189 [BT_CTF_TYPE_ID_STRUCT
] =
190 bt_ctf_field_type_structure_set_byte_order
,
191 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_set_byte_order
,
192 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_set_byte_order
,
193 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_set_byte_order
,
194 [BT_CTF_TYPE_ID_STRING
] = NULL
,
198 struct bt_ctf_field_type
*bt_ctf_field_type_integer_copy(
199 struct bt_ctf_field_type
*);
201 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_copy(
202 struct bt_ctf_field_type
*);
204 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_copy(
205 struct bt_ctf_field_type
*);
207 struct bt_ctf_field_type
*bt_ctf_field_type_structure_copy(
208 struct bt_ctf_field_type
*);
210 struct bt_ctf_field_type
*bt_ctf_field_type_variant_copy(
211 struct bt_ctf_field_type
*);
213 struct bt_ctf_field_type
*bt_ctf_field_type_array_copy(
214 struct bt_ctf_field_type
*);
216 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_copy(
217 struct bt_ctf_field_type
*);
219 struct bt_ctf_field_type
*bt_ctf_field_type_string_copy(
220 struct bt_ctf_field_type
*);
223 struct bt_ctf_field_type
*(* const type_copy_funcs
[])(
224 struct bt_ctf_field_type
*) = {
225 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_copy
,
226 [BT_CTF_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_copy
,
227 [BT_CTF_TYPE_ID_FLOAT
] = bt_ctf_field_type_floating_point_copy
,
228 [BT_CTF_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_copy
,
229 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_copy
,
230 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_copy
,
231 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_copy
,
232 [BT_CTF_TYPE_ID_STRING
] = bt_ctf_field_type_string_copy
,
236 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type
*,
237 struct bt_ctf_field_type
*);
239 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type
*,
240 struct bt_ctf_field_type
*);
242 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type
*,
243 struct bt_ctf_field_type
*);
245 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type
*,
246 struct bt_ctf_field_type
*);
248 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type
*,
249 struct bt_ctf_field_type
*);
251 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type
*,
252 struct bt_ctf_field_type
*);
254 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type
*,
255 struct bt_ctf_field_type
*);
257 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type
*,
258 struct bt_ctf_field_type
*);
261 int (* const type_compare_funcs
[])(struct bt_ctf_field_type
*,
262 struct bt_ctf_field_type
*) = {
263 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_compare
,
264 [BT_CTF_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_compare
,
265 [BT_CTF_TYPE_ID_FLOAT
] = bt_ctf_field_type_floating_point_compare
,
266 [BT_CTF_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_compare
,
267 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_compare
,
268 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_compare
,
269 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_compare
,
270 [BT_CTF_TYPE_ID_STRING
] = bt_ctf_field_type_string_compare
,
274 int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type
*);
276 int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type
*);
278 int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type
*);
280 int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type
*);
282 int bt_ctf_field_type_array_validate(struct bt_ctf_field_type
*);
284 int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type
*);
287 int (* const type_validate_funcs
[])(struct bt_ctf_field_type
*) = {
288 [BT_CTF_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_validate
,
289 [BT_CTF_TYPE_ID_FLOAT
] = NULL
,
290 [BT_CTF_TYPE_ID_STRING
] = NULL
,
291 [BT_CTF_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_validate
,
292 [BT_CTF_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_validate
,
293 [BT_CTF_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_validate
,
294 [BT_CTF_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_validate
,
295 [BT_CTF_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_validate
,
299 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
305 void destroy_structure_field(struct structure_field
*field
)
312 void check_ranges_overlap(gpointer element
, gpointer query
)
314 struct enumeration_mapping
*mapping
= element
;
315 struct range_overlap_query
*overlap_query
= query
;
317 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
318 && overlap_query
->range_start
._signed
<=
319 mapping
->range_end
._signed
) {
320 overlap_query
->overlaps
= 1;
321 overlap_query
->mapping_name
= mapping
->string
;
324 overlap_query
->overlaps
|=
325 mapping
->string
== overlap_query
->mapping_name
;
329 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
331 struct enumeration_mapping
*mapping
= element
;
332 struct range_overlap_query
*overlap_query
= query
;
334 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
335 && overlap_query
->range_start
._unsigned
<=
336 mapping
->range_end
._unsigned
) {
337 overlap_query
->overlaps
= 1;
338 overlap_query
->mapping_name
= mapping
->string
;
341 overlap_query
->overlaps
|=
342 mapping
->string
== overlap_query
->mapping_name
;
346 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
347 struct enumeration_mapping
**b
)
349 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
353 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
354 struct enumeration_mapping
**b
)
356 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
360 void bt_ctf_field_type_init(struct bt_ctf_field_type
*type
, int init_bo
)
362 enum bt_ctf_type_id type_id
= type
->declaration
->id
;
364 assert(type
&& (type_id
> BT_CTF_TYPE_ID_UNKNOWN
) &&
365 (type_id
< BT_CTF_NR_TYPE_IDS
));
367 bt_object_init(type
, bt_ctf_field_type_destroy
);
368 type
->freeze
= type_freeze_funcs
[type_id
];
369 type
->serialize
= type_serialize_funcs
[type_id
];
372 int ret
= bt_ctf_field_type_set_byte_order(type
,
373 BT_CTF_BYTE_ORDER_NATIVE
);
377 type
->declaration
->alignment
= 1;
381 int add_structure_field(GPtrArray
*fields
,
382 GHashTable
*field_name_to_index
,
383 struct bt_ctf_field_type
*field_type
,
384 const char *field_name
)
387 GQuark name_quark
= g_quark_from_string(field_name
);
388 struct structure_field
*field
;
390 /* Make sure structure does not contain a field of the same name */
391 if (g_hash_table_lookup_extended(field_name_to_index
,
392 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
397 field
= g_new0(struct structure_field
, 1);
404 field
->name
= name_quark
;
405 field
->type
= field_type
;
406 g_hash_table_insert(field_name_to_index
,
407 GUINT_TO_POINTER(name_quark
),
408 GUINT_TO_POINTER(fields
->len
));
409 g_ptr_array_add(fields
, field
);
415 void bt_ctf_field_type_destroy(struct bt_object
*obj
)
417 struct bt_ctf_field_type
*type
;
418 enum bt_ctf_type_id type_id
;
420 type
= container_of(obj
, struct bt_ctf_field_type
, base
);
421 type_id
= type
->declaration
->id
;
422 if (type_id
<= BT_CTF_TYPE_ID_UNKNOWN
||
423 type_id
>= BT_CTF_NR_TYPE_IDS
) {
427 type_destroy_funcs
[type_id
](type
);
431 int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type
*type
)
435 struct bt_ctf_field_type_integer
*integer
=
436 container_of(type
, struct bt_ctf_field_type_integer
,
439 if (integer
->mapped_clock
&& integer
->declaration
.signedness
) {
449 int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type
*type
)
453 struct bt_ctf_field_type_enumeration
*enumeration
=
454 container_of(type
, struct bt_ctf_field_type_enumeration
,
456 struct bt_ctf_field_type
*container_type
=
457 bt_ctf_field_type_enumeration_get_container_type(type
);
459 if (!container_type
) {
464 ret
= bt_ctf_field_type_validate(container_type
);
469 /* Ensure enum has entries */
470 ret
= enumeration
->entries
->len
? 0 : -1;
473 BT_PUT(container_type
);
478 int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type
*type
)
481 struct bt_ctf_field_type
*element_type
= NULL
;
482 struct bt_ctf_field_type_sequence
*sequence
=
483 container_of(type
, struct bt_ctf_field_type_sequence
,
486 /* Length field name should be set at this point */
487 if (sequence
->length_field_name
->len
== 0) {
492 element_type
= bt_ctf_field_type_sequence_get_element_type(type
);
498 ret
= bt_ctf_field_type_validate(element_type
);
501 BT_PUT(element_type
);
507 int bt_ctf_field_type_array_validate(struct bt_ctf_field_type
*type
)
510 struct bt_ctf_field_type
*element_type
= NULL
;
512 element_type
= bt_ctf_field_type_array_get_element_type(type
);
518 ret
= bt_ctf_field_type_validate(element_type
);
521 BT_PUT(element_type
);
527 int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type
*type
)
530 struct bt_ctf_field_type
*child_type
= NULL
;
531 int field_count
= bt_ctf_field_type_structure_get_field_count(type
);
534 if (field_count
< 0) {
539 for (i
= 0; i
< field_count
; ++i
) {
540 ret
= bt_ctf_field_type_structure_get_field(type
,
541 NULL
, &child_type
, i
);
546 ret
= bt_ctf_field_type_validate(child_type
);
561 int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type
*type
)
565 struct bt_ctf_field_type
*child_type
= NULL
;
566 struct bt_ctf_field_type_variant
*variant
=
567 container_of(type
, struct bt_ctf_field_type_variant
,
570 int tag_mappings_count
;
572 if (variant
->tag_name
->len
== 0 || !variant
->tag
) {
578 bt_ctf_field_type_enumeration_get_mapping_count(
579 (struct bt_ctf_field_type
*) variant
->tag
);
581 if (tag_mappings_count
!= variant
->fields
->len
) {
586 for (i
= 0; i
< tag_mappings_count
; ++i
) {
588 int64_t range_start
, range_end
;
589 struct bt_ctf_field_type
*ft
;
591 ret
= bt_ctf_field_type_enumeration_get_mapping(
592 (struct bt_ctf_field_type
*) variant
->tag
,
593 i
, &label
, &range_start
, &range_end
);
602 ft
= bt_ctf_field_type_variant_get_field_type_by_name(
612 field_count
= bt_ctf_field_type_variant_get_field_count(type
);
613 if (field_count
< 0) {
618 for (i
= 0; i
< field_count
; ++i
) {
619 ret
= bt_ctf_field_type_variant_get_field(type
,
620 NULL
, &child_type
, i
);
625 ret
= bt_ctf_field_type_validate(child_type
);
640 * This function validates a given field type without considering
641 * where this field type is located. It only validates the properties
642 * of the given field type and the properties of its children if
646 int bt_ctf_field_type_validate(struct bt_ctf_field_type
*type
)
649 enum bt_ctf_type_id id
= bt_ctf_field_type_get_type_id(type
);
657 /* Already marked as valid */
661 if (type_validate_funcs
[id
]) {
662 ret
= type_validate_funcs
[id
](type
);
665 if (!ret
&& type
->frozen
) {
666 /* Field type is valid */
674 struct bt_ctf_field_type
*bt_ctf_field_type_integer_create(unsigned int size
)
676 struct bt_ctf_field_type_integer
*integer
=
677 g_new0(struct bt_ctf_field_type_integer
, 1);
679 if (!integer
|| size
== 0 || size
> 64) {
683 integer
->parent
.declaration
= &integer
->declaration
.p
;
684 integer
->parent
.declaration
->id
= BT_CTF_TYPE_ID_INTEGER
;
685 integer
->declaration
.len
= size
;
686 integer
->declaration
.base
= BT_CTF_INTEGER_BASE_DECIMAL
;
687 integer
->declaration
.encoding
= BT_CTF_STRING_ENCODING_NONE
;
688 bt_ctf_field_type_init(&integer
->parent
, TRUE
);
689 return &integer
->parent
;
692 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type
*type
)
695 struct bt_ctf_field_type_integer
*integer
;
697 if (!type
|| type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
702 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
703 ret
= (int) integer
->declaration
.len
;
708 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type
*type
)
711 struct bt_ctf_field_type_integer
*integer
;
713 if (!type
|| type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
718 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
719 ret
= integer
->declaration
.signedness
;
724 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type
*type
,
728 struct bt_ctf_field_type_integer
*integer
;
730 if (!type
|| type
->frozen
||
731 type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
736 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
737 integer
->declaration
.signedness
= !!is_signed
;
742 enum bt_ctf_integer_base
bt_ctf_field_type_integer_get_base(
743 struct bt_ctf_field_type
*type
)
745 enum bt_ctf_integer_base ret
= BT_CTF_INTEGER_BASE_UNKNOWN
;
746 struct bt_ctf_field_type_integer
*integer
;
748 if (!type
|| type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
752 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
753 ret
= integer
->declaration
.base
;
758 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type
*type
,
759 enum bt_ctf_integer_base base
)
763 if (!type
|| type
->frozen
||
764 type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
770 case BT_CTF_INTEGER_BASE_BINARY
:
771 case BT_CTF_INTEGER_BASE_OCTAL
:
772 case BT_CTF_INTEGER_BASE_DECIMAL
:
773 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
775 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
776 struct bt_ctf_field_type_integer
, parent
);
777 integer
->declaration
.base
= base
;
787 enum bt_ctf_string_encoding
bt_ctf_field_type_integer_get_encoding(
788 struct bt_ctf_field_type
*type
)
790 enum bt_ctf_string_encoding ret
= BT_CTF_STRING_ENCODING_UNKNOWN
;
791 struct bt_ctf_field_type_integer
*integer
;
793 if (!type
|| type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
797 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
798 ret
= integer
->declaration
.encoding
;
803 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type
*type
,
804 enum bt_ctf_string_encoding encoding
)
807 struct bt_ctf_field_type_integer
*integer
;
809 if (!type
|| type
->frozen
||
810 (type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) ||
811 (encoding
< BT_CTF_STRING_ENCODING_NONE
) ||
812 (encoding
>= BT_CTF_STRING_ENCODING_UNKNOWN
)) {
817 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
818 integer
->declaration
.encoding
= encoding
;
823 struct bt_ctf_clock_class
*bt_ctf_field_type_integer_get_mapped_clock_class(
824 struct bt_ctf_field_type
*type
)
826 struct bt_ctf_field_type_integer
*integer
;
827 struct bt_ctf_clock_class
*clock_class
= NULL
;
833 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
834 clock_class
= integer
->mapped_clock
;
840 int bt_ctf_field_type_integer_set_mapped_clock_class(
841 struct bt_ctf_field_type
*type
,
842 struct bt_ctf_clock_class
*clock_class
)
844 struct bt_ctf_field_type_integer
*integer
;
847 if (!type
|| type
->frozen
|| !bt_ctf_clock_class_is_valid(clock_class
)) {
852 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
853 bt_put(integer
->mapped_clock
);
854 integer
->mapped_clock
= bt_get(clock_class
);
859 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_create(
860 struct bt_ctf_field_type
*integer_container_type
)
862 struct bt_ctf_field_type_enumeration
*enumeration
= NULL
;
864 if (!integer_container_type
) {
868 if (integer_container_type
->declaration
->id
!= BT_CTF_TYPE_ID_INTEGER
) {
872 enumeration
= g_new0(struct bt_ctf_field_type_enumeration
, 1);
877 enumeration
->parent
.declaration
= &enumeration
->declaration
.p
;
878 enumeration
->parent
.declaration
->id
= BT_CTF_TYPE_ID_ENUM
;
879 bt_get(integer_container_type
);
880 enumeration
->container
= integer_container_type
;
881 enumeration
->entries
= g_ptr_array_new_with_free_func(
882 (GDestroyNotify
)destroy_enumeration_mapping
);
883 bt_ctf_field_type_init(&enumeration
->parent
, FALSE
);
884 return &enumeration
->parent
;
890 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_get_container_type(
891 struct bt_ctf_field_type
*type
)
893 struct bt_ctf_field_type
*container_type
= NULL
;
894 struct bt_ctf_field_type_enumeration
*enumeration_type
;
900 if (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
) {
904 enumeration_type
= container_of(type
,
905 struct bt_ctf_field_type_enumeration
, parent
);
906 container_type
= enumeration_type
->container
;
907 bt_get(container_type
);
909 return container_type
;
912 int bt_ctf_field_type_enumeration_add_mapping(
913 struct bt_ctf_field_type
*type
, const char *string
,
914 int64_t range_start
, int64_t range_end
)
918 struct enumeration_mapping
*mapping
;
919 struct bt_ctf_field_type_enumeration
*enumeration
;
920 struct range_overlap_query query
;
921 char *escaped_string
;
923 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
) ||
925 (range_end
< range_start
)) {
930 if (!string
|| strlen(string
) == 0) {
935 escaped_string
= g_strescape(string
, NULL
);
936 if (!escaped_string
) {
941 mapping_name
= g_quark_from_string(escaped_string
);
942 query
= (struct range_overlap_query
) {
943 .range_start
._signed
= range_start
,
944 .range_end
._signed
= range_end
,
945 .mapping_name
= mapping_name
,
947 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
950 /* Check that the range does not overlap with one already present */
951 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap
, &query
);
952 if (query
.overlaps
) {
957 mapping
= g_new(struct enumeration_mapping
, 1);
963 *mapping
= (struct enumeration_mapping
) {
964 .range_start
._signed
= range_start
,
965 .range_end
._signed
= range_end
, .string
= mapping_name
};
966 g_ptr_array_add(enumeration
->entries
, mapping
);
967 g_ptr_array_sort(enumeration
->entries
,
968 (GCompareFunc
)compare_enumeration_mappings_signed
);
970 free(escaped_string
);
975 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
976 struct bt_ctf_field_type
*type
, const char *string
,
977 uint64_t range_start
, uint64_t range_end
)
981 struct enumeration_mapping
*mapping
;
982 struct bt_ctf_field_type_enumeration
*enumeration
;
983 struct range_overlap_query query
;
984 char *escaped_string
;
986 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
) ||
988 (range_end
< range_start
)) {
993 if (!string
|| strlen(string
) == 0) {
998 escaped_string
= g_strescape(string
, NULL
);
999 if (!escaped_string
) {
1004 mapping_name
= g_quark_from_string(escaped_string
);
1005 query
= (struct range_overlap_query
) {
1006 .range_start
._unsigned
= range_start
,
1007 .range_end
._unsigned
= range_end
,
1008 .mapping_name
= mapping_name
,
1010 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
1013 /* Check that the range does not overlap with one already present */
1014 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap_unsigned
,
1016 if (query
.overlaps
) {
1021 mapping
= g_new(struct enumeration_mapping
, 1);
1027 *mapping
= (struct enumeration_mapping
) {
1028 .range_start
._unsigned
= range_start
,
1029 .range_end
._unsigned
= range_end
, .string
= mapping_name
};
1030 g_ptr_array_add(enumeration
->entries
, mapping
);
1031 g_ptr_array_sort(enumeration
->entries
,
1032 (GCompareFunc
)compare_enumeration_mappings_unsigned
);
1034 free(escaped_string
);
1039 const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
1040 struct bt_ctf_field_type_enumeration
*enumeration_type
,
1043 const char *name
= NULL
;
1044 struct range_overlap_query query
=
1045 (struct range_overlap_query
) {
1046 .range_start
._unsigned
= value
,
1047 .range_end
._unsigned
= value
,
1050 g_ptr_array_foreach(enumeration_type
->entries
,
1051 check_ranges_overlap_unsigned
,
1053 if (!query
.overlaps
) {
1057 name
= g_quark_to_string(query
.mapping_name
);
1062 const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
1063 struct bt_ctf_field_type_enumeration
*enumeration_type
,
1066 const char *name
= NULL
;
1067 struct range_overlap_query query
=
1068 (struct range_overlap_query
) {
1069 .range_start
._signed
= value
,
1070 .range_end
._signed
= value
,
1073 g_ptr_array_foreach(enumeration_type
->entries
, check_ranges_overlap
,
1075 if (!query
.overlaps
) {
1079 name
= g_quark_to_string(query
.mapping_name
);
1084 int bt_ctf_field_type_enumeration_get_mapping_count(
1085 struct bt_ctf_field_type
*type
)
1088 struct bt_ctf_field_type_enumeration
*enumeration
;
1090 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
)) {
1095 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
1097 ret
= (int) enumeration
->entries
->len
;
1103 struct enumeration_mapping
*get_enumeration_mapping(
1104 struct bt_ctf_field_type
*type
, int index
)
1106 struct enumeration_mapping
*mapping
= NULL
;
1107 struct bt_ctf_field_type_enumeration
*enumeration
;
1109 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
1111 if (index
>= enumeration
->entries
->len
) {
1115 mapping
= g_ptr_array_index(enumeration
->entries
, index
);
1120 int bt_ctf_field_type_enumeration_get_mapping(
1121 struct bt_ctf_field_type
*type
, int index
,
1122 const char **string
, int64_t *range_start
, int64_t *range_end
)
1124 struct enumeration_mapping
*mapping
;
1127 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
1128 (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
)) {
1133 mapping
= get_enumeration_mapping(type
, index
);
1139 *string
= g_quark_to_string(mapping
->string
);
1140 *range_start
= mapping
->range_start
._signed
;
1141 *range_end
= mapping
->range_end
._signed
;
1146 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
1147 struct bt_ctf_field_type
*type
, int index
,
1148 const char **string
, uint64_t *range_start
, uint64_t *range_end
)
1150 struct enumeration_mapping
*mapping
;
1153 if (!type
|| index
< 0 || !string
|| !range_start
|| !range_end
||
1154 (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
)) {
1159 mapping
= get_enumeration_mapping(type
, index
);
1165 *string
= g_quark_to_string(mapping
->string
);
1166 *range_start
= mapping
->range_start
._unsigned
;
1167 *range_end
= mapping
->range_end
._unsigned
;
1172 int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
1173 struct bt_ctf_field_type
*type
, const char *name
)
1176 struct bt_ctf_field_type_enumeration
*enumeration
;
1179 if (!type
|| !name
||
1180 (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
)) {
1185 name_quark
= g_quark_try_string(name
);
1191 enumeration
= container_of(type
,
1192 struct bt_ctf_field_type_enumeration
, parent
);
1193 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
1194 struct enumeration_mapping
*mapping
=
1195 get_enumeration_mapping(type
, i
);
1197 if (mapping
->string
== name_quark
) {
1208 int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
1209 struct bt_ctf_field_type
*type
, int64_t value
)
1211 struct bt_ctf_field_type_enumeration
*enumeration
;
1214 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
)) {
1219 enumeration
= container_of(type
,
1220 struct bt_ctf_field_type_enumeration
, parent
);
1221 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
1222 struct enumeration_mapping
*mapping
=
1223 get_enumeration_mapping(type
, i
);
1225 if (value
>= mapping
->range_start
._signed
&&
1226 value
<= mapping
->range_end
._signed
) {
1237 int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
1238 struct bt_ctf_field_type
*type
, uint64_t value
)
1240 struct bt_ctf_field_type_enumeration
*enumeration
;
1243 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ENUM
)) {
1248 enumeration
= container_of(type
,
1249 struct bt_ctf_field_type_enumeration
, parent
);
1250 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
1251 struct enumeration_mapping
*mapping
=
1252 get_enumeration_mapping(type
, i
);
1254 if (value
>= mapping
->range_start
._unsigned
&&
1255 value
<= mapping
->range_end
._unsigned
) {
1266 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_create(void)
1268 struct bt_ctf_field_type_floating_point
*floating_point
=
1269 g_new0(struct bt_ctf_field_type_floating_point
, 1);
1271 if (!floating_point
) {
1275 floating_point
->declaration
.sign
= &floating_point
->sign
;
1276 floating_point
->declaration
.mantissa
= &floating_point
->mantissa
;
1277 floating_point
->declaration
.exp
= &floating_point
->exp
;
1278 floating_point
->sign
.len
= 1;
1279 floating_point
->parent
.declaration
= &floating_point
->declaration
.p
;
1280 floating_point
->parent
.declaration
->id
= BT_CTF_TYPE_ID_FLOAT
;
1281 floating_point
->declaration
.exp
->len
=
1282 sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
1283 floating_point
->declaration
.mantissa
->len
= FLT_MANT_DIG
- 1;
1284 floating_point
->sign
.p
.alignment
= 1;
1285 floating_point
->mantissa
.p
.alignment
= 1;
1286 floating_point
->exp
.p
.alignment
= 1;
1288 bt_ctf_field_type_init(&floating_point
->parent
, TRUE
);
1290 return floating_point
? &floating_point
->parent
: NULL
;
1293 int bt_ctf_field_type_floating_point_get_exponent_digits(
1294 struct bt_ctf_field_type
*type
)
1297 struct bt_ctf_field_type_floating_point
*floating_point
;
1299 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_FLOAT
)) {
1304 floating_point
= container_of(type
,
1305 struct bt_ctf_field_type_floating_point
, parent
);
1306 ret
= (int) floating_point
->declaration
.exp
->len
;
1311 int bt_ctf_field_type_floating_point_set_exponent_digits(
1312 struct bt_ctf_field_type
*type
,
1313 unsigned int exponent_digits
)
1316 struct bt_ctf_field_type_floating_point
*floating_point
;
1318 if (!type
|| type
->frozen
||
1319 (type
->declaration
->id
!= BT_CTF_TYPE_ID_FLOAT
)) {
1324 floating_point
= container_of(type
,
1325 struct bt_ctf_field_type_floating_point
, parent
);
1326 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
1327 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
1329 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
1334 floating_point
->declaration
.exp
->len
= exponent_digits
;
1339 int bt_ctf_field_type_floating_point_get_mantissa_digits(
1340 struct bt_ctf_field_type
*type
)
1343 struct bt_ctf_field_type_floating_point
*floating_point
;
1345 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_FLOAT
)) {
1350 floating_point
= container_of(type
,
1351 struct bt_ctf_field_type_floating_point
, parent
);
1352 ret
= (int) floating_point
->mantissa
.len
+ 1;
1357 int bt_ctf_field_type_floating_point_set_mantissa_digits(
1358 struct bt_ctf_field_type
*type
,
1359 unsigned int mantissa_digits
)
1362 struct bt_ctf_field_type_floating_point
*floating_point
;
1364 if (!type
|| type
->frozen
||
1365 (type
->declaration
->id
!= BT_CTF_TYPE_ID_FLOAT
)) {
1370 floating_point
= container_of(type
,
1371 struct bt_ctf_field_type_floating_point
, parent
);
1373 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
1374 (mantissa_digits
!= DBL_MANT_DIG
) &&
1375 (mantissa_digits
!= LDBL_MANT_DIG
)) {
1380 floating_point
->declaration
.mantissa
->len
= mantissa_digits
- 1;
1385 struct bt_ctf_field_type
*bt_ctf_field_type_structure_create(void)
1387 struct bt_ctf_field_type_structure
*structure
=
1388 g_new0(struct bt_ctf_field_type_structure
, 1);
1394 structure
->parent
.declaration
= &structure
->declaration
.p
;
1395 structure
->parent
.declaration
->id
= BT_CTF_TYPE_ID_STRUCT
;
1396 structure
->fields
= g_ptr_array_new_with_free_func(
1397 (GDestroyNotify
)destroy_structure_field
);
1398 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1399 bt_ctf_field_type_init(&structure
->parent
, TRUE
);
1400 return &structure
->parent
;
1405 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type
*type
,
1406 struct bt_ctf_field_type
*field_type
,
1407 const char *field_name
)
1410 struct bt_ctf_field_type_structure
*structure
;
1413 * TODO: check that `field_type` does not contain `type`,
1416 if (!type
|| !field_type
|| type
->frozen
||
1417 bt_ctf_validate_identifier(field_name
) ||
1418 (type
->declaration
->id
!= BT_CTF_TYPE_ID_STRUCT
) ||
1419 type
== field_type
) {
1424 structure
= container_of(type
,
1425 struct bt_ctf_field_type_structure
, parent
);
1426 if (add_structure_field(structure
->fields
,
1427 structure
->field_name_to_index
, field_type
, field_name
)) {
1435 int bt_ctf_field_type_structure_get_field_count(
1436 struct bt_ctf_field_type
*type
)
1439 struct bt_ctf_field_type_structure
*structure
;
1441 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_STRUCT
)) {
1446 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1448 ret
= (int) structure
->fields
->len
;
1453 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type
*type
,
1454 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1457 struct bt_ctf_field_type_structure
*structure
;
1458 struct structure_field
*field
;
1461 if (!type
|| index
< 0 ||
1462 (type
->declaration
->id
!= BT_CTF_TYPE_ID_STRUCT
)) {
1467 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1469 if (index
>= structure
->fields
->len
) {
1474 field
= g_ptr_array_index(structure
->fields
, index
);
1476 *field_type
= field
->type
;
1477 bt_get(field
->type
);
1480 *field_name
= g_quark_to_string(field
->name
);
1486 struct bt_ctf_field_type
*bt_ctf_field_type_structure_get_field_type_by_name(
1487 struct bt_ctf_field_type
*type
,
1492 struct structure_field
*field
;
1493 struct bt_ctf_field_type_structure
*structure
;
1494 struct bt_ctf_field_type
*field_type
= NULL
;
1496 if (!type
|| !name
) {
1500 name_quark
= g_quark_try_string(name
);
1505 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
1507 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
1508 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1512 field
= structure
->fields
->pdata
[index
];
1513 field_type
= field
->type
;
1519 struct bt_ctf_field_type
*bt_ctf_field_type_variant_create(
1520 struct bt_ctf_field_type
*enum_tag
, const char *tag_name
)
1522 struct bt_ctf_field_type_variant
*variant
= NULL
;
1524 if (tag_name
&& bt_ctf_validate_identifier(tag_name
)) {
1528 variant
= g_new0(struct bt_ctf_field_type_variant
, 1);
1533 variant
->parent
.declaration
= &variant
->declaration
.p
;
1534 variant
->parent
.declaration
->id
= BT_CTF_TYPE_ID_VARIANT
;
1535 variant
->tag_name
= g_string_new(tag_name
);
1536 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
1537 variant
->fields
= g_ptr_array_new_with_free_func(
1538 (GDestroyNotify
) destroy_structure_field
);
1541 variant
->tag
= container_of(enum_tag
,
1542 struct bt_ctf_field_type_enumeration
, parent
);
1545 bt_ctf_field_type_init(&variant
->parent
, TRUE
);
1546 /* A variant's alignment is undefined */
1547 variant
->parent
.declaration
->alignment
= 0;
1548 return &variant
->parent
;
1553 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_tag_type(
1554 struct bt_ctf_field_type
*type
)
1556 struct bt_ctf_field_type_variant
*variant
;
1557 struct bt_ctf_field_type
*tag_type
= NULL
;
1559 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
)) {
1563 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1564 if (!variant
->tag
) {
1568 tag_type
= &variant
->tag
->parent
;
1574 const char *bt_ctf_field_type_variant_get_tag_name(
1575 struct bt_ctf_field_type
*type
)
1577 struct bt_ctf_field_type_variant
*variant
;
1578 const char *tag_name
= NULL
;
1580 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
)) {
1584 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1585 if (variant
->tag_name
->len
== 0) {
1589 tag_name
= variant
->tag_name
->str
;
1594 int bt_ctf_field_type_variant_set_tag_name(
1595 struct bt_ctf_field_type
*type
, const char *name
)
1598 struct bt_ctf_field_type_variant
*variant
;
1600 if (!type
|| type
->frozen
||
1601 (type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
) ||
1602 bt_ctf_validate_identifier(name
)) {
1607 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1608 g_string_assign(variant
->tag_name
, name
);
1613 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type
*type
,
1614 struct bt_ctf_field_type
*field_type
,
1615 const char *field_name
)
1619 struct bt_ctf_field_type_variant
*variant
;
1620 GQuark field_name_quark
= g_quark_from_string(field_name
);
1623 * TODO: check that `field_type` does not contain `type`,
1626 if (!type
|| !field_type
|| type
->frozen
||
1627 bt_ctf_validate_identifier(field_name
) ||
1628 (type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
) ||
1629 type
== field_type
) {
1634 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1636 /* The user has explicitly provided a tag; validate against it. */
1640 /* Make sure this name is present in the enum tag */
1641 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
1642 struct enumeration_mapping
*mapping
=
1643 g_ptr_array_index(variant
->tag
->entries
, i
);
1645 if (mapping
->string
== field_name_quark
) {
1652 /* Validation failed */
1658 if (add_structure_field(variant
->fields
, variant
->field_name_to_index
,
1659 field_type
, field_name
)) {
1667 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_by_name(
1668 struct bt_ctf_field_type
*type
,
1669 const char *field_name
)
1673 struct structure_field
*field
;
1674 struct bt_ctf_field_type_variant
*variant
;
1675 struct bt_ctf_field_type
*field_type
= NULL
;
1677 if (!type
|| !field_name
) {
1681 name_quark
= g_quark_try_string(field_name
);
1686 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
1687 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
1688 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
1692 field
= g_ptr_array_index(variant
->fields
, index
);
1693 field_type
= field
->type
;
1699 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_from_tag(
1700 struct bt_ctf_field_type
*type
,
1701 struct bt_ctf_field
*tag
)
1703 const char *enum_value
;
1704 struct bt_ctf_field_type
*field_type
= NULL
;
1706 if (!type
|| !tag
|| type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
) {
1710 enum_value
= bt_ctf_field_enumeration_get_mapping_name(tag
);
1715 /* Already increments field_type's reference count */
1716 field_type
= bt_ctf_field_type_variant_get_field_type_by_name(
1722 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type
*type
)
1725 struct bt_ctf_field_type_variant
*variant
;
1727 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
)) {
1732 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1734 ret
= (int) variant
->fields
->len
;
1740 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type
*type
,
1741 const char **field_name
, struct bt_ctf_field_type
**field_type
,
1744 struct bt_ctf_field_type_variant
*variant
;
1745 struct structure_field
*field
;
1748 if (!type
|| index
< 0 ||
1749 (type
->declaration
->id
!= BT_CTF_TYPE_ID_VARIANT
)) {
1754 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
1756 if (index
>= variant
->fields
->len
) {
1761 field
= g_ptr_array_index(variant
->fields
, index
);
1763 *field_type
= field
->type
;
1764 bt_get(field
->type
);
1767 *field_name
= g_quark_to_string(field
->name
);
1773 struct bt_ctf_field_type
*bt_ctf_field_type_array_create(
1774 struct bt_ctf_field_type
*element_type
,
1775 unsigned int length
)
1777 struct bt_ctf_field_type_array
*array
= NULL
;
1779 if (!element_type
|| length
== 0) {
1783 array
= g_new0(struct bt_ctf_field_type_array
, 1);
1788 array
->parent
.declaration
= &array
->declaration
.p
;
1789 array
->parent
.declaration
->id
= BT_CTF_TYPE_ID_ARRAY
;
1791 bt_get(element_type
);
1792 array
->element_type
= element_type
;
1793 array
->length
= length
;
1794 bt_ctf_field_type_init(&array
->parent
, FALSE
);
1795 return &array
->parent
;
1800 struct bt_ctf_field_type
*bt_ctf_field_type_array_get_element_type(
1801 struct bt_ctf_field_type
*type
)
1803 struct bt_ctf_field_type
*ret
= NULL
;
1804 struct bt_ctf_field_type_array
*array
;
1806 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ARRAY
)) {
1810 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1811 ret
= array
->element_type
;
1818 int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type
*type
,
1819 struct bt_ctf_field_type
*element_type
)
1822 struct bt_ctf_field_type_array
*array
;
1824 if (!type
|| !element_type
||
1825 (type
->declaration
->id
!= BT_CTF_TYPE_ID_ARRAY
)) {
1830 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1832 if (array
->element_type
) {
1833 BT_PUT(array
->element_type
);
1836 array
->element_type
= element_type
;
1837 bt_get(array
->element_type
);
1843 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type
*type
)
1846 struct bt_ctf_field_type_array
*array
;
1848 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_ARRAY
)) {
1853 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1854 ret
= (int64_t) array
->length
;
1859 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_create(
1860 struct bt_ctf_field_type
*element_type
,
1861 const char *length_field_name
)
1863 struct bt_ctf_field_type_sequence
*sequence
= NULL
;
1865 if (!element_type
|| bt_ctf_validate_identifier(length_field_name
)) {
1869 sequence
= g_new0(struct bt_ctf_field_type_sequence
, 1);
1874 sequence
->parent
.declaration
= &sequence
->declaration
.p
;
1875 sequence
->parent
.declaration
->id
= BT_CTF_TYPE_ID_SEQUENCE
;
1876 bt_get(element_type
);
1877 sequence
->element_type
= element_type
;
1878 sequence
->length_field_name
= g_string_new(length_field_name
);
1879 bt_ctf_field_type_init(&sequence
->parent
, FALSE
);
1880 return &sequence
->parent
;
1885 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_get_element_type(
1886 struct bt_ctf_field_type
*type
)
1888 struct bt_ctf_field_type
*ret
= NULL
;
1889 struct bt_ctf_field_type_sequence
*sequence
;
1891 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_SEQUENCE
)) {
1895 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1897 ret
= sequence
->element_type
;
1904 int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type
*type
,
1905 struct bt_ctf_field_type
*element_type
)
1908 struct bt_ctf_field_type_sequence
*sequence
;
1910 if (!type
|| !element_type
||
1911 (type
->declaration
->id
!= BT_CTF_TYPE_ID_SEQUENCE
)) {
1916 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
, parent
);
1918 if (sequence
->element_type
) {
1919 BT_PUT(sequence
->element_type
);
1922 sequence
->element_type
= element_type
;
1923 bt_get(sequence
->element_type
);
1929 const char *bt_ctf_field_type_sequence_get_length_field_name(
1930 struct bt_ctf_field_type
*type
)
1932 const char *ret
= NULL
;
1933 struct bt_ctf_field_type_sequence
*sequence
;
1935 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_SEQUENCE
)) {
1939 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
1941 ret
= sequence
->length_field_name
->str
;
1946 struct bt_ctf_field_type
*bt_ctf_field_type_string_create(void)
1948 struct bt_ctf_field_type_string
*string
=
1949 g_new0(struct bt_ctf_field_type_string
, 1);
1955 string
->parent
.declaration
= &string
->declaration
.p
;
1956 string
->parent
.declaration
->id
= BT_CTF_TYPE_ID_STRING
;
1957 bt_ctf_field_type_init(&string
->parent
, TRUE
);
1958 string
->declaration
.encoding
= BT_CTF_STRING_ENCODING_UTF8
;
1959 string
->parent
.declaration
->alignment
= CHAR_BIT
;
1960 return &string
->parent
;
1963 enum bt_ctf_string_encoding
bt_ctf_field_type_string_get_encoding(
1964 struct bt_ctf_field_type
*type
)
1966 struct bt_ctf_field_type_string
*string
;
1967 enum bt_ctf_string_encoding ret
= BT_CTF_STRING_ENCODING_UNKNOWN
;
1969 if (!type
|| (type
->declaration
->id
!= BT_CTF_TYPE_ID_STRING
)) {
1973 string
= container_of(type
, struct bt_ctf_field_type_string
,
1975 ret
= string
->declaration
.encoding
;
1980 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type
*type
,
1981 enum bt_ctf_string_encoding encoding
)
1984 struct bt_ctf_field_type_string
*string
;
1986 if (!type
|| type
->declaration
->id
!= BT_CTF_TYPE_ID_STRING
||
1987 (encoding
!= BT_CTF_STRING_ENCODING_UTF8
&&
1988 encoding
!= BT_CTF_STRING_ENCODING_ASCII
)) {
1993 string
= container_of(type
, struct bt_ctf_field_type_string
, parent
);
1994 string
->declaration
.encoding
= encoding
;
1999 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type
*type
)
2002 enum bt_ctf_type_id type_id
;
2010 ret
= (int) type
->declaration
->alignment
;
2014 type_id
= bt_ctf_field_type_get_type_id(type
);
2016 case BT_CTF_TYPE_ID_SEQUENCE
:
2018 struct bt_ctf_field_type
*element
=
2019 bt_ctf_field_type_sequence_get_element_type(type
);
2026 ret
= bt_ctf_field_type_get_alignment(element
);
2030 case BT_CTF_TYPE_ID_ARRAY
:
2032 struct bt_ctf_field_type
*element
=
2033 bt_ctf_field_type_array_get_element_type(type
);
2040 ret
= bt_ctf_field_type_get_alignment(element
);
2044 case BT_CTF_TYPE_ID_STRUCT
:
2046 int i
, element_count
;
2048 element_count
= bt_ctf_field_type_structure_get_field_count(
2050 if (element_count
< 0) {
2051 ret
= element_count
;
2055 for (i
= 0; i
< element_count
; i
++) {
2056 struct bt_ctf_field_type
*field
;
2057 int field_alignment
;
2059 ret
= bt_ctf_field_type_structure_get_field(type
, NULL
,
2066 field_alignment
= bt_ctf_field_type_get_alignment(
2069 if (field_alignment
< 0) {
2070 ret
= field_alignment
;
2074 type
->declaration
->alignment
= MAX(field_alignment
,
2075 type
->declaration
->alignment
);
2077 ret
= (int) type
->declaration
->alignment
;
2080 case BT_CTF_TYPE_ID_UNKNOWN
:
2084 ret
= (int) type
->declaration
->alignment
;
2092 int is_power_of_two(unsigned int value
)
2094 return ((value
& (value
- 1)) == 0) && value
> 0;
2097 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type
*type
,
2098 unsigned int alignment
)
2101 enum bt_ctf_type_id type_id
;
2103 /* Alignment must be a power of two */
2104 if (!type
|| type
->frozen
|| !is_power_of_two(alignment
)) {
2109 type_id
= bt_ctf_field_type_get_type_id(type
);
2110 if (type_id
== BT_CTF_TYPE_ID_UNKNOWN
) {
2115 if (type
->declaration
->id
== BT_CTF_TYPE_ID_STRING
&&
2116 alignment
!= CHAR_BIT
) {
2121 if (type_id
== BT_CTF_TYPE_ID_VARIANT
||
2122 type_id
== BT_CTF_TYPE_ID_SEQUENCE
||
2123 type_id
== BT_CTF_TYPE_ID_ARRAY
) {
2124 /* Setting an alignment on these types makes no sense */
2129 type
->declaration
->alignment
= alignment
;
2135 enum bt_ctf_byte_order
bt_ctf_field_type_get_byte_order(
2136 struct bt_ctf_field_type
*type
)
2138 enum bt_ctf_byte_order ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
2144 switch (type
->declaration
->id
) {
2145 case BT_CTF_TYPE_ID_INTEGER
:
2147 struct bt_ctf_field_type_integer
*integer
= container_of(
2148 type
, struct bt_ctf_field_type_integer
, parent
);
2149 ret
= integer
->user_byte_order
;
2152 case BT_CTF_TYPE_ID_ENUM
:
2154 struct bt_ctf_field_type_enumeration
*enum_ft
= container_of(
2155 type
, struct bt_ctf_field_type_enumeration
, parent
);
2156 ret
= bt_ctf_field_type_get_byte_order(enum_ft
->container
);
2159 case BT_CTF_TYPE_ID_FLOAT
:
2161 struct bt_ctf_field_type_floating_point
*floating_point
=
2163 struct bt_ctf_field_type_floating_point
,
2165 ret
= floating_point
->user_byte_order
;
2172 assert(ret
== BT_CTF_BYTE_ORDER_NATIVE
||
2173 ret
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
||
2174 ret
== BT_CTF_BYTE_ORDER_BIG_ENDIAN
||
2175 ret
== BT_CTF_BYTE_ORDER_NETWORK
);
2181 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type
*type
,
2182 enum bt_ctf_byte_order byte_order
)
2185 int internal_byte_order
;
2186 enum bt_ctf_type_id type_id
;
2188 if (!type
|| type
->frozen
) {
2193 switch (byte_order
) {
2194 case BT_CTF_BYTE_ORDER_NATIVE
:
2195 /* Leave unset. Will be initialized by parent. */
2196 internal_byte_order
= 0;
2198 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
2199 internal_byte_order
= LITTLE_ENDIAN
;
2201 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
2202 case BT_CTF_BYTE_ORDER_NETWORK
:
2203 internal_byte_order
= BIG_ENDIAN
;
2210 type_id
= type
->declaration
->id
;
2211 if (set_byte_order_funcs
[type_id
]) {
2212 set_byte_order_funcs
[type_id
](type
, internal_byte_order
, 0);
2218 enum bt_ctf_type_id
bt_ctf_field_type_get_type_id(
2219 struct bt_ctf_field_type
*type
)
2222 return BT_CTF_TYPE_ID_UNKNOWN
;
2225 return type
->declaration
->id
;
2228 int bt_ctf_field_type_is_integer(struct bt_ctf_field_type
*type
)
2230 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_INTEGER
;
2233 int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type
*type
)
2235 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_FLOAT
;
2238 int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type
*type
)
2240 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_ENUM
;
2243 int bt_ctf_field_type_is_string(struct bt_ctf_field_type
*type
)
2245 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_STRING
;
2248 int bt_ctf_field_type_is_structure(struct bt_ctf_field_type
*type
)
2250 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_STRUCT
;
2253 int bt_ctf_field_type_is_array(struct bt_ctf_field_type
*type
)
2255 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_ARRAY
;
2258 int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type
*type
)
2260 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_SEQUENCE
;
2263 int bt_ctf_field_type_is_variant(struct bt_ctf_field_type
*type
)
2265 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_TYPE_ID_VARIANT
;
2268 void bt_ctf_field_type_get(struct bt_ctf_field_type
*type
)
2273 void bt_ctf_field_type_put(struct bt_ctf_field_type
*type
)
2279 void bt_ctf_field_type_freeze(struct bt_ctf_field_type
*type
)
2289 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_signed(
2290 struct bt_ctf_field_type_variant
*variant
,
2293 struct bt_ctf_field_type
*type
= NULL
;
2294 GQuark field_name_quark
;
2296 struct structure_field
*field_entry
;
2297 struct range_overlap_query query
= {
2298 .range_start
._signed
= tag_value
,
2299 .range_end
._signed
= tag_value
,
2300 .mapping_name
= 0, .overlaps
= 0};
2302 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
2304 if (!query
.overlaps
) {
2308 field_name_quark
= query
.mapping_name
;
2309 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
2310 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
2314 field_entry
= g_ptr_array_index(variant
->fields
, (size_t) index
);
2315 type
= field_entry
->type
;
2321 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_unsigned(
2322 struct bt_ctf_field_type_variant
*variant
,
2325 struct bt_ctf_field_type
*type
= NULL
;
2326 GQuark field_name_quark
;
2328 struct structure_field
*field_entry
;
2329 struct range_overlap_query query
= {
2330 .range_start
._unsigned
= tag_value
,
2331 .range_end
._unsigned
= tag_value
,
2332 .mapping_name
= 0, .overlaps
= 0};
2334 g_ptr_array_foreach(variant
->tag
->entries
,
2335 check_ranges_overlap_unsigned
,
2337 if (!query
.overlaps
) {
2341 field_name_quark
= query
.mapping_name
;
2342 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
2343 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
2347 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
2348 type
= field_entry
->type
;
2354 int bt_ctf_field_type_serialize(struct bt_ctf_field_type
*type
,
2355 struct metadata_context
*context
)
2359 if (!type
|| !context
) {
2364 /* Make sure field type is valid before serializing it */
2365 ret
= bt_ctf_field_type_validate(type
);
2371 ret
= type
->serialize(type
, context
);
2377 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type
*type
,
2384 assert(byte_order
== LITTLE_ENDIAN
|| byte_order
== BIG_ENDIAN
);
2385 if (set_byte_order_funcs
[type
->declaration
->id
]) {
2386 set_byte_order_funcs
[type
->declaration
->id
](type
,
2391 struct bt_ctf_field_type
*bt_ctf_field_type_copy(struct bt_ctf_field_type
*type
)
2393 struct bt_ctf_field_type
*copy
= NULL
;
2399 copy
= type_copy_funcs
[type
->declaration
->id
](type
);
2405 int bt_ctf_field_type_structure_get_field_name_index(
2406 struct bt_ctf_field_type
*type
, const char *name
)
2411 struct bt_ctf_field_type_structure
*structure
;
2413 if (!type
|| !name
||
2414 bt_ctf_field_type_get_type_id(type
) != BT_CTF_TYPE_ID_STRUCT
) {
2419 name_quark
= g_quark_try_string(name
);
2425 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
2427 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
2428 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
2438 int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type
*type
,
2439 struct bt_ctf_field_type
*field
, int index
)
2442 struct bt_ctf_field_type_structure
*structure
;
2444 if (!type
|| !field
||
2445 bt_ctf_field_type_get_type_id(type
) != BT_CTF_TYPE_ID_STRUCT
) {
2450 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
2452 if (index
< 0 || index
>= structure
->fields
->len
) {
2458 bt_put(((struct structure_field
*)
2459 g_ptr_array_index(structure
->fields
, index
))->type
);
2460 ((struct structure_field
*) structure
->fields
->pdata
[index
])->type
=
2467 int bt_ctf_field_type_variant_get_field_name_index(
2468 struct bt_ctf_field_type
*type
, const char *name
)
2473 struct bt_ctf_field_type_variant
*variant
;
2475 if (!type
|| !name
||
2476 bt_ctf_field_type_get_type_id(type
) != BT_CTF_TYPE_ID_VARIANT
) {
2481 name_quark
= g_quark_try_string(name
);
2487 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
2489 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
2490 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
2500 int bt_ctf_field_type_sequence_set_length_field_path(
2501 struct bt_ctf_field_type
*type
,
2502 struct bt_ctf_field_path
*path
)
2505 struct bt_ctf_field_type_sequence
*sequence
;
2507 if (!type
|| bt_ctf_field_type_get_type_id(type
) !=
2508 BT_CTF_TYPE_ID_SEQUENCE
) {
2513 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
2516 BT_MOVE(sequence
->length_field_path
, path
);
2522 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type
*type
,
2523 struct bt_ctf_field_path
*path
)
2526 struct bt_ctf_field_type_variant
*variant
;
2528 if (!type
|| bt_ctf_field_type_get_type_id(type
) !=
2529 BT_CTF_TYPE_ID_VARIANT
) {
2534 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
2537 BT_MOVE(variant
->tag_field_path
, path
);
2543 int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type
*type
,
2544 struct bt_ctf_field_type
*tag
)
2547 struct bt_ctf_field_type_variant
*variant
;
2549 if (!type
|| !tag
||
2550 bt_ctf_field_type_get_type_id(tag
) !=
2551 BT_CTF_TYPE_ID_ENUM
) {
2556 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
2560 bt_put(&variant
->tag
->parent
);
2562 variant
->tag
= container_of(tag
, struct bt_ctf_field_type_enumeration
,
2569 int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type
*type
,
2570 struct bt_ctf_field_type
*field
, int index
)
2573 struct bt_ctf_field_type_variant
*variant
;
2575 if (!type
|| !field
||
2576 bt_ctf_field_type_get_type_id(type
) != BT_CTF_TYPE_ID_VARIANT
) {
2581 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
2583 if (index
< 0 || index
>= variant
->fields
->len
) {
2589 bt_put(((struct structure_field
*)
2590 g_ptr_array_index(variant
->fields
, index
))->type
);
2591 ((struct structure_field
*) variant
->fields
->pdata
[index
])->type
=
2598 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type
*type
)
2600 struct bt_ctf_field_type_integer
*integer
=
2601 (struct bt_ctf_field_type_integer
*) type
;
2607 bt_put(integer
->mapped_clock
);
2612 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type
*type
)
2614 struct bt_ctf_field_type_enumeration
*enumeration
=
2615 (struct bt_ctf_field_type_enumeration
*) type
;
2621 g_ptr_array_free(enumeration
->entries
, TRUE
);
2622 bt_put(enumeration
->container
);
2623 g_free(enumeration
);
2627 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type
*type
)
2629 struct bt_ctf_field_type_floating_point
*floating_point
=
2630 (struct bt_ctf_field_type_floating_point
*) type
;
2636 g_free(floating_point
);
2640 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type
*type
)
2642 struct bt_ctf_field_type_structure
*structure
=
2643 (struct bt_ctf_field_type_structure
*) type
;
2649 g_ptr_array_free(structure
->fields
, TRUE
);
2650 g_hash_table_destroy(structure
->field_name_to_index
);
2655 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type
*type
)
2657 struct bt_ctf_field_type_variant
*variant
=
2658 (struct bt_ctf_field_type_variant
*) type
;
2664 g_ptr_array_free(variant
->fields
, TRUE
);
2665 g_hash_table_destroy(variant
->field_name_to_index
);
2666 g_string_free(variant
->tag_name
, TRUE
);
2667 bt_put(&variant
->tag
->parent
);
2668 BT_PUT(variant
->tag_field_path
);
2673 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type
*type
)
2675 struct bt_ctf_field_type_array
*array
=
2676 (struct bt_ctf_field_type_array
*) type
;
2682 bt_put(array
->element_type
);
2687 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type
*type
)
2689 struct bt_ctf_field_type_sequence
*sequence
=
2690 (struct bt_ctf_field_type_sequence
*) type
;
2696 bt_put(sequence
->element_type
);
2697 g_string_free(sequence
->length_field_name
, TRUE
);
2698 BT_PUT(sequence
->length_field_path
);
2703 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type
*type
)
2705 struct bt_ctf_field_type_string
*string
=
2706 (struct bt_ctf_field_type_string
*) type
;
2716 void generic_field_type_freeze(struct bt_ctf_field_type
*type
)
2722 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type
*type
)
2724 struct bt_ctf_field_type_integer
*integer_type
= container_of(
2725 type
, struct bt_ctf_field_type_integer
, parent
);
2727 if (integer_type
->mapped_clock
) {
2728 bt_ctf_clock_class_freeze(integer_type
->mapped_clock
);
2731 generic_field_type_freeze(type
);
2735 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*type
)
2737 struct bt_ctf_field_type_enumeration
*enumeration_type
= container_of(
2738 type
, struct bt_ctf_field_type_enumeration
, parent
);
2740 generic_field_type_freeze(type
);
2741 bt_ctf_field_type_freeze(enumeration_type
->container
);
2745 void freeze_structure_field(struct structure_field
*field
)
2747 bt_ctf_field_type_freeze(field
->type
);
2751 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*type
)
2753 struct bt_ctf_field_type_structure
*structure_type
= container_of(
2754 type
, struct bt_ctf_field_type_structure
, parent
);
2756 /* Cache the alignment */
2757 type
->declaration
->alignment
= bt_ctf_field_type_get_alignment(type
);
2758 generic_field_type_freeze(type
);
2759 g_ptr_array_foreach(structure_type
->fields
,
2760 (GFunc
) freeze_structure_field
, NULL
);
2764 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*type
)
2766 struct bt_ctf_field_type_variant
*variant_type
= container_of(
2767 type
, struct bt_ctf_field_type_variant
, parent
);
2769 generic_field_type_freeze(type
);
2770 g_ptr_array_foreach(variant_type
->fields
,
2771 (GFunc
) freeze_structure_field
, NULL
);
2775 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*type
)
2777 struct bt_ctf_field_type_array
*array_type
= container_of(
2778 type
, struct bt_ctf_field_type_array
, parent
);
2780 /* Cache the alignment */
2781 type
->declaration
->alignment
= bt_ctf_field_type_get_alignment(type
);
2782 generic_field_type_freeze(type
);
2783 bt_ctf_field_type_freeze(array_type
->element_type
);
2787 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*type
)
2789 struct bt_ctf_field_type_sequence
*sequence_type
= container_of(
2790 type
, struct bt_ctf_field_type_sequence
, parent
);
2792 /* Cache the alignment */
2793 type
->declaration
->alignment
= bt_ctf_field_type_get_alignment(type
);
2794 generic_field_type_freeze(type
);
2795 bt_ctf_field_type_freeze(sequence_type
->element_type
);
2799 const char *get_encoding_string(enum bt_ctf_string_encoding encoding
)
2801 const char *encoding_string
;
2804 case BT_CTF_STRING_ENCODING_NONE
:
2805 encoding_string
= "none";
2807 case BT_CTF_STRING_ENCODING_ASCII
:
2808 encoding_string
= "ASCII";
2810 case BT_CTF_STRING_ENCODING_UTF8
:
2811 encoding_string
= "UTF8";
2814 encoding_string
= "unknown";
2818 return encoding_string
;
2822 const char *get_integer_base_string(enum bt_ctf_integer_base base
)
2824 const char *base_string
;
2827 case BT_CTF_INTEGER_BASE_DECIMAL
:
2828 base_string
= "decimal";
2830 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
2831 base_string
= "hexadecimal";
2833 case BT_CTF_INTEGER_BASE_OCTAL
:
2834 base_string
= "octal";
2836 case BT_CTF_INTEGER_BASE_BINARY
:
2837 base_string
= "binary";
2840 base_string
= "unknown";
2848 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*type
,
2849 struct metadata_context
*context
)
2851 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
2852 struct bt_ctf_field_type_integer
, parent
);
2855 g_string_append_printf(context
->string
,
2856 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2857 integer
->declaration
.len
, type
->declaration
->alignment
,
2858 (integer
->declaration
.signedness
? "true" : "false"),
2859 get_encoding_string(integer
->declaration
.encoding
),
2860 get_integer_base_string(integer
->declaration
.base
),
2861 get_byte_order_string(integer
->declaration
.byte_order
));
2862 if (integer
->mapped_clock
) {
2863 const char *clock_name
= bt_ctf_clock_class_get_name(
2864 integer
->mapped_clock
);
2871 g_string_append_printf(context
->string
,
2872 "; map = clock.%s.value", clock_name
);
2875 g_string_append(context
->string
, "; }");
2881 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*type
,
2882 struct metadata_context
*context
)
2886 struct bt_ctf_field_type_enumeration
*enumeration
= container_of(type
,
2887 struct bt_ctf_field_type_enumeration
, parent
);
2888 struct bt_ctf_field_type
*container_type
;
2889 int container_signed
;
2891 container_type
= bt_ctf_field_type_enumeration_get_container_type(type
);
2892 if (!container_type
) {
2897 container_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
2898 if (container_signed
< 0) {
2899 ret
= container_signed
;
2900 goto error_put_container_type
;
2903 g_string_append(context
->string
, "enum : ");
2904 ret
= bt_ctf_field_type_serialize(enumeration
->container
, context
);
2906 goto error_put_container_type
;
2909 g_string_append(context
->string
, " { ");
2910 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
2911 struct enumeration_mapping
*mapping
=
2912 enumeration
->entries
->pdata
[entry
];
2914 if (container_signed
) {
2915 if (mapping
->range_start
._signed
==
2916 mapping
->range_end
._signed
) {
2917 g_string_append_printf(context
->string
,
2918 "\"%s\" = %" PRId64
,
2919 g_quark_to_string(mapping
->string
),
2920 mapping
->range_start
._signed
);
2922 g_string_append_printf(context
->string
,
2923 "\"%s\" = %" PRId64
" ... %" PRId64
,
2924 g_quark_to_string(mapping
->string
),
2925 mapping
->range_start
._signed
,
2926 mapping
->range_end
._signed
);
2929 if (mapping
->range_start
._unsigned
==
2930 mapping
->range_end
._unsigned
) {
2931 g_string_append_printf(context
->string
,
2932 "\"%s\" = %" PRIu64
,
2933 g_quark_to_string(mapping
->string
),
2934 mapping
->range_start
._unsigned
);
2936 g_string_append_printf(context
->string
,
2937 "\"%s\" = %" PRIu64
" ... %" PRIu64
,
2938 g_quark_to_string(mapping
->string
),
2939 mapping
->range_start
._unsigned
,
2940 mapping
->range_end
._unsigned
);
2944 g_string_append(context
->string
,
2945 ((entry
!= (enumeration
->entries
->len
- 1)) ?
2949 if (context
->field_name
->len
) {
2950 g_string_append_printf(context
->string
, " %s",
2951 context
->field_name
->str
);
2952 g_string_assign(context
->field_name
, "");
2954 error_put_container_type
:
2955 bt_put(container_type
);
2961 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type
*type
,
2962 struct metadata_context
*context
)
2964 struct bt_ctf_field_type_floating_point
*floating_point
= container_of(
2965 type
, struct bt_ctf_field_type_floating_point
, parent
);
2967 g_string_append_printf(context
->string
,
2968 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2969 floating_point
->declaration
.exp
->len
,
2970 floating_point
->declaration
.mantissa
->len
+ 1,
2971 get_byte_order_string(floating_point
->declaration
.byte_order
),
2972 type
->declaration
->alignment
);
2977 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*type
,
2978 struct metadata_context
*context
)
2981 unsigned int indent
;
2983 struct bt_ctf_field_type_structure
*structure
= container_of(type
,
2984 struct bt_ctf_field_type_structure
, parent
);
2985 GString
*structure_field_name
= context
->field_name
;
2987 context
->field_name
= g_string_new("");
2989 context
->current_indentation_level
++;
2990 g_string_append(context
->string
, "struct {\n");
2992 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2993 struct structure_field
*field
;
2995 for (indent
= 0; indent
< context
->current_indentation_level
;
2997 g_string_append_c(context
->string
, '\t');
3000 field
= structure
->fields
->pdata
[i
];
3001 g_string_assign(context
->field_name
,
3002 g_quark_to_string(field
->name
));
3003 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
3008 if (context
->field_name
->len
) {
3009 g_string_append_printf(context
->string
, " %s",
3010 context
->field_name
->str
);
3012 g_string_append(context
->string
, ";\n");
3015 context
->current_indentation_level
--;
3016 for (indent
= 0; indent
< context
->current_indentation_level
;
3018 g_string_append_c(context
->string
, '\t');
3021 g_string_append_printf(context
->string
, "} align(%zu)",
3022 type
->declaration
->alignment
);
3024 g_string_free(context
->field_name
, TRUE
);
3025 context
->field_name
= structure_field_name
;
3030 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*type
,
3031 struct metadata_context
*context
)
3034 unsigned int indent
;
3036 struct bt_ctf_field_type_variant
*variant
= container_of(
3037 type
, struct bt_ctf_field_type_variant
, parent
);
3038 GString
*variant_field_name
= context
->field_name
;
3040 context
->field_name
= g_string_new("");
3041 if (variant
->tag_name
->len
> 0) {
3042 g_string_append_printf(context
->string
,
3043 "variant <%s> {\n", variant
->tag_name
->str
);
3045 g_string_append(context
->string
, "variant {\n");
3048 context
->current_indentation_level
++;
3049 for (i
= 0; i
< variant
->fields
->len
; i
++) {
3050 struct structure_field
*field
= variant
->fields
->pdata
[i
];
3052 g_string_assign(context
->field_name
,
3053 g_quark_to_string(field
->name
));
3054 for (indent
= 0; indent
< context
->current_indentation_level
;
3056 g_string_append_c(context
->string
, '\t');
3059 g_string_assign(context
->field_name
,
3060 g_quark_to_string(field
->name
));
3061 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
3066 if (context
->field_name
->len
) {
3067 g_string_append_printf(context
->string
, " %s;",
3068 context
->field_name
->str
);
3071 g_string_append_c(context
->string
, '\n');
3074 context
->current_indentation_level
--;
3075 for (indent
= 0; indent
< context
->current_indentation_level
;
3077 g_string_append_c(context
->string
, '\t');
3080 g_string_append(context
->string
, "}");
3082 g_string_free(context
->field_name
, TRUE
);
3083 context
->field_name
= variant_field_name
;
3088 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*type
,
3089 struct metadata_context
*context
)
3092 struct bt_ctf_field_type_array
*array
= container_of(type
,
3093 struct bt_ctf_field_type_array
, parent
);
3095 ret
= bt_ctf_field_type_serialize(array
->element_type
, context
);
3100 if (context
->field_name
->len
) {
3101 g_string_append_printf(context
->string
, " %s[%u]",
3102 context
->field_name
->str
, array
->length
);
3103 g_string_assign(context
->field_name
, "");
3105 g_string_append_printf(context
->string
, "[%u]", array
->length
);
3112 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*type
,
3113 struct metadata_context
*context
)
3116 struct bt_ctf_field_type_sequence
*sequence
= container_of(
3117 type
, struct bt_ctf_field_type_sequence
, parent
);
3119 ret
= bt_ctf_field_type_serialize(sequence
->element_type
, context
);
3124 if (context
->field_name
->len
) {
3125 g_string_append_printf(context
->string
, " %s[%s]",
3126 context
->field_name
->str
,
3127 sequence
->length_field_name
->str
);
3128 g_string_assign(context
->field_name
, "");
3130 g_string_append_printf(context
->string
, "[%s]",
3131 sequence
->length_field_name
->str
);
3138 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*type
,
3139 struct metadata_context
*context
)
3141 struct bt_ctf_field_type_string
*string
= container_of(
3142 type
, struct bt_ctf_field_type_string
, parent
);
3144 g_string_append_printf(context
->string
,
3145 "string { encoding = %s; }",
3146 get_encoding_string(string
->declaration
.encoding
));
3151 enum bt_ctf_byte_order
get_ctf_ir_byte_order(int byte_order
) {
3152 enum bt_ctf_byte_order ret
;
3154 switch (byte_order
) {
3155 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
3157 ret
= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
;
3159 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
3161 ret
= BT_CTF_BYTE_ORDER_BIG_ENDIAN
;
3163 case BT_CTF_BYTE_ORDER_NETWORK
:
3164 ret
= BT_CTF_BYTE_ORDER_NETWORK
;
3166 case BT_CTF_BYTE_ORDER_NATIVE
:
3167 ret
= BT_CTF_BYTE_ORDER_NATIVE
;
3170 ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
3178 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*type
,
3179 int byte_order
, int set_native
)
3181 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
3182 struct bt_ctf_field_type_integer
, parent
);
3185 if (integer_type
->user_byte_order
== BT_CTF_BYTE_ORDER_NATIVE
) {
3187 * User byte order is native, so we can set
3188 * the real byte order.
3190 integer_type
->declaration
.byte_order
=
3194 integer_type
->user_byte_order
=
3195 get_ctf_ir_byte_order(byte_order
);
3196 integer_type
->declaration
.byte_order
= byte_order
;
3201 void bt_ctf_field_type_enumeration_set_byte_order(
3202 struct bt_ctf_field_type
*type
, int byte_order
, int set_native
)
3204 struct bt_ctf_field_type_enumeration
*enum_type
= container_of(type
,
3205 struct bt_ctf_field_type_enumeration
, parent
);
3207 /* Safe to assume that container is an integer */
3208 bt_ctf_field_type_integer_set_byte_order(enum_type
->container
,
3209 byte_order
, set_native
);
3213 void bt_ctf_field_type_floating_point_set_byte_order(
3214 struct bt_ctf_field_type
*type
, int byte_order
, int set_native
)
3216 struct bt_ctf_field_type_floating_point
*floating_point_type
=
3217 container_of(type
, struct bt_ctf_field_type_floating_point
,
3221 if (floating_point_type
->user_byte_order
==
3222 BT_CTF_BYTE_ORDER_NATIVE
) {
3224 * User byte order is native, so we can set
3225 * the real byte order.
3227 floating_point_type
->declaration
.byte_order
=
3229 floating_point_type
->sign
.byte_order
=
3231 floating_point_type
->mantissa
.byte_order
=
3233 floating_point_type
->exp
.byte_order
=
3237 floating_point_type
->user_byte_order
=
3238 get_ctf_ir_byte_order(byte_order
);
3239 floating_point_type
->declaration
.byte_order
= byte_order
;
3240 floating_point_type
->sign
.byte_order
= byte_order
;
3241 floating_point_type
->mantissa
.byte_order
= byte_order
;
3242 floating_point_type
->exp
.byte_order
= byte_order
;
3247 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*type
,
3248 int byte_order
, int set_native
)
3251 struct bt_ctf_field_type_structure
*structure_type
=
3252 container_of(type
, struct bt_ctf_field_type_structure
,
3255 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
3256 struct structure_field
*field
= g_ptr_array_index(
3257 structure_type
->fields
, i
);
3258 struct bt_ctf_field_type
*field_type
= field
->type
;
3260 if (set_byte_order_funcs
[field_type
->declaration
->id
]) {
3261 set_byte_order_funcs
[field_type
->declaration
->id
](
3262 field_type
, byte_order
, set_native
);
3268 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*type
,
3269 int byte_order
, int set_native
)
3272 struct bt_ctf_field_type_variant
*variant_type
=
3273 container_of(type
, struct bt_ctf_field_type_variant
,
3276 for (i
= 0; i
< variant_type
->fields
->len
; i
++) {
3277 struct structure_field
*field
= g_ptr_array_index(
3278 variant_type
->fields
, i
);
3279 struct bt_ctf_field_type
*field_type
= field
->type
;
3281 if (set_byte_order_funcs
[field_type
->declaration
->id
]) {
3282 set_byte_order_funcs
[field_type
->declaration
->id
](
3283 field_type
, byte_order
, set_native
);
3289 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*type
,
3290 int byte_order
, int set_native
)
3292 struct bt_ctf_field_type_array
*array_type
=
3293 container_of(type
, struct bt_ctf_field_type_array
,
3296 if (set_byte_order_funcs
[array_type
->element_type
->declaration
->id
]) {
3297 set_byte_order_funcs
[array_type
->element_type
->declaration
->id
](
3298 array_type
->element_type
, byte_order
, set_native
);
3303 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*type
,
3304 int byte_order
, int set_native
)
3306 struct bt_ctf_field_type_sequence
*sequence_type
=
3307 container_of(type
, struct bt_ctf_field_type_sequence
,
3310 if (set_byte_order_funcs
[
3311 sequence_type
->element_type
->declaration
->id
]) {
3312 set_byte_order_funcs
[
3313 sequence_type
->element_type
->declaration
->id
](
3314 sequence_type
->element_type
, byte_order
, set_native
);
3319 struct bt_ctf_field_type
*bt_ctf_field_type_integer_copy(
3320 struct bt_ctf_field_type
*type
)
3322 struct bt_ctf_field_type
*copy
;
3323 struct bt_ctf_field_type_integer
*integer
, *copy_integer
;
3325 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
3326 copy
= bt_ctf_field_type_integer_create(integer
->declaration
.len
);
3331 copy_integer
= container_of(copy
, struct bt_ctf_field_type_integer
,
3333 copy_integer
->declaration
= integer
->declaration
;
3334 if (integer
->mapped_clock
) {
3335 bt_get(integer
->mapped_clock
);
3336 copy_integer
->mapped_clock
= integer
->mapped_clock
;
3339 copy_integer
->user_byte_order
= integer
->user_byte_order
;
3346 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_copy(
3347 struct bt_ctf_field_type
*type
)
3350 struct bt_ctf_field_type
*copy
= NULL
, *copy_container
;
3351 struct bt_ctf_field_type_enumeration
*enumeration
, *copy_enumeration
;
3353 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
3356 /* Copy the source enumeration's container */
3357 copy_container
= bt_ctf_field_type_copy(enumeration
->container
);
3358 if (!copy_container
) {
3362 copy
= bt_ctf_field_type_enumeration_create(copy_container
);
3366 copy_enumeration
= container_of(copy
,
3367 struct bt_ctf_field_type_enumeration
, parent
);
3369 /* Copy all enumaration entries */
3370 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
3371 struct enumeration_mapping
*mapping
= g_ptr_array_index(
3372 enumeration
->entries
, i
);
3373 struct enumeration_mapping
* copy_mapping
= g_new0(
3374 struct enumeration_mapping
, 1);
3376 if (!copy_mapping
) {
3380 *copy_mapping
= *mapping
;
3381 g_ptr_array_add(copy_enumeration
->entries
, copy_mapping
);
3384 copy_enumeration
->declaration
= enumeration
->declaration
;
3386 bt_put(copy_container
);
3389 bt_put(copy_container
);
3395 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_copy(
3396 struct bt_ctf_field_type
*type
)
3398 struct bt_ctf_field_type
*copy
;
3399 struct bt_ctf_field_type_floating_point
*floating_point
, *copy_float
;
3401 floating_point
= container_of(type
,
3402 struct bt_ctf_field_type_floating_point
, parent
);
3403 copy
= bt_ctf_field_type_floating_point_create();
3408 copy_float
= container_of(copy
,
3409 struct bt_ctf_field_type_floating_point
, parent
);
3410 copy_float
->declaration
= floating_point
->declaration
;
3411 copy_float
->sign
= floating_point
->sign
;
3412 copy_float
->mantissa
= floating_point
->mantissa
;
3413 copy_float
->exp
= floating_point
->exp
;
3414 copy_float
->user_byte_order
= floating_point
->user_byte_order
;
3415 copy_float
->declaration
.sign
= ©_float
->sign
;
3416 copy_float
->declaration
.mantissa
= ©_float
->mantissa
;
3417 copy_float
->declaration
.exp
= ©_float
->exp
;
3423 struct bt_ctf_field_type
*bt_ctf_field_type_structure_copy(
3424 struct bt_ctf_field_type
*type
)
3427 GHashTableIter iter
;
3428 gpointer key
, value
;
3429 struct bt_ctf_field_type
*copy
;
3430 struct bt_ctf_field_type_structure
*structure
, *copy_structure
;
3432 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
3434 copy
= bt_ctf_field_type_structure_create();
3439 copy_structure
= container_of(copy
,
3440 struct bt_ctf_field_type_structure
, parent
);
3442 /* Copy field_name_to_index */
3443 g_hash_table_iter_init(&iter
, structure
->field_name_to_index
);
3444 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
3445 g_hash_table_insert(copy_structure
->field_name_to_index
,
3449 for (i
= 0; i
< structure
->fields
->len
; i
++) {
3450 struct structure_field
*entry
, *copy_entry
;
3451 struct bt_ctf_field_type
*copy_field
;
3453 copy_entry
= g_new0(struct structure_field
, 1);
3458 entry
= g_ptr_array_index(structure
->fields
, i
);
3459 copy_field
= bt_ctf_field_type_copy(entry
->type
);
3465 copy_entry
->name
= entry
->name
;
3466 copy_entry
->type
= copy_field
;
3467 g_ptr_array_add(copy_structure
->fields
, copy_entry
);
3470 copy_structure
->declaration
= structure
->declaration
;
3479 struct bt_ctf_field_type
*bt_ctf_field_type_variant_copy(
3480 struct bt_ctf_field_type
*type
)
3483 GHashTableIter iter
;
3484 gpointer key
, value
;
3485 struct bt_ctf_field_type
*copy
= NULL
, *copy_tag
= NULL
;
3486 struct bt_ctf_field_type_variant
*variant
, *copy_variant
;
3488 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
3491 copy_tag
= bt_ctf_field_type_copy(&variant
->tag
->parent
);
3497 copy
= bt_ctf_field_type_variant_create(copy_tag
,
3498 variant
->tag_name
->len
? variant
->tag_name
->str
: NULL
);
3503 copy_variant
= container_of(copy
, struct bt_ctf_field_type_variant
,
3506 /* Copy field_name_to_index */
3507 g_hash_table_iter_init(&iter
, variant
->field_name_to_index
);
3508 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
3509 g_hash_table_insert(copy_variant
->field_name_to_index
,
3513 for (i
= 0; i
< variant
->fields
->len
; i
++) {
3514 struct structure_field
*entry
, *copy_entry
;
3515 struct bt_ctf_field_type
*copy_field
;
3517 copy_entry
= g_new0(struct structure_field
, 1);
3522 entry
= g_ptr_array_index(variant
->fields
, i
);
3523 copy_field
= bt_ctf_field_type_copy(entry
->type
);
3529 copy_entry
->name
= entry
->name
;
3530 copy_entry
->type
= copy_field
;
3531 g_ptr_array_add(copy_variant
->fields
, copy_entry
);
3534 copy_variant
->declaration
= variant
->declaration
;
3535 if (variant
->tag_field_path
) {
3536 copy_variant
->tag_field_path
= bt_ctf_field_path_copy(
3537 variant
->tag_field_path
);
3538 if (!copy_variant
->tag_field_path
) {
3552 struct bt_ctf_field_type
*bt_ctf_field_type_array_copy(
3553 struct bt_ctf_field_type
*type
)
3555 struct bt_ctf_field_type
*copy
= NULL
, *copy_element
;
3556 struct bt_ctf_field_type_array
*array
, *copy_array
;
3558 array
= container_of(type
, struct bt_ctf_field_type_array
,
3560 copy_element
= bt_ctf_field_type_copy(array
->element_type
);
3561 if (!copy_element
) {
3565 copy
= bt_ctf_field_type_array_create(copy_element
, array
->length
);
3570 copy_array
= container_of(copy
, struct bt_ctf_field_type_array
,
3572 copy_array
->declaration
= array
->declaration
;
3574 bt_put(copy_element
);
3579 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_copy(
3580 struct bt_ctf_field_type
*type
)
3582 struct bt_ctf_field_type
*copy
= NULL
, *copy_element
;
3583 struct bt_ctf_field_type_sequence
*sequence
, *copy_sequence
;
3585 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
3587 copy_element
= bt_ctf_field_type_copy(sequence
->element_type
);
3588 if (!copy_element
) {
3592 copy
= bt_ctf_field_type_sequence_create(copy_element
,
3593 sequence
->length_field_name
->len
?
3594 sequence
->length_field_name
->str
: NULL
);
3599 copy_sequence
= container_of(copy
, struct bt_ctf_field_type_sequence
,
3601 copy_sequence
->declaration
= sequence
->declaration
;
3602 if (sequence
->length_field_path
) {
3603 copy_sequence
->length_field_path
= bt_ctf_field_path_copy(
3604 sequence
->length_field_path
);
3605 if (!copy_sequence
->length_field_path
) {
3610 bt_put(copy_element
);
3618 struct bt_ctf_field_type
*bt_ctf_field_type_string_copy(
3619 struct bt_ctf_field_type
*type
)
3621 struct bt_ctf_field_type
*copy
;
3622 struct bt_ctf_field_type_string
*string
, *copy_string
;
3624 copy
= bt_ctf_field_type_string_create();
3629 string
= container_of(type
, struct bt_ctf_field_type_string
,
3631 copy_string
= container_of(type
, struct bt_ctf_field_type_string
,
3633 copy_string
->declaration
= string
->declaration
;
3639 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type
*type_a
,
3640 struct bt_ctf_field_type
*type_b
)
3643 struct bt_ctf_field_type_integer
*integer_a
;
3644 struct bt_ctf_field_type_integer
*integer_b
;
3645 struct declaration_integer
*decl_a
;
3646 struct declaration_integer
*decl_b
;
3648 integer_a
= container_of(type_a
, struct bt_ctf_field_type_integer
,
3650 integer_b
= container_of(type_b
, struct bt_ctf_field_type_integer
,
3652 decl_a
= &integer_a
->declaration
;
3653 decl_b
= &integer_b
->declaration
;
3656 if (decl_a
->len
!= decl_b
->len
) {
3661 * Compare user byte orders only, not the cached,
3664 if (integer_a
->user_byte_order
!= integer_b
->user_byte_order
) {
3669 if (decl_a
->signedness
!= decl_b
->signedness
) {
3674 if (decl_a
->base
!= decl_b
->base
) {
3679 if (decl_a
->encoding
!= decl_b
->encoding
) {
3684 if (integer_a
->mapped_clock
!= integer_b
->mapped_clock
) {
3696 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type
*type_a
,
3697 struct bt_ctf_field_type
*type_b
)
3700 struct bt_ctf_field_type_floating_point
*float_a
;
3701 struct bt_ctf_field_type_floating_point
*float_b
;
3703 float_a
= container_of(type_a
,
3704 struct bt_ctf_field_type_floating_point
, parent
);
3705 float_b
= container_of(type_b
,
3706 struct bt_ctf_field_type_floating_point
, parent
);
3709 if (float_a
->sign
.len
!= float_b
->sign
.len
) {
3713 /* Exponent length */
3714 if (float_a
->exp
.len
!= float_b
->exp
.len
) {
3718 /* Mantissa length */
3719 if (float_a
->mantissa
.len
!= float_b
->mantissa
.len
) {
3724 * Compare user byte orders only, not the cached,
3727 if (float_a
->user_byte_order
!= float_b
->user_byte_order
) {
3739 int compare_enumeration_mappings(struct enumeration_mapping
*mapping_a
,
3740 struct enumeration_mapping
*mapping_b
)
3745 if (mapping_a
->string
!= mapping_b
->string
) {
3750 if (mapping_a
->range_start
._unsigned
!=
3751 mapping_b
->range_start
._unsigned
) {
3756 if (mapping_a
->range_end
._unsigned
!=
3757 mapping_b
->range_end
._unsigned
) {
3769 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type
*type_a
,
3770 struct bt_ctf_field_type
*type_b
)
3774 struct bt_ctf_field_type_enumeration
*enum_a
;
3775 struct bt_ctf_field_type_enumeration
*enum_b
;
3777 enum_a
= container_of(type_a
,
3778 struct bt_ctf_field_type_enumeration
, parent
);
3779 enum_b
= container_of(type_b
,
3780 struct bt_ctf_field_type_enumeration
, parent
);
3782 /* Container field type */
3783 ret
= bt_ctf_field_type_compare(enum_a
->container
, enum_b
->container
);
3791 if (enum_a
->entries
->len
!= enum_b
->entries
->len
) {
3795 for (i
= 0; i
< enum_a
->entries
->len
; ++i
) {
3796 struct enumeration_mapping
*mapping_a
=
3797 g_ptr_array_index(enum_a
->entries
, i
);
3798 struct enumeration_mapping
*mapping_b
=
3799 g_ptr_array_index(enum_b
->entries
, i
);
3801 if (compare_enumeration_mappings(mapping_a
, mapping_b
)) {
3814 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type
*type_a
,
3815 struct bt_ctf_field_type
*type_b
)
3818 struct bt_ctf_field_type_string
*string_a
;
3819 struct bt_ctf_field_type_string
*string_b
;
3821 string_a
= container_of(type_a
,
3822 struct bt_ctf_field_type_string
, parent
);
3823 string_b
= container_of(type_b
,
3824 struct bt_ctf_field_type_string
, parent
);
3827 if (string_a
->declaration
.encoding
!= string_b
->declaration
.encoding
) {
3839 int compare_structure_fields(struct structure_field
*field_a
,
3840 struct structure_field
*field_b
)
3845 if (field_a
->name
!= field_b
->name
) {
3850 ret
= bt_ctf_field_type_compare(field_a
->type
, field_b
->type
);
3857 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type
*type_a
,
3858 struct bt_ctf_field_type
*type_b
)
3862 struct bt_ctf_field_type_structure
*struct_a
;
3863 struct bt_ctf_field_type_structure
*struct_b
;
3865 struct_a
= container_of(type_a
,
3866 struct bt_ctf_field_type_structure
, parent
);
3867 struct_b
= container_of(type_b
,
3868 struct bt_ctf_field_type_structure
, parent
);
3871 if (bt_ctf_field_type_get_alignment(type_a
) !=
3872 bt_ctf_field_type_get_alignment(type_b
)) {
3877 if (struct_a
->fields
->len
!= struct_b
->fields
->len
) {
3881 for (i
= 0; i
< struct_a
->fields
->len
; ++i
) {
3882 struct structure_field
*field_a
=
3883 g_ptr_array_index(struct_a
->fields
, i
);
3884 struct structure_field
*field_b
=
3885 g_ptr_array_index(struct_b
->fields
, i
);
3887 ret
= compare_structure_fields(field_a
, field_b
);
3901 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type
*type_a
,
3902 struct bt_ctf_field_type
*type_b
)
3906 struct bt_ctf_field_type_variant
*variant_a
;
3907 struct bt_ctf_field_type_variant
*variant_b
;
3909 variant_a
= container_of(type_a
,
3910 struct bt_ctf_field_type_variant
, parent
);
3911 variant_b
= container_of(type_b
,
3912 struct bt_ctf_field_type_variant
, parent
);
3915 if (strcmp(variant_a
->tag_name
->str
, variant_b
->tag_name
->str
)) {
3920 ret
= bt_ctf_field_type_compare(
3921 (struct bt_ctf_field_type
*) variant_a
->tag
,
3922 (struct bt_ctf_field_type
*) variant_b
->tag
);
3930 if (variant_a
->fields
->len
!= variant_b
->fields
->len
) {
3934 for (i
= 0; i
< variant_a
->fields
->len
; ++i
) {
3935 struct structure_field
*field_a
=
3936 g_ptr_array_index(variant_a
->fields
, i
);
3937 struct structure_field
*field_b
=
3938 g_ptr_array_index(variant_b
->fields
, i
);
3940 ret
= compare_structure_fields(field_a
, field_b
);
3954 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type
*type_a
,
3955 struct bt_ctf_field_type
*type_b
)
3958 struct bt_ctf_field_type_array
*array_a
;
3959 struct bt_ctf_field_type_array
*array_b
;
3961 array_a
= container_of(type_a
,
3962 struct bt_ctf_field_type_array
, parent
);
3963 array_b
= container_of(type_b
,
3964 struct bt_ctf_field_type_array
, parent
);
3967 if (array_a
->length
!= array_b
->length
) {
3972 ret
= bt_ctf_field_type_compare(array_a
->element_type
,
3973 array_b
->element_type
);
3980 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type
*type_a
,
3981 struct bt_ctf_field_type
*type_b
)
3984 struct bt_ctf_field_type_sequence
*sequence_a
;
3985 struct bt_ctf_field_type_sequence
*sequence_b
;
3987 sequence_a
= container_of(type_a
,
3988 struct bt_ctf_field_type_sequence
, parent
);
3989 sequence_b
= container_of(type_b
,
3990 struct bt_ctf_field_type_sequence
, parent
);
3993 if (strcmp(sequence_a
->length_field_name
->str
,
3994 sequence_b
->length_field_name
->str
)) {
3999 ret
= bt_ctf_field_type_compare(sequence_a
->element_type
,
4000 sequence_b
->element_type
);
4006 int bt_ctf_field_type_compare(struct bt_ctf_field_type
*type_a
,
4007 struct bt_ctf_field_type
*type_b
)
4011 if (type_a
== type_b
) {
4012 /* Same reference: equal (even if both are NULL) */
4017 if (!type_a
|| !type_b
) {
4022 if (type_a
->declaration
->id
!= type_b
->declaration
->id
) {
4023 /* Different type IDs */
4027 if (type_a
->declaration
->id
== BT_CTF_TYPE_ID_UNKNOWN
) {
4028 /* Both have unknown type IDs */
4032 ret
= type_compare_funcs
[type_a
->declaration
->id
](type_a
, type_b
);
4039 int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type
*field_type
)
4041 int field_count
= -1;
4042 enum ctf_type_id type_id
= bt_ctf_field_type_get_type_id(field_type
);
4045 case CTF_TYPE_STRUCT
:
4047 bt_ctf_field_type_structure_get_field_count(field_type
);
4049 case CTF_TYPE_VARIANT
:
4051 bt_ctf_field_type_variant_get_field_count(field_type
);
4053 case CTF_TYPE_ARRAY
:
4054 case CTF_TYPE_SEQUENCE
:
4056 * Array and sequence types always contain a single member
4057 * (the element type).
4069 struct bt_ctf_field_type
*bt_ctf_field_type_get_field_at_index(
4070 struct bt_ctf_field_type
*field_type
, int index
)
4072 struct bt_ctf_field_type
*field
= NULL
;
4073 enum ctf_type_id type_id
= bt_ctf_field_type_get_type_id(field_type
);
4076 case CTF_TYPE_STRUCT
:
4077 bt_ctf_field_type_structure_get_field(field_type
, NULL
, &field
,
4080 case CTF_TYPE_VARIANT
:
4082 int ret
= bt_ctf_field_type_variant_get_field(field_type
, NULL
,
4090 case CTF_TYPE_ARRAY
:
4091 field
= bt_ctf_field_type_array_get_element_type(field_type
);
4093 case CTF_TYPE_SEQUENCE
:
4094 field
= bt_ctf_field_type_sequence_get_element_type(field_type
);
4104 int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type
*field_type
,
4107 int field_index
= -1;
4108 enum ctf_type_id type_id
= bt_ctf_field_type_get_type_id(field_type
);
4111 case CTF_TYPE_STRUCT
:
4112 field_index
= bt_ctf_field_type_structure_get_field_name_index(
4115 case CTF_TYPE_VARIANT
:
4116 field_index
= bt_ctf_field_type_variant_get_field_name_index(
4126 struct bt_ctf_field_path
*bt_ctf_field_type_variant_get_tag_field_path(
4127 struct bt_ctf_field_type
*type
)
4129 struct bt_ctf_field_path
*field_path
= NULL
;
4130 struct bt_ctf_field_type_variant
*variant
;
4132 if (!type
|| !bt_ctf_field_type_is_variant(type
)) {
4136 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
4138 field_path
= bt_get(variant
->tag_field_path
);
4143 struct bt_ctf_field_path
*bt_ctf_field_type_sequence_get_length_field_path(
4144 struct bt_ctf_field_type
*type
)
4146 struct bt_ctf_field_path
*field_path
= NULL
;
4147 struct bt_ctf_field_type_sequence
*sequence
;
4149 if (!type
|| !bt_ctf_field_type_is_sequence(type
)) {
4153 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
4155 field_path
= bt_get(sequence
->length_field_path
);