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/assert-pre-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/field-path-internal.h>
35 #include <babeltrace/ctf-ir/fields-internal.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-ir/utils-internal.h>
38 #include <babeltrace/ref.h>
39 #include <babeltrace/ctf-ir/clock-class.h>
40 #include <babeltrace/ctf-ir/clock-class-internal.h>
41 #include <babeltrace/object-internal.h>
42 #include <babeltrace/ref.h>
43 #include <babeltrace/compiler-internal.h>
44 #include <babeltrace/endian-internal.h>
45 #include <babeltrace/assert-internal.h>
46 #include <babeltrace/compat/glib-internal.h>
51 enum bt_field_type_id
bt_field_type_get_type_id(struct bt_field_type
*ft
)
53 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
58 void init_field_type(struct bt_field_type
*ft
, enum bt_field_type_id id
,
59 bt_object_release_func release_func
)
62 BT_ASSERT(bt_field_type_has_known_id(ft
));
63 BT_ASSERT(release_func
);
64 bt_object_init_shared(&ft
->base
, release_func
);
69 void init_integer_field_type(struct bt_field_type_integer
*ft
, enum bt_field_type_id id
,
70 bt_object_release_func release_func
)
72 init_field_type((void *) ft
, id
, release_func
);
74 ft
->base
= BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
78 void destroy_integer_field_type(struct bt_object
*obj
)
81 BT_LIB_LOGD("Destroying integer field type object: %!+F", obj
);
86 struct bt_field_type
*create_integer_field_type(enum bt_field_type_id id
)
88 struct bt_field_type_integer
*int_ft
= NULL
;
90 BT_LOGD("Creating default integer field type object: id=%s",
91 bt_common_field_type_id_string(id
));
92 int_ft
= g_new0(struct bt_field_type_integer
, 1);
94 BT_LOGE_STR("Failed to allocate one integer field type.");
98 init_integer_field_type(int_ft
, id
, destroy_integer_field_type
);
99 BT_LIB_LOGD("Created integer field type object: %!+F", int_ft
);
106 return (void *) int_ft
;
109 struct bt_field_type
*bt_field_type_unsigned_integer_create(void)
111 return create_integer_field_type(BT_FIELD_TYPE_ID_UNSIGNED_INTEGER
);
114 struct bt_field_type
*bt_field_type_signed_integer_create(void)
116 return create_integer_field_type(BT_FIELD_TYPE_ID_SIGNED_INTEGER
);
119 uint64_t bt_field_type_integer_get_field_value_range(
120 struct bt_field_type
*ft
)
122 struct bt_field_type_integer
*int_ft
= (void *) ft
;
124 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
125 BT_ASSERT_PRE_FT_IS_INT(ft
, "Field type");
126 return int_ft
->range
;
131 bool size_is_valid_for_enumeration_field_type(struct bt_field_type
*ft
,
138 int bt_field_type_integer_set_field_value_range(
139 struct bt_field_type
*ft
, uint64_t size
)
141 struct bt_field_type_integer
*int_ft
= (void *) ft
;
143 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
144 BT_ASSERT_PRE_FT_IS_INT(ft
, "Field type");
145 BT_ASSERT_PRE_FT_HOT(ft
, "Field type");
146 BT_ASSERT_PRE(size
<= 64,
147 "Unsupported size for integer field type's field value range "
148 "(maximum is 64): size=%" PRIu64
, size
);
149 BT_ASSERT_PRE(int_ft
->common
.id
== BT_FIELD_TYPE_ID_UNSIGNED_INTEGER
||
150 int_ft
->common
.id
== BT_FIELD_TYPE_ID_SIGNED_INTEGER
||
151 size_is_valid_for_enumeration_field_type(ft
, size
),
152 "Invalid field value range for enumeration field type: "
153 "at least one of the current mapping ranges contains values "
154 "which are outside this range: %!+F, size=%" PRIu64
, ft
, size
);
155 int_ft
->range
= size
;
156 BT_LIB_LOGV("Set integer field type's field value range: %!+F", ft
);
160 enum bt_field_type_integer_preferred_display_base
161 bt_field_type_integer_get_preferred_display_base(struct bt_field_type
*ft
)
163 struct bt_field_type_integer
*int_ft
= (void *) ft
;
165 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
166 BT_ASSERT_PRE_FT_IS_INT(ft
, "Field type");
170 int bt_field_type_integer_set_preferred_display_base(struct bt_field_type
*ft
,
171 enum bt_field_type_integer_preferred_display_base base
)
173 struct bt_field_type_integer
*int_ft
= (void *) ft
;
175 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
176 BT_ASSERT_PRE_FT_IS_INT(ft
, "Field type");
177 BT_ASSERT_PRE_FT_HOT(ft
, "Field type");
179 BT_LIB_LOGV("Set integer field type's preferred display base: %!+F", ft
);
184 void finalize_enumeration_field_type_mapping(
185 struct bt_field_type_enumeration_mapping
*mapping
)
189 if (mapping
->label
) {
190 g_string_free(mapping
->label
, TRUE
);
193 if (mapping
->ranges
) {
194 g_array_free(mapping
->ranges
, TRUE
);
199 void destroy_enumeration_field_type(struct bt_object
*obj
)
201 struct bt_field_type_enumeration
*ft
= (void *) obj
;
204 BT_LIB_LOGD("Destroying enumeration field type object: %!+F", ft
);
209 for (i
= 0; i
< ft
->mappings
->len
; i
++) {
210 finalize_enumeration_field_type_mapping(
211 BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft
, i
));
214 g_array_free(ft
->mappings
, TRUE
);
218 g_ptr_array_free(ft
->label_buf
, TRUE
);
225 struct bt_field_type
*create_enumeration_field_type(enum bt_field_type_id id
)
227 struct bt_field_type_enumeration
*enum_ft
= NULL
;
229 BT_LOGD("Creating default enumeration field type object: id=%s",
230 bt_common_field_type_id_string(id
));
231 enum_ft
= g_new0(struct bt_field_type_enumeration
, 1);
233 BT_LOGE_STR("Failed to allocate one enumeration field type.");
237 init_integer_field_type((void *) enum_ft
, id
,
238 destroy_enumeration_field_type
);
239 enum_ft
->mappings
= g_array_new(FALSE
, TRUE
,
240 sizeof(struct bt_field_type_enumeration_mapping
));
241 if (!enum_ft
->mappings
) {
242 BT_LOGE_STR("Failed to allocate a GArray.");
246 enum_ft
->label_buf
= g_ptr_array_new();
247 if (!enum_ft
->label_buf
) {
248 BT_LOGE_STR("Failed to allocate a GArray.");
252 BT_LIB_LOGD("Created enumeration field type object: %!+F", enum_ft
);
259 return (void *) enum_ft
;
262 struct bt_field_type
*bt_field_type_unsigned_enumeration_create(void)
264 return create_enumeration_field_type(
265 BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION
);
268 struct bt_field_type
*bt_field_type_signed_enumeration_create(void)
270 return create_enumeration_field_type(
271 BT_FIELD_TYPE_ID_SIGNED_ENUMERATION
);
274 uint64_t bt_field_type_enumeration_get_mapping_count(struct bt_field_type
*ft
)
276 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
278 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
279 BT_ASSERT_PRE_FT_IS_ENUM(ft
, "Field type");
280 return (uint64_t) enum_ft
->mappings
->len
;
283 void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
284 struct bt_field_type
*ft
, uint64_t index
,
286 struct bt_field_type_unsigned_enumeration_mapping_ranges
**ranges
)
288 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
289 struct bt_field_type_enumeration_mapping
*mapping
;
291 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
292 BT_ASSERT_PRE_NON_NULL(name
, "Name (output)");
293 BT_ASSERT_PRE_NON_NULL(ranges
, "Ranges (output)");
294 BT_ASSERT_PRE_VALID_INDEX(index
, enum_ft
->mappings
->len
);
295 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION
,
297 mapping
= BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft
, index
);
298 *name
= mapping
->label
->str
;
299 *ranges
= (void *) mapping
;
302 void bt_field_type_signed_enumeration_borrow_mapping_by_index(
303 struct bt_field_type
*ft
, uint64_t index
,
305 struct bt_field_type_signed_enumeration_mapping_ranges
**ranges
)
307 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
308 struct bt_field_type_enumeration_mapping
*mapping
;
310 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
311 BT_ASSERT_PRE_NON_NULL(name
, "Name (output)");
312 BT_ASSERT_PRE_NON_NULL(ranges
, "Ranges (output)");
313 BT_ASSERT_PRE_VALID_INDEX(index
, enum_ft
->mappings
->len
);
314 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION
,
316 mapping
= BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft
, index
);
317 *name
= mapping
->label
->str
;
318 *ranges
= (void *) mapping
;
322 uint64_t get_enumeration_field_type_mapping_range_count(
323 struct bt_field_type_enumeration_mapping
*mapping
)
325 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
326 return (uint64_t) mapping
->ranges
->len
;
329 uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
330 struct bt_field_type_unsigned_enumeration_mapping_ranges
*ranges
)
332 return get_enumeration_field_type_mapping_range_count((void *) ranges
);
335 uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
336 struct bt_field_type_signed_enumeration_mapping_ranges
*ranges
)
338 return get_enumeration_field_type_mapping_range_count((void *) ranges
);
342 void get_enumeration_field_type_mapping_range_at_index(
343 struct bt_field_type_enumeration_mapping
*mapping
,
344 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
346 struct bt_field_type_enumeration_mapping_range
*range
;
348 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
349 BT_ASSERT_PRE_NON_NULL(lower
, "Range's lower (output)");
350 BT_ASSERT_PRE_NON_NULL(upper
, "Range's upper (output)");
351 BT_ASSERT_PRE_VALID_INDEX(index
, mapping
->ranges
->len
);
352 range
= BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping
, index
);
353 *lower
= range
->lower
.u
;
354 *upper
= range
->upper
.u
;
357 void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
358 struct bt_field_type_unsigned_enumeration_mapping_ranges
*ranges
,
359 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
361 get_enumeration_field_type_mapping_range_at_index((void *) ranges
,
362 index
, lower
, upper
);
365 void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
366 struct bt_field_type_unsigned_enumeration_mapping_ranges
*ranges
,
367 uint64_t index
, int64_t *lower
, int64_t *upper
)
369 get_enumeration_field_type_mapping_range_at_index((void *) ranges
,
370 index
, (uint64_t *) lower
, (uint64_t *) upper
);
375 int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
376 struct bt_field_type
*ft
, uint64_t value
,
377 bt_field_type_enumeration_mapping_label_array
*label_array
,
380 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
383 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
384 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
385 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
386 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION
,
388 g_ptr_array_set_size(enum_ft
->label_buf
, 0);
390 for (i
= 0; i
< enum_ft
->mappings
->len
; i
++) {
392 struct bt_field_type_enumeration_mapping
*mapping
=
393 BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft
, i
);
395 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
396 struct bt_field_type_enumeration_mapping_range
*range
=
397 BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
400 if (value
>= range
->lower
.u
&&
401 value
<= range
->upper
.u
) {
402 g_ptr_array_add(enum_ft
->label_buf
,
403 mapping
->label
->str
);
409 *label_array
= (void *) enum_ft
->label_buf
->pdata
;
410 *count
= (uint64_t) enum_ft
->label_buf
->len
;
414 int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
415 struct bt_field_type
*ft
, int64_t value
,
416 bt_field_type_enumeration_mapping_label_array
*label_array
,
419 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
422 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
423 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
424 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
425 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION
,
427 g_ptr_array_set_size(enum_ft
->label_buf
, 0);
429 for (i
= 0; i
< enum_ft
->mappings
->len
; i
++) {
431 struct bt_field_type_enumeration_mapping
*mapping
=
432 BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft
, i
);
434 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
435 struct bt_field_type_enumeration_mapping_range
*range
=
436 BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
439 if (value
>= range
->lower
.i
&&
440 value
<= range
->upper
.i
) {
441 g_ptr_array_add(enum_ft
->label_buf
,
442 mapping
->label
->str
);
448 *label_array
= (void *) enum_ft
->label_buf
->pdata
;
449 *count
= (uint64_t) enum_ft
->label_buf
->len
;
454 int add_mapping_to_enumeration_field_type(struct bt_field_type
*ft
,
455 const char *label
, uint64_t lower
, uint64_t upper
)
459 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
460 struct bt_field_type_enumeration_mapping
*mapping
= NULL
;
461 struct bt_field_type_enumeration_mapping_range
*range
;
464 BT_ASSERT_PRE_NON_NULL(label
, "Label");
466 /* Find existing mapping identified by this label */
467 for (i
= 0; i
< enum_ft
->mappings
->len
; i
++) {
468 struct bt_field_type_enumeration_mapping
*mapping_candidate
=
469 BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft
, i
);
471 if (strcmp(mapping_candidate
->label
->str
, label
) == 0) {
472 mapping
= mapping_candidate
;
478 /* Create new mapping for this label */
479 g_array_set_size(enum_ft
->mappings
, enum_ft
->mappings
->len
+ 1);
480 mapping
= BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft
,
481 enum_ft
->mappings
->len
- 1);
482 mapping
->ranges
= g_array_new(FALSE
, TRUE
,
483 sizeof(struct bt_field_type_enumeration_mapping_range
));
484 if (!mapping
->ranges
) {
485 finalize_enumeration_field_type_mapping(mapping
);
486 g_array_set_size(enum_ft
->mappings
,
487 enum_ft
->mappings
->len
- 1);
492 mapping
->label
= g_string_new(label
);
493 if (!mapping
->label
) {
494 finalize_enumeration_field_type_mapping(mapping
);
495 g_array_set_size(enum_ft
->mappings
,
496 enum_ft
->mappings
->len
- 1);
504 g_array_set_size(mapping
->ranges
, mapping
->ranges
->len
+ 1);
505 range
= BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping
,
506 mapping
->ranges
->len
- 1);
507 range
->lower
.u
= lower
;
508 range
->upper
.u
= upper
;
509 BT_LIB_LOGV("Added mapping to enumeration field type: "
510 "%![ft-]+F, label=\"%s\", lower-unsigned=%" PRIu64
", "
511 "upper-unsigned=%" PRIu64
, ft
, label
, lower
, upper
);
517 int bt_field_type_unsigned_enumeration_map_range(
518 struct bt_field_type
*ft
, const char *label
,
519 uint64_t range_lower
, uint64_t range_upper
)
521 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
523 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
524 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION
,
526 BT_ASSERT_PRE(range_lower
<= range_upper
,
527 "Range's upper bound is less than lower bound: "
528 "upper=%" PRIu64
", lower=%" PRIu64
,
529 range_lower
, range_upper
);
530 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft
->common
.range
,
532 "Range's lower bound is outside the enumeration field type's value range: "
533 "%![ft-]+F, lower=%" PRIu64
, ft
, range_lower
);
534 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft
->common
.range
,
536 "Range's upper bound is outside the enumeration field type's value range: "
537 "%![ft-]+F, upper=%" PRIu64
, ft
, range_upper
);
538 return add_mapping_to_enumeration_field_type(ft
, label
, range_lower
,
542 int bt_field_type_signed_enumeration_map_range(
543 struct bt_field_type
*ft
, const char *label
,
544 int64_t range_lower
, int64_t range_upper
)
546 struct bt_field_type_enumeration
*enum_ft
= (void *) ft
;
548 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
549 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION
,
551 BT_ASSERT_PRE(range_lower
<= range_upper
,
552 "Range's upper bound is less than lower bound: "
553 "upper=%" PRId64
", lower=%" PRId64
,
554 range_lower
, range_upper
);
555 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft
->common
.range
,
557 "Range's lower bound is outside the enumeration field type's value range: "
558 "%![ft-]+F, lower=%" PRId64
, ft
, range_lower
);
559 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft
->common
.range
,
561 "Range's upper bound is outside the enumeration field type's value range: "
562 "%![ft-]+F, upper=%" PRId64
, ft
, range_upper
);
563 return add_mapping_to_enumeration_field_type(ft
, label
, range_lower
,
568 void destroy_real_field_type(struct bt_object
*obj
)
571 BT_LIB_LOGD("Destroying real field type object: %!+F", obj
);
575 struct bt_field_type
*bt_field_type_real_create(void)
577 struct bt_field_type_real
*real_ft
= NULL
;
579 BT_LOGD_STR("Creating default real field type object.");
580 real_ft
= g_new0(struct bt_field_type_real
, 1);
582 BT_LOGE_STR("Failed to allocate one real field type.");
586 init_field_type((void *) real_ft
, BT_FIELD_TYPE_ID_REAL
,
587 destroy_real_field_type
);
588 BT_LIB_LOGD("Created real field type object: %!+F", real_ft
);
595 return (void *) real_ft
;
598 bt_bool
bt_field_type_real_is_single_precision(struct bt_field_type
*ft
)
600 struct bt_field_type_real
*real_ft
= (void *) ft
;
602 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
603 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_REAL
, "Field type");
604 return real_ft
->is_single_precision
;
607 int bt_field_type_real_set_is_single_precision(struct bt_field_type
*ft
,
608 bt_bool is_single_precision
)
610 struct bt_field_type_real
*real_ft
= (void *) ft
;
612 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
613 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_REAL
, "Field type");
614 BT_ASSERT_PRE_FT_HOT(ft
, "Field type");
615 real_ft
->is_single_precision
= (bool) is_single_precision
;
616 BT_LIB_LOGV("Set real field type's \"is single precision\" property: "
622 int init_named_field_types_container(
623 struct bt_field_type_named_field_types_container
*ft
,
624 enum bt_field_type_id id
, bt_object_release_func release_func
)
628 init_field_type((void *) ft
, id
, release_func
);
629 ft
->named_fts
= g_array_new(FALSE
, TRUE
,
630 sizeof(struct bt_named_field_type
));
631 if (!ft
->named_fts
) {
632 BT_LOGE_STR("Failed to allocate a GArray.");
637 ft
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
638 if (!ft
->name_to_index
) {
639 BT_LOGE_STR("Failed to allocate a GHashTable.");
649 void finalize_named_field_type(struct bt_named_field_type
*named_ft
)
652 BT_LIB_LOGD("Finalizing named field type: "
653 "addr=%p, name=\"%s\", %![ft-]+F",
654 named_ft
, named_ft
->name
? named_ft
->name
->str
: NULL
,
657 if (named_ft
->name
) {
658 g_string_free(named_ft
->name
, TRUE
);
661 BT_LOGD_STR("Putting named field type's field type.");
662 bt_put(named_ft
->ft
);
666 void finalize_named_field_types_container(
667 struct bt_field_type_named_field_types_container
*ft
)
674 for (i
= 0; i
< ft
->named_fts
->len
; i
++) {
675 finalize_named_field_type(
676 &g_array_index(ft
->named_fts
,
677 struct bt_named_field_type
, i
));
680 g_array_free(ft
->named_fts
, TRUE
);
683 if (ft
->name_to_index
) {
684 g_hash_table_destroy(ft
->name_to_index
);
689 void destroy_structure_field_type(struct bt_object
*obj
)
692 BT_LIB_LOGD("Destroying string field type object: %!+F", obj
);
693 finalize_named_field_types_container((void *) obj
);
697 struct bt_field_type
*bt_field_type_structure_create(void)
700 struct bt_field_type_structure
*struct_ft
= NULL
;
702 BT_LOGD_STR("Creating default structure field type object.");
703 struct_ft
= g_new0(struct bt_field_type_structure
, 1);
705 BT_LOGE_STR("Failed to allocate one structure field type.");
709 ret
= init_named_field_types_container((void *) struct_ft
,
710 BT_FIELD_TYPE_ID_STRUCTURE
, destroy_structure_field_type
);
715 BT_LIB_LOGD("Created structure field type object: %!+F", struct_ft
);
722 return (void *) struct_ft
;
726 int append_named_field_type_to_container_field_type(
727 struct bt_field_type_named_field_types_container
*container_ft
,
728 const char *name
, struct bt_field_type
*ft
)
731 struct bt_named_field_type
*named_ft
;
734 BT_ASSERT(container_ft
);
735 BT_ASSERT_PRE_FT_HOT(container_ft
, "Field type");
736 BT_ASSERT_PRE_NON_NULL(name
, "Name");
737 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
738 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_ft
->name_to_index
,
740 "Duplicate member/option name in structure/variant field type: "
741 "%![container-ft-]+F, name=\"%s\"", container_ft
, name
);
742 name_str
= g_string_new(name
);
744 BT_LOGE_STR("Failed to allocate a GString.");
749 g_array_set_size(container_ft
->named_fts
,
750 container_ft
->named_fts
->len
+ 1);
751 named_ft
= &g_array_index(container_ft
->named_fts
,
752 struct bt_named_field_type
, container_ft
->named_fts
->len
- 1);
753 named_ft
->name
= name_str
;
754 named_ft
->ft
= bt_get(ft
);
755 g_hash_table_insert(container_ft
->name_to_index
, named_ft
->name
->str
,
756 GUINT_TO_POINTER(container_ft
->named_fts
->len
- 1));
757 bt_field_type_freeze(ft
);
763 int bt_field_type_structure_append_member(struct bt_field_type
*ft
,
764 const char *name
, struct bt_field_type
*member_ft
)
766 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
767 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCTURE
, "Field type");
768 return append_named_field_type_to_container_field_type((void *) ft
,
772 uint64_t bt_field_type_structure_get_member_count(struct bt_field_type
*ft
)
774 struct bt_field_type_structure
*struct_ft
= (void *) ft
;
776 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
777 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCTURE
, "Field type");
778 return (uint64_t) struct_ft
->common
.named_fts
->len
;
782 void borrow_named_field_type_from_container_field_type_at_index(
783 struct bt_field_type_named_field_types_container
*ft
,
784 uint64_t index
, const char **name
,
785 struct bt_field_type
**out_ft
)
787 struct bt_named_field_type
*named_ft
;
790 BT_ASSERT_PRE_NON_NULL(name
, "Name");
791 BT_ASSERT_PRE_NON_NULL(out_ft
, "Field type (output)");
792 BT_ASSERT_PRE_VALID_INDEX(index
, ft
->named_fts
->len
);
793 named_ft
= BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft
, index
);
794 *name
= named_ft
->name
->str
;
795 *out_ft
= named_ft
->ft
;
798 void bt_field_type_structure_borrow_member_by_index(
799 struct bt_field_type
*ft
, uint64_t index
,
800 const char **name
, struct bt_field_type
**out_ft
)
802 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
803 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCTURE
, "Field type");
804 borrow_named_field_type_from_container_field_type_at_index((void *) ft
,
805 index
, name
, out_ft
);
809 struct bt_field_type
*borrow_field_type_from_container_field_type_by_name(
810 struct bt_field_type_named_field_types_container
*ft
,
813 struct bt_field_type
*ret_ft
= NULL
;
814 struct bt_named_field_type
*named_ft
;
819 BT_ASSERT_PRE_NON_NULL(name
, "Name");
820 if (!g_hash_table_lookup_extended(ft
->name_to_index
, name
, &orig_key
,
825 named_ft
= BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft
,
826 GPOINTER_TO_UINT(value
));
827 ret_ft
= named_ft
->ft
;
833 struct bt_field_type
*bt_field_type_structure_borrow_member_field_type_by_name(
834 struct bt_field_type
*ft
, const char *name
)
836 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
837 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_STRUCTURE
, "Field type");
838 return borrow_field_type_from_container_field_type_by_name((void *) ft
,
843 void destroy_variant_field_type(struct bt_object
*obj
)
845 struct bt_field_type_variant
*ft
= (void *) obj
;
848 BT_LIB_LOGD("Destroying variant field type object: %!+F", ft
);
849 finalize_named_field_types_container((void *) ft
);
850 BT_LOGD_STR("Putting selector field path.");
851 bt_put(ft
->selector_field_path
);
855 struct bt_field_type
*bt_field_type_variant_create(void)
858 struct bt_field_type_variant
*var_ft
= NULL
;
860 BT_LOGD_STR("Creating default variant field type object.");
861 var_ft
= g_new0(struct bt_field_type_variant
, 1);
863 BT_LOGE_STR("Failed to allocate one variant field type.");
867 ret
= init_named_field_types_container((void *) var_ft
,
868 BT_FIELD_TYPE_ID_VARIANT
, destroy_variant_field_type
);
873 BT_LIB_LOGD("Created variant field type object: %!+F", var_ft
);
880 return (void *) var_ft
;
883 int bt_field_type_variant_set_selector_field_type(
884 struct bt_field_type
*ft
, struct bt_field_type
*selector_ft
)
886 struct bt_field_type_variant
*var_ft
= (void *) ft
;
888 BT_ASSERT_PRE_NON_NULL(ft
, "Variant field type");
889 BT_ASSERT_PRE_NON_NULL(selector_ft
, "Selector field type");
890 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
, "Field type");
891 BT_ASSERT_PRE_FT_IS_ENUM(selector_ft
, "Selector field type");
892 BT_ASSERT_PRE_FT_HOT(ft
, "Variant field type");
893 var_ft
->selector_ft
= selector_ft
;
894 bt_field_type_freeze(selector_ft
);
898 int bt_field_type_variant_append_option(struct bt_field_type
*ft
,
899 const char *name
, struct bt_field_type
*option_ft
)
901 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
902 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
, "Field type");
903 return append_named_field_type_to_container_field_type((void *) ft
,
907 struct bt_field_type
*bt_field_type_variant_borrow_option_field_type_by_name(
908 struct bt_field_type
*ft
, const char *name
)
910 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
911 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
, "Field type");
912 return borrow_field_type_from_container_field_type_by_name((void *) ft
,
916 uint64_t bt_field_type_variant_get_option_count(struct bt_field_type
*ft
)
918 struct bt_field_type_variant
*var_ft
= (void *) ft
;
920 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
921 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
, "Field type");
922 return (uint64_t) var_ft
->common
.named_fts
->len
;
925 void bt_field_type_variant_borrow_option_by_index(
926 struct bt_field_type
*ft
, uint64_t index
,
927 const char **name
, struct bt_field_type
**out_ft
)
929 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
930 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
, "Field type");
931 borrow_named_field_type_from_container_field_type_at_index((void *) ft
,
932 index
, name
, out_ft
);
935 struct bt_field_path
*bt_field_type_variant_borrow_selector_field_path(
936 struct bt_field_type
*ft
)
938 struct bt_field_type_variant
*var_ft
= (void *) ft
;
940 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
941 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_VARIANT
,
943 return var_ft
->selector_field_path
;
947 void init_array_field_type(struct bt_field_type_array
*ft
,
948 enum bt_field_type_id id
, bt_object_release_func release_func
,
949 struct bt_field_type
*element_ft
)
951 BT_ASSERT(element_ft
);
952 init_field_type((void *) ft
, id
, release_func
);
953 ft
->element_ft
= bt_get(element_ft
);
954 bt_field_type_freeze(element_ft
);
958 void finalize_array_field_type(struct bt_field_type_array
*array_ft
)
961 BT_LOGD_STR("Putting element field type.");
962 bt_put(array_ft
->element_ft
);
966 void destroy_static_array_field_type(struct bt_object
*obj
)
969 BT_LIB_LOGD("Destroying static array field type object: %!+F", obj
);
970 finalize_array_field_type((void *) obj
);
974 struct bt_field_type
*bt_field_type_static_array_create(
975 struct bt_field_type
*element_ft
, uint64_t length
)
977 struct bt_field_type_static_array
*array_ft
= NULL
;
979 BT_ASSERT_PRE_NON_NULL(element_ft
, "Element field type");
980 BT_LOGD_STR("Creating default static array field type object.");
981 array_ft
= g_new0(struct bt_field_type_static_array
, 1);
983 BT_LOGE_STR("Failed to allocate one static array field type.");
987 init_array_field_type((void *) array_ft
, BT_FIELD_TYPE_ID_STATIC_ARRAY
,
988 destroy_static_array_field_type
, element_ft
);
989 array_ft
->length
= length
;
990 BT_LIB_LOGD("Created static array field type object: %!+F", array_ft
);
997 return (void *) array_ft
;
1000 struct bt_field_type
*bt_field_type_array_borrow_element_field_type(
1001 struct bt_field_type
*ft
)
1003 struct bt_field_type_array
*array_ft
= (void *) ft
;
1005 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1006 BT_ASSERT_PRE_FT_IS_ARRAY(ft
, "Field type");
1007 return array_ft
->element_ft
;
1010 uint64_t bt_field_type_static_array_get_length(struct bt_field_type
*ft
)
1012 struct bt_field_type_static_array
*array_ft
= (void *) ft
;
1014 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1015 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_STATIC_ARRAY
,
1017 return (uint64_t) array_ft
->length
;
1021 void destroy_dynamic_array_field_type(struct bt_object
*obj
)
1023 struct bt_field_type_dynamic_array
*ft
= (void *) obj
;
1026 BT_LIB_LOGD("Destroying dynamic array field type object: %!+F", ft
);
1027 finalize_array_field_type((void *) ft
);
1028 BT_LOGD_STR("Putting length field path.");
1029 bt_put(ft
->length_field_path
);
1033 struct bt_field_type
*bt_field_type_dynamic_array_create(
1034 struct bt_field_type
*element_ft
)
1036 struct bt_field_type_dynamic_array
*array_ft
= NULL
;
1038 BT_ASSERT_PRE_NON_NULL(element_ft
, "Element field type");
1039 BT_LOGD_STR("Creating default dynamic array field type object.");
1040 array_ft
= g_new0(struct bt_field_type_dynamic_array
, 1);
1042 BT_LOGE_STR("Failed to allocate one dynamic array field type.");
1046 init_array_field_type((void *) array_ft
, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY
,
1047 destroy_dynamic_array_field_type
, element_ft
);
1048 BT_LIB_LOGD("Created dynamic array field type object: %!+F", array_ft
);
1055 return (void *) array_ft
;
1058 int bt_field_type_dynamic_array_set_length_field_type(struct bt_field_type
*ft
,
1059 struct bt_field_type
*length_ft
)
1061 struct bt_field_type_dynamic_array
*array_ft
= (void *) ft
;
1063 BT_ASSERT_PRE_NON_NULL(ft
, "Dynamic array field type");
1064 BT_ASSERT_PRE_NON_NULL(length_ft
, "Length field type");
1065 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY
,
1067 BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(length_ft
, "Length field type");
1068 BT_ASSERT_PRE_FT_HOT(ft
, "Dynamic array field type");
1069 array_ft
->length_ft
= length_ft
;
1070 bt_field_type_freeze(length_ft
);
1074 struct bt_field_path
*bt_field_type_dynamic_array_borrow_length_field_path(
1075 struct bt_field_type
*ft
)
1077 struct bt_field_type_dynamic_array
*seq_ft
= (void *) ft
;
1079 BT_ASSERT_PRE_NON_NULL(ft
, "Field type");
1080 BT_ASSERT_PRE_FT_HAS_ID(ft
, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY
,
1082 return seq_ft
->length_field_path
;
1086 void destroy_string_field_type(struct bt_object
*obj
)
1089 BT_LIB_LOGD("Destroying string field type object: %!+F", obj
);
1093 struct bt_field_type
*bt_field_type_string_create(void)
1095 struct bt_field_type_string
*string_ft
= NULL
;
1097 BT_LOGD_STR("Creating default string field type object.");
1098 string_ft
= g_new0(struct bt_field_type_string
, 1);
1100 BT_LOGE_STR("Failed to allocate one string field type.");
1104 init_field_type((void *) string_ft
, BT_FIELD_TYPE_ID_STRING
,
1105 destroy_string_field_type
);
1106 BT_LIB_LOGD("Created string field type object: %!+F", string_ft
);
1113 return (void *) string_ft
;
1117 void _bt_field_type_freeze(struct bt_field_type
*ft
)
1120 * Element/member/option field types are frozen when added to
1128 void _bt_field_type_make_part_of_trace(struct bt_field_type
*ft
)
1131 BT_ASSERT_PRE(!ft
->part_of_trace
,
1132 "Field type is already part of a trace: %!+F", ft
);
1133 ft
->part_of_trace
= true;
1136 case BT_FIELD_TYPE_ID_STRUCTURE
:
1137 case BT_FIELD_TYPE_ID_VARIANT
:
1139 struct bt_field_type_named_field_types_container
*container_ft
=
1143 for (i
= 0; i
< container_ft
->named_fts
->len
; i
++) {
1144 struct bt_named_field_type
*named_ft
=
1145 BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
1148 bt_field_type_make_part_of_trace(named_ft
->ft
);
1153 case BT_FIELD_TYPE_ID_STATIC_ARRAY
:
1154 case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY
:
1156 struct bt_field_type_array
*array_ft
= (void *) ft
;
1158 bt_field_type_make_part_of_trace(array_ft
->element_ft
);