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 #define BT_LOG_TAG "FIELD-TYPES"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/ctf-ir/field-types-internal.h>
33 #include <babeltrace/ctf-ir/field-path-internal.h>
34 #include <babeltrace/ctf-ir/utils.h>
35 #include <babeltrace/ref.h>
36 #include <babeltrace/ctf-ir/clock-class.h>
37 #include <babeltrace/ctf-ir/clock-class-internal.h>
38 #include <babeltrace/ctf-writer/writer-internal.h>
39 #include <babeltrace/object-internal.h>
40 #include <babeltrace/ref.h>
41 #include <babeltrace/compiler-internal.h>
42 #include <babeltrace/endian-internal.h>
47 struct range_overlap_query
{
62 void bt_ctf_field_type_destroy(struct bt_object
*);
64 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type
*);
66 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type
*);
68 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type
*);
70 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type
*);
72 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type
*);
74 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type
*);
76 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type
*);
78 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type
*);
81 void (* const type_destroy_funcs
[])(struct bt_ctf_field_type
*) = {
82 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_destroy
,
83 [BT_CTF_FIELD_TYPE_ID_ENUM
] =
84 bt_ctf_field_type_enumeration_destroy
,
85 [BT_CTF_FIELD_TYPE_ID_FLOAT
] =
86 bt_ctf_field_type_floating_point_destroy
,
87 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_destroy
,
88 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_destroy
,
89 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_destroy
,
90 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_destroy
,
91 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_type_string_destroy
,
95 void generic_field_type_freeze(struct bt_ctf_field_type
*);
97 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type
*);
99 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*);
101 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*);
103 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*);
105 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*);
107 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*);
110 type_freeze_func
const type_freeze_funcs
[] = {
111 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_freeze
,
112 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_freeze
,
113 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = generic_field_type_freeze
,
114 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_freeze
,
115 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_freeze
,
116 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_freeze
,
117 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_freeze
,
118 [BT_CTF_FIELD_TYPE_ID_STRING
] = generic_field_type_freeze
,
122 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*,
123 struct metadata_context
*);
125 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*,
126 struct metadata_context
*);
128 int bt_ctf_field_type_floating_point_serialize(
129 struct bt_ctf_field_type
*, struct metadata_context
*);
131 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*,
132 struct metadata_context
*);
134 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*,
135 struct metadata_context
*);
137 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*,
138 struct metadata_context
*);
140 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*,
141 struct metadata_context
*);
143 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*,
144 struct metadata_context
*);
147 type_serialize_func
const type_serialize_funcs
[] = {
148 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_serialize
,
149 [BT_CTF_FIELD_TYPE_ID_ENUM
] =
150 bt_ctf_field_type_enumeration_serialize
,
151 [BT_CTF_FIELD_TYPE_ID_FLOAT
] =
152 bt_ctf_field_type_floating_point_serialize
,
153 [BT_CTF_FIELD_TYPE_ID_STRUCT
] =
154 bt_ctf_field_type_structure_serialize
,
155 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_serialize
,
156 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_serialize
,
157 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_serialize
,
158 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_type_string_serialize
,
162 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*,
163 enum bt_ctf_byte_order byte_order
);
165 void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type
*,
166 enum bt_ctf_byte_order byte_order
);
168 void bt_ctf_field_type_floating_point_set_byte_order(
169 struct bt_ctf_field_type
*, enum bt_ctf_byte_order byte_order
);
171 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*,
172 enum bt_ctf_byte_order byte_order
);
174 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*,
175 enum bt_ctf_byte_order byte_order
);
177 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*,
178 enum bt_ctf_byte_order byte_order
);
180 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*,
181 enum bt_ctf_byte_order byte_order
);
184 void (* const set_byte_order_funcs
[])(struct bt_ctf_field_type
*,
185 enum bt_ctf_byte_order
) = {
186 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_set_byte_order
,
187 [BT_CTF_FIELD_TYPE_ID_ENUM
] =
188 bt_ctf_field_type_enumeration_set_byte_order
,
189 [BT_CTF_FIELD_TYPE_ID_FLOAT
] =
190 bt_ctf_field_type_floating_point_set_byte_order
,
191 [BT_CTF_FIELD_TYPE_ID_STRUCT
] =
192 bt_ctf_field_type_structure_set_byte_order
,
193 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_set_byte_order
,
194 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_set_byte_order
,
195 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_set_byte_order
,
196 [BT_CTF_FIELD_TYPE_ID_STRING
] = NULL
,
200 struct bt_ctf_field_type
*bt_ctf_field_type_integer_copy(
201 struct bt_ctf_field_type
*);
203 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_copy(
204 struct bt_ctf_field_type
*);
206 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_copy(
207 struct bt_ctf_field_type
*);
209 struct bt_ctf_field_type
*bt_ctf_field_type_structure_copy(
210 struct bt_ctf_field_type
*);
212 struct bt_ctf_field_type
*bt_ctf_field_type_variant_copy(
213 struct bt_ctf_field_type
*);
215 struct bt_ctf_field_type
*bt_ctf_field_type_array_copy(
216 struct bt_ctf_field_type
*);
218 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_copy(
219 struct bt_ctf_field_type
*);
221 struct bt_ctf_field_type
*bt_ctf_field_type_string_copy(
222 struct bt_ctf_field_type
*);
225 struct bt_ctf_field_type
*(* const type_copy_funcs
[])(
226 struct bt_ctf_field_type
*) = {
227 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_copy
,
228 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_copy
,
229 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = bt_ctf_field_type_floating_point_copy
,
230 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_copy
,
231 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_copy
,
232 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_copy
,
233 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_copy
,
234 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_type_string_copy
,
238 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type
*,
239 struct bt_ctf_field_type
*);
241 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type
*,
242 struct bt_ctf_field_type
*);
244 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type
*,
245 struct bt_ctf_field_type
*);
247 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type
*,
248 struct bt_ctf_field_type
*);
250 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type
*,
251 struct bt_ctf_field_type
*);
253 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type
*,
254 struct bt_ctf_field_type
*);
256 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type
*,
257 struct bt_ctf_field_type
*);
259 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type
*,
260 struct bt_ctf_field_type
*);
263 int (* const type_compare_funcs
[])(struct bt_ctf_field_type
*,
264 struct bt_ctf_field_type
*) = {
265 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_compare
,
266 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_compare
,
267 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = bt_ctf_field_type_floating_point_compare
,
268 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_compare
,
269 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_compare
,
270 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_compare
,
271 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_compare
,
272 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_type_string_compare
,
276 int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type
*);
278 int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type
*);
280 int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type
*);
282 int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type
*);
284 int bt_ctf_field_type_array_validate(struct bt_ctf_field_type
*);
286 int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type
*);
289 int (* const type_validate_funcs
[])(struct bt_ctf_field_type
*) = {
290 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_type_integer_validate
,
291 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = NULL
,
292 [BT_CTF_FIELD_TYPE_ID_STRING
] = NULL
,
293 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_type_enumeration_validate
,
294 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_type_structure_validate
,
295 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_type_variant_validate
,
296 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_type_array_validate
,
297 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_type_sequence_validate
,
301 void destroy_enumeration_mapping(struct enumeration_mapping
*mapping
)
307 void destroy_structure_field(struct structure_field
*field
)
314 void check_ranges_overlap(gpointer element
, gpointer query
)
316 struct enumeration_mapping
*mapping
= element
;
317 struct range_overlap_query
*overlap_query
= query
;
319 if (mapping
->range_start
._signed
<= overlap_query
->range_end
._signed
320 && overlap_query
->range_start
._signed
<=
321 mapping
->range_end
._signed
) {
322 overlap_query
->overlaps
= 1;
323 overlap_query
->mapping_name
= mapping
->string
;
326 overlap_query
->overlaps
|=
327 mapping
->string
== overlap_query
->mapping_name
;
329 if (overlap_query
->overlaps
) {
330 BT_LOGV("Overlapping enumeration field type mappings: "
331 "mapping-name=\"%s\", "
332 "mapping-a-range-start=%" PRId64
", "
333 "mapping-a-range-end=%" PRId64
", "
334 "mapping-b-range-start=%" PRId64
", "
335 "mapping-b-range-end=%" PRId64
,
336 g_quark_to_string(mapping
->string
),
337 mapping
->range_start
._signed
,
338 mapping
->range_end
._signed
,
339 overlap_query
->range_start
._signed
,
340 overlap_query
->range_end
._signed
);
345 void check_ranges_overlap_unsigned(gpointer element
, gpointer query
)
347 struct enumeration_mapping
*mapping
= element
;
348 struct range_overlap_query
*overlap_query
= query
;
350 if (mapping
->range_start
._unsigned
<= overlap_query
->range_end
._unsigned
351 && overlap_query
->range_start
._unsigned
<=
352 mapping
->range_end
._unsigned
) {
353 overlap_query
->overlaps
= 1;
354 overlap_query
->mapping_name
= mapping
->string
;
357 overlap_query
->overlaps
|=
358 mapping
->string
== overlap_query
->mapping_name
;
360 if (overlap_query
->overlaps
) {
361 BT_LOGW("Overlapping enumeration field type mappings: "
362 "mapping-name=\"%s\", "
363 "mapping-a-range-start=%" PRIu64
", "
364 "mapping-a-range-end=%" PRIu64
", "
365 "mapping-b-range-start=%" PRIu64
", "
366 "mapping-b-range-end=%" PRIu64
,
367 g_quark_to_string(mapping
->string
),
368 mapping
->range_start
._unsigned
,
369 mapping
->range_end
._unsigned
,
370 overlap_query
->range_start
._unsigned
,
371 overlap_query
->range_end
._unsigned
);
376 gint
compare_enumeration_mappings_signed(struct enumeration_mapping
**a
,
377 struct enumeration_mapping
**b
)
379 return ((*a
)->range_start
._signed
< (*b
)->range_start
._signed
) ? -1 : 1;
383 gint
compare_enumeration_mappings_unsigned(struct enumeration_mapping
**a
,
384 struct enumeration_mapping
**b
)
386 return ((*a
)->range_start
._unsigned
< (*b
)->range_start
._unsigned
) ? -1 : 1;
390 void bt_ctf_field_type_init(struct bt_ctf_field_type
*type
, bt_bool init_bo
)
392 assert(type
&& (type
->id
> BT_CTF_FIELD_TYPE_ID_UNKNOWN
) &&
393 (type
->id
< BT_CTF_NR_TYPE_IDS
));
395 bt_object_init(type
, bt_ctf_field_type_destroy
);
396 type
->freeze
= type_freeze_funcs
[type
->id
];
397 type
->serialize
= type_serialize_funcs
[type
->id
];
400 int ret
= bt_ctf_field_type_set_byte_order(type
,
401 BT_CTF_BYTE_ORDER_NATIVE
);
409 int add_structure_field(GPtrArray
*fields
,
410 GHashTable
*field_name_to_index
,
411 struct bt_ctf_field_type
*field_type
,
412 const char *field_name
)
415 GQuark name_quark
= g_quark_from_string(field_name
);
416 struct structure_field
*field
;
418 /* Make sure structure does not contain a field of the same name */
419 if (g_hash_table_lookup_extended(field_name_to_index
,
420 GUINT_TO_POINTER(name_quark
), NULL
, NULL
)) {
421 BT_LOGW("Structure or variant field type already contains a field type with this name: "
422 "field-name=\"%s\"", field_name
);
427 field
= g_new0(struct structure_field
, 1);
429 BT_LOGE_STR("Failed to allocate one structure/variant field type field.");
435 field
->name
= name_quark
;
436 field
->type
= field_type
;
437 g_hash_table_insert(field_name_to_index
,
438 GUINT_TO_POINTER(name_quark
),
439 GUINT_TO_POINTER(fields
->len
));
440 g_ptr_array_add(fields
, field
);
441 BT_LOGV("Added structure/variant field type field: field-ft-addr=%p, "
442 "field-name=\"%s\"", field_type
, field_name
);
448 void bt_ctf_field_type_destroy(struct bt_object
*obj
)
450 struct bt_ctf_field_type
*type
;
451 enum bt_ctf_field_type_id type_id
;
453 type
= container_of(obj
, struct bt_ctf_field_type
, base
);
455 assert(type_id
> BT_CTF_FIELD_TYPE_ID_UNKNOWN
&&
456 type_id
< BT_CTF_NR_TYPE_IDS
);
457 type_destroy_funcs
[type_id
](type
);
461 int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type
*type
)
465 struct bt_ctf_field_type_integer
*integer
=
466 container_of(type
, struct bt_ctf_field_type_integer
,
469 if (integer
->mapped_clock
&& integer
->is_signed
) {
470 BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
471 "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
472 type
, integer
->mapped_clock
,
473 bt_ctf_clock_class_get_name(integer
->mapped_clock
));
483 struct enumeration_mapping
*get_enumeration_mapping(
484 struct bt_ctf_field_type
*type
, uint64_t index
)
486 struct enumeration_mapping
*mapping
= NULL
;
487 struct bt_ctf_field_type_enumeration
*enumeration
;
489 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
491 if (index
>= enumeration
->entries
->len
) {
492 BT_LOGW("Invalid parameter: index is out of bounds: "
493 "addr=%p, index=%" PRIu64
", count=%u",
494 type
, index
, enumeration
->entries
->len
);
498 mapping
= g_ptr_array_index(enumeration
->entries
, index
);
504 * Note: This algorithm is O(n^2) vs number of enumeration mappings.
505 * Only used when freezing an enumeration.
508 void set_enumeration_range_overlap(
509 struct bt_ctf_field_type
*type
)
512 struct bt_ctf_field_type
*container_type
;
513 struct bt_ctf_field_type_enumeration
*enumeration_type
;
516 BT_LOGV("Setting enumeration field type's overlap flag: addr=%p",
518 enumeration_type
= container_of(type
,
519 struct bt_ctf_field_type_enumeration
, parent
);
521 len
= enumeration_type
->entries
->len
;
522 container_type
= enumeration_type
->container
;
523 is_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
525 for (i
= 0; i
< len
; i
++) {
526 for (j
= i
+ 1; j
< len
; j
++) {
527 struct enumeration_mapping
*mapping
[2];
529 mapping
[0] = get_enumeration_mapping(type
, i
);
530 mapping
[1] = get_enumeration_mapping(type
, j
);
532 if (mapping
[0]->range_start
._signed
533 <= mapping
[1]->range_end
._signed
534 && mapping
[0]->range_end
._signed
535 >= mapping
[1]->range_start
._signed
) {
536 enumeration_type
->has_overlapping_ranges
= BT_TRUE
;
540 if (mapping
[0]->range_start
._unsigned
541 <= mapping
[1]->range_end
._unsigned
542 && mapping
[0]->range_end
._unsigned
543 >= mapping
[1]->range_start
._unsigned
) {
544 enumeration_type
->has_overlapping_ranges
= BT_TRUE
;
552 if (enumeration_type
->has_overlapping_ranges
) {
553 BT_LOGV_STR("Enumeration field type has overlapping ranges.");
555 BT_LOGV_STR("Enumeration field type has no overlapping ranges.");
560 int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type
*type
)
564 struct bt_ctf_field_type_enumeration
*enumeration
=
565 container_of(type
, struct bt_ctf_field_type_enumeration
,
567 struct bt_ctf_field_type
*container_type
=
568 bt_ctf_field_type_enumeration_get_container_type(type
);
570 assert(container_type
);
571 ret
= bt_ctf_field_type_validate(container_type
);
573 BT_LOGW("Invalid enumeration field type: container type is invalid: "
574 "enum-ft-addr=%p, int-ft-addr=%p",
575 type
, container_type
);
579 /* Ensure enum has entries */
580 if (enumeration
->entries
->len
== 0) {
581 BT_LOGW("Invalid enumeration field type: no entries: "
588 BT_PUT(container_type
);
593 int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type
*type
)
596 struct bt_ctf_field_type
*element_type
= NULL
;
597 struct bt_ctf_field_type_sequence
*sequence
=
598 container_of(type
, struct bt_ctf_field_type_sequence
,
601 /* Length field name should be set at this point */
602 if (sequence
->length_field_name
->len
== 0) {
603 BT_LOGW("Invalid sequence field type: no length field name: "
609 element_type
= bt_ctf_field_type_sequence_get_element_type(type
);
610 assert(element_type
);
611 ret
= bt_ctf_field_type_validate(element_type
);
613 BT_LOGW("Invalid sequence field type: invalid element field type: "
614 "seq-ft-addr=%p, element-ft-add=%p",
619 BT_PUT(element_type
);
625 int bt_ctf_field_type_array_validate(struct bt_ctf_field_type
*type
)
628 struct bt_ctf_field_type
*element_type
= NULL
;
630 element_type
= bt_ctf_field_type_array_get_element_type(type
);
631 assert(element_type
);
632 ret
= bt_ctf_field_type_validate(element_type
);
634 BT_LOGW("Invalid array field type: invalid element field type: "
635 "array-ft-addr=%p, element-ft-add=%p",
639 BT_PUT(element_type
);
644 int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type
*type
)
647 struct bt_ctf_field_type
*child_type
= NULL
;
648 int64_t field_count
= bt_ctf_field_type_structure_get_field_count(type
);
651 assert(field_count
>= 0);
653 for (i
= 0; i
< field_count
; ++i
) {
654 const char *field_name
;
656 ret
= bt_ctf_field_type_structure_get_field_by_index(type
,
657 &field_name
, &child_type
, i
);
659 ret
= bt_ctf_field_type_validate(child_type
);
661 BT_LOGW("Invalid structure field type: "
662 "a contained field type is invalid: "
663 "struct-ft-addr=%p, field-ft-addr=%p, "
664 "field-name=\"%s\", field-index=%" PRId64
,
665 type
, child_type
, field_name
, i
);
679 bt_bool
bt_ctf_field_type_enumeration_has_overlapping_ranges(
680 struct bt_ctf_field_type_enumeration
*enumeration_type
)
682 if (!enumeration_type
->parent
.frozen
) {
683 set_enumeration_range_overlap(&enumeration_type
->parent
);
685 return enumeration_type
->has_overlapping_ranges
;
689 int bt_ctf_field_type_enumeration_get_mapping_name(
690 struct bt_ctf_field_type
*enum_field_type
,
692 const char **mapping_name
)
695 struct enumeration_mapping
*mapping
;
697 assert(enum_field_type
);
698 mapping
= get_enumeration_mapping(enum_field_type
, index
);
701 *mapping_name
= g_quark_to_string(mapping
->string
);
708 int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type
*type
)
712 struct bt_ctf_field_type
*child_type
= NULL
;
713 struct bt_ctf_field_type_variant
*variant
=
714 container_of(type
, struct bt_ctf_field_type_variant
,
717 int64_t tag_mappings_count
;
719 if (variant
->tag_name
->len
== 0) {
720 BT_LOGW("Invalid variant field type: no tag field name: "
727 BT_LOGW("Invalid variant field type: no tag field type: "
728 "addr=%p, tag-field-name=\"%s\"", type
,
729 variant
->tag_name
->str
);
734 if (bt_ctf_field_type_enumeration_has_overlapping_ranges(
736 BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
737 "variant-ft-addr=%p, tag-field-name=\"%s\", "
738 "enum-ft-addr=%p", type
, variant
->tag_name
->str
,
745 bt_ctf_field_type_enumeration_get_mapping_count(
746 (struct bt_ctf_field_type
*) variant
->tag
);
749 * Validate that each mapping found in the tag has a name which
750 * is also the name of a field in this variant field type.
752 * The opposite is accepted: variant FT fields which cannot be
753 * selected because the variant FT tag has no mapping named as
754 * such. This scenario, while not ideal, cannot cause any error.
756 for (i
= 0; i
< tag_mappings_count
; ++i
) {
758 struct bt_ctf_field_type
*ft
;
760 ret
= bt_ctf_field_type_enumeration_get_mapping_name(
761 (struct bt_ctf_field_type
*) variant
->tag
,
765 ft
= bt_ctf_field_type_variant_get_field_type_by_name(
768 BT_LOGW("Invalid variant field type: "
769 "enumeration tag field type contains a mapping which does not name a variant field type field: "
770 "variant-ft-addr=%p, tag-field-name=\"%s\", "
771 "enum-ft-addr=%p, mapping-name=\"%s\"",
772 type
, variant
->tag_name
->str
, variant
->tag
,
781 field_count
= bt_ctf_field_type_variant_get_field_count(type
);
782 if (field_count
< 0) {
783 BT_LOGW("Invalid variant field type: no fields: "
784 "addr=%p, tag-field-name=\"%s\"",
785 type
, variant
->tag_name
->str
);
790 for (i
= 0; i
< field_count
; ++i
) {
791 const char *field_name
;
793 ret
= bt_ctf_field_type_variant_get_field_by_index(type
,
794 &field_name
, &child_type
, i
);
796 ret
= bt_ctf_field_type_validate(child_type
);
798 BT_LOGW("Invalid variant field type: "
799 "a contained field type is invalid: "
800 "variant-ft-addr=%p, tag-field-name=\"%s\", "
801 "field-ft-addr=%p, field-name=\"%s\", "
802 "field-index=%" PRId64
,
803 type
, variant
->tag_name
->str
, child_type
,
818 * This function validates a given field type without considering
819 * where this field type is located. It only validates the properties
820 * of the given field type and the properties of its children if
824 int bt_ctf_field_type_validate(struct bt_ctf_field_type
*type
)
827 enum bt_ctf_field_type_id id
= bt_ctf_field_type_get_type_id(type
);
832 /* Already marked as valid */
836 if (type_validate_funcs
[id
]) {
837 ret
= type_validate_funcs
[id
](type
);
840 if (!ret
&& type
->frozen
) {
841 /* Field type is valid */
849 struct bt_ctf_field_type
*bt_ctf_field_type_integer_create(unsigned int size
)
851 struct bt_ctf_field_type_integer
*integer
=
852 g_new0(struct bt_ctf_field_type_integer
, 1);
854 BT_LOGD("Creating integer field type object: size=%u", size
);
857 BT_LOGE_STR("Failed to allocate one integer field type.");
861 if (size
== 0 || size
> 64) {
862 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
867 integer
->parent
.id
= BT_CTF_FIELD_TYPE_ID_INTEGER
;
868 integer
->size
= size
;
869 integer
->base
= BT_CTF_INTEGER_BASE_DECIMAL
;
870 integer
->encoding
= BT_CTF_STRING_ENCODING_NONE
;
871 bt_ctf_field_type_init(&integer
->parent
, TRUE
);
872 BT_LOGD("Created integer field type object: addr=%p, size=%u",
873 &integer
->parent
, size
);
874 return &integer
->parent
;
877 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type
*type
)
880 struct bt_ctf_field_type_integer
*integer
;
883 BT_LOGW_STR("Invalid parameter: field type is NULL.");
888 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
889 BT_LOGW("Invalid parameter: field type is not an integer field type: "
890 "addr=%p, ft-id=%s", type
,
891 bt_ctf_field_type_id_string(type
->id
));
896 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
897 ret
= (int) integer
->size
;
902 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type
*type
)
905 struct bt_ctf_field_type_integer
*integer
;
908 BT_LOGW_STR("Invalid parameter: field type is NULL.");
913 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
914 BT_LOGW("Invalid parameter: field type is not an integer field type: "
915 "addr=%p, ft-id=%s", type
,
916 bt_ctf_field_type_id_string(type
->id
));
921 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
922 ret
= integer
->is_signed
;
927 bt_bool
bt_ctf_field_type_integer_is_signed(
928 struct bt_ctf_field_type
*int_field_type
)
930 return bt_ctf_field_type_integer_get_signed(int_field_type
) ?
934 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type
*type
,
938 struct bt_ctf_field_type_integer
*integer
;
941 BT_LOGW_STR("Invalid parameter: field type is NULL.");
947 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
953 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
954 BT_LOGW("Invalid parameter: field type is not an integer field type: "
955 "addr=%p, ft-id=%s", type
,
956 bt_ctf_field_type_id_string(type
->id
));
961 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
962 integer
->is_signed
= !!is_signed
;
963 BT_LOGV("Set integer field type's signedness: addr=%p, is-signed=%d",
969 int bt_ctf_field_type_integer_set_size(struct bt_ctf_field_type
*type
,
973 struct bt_ctf_field_type_integer
*integer
;
976 BT_LOGW_STR("Invalid parameter: field type is NULL.");
982 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
988 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
989 BT_LOGW("Invalid parameter: field type is not an integer field type: "
990 "addr=%p, ft-id=%s", type
,
991 bt_ctf_field_type_id_string(type
->id
));
996 if (size
== 0 || size
> 64) {
997 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
998 "addr=%p, size=%u", type
, size
);
1003 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
1004 integer
->size
= size
;
1005 BT_LOGV("Set integer field type's size: addr=%p, size=%u",
1011 enum bt_ctf_integer_base
bt_ctf_field_type_integer_get_base(
1012 struct bt_ctf_field_type
*type
)
1014 enum bt_ctf_integer_base ret
= BT_CTF_INTEGER_BASE_UNKNOWN
;
1015 struct bt_ctf_field_type_integer
*integer
;
1018 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1022 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1023 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1024 "addr=%p, ft-id=%s", type
,
1025 bt_ctf_field_type_id_string(type
->id
));
1029 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
1030 ret
= integer
->base
;
1035 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type
*type
,
1036 enum bt_ctf_integer_base base
)
1041 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1047 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1053 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1054 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1055 "addr=%p, ft-id=%s", type
,
1056 bt_ctf_field_type_id_string(type
->id
));
1062 case BT_CTF_INTEGER_BASE_BINARY
:
1063 case BT_CTF_INTEGER_BASE_OCTAL
:
1064 case BT_CTF_INTEGER_BASE_DECIMAL
:
1065 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
1067 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
1068 struct bt_ctf_field_type_integer
, parent
);
1069 integer
->base
= base
;
1073 BT_LOGW("Invalid parameter: unknown integer field type base: "
1074 "addr=%p, base=%d", type
, base
);
1078 BT_LOGV("Set integer field type's base: addr=%p, base=%s",
1079 type
, bt_ctf_integer_base_string(base
));
1085 enum bt_ctf_string_encoding
bt_ctf_field_type_integer_get_encoding(
1086 struct bt_ctf_field_type
*type
)
1088 enum bt_ctf_string_encoding ret
= BT_CTF_STRING_ENCODING_UNKNOWN
;
1089 struct bt_ctf_field_type_integer
*integer
;
1092 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1096 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1097 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1098 "addr=%p, ft-id=%s", type
,
1099 bt_ctf_field_type_id_string(type
->id
));
1103 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
1104 ret
= integer
->encoding
;
1109 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type
*type
,
1110 enum bt_ctf_string_encoding encoding
)
1113 struct bt_ctf_field_type_integer
*integer
;
1116 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1122 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1128 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1129 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1130 "addr=%p, ft-id=%s", type
,
1131 bt_ctf_field_type_id_string(type
->id
));
1136 if (encoding
< BT_CTF_STRING_ENCODING_NONE
||
1137 encoding
>= BT_CTF_STRING_ENCODING_UNKNOWN
) {
1138 BT_LOGW("Invalid parameter: unknown string encoding: "
1139 "addr=%p, encoding=%d", type
, encoding
);
1144 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
1145 integer
->encoding
= encoding
;
1146 BT_LOGV("Set integer field type's encoding: addr=%p, encoding=%s",
1147 type
, bt_ctf_string_encoding_string(encoding
));
1152 struct bt_ctf_clock_class
*bt_ctf_field_type_integer_get_mapped_clock_class(
1153 struct bt_ctf_field_type
*type
)
1155 struct bt_ctf_field_type_integer
*integer
;
1156 struct bt_ctf_clock_class
*clock_class
= NULL
;
1159 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1163 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
1164 clock_class
= integer
->mapped_clock
;
1165 bt_get(clock_class
);
1170 int bt_ctf_field_type_integer_set_mapped_clock_class(
1171 struct bt_ctf_field_type
*type
,
1172 struct bt_ctf_clock_class
*clock_class
)
1174 struct bt_ctf_field_type_integer
*integer
;
1178 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1184 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
1190 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1196 if (!bt_ctf_clock_class_is_valid(clock_class
)) {
1197 BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
1198 "clock-class-addr=%p, clock-class-name=\"%s\"",
1200 bt_ctf_clock_class_get_name(clock_class
));
1205 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
1206 bt_put(integer
->mapped_clock
);
1207 integer
->mapped_clock
= bt_get(clock_class
);
1208 BT_LOGV("Set integer field type's mapped clock class: ft-addr=%p, "
1209 "clock-class-addr=%p, clock-class-name=\"%s\"",
1210 type
, clock_class
, bt_ctf_clock_class_get_name(clock_class
));
1216 void bt_ctf_field_type_enum_iter_destroy(struct bt_object
*obj
)
1218 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
=
1220 struct bt_ctf_field_type_enumeration_mapping_iterator
,
1223 bt_put(&iter
->enumeration_type
->parent
);
1228 struct bt_ctf_field_type_enumeration_mapping_iterator
*
1229 bt_ctf_field_type_enumeration_find_mappings_type(
1230 struct bt_ctf_field_type
*type
,
1231 enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type
)
1233 struct bt_ctf_field_type_enumeration
*enumeration_type
;
1234 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1237 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1241 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ENUM
) {
1242 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1243 "addr=%p, ft-id=%s", type
,
1244 bt_ctf_field_type_id_string(type
->id
));
1248 enumeration_type
= container_of(type
,
1249 struct bt_ctf_field_type_enumeration
, parent
);
1250 iter
= g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator
, 1);
1252 BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
1256 bt_object_init(&iter
->base
, bt_ctf_field_type_enum_iter_destroy
);
1258 iter
->enumeration_type
= enumeration_type
;
1260 iter
->type
= iterator_type
;
1265 struct bt_ctf_field_type_enumeration_mapping_iterator
*
1266 bt_ctf_field_type_enumeration_find_mappings_by_name(
1267 struct bt_ctf_field_type
*type
, const char *name
)
1269 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
;
1271 iter
= bt_ctf_field_type_enumeration_find_mappings_type(
1272 type
, ITERATOR_BY_NAME
);
1274 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1275 "ft-addr=%p, mapping-name=\"%s\"", type
, name
);
1279 iter
->u
.name_quark
= g_quark_try_string(name
);
1280 if (!iter
->u
.name_quark
) {
1281 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
1285 /* Advance iterator to first entry, or leave index at -1. */
1286 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter
)) {
1287 /* No entry found. */
1297 int bt_ctf_field_type_enumeration_mapping_iterator_next(
1298 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
)
1300 struct bt_ctf_field_type_enumeration
*enumeration
;
1301 struct bt_ctf_field_type
*type
;
1302 int i
, ret
= 0, len
;
1305 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1310 enumeration
= iter
->enumeration_type
;
1311 type
= &enumeration
->parent
;
1312 len
= enumeration
->entries
->len
;
1313 for (i
= iter
->index
+ 1; i
< len
; i
++) {
1314 struct enumeration_mapping
*mapping
=
1315 get_enumeration_mapping(type
, i
);
1317 switch (iter
->type
) {
1318 case ITERATOR_BY_NAME
:
1319 if (mapping
->string
== iter
->u
.name_quark
) {
1324 case ITERATOR_BY_SIGNED_VALUE
:
1326 int64_t value
= iter
->u
.signed_value
;
1328 if (value
>= mapping
->range_start
._signed
&&
1329 value
<= mapping
->range_end
._signed
) {
1335 case ITERATOR_BY_UNSIGNED_VALUE
:
1337 uint64_t value
= iter
->u
.unsigned_value
;
1339 if (value
>= mapping
->range_start
._unsigned
&&
1340 value
<= mapping
->range_end
._unsigned
) {
1356 struct bt_ctf_field_type_enumeration_mapping_iterator
*
1357 bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
1358 struct bt_ctf_field_type
*type
, int64_t value
)
1360 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
;
1362 iter
= bt_ctf_field_type_enumeration_find_mappings_type(
1363 type
, ITERATOR_BY_SIGNED_VALUE
);
1365 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1366 "ft-addr=%p, value=%" PRId64
, type
, value
);
1370 if (bt_ctf_field_type_integer_get_signed(
1371 iter
->enumeration_type
->container
) != 1) {
1372 BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
1373 "enum-ft-addr=%p, int-ft-addr=%p",
1374 type
, iter
->enumeration_type
->container
);
1378 iter
->u
.signed_value
= value
;
1380 /* Advance iterator to first entry, or leave index at -1. */
1381 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter
)) {
1382 /* No entry found. */
1392 struct bt_ctf_field_type_enumeration_mapping_iterator
*
1393 bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
1394 struct bt_ctf_field_type
*type
, uint64_t value
)
1396 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1399 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1403 iter
= bt_ctf_field_type_enumeration_find_mappings_type(
1404 type
, ITERATOR_BY_UNSIGNED_VALUE
);
1406 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1407 "ft-addr=%p, value=%" PRIu64
, type
, value
);
1411 if (bt_ctf_field_type_integer_get_signed(
1412 iter
->enumeration_type
->container
) != 0) {
1413 BT_LOGW("Invalid parameter: enumeration field type is signed: "
1414 "enum-ft-addr=%p, int-ft-addr=%p",
1415 type
, iter
->enumeration_type
->container
);
1418 iter
->u
.unsigned_value
= value
;
1420 /* Advance iterator to first entry, or leave index at -1. */
1421 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter
)) {
1422 /* No entry found. */
1432 int bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
1433 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
,
1434 const char **mapping_name
, int64_t *range_begin
,
1440 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1445 ret
= bt_ctf_field_type_enumeration_get_mapping_signed(
1446 &iter
->enumeration_type
->parent
, iter
->index
,
1447 mapping_name
, range_begin
, range_end
);
1452 int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
1453 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
,
1454 const char **mapping_name
, uint64_t *range_begin
,
1455 uint64_t *range_end
)
1460 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1465 ret
= bt_ctf_field_type_enumeration_get_mapping_unsigned(
1466 &iter
->enumeration_type
->parent
, iter
->index
,
1467 mapping_name
, range_begin
, range_end
);
1472 int bt_ctf_field_type_enumeration_get_mapping_signed(
1473 struct bt_ctf_field_type
*enum_field_type
,
1474 uint64_t index
, const char **mapping_name
, int64_t *range_begin
,
1478 struct enumeration_mapping
*mapping
;
1480 if (!enum_field_type
) {
1481 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1486 mapping
= get_enumeration_mapping(enum_field_type
, index
);
1488 /* get_enumeration_mapping() reports any error */
1494 *mapping_name
= g_quark_to_string(mapping
->string
);
1498 *range_begin
= mapping
->range_start
._signed
;
1502 *range_end
= mapping
->range_end
._signed
;
1508 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
1509 struct bt_ctf_field_type
*enum_field_type
,
1511 const char **mapping_name
, uint64_t *range_begin
,
1512 uint64_t *range_end
)
1515 struct enumeration_mapping
*mapping
;
1517 if (!enum_field_type
) {
1518 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1523 mapping
= get_enumeration_mapping(enum_field_type
, index
);
1525 /* get_enumeration_mapping() reports any error */
1531 *mapping_name
= g_quark_to_string(mapping
->string
);
1535 *range_begin
= mapping
->range_start
._unsigned
;
1539 *range_end
= mapping
->range_end
._unsigned
;
1545 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_create(
1546 struct bt_ctf_field_type
*integer_container_type
)
1548 struct bt_ctf_field_type_enumeration
*enumeration
= NULL
;
1550 BT_LOGD("Creating enumeration field type object: int-ft-addr=%p",
1551 integer_container_type
);
1553 if (!integer_container_type
) {
1554 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1558 if (integer_container_type
->id
!= BT_CTF_FIELD_TYPE_ID_INTEGER
) {
1559 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
1560 "container-ft-addr=%p, container-ft-id=%s",
1561 integer_container_type
,
1562 bt_ctf_field_type_id_string(integer_container_type
->id
));
1566 enumeration
= g_new0(struct bt_ctf_field_type_enumeration
, 1);
1568 BT_LOGE_STR("Failed to allocate one enumeration field type.");
1572 enumeration
->parent
.id
= BT_CTF_FIELD_TYPE_ID_ENUM
;
1573 bt_get(integer_container_type
);
1574 enumeration
->container
= integer_container_type
;
1575 enumeration
->entries
= g_ptr_array_new_with_free_func(
1576 (GDestroyNotify
)destroy_enumeration_mapping
);
1577 bt_ctf_field_type_init(&enumeration
->parent
, FALSE
);
1578 BT_LOGD("Created enumeration field type object: addr=%p, "
1579 "int-ft-addr=%p, int-ft-size=%u",
1580 &enumeration
->parent
, integer_container_type
,
1581 bt_ctf_field_type_integer_get_size(integer_container_type
));
1582 return &enumeration
->parent
;
1584 g_free(enumeration
);
1588 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_get_container_type(
1589 struct bt_ctf_field_type
*type
)
1591 struct bt_ctf_field_type
*container_type
= NULL
;
1592 struct bt_ctf_field_type_enumeration
*enumeration_type
;
1595 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1599 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ENUM
) {
1600 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1601 "addr=%p, ft-id=%s", type
,
1602 bt_ctf_field_type_id_string(type
->id
));
1606 enumeration_type
= container_of(type
,
1607 struct bt_ctf_field_type_enumeration
, parent
);
1608 container_type
= enumeration_type
->container
;
1609 bt_get(container_type
);
1611 return container_type
;
1614 int bt_ctf_field_type_enumeration_add_mapping_signed(
1615 struct bt_ctf_field_type
*type
, const char *string
,
1616 int64_t range_start
, int64_t range_end
)
1619 GQuark mapping_name
;
1620 struct enumeration_mapping
*mapping
;
1621 struct bt_ctf_field_type_enumeration
*enumeration
;
1622 char *escaped_string
;
1625 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1631 BT_LOGW_STR("Invalid parameter: string is NULL.");
1637 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1643 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ENUM
) {
1644 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1645 "addr=%p, ft-id=%s", type
,
1646 bt_ctf_field_type_id_string(type
->id
));
1651 if (range_end
< range_start
) {
1652 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1653 "addr=%p, range-start=%" PRId64
", range-end=%" PRId64
,
1654 type
, range_start
, range_end
);
1659 if (strlen(string
) == 0) {
1660 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1661 "enum-ft-addr=%p, mapping-name-addr=%p", type
,
1667 escaped_string
= g_strescape(string
, NULL
);
1668 if (!escaped_string
) {
1669 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1670 "mapping-name-addr=%p, mapping-name=\"%s\"",
1671 type
, string
, string
);
1676 mapping
= g_new(struct enumeration_mapping
, 1);
1678 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1682 mapping_name
= g_quark_from_string(escaped_string
);
1683 *mapping
= (struct enumeration_mapping
) {
1684 .range_start
._signed
= range_start
,
1685 .range_end
._signed
= range_end
,
1686 .string
= mapping_name
,
1688 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
1690 g_ptr_array_add(enumeration
->entries
, mapping
);
1691 g_ptr_array_sort(enumeration
->entries
,
1692 (GCompareFunc
)compare_enumeration_mappings_signed
);
1693 BT_LOGV("Added mapping to signed enumeration field type: addr=%p, "
1694 "name=\"%s\", range-start=%" PRId64
", "
1695 "range-end=%" PRId64
,
1696 type
, string
, range_start
, range_end
);
1698 free(escaped_string
);
1703 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
1704 struct bt_ctf_field_type
*type
, const char *string
,
1705 uint64_t range_start
, uint64_t range_end
)
1708 GQuark mapping_name
;
1709 struct enumeration_mapping
*mapping
;
1710 struct bt_ctf_field_type_enumeration
*enumeration
;
1711 char *escaped_string
;
1714 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1720 BT_LOGW_STR("Invalid parameter: string is NULL.");
1726 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1732 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ENUM
) {
1733 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1734 "addr=%p, ft-id=%s", type
,
1735 bt_ctf_field_type_id_string(type
->id
));
1740 if (range_end
< range_start
) {
1741 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1742 "addr=%p, range-start=%" PRIu64
", range-end=%" PRIu64
,
1743 type
, range_start
, range_end
);
1748 if (strlen(string
) == 0) {
1749 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1750 "enum-ft-addr=%p, mapping-name-addr=%p", type
,
1756 escaped_string
= g_strescape(string
, NULL
);
1757 if (!escaped_string
) {
1758 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1759 "mapping-name-addr=%p, mapping-name=\"%s\"",
1760 type
, string
, string
);
1765 mapping
= g_new(struct enumeration_mapping
, 1);
1767 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1771 mapping_name
= g_quark_from_string(escaped_string
);
1772 *mapping
= (struct enumeration_mapping
) {
1773 .range_start
._unsigned
= range_start
,
1774 .range_end
._unsigned
= range_end
,
1775 .string
= mapping_name
,
1777 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
1779 g_ptr_array_add(enumeration
->entries
, mapping
);
1780 g_ptr_array_sort(enumeration
->entries
,
1781 (GCompareFunc
)compare_enumeration_mappings_unsigned
);
1782 BT_LOGV("Added mapping to unsigned enumeration field type: addr=%p, "
1783 "name=\"%s\", range-start=%" PRIu64
", "
1784 "range-end=%" PRIu64
,
1785 type
, string
, range_start
, range_end
);
1787 free(escaped_string
);
1792 int64_t bt_ctf_field_type_enumeration_get_mapping_count(
1793 struct bt_ctf_field_type
*type
)
1796 struct bt_ctf_field_type_enumeration
*enumeration
;
1799 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1804 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ENUM
) {
1805 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1806 "addr=%p, ft-id=%s", type
,
1807 bt_ctf_field_type_id_string(type
->id
));
1812 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
1814 ret
= (int64_t) enumeration
->entries
->len
;
1819 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_create(void)
1821 struct bt_ctf_field_type_floating_point
*floating_point
=
1822 g_new0(struct bt_ctf_field_type_floating_point
, 1);
1824 BT_LOGD_STR("Creating floating point number field type object.");
1826 if (!floating_point
) {
1827 BT_LOGE_STR("Failed to allocate one floating point number field type.");
1831 floating_point
->parent
.id
= BT_CTF_FIELD_TYPE_ID_FLOAT
;
1832 floating_point
->exp_dig
= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
;
1833 floating_point
->mant_dig
= FLT_MANT_DIG
;
1834 bt_ctf_field_type_init(&floating_point
->parent
, TRUE
);
1835 BT_LOGD("Created floating point number field type object: addr=%p, "
1836 "exp-size=%u, mant-size=%u", &floating_point
->parent
,
1837 floating_point
->exp_dig
, floating_point
->mant_dig
);
1839 return floating_point
? &floating_point
->parent
: NULL
;
1842 int bt_ctf_field_type_floating_point_get_exponent_digits(
1843 struct bt_ctf_field_type
*type
)
1846 struct bt_ctf_field_type_floating_point
*floating_point
;
1849 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1854 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_FLOAT
) {
1855 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1856 "addr=%p, ft-id=%s", type
,
1857 bt_ctf_field_type_id_string(type
->id
));
1862 floating_point
= container_of(type
,
1863 struct bt_ctf_field_type_floating_point
, parent
);
1864 ret
= (int) floating_point
->exp_dig
;
1869 int bt_ctf_field_type_floating_point_set_exponent_digits(
1870 struct bt_ctf_field_type
*type
,
1871 unsigned int exponent_digits
)
1874 struct bt_ctf_field_type_floating_point
*floating_point
;
1877 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1883 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1889 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_FLOAT
) {
1890 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1891 "addr=%p, ft-id=%s", type
,
1892 bt_ctf_field_type_id_string(type
->id
));
1897 floating_point
= container_of(type
,
1898 struct bt_ctf_field_type_floating_point
, parent
);
1899 if ((exponent_digits
!= sizeof(float) * CHAR_BIT
- FLT_MANT_DIG
) &&
1900 (exponent_digits
!= sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
) &&
1902 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
)) {
1903 BT_LOGW("Invalid parameter: invalid exponent size: "
1904 "addr=%p, exp-size=%u", type
, exponent_digits
);
1909 floating_point
->exp_dig
= exponent_digits
;
1910 BT_LOGV("Set floating point number field type's exponent size: addr=%p, "
1911 "exp-size=%u", type
, exponent_digits
);
1916 int bt_ctf_field_type_floating_point_get_mantissa_digits(
1917 struct bt_ctf_field_type
*type
)
1920 struct bt_ctf_field_type_floating_point
*floating_point
;
1923 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1928 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_FLOAT
) {
1929 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1930 "addr=%p, ft-id=%s", type
,
1931 bt_ctf_field_type_id_string(type
->id
));
1936 floating_point
= container_of(type
,
1937 struct bt_ctf_field_type_floating_point
, parent
);
1938 ret
= (int) floating_point
->mant_dig
;
1943 int bt_ctf_field_type_floating_point_set_mantissa_digits(
1944 struct bt_ctf_field_type
*type
,
1945 unsigned int mantissa_digits
)
1948 struct bt_ctf_field_type_floating_point
*floating_point
;
1951 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1957 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1963 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_FLOAT
) {
1964 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1965 "addr=%p, ft-id=%s", type
,
1966 bt_ctf_field_type_id_string(type
->id
));
1971 floating_point
= container_of(type
,
1972 struct bt_ctf_field_type_floating_point
, parent
);
1974 if ((mantissa_digits
!= FLT_MANT_DIG
) &&
1975 (mantissa_digits
!= DBL_MANT_DIG
) &&
1976 (mantissa_digits
!= LDBL_MANT_DIG
)) {
1977 BT_LOGW("Invalid parameter: invalid mantissa size: "
1978 "addr=%p, mant-size=%u", type
, mantissa_digits
);
1983 floating_point
->mant_dig
= mantissa_digits
;
1984 BT_LOGV("Set floating point number field type's mantissa size: addr=%p, "
1985 "mant-size=%u", type
, mantissa_digits
);
1990 struct bt_ctf_field_type
*bt_ctf_field_type_structure_create(void)
1992 struct bt_ctf_field_type_structure
*structure
=
1993 g_new0(struct bt_ctf_field_type_structure
, 1);
1995 BT_LOGD_STR("Creating structure field type object.");
1998 BT_LOGE_STR("Failed to allocate one structure field type.");
2002 structure
->parent
.id
= BT_CTF_FIELD_TYPE_ID_STRUCT
;
2003 structure
->fields
= g_ptr_array_new_with_free_func(
2004 (GDestroyNotify
)destroy_structure_field
);
2005 structure
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
2006 bt_ctf_field_type_init(&structure
->parent
, TRUE
);
2007 BT_LOGD("Created structure field type object: addr=%p",
2008 &structure
->parent
);
2009 return &structure
->parent
;
2014 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type
*type
,
2015 struct bt_ctf_field_type
*field_type
,
2016 const char *field_name
)
2019 struct bt_ctf_field_type_structure
*structure
;
2022 * TODO: check that `field_type` does not contain `type`,
2026 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2032 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2038 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2044 if (bt_ctf_validate_identifier(field_name
)) {
2045 BT_LOGW("Invalid parameter: field name is not a valid CTF identifier: "
2046 "struct-ft-addr=%p, field-name=\"%s\"",
2052 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_STRUCT
) {
2053 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2054 "addr=%p, ft-id=%s", type
,
2055 bt_ctf_field_type_id_string(type
->id
));
2060 if (type
== field_type
) {
2061 BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
2067 structure
= container_of(type
,
2068 struct bt_ctf_field_type_structure
, parent
);
2069 if (add_structure_field(structure
->fields
,
2070 structure
->field_name_to_index
, field_type
, field_name
)) {
2071 BT_LOGW("Cannot add field to structure field type: "
2072 "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2073 type
, field_type
, field_name
);
2078 BT_LOGV("Added structure field type field: struct-ft-addr=%p, "
2079 "field-ft-addr=%p, field-name=\"%s\"", type
,
2080 field_type
, field_name
);
2085 int64_t bt_ctf_field_type_structure_get_field_count(
2086 struct bt_ctf_field_type
*type
)
2089 struct bt_ctf_field_type_structure
*structure
;
2092 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2097 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_STRUCT
) {
2098 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2099 "addr=%p, ft-id=%s", type
,
2100 bt_ctf_field_type_id_string(type
->id
));
2105 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
2107 ret
= (int64_t) structure
->fields
->len
;
2112 int bt_ctf_field_type_structure_get_field_by_index(
2113 struct bt_ctf_field_type
*type
,
2114 const char **field_name
, struct bt_ctf_field_type
**field_type
,
2117 struct bt_ctf_field_type_structure
*structure
;
2118 struct structure_field
*field
;
2122 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2127 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_STRUCT
) {
2128 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2129 "addr=%p, ft-id=%s", type
,
2130 bt_ctf_field_type_id_string(type
->id
));
2135 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
2137 if (index
>= structure
->fields
->len
) {
2138 BT_LOGW("Invalid parameter: index is out of bounds: "
2139 "addr=%p, index=%" PRIu64
", count=%u",
2140 type
, index
, structure
->fields
->len
);
2145 field
= g_ptr_array_index(structure
->fields
, index
);
2147 *field_type
= field
->type
;
2148 bt_get(field
->type
);
2151 *field_name
= g_quark_to_string(field
->name
);
2157 struct bt_ctf_field_type
*bt_ctf_field_type_structure_get_field_type_by_name(
2158 struct bt_ctf_field_type
*type
,
2163 struct structure_field
*field
;
2164 struct bt_ctf_field_type_structure
*structure
;
2165 struct bt_ctf_field_type
*field_type
= NULL
;
2168 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2173 BT_LOGW_STR("Invalid parameter: name is NULL.");
2177 name_quark
= g_quark_try_string(name
);
2179 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
2183 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
2185 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
2186 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
2190 field
= structure
->fields
->pdata
[index
];
2191 field_type
= field
->type
;
2197 struct bt_ctf_field_type
*bt_ctf_field_type_variant_create(
2198 struct bt_ctf_field_type
*enum_tag
, const char *tag_name
)
2200 struct bt_ctf_field_type_variant
*variant
= NULL
;
2202 BT_LOGD("Creating variant field type object: "
2203 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2204 enum_tag
, tag_name
);
2206 if (tag_name
&& bt_ctf_validate_identifier(tag_name
)) {
2207 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2208 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2209 enum_tag
, tag_name
);
2213 variant
= g_new0(struct bt_ctf_field_type_variant
, 1);
2215 BT_LOGE_STR("Failed to allocate one variant field type.");
2219 variant
->parent
.id
= BT_CTF_FIELD_TYPE_ID_VARIANT
;
2220 variant
->tag_name
= g_string_new(tag_name
);
2221 variant
->field_name_to_index
= g_hash_table_new(NULL
, NULL
);
2222 variant
->fields
= g_ptr_array_new_with_free_func(
2223 (GDestroyNotify
) destroy_structure_field
);
2226 variant
->tag
= container_of(enum_tag
,
2227 struct bt_ctf_field_type_enumeration
, parent
);
2230 bt_ctf_field_type_init(&variant
->parent
, TRUE
);
2231 /* A variant's alignment is undefined */
2232 variant
->parent
.alignment
= 0;
2233 BT_LOGD("Created variant field type object: addr=%p, "
2234 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2235 &variant
->parent
, enum_tag
, tag_name
);
2236 return &variant
->parent
;
2241 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_tag_type(
2242 struct bt_ctf_field_type
*type
)
2244 struct bt_ctf_field_type_variant
*variant
;
2245 struct bt_ctf_field_type
*tag_type
= NULL
;
2248 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2252 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2253 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2254 "addr=%p, ft-id=%s", type
,
2255 bt_ctf_field_type_id_string(type
->id
));
2259 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
2260 if (!variant
->tag
) {
2261 BT_LOGV("Variant field type has no tag field type: "
2266 tag_type
= &variant
->tag
->parent
;
2272 const char *bt_ctf_field_type_variant_get_tag_name(
2273 struct bt_ctf_field_type
*type
)
2275 struct bt_ctf_field_type_variant
*variant
;
2276 const char *tag_name
= NULL
;
2279 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2283 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2284 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2285 "addr=%p, ft-id=%s", type
,
2286 bt_ctf_field_type_id_string(type
->id
));
2290 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
2291 if (variant
->tag_name
->len
== 0) {
2292 BT_LOGV("Variant field type has no tag field name: "
2297 tag_name
= variant
->tag_name
->str
;
2302 int bt_ctf_field_type_variant_set_tag_name(
2303 struct bt_ctf_field_type
*type
, const char *name
)
2306 struct bt_ctf_field_type_variant
*variant
;
2309 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2315 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2321 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2322 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2323 "addr=%p, ft-id=%s", type
,
2324 bt_ctf_field_type_id_string(type
->id
));
2329 if (bt_ctf_validate_identifier(name
)) {
2330 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2331 "variant-ft-addr=%p, tag-field-name=\"%s\"",
2337 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
2338 g_string_assign(variant
->tag_name
, name
);
2339 BT_LOGV("Set variant field type's tag field name: addr=%p, "
2340 "tag-field-name=\"%s\"", type
, name
);
2345 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type
*type
,
2346 struct bt_ctf_field_type
*field_type
,
2347 const char *field_name
)
2351 struct bt_ctf_field_type_variant
*variant
;
2352 GQuark field_name_quark
= g_quark_from_string(field_name
);
2355 * TODO: check that `field_type` does not contain `type`,
2359 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2365 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2371 if (bt_ctf_validate_identifier(field_name
)) {
2372 BT_LOGW("Invalid parameter: field name is not a valid CTF identifier: "
2373 "variant-ft-addr=%p, field-name=\"%s\"",
2379 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2380 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2381 "addr=%p, ft-id=%s", type
,
2382 bt_ctf_field_type_id_string(type
->id
));
2387 if (type
== field_type
) {
2388 BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
2394 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
2396 /* The user has explicitly provided a tag; validate against it. */
2400 /* Make sure this name is present in the enum tag */
2401 for (i
= 0; i
< variant
->tag
->entries
->len
; i
++) {
2402 struct enumeration_mapping
*mapping
=
2403 g_ptr_array_index(variant
->tag
->entries
, i
);
2405 if (mapping
->string
== field_name_quark
) {
2412 /* Validation failed */
2413 BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
2414 "variant-ft-addr=%p, tag-ft-addr=%p, "
2415 "tag-field-name=\"%s\""
2416 "field-ft-addr=%p, field-name=\"%s\"",
2417 type
, variant
->tag
, variant
->tag_name
->str
,
2418 field_type
, field_name
);
2424 if (add_structure_field(variant
->fields
, variant
->field_name_to_index
,
2425 field_type
, field_name
)) {
2426 BT_LOGW("Cannot add field to variant field type: "
2427 "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2428 type
, field_type
, field_name
);
2433 BT_LOGV("Added variant field type field: variant-ft-addr=%p, "
2434 "field-ft-addr=%p, field-name=\"%s\"", type
,
2435 field_type
, field_name
);
2441 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_by_name(
2442 struct bt_ctf_field_type
*type
,
2443 const char *field_name
)
2447 struct structure_field
*field
;
2448 struct bt_ctf_field_type_variant
*variant
;
2449 struct bt_ctf_field_type
*field_type
= NULL
;
2452 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2457 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2461 name_quark
= g_quark_try_string(field_name
);
2463 BT_LOGE("Cannot get GQuark: string=\"%s\"", field_name
);
2467 variant
= container_of(type
, struct bt_ctf_field_type_variant
, parent
);
2468 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
2469 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
2473 field
= g_ptr_array_index(variant
->fields
, index
);
2474 field_type
= field
->type
;
2480 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_from_tag(
2481 struct bt_ctf_field_type
*type
,
2482 struct bt_ctf_field
*tag
)
2485 const char *enum_value
;
2486 struct bt_ctf_field_type
*field_type
= NULL
;
2487 struct bt_ctf_field_type_enumeration_mapping_iterator
*iter
= NULL
;
2490 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
2495 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
2499 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2500 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2501 "addr=%p, ft-id=%s", type
,
2502 bt_ctf_field_type_id_string(type
->id
));
2506 iter
= bt_ctf_field_enumeration_get_mappings(tag
);
2508 BT_LOGE("Cannot get enumeration field type mapping iterator from enumeration field: "
2509 "enum-field-addr=%p", tag
);
2513 ret
= bt_ctf_field_type_enumeration_mapping_iterator_get_signed(iter
,
2514 &enum_value
, NULL
, NULL
);
2516 BT_LOGW("Cannot get enumeration field type mapping iterator's current mapping: "
2517 "iter-addr=%p", iter
);
2521 field_type
= bt_ctf_field_type_variant_get_field_type_by_name(
2528 int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type
*type
)
2531 struct bt_ctf_field_type_variant
*variant
;
2534 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2539 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2540 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2541 "addr=%p, ft-id=%s", type
,
2542 bt_ctf_field_type_id_string(type
->id
));
2547 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
2549 ret
= (int64_t) variant
->fields
->len
;
2555 int bt_ctf_field_type_variant_get_field_by_index(struct bt_ctf_field_type
*type
,
2556 const char **field_name
, struct bt_ctf_field_type
**field_type
,
2559 struct bt_ctf_field_type_variant
*variant
;
2560 struct structure_field
*field
;
2564 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2569 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_VARIANT
) {
2570 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2571 "addr=%p, ft-id=%s", type
,
2572 bt_ctf_field_type_id_string(type
->id
));
2577 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
2579 if (index
>= variant
->fields
->len
) {
2580 BT_LOGW("Invalid parameter: index is out of bounds: "
2581 "addr=%p, index=%" PRIu64
", count=%u",
2582 type
, index
, variant
->fields
->len
);
2587 field
= g_ptr_array_index(variant
->fields
, index
);
2589 *field_type
= field
->type
;
2590 bt_get(field
->type
);
2593 *field_name
= g_quark_to_string(field
->name
);
2599 struct bt_ctf_field_type
*bt_ctf_field_type_array_create(
2600 struct bt_ctf_field_type
*element_type
,
2601 unsigned int length
)
2603 struct bt_ctf_field_type_array
*array
= NULL
;
2605 BT_LOGD("Creating array field type object: element-ft-addr=%p, "
2606 "length=%u", element_type
, length
);
2608 if (!element_type
) {
2609 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2614 BT_LOGW_STR("Invalid parameter: length is zero.");
2618 array
= g_new0(struct bt_ctf_field_type_array
, 1);
2620 BT_LOGE_STR("Failed to allocate one array field type.");
2624 array
->parent
.id
= BT_CTF_FIELD_TYPE_ID_ARRAY
;
2625 bt_get(element_type
);
2626 array
->element_type
= element_type
;
2627 array
->length
= length
;
2628 bt_ctf_field_type_init(&array
->parent
, FALSE
);
2629 BT_LOGD("Created array field type object: addr=%p, "
2630 "element-ft-addr=%p, length=%u",
2631 &array
->parent
, element_type
, length
);
2632 return &array
->parent
;
2637 struct bt_ctf_field_type
*bt_ctf_field_type_array_get_element_type(
2638 struct bt_ctf_field_type
*type
)
2640 struct bt_ctf_field_type
*ret
= NULL
;
2641 struct bt_ctf_field_type_array
*array
;
2644 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2648 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ARRAY
) {
2649 BT_LOGW("Invalid parameter: field type is not an array field type: "
2650 "addr=%p, ft-id=%s", type
,
2651 bt_ctf_field_type_id_string(type
->id
));
2655 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
2656 ret
= array
->element_type
;
2663 int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type
*type
,
2664 struct bt_ctf_field_type
*element_type
)
2667 struct bt_ctf_field_type_array
*array
;
2670 BT_LOGW_STR("Invalid parameter: array field type is NULL.");
2675 if (!element_type
) {
2676 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2681 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ARRAY
) {
2682 BT_LOGW("Invalid parameter: field type is not an array field type: "
2683 "addr=%p, ft-id=%s", type
,
2684 bt_ctf_field_type_id_string(type
->id
));
2689 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
2691 if (array
->element_type
) {
2692 BT_PUT(array
->element_type
);
2695 array
->element_type
= element_type
;
2696 bt_get(array
->element_type
);
2697 BT_LOGV("Set array field type's element field type: array-ft-addr=%p, "
2698 "element-ft-addr=%p", type
, element_type
);
2704 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type
*type
)
2707 struct bt_ctf_field_type_array
*array
;
2710 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2715 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_ARRAY
) {
2716 BT_LOGW("Invalid parameter: field type is not an array field type: "
2717 "addr=%p, ft-id=%s", type
,
2718 bt_ctf_field_type_id_string(type
->id
));
2723 array
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
2724 ret
= (int64_t) array
->length
;
2729 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_create(
2730 struct bt_ctf_field_type
*element_type
,
2731 const char *length_field_name
)
2733 struct bt_ctf_field_type_sequence
*sequence
= NULL
;
2735 BT_LOGD("Creating sequence field type object: element-ft-addr=%p, "
2736 "length-field-name=\"%s\"", element_type
, length_field_name
);
2738 if (!element_type
) {
2739 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2743 if (bt_ctf_validate_identifier(length_field_name
)) {
2744 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
2745 "length-field-name=\"%s\"", length_field_name
);
2749 sequence
= g_new0(struct bt_ctf_field_type_sequence
, 1);
2751 BT_LOGE_STR("Failed to allocate one sequence field type.");
2755 sequence
->parent
.id
= BT_CTF_FIELD_TYPE_ID_SEQUENCE
;
2756 bt_get(element_type
);
2757 sequence
->element_type
= element_type
;
2758 sequence
->length_field_name
= g_string_new(length_field_name
);
2759 bt_ctf_field_type_init(&sequence
->parent
, FALSE
);
2760 BT_LOGD("Created sequence field type object: addr=%p, "
2761 "element-ft-addr=%p, length-field-name=\"%s\"",
2762 &sequence
->parent
, element_type
, length_field_name
);
2763 return &sequence
->parent
;
2768 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_get_element_type(
2769 struct bt_ctf_field_type
*type
)
2771 struct bt_ctf_field_type
*ret
= NULL
;
2772 struct bt_ctf_field_type_sequence
*sequence
;
2775 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2779 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
2780 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2781 "addr=%p, ft-id=%s", type
,
2782 bt_ctf_field_type_id_string(type
->id
));
2786 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
2788 ret
= sequence
->element_type
;
2795 int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type
*type
,
2796 struct bt_ctf_field_type
*element_type
)
2799 struct bt_ctf_field_type_sequence
*sequence
;
2802 BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
2807 if (!element_type
) {
2808 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2813 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
2814 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2815 "addr=%p, ft-id=%s", type
,
2816 bt_ctf_field_type_id_string(type
->id
));
2821 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
, parent
);
2822 if (sequence
->element_type
) {
2823 BT_PUT(sequence
->element_type
);
2826 sequence
->element_type
= element_type
;
2827 bt_get(sequence
->element_type
);
2828 BT_LOGV("Set sequence field type's element field type: sequence-ft-addr=%p, "
2829 "element-ft-addr=%p", type
, element_type
);
2835 const char *bt_ctf_field_type_sequence_get_length_field_name(
2836 struct bt_ctf_field_type
*type
)
2838 const char *ret
= NULL
;
2839 struct bt_ctf_field_type_sequence
*sequence
;
2842 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2846 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
2847 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2848 "addr=%p, ft-id=%s", type
,
2849 bt_ctf_field_type_id_string(type
->id
));
2853 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
2855 ret
= sequence
->length_field_name
->str
;
2860 struct bt_ctf_field_type
*bt_ctf_field_type_string_create(void)
2862 struct bt_ctf_field_type_string
*string
=
2863 g_new0(struct bt_ctf_field_type_string
, 1);
2865 BT_LOGD_STR("Creating string field type object.");
2868 BT_LOGE_STR("Failed to allocate one string field type.");
2872 string
->parent
.id
= BT_CTF_FIELD_TYPE_ID_STRING
;
2873 bt_ctf_field_type_init(&string
->parent
, TRUE
);
2874 string
->encoding
= BT_CTF_STRING_ENCODING_UTF8
;
2875 string
->parent
.alignment
= CHAR_BIT
;
2876 BT_LOGD("Created string field type object: addr=%p", &string
->parent
);
2877 return &string
->parent
;
2880 enum bt_ctf_string_encoding
bt_ctf_field_type_string_get_encoding(
2881 struct bt_ctf_field_type
*type
)
2883 struct bt_ctf_field_type_string
*string
;
2884 enum bt_ctf_string_encoding ret
= BT_CTF_STRING_ENCODING_UNKNOWN
;
2887 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2891 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_STRING
) {
2892 BT_LOGW("Invalid parameter: field type is not a string field type: "
2893 "addr=%p, ft-id=%s", type
,
2894 bt_ctf_field_type_id_string(type
->id
));
2898 string
= container_of(type
, struct bt_ctf_field_type_string
,
2900 ret
= string
->encoding
;
2905 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type
*type
,
2906 enum bt_ctf_string_encoding encoding
)
2909 struct bt_ctf_field_type_string
*string
;
2912 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2917 if (type
->id
!= BT_CTF_FIELD_TYPE_ID_STRING
) {
2918 BT_LOGW("Invalid parameter: field type is not a string field type: "
2919 "addr=%p, ft-id=%s", type
,
2920 bt_ctf_field_type_id_string(type
->id
));
2925 if ((encoding
!= BT_CTF_STRING_ENCODING_UTF8
&&
2926 encoding
!= BT_CTF_STRING_ENCODING_ASCII
)) {
2927 BT_LOGW("Invalid parameter: unknown string encoding: "
2928 "addr=%p, encoding=%d", type
, encoding
);
2933 string
= container_of(type
, struct bt_ctf_field_type_string
, parent
);
2934 string
->encoding
= encoding
;
2935 BT_LOGV("Set string field type's encoding: addr=%p, encoding=%s",
2936 type
, bt_ctf_string_encoding_string(encoding
));
2941 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type
*type
)
2944 enum bt_ctf_field_type_id type_id
;
2947 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2953 ret
= (int) type
->alignment
;
2957 type_id
= bt_ctf_field_type_get_type_id(type
);
2959 case BT_CTF_FIELD_TYPE_ID_SEQUENCE
:
2961 struct bt_ctf_field_type
*element
=
2962 bt_ctf_field_type_sequence_get_element_type(type
);
2965 ret
= bt_ctf_field_type_get_alignment(element
);
2969 case BT_CTF_FIELD_TYPE_ID_ARRAY
:
2971 struct bt_ctf_field_type
*element
=
2972 bt_ctf_field_type_array_get_element_type(type
);
2975 ret
= bt_ctf_field_type_get_alignment(element
);
2979 case BT_CTF_FIELD_TYPE_ID_STRUCT
:
2981 int64_t i
, element_count
;
2983 element_count
= bt_ctf_field_type_structure_get_field_count(
2985 assert(element_count
>= 0);
2987 for (i
= 0; i
< element_count
; i
++) {
2988 struct bt_ctf_field_type
*field
;
2989 int field_alignment
;
2991 ret
= bt_ctf_field_type_structure_get_field_by_index(
2992 type
, NULL
, &field
, i
);
2995 field_alignment
= bt_ctf_field_type_get_alignment(
2998 if (field_alignment
< 0) {
2999 ret
= field_alignment
;
3003 type
->alignment
= MAX(field_alignment
, type
->alignment
);
3005 ret
= (int) type
->alignment
;
3008 case BT_CTF_FIELD_TYPE_ID_UNKNOWN
:
3009 BT_LOGW("Invalid parameter: unknown field type ID: "
3010 "addr=%p, ft-id=%d", type
, type_id
);
3014 ret
= (int) type
->alignment
;
3022 int is_power_of_two(unsigned int value
)
3024 return ((value
& (value
- 1)) == 0) && value
> 0;
3027 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type
*type
,
3028 unsigned int alignment
)
3031 enum bt_ctf_field_type_id type_id
;
3033 /* Alignment must be a power of two */
3035 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3041 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3047 if (!is_power_of_two(alignment
)) {
3048 BT_LOGW("Invalid parameter: alignment is not a power of two: "
3049 "addr=%p, align=%u", type
, alignment
);
3054 type_id
= bt_ctf_field_type_get_type_id(type
);
3055 if (type_id
== BT_CTF_FIELD_TYPE_ID_UNKNOWN
) {
3056 BT_LOGW("Invalid parameter: unknown field type ID: "
3057 "addr=%p, ft-id=%d", type
, type_id
);
3062 if (type
->id
== BT_CTF_FIELD_TYPE_ID_STRING
&&
3063 alignment
!= CHAR_BIT
) {
3064 BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
3065 "addr=%p, align=%u", CHAR_BIT
, type
, alignment
);
3070 if (type_id
== BT_CTF_FIELD_TYPE_ID_VARIANT
||
3071 type_id
== BT_CTF_FIELD_TYPE_ID_SEQUENCE
||
3072 type_id
== BT_CTF_FIELD_TYPE_ID_ARRAY
) {
3073 /* Setting an alignment on these types makes no sense */
3074 BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
3075 "addr=%p, ft-id=%s", type
,
3076 bt_ctf_field_type_id_string(type
->id
));
3081 type
->alignment
= alignment
;
3083 BT_LOGV("Set field type's alignment: addr=%p, align=%u",
3089 enum bt_ctf_byte_order
bt_ctf_field_type_get_byte_order(
3090 struct bt_ctf_field_type
*type
)
3092 enum bt_ctf_byte_order ret
= BT_CTF_BYTE_ORDER_UNKNOWN
;
3095 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3100 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
3102 struct bt_ctf_field_type_integer
*integer
= container_of(
3103 type
, struct bt_ctf_field_type_integer
, parent
);
3104 ret
= integer
->user_byte_order
;
3107 case BT_CTF_FIELD_TYPE_ID_ENUM
:
3109 struct bt_ctf_field_type_enumeration
*enum_ft
= container_of(
3110 type
, struct bt_ctf_field_type_enumeration
, parent
);
3111 ret
= bt_ctf_field_type_get_byte_order(enum_ft
->container
);
3114 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
3116 struct bt_ctf_field_type_floating_point
*floating_point
=
3118 struct bt_ctf_field_type_floating_point
,
3120 ret
= floating_point
->user_byte_order
;
3124 BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
3125 "addr=%p, ft-id=%s", type
,
3126 bt_ctf_field_type_id_string(type
->id
));
3130 assert(ret
== BT_CTF_BYTE_ORDER_NATIVE
||
3131 ret
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
||
3132 ret
== BT_CTF_BYTE_ORDER_BIG_ENDIAN
||
3133 ret
== BT_CTF_BYTE_ORDER_NETWORK
);
3139 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type
*type
,
3140 enum bt_ctf_byte_order byte_order
)
3145 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3151 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3157 if (byte_order
!= BT_CTF_BYTE_ORDER_NATIVE
&&
3158 byte_order
!= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
&&
3159 byte_order
!= BT_CTF_BYTE_ORDER_BIG_ENDIAN
&&
3160 byte_order
!= BT_CTF_BYTE_ORDER_NETWORK
) {
3161 BT_LOGW("Invalid parameter: unknown byte order: "
3162 "addr=%p, bo=%s", type
,
3163 bt_ctf_byte_order_string(byte_order
));
3168 if (set_byte_order_funcs
[type
->id
]) {
3169 set_byte_order_funcs
[type
->id
](type
, byte_order
);
3172 BT_LOGV("Set field type's byte order: addr=%p, bo=%s",
3173 type
, bt_ctf_byte_order_string(byte_order
));
3179 enum bt_ctf_field_type_id
bt_ctf_field_type_get_type_id(
3180 struct bt_ctf_field_type
*type
)
3183 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3184 return BT_CTF_FIELD_TYPE_ID_UNKNOWN
;
3190 int bt_ctf_field_type_is_integer(struct bt_ctf_field_type
*type
)
3192 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_INTEGER
;
3195 int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type
*type
)
3197 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_FLOAT
;
3200 int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type
*type
)
3202 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_ENUM
;
3205 int bt_ctf_field_type_is_string(struct bt_ctf_field_type
*type
)
3207 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_STRING
;
3210 int bt_ctf_field_type_is_structure(struct bt_ctf_field_type
*type
)
3212 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_STRUCT
;
3215 int bt_ctf_field_type_is_array(struct bt_ctf_field_type
*type
)
3217 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_ARRAY
;
3220 int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type
*type
)
3222 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_SEQUENCE
;
3225 int bt_ctf_field_type_is_variant(struct bt_ctf_field_type
*type
)
3227 return bt_ctf_field_type_get_type_id(type
) == BT_CTF_FIELD_TYPE_ID_VARIANT
;
3230 /* Pre-2.0 CTF writer backward compatibility */
3231 void bt_ctf_field_type_get(struct bt_ctf_field_type
*type
)
3236 /* Pre-2.0 CTF writer backward compatibility */
3237 void bt_ctf_field_type_put(struct bt_ctf_field_type
*type
)
3243 void bt_ctf_field_type_freeze(struct bt_ctf_field_type
*type
)
3245 if (!type
|| type
->frozen
) {
3253 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_signed(
3254 struct bt_ctf_field_type_variant
*variant
,
3257 struct bt_ctf_field_type
*type
= NULL
;
3258 GQuark field_name_quark
;
3260 struct structure_field
*field_entry
;
3261 struct range_overlap_query query
= {
3262 .range_start
._signed
= tag_value
,
3263 .range_end
._signed
= tag_value
,
3268 g_ptr_array_foreach(variant
->tag
->entries
, check_ranges_overlap
,
3270 if (!query
.overlaps
) {
3274 field_name_quark
= query
.mapping_name
;
3275 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
3276 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3280 field_entry
= g_ptr_array_index(variant
->fields
, (size_t) index
);
3281 type
= field_entry
->type
;
3287 struct bt_ctf_field_type
*bt_ctf_field_type_variant_get_field_type_unsigned(
3288 struct bt_ctf_field_type_variant
*variant
,
3291 struct bt_ctf_field_type
*type
= NULL
;
3292 GQuark field_name_quark
;
3294 struct structure_field
*field_entry
;
3295 struct range_overlap_query query
= {
3296 .range_start
._unsigned
= tag_value
,
3297 .range_end
._unsigned
= tag_value
,
3302 g_ptr_array_foreach(variant
->tag
->entries
,
3303 check_ranges_overlap_unsigned
,
3305 if (!query
.overlaps
) {
3309 field_name_quark
= query
.mapping_name
;
3310 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
3311 GUINT_TO_POINTER(field_name_quark
), NULL
, &index
)) {
3315 field_entry
= g_ptr_array_index(variant
->fields
, (size_t)index
);
3316 type
= field_entry
->type
;
3322 int bt_ctf_field_type_serialize(struct bt_ctf_field_type
*type
,
3323 struct metadata_context
*context
)
3330 /* Make sure field type is valid before serializing it */
3331 ret
= bt_ctf_field_type_validate(type
);
3333 BT_LOGW("Cannot serialize field type's metadata: field type is invalid: "
3338 ret
= type
->serialize(type
, context
);
3343 struct bt_ctf_field_type
*bt_ctf_field_type_copy(struct bt_ctf_field_type
*type
)
3345 struct bt_ctf_field_type
*copy
= NULL
;
3348 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3352 copy
= type_copy_funcs
[type
->id
](type
);
3354 BT_LOGE_STR("Cannot copy field type.");
3358 copy
->alignment
= type
->alignment
;
3364 int bt_ctf_field_type_structure_get_field_name_index(
3365 struct bt_ctf_field_type
*type
, const char *name
)
3370 struct bt_ctf_field_type_structure
*structure
;
3373 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3379 BT_LOGW_STR("Invalid parameter: field name is NULL.");
3384 if (bt_ctf_field_type_get_type_id(type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
3385 BT_LOGW("Invalid parameter: field type is not a structure field type: "
3386 "addr=%p, ft-id=%s", type
,
3387 bt_ctf_field_type_id_string(type
->id
));
3392 name_quark
= g_quark_try_string(name
);
3394 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
3399 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
3401 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
3402 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
3412 int bt_ctf_field_type_variant_get_field_name_index(
3413 struct bt_ctf_field_type
*type
, const char *name
)
3418 struct bt_ctf_field_type_variant
*variant
;
3421 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3427 BT_LOGW_STR("Invalid parameter: field name is NULL.");
3432 if (bt_ctf_field_type_get_type_id(type
) != BT_CTF_FIELD_TYPE_ID_VARIANT
) {
3433 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3434 "addr=%p, ft-id=%s", type
,
3435 bt_ctf_field_type_id_string(type
->id
));
3440 name_quark
= g_quark_try_string(name
);
3442 BT_LOGE("Cannot get GQuark: string=\"%s\"", name
);
3447 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
3449 if (!g_hash_table_lookup_extended(variant
->field_name_to_index
,
3450 GUINT_TO_POINTER(name_quark
), NULL
, (gpointer
*)&index
)) {
3460 int bt_ctf_field_type_sequence_set_length_field_path(
3461 struct bt_ctf_field_type
*type
,
3462 struct bt_ctf_field_path
*path
)
3465 struct bt_ctf_field_type_sequence
*sequence
;
3468 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3473 if (bt_ctf_field_type_get_type_id(type
) != BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
3474 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
3475 "addr=%p, ft-id=%s", type
,
3476 bt_ctf_field_type_id_string(type
->id
));
3481 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
3484 BT_MOVE(sequence
->length_field_path
, path
);
3485 BT_LOGV("Set sequence field type's length field path: ft-addr=%p, "
3486 "field-path-addr=%p", type
, path
);
3492 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type
*type
,
3493 struct bt_ctf_field_path
*path
)
3496 struct bt_ctf_field_type_variant
*variant
;
3499 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3504 if (bt_ctf_field_type_get_type_id(type
) != BT_CTF_FIELD_TYPE_ID_VARIANT
) {
3505 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3506 "addr=%p, ft-id=%s", type
,
3507 bt_ctf_field_type_id_string(type
->id
));
3512 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
3515 BT_MOVE(variant
->tag_field_path
, path
);
3516 BT_LOGV("Set variant field type's tag field path: ft-addr=%p, "
3517 "field-path-addr=%p", type
, path
);
3523 int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type
*type
,
3524 struct bt_ctf_field_type
*tag
)
3527 struct bt_ctf_field_type_variant
*variant
;
3530 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3536 BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
3541 if (bt_ctf_field_type_get_type_id(tag
) != BT_CTF_FIELD_TYPE_ID_ENUM
) {
3542 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
3543 "addr=%p, ft-id=%s", type
,
3544 bt_ctf_field_type_id_string(type
->id
));
3549 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
3553 bt_put(&variant
->tag
->parent
);
3555 variant
->tag
= container_of(tag
, struct bt_ctf_field_type_enumeration
,
3557 BT_LOGV("Set variant field type's tag field type: variant-ft-addr=%p, "
3558 "tag-ft-addr=%p", type
, tag
);
3564 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type
*type
)
3566 struct bt_ctf_field_type_integer
*integer
=
3567 (struct bt_ctf_field_type_integer
*) type
;
3573 BT_LOGD("Destroying integer field type object: addr=%p", type
);
3574 bt_put(integer
->mapped_clock
);
3579 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type
*type
)
3581 struct bt_ctf_field_type_enumeration
*enumeration
=
3582 (struct bt_ctf_field_type_enumeration
*) type
;
3588 BT_LOGD("Destroying enumeration field type object: addr=%p", type
);
3589 g_ptr_array_free(enumeration
->entries
, TRUE
);
3590 bt_put(enumeration
->container
);
3591 g_free(enumeration
);
3595 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type
*type
)
3597 struct bt_ctf_field_type_floating_point
*floating_point
=
3598 (struct bt_ctf_field_type_floating_point
*) type
;
3604 BT_LOGD("Destroying floating point number field type object: addr=%p", type
);
3605 g_free(floating_point
);
3609 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type
*type
)
3611 struct bt_ctf_field_type_structure
*structure
=
3612 (struct bt_ctf_field_type_structure
*) type
;
3618 BT_LOGD("Destroying structure field type object: addr=%p", type
);
3619 g_ptr_array_free(structure
->fields
, TRUE
);
3620 g_hash_table_destroy(structure
->field_name_to_index
);
3625 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type
*type
)
3627 struct bt_ctf_field_type_variant
*variant
=
3628 (struct bt_ctf_field_type_variant
*) type
;
3634 BT_LOGD("Destroying variant field type object: addr=%p", type
);
3635 g_ptr_array_free(variant
->fields
, TRUE
);
3636 g_hash_table_destroy(variant
->field_name_to_index
);
3637 g_string_free(variant
->tag_name
, TRUE
);
3638 bt_put(&variant
->tag
->parent
);
3639 BT_PUT(variant
->tag_field_path
);
3644 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type
*type
)
3646 struct bt_ctf_field_type_array
*array
=
3647 (struct bt_ctf_field_type_array
*) type
;
3653 BT_LOGD("Destroying array field type object: addr=%p", type
);
3654 bt_put(array
->element_type
);
3659 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type
*type
)
3661 struct bt_ctf_field_type_sequence
*sequence
=
3662 (struct bt_ctf_field_type_sequence
*) type
;
3668 BT_LOGD("Destroying sequence field type object: addr=%p", type
);
3669 bt_put(sequence
->element_type
);
3670 g_string_free(sequence
->length_field_name
, TRUE
);
3671 BT_PUT(sequence
->length_field_path
);
3676 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type
*type
)
3678 struct bt_ctf_field_type_string
*string
=
3679 (struct bt_ctf_field_type_string
*) type
;
3685 BT_LOGD("Destroying string field type object: addr=%p", type
);
3690 void generic_field_type_freeze(struct bt_ctf_field_type
*type
)
3696 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type
*type
)
3698 struct bt_ctf_field_type_integer
*integer_type
= container_of(
3699 type
, struct bt_ctf_field_type_integer
, parent
);
3701 BT_LOGD("Freezing integer field type object: addr=%p", type
);
3703 if (integer_type
->mapped_clock
) {
3704 bt_ctf_clock_class_freeze(integer_type
->mapped_clock
);
3707 generic_field_type_freeze(type
);
3711 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type
*type
)
3713 struct bt_ctf_field_type_enumeration
*enumeration_type
= container_of(
3714 type
, struct bt_ctf_field_type_enumeration
, parent
);
3716 BT_LOGD("Freezing enumeration field type object: addr=%p", type
);
3717 set_enumeration_range_overlap(type
);
3718 generic_field_type_freeze(type
);
3719 BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
3720 enumeration_type
->container
);
3721 bt_ctf_field_type_freeze(enumeration_type
->container
);
3725 void freeze_structure_field(struct structure_field
*field
)
3727 BT_LOGD("Freezing structure/variant field type field: field-addr=%p, "
3728 "field-ft-addr=%p, field-name=\"%s\"", field
,
3729 field
->type
, g_quark_to_string(field
->name
));
3730 bt_ctf_field_type_freeze(field
->type
);
3734 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type
*type
)
3736 struct bt_ctf_field_type_structure
*structure_type
= container_of(
3737 type
, struct bt_ctf_field_type_structure
, parent
);
3739 /* Cache the alignment */
3740 BT_LOGD("Freezing structure field type object: addr=%p", type
);
3741 type
->alignment
= bt_ctf_field_type_get_alignment(type
);
3742 generic_field_type_freeze(type
);
3743 g_ptr_array_foreach(structure_type
->fields
,
3744 (GFunc
) freeze_structure_field
, NULL
);
3748 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type
*type
)
3750 struct bt_ctf_field_type_variant
*variant_type
= container_of(
3751 type
, struct bt_ctf_field_type_variant
, parent
);
3753 BT_LOGD("Freezing variant field type object: addr=%p", type
);
3754 generic_field_type_freeze(type
);
3755 g_ptr_array_foreach(variant_type
->fields
,
3756 (GFunc
) freeze_structure_field
, NULL
);
3760 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type
*type
)
3762 struct bt_ctf_field_type_array
*array_type
= container_of(
3763 type
, struct bt_ctf_field_type_array
, parent
);
3765 /* Cache the alignment */
3766 BT_LOGD("Freezing array field type object: addr=%p", type
);
3767 type
->alignment
= bt_ctf_field_type_get_alignment(type
);
3768 generic_field_type_freeze(type
);
3769 BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
3770 array_type
->element_type
);
3771 bt_ctf_field_type_freeze(array_type
->element_type
);
3775 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type
*type
)
3777 struct bt_ctf_field_type_sequence
*sequence_type
= container_of(
3778 type
, struct bt_ctf_field_type_sequence
, parent
);
3780 /* Cache the alignment */
3781 BT_LOGD("Freezing sequence field type object: addr=%p", type
);
3782 type
->alignment
= bt_ctf_field_type_get_alignment(type
);
3783 generic_field_type_freeze(type
);
3784 BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
3785 sequence_type
->element_type
);
3786 bt_ctf_field_type_freeze(sequence_type
->element_type
);
3790 const char *get_encoding_string(enum bt_ctf_string_encoding encoding
)
3792 const char *encoding_string
;
3795 case BT_CTF_STRING_ENCODING_NONE
:
3796 encoding_string
= "none";
3798 case BT_CTF_STRING_ENCODING_ASCII
:
3799 encoding_string
= "ASCII";
3801 case BT_CTF_STRING_ENCODING_UTF8
:
3802 encoding_string
= "UTF8";
3805 encoding_string
= "unknown";
3809 return encoding_string
;
3813 const char *get_integer_base_string(enum bt_ctf_integer_base base
)
3815 const char *base_string
;
3818 case BT_CTF_INTEGER_BASE_DECIMAL
:
3819 base_string
= "decimal";
3821 case BT_CTF_INTEGER_BASE_HEXADECIMAL
:
3822 base_string
= "hexadecimal";
3824 case BT_CTF_INTEGER_BASE_OCTAL
:
3825 base_string
= "octal";
3827 case BT_CTF_INTEGER_BASE_BINARY
:
3828 base_string
= "binary";
3831 base_string
= "unknown";
3839 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type
*type
,
3840 struct metadata_context
*context
)
3842 struct bt_ctf_field_type_integer
*integer
= container_of(type
,
3843 struct bt_ctf_field_type_integer
, parent
);
3846 BT_LOGD("Serializing integer field type's metadata: "
3847 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
3848 g_string_append_printf(context
->string
,
3849 "integer { size = %u; align = %u; signed = %s; encoding = %s; base = %s; byte_order = %s",
3850 integer
->size
, type
->alignment
,
3851 (integer
->is_signed
? "true" : "false"),
3852 get_encoding_string(integer
->encoding
),
3853 get_integer_base_string(integer
->base
),
3854 get_byte_order_string(integer
->user_byte_order
));
3855 if (integer
->mapped_clock
) {
3856 const char *clock_name
= bt_ctf_clock_class_get_name(
3857 integer
->mapped_clock
);
3860 g_string_append_printf(context
->string
,
3861 "; map = clock.%s.value", clock_name
);
3864 g_string_append(context
->string
, "; }");
3869 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type
*type
,
3870 struct metadata_context
*context
)
3874 struct bt_ctf_field_type_enumeration
*enumeration
= container_of(type
,
3875 struct bt_ctf_field_type_enumeration
, parent
);
3876 struct bt_ctf_field_type
*container_type
;
3877 int container_signed
;
3879 BT_LOGD("Serializing enumeration field type's metadata: "
3880 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
3881 container_type
= bt_ctf_field_type_enumeration_get_container_type(type
);
3882 assert(container_type
);
3883 container_signed
= bt_ctf_field_type_integer_get_signed(container_type
);
3884 assert(container_signed
>= 0);
3885 g_string_append(context
->string
, "enum : ");
3886 ret
= bt_ctf_field_type_serialize(enumeration
->container
, context
);
3888 BT_LOGW("Cannot serialize enumeration field type's container field type's metadata: "
3889 "container-ft-addr=%p", enumeration
->container
);
3893 g_string_append(context
->string
, " { ");
3894 for (entry
= 0; entry
< enumeration
->entries
->len
; entry
++) {
3895 struct enumeration_mapping
*mapping
=
3896 enumeration
->entries
->pdata
[entry
];
3898 if (container_signed
) {
3899 if (mapping
->range_start
._signed
==
3900 mapping
->range_end
._signed
) {
3901 g_string_append_printf(context
->string
,
3902 "\"%s\" = %" PRId64
,
3903 g_quark_to_string(mapping
->string
),
3904 mapping
->range_start
._signed
);
3906 g_string_append_printf(context
->string
,
3907 "\"%s\" = %" PRId64
" ... %" PRId64
,
3908 g_quark_to_string(mapping
->string
),
3909 mapping
->range_start
._signed
,
3910 mapping
->range_end
._signed
);
3913 if (mapping
->range_start
._unsigned
==
3914 mapping
->range_end
._unsigned
) {
3915 g_string_append_printf(context
->string
,
3916 "\"%s\" = %" PRIu64
,
3917 g_quark_to_string(mapping
->string
),
3918 mapping
->range_start
._unsigned
);
3920 g_string_append_printf(context
->string
,
3921 "\"%s\" = %" PRIu64
" ... %" PRIu64
,
3922 g_quark_to_string(mapping
->string
),
3923 mapping
->range_start
._unsigned
,
3924 mapping
->range_end
._unsigned
);
3928 g_string_append(context
->string
,
3929 ((entry
!= (enumeration
->entries
->len
- 1)) ?
3933 if (context
->field_name
->len
) {
3934 g_string_append_printf(context
->string
, " %s",
3935 context
->field_name
->str
);
3936 g_string_assign(context
->field_name
, "");
3939 bt_put(container_type
);
3944 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type
*type
,
3945 struct metadata_context
*context
)
3947 struct bt_ctf_field_type_floating_point
*floating_point
= container_of(
3948 type
, struct bt_ctf_field_type_floating_point
, parent
);
3950 BT_LOGD("Serializing floating point number field type's metadata: "
3951 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
3952 g_string_append_printf(context
->string
,
3953 "floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
3954 floating_point
->exp_dig
,
3955 floating_point
->mant_dig
,
3956 get_byte_order_string(floating_point
->user_byte_order
),
3962 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type
*type
,
3963 struct metadata_context
*context
)
3966 unsigned int indent
;
3968 struct bt_ctf_field_type_structure
*structure
= container_of(type
,
3969 struct bt_ctf_field_type_structure
, parent
);
3970 GString
*structure_field_name
= context
->field_name
;
3972 BT_LOGD("Serializing structure field type's metadata: "
3973 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
3974 context
->field_name
= g_string_new("");
3976 context
->current_indentation_level
++;
3977 g_string_append(context
->string
, "struct {\n");
3979 for (i
= 0; i
< structure
->fields
->len
; i
++) {
3980 struct structure_field
*field
= structure
->fields
->pdata
[i
];
3982 BT_LOGV("Serializing structure field type's field metadata: "
3983 "index=%" PRId64
", "
3984 "field-ft-addr=%p, field-name=\"%s\"",
3985 i
, field
, g_quark_to_string(field
->name
));
3987 for (indent
= 0; indent
< context
->current_indentation_level
;
3989 g_string_append_c(context
->string
, '\t');
3992 g_string_assign(context
->field_name
,
3993 g_quark_to_string(field
->name
));
3994 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
3996 BT_LOGW("Cannot serialize structure field type's field's metadata: "
3997 "index=%" PRId64
", "
3998 "field-ft-addr=%p, field-name=\"%s\"",
4000 g_quark_to_string(field
->name
));
4004 if (context
->field_name
->len
) {
4005 g_string_append_printf(context
->string
, " %s",
4006 context
->field_name
->str
);
4008 g_string_append(context
->string
, ";\n");
4011 context
->current_indentation_level
--;
4012 for (indent
= 0; indent
< context
->current_indentation_level
;
4014 g_string_append_c(context
->string
, '\t');
4017 g_string_append_printf(context
->string
, "} align(%u)",
4020 g_string_free(context
->field_name
, TRUE
);
4021 context
->field_name
= structure_field_name
;
4026 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type
*type
,
4027 struct metadata_context
*context
)
4030 unsigned int indent
;
4032 struct bt_ctf_field_type_variant
*variant
= container_of(
4033 type
, struct bt_ctf_field_type_variant
, parent
);
4034 GString
*variant_field_name
= context
->field_name
;
4036 BT_LOGD("Serializing variant field type's metadata: "
4037 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4038 context
->field_name
= g_string_new("");
4039 if (variant
->tag_name
->len
> 0) {
4040 g_string_append_printf(context
->string
,
4041 "variant <%s> {\n", variant
->tag_name
->str
);
4043 g_string_append(context
->string
, "variant {\n");
4046 context
->current_indentation_level
++;
4047 for (i
= 0; i
< variant
->fields
->len
; i
++) {
4048 struct structure_field
*field
= variant
->fields
->pdata
[i
];
4050 BT_LOGV("Serializing variant field type's field metadata: "
4051 "index=%" PRId64
", "
4052 "field-ft-addr=%p, field-name=\"%s\"",
4053 i
, field
, g_quark_to_string(field
->name
));
4055 g_string_assign(context
->field_name
,
4056 g_quark_to_string(field
->name
));
4057 for (indent
= 0; indent
< context
->current_indentation_level
;
4059 g_string_append_c(context
->string
, '\t');
4062 g_string_assign(context
->field_name
,
4063 g_quark_to_string(field
->name
));
4064 ret
= bt_ctf_field_type_serialize(field
->type
, context
);
4066 BT_LOGW("Cannot serialize variant field type's field's metadata: "
4067 "index=%" PRId64
", "
4068 "field-ft-addr=%p, field-name=\"%s\"",
4070 g_quark_to_string(field
->name
));
4074 if (context
->field_name
->len
) {
4075 g_string_append_printf(context
->string
, " %s;",
4076 context
->field_name
->str
);
4079 g_string_append_c(context
->string
, '\n');
4082 context
->current_indentation_level
--;
4083 for (indent
= 0; indent
< context
->current_indentation_level
;
4085 g_string_append_c(context
->string
, '\t');
4088 g_string_append(context
->string
, "}");
4090 g_string_free(context
->field_name
, TRUE
);
4091 context
->field_name
= variant_field_name
;
4096 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type
*type
,
4097 struct metadata_context
*context
)
4100 struct bt_ctf_field_type_array
*array
= container_of(type
,
4101 struct bt_ctf_field_type_array
, parent
);
4103 BT_LOGD("Serializing array field type's metadata: "
4104 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4105 ret
= bt_ctf_field_type_serialize(array
->element_type
, context
);
4107 BT_LOGW("Cannot serialize array field type's element field type's metadata: "
4108 "element-ft-addr=%p", array
->element_type
);
4112 if (context
->field_name
->len
) {
4113 g_string_append_printf(context
->string
, " %s[%u]",
4114 context
->field_name
->str
, array
->length
);
4115 g_string_assign(context
->field_name
, "");
4117 g_string_append_printf(context
->string
, "[%u]", array
->length
);
4124 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type
*type
,
4125 struct metadata_context
*context
)
4128 struct bt_ctf_field_type_sequence
*sequence
= container_of(
4129 type
, struct bt_ctf_field_type_sequence
, parent
);
4131 BT_LOGD("Serializing sequence field type's metadata: "
4132 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4133 ret
= bt_ctf_field_type_serialize(sequence
->element_type
, context
);
4135 BT_LOGW("Cannot serialize sequence field type's element field type's metadata: "
4136 "element-ft-addr=%p", sequence
->element_type
);
4140 if (context
->field_name
->len
) {
4141 g_string_append_printf(context
->string
, " %s[%s]",
4142 context
->field_name
->str
,
4143 sequence
->length_field_name
->str
);
4144 g_string_assign(context
->field_name
, "");
4146 g_string_append_printf(context
->string
, "[%s]",
4147 sequence
->length_field_name
->str
);
4154 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type
*type
,
4155 struct metadata_context
*context
)
4157 struct bt_ctf_field_type_string
*string
= container_of(
4158 type
, struct bt_ctf_field_type_string
, parent
);
4160 BT_LOGD("Serializing string field type's metadata: "
4161 "ft-addr=%p, metadata-context-addr=%p", type
, context
);
4162 g_string_append_printf(context
->string
,
4163 "string { encoding = %s; }",
4164 get_encoding_string(string
->encoding
));
4169 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type
*type
,
4170 enum bt_ctf_byte_order byte_order
)
4172 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
4173 struct bt_ctf_field_type_integer
, parent
);
4175 integer_type
->user_byte_order
= byte_order
;
4179 void bt_ctf_field_type_enumeration_set_byte_order(
4180 struct bt_ctf_field_type
*type
, enum bt_ctf_byte_order byte_order
)
4182 struct bt_ctf_field_type_enumeration
*enum_type
= container_of(type
,
4183 struct bt_ctf_field_type_enumeration
, parent
);
4185 /* Safe to assume that container is an integer */
4186 bt_ctf_field_type_integer_set_byte_order(enum_type
->container
,
4191 void bt_ctf_field_type_floating_point_set_byte_order(
4192 struct bt_ctf_field_type
*type
, enum bt_ctf_byte_order byte_order
)
4194 struct bt_ctf_field_type_floating_point
*floating_point_type
=
4195 container_of(type
, struct bt_ctf_field_type_floating_point
,
4198 floating_point_type
->user_byte_order
= byte_order
;
4202 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type
*type
,
4203 enum bt_ctf_byte_order byte_order
)
4206 struct bt_ctf_field_type_structure
*structure_type
=
4207 container_of(type
, struct bt_ctf_field_type_structure
,
4210 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
4211 struct structure_field
*field
= g_ptr_array_index(
4212 structure_type
->fields
, i
);
4213 struct bt_ctf_field_type
*field_type
= field
->type
;
4215 if (set_byte_order_funcs
[field_type
->id
]) {
4216 set_byte_order_funcs
[field_type
->id
](
4217 field_type
, byte_order
);
4223 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type
*type
,
4224 enum bt_ctf_byte_order byte_order
)
4227 struct bt_ctf_field_type_variant
*variant_type
=
4228 container_of(type
, struct bt_ctf_field_type_variant
,
4231 for (i
= 0; i
< variant_type
->fields
->len
; i
++) {
4232 struct structure_field
*field
= g_ptr_array_index(
4233 variant_type
->fields
, i
);
4234 struct bt_ctf_field_type
*field_type
= field
->type
;
4236 if (set_byte_order_funcs
[field_type
->id
]) {
4237 set_byte_order_funcs
[field_type
->id
](
4238 field_type
, byte_order
);
4244 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type
*type
,
4245 enum bt_ctf_byte_order byte_order
)
4247 struct bt_ctf_field_type_array
*array_type
=
4248 container_of(type
, struct bt_ctf_field_type_array
,
4251 if (set_byte_order_funcs
[array_type
->element_type
->id
]) {
4252 set_byte_order_funcs
[array_type
->element_type
->id
](
4253 array_type
->element_type
, byte_order
);
4258 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type
*type
,
4259 enum bt_ctf_byte_order byte_order
)
4261 struct bt_ctf_field_type_sequence
*sequence_type
=
4262 container_of(type
, struct bt_ctf_field_type_sequence
,
4265 if (set_byte_order_funcs
[
4266 sequence_type
->element_type
->id
]) {
4267 set_byte_order_funcs
[
4268 sequence_type
->element_type
->id
](
4269 sequence_type
->element_type
, byte_order
);
4274 struct bt_ctf_field_type
*bt_ctf_field_type_integer_copy(
4275 struct bt_ctf_field_type
*type
)
4277 struct bt_ctf_field_type
*copy
;
4278 struct bt_ctf_field_type_integer
*integer
, *copy_integer
;
4280 BT_LOGD("Copying integer field type's: addr=%p", type
);
4281 integer
= container_of(type
, struct bt_ctf_field_type_integer
, parent
);
4282 copy
= bt_ctf_field_type_integer_create(integer
->size
);
4284 BT_LOGE_STR("Cannot create integer field type.");
4288 copy_integer
= container_of(copy
, struct bt_ctf_field_type_integer
,
4290 copy_integer
->mapped_clock
= bt_get(integer
->mapped_clock
);
4291 copy_integer
->user_byte_order
= integer
->user_byte_order
;
4292 copy_integer
->is_signed
= integer
->is_signed
;
4293 copy_integer
->size
= integer
->size
;
4294 copy_integer
->base
= integer
->base
;
4295 copy_integer
->encoding
= integer
->encoding
;
4296 BT_LOGD("Copied integer field type: original-ft-addr=%p, copy-ft-addr=%p",
4304 struct bt_ctf_field_type
*bt_ctf_field_type_enumeration_copy(
4305 struct bt_ctf_field_type
*type
)
4308 struct bt_ctf_field_type
*copy
= NULL
, *copy_container
;
4309 struct bt_ctf_field_type_enumeration
*enumeration
, *copy_enumeration
;
4311 BT_LOGD("Copying enumeration field type's: addr=%p", type
);
4312 enumeration
= container_of(type
, struct bt_ctf_field_type_enumeration
,
4315 /* Copy the source enumeration's container */
4316 copy_container
= bt_ctf_field_type_copy(enumeration
->container
);
4317 if (!copy_container
) {
4318 BT_LOGE_STR("Cannot copy enumeration field type's container field type.");
4322 copy
= bt_ctf_field_type_enumeration_create(copy_container
);
4324 BT_LOGE_STR("Cannot create enumeration field type.");
4327 copy_enumeration
= container_of(copy
,
4328 struct bt_ctf_field_type_enumeration
, parent
);
4330 /* Copy all enumaration entries */
4331 for (i
= 0; i
< enumeration
->entries
->len
; i
++) {
4332 struct enumeration_mapping
*mapping
= g_ptr_array_index(
4333 enumeration
->entries
, i
);
4334 struct enumeration_mapping
*copy_mapping
= g_new0(
4335 struct enumeration_mapping
, 1);
4337 if (!copy_mapping
) {
4338 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
4342 *copy_mapping
= *mapping
;
4343 g_ptr_array_add(copy_enumeration
->entries
, copy_mapping
);
4346 BT_LOGD("Copied enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
4350 bt_put(copy_container
);
4353 bt_put(copy_container
);
4359 struct bt_ctf_field_type
*bt_ctf_field_type_floating_point_copy(
4360 struct bt_ctf_field_type
*type
)
4362 struct bt_ctf_field_type
*copy
;
4363 struct bt_ctf_field_type_floating_point
*floating_point
, *copy_float
;
4365 BT_LOGD("Copying floating point number field type's: addr=%p", type
);
4366 floating_point
= container_of(type
,
4367 struct bt_ctf_field_type_floating_point
, parent
);
4368 copy
= bt_ctf_field_type_floating_point_create();
4370 BT_LOGE_STR("Cannot create floating point number field type.");
4374 copy_float
= container_of(copy
,
4375 struct bt_ctf_field_type_floating_point
, parent
);
4376 copy_float
->user_byte_order
= floating_point
->user_byte_order
;
4377 copy_float
->exp_dig
= floating_point
->exp_dig
;
4378 copy_float
->mant_dig
= floating_point
->mant_dig
;
4379 BT_LOGD("Copied floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
4386 struct bt_ctf_field_type
*bt_ctf_field_type_structure_copy(
4387 struct bt_ctf_field_type
*type
)
4390 GHashTableIter iter
;
4391 gpointer key
, value
;
4392 struct bt_ctf_field_type
*copy
;
4393 struct bt_ctf_field_type_structure
*structure
, *copy_structure
;
4395 BT_LOGD("Copying structure field type's: addr=%p", type
);
4396 structure
= container_of(type
, struct bt_ctf_field_type_structure
,
4398 copy
= bt_ctf_field_type_structure_create();
4400 BT_LOGE_STR("Cannot create structure field type.");
4404 copy_structure
= container_of(copy
,
4405 struct bt_ctf_field_type_structure
, parent
);
4407 /* Copy field_name_to_index */
4408 g_hash_table_iter_init(&iter
, structure
->field_name_to_index
);
4409 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
4410 g_hash_table_insert(copy_structure
->field_name_to_index
,
4414 for (i
= 0; i
< structure
->fields
->len
; i
++) {
4415 struct structure_field
*entry
, *copy_entry
;
4416 struct bt_ctf_field_type
*copy_field
;
4418 entry
= g_ptr_array_index(structure
->fields
, i
);
4419 BT_LOGV("Copying structure field type's field: "
4420 "index=%" PRId64
", "
4421 "field-ft-addr=%p, field-name=\"%s\"",
4422 i
, entry
, g_quark_to_string(entry
->name
));
4423 copy_entry
= g_new0(struct structure_field
, 1);
4425 BT_LOGE_STR("Failed to allocate one structure field type field.");
4429 copy_field
= bt_ctf_field_type_copy(entry
->type
);
4431 BT_LOGE("Cannot copy structure field type's field: "
4432 "index=%" PRId64
", "
4433 "field-ft-addr=%p, field-name=\"%s\"",
4434 i
, entry
, g_quark_to_string(entry
->name
));
4439 copy_entry
->name
= entry
->name
;
4440 copy_entry
->type
= copy_field
;
4441 g_ptr_array_add(copy_structure
->fields
, copy_entry
);
4444 BT_LOGD("Copied structure field type: original-ft-addr=%p, copy-ft-addr=%p",
4455 struct bt_ctf_field_type
*bt_ctf_field_type_variant_copy(
4456 struct bt_ctf_field_type
*type
)
4459 GHashTableIter iter
;
4460 gpointer key
, value
;
4461 struct bt_ctf_field_type
*copy
= NULL
, *copy_tag
= NULL
;
4462 struct bt_ctf_field_type_variant
*variant
, *copy_variant
;
4464 BT_LOGD("Copying variant field type's: addr=%p", type
);
4465 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
4468 copy_tag
= bt_ctf_field_type_copy(&variant
->tag
->parent
);
4470 BT_LOGE_STR("Cannot copy variant field type's tag field type.");
4475 copy
= bt_ctf_field_type_variant_create(copy_tag
,
4476 variant
->tag_name
->len
? variant
->tag_name
->str
: NULL
);
4478 BT_LOGE_STR("Cannot create variant field type.");
4482 copy_variant
= container_of(copy
, struct bt_ctf_field_type_variant
,
4485 /* Copy field_name_to_index */
4486 g_hash_table_iter_init(&iter
, variant
->field_name_to_index
);
4487 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
4488 g_hash_table_insert(copy_variant
->field_name_to_index
,
4492 for (i
= 0; i
< variant
->fields
->len
; i
++) {
4493 struct structure_field
*entry
, *copy_entry
;
4494 struct bt_ctf_field_type
*copy_field
;
4496 entry
= g_ptr_array_index(variant
->fields
, i
);
4497 BT_LOGV("Copying variant field type's field: "
4498 "index=%" PRId64
", "
4499 "field-ft-addr=%p, field-name=\"%s\"",
4500 i
, entry
, g_quark_to_string(entry
->name
));
4501 copy_entry
= g_new0(struct structure_field
, 1);
4503 BT_LOGE_STR("Failed to allocate one variant field type field.");
4507 copy_field
= bt_ctf_field_type_copy(entry
->type
);
4509 BT_LOGE("Cannot copy variant field type's field: "
4510 "index=%" PRId64
", "
4511 "field-ft-addr=%p, field-name=\"%s\"",
4512 i
, entry
, g_quark_to_string(entry
->name
));
4517 copy_entry
->name
= entry
->name
;
4518 copy_entry
->type
= copy_field
;
4519 g_ptr_array_add(copy_variant
->fields
, copy_entry
);
4522 if (variant
->tag_field_path
) {
4523 BT_LOGV_STR("Copying variant field type's tag field path.");
4524 copy_variant
->tag_field_path
= bt_ctf_field_path_copy(
4525 variant
->tag_field_path
);
4526 if (!copy_variant
->tag_field_path
) {
4527 BT_LOGE_STR("Cannot copy variant field type's tag field path.");
4532 BT_LOGD("Copied variant field type: original-ft-addr=%p, copy-ft-addr=%p",
4545 struct bt_ctf_field_type
*bt_ctf_field_type_array_copy(
4546 struct bt_ctf_field_type
*type
)
4548 struct bt_ctf_field_type
*copy
= NULL
, *copy_element
;
4549 struct bt_ctf_field_type_array
*array
;
4551 BT_LOGD("Copying array field type's: addr=%p", type
);
4552 array
= container_of(type
, struct bt_ctf_field_type_array
,
4554 copy_element
= bt_ctf_field_type_copy(array
->element_type
);
4555 if (!copy_element
) {
4556 BT_LOGE_STR("Cannot copy array field type's element field type.");
4560 copy
= bt_ctf_field_type_array_create(copy_element
, array
->length
);
4562 BT_LOGE_STR("Cannot create array field type.");
4566 BT_LOGD("Copied array field type: original-ft-addr=%p, copy-ft-addr=%p",
4570 bt_put(copy_element
);
4575 struct bt_ctf_field_type
*bt_ctf_field_type_sequence_copy(
4576 struct bt_ctf_field_type
*type
)
4578 struct bt_ctf_field_type
*copy
= NULL
, *copy_element
;
4579 struct bt_ctf_field_type_sequence
*sequence
, *copy_sequence
;
4581 BT_LOGD("Copying sequence field type's: addr=%p", type
);
4582 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
4584 copy_element
= bt_ctf_field_type_copy(sequence
->element_type
);
4585 if (!copy_element
) {
4586 BT_LOGE_STR("Cannot copy sequence field type's element field type.");
4590 copy
= bt_ctf_field_type_sequence_create(copy_element
,
4591 sequence
->length_field_name
->len
?
4592 sequence
->length_field_name
->str
: NULL
);
4594 BT_LOGE_STR("Cannot create sequence field type.");
4598 copy_sequence
= container_of(copy
, struct bt_ctf_field_type_sequence
,
4600 if (sequence
->length_field_path
) {
4601 BT_LOGV_STR("Copying sequence field type's length field path.");
4602 copy_sequence
->length_field_path
= bt_ctf_field_path_copy(
4603 sequence
->length_field_path
);
4604 if (!copy_sequence
->length_field_path
) {
4605 BT_LOGE_STR("Cannot copy sequence field type's length field path.");
4610 BT_LOGD("Copied sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
4614 bt_put(copy_element
);
4622 struct bt_ctf_field_type
*bt_ctf_field_type_string_copy(
4623 struct bt_ctf_field_type
*type
)
4625 struct bt_ctf_field_type
*copy
;
4626 struct bt_ctf_field_type_string
*string
;
4628 BT_LOGD("Copying string field type's: addr=%p", type
);
4629 copy
= bt_ctf_field_type_string_create();
4631 BT_LOGE_STR("Cannot create string field type.");
4635 string
= container_of(type
, struct bt_ctf_field_type_string
,
4637 BT_LOGD("Copied string field type: original-ft-addr=%p, copy-ft-addr=%p",
4644 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type
*type_a
,
4645 struct bt_ctf_field_type
*type_b
)
4648 struct bt_ctf_field_type_integer
*int_type_a
;
4649 struct bt_ctf_field_type_integer
*int_type_b
;
4651 int_type_a
= container_of(type_a
, struct bt_ctf_field_type_integer
,
4653 int_type_b
= container_of(type_b
, struct bt_ctf_field_type_integer
,
4657 if (int_type_a
->size
!= int_type_b
->size
) {
4658 BT_LOGV("Integer field types differ: different sizes: "
4659 "ft-a-size=%u, ft-b-size=%u",
4660 int_type_a
->size
, int_type_b
->size
);
4665 if (int_type_a
->user_byte_order
!= int_type_b
->user_byte_order
) {
4666 BT_LOGV("Integer field types differ: different byte orders: "
4667 "ft-a-bo=%s, ft-b-bo=%s",
4668 bt_ctf_byte_order_string(int_type_a
->user_byte_order
),
4669 bt_ctf_byte_order_string(int_type_b
->user_byte_order
));
4674 if (int_type_a
->is_signed
!= int_type_b
->is_signed
) {
4675 BT_LOGV("Integer field types differ: different signedness: "
4676 "ft-a-is-signed=%d, ft-b-is-signed=%d",
4677 int_type_a
->is_signed
,
4678 int_type_b
->is_signed
);
4683 if (int_type_a
->base
!= int_type_b
->base
) {
4684 BT_LOGV("Integer field types differ: different bases: "
4685 "ft-a-base=%s, ft-b-base=%s",
4686 bt_ctf_integer_base_string(int_type_a
->base
),
4687 bt_ctf_integer_base_string(int_type_b
->base
));
4692 if (int_type_a
->encoding
!= int_type_b
->encoding
) {
4693 BT_LOGV("Integer field types differ: different encodings: "
4694 "ft-a-encoding=%s, ft-b-encoding=%s",
4695 bt_ctf_string_encoding_string(int_type_a
->encoding
),
4696 bt_ctf_string_encoding_string(int_type_b
->encoding
));
4701 if (int_type_a
->mapped_clock
!= int_type_b
->mapped_clock
) {
4702 BT_LOGV("Integer field types differ: different mapped clock classes: "
4703 "ft-a-mapped-clock-class-addr=%p, "
4704 "ft-b-mapped-clock-class-addr=%p, ",
4705 "ft-a-mapped-clock-class-name=\"%s\", ",
4706 "ft-b-mapped-clock-class-name=\"%s\"",
4707 int_type_a
->mapped_clock
, int_type_b
->mapped_clock
,
4708 int_type_a
->mapped_clock
? bt_ctf_clock_class_get_name(int_type_a
->mapped_clock
) : "",
4709 int_type_b
->mapped_clock
? bt_ctf_clock_class_get_name(int_type_b
->mapped_clock
) : "");
4721 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type
*type_a
,
4722 struct bt_ctf_field_type
*type_b
)
4725 struct bt_ctf_field_type_floating_point
*float_a
;
4726 struct bt_ctf_field_type_floating_point
*float_b
;
4728 float_a
= container_of(type_a
,
4729 struct bt_ctf_field_type_floating_point
, parent
);
4730 float_b
= container_of(type_b
,
4731 struct bt_ctf_field_type_floating_point
, parent
);
4734 if (float_a
->user_byte_order
!= float_b
->user_byte_order
) {
4735 BT_LOGV("Floating point number field types differ: different byte orders: "
4736 "ft-a-bo=%s, ft-b-bo=%s",
4737 bt_ctf_byte_order_string(float_a
->user_byte_order
),
4738 bt_ctf_byte_order_string(float_b
->user_byte_order
));
4742 /* Exponent length */
4743 if (float_a
->exp_dig
!= float_b
->exp_dig
) {
4744 BT_LOGV("Floating point number field types differ: different exponent sizes: "
4745 "ft-a-exp-size=%s, ft-b-exp-size=%s",
4746 float_a
->exp_dig
, float_b
->exp_dig
);
4750 /* Mantissa length */
4751 if (float_a
->mant_dig
!= float_b
->mant_dig
) {
4752 BT_LOGV("Floating point number field types differ: different mantissa sizes: "
4753 "ft-a-mant-size=%s, ft-b-mant-size=%s",
4754 float_a
->mant_dig
, float_b
->mant_dig
);
4766 int compare_enumeration_mappings(struct enumeration_mapping
*mapping_a
,
4767 struct enumeration_mapping
*mapping_b
)
4772 if (mapping_a
->string
!= mapping_b
->string
) {
4773 BT_LOGV("Enumeration field type mappings differ: different names: "
4774 "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
4775 g_quark_to_string(mapping_a
->string
),
4776 g_quark_to_string(mapping_b
->string
));
4781 if (mapping_a
->range_start
._unsigned
!=
4782 mapping_b
->range_start
._unsigned
) {
4783 BT_LOGV("Enumeration field type mappings differ: different starts of range: "
4784 "mapping-a-range-start-unsigned=%" PRIu64
", "
4785 "mapping-b-range-start-unsigned=%" PRIu64
,
4786 mapping_a
->range_start
._unsigned
,
4787 mapping_b
->range_start
._unsigned
);
4792 if (mapping_a
->range_end
._unsigned
!=
4793 mapping_b
->range_end
._unsigned
) {
4794 BT_LOGV("Enumeration field type mappings differ: different ends of range: "
4795 "mapping-a-range-end-unsigned=%" PRIu64
", "
4796 "mapping-b-range-end-unsigned=%" PRIu64
,
4797 mapping_a
->range_end
._unsigned
,
4798 mapping_b
->range_end
._unsigned
);
4810 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type
*type_a
,
4811 struct bt_ctf_field_type
*type_b
)
4815 struct bt_ctf_field_type_enumeration
*enum_a
;
4816 struct bt_ctf_field_type_enumeration
*enum_b
;
4818 enum_a
= container_of(type_a
,
4819 struct bt_ctf_field_type_enumeration
, parent
);
4820 enum_b
= container_of(type_b
,
4821 struct bt_ctf_field_type_enumeration
, parent
);
4823 /* Container field type */
4824 ret
= bt_ctf_field_type_compare(enum_a
->container
, enum_b
->container
);
4826 BT_LOGV("Enumeration field types differ: different container field types: "
4827 "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
4828 enum_a
->container
, enum_b
->container
);
4835 if (enum_a
->entries
->len
!= enum_b
->entries
->len
) {
4839 for (i
= 0; i
< enum_a
->entries
->len
; ++i
) {
4840 struct enumeration_mapping
*mapping_a
=
4841 g_ptr_array_index(enum_a
->entries
, i
);
4842 struct enumeration_mapping
*mapping_b
=
4843 g_ptr_array_index(enum_b
->entries
, i
);
4845 if (compare_enumeration_mappings(mapping_a
, mapping_b
)) {
4846 BT_LOGV("Enumeration field types differ: different mappings: "
4847 "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
4848 "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
4849 mapping_a
, mapping_b
,
4850 g_quark_to_string(mapping_a
->string
),
4851 g_quark_to_string(mapping_b
->string
));
4864 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type
*type_a
,
4865 struct bt_ctf_field_type
*type_b
)
4868 struct bt_ctf_field_type_string
*string_a
;
4869 struct bt_ctf_field_type_string
*string_b
;
4871 string_a
= container_of(type_a
,
4872 struct bt_ctf_field_type_string
, parent
);
4873 string_b
= container_of(type_b
,
4874 struct bt_ctf_field_type_string
, parent
);
4877 if (string_a
->encoding
!= string_b
->encoding
) {
4878 BT_LOGV("String field types differ: different encodings: "
4879 "ft-a-encoding=%s, ft-b-encoding=%s",
4880 bt_ctf_string_encoding_string(string_a
->encoding
),
4881 bt_ctf_string_encoding_string(string_b
->encoding
));
4893 int compare_structure_fields(struct structure_field
*field_a
,
4894 struct structure_field
*field_b
)
4899 if (field_a
->name
!= field_b
->name
) {
4900 BT_LOGV("Structure/variant field type fields differ: different names: "
4901 "field-a-name=%s, field-b-name=%s",
4902 g_quark_to_string(field_a
->name
),
4903 g_quark_to_string(field_b
->name
));
4908 ret
= bt_ctf_field_type_compare(field_a
->type
, field_b
->type
);
4910 BT_LOGV("Structure/variant field type fields differ: different field types: "
4911 "field-name=\"%s\", field-a-ft-addr=%s, field-b-ft-addr=%s",
4912 g_quark_to_string(field_a
->name
),
4913 field_a
->type
, field_b
->type
);
4921 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type
*type_a
,
4922 struct bt_ctf_field_type
*type_b
)
4926 struct bt_ctf_field_type_structure
*struct_a
;
4927 struct bt_ctf_field_type_structure
*struct_b
;
4929 struct_a
= container_of(type_a
,
4930 struct bt_ctf_field_type_structure
, parent
);
4931 struct_b
= container_of(type_b
,
4932 struct bt_ctf_field_type_structure
, parent
);
4935 if (bt_ctf_field_type_get_alignment(type_a
) !=
4936 bt_ctf_field_type_get_alignment(type_b
)) {
4937 BT_LOGV("Structure field types differ: different alignments: "
4938 "ft-a-align=%u, ft-b-align=%u",
4939 bt_ctf_field_type_get_alignment(type_a
),
4940 bt_ctf_field_type_get_alignment(type_b
));
4945 if (struct_a
->fields
->len
!= struct_b
->fields
->len
) {
4946 BT_LOGV("Structure field types differ: different field counts: "
4947 "ft-a-field-count=%u, ft-b-field-count=%u",
4948 struct_a
->fields
->len
, struct_b
->fields
->len
);
4952 for (i
= 0; i
< struct_a
->fields
->len
; ++i
) {
4953 struct structure_field
*field_a
=
4954 g_ptr_array_index(struct_a
->fields
, i
);
4955 struct structure_field
*field_b
=
4956 g_ptr_array_index(struct_b
->fields
, i
);
4958 ret
= compare_structure_fields(field_a
, field_b
);
4960 /* compare_structure_fields() logs what differs */
4961 BT_LOGV_STR("Structure field types differ: different fields.");
4974 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type
*type_a
,
4975 struct bt_ctf_field_type
*type_b
)
4979 struct bt_ctf_field_type_variant
*variant_a
;
4980 struct bt_ctf_field_type_variant
*variant_b
;
4982 variant_a
= container_of(type_a
,
4983 struct bt_ctf_field_type_variant
, parent
);
4984 variant_b
= container_of(type_b
,
4985 struct bt_ctf_field_type_variant
, parent
);
4988 if (strcmp(variant_a
->tag_name
->str
, variant_b
->tag_name
->str
)) {
4989 BT_LOGV("Variant field types differ: different tag field names: "
4990 "ft-a-tag-field-name=%u, ft-b-tag-field-name=%u",
4991 variant_a
->tag_name
->str
, variant_b
->tag_name
->str
);
4996 ret
= bt_ctf_field_type_compare(
4997 (struct bt_ctf_field_type
*) variant_a
->tag
,
4998 (struct bt_ctf_field_type
*) variant_b
->tag
);
5000 BT_LOGV("Variant field types differ: different tag field types: "
5001 "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
5002 variant_a
->tag
, variant_b
->tag
);
5009 if (variant_a
->fields
->len
!= variant_b
->fields
->len
) {
5010 BT_LOGV("Structure field types differ: different field counts: "
5011 "ft-a-field-count=%u, ft-b-field-count=%u",
5012 variant_a
->fields
->len
, variant_b
->fields
->len
);
5016 for (i
= 0; i
< variant_a
->fields
->len
; ++i
) {
5017 struct structure_field
*field_a
=
5018 g_ptr_array_index(variant_a
->fields
, i
);
5019 struct structure_field
*field_b
=
5020 g_ptr_array_index(variant_b
->fields
, i
);
5022 ret
= compare_structure_fields(field_a
, field_b
);
5024 /* compare_structure_fields() logs what differs */
5025 BT_LOGV_STR("Variant field types differ: different fields.");
5038 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type
*type_a
,
5039 struct bt_ctf_field_type
*type_b
)
5042 struct bt_ctf_field_type_array
*array_a
;
5043 struct bt_ctf_field_type_array
*array_b
;
5045 array_a
= container_of(type_a
,
5046 struct bt_ctf_field_type_array
, parent
);
5047 array_b
= container_of(type_b
,
5048 struct bt_ctf_field_type_array
, parent
);
5051 if (array_a
->length
!= array_b
->length
) {
5052 BT_LOGV("Structure field types differ: different lengths: "
5053 "ft-a-length=%u, ft-b-length=%u",
5054 array_a
->length
, array_b
->length
);
5059 ret
= bt_ctf_field_type_compare(array_a
->element_type
,
5060 array_b
->element_type
);
5062 BT_LOGV("Array field types differ: different element field types: "
5063 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
5064 array_a
->element_type
, array_b
->element_type
);
5072 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type
*type_a
,
5073 struct bt_ctf_field_type
*type_b
)
5076 struct bt_ctf_field_type_sequence
*sequence_a
;
5077 struct bt_ctf_field_type_sequence
*sequence_b
;
5079 sequence_a
= container_of(type_a
,
5080 struct bt_ctf_field_type_sequence
, parent
);
5081 sequence_b
= container_of(type_b
,
5082 struct bt_ctf_field_type_sequence
, parent
);
5085 if (strcmp(sequence_a
->length_field_name
->str
,
5086 sequence_b
->length_field_name
->str
)) {
5087 BT_LOGV("Sequence field types differ: different length field names: "
5088 "ft-a-length-field-name=%u, ft-b-length-field-name=%u",
5089 sequence_a
->length_field_name
->str
,
5090 sequence_b
->length_field_name
->str
);
5095 ret
= bt_ctf_field_type_compare(sequence_a
->element_type
,
5096 sequence_b
->element_type
);
5098 BT_LOGV("Sequence field types differ: different element field types: "
5099 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
5100 sequence_a
->element_type
, sequence_b
->element_type
);
5107 int bt_ctf_field_type_compare(struct bt_ctf_field_type
*type_a
,
5108 struct bt_ctf_field_type
*type_b
)
5112 if (type_a
== type_b
) {
5113 /* Same reference: equal (even if both are NULL) */
5119 BT_LOGW_STR("Invalid parameter: field type A is NULL.");
5125 BT_LOGW_STR("Invalid parameter: field type B is NULL.");
5130 if (type_a
->id
!= type_b
->id
) {
5131 /* Different type IDs */
5132 BT_LOGV("Field types differ: different IDs: "
5133 "ft-a-addr=%p, ft-b-addr=%p, "
5134 "ft-a-id=%s, ft-b-id=%s",
5136 bt_ctf_field_type_id_string(type_a
->id
),
5137 bt_ctf_field_type_id_string(type_b
->id
));
5141 if (type_a
->id
== BT_CTF_FIELD_TYPE_ID_UNKNOWN
) {
5142 /* Both have unknown type IDs */
5143 BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
5147 ret
= type_compare_funcs
[type_a
->id
](type_a
, type_b
);
5149 BT_LOGV("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
5158 int64_t bt_ctf_field_type_get_field_count(struct bt_ctf_field_type
*field_type
)
5160 int64_t field_count
= -1;
5161 enum bt_ctf_field_type_id type_id
= bt_ctf_field_type_get_type_id(field_type
);
5164 case CTF_TYPE_STRUCT
:
5166 bt_ctf_field_type_structure_get_field_count(field_type
);
5168 case CTF_TYPE_VARIANT
:
5170 bt_ctf_field_type_variant_get_field_count(field_type
);
5172 case CTF_TYPE_ARRAY
:
5173 case CTF_TYPE_SEQUENCE
:
5175 * Array and sequence types always contain a single member
5176 * (the element type).
5188 struct bt_ctf_field_type
*bt_ctf_field_type_get_field_at_index(
5189 struct bt_ctf_field_type
*field_type
, int index
)
5191 struct bt_ctf_field_type
*field
= NULL
;
5192 enum bt_ctf_field_type_id type_id
= bt_ctf_field_type_get_type_id(field_type
);
5195 case CTF_TYPE_STRUCT
:
5196 bt_ctf_field_type_structure_get_field_by_index(field_type
,
5197 NULL
, &field
, index
);
5199 case CTF_TYPE_VARIANT
:
5201 int ret
= bt_ctf_field_type_variant_get_field_by_index(
5202 field_type
, NULL
, &field
, index
);
5209 case CTF_TYPE_ARRAY
:
5210 field
= bt_ctf_field_type_array_get_element_type(field_type
);
5212 case CTF_TYPE_SEQUENCE
:
5213 field
= bt_ctf_field_type_sequence_get_element_type(field_type
);
5223 int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type
*field_type
,
5226 int field_index
= -1;
5227 enum bt_ctf_field_type_id type_id
= bt_ctf_field_type_get_type_id(field_type
);
5230 case CTF_TYPE_STRUCT
:
5231 field_index
= bt_ctf_field_type_structure_get_field_name_index(
5234 case CTF_TYPE_VARIANT
:
5235 field_index
= bt_ctf_field_type_variant_get_field_name_index(
5245 struct bt_ctf_field_path
*bt_ctf_field_type_variant_get_tag_field_path(
5246 struct bt_ctf_field_type
*type
)
5248 struct bt_ctf_field_path
*field_path
= NULL
;
5249 struct bt_ctf_field_type_variant
*variant
;
5252 BT_LOGW_STR("Invalid parameter: field type is NULL.");
5256 if (!bt_ctf_field_type_is_variant(type
)) {
5257 BT_LOGW("Invalid parameter: field type is not a variant field type: "
5258 "addr=%p, ft-id=%s", type
,
5259 bt_ctf_field_type_id_string(type
->id
));
5263 variant
= container_of(type
, struct bt_ctf_field_type_variant
,
5265 field_path
= bt_get(variant
->tag_field_path
);
5270 struct bt_ctf_field_path
*bt_ctf_field_type_sequence_get_length_field_path(
5271 struct bt_ctf_field_type
*type
)
5273 struct bt_ctf_field_path
*field_path
= NULL
;
5274 struct bt_ctf_field_type_sequence
*sequence
;
5277 BT_LOGW_STR("Invalid parameter: field type is NULL.");
5281 if (!bt_ctf_field_type_is_sequence(type
)) {
5282 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
5283 "addr=%p, ft-id=%s", type
,
5284 bt_ctf_field_type_id_string(type
->id
));
5288 sequence
= container_of(type
, struct bt_ctf_field_type_sequence
,
5290 field_path
= bt_get(sequence
->length_field_path
);