4 * Babeltrace trace 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-CLASSES"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/assert-pre-internal.h>
33 #include <babeltrace/trace-ir/field-classes-internal.h>
34 #include <babeltrace/trace-ir/field-path-internal.h>
35 #include <babeltrace/trace-ir/fields-internal.h>
36 #include <babeltrace/trace-ir/fields.h>
37 #include <babeltrace/trace-ir/utils-internal.h>
38 #include <babeltrace/ref.h>
39 #include <babeltrace/trace-ir/clock-class.h>
40 #include <babeltrace/trace-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_class_id
bt_field_class_get_id(struct bt_field_class
*fc
)
53 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
58 void init_field_class(struct bt_field_class
*fc
, enum bt_field_class_id id
,
59 bt_object_release_func release_func
)
62 BT_ASSERT(bt_field_class_has_known_id(fc
));
63 BT_ASSERT(release_func
);
64 bt_object_init_shared(&fc
->base
, release_func
);
69 void init_integer_field_class(struct bt_field_class_integer
*fc
, enum bt_field_class_id id
,
70 bt_object_release_func release_func
)
72 init_field_class((void *) fc
, id
, release_func
);
74 fc
->base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
78 void destroy_integer_field_class(struct bt_object
*obj
)
81 BT_LIB_LOGD("Destroying integer field classe object: %!+F", obj
);
86 struct bt_field_class
*create_integer_field_class(enum bt_field_class_id id
)
88 struct bt_field_class_integer
*int_fc
= NULL
;
90 BT_LOGD("Creating default integer field classe object: id=%s",
91 bt_common_field_class_id_string(id
));
92 int_fc
= g_new0(struct bt_field_class_integer
, 1);
94 BT_LOGE_STR("Failed to allocate one integer field classe.");
98 init_integer_field_class(int_fc
, id
, destroy_integer_field_class
);
99 BT_LIB_LOGD("Created integer field classe object: %!+F", int_fc
);
106 return (void *) int_fc
;
109 struct bt_field_class
*bt_field_class_unsigned_integer_create(void)
111 return create_integer_field_class(BT_FIELD_CLASS_ID_UNSIGNED_INTEGER
);
114 struct bt_field_class
*bt_field_class_signed_integer_create(void)
116 return create_integer_field_class(BT_FIELD_CLASS_ID_SIGNED_INTEGER
);
119 uint64_t bt_field_class_integer_get_field_value_range(
120 struct bt_field_class
*fc
)
122 struct bt_field_class_integer
*int_fc
= (void *) fc
;
124 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
125 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
126 return int_fc
->range
;
131 bool size_is_valid_for_enumeration_field_class(struct bt_field_class
*fc
,
138 int bt_field_class_integer_set_field_value_range(
139 struct bt_field_class
*fc
, uint64_t size
)
141 struct bt_field_class_integer
*int_fc
= (void *) fc
;
143 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
144 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
145 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
146 BT_ASSERT_PRE(size
<= 64,
147 "Unsupported size for integer field classe's field value range "
148 "(maximum is 64): size=%" PRIu64
, size
);
149 BT_ASSERT_PRE(int_fc
->common
.id
== BT_FIELD_CLASS_ID_UNSIGNED_INTEGER
||
150 int_fc
->common
.id
== BT_FIELD_CLASS_ID_SIGNED_INTEGER
||
151 size_is_valid_for_enumeration_field_class(fc
, size
),
152 "Invalid field value range for enumeration field classe: "
153 "at least one of the current mapping ranges contains values "
154 "which are outside this range: %!+F, size=%" PRIu64
, fc
, size
);
155 int_fc
->range
= size
;
156 BT_LIB_LOGV("Set integer field classe's field value range: %!+F", fc
);
160 enum bt_field_class_integer_preferred_display_base
161 bt_field_class_integer_get_preferred_display_base(struct bt_field_class
*fc
)
163 struct bt_field_class_integer
*int_fc
= (void *) fc
;
165 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
166 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
170 int bt_field_class_integer_set_preferred_display_base(struct bt_field_class
*fc
,
171 enum bt_field_class_integer_preferred_display_base base
)
173 struct bt_field_class_integer
*int_fc
= (void *) fc
;
175 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
176 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
177 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
179 BT_LIB_LOGV("Set integer field classe's preferred display base: %!+F", fc
);
184 void finalize_enumeration_field_class_mapping(
185 struct bt_field_class_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_class(struct bt_object
*obj
)
201 struct bt_field_class_enumeration
*fc
= (void *) obj
;
204 BT_LIB_LOGD("Destroying enumeration field classe object: %!+F", fc
);
209 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
210 finalize_enumeration_field_class_mapping(
211 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
));
214 g_array_free(fc
->mappings
, TRUE
);
218 g_ptr_array_free(fc
->label_buf
, TRUE
);
225 struct bt_field_class
*create_enumeration_field_class(enum bt_field_class_id id
)
227 struct bt_field_class_enumeration
*enum_fc
= NULL
;
229 BT_LOGD("Creating default enumeration field classe object: id=%s",
230 bt_common_field_class_id_string(id
));
231 enum_fc
= g_new0(struct bt_field_class_enumeration
, 1);
233 BT_LOGE_STR("Failed to allocate one enumeration field classe.");
237 init_integer_field_class((void *) enum_fc
, id
,
238 destroy_enumeration_field_class
);
239 enum_fc
->mappings
= g_array_new(FALSE
, TRUE
,
240 sizeof(struct bt_field_class_enumeration_mapping
));
241 if (!enum_fc
->mappings
) {
242 BT_LOGE_STR("Failed to allocate a GArray.");
246 enum_fc
->label_buf
= g_ptr_array_new();
247 if (!enum_fc
->label_buf
) {
248 BT_LOGE_STR("Failed to allocate a GArray.");
252 BT_LIB_LOGD("Created enumeration field classe object: %!+F", enum_fc
);
259 return (void *) enum_fc
;
262 struct bt_field_class
*bt_field_class_unsigned_enumeration_create(void)
264 return create_enumeration_field_class(
265 BT_FIELD_CLASS_ID_UNSIGNED_ENUMERATION
);
268 struct bt_field_class
*bt_field_class_signed_enumeration_create(void)
270 return create_enumeration_field_class(
271 BT_FIELD_CLASS_ID_SIGNED_ENUMERATION
);
274 uint64_t bt_field_class_enumeration_get_mapping_count(struct bt_field_class
*fc
)
276 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
278 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
279 BT_ASSERT_PRE_FC_IS_ENUM(fc
, "Field class");
280 return (uint64_t) enum_fc
->mappings
->len
;
283 void bt_field_class_unsigned_enumeration_borrow_mapping_by_index(
284 struct bt_field_class
*fc
, uint64_t index
,
286 struct bt_field_class_unsigned_enumeration_mapping_ranges
**ranges
)
288 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
289 struct bt_field_class_enumeration_mapping
*mapping
;
291 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
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_fc
->mappings
->len
);
295 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_UNSIGNED_ENUMERATION
,
297 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
298 *name
= mapping
->label
->str
;
299 *ranges
= (void *) mapping
;
302 void bt_field_class_signed_enumeration_borrow_mapping_by_index(
303 struct bt_field_class
*fc
, uint64_t index
,
305 struct bt_field_class_signed_enumeration_mapping_ranges
**ranges
)
307 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
308 struct bt_field_class_enumeration_mapping
*mapping
;
310 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
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_fc
->mappings
->len
);
314 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_SIGNED_ENUMERATION
,
316 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
317 *name
= mapping
->label
->str
;
318 *ranges
= (void *) mapping
;
322 uint64_t get_enumeration_field_class_mapping_range_count(
323 struct bt_field_class_enumeration_mapping
*mapping
)
325 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
326 return (uint64_t) mapping
->ranges
->len
;
329 uint64_t bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count(
330 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
)
332 return get_enumeration_field_class_mapping_range_count((void *) ranges
);
335 uint64_t bt_field_class_signed_enumeration_mapping_ranges_get_range_count(
336 struct bt_field_class_signed_enumeration_mapping_ranges
*ranges
)
338 return get_enumeration_field_class_mapping_range_count((void *) ranges
);
342 void get_enumeration_field_class_mapping_range_at_index(
343 struct bt_field_class_enumeration_mapping
*mapping
,
344 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
346 struct bt_field_class_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_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping
, index
);
353 *lower
= range
->lower
.u
;
354 *upper
= range
->upper
.u
;
357 void bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index(
358 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
,
359 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
361 get_enumeration_field_class_mapping_range_at_index((void *) ranges
,
362 index
, lower
, upper
);
365 void bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index(
366 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
,
367 uint64_t index
, int64_t *lower
, int64_t *upper
)
369 get_enumeration_field_class_mapping_range_at_index((void *) ranges
,
370 index
, (uint64_t *) lower
, (uint64_t *) upper
);
375 int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value(
376 struct bt_field_class
*fc
, uint64_t value
,
377 bt_field_class_enumeration_mapping_label_array
*label_array
,
380 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
383 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
384 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
385 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
386 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_UNSIGNED_ENUMERATION
,
388 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
390 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
392 struct bt_field_class_enumeration_mapping
*mapping
=
393 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
395 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
396 struct bt_field_class_enumeration_mapping_range
*range
=
397 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
400 if (value
>= range
->lower
.u
&&
401 value
<= range
->upper
.u
) {
402 g_ptr_array_add(enum_fc
->label_buf
,
403 mapping
->label
->str
);
409 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
410 *count
= (uint64_t) enum_fc
->label_buf
->len
;
414 int bt_field_class_signed_enumeration_get_mapping_labels_by_value(
415 struct bt_field_class
*fc
, int64_t value
,
416 bt_field_class_enumeration_mapping_label_array
*label_array
,
419 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
422 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
423 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
424 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
425 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_SIGNED_ENUMERATION
,
427 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
429 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
431 struct bt_field_class_enumeration_mapping
*mapping
=
432 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
434 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
435 struct bt_field_class_enumeration_mapping_range
*range
=
436 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
439 if (value
>= range
->lower
.i
&&
440 value
<= range
->upper
.i
) {
441 g_ptr_array_add(enum_fc
->label_buf
,
442 mapping
->label
->str
);
448 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
449 *count
= (uint64_t) enum_fc
->label_buf
->len
;
454 int add_mapping_to_enumeration_field_class(struct bt_field_class
*fc
,
455 const char *label
, uint64_t lower
, uint64_t upper
)
459 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
460 struct bt_field_class_enumeration_mapping
*mapping
= NULL
;
461 struct bt_field_class_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_fc
->mappings
->len
; i
++) {
468 struct bt_field_class_enumeration_mapping
*mapping_candidate
=
469 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, 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_fc
->mappings
, enum_fc
->mappings
->len
+ 1);
480 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
,
481 enum_fc
->mappings
->len
- 1);
482 mapping
->ranges
= g_array_new(FALSE
, TRUE
,
483 sizeof(struct bt_field_class_enumeration_mapping_range
));
484 if (!mapping
->ranges
) {
485 finalize_enumeration_field_class_mapping(mapping
);
486 g_array_set_size(enum_fc
->mappings
,
487 enum_fc
->mappings
->len
- 1);
492 mapping
->label
= g_string_new(label
);
493 if (!mapping
->label
) {
494 finalize_enumeration_field_class_mapping(mapping
);
495 g_array_set_size(enum_fc
->mappings
,
496 enum_fc
->mappings
->len
- 1);
504 g_array_set_size(mapping
->ranges
, mapping
->ranges
->len
+ 1);
505 range
= BT_FIELD_CLASS_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 classe: "
510 "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64
", "
511 "upper-unsigned=%" PRIu64
, fc
, label
, lower
, upper
);
517 int bt_field_class_unsigned_enumeration_map_range(
518 struct bt_field_class
*fc
, const char *label
,
519 uint64_t range_lower
, uint64_t range_upper
)
521 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
523 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
524 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_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_fc
->common
.range
,
532 "Range's lower bound is outside the enumeration field classe's value range: "
533 "%![fc-]+F, lower=%" PRIu64
, fc
, range_lower
);
534 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc
->common
.range
,
536 "Range's upper bound is outside the enumeration field classe's value range: "
537 "%![fc-]+F, upper=%" PRIu64
, fc
, range_upper
);
538 return add_mapping_to_enumeration_field_class(fc
, label
, range_lower
,
542 int bt_field_class_signed_enumeration_map_range(
543 struct bt_field_class
*fc
, const char *label
,
544 int64_t range_lower
, int64_t range_upper
)
546 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
548 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
549 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_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_fc
->common
.range
,
557 "Range's lower bound is outside the enumeration field classe's value range: "
558 "%![fc-]+F, lower=%" PRId64
, fc
, range_lower
);
559 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc
->common
.range
,
561 "Range's upper bound is outside the enumeration field classe's value range: "
562 "%![fc-]+F, upper=%" PRId64
, fc
, range_upper
);
563 return add_mapping_to_enumeration_field_class(fc
, label
, range_lower
,
568 void destroy_real_field_class(struct bt_object
*obj
)
571 BT_LIB_LOGD("Destroying real field classe object: %!+F", obj
);
575 struct bt_field_class
*bt_field_class_real_create(void)
577 struct bt_field_class_real
*real_fc
= NULL
;
579 BT_LOGD_STR("Creating default real field classe object.");
580 real_fc
= g_new0(struct bt_field_class_real
, 1);
582 BT_LOGE_STR("Failed to allocate one real field classe.");
586 init_field_class((void *) real_fc
, BT_FIELD_CLASS_ID_REAL
,
587 destroy_real_field_class
);
588 BT_LIB_LOGD("Created real field classe object: %!+F", real_fc
);
595 return (void *) real_fc
;
598 bt_bool
bt_field_class_real_is_single_precision(struct bt_field_class
*fc
)
600 struct bt_field_class_real
*real_fc
= (void *) fc
;
602 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
603 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_REAL
, "Field class");
604 return real_fc
->is_single_precision
;
607 int bt_field_class_real_set_is_single_precision(struct bt_field_class
*fc
,
608 bt_bool is_single_precision
)
610 struct bt_field_class_real
*real_fc
= (void *) fc
;
612 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
613 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_REAL
, "Field class");
614 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
615 real_fc
->is_single_precision
= (bool) is_single_precision
;
616 BT_LIB_LOGV("Set real field classe's \"is single precision\" property: "
622 int init_named_field_classes_container(
623 struct bt_field_class_named_field_class_container
*fc
,
624 enum bt_field_class_id id
, bt_object_release_func release_func
)
628 init_field_class((void *) fc
, id
, release_func
);
629 fc
->named_fcs
= g_array_new(FALSE
, TRUE
,
630 sizeof(struct bt_named_field_class
));
631 if (!fc
->named_fcs
) {
632 BT_LOGE_STR("Failed to allocate a GArray.");
637 fc
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
638 if (!fc
->name_to_index
) {
639 BT_LOGE_STR("Failed to allocate a GHashTable.");
649 void finalize_named_field_class(struct bt_named_field_class
*named_fc
)
652 BT_LIB_LOGD("Finalizing named field classe: "
653 "addr=%p, name=\"%s\", %![fc-]+F",
654 named_fc
, named_fc
->name
? named_fc
->name
->str
: NULL
,
657 if (named_fc
->name
) {
658 g_string_free(named_fc
->name
, TRUE
);
661 BT_LOGD_STR("Putting named field classe's field classe.");
662 bt_put(named_fc
->fc
);
666 void finalize_named_field_classes_container(
667 struct bt_field_class_named_field_class_container
*fc
)
674 for (i
= 0; i
< fc
->named_fcs
->len
; i
++) {
675 finalize_named_field_class(
676 &g_array_index(fc
->named_fcs
,
677 struct bt_named_field_class
, i
));
680 g_array_free(fc
->named_fcs
, TRUE
);
683 if (fc
->name_to_index
) {
684 g_hash_table_destroy(fc
->name_to_index
);
689 void destroy_structure_field_class(struct bt_object
*obj
)
692 BT_LIB_LOGD("Destroying string field classe object: %!+F", obj
);
693 finalize_named_field_classes_container((void *) obj
);
697 struct bt_field_class
*bt_field_class_structure_create(void)
700 struct bt_field_class_structure
*struct_fc
= NULL
;
702 BT_LOGD_STR("Creating default structure field classe object.");
703 struct_fc
= g_new0(struct bt_field_class_structure
, 1);
705 BT_LOGE_STR("Failed to allocate one structure field classe.");
709 ret
= init_named_field_classes_container((void *) struct_fc
,
710 BT_FIELD_CLASS_ID_STRUCTURE
, destroy_structure_field_class
);
715 BT_LIB_LOGD("Created structure field classe object: %!+F", struct_fc
);
722 return (void *) struct_fc
;
726 int append_named_field_class_to_container_field_class(
727 struct bt_field_class_named_field_class_container
*container_fc
,
728 const char *name
, struct bt_field_class
*fc
)
731 struct bt_named_field_class
*named_fc
;
734 BT_ASSERT(container_fc
);
735 BT_ASSERT_PRE_FC_HOT(container_fc
, "Field class");
736 BT_ASSERT_PRE_NON_NULL(name
, "Name");
737 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
738 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc
->name_to_index
,
740 "Duplicate member/option name in structure/variant field classe: "
741 "%![container-fc-]+F, name=\"%s\"", container_fc
, name
);
742 name_str
= g_string_new(name
);
744 BT_LOGE_STR("Failed to allocate a GString.");
749 g_array_set_size(container_fc
->named_fcs
,
750 container_fc
->named_fcs
->len
+ 1);
751 named_fc
= &g_array_index(container_fc
->named_fcs
,
752 struct bt_named_field_class
, container_fc
->named_fcs
->len
- 1);
753 named_fc
->name
= name_str
;
754 named_fc
->fc
= bt_get(fc
);
755 g_hash_table_insert(container_fc
->name_to_index
, named_fc
->name
->str
,
756 GUINT_TO_POINTER(container_fc
->named_fcs
->len
- 1));
757 bt_field_class_freeze(fc
);
763 int bt_field_class_structure_append_member(struct bt_field_class
*fc
,
764 const char *name
, struct bt_field_class
*member_fc
)
766 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
767 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_STRUCTURE
, "Field class");
768 return append_named_field_class_to_container_field_class((void *) fc
,
772 uint64_t bt_field_class_structure_get_member_count(struct bt_field_class
*fc
)
774 struct bt_field_class_structure
*struct_fc
= (void *) fc
;
776 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
777 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_STRUCTURE
, "Field class");
778 return (uint64_t) struct_fc
->common
.named_fcs
->len
;
782 void borrow_named_field_class_from_container_field_class_at_index(
783 struct bt_field_class_named_field_class_container
*fc
,
784 uint64_t index
, const char **name
,
785 struct bt_field_class
**out_fc
)
787 struct bt_named_field_class
*named_fc
;
790 BT_ASSERT_PRE_NON_NULL(name
, "Name");
791 BT_ASSERT_PRE_NON_NULL(out_fc
, "Field class (output)");
792 BT_ASSERT_PRE_VALID_INDEX(index
, fc
->named_fcs
->len
);
793 named_fc
= BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc
, index
);
794 *name
= named_fc
->name
->str
;
795 *out_fc
= named_fc
->fc
;
798 void bt_field_class_structure_borrow_member_by_index(
799 struct bt_field_class
*fc
, uint64_t index
,
800 const char **name
, struct bt_field_class
**out_fc
)
802 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
803 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_STRUCTURE
, "Field class");
804 borrow_named_field_class_from_container_field_class_at_index((void *) fc
,
805 index
, name
, out_fc
);
809 struct bt_field_class
*borrow_field_class_from_container_field_class_by_name(
810 struct bt_field_class_named_field_class_container
*fc
,
813 struct bt_field_class
*ret_fc
= NULL
;
814 struct bt_named_field_class
*named_fc
;
819 BT_ASSERT_PRE_NON_NULL(name
, "Name");
820 if (!g_hash_table_lookup_extended(fc
->name_to_index
, name
, &orig_key
,
825 named_fc
= BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc
,
826 GPOINTER_TO_UINT(value
));
827 ret_fc
= named_fc
->fc
;
833 struct bt_field_class
*bt_field_class_structure_borrow_member_field_class_by_name(
834 struct bt_field_class
*fc
, const char *name
)
836 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
837 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_STRUCTURE
, "Field class");
838 return borrow_field_class_from_container_field_class_by_name((void *) fc
,
843 void destroy_variant_field_class(struct bt_object
*obj
)
845 struct bt_field_class_variant
*fc
= (void *) obj
;
848 BT_LIB_LOGD("Destroying variant field classe object: %!+F", fc
);
849 finalize_named_field_classes_container((void *) fc
);
850 BT_LOGD_STR("Putting selector field path.");
851 bt_put(fc
->selector_field_path
);
855 struct bt_field_class
*bt_field_class_variant_create(void)
858 struct bt_field_class_variant
*var_fc
= NULL
;
860 BT_LOGD_STR("Creating default variant field classe object.");
861 var_fc
= g_new0(struct bt_field_class_variant
, 1);
863 BT_LOGE_STR("Failed to allocate one variant field classe.");
867 ret
= init_named_field_classes_container((void *) var_fc
,
868 BT_FIELD_CLASS_ID_VARIANT
, destroy_variant_field_class
);
873 BT_LIB_LOGD("Created variant field classe object: %!+F", var_fc
);
880 return (void *) var_fc
;
883 int bt_field_class_variant_set_selector_field_class(
884 struct bt_field_class
*fc
, struct bt_field_class
*selector_fc
)
886 struct bt_field_class_variant
*var_fc
= (void *) fc
;
888 BT_ASSERT_PRE_NON_NULL(fc
, "Variant field classe");
889 BT_ASSERT_PRE_NON_NULL(selector_fc
, "Selector field classe");
890 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_VARIANT
, "Field class");
891 BT_ASSERT_PRE_FC_IS_ENUM(selector_fc
, "Selector field classe");
892 BT_ASSERT_PRE_FC_HOT(fc
, "Variant field classe");
893 var_fc
->selector_fc
= selector_fc
;
894 bt_field_class_freeze(selector_fc
);
898 int bt_field_class_variant_append_option(struct bt_field_class
*fc
,
899 const char *name
, struct bt_field_class
*option_fc
)
901 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
902 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_VARIANT
, "Field class");
903 return append_named_field_class_to_container_field_class((void *) fc
,
907 struct bt_field_class
*bt_field_class_variant_borrow_option_field_class_by_name(
908 struct bt_field_class
*fc
, const char *name
)
910 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
911 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_VARIANT
, "Field class");
912 return borrow_field_class_from_container_field_class_by_name((void *) fc
,
916 uint64_t bt_field_class_variant_get_option_count(struct bt_field_class
*fc
)
918 struct bt_field_class_variant
*var_fc
= (void *) fc
;
920 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
921 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_VARIANT
, "Field class");
922 return (uint64_t) var_fc
->common
.named_fcs
->len
;
925 void bt_field_class_variant_borrow_option_by_index(
926 struct bt_field_class
*fc
, uint64_t index
,
927 const char **name
, struct bt_field_class
**out_fc
)
929 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
930 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_VARIANT
, "Field class");
931 borrow_named_field_class_from_container_field_class_at_index((void *) fc
,
932 index
, name
, out_fc
);
935 struct bt_field_path
*bt_field_class_variant_borrow_selector_field_path(
936 struct bt_field_class
*fc
)
938 struct bt_field_class_variant
*var_fc
= (void *) fc
;
940 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
941 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_VARIANT
,
943 return var_fc
->selector_field_path
;
947 void init_array_field_class(struct bt_field_class_array
*fc
,
948 enum bt_field_class_id id
, bt_object_release_func release_func
,
949 struct bt_field_class
*element_fc
)
951 BT_ASSERT(element_fc
);
952 init_field_class((void *) fc
, id
, release_func
);
953 fc
->element_fc
= bt_get(element_fc
);
954 bt_field_class_freeze(element_fc
);
958 void finalize_array_field_class(struct bt_field_class_array
*array_fc
)
961 BT_LOGD_STR("Putting element field classe.");
962 bt_put(array_fc
->element_fc
);
966 void destroy_static_array_field_class(struct bt_object
*obj
)
969 BT_LIB_LOGD("Destroying static array field classe object: %!+F", obj
);
970 finalize_array_field_class((void *) obj
);
974 struct bt_field_class
*bt_field_class_static_array_create(
975 struct bt_field_class
*element_fc
, uint64_t length
)
977 struct bt_field_class_static_array
*array_fc
= NULL
;
979 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field classe");
980 BT_LOGD_STR("Creating default static array field classe object.");
981 array_fc
= g_new0(struct bt_field_class_static_array
, 1);
983 BT_LOGE_STR("Failed to allocate one static array field classe.");
987 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_ID_STATIC_ARRAY
,
988 destroy_static_array_field_class
, element_fc
);
989 array_fc
->length
= length
;
990 BT_LIB_LOGD("Created static array field classe object: %!+F", array_fc
);
997 return (void *) array_fc
;
1000 struct bt_field_class
*bt_field_class_array_borrow_element_field_class(
1001 struct bt_field_class
*fc
)
1003 struct bt_field_class_array
*array_fc
= (void *) fc
;
1005 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1006 BT_ASSERT_PRE_FC_IS_ARRAY(fc
, "Field class");
1007 return array_fc
->element_fc
;
1010 uint64_t bt_field_class_static_array_get_length(struct bt_field_class
*fc
)
1012 struct bt_field_class_static_array
*array_fc
= (void *) fc
;
1014 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1015 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_STATIC_ARRAY
,
1017 return (uint64_t) array_fc
->length
;
1021 void destroy_dynamic_array_field_class(struct bt_object
*obj
)
1023 struct bt_field_class_dynamic_array
*fc
= (void *) obj
;
1026 BT_LIB_LOGD("Destroying dynamic array field classe object: %!+F", fc
);
1027 finalize_array_field_class((void *) fc
);
1028 BT_LOGD_STR("Putting length field path.");
1029 bt_put(fc
->length_field_path
);
1033 struct bt_field_class
*bt_field_class_dynamic_array_create(
1034 struct bt_field_class
*element_fc
)
1036 struct bt_field_class_dynamic_array
*array_fc
= NULL
;
1038 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field classe");
1039 BT_LOGD_STR("Creating default dynamic array field classe object.");
1040 array_fc
= g_new0(struct bt_field_class_dynamic_array
, 1);
1042 BT_LOGE_STR("Failed to allocate one dynamic array field classe.");
1046 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_ID_DYNAMIC_ARRAY
,
1047 destroy_dynamic_array_field_class
, element_fc
);
1048 BT_LIB_LOGD("Created dynamic array field classe object: %!+F", array_fc
);
1055 return (void *) array_fc
;
1058 int bt_field_class_dynamic_array_set_length_field_class(struct bt_field_class
*fc
,
1059 struct bt_field_class
*length_fc
)
1061 struct bt_field_class_dynamic_array
*array_fc
= (void *) fc
;
1063 BT_ASSERT_PRE_NON_NULL(fc
, "Dynamic array field classe");
1064 BT_ASSERT_PRE_NON_NULL(length_fc
, "Length field classe");
1065 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_DYNAMIC_ARRAY
,
1067 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc
, "Length field classe");
1068 BT_ASSERT_PRE_FC_HOT(fc
, "Dynamic array field classe");
1069 array_fc
->length_fc
= length_fc
;
1070 bt_field_class_freeze(length_fc
);
1074 struct bt_field_path
*bt_field_class_dynamic_array_borrow_length_field_path(
1075 struct bt_field_class
*fc
)
1077 struct bt_field_class_dynamic_array
*seq_fc
= (void *) fc
;
1079 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1080 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_ID_DYNAMIC_ARRAY
,
1082 return seq_fc
->length_field_path
;
1086 void destroy_string_field_class(struct bt_object
*obj
)
1089 BT_LIB_LOGD("Destroying string field classe object: %!+F", obj
);
1093 struct bt_field_class
*bt_field_class_string_create(void)
1095 struct bt_field_class_string
*string_fc
= NULL
;
1097 BT_LOGD_STR("Creating default string field classe object.");
1098 string_fc
= g_new0(struct bt_field_class_string
, 1);
1100 BT_LOGE_STR("Failed to allocate one string field classe.");
1104 init_field_class((void *) string_fc
, BT_FIELD_CLASS_ID_STRING
,
1105 destroy_string_field_class
);
1106 BT_LIB_LOGD("Created string field classe object: %!+F", string_fc
);
1113 return (void *) string_fc
;
1117 void _bt_field_class_freeze(struct bt_field_class
*fc
)
1120 * Element/member/option field classes are frozen when added to
1128 void _bt_field_class_make_part_of_trace(struct bt_field_class
*fc
)
1131 BT_ASSERT_PRE(!fc
->part_of_trace
,
1132 "Field class is already part of a trace: %!+F", fc
);
1133 fc
->part_of_trace
= true;
1136 case BT_FIELD_CLASS_ID_STRUCTURE
:
1137 case BT_FIELD_CLASS_ID_VARIANT
:
1139 struct bt_field_class_named_field_class_container
*container_fc
=
1143 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1144 struct bt_named_field_class
*named_fc
=
1145 BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
1148 bt_field_class_make_part_of_trace(named_fc
->fc
);
1153 case BT_FIELD_CLASS_ID_STATIC_ARRAY
:
1154 case BT_FIELD_CLASS_ID_DYNAMIC_ARRAY
:
1156 struct bt_field_class_array
*array_fc
= (void *) fc
;
1158 bt_field_class_make_part_of_trace(array_fc
->element_fc
);