4 * Babeltrace CTF Writer
6 * Copyright 2013 EfficiOS Inc.
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/ctf-writer/event-types.h>
30 #include <babeltrace/ctf-writer/event-types-internal.h>
31 #include <babeltrace/ctf-writer/writer-internal.h>
32 #include <babeltrace/compiler.h>
33 #include <babeltrace/endian.h>
37 struct range_overlap_query
{
38 int64_t range_start
, range_end
;
44 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*);
46 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*);
48 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*);
50 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*);
52 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*);
54 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*);
56 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*);
58 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*);
61 void (* const type_destroy_funcs
[])(struct bt_ctf_ref
*) = {
62 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_destroy
,
64 bt_ctf_field_type_enumeration_destroy
,
66 bt_ctf_field_type_floating_point_destroy
,
67 [CTF_TYPE_STRUCT
] = bt_ctf_field_type_structure_destroy
,
68 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_destroy
,
69 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_destroy
,
70 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_destroy
,
71 [CTF_TYPE_STRING
] = bt_ctf_field_type_string_destroy
,
75 void generic_field_type_freeze(struct bt_ctf_field_type
*);
77 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*);
79 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*);
81 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*);
83 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*);
85 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*);
88 type_freeze_func
const type_freeze_funcs
[] = {
89 [CTF_TYPE_INTEGER
] = generic_field_type_freeze
,
90 [CTF_TYPE_ENUM
] = bt_ctf_field_type_enumeration_freeze
,
91 [CTF_TYPE_FLOAT
] = generic_field_type_freeze
,
92 [CTF_TYPE_STRUCT
] = bt_ctf_field_type_structure_freeze
,
93 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_freeze
,
94 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_freeze
,
95 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_freeze
,
96 [CTF_TYPE_STRING
] = generic_field_type_freeze
,
100 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*,
101 struct metadata_context
*);
103 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*,
104 struct metadata_context
*);
106 int bt_ctf_field_type_floating_point_serialize(
107 struct bt_ctf_field_type
*, struct metadata_context
*);
109 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*,
110 struct metadata_context
*);
112 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*,
113 struct metadata_context
*);
115 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*,
116 struct metadata_context
*);
118 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*,
119 struct metadata_context
*);
121 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*,
122 struct metadata_context
*);
125 type_serialize_func
const type_serialize_funcs
[] = {
126 [CTF_TYPE_INTEGER
] = bt_ctf_field_type_integer_serialize
,
128 bt_ctf_field_type_enumeration_serialize
,
130 bt_ctf_field_type_floating_point_serialize
,
132 bt_ctf_field_type_structure_serialize
,
133 [CTF_TYPE_VARIANT
] = bt_ctf_field_type_variant_serialize
,
134 [CTF_TYPE_ARRAY
] = bt_ctf_field_type_array_serialize
,
135 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_type_sequence_serialize
,
136 [CTF_TYPE_STRING
] = bt_ctf_field_type_string_serialize
,
140 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*,
143 void bt_ctf_field_type_floating_point_set_byte_order(
144 struct bt_ctf_field_type
*, int byte_order
);
147 void (* const set_byte_order_funcs
[])(struct bt_ctf_field_type
*,
150 bt_ctf_field_type_integer_set_byte_order
,
152 bt_ctf_field_type_floating_point_set_byte_order
,
153 [CTF_TYPE_ENUM
... CTF_TYPE_SEQUENCE
] = NULL
,
158 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
164 void destroy_structure_field(struct structure_field
*field
)
167 bt_ctf_field_type_put(field
->type
);
174 void check_ranges_overlap(gpointer element
, gpointer query
)
176 struct enumeration_mapping
*mapping
= element
;
177 struct range_overlap_query
*overlap_query
= query
;
179 if (mapping
->range_start
<= overlap_query
->range_end
180 && overlap_query
->range_start
<= mapping
->range_end
) {
181 overlap_query
->overlaps
= 1;
182 overlap_query
->mapping_name
= mapping
->string
;
185 overlap_query
->overlaps
|=
186 mapping
->string
== overlap_query
->mapping_name
;
190 void bt_ctf_field_type_init(struct bt_ctf_field_type
*type
)
192 enum ctf_type_id type_id
= type
->declaration
->id
;
195 assert(type
&& (type_id
> CTF_TYPE_UNKNOWN
) &&
196 (type_id
< NR_CTF_TYPES
));
198 bt_ctf_ref_init(&type
->ref_count
);
199 type
->freeze
= type_freeze_funcs
[type_id
];
200 type
->serialize
= type_serialize_funcs
[type_id
];
201 ret
= bt_ctf_field_type_set_byte_order(type
, BT_CTF_BYTE_ORDER_NATIVE
);
203 type
->declaration
->alignment
= 1;
207 int add_structure_field(GPtrArray
*fields
,
208 GHashTable
*field_name_to_index
,
209 struct bt_ctf_field_type
*field_type
,
210 const char *field_name
)
213 GQuark name_quark
= g_quark_from_string(field_name
);
214 struct structure_field
*field
;
216 /* Make sure structure does not contain a field of the same name */
217 if (g_hash_table_lookup_extended(field_name_to_index
,
218 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
223 field
= g_new0(struct structure_field
, 1);
229 bt_ctf_field_type_get(field_type
);
230 field
->name
= name_quark
;
231 field
->type
= field_type
;
232 g_hash_table_insert(field_name_to_index
,
233 (gpointer
) (unsigned long) name_quark
,
234 (gpointer
) (unsigned long) fields
->len
);
235 g_ptr_array_add(fields
, field
);
236 bt_ctf_field_type_freeze(field_type
);
242 int bt_ctf_field_type_validate(struct bt_ctf_field_type
*type
)
251 if (type
->declaration
->id
== CTF_TYPE_ENUM
) {
252 struct bt_ctf_field_type_enumeration
*enumeration
=
253 container_of(type
, struct bt_ctf_field_type_enumeration
,
256 ret
= enumeration
->entries
->len
? 0 : -1;
262 struct bt_ctf_field_type
*bt_ctf_field_type_integer_create(unsigned int size
)
264 struct bt_ctf_field_type_integer
*integer
=
265 g_new0(struct bt_ctf_field_type_integer
, 1);
267 if (!integer
|| size
> 64) {
271 integer
->parent
.declaration
= &integer
->declaration
.p
;
272 integer
->parent
.declaration
->id
= CTF_TYPE_INTEGER
;
273 integer
->declaration
.len
= size
;
274 integer
->declaration
.base
= BT_CTF_INTEGER_BASE_DECIMAL
;
275 integer
->declaration
.encoding
= CTF_STRING_NONE
;
276 bt_ctf_field_type_init(&integer
->parent
);
277 return &integer
->parent
;
280 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type
*type
,
284 struct bt_ctf_field_type_integer
*integer
;
286 if (!type
|| type
->frozen
||
287 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
292 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
293 if (is_signed
&& integer
->declaration
.len
<= 1) {
298 integer
->declaration
.signedness
= !!is_signed
;
303 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type
*type
,
304 enum bt_ctf_integer_base base
)
308 if (!type
|| type
->frozen
||
309 type
->declaration
->id
!= CTF_TYPE_INTEGER
) {
315 case BT_CTF_INTEGER_BASE_BINARY
:
316 case BT_CTF_INTEGER_BASE_OCTAL
:
317 case BT_CTF_INTEGER_BASE_DECIMAL
:
318 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
320 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
321 struct bt_ctf_field_type_integer
, parent
);
322 integer
->declaration
.base
= base
;
332 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type
*type
,
333 enum ctf_string_encoding encoding
)
336 struct bt_ctf_field_type_integer
*integer
;
338 if (!type
|| type
->frozen
||
339 (type
->declaration
->id
!= CTF_TYPE_INTEGER
) ||
340 (encoding
< CTF_STRING_NONE
) ||
341 (encoding
>= CTF_STRING_UNKNOWN
)) {
346 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
347 integer
->declaration
.encoding
= encoding
;
352 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_create(
353 struct bt_ctf_field_type
*integer_container_type
)
355 struct bt_ctf_field_type_enumeration
*enumeration
= NULL
;
357 if (!integer_container_type
) {
361 enumeration
= g_new0(struct bt_ctf_field_type_enumeration
, 1);
366 enumeration
->parent
.declaration
= &enumeration
->declaration
.p
;
367 enumeration
->parent
.declaration
->id
= CTF_TYPE_ENUM
;
368 bt_ctf_field_type_get(integer_container_type
);
369 enumeration
->container
= integer_container_type
;
370 enumeration
->entries
= g_ptr_array_new_with_free_func(
371 (GDestroyNotify
)destroy_enumeration_mapping
);
372 bt_ctf_field_type_init(&enumeration
->parent
);
373 return &enumeration
->parent
;
379 int bt_ctf_field_type_enumeration_add_mapping(
380 struct bt_ctf_field_type
*type
, const char *string
,
381 int64_t range_start
, int64_t range_end
)
385 struct enumeration_mapping
*mapping
;
386 struct bt_ctf_field_type_enumeration
*enumeration
;
387 struct range_overlap_query query
;
389 if (!type
|| (type
->declaration
->id
!= CTF_TYPE_ENUM
) ||
391 (range_end
< range_start
)) {
396 if (validate_identifier(string
)) {
401 mapping_name
= g_quark_from_string(string
);
402 query
= (struct range_overlap_query
) { .range_start
= range_start
,
403 .range_end
= range_end
,
404 .mapping_name
= mapping_name
,
406 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
409 /* Check that the range does not overlap with one already present */
410 g_ptr_array_foreach(enumeration
->entries
, check_ranges_overlap
, &query
);
411 if (query
.overlaps
) {
416 mapping
= g_new(struct enumeration_mapping
, 1);
422 *mapping
= (struct enumeration_mapping
) {.range_start
= range_start
,
423 .range_end
= range_end
, .string
= mapping_name
};
424 g_ptr_array_add(enumeration
->entries
, mapping
);
429 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_create(void)
431 struct bt_ctf_field_type_floating_point
*floating_point
=
432 g_new0(struct bt_ctf_field_type_floating_point
, 1);
434 if (!floating_point
) {
438 floating_point
->declaration
.sign
= &floating_point
->sign
;
439 floating_point
->declaration
.mantissa
= &floating_point
->mantissa
;
440 floating_point
->declaration
.exp
= &floating_point
->exp
;
441 floating_point
->sign
.len
= 1;
442 floating_point
->parent
.declaration
= &floating_point
->declaration
.p
;
443 floating_point
->parent
.declaration
->id
= CTF_TYPE_FLOAT
;
444 floating_point
->declaration
.exp
->len
=
445 sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
446 floating_point
->declaration
.mantissa
->len
= FLT_MANT_DIG
- 1;
447 floating_point
->sign
.p
.alignment
= 1;
448 floating_point
->mantissa
.p
.alignment
= 1;
449 floating_point
->exp
.p
.alignment
= 1;
451 bt_ctf_field_type_init(&floating_point
->parent
);
453 return floating_point
? &floating_point
->parent
: NULL
;
456 int bt_ctf_field_type_floating_point_set_exponent_digits(
457 struct bt_ctf_field_type
*type
,
458 unsigned int exponent_digits
)
461 struct bt_ctf_field_type_floating_point
*floating_point
;
463 if (!type
|| type
->frozen
||
464 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
469 floating_point
= container_of(type
,
470 struct bt_ctf_field_type_floating_point
, parent
);
471 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
472 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
474 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
479 floating_point
->declaration
.exp
->len
= exponent_digits
;
484 int bt_ctf_field_type_floating_point_set_mantissa_digits(
485 struct bt_ctf_field_type
*type
,
486 unsigned int mantissa_digits
)
489 struct bt_ctf_field_type_floating_point
*floating_point
;
491 if (!type
|| type
->frozen
||
492 (type
->declaration
->id
!= CTF_TYPE_FLOAT
)) {
497 floating_point
= container_of(type
,
498 struct bt_ctf_field_type_floating_point
, parent
);
500 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
501 (mantissa_digits
!= DBL_MANT_DIG
) &&
502 (mantissa_digits
!= LDBL_MANT_DIG
)) {
507 floating_point
->declaration
.mantissa
->len
= mantissa_digits
- 1;
512 struct bt_ctf_field_type
*bt_ctf_field_type_structure_create(void)
514 struct bt_ctf_field_type_structure
*structure
=
515 g_new0(struct bt_ctf_field_type_structure
, 1);
521 structure
->parent
.declaration
= &structure
->declaration
.p
;
522 structure
->parent
.declaration
->id
= CTF_TYPE_STRUCT
;
523 bt_ctf_field_type_init(&structure
->parent
);
524 structure
->fields
= g_ptr_array_new_with_free_func(
525 (GDestroyNotify
)destroy_structure_field
);
526 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
527 return &structure
->parent
;
532 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type
*type
,
533 struct bt_ctf_field_type
*field_type
,
534 const char *field_name
)
537 struct bt_ctf_field_type_structure
*structure
;
539 if (!type
|| !field_type
|| type
->frozen
||
540 validate_identifier(field_name
) ||
541 (type
->declaration
->id
!= CTF_TYPE_STRUCT
) ||
542 bt_ctf_field_type_validate(field_type
)) {
546 structure
= container_of(type
,
547 struct bt_ctf_field_type_structure
, parent
);
548 if (add_structure_field(structure
->fields
,
549 structure
->field_name_to_index
, field_type
, field_name
)) {
554 if (type
->declaration
->alignment
< field_type
->declaration
->alignment
) {
555 type
->declaration
->alignment
=
556 field_type
->declaration
->alignment
;
562 struct bt_ctf_field_type
*bt_ctf_field_type_variant_create(
563 struct bt_ctf_field_type
*enum_tag
, const char *tag_name
)
565 struct bt_ctf_field_type_variant
*variant
= NULL
;
567 if (!enum_tag
|| validate_identifier(tag_name
) ||
568 (enum_tag
->declaration
->id
!= CTF_TYPE_ENUM
)) {
572 variant
= g_new0(struct bt_ctf_field_type_variant
, 1);
577 variant
->parent
.declaration
= &variant
->declaration
.p
;
578 variant
->parent
.declaration
->id
= CTF_TYPE_VARIANT
;
579 variant
->tag_name
= g_string_new(tag_name
);
580 bt_ctf_field_type_init(&variant
->parent
);
581 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
582 variant
->fields
= g_ptr_array_new_with_free_func(
583 (GDestroyNotify
)destroy_structure_field
);
584 bt_ctf_field_type_get(enum_tag
);
585 variant
->tag
= container_of(enum_tag
,
586 struct bt_ctf_field_type_enumeration
, parent
);
587 return &variant
->parent
;
592 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type
*type
,
593 struct bt_ctf_field_type
*field_type
,
594 const char *field_name
)
599 struct bt_ctf_field_type_variant
*variant
;
600 GQuark field_name_quark
= g_quark_from_string(field_name
);
602 if (!type
|| !field_type
|| type
->frozen
||
603 validate_identifier(field_name
) ||
604 (type
->declaration
->id
!= CTF_TYPE_VARIANT
) ||
605 bt_ctf_field_type_validate(field_type
)) {
610 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
611 /* Make sure this name is present in the enum tag */
612 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
613 struct enumeration_mapping
*mapping
=
614 g_ptr_array_index(variant
->tag
->entries
, i
);
616 if (mapping
->string
== field_name_quark
) {
622 if (!name_found
|| add_structure_field(variant
->fields
,
623 variant
->field_name_to_index
, field_type
, field_name
)) {
631 struct bt_ctf_field_type
*bt_ctf_field_type_array_create(
632 struct bt_ctf_field_type
*element_type
,
635 struct bt_ctf_field_type_array
*array
= NULL
;
637 if (!element_type
|| length
== 0 ||
638 bt_ctf_field_type_validate(element_type
)) {
642 array
= g_new0(struct bt_ctf_field_type_array
, 1);
647 array
->parent
.declaration
= &array
->declaration
.p
;
648 array
->parent
.declaration
->id
= CTF_TYPE_ARRAY
;
649 bt_ctf_field_type_init(&array
->parent
);
650 bt_ctf_field_type_get(element_type
);
651 array
->element_type
= element_type
;
652 array
->length
= length
;
653 array
->parent
.declaration
->alignment
=
654 element_type
->declaration
->alignment
;
655 return &array
->parent
;
660 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_create(
661 struct bt_ctf_field_type
*element_type
,
662 const char *length_field_name
)
664 struct bt_ctf_field_type_sequence
*sequence
= NULL
;
666 if (!element_type
|| validate_identifier(length_field_name
) ||
667 bt_ctf_field_type_validate(element_type
)) {
671 sequence
= g_new0(struct bt_ctf_field_type_sequence
, 1);
676 sequence
->parent
.declaration
= &sequence
->declaration
.p
;
677 sequence
->parent
.declaration
->id
= CTF_TYPE_SEQUENCE
;
678 bt_ctf_field_type_init(&sequence
->parent
);
679 bt_ctf_field_type_get(element_type
);
680 sequence
->element_type
= element_type
;
681 sequence
->length_field_name
= g_string_new(length_field_name
);
682 sequence
->parent
.declaration
->alignment
=
683 element_type
->declaration
->alignment
;
684 return &sequence
->parent
;
689 struct bt_ctf_field_type
*bt_ctf_field_type_string_create(void)
691 struct bt_ctf_field_type_string
*string
=
692 g_new0(struct bt_ctf_field_type_string
, 1);
698 string
->parent
.declaration
= &string
->declaration
.p
;
699 string
->parent
.declaration
->id
= CTF_TYPE_STRING
;
700 bt_ctf_field_type_init(&string
->parent
);
701 string
->declaration
.encoding
= CTF_STRING_UTF8
;
702 string
->parent
.declaration
->alignment
= CHAR_BIT
;
703 return &string
->parent
;
706 int bt_ctf_field_type_string_set_encoding(
707 struct bt_ctf_field_type
*type
,
708 enum ctf_string_encoding encoding
)
711 struct bt_ctf_field_type_string
*string
;
713 if (!type
|| type
->declaration
->id
!= CTF_TYPE_STRING
||
714 (encoding
!= CTF_STRING_UTF8
&&
715 encoding
!= CTF_STRING_ASCII
)) {
720 string
= container_of(type
, struct bt_ctf_field_type_string
, parent
);
721 string
->declaration
.encoding
= encoding
;
726 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type
*type
,
727 unsigned int alignment
)
731 /* Alignment must be bit-aligned (1) or byte aligned */
732 if (!type
|| type
->frozen
|| (alignment
!= 1 && (alignment
& 0x7))) {
737 if (type
->declaration
->id
== CTF_TYPE_STRING
&&
738 alignment
!= CHAR_BIT
) {
743 type
->declaration
->alignment
= alignment
;
749 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type
*type
,
750 enum bt_ctf_byte_order byte_order
)
753 int internal_byte_order
;
754 enum ctf_type_id type_id
;
756 if (!type
|| type
->frozen
) {
761 type_id
= type
->declaration
->id
;
762 switch (byte_order
) {
763 case BT_CTF_BYTE_ORDER_NATIVE
:
764 internal_byte_order
= (G_BYTE_ORDER
== G_LITTLE_ENDIAN
?
765 LITTLE_ENDIAN
: BIG_ENDIAN
);
767 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
768 internal_byte_order
= LITTLE_ENDIAN
;
770 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
771 case BT_CTF_BYTE_ORDER_NETWORK
:
772 internal_byte_order
= BIG_ENDIAN
;
779 if (set_byte_order_funcs
[type_id
]) {
780 set_byte_order_funcs
[type_id
](type
, internal_byte_order
);
786 void bt_ctf_field_type_get(struct bt_ctf_field_type
*type
)
792 bt_ctf_ref_get(&type
->ref_count
);
795 void bt_ctf_field_type_put(struct bt_ctf_field_type
*type
)
797 enum ctf_type_id type_id
;
803 type_id
= type
->declaration
->id
;
804 assert(type_id
> CTF_TYPE_UNKNOWN
&& type_id
< NR_CTF_TYPES
);
805 bt_ctf_ref_put(&type
->ref_count
, type_destroy_funcs
[type_id
]);
809 void bt_ctf_field_type_freeze(struct bt_ctf_field_type
*type
)
819 enum ctf_type_id
bt_ctf_field_type_get_type_id(
820 struct bt_ctf_field_type
*type
)
823 return CTF_TYPE_UNKNOWN
;
826 return type
->declaration
->id
;
830 struct bt_ctf_field_type
*bt_ctf_field_type_structure_get_type(
831 struct bt_ctf_field_type_structure
*structure
,
834 struct bt_ctf_field_type
*type
= NULL
;
835 struct structure_field
*field
;
836 GQuark name_quark
= g_quark_try_string(name
);
843 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
844 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
848 field
= structure
->fields
->pdata
[index
];
855 struct bt_ctf_field_type
*bt_ctf_field_type_array_get_element_type(
856 struct bt_ctf_field_type_array
*array
)
859 return array
->element_type
;
863 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_get_element_type(
864 struct bt_ctf_field_type_sequence
*sequence
)
867 return sequence
->element_type
;
871 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type(
872 struct bt_ctf_field_type_variant
*variant
,
875 struct bt_ctf_field_type
*type
= NULL
;
876 GQuark field_name_quark
;
878 struct structure_field
*field_entry
;
879 struct range_overlap_query query
= {.range_start
= tag_value
,
880 .range_end
= tag_value
, .mapping_name
= 0, .overlaps
= 0};
882 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
884 if (!query
.overlaps
) {
888 field_name_quark
= query
.mapping_name
;
889 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
890 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
894 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
895 type
= field_entry
->type
;
901 int bt_ctf_field_type_serialize(struct bt_ctf_field_type
*type
,
902 struct metadata_context
*context
)
906 if (!type
|| !context
) {
911 ret
= type
->serialize(type
, context
);
917 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref
*ref
)
919 struct bt_ctf_field_type_integer
*integer
;
925 integer
= container_of(
926 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
927 struct bt_ctf_field_type_integer
, parent
);
932 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref
*ref
)
934 struct bt_ctf_field_type_enumeration
*enumeration
;
940 enumeration
= container_of(
941 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
942 struct bt_ctf_field_type_enumeration
, parent
);
943 g_ptr_array_free(enumeration
->entries
, TRUE
);
944 bt_ctf_field_type_put(enumeration
->container
);
949 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref
*ref
)
951 struct bt_ctf_field_type_floating_point
*floating_point
;
957 floating_point
= container_of(
958 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
959 struct bt_ctf_field_type_floating_point
, parent
);
960 g_free(floating_point
);
964 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref
*ref
)
966 struct bt_ctf_field_type_structure
*structure
;
972 structure
= container_of(
973 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
974 struct bt_ctf_field_type_structure
, parent
);
975 g_ptr_array_free(structure
->fields
, TRUE
);
976 g_hash_table_destroy(structure
->field_name_to_index
);
981 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref
*ref
)
983 struct bt_ctf_field_type_variant
*variant
;
989 variant
= container_of(
990 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
991 struct bt_ctf_field_type_variant
, parent
);
992 g_ptr_array_free(variant
->fields
, TRUE
);
993 g_hash_table_destroy(variant
->field_name_to_index
);
994 g_string_free(variant
->tag_name
, TRUE
);
995 bt_ctf_field_type_put(&variant
->tag
->parent
);
1000 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref
*ref
)
1002 struct bt_ctf_field_type_array
*array
;
1008 array
= container_of(
1009 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1010 struct bt_ctf_field_type_array
, parent
);
1011 bt_ctf_field_type_put(array
->element_type
);
1016 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref
*ref
)
1018 struct bt_ctf_field_type_sequence
*sequence
;
1024 sequence
= container_of(
1025 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1026 struct bt_ctf_field_type_sequence
, parent
);
1027 bt_ctf_field_type_put(sequence
->element_type
);
1028 g_string_free(sequence
->length_field_name
, TRUE
);
1033 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref
*ref
)
1035 struct bt_ctf_field_type_string
*string
;
1041 string
= container_of(
1042 container_of(ref
, struct bt_ctf_field_type
, ref_count
),
1043 struct bt_ctf_field_type_string
, parent
);
1048 void generic_field_type_freeze(struct bt_ctf_field_type
*type
)
1054 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*type
)
1056 struct bt_ctf_field_type_enumeration
*enumeration_type
= container_of(
1057 type
, struct bt_ctf_field_type_enumeration
, parent
);
1059 generic_field_type_freeze(type
);
1060 bt_ctf_field_type_freeze(enumeration_type
->container
);
1064 void freeze_structure_field(struct structure_field
*field
)
1066 bt_ctf_field_type_freeze(field
->type
);
1070 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*type
)
1072 struct bt_ctf_field_type_structure
*structure_type
= container_of(
1073 type
, struct bt_ctf_field_type_structure
, parent
);
1075 generic_field_type_freeze(type
);
1076 g_ptr_array_foreach(structure_type
->fields
, (GFunc
)freeze_structure_field
,
1081 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*type
)
1083 struct bt_ctf_field_type_variant
*variant_type
= container_of(
1084 type
, struct bt_ctf_field_type_variant
, parent
);
1086 generic_field_type_freeze(type
);
1087 g_ptr_array_foreach(variant_type
->fields
, (GFunc
)freeze_structure_field
,
1092 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*type
)
1094 struct bt_ctf_field_type_array
*array_type
= container_of(
1095 type
, struct bt_ctf_field_type_array
, parent
);
1097 generic_field_type_freeze(type
);
1098 bt_ctf_field_type_freeze(array_type
->element_type
);
1102 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*type
)
1104 struct bt_ctf_field_type_sequence
*sequence_type
= container_of(
1105 type
, struct bt_ctf_field_type_sequence
, parent
);
1107 generic_field_type_freeze(type
);
1108 bt_ctf_field_type_freeze(sequence_type
->element_type
);
1112 const char *get_encoding_string(enum ctf_string_encoding encoding
)
1114 const char *encoding_string
;
1117 case CTF_STRING_NONE
:
1118 encoding_string
= "none";
1120 case CTF_STRING_ASCII
:
1121 encoding_string
= "ASCII";
1123 case CTF_STRING_UTF8
:
1124 encoding_string
= "UTF8";
1127 encoding_string
= "unknown";
1131 return encoding_string
;
1135 const char *get_integer_base_string(enum bt_ctf_integer_base base
)
1137 const char *base_string
;
1140 case BT_CTF_INTEGER_BASE_DECIMAL
:
1141 base_string
= "decimal";
1143 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
1144 base_string
= "hexadecimal";
1146 case BT_CTF_INTEGER_BASE_OCTAL
:
1147 base_string
= "octal";
1149 case BT_CTF_INTEGER_BASE_BINARY
:
1150 base_string
= "binary";
1153 base_string
= "unknown";
1161 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*type
,
1162 struct metadata_context
*context
)
1164 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
1165 struct bt_ctf_field_type_integer
, parent
);
1167 g_string_append_printf(context
->string
,
1168 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
1169 integer
->declaration
.len
, type
->declaration
->alignment
,
1170 (integer
->declaration
.signedness
? "true" : "false"),
1171 get_encoding_string(integer
->declaration
.encoding
),
1172 get_integer_base_string(integer
->declaration
.base
),
1173 get_byte_order_string(integer
->declaration
.byte_order
));
1178 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*type
,
1179 struct metadata_context
*context
)
1183 struct bt_ctf_field_type_enumeration
*enumeration
= container_of(type
,
1184 struct bt_ctf_field_type_enumeration
, parent
);
1186 ret
= bt_ctf_field_type_validate(type
);
1191 g_string_append(context
->string
, "enum : ");
1192 ret
= bt_ctf_field_type_serialize(enumeration
->container
, context
);
1197 g_string_append(context
->string
, " { ");
1198 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
1199 struct enumeration_mapping
*mapping
=
1200 enumeration
->entries
->pdata
[entry
];
1202 if (mapping
->range_start
== mapping
->range_end
) {
1203 g_string_append_printf(context
->string
, "%s = %" PRId64
,
1204 g_quark_to_string(mapping
->string
),
1205 mapping
->range_start
);
1207 g_string_append_printf(context
->string
,
1208 "%s = %" PRId64
" ... %" PRId64
,
1209 g_quark_to_string(mapping
->string
),
1210 mapping
->range_start
, mapping
->range_end
);
1213 g_string_append(context
->string
,
1214 ((entry
!= (enumeration
->entries
->len
- 1)) ?
1218 if (context
->field_name
->len
) {
1219 g_string_append_printf(context
->string
, " %s",
1220 context
->field_name
->str
);
1221 g_string_assign(context
->field_name
, "");
1228 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type
*type
,
1229 struct metadata_context
*context
)
1231 struct bt_ctf_field_type_floating_point
*floating_point
= container_of(
1232 type
, struct bt_ctf_field_type_floating_point
, parent
);
1234 g_string_append_printf(context
->string
,
1235 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
1236 floating_point
->declaration
.exp
->len
,
1237 floating_point
->declaration
.mantissa
->len
+ 1,
1238 get_byte_order_string(floating_point
->declaration
.byte_order
),
1239 type
->declaration
->alignment
);
1244 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*type
,
1245 struct metadata_context
*context
)
1248 unsigned int indent
;
1250 struct bt_ctf_field_type_structure
*structure
= container_of(type
,
1251 struct bt_ctf_field_type_structure
, parent
);
1252 GString
*structure_field_name
= context
->field_name
;
1254 context
->field_name
= g_string_new("");
1256 context
->current_indentation_level
++;
1257 g_string_append(context
->string
, "struct {\n");
1259 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1260 struct structure_field
*field
;
1262 for (indent
= 0; indent
< context
->current_indentation_level
;
1264 g_string_append_c(context
->string
, '\t');
1267 field
= structure
->fields
->pdata
[i
];
1268 g_string_assign(context
->field_name
,
1269 g_quark_to_string(field
->name
));
1270 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
1275 if (context
->field_name
->len
) {
1276 g_string_append_printf(context
->string
, " %s",
1277 context
->field_name
->str
);
1279 g_string_append(context
->string
, ";\n");
1282 context
->current_indentation_level
--;
1283 for (indent
= 0; indent
< context
->current_indentation_level
;
1285 g_string_append_c(context
->string
, '\t');
1288 g_string_append_printf(context
->string
, "} align(%zu)",
1289 type
->declaration
->alignment
);
1291 g_string_free(context
->field_name
, TRUE
);
1292 context
->field_name
= structure_field_name
;
1297 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*type
,
1298 struct metadata_context
*context
)
1301 unsigned int indent
;
1303 struct bt_ctf_field_type_variant
*variant
= container_of(
1304 type
, struct bt_ctf_field_type_variant
, parent
);
1305 GString
*variant_field_name
= context
->field_name
;
1307 context
->field_name
= g_string_new("");
1308 g_string_append_printf(context
->string
,
1309 "variant <%s> {\n", variant
->tag_name
->str
);
1310 context
->current_indentation_level
++;
1311 for (i
= 0; i
< variant
->fields
->len
; i
++) {
1312 struct structure_field
*field
= variant
->fields
->pdata
[i
];
1314 g_string_assign(context
->field_name
,
1315 g_quark_to_string(field
->name
));
1316 for (indent
= 0; indent
< context
->current_indentation_level
;
1318 g_string_append_c(context
->string
, '\t');
1321 g_string_assign(context
->field_name
,
1322 g_quark_to_string(field
->name
));
1323 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
1328 if (context
->field_name
->len
) {
1329 g_string_append_printf(context
->string
, " %s;",
1330 context
->field_name
->str
);
1333 g_string_append_c(context
->string
, '\n');
1336 context
->current_indentation_level
--;
1337 for (indent
= 0; indent
< context
->current_indentation_level
;
1339 g_string_append_c(context
->string
, '\t');
1342 g_string_append(context
->string
, "}");
1344 g_string_free(context
->field_name
, TRUE
);
1345 context
->field_name
= variant_field_name
;
1350 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*type
,
1351 struct metadata_context
*context
)
1354 struct bt_ctf_field_type_array
*array
= container_of(type
,
1355 struct bt_ctf_field_type_array
, parent
);
1357 ret
= bt_ctf_field_type_serialize(array
->element_type
, context
);
1362 if (context
->field_name
->len
) {
1363 g_string_append_printf(context
->string
, " %s[%u]",
1364 context
->field_name
->str
, array
->length
);
1365 g_string_assign(context
->field_name
, "");
1367 g_string_append_printf(context
->string
, "[%u]", array
->length
);
1374 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*type
,
1375 struct metadata_context
*context
)
1378 struct bt_ctf_field_type_sequence
*sequence
= container_of(
1379 type
, struct bt_ctf_field_type_sequence
, parent
);
1381 ret
= bt_ctf_field_type_serialize(sequence
->element_type
, context
);
1386 if (context
->field_name
->len
) {
1387 g_string_append_printf(context
->string
, " %s[%s]",
1388 context
->field_name
->str
,
1389 sequence
->length_field_name
->str
);
1390 g_string_assign(context
->field_name
, "");
1392 g_string_append_printf(context
->string
, "[%s]",
1393 sequence
->length_field_name
->str
);
1400 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*type
,
1401 struct metadata_context
*context
)
1403 struct bt_ctf_field_type_string
*string
= container_of(
1404 type
, struct bt_ctf_field_type_string
, parent
);
1406 g_string_append_printf(context
->string
,
1407 "string { encoding = %s; }",
1408 get_encoding_string(string
->declaration
.encoding
));
1413 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*type
,
1416 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
1417 struct bt_ctf_field_type_integer
, parent
);
1419 integer_type
->declaration
.byte_order
= byte_order
;
1423 void bt_ctf_field_type_floating_point_set_byte_order(
1424 struct bt_ctf_field_type
*type
, int byte_order
)
1426 struct bt_ctf_field_type_floating_point
*floating_point_type
=
1427 container_of(type
, struct bt_ctf_field_type_floating_point
,
1430 floating_point_type
->declaration
.byte_order
= byte_order
;
1431 floating_point_type
->sign
.byte_order
= byte_order
;
1432 floating_point_type
->mantissa
.byte_order
= byte_order
;
1433 floating_point_type
->exp
.byte_order
= byte_order
;