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_type
bt_field_class_get_type(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_type type
,
59 bt_object_release_func release_func
)
62 BT_ASSERT(bt_field_class_has_known_type(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
,
70 enum bt_field_class_type type
,
71 bt_object_release_func release_func
)
73 init_field_class((void *) fc
, type
, release_func
);
75 fc
->base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
79 void destroy_integer_field_class(struct bt_object
*obj
)
82 BT_LIB_LOGD("Destroying integer field classe object: %!+F", obj
);
87 struct bt_field_class
*create_integer_field_class(enum bt_field_class_type type
)
89 struct bt_field_class_integer
*int_fc
= NULL
;
91 BT_LOGD("Creating default integer field classe object: type=%s",
92 bt_common_field_class_type_string(type
));
93 int_fc
= g_new0(struct bt_field_class_integer
, 1);
95 BT_LOGE_STR("Failed to allocate one integer field classe.");
99 init_integer_field_class(int_fc
, type
, destroy_integer_field_class
);
100 BT_LIB_LOGD("Created integer field classe object: %!+F", int_fc
);
107 return (void *) int_fc
;
110 struct bt_field_class
*bt_field_class_unsigned_integer_create(void)
112 return create_integer_field_class(BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
);
115 struct bt_field_class
*bt_field_class_signed_integer_create(void)
117 return create_integer_field_class(BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
);
120 uint64_t bt_field_class_integer_get_field_value_range(
121 struct bt_field_class
*fc
)
123 struct bt_field_class_integer
*int_fc
= (void *) fc
;
125 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
126 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
127 return int_fc
->range
;
132 bool size_is_valid_for_enumeration_field_class(struct bt_field_class
*fc
,
139 int bt_field_class_integer_set_field_value_range(
140 struct bt_field_class
*fc
, uint64_t size
)
142 struct bt_field_class_integer
*int_fc
= (void *) fc
;
144 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
145 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
146 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
147 BT_ASSERT_PRE(size
<= 64,
148 "Unsupported size for integer field classe's field value range "
149 "(maximum is 64): size=%" PRIu64
, size
);
151 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
152 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
||
153 size_is_valid_for_enumeration_field_class(fc
, size
),
154 "Invalid field value range for enumeration field classe: "
155 "at least one of the current mapping ranges contains values "
156 "which are outside this range: %!+F, size=%" PRIu64
, fc
, size
);
157 int_fc
->range
= size
;
158 BT_LIB_LOGV("Set integer field classe's field value range: %!+F", fc
);
162 enum bt_field_class_integer_preferred_display_base
163 bt_field_class_integer_get_preferred_display_base(struct bt_field_class
*fc
)
165 struct bt_field_class_integer
*int_fc
= (void *) fc
;
167 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
168 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
172 int bt_field_class_integer_set_preferred_display_base(struct bt_field_class
*fc
,
173 enum bt_field_class_integer_preferred_display_base base
)
175 struct bt_field_class_integer
*int_fc
= (void *) fc
;
177 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
178 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
179 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
181 BT_LIB_LOGV("Set integer field classe's preferred display base: %!+F", fc
);
186 void finalize_enumeration_field_class_mapping(
187 struct bt_field_class_enumeration_mapping
*mapping
)
191 if (mapping
->label
) {
192 g_string_free(mapping
->label
, TRUE
);
195 if (mapping
->ranges
) {
196 g_array_free(mapping
->ranges
, TRUE
);
201 void destroy_enumeration_field_class(struct bt_object
*obj
)
203 struct bt_field_class_enumeration
*fc
= (void *) obj
;
206 BT_LIB_LOGD("Destroying enumeration field classe object: %!+F", fc
);
211 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
212 finalize_enumeration_field_class_mapping(
213 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
));
216 g_array_free(fc
->mappings
, TRUE
);
220 g_ptr_array_free(fc
->label_buf
, TRUE
);
227 struct bt_field_class
*create_enumeration_field_class(enum bt_field_class_type type
)
229 struct bt_field_class_enumeration
*enum_fc
= NULL
;
231 BT_LOGD("Creating default enumeration field classe object: type=%s",
232 bt_common_field_class_type_string(type
));
233 enum_fc
= g_new0(struct bt_field_class_enumeration
, 1);
235 BT_LOGE_STR("Failed to allocate one enumeration field classe.");
239 init_integer_field_class((void *) enum_fc
, type
,
240 destroy_enumeration_field_class
);
241 enum_fc
->mappings
= g_array_new(FALSE
, TRUE
,
242 sizeof(struct bt_field_class_enumeration_mapping
));
243 if (!enum_fc
->mappings
) {
244 BT_LOGE_STR("Failed to allocate a GArray.");
248 enum_fc
->label_buf
= g_ptr_array_new();
249 if (!enum_fc
->label_buf
) {
250 BT_LOGE_STR("Failed to allocate a GArray.");
254 BT_LIB_LOGD("Created enumeration field classe object: %!+F", enum_fc
);
261 return (void *) enum_fc
;
264 struct bt_field_class
*bt_field_class_unsigned_enumeration_create(void)
266 return create_enumeration_field_class(
267 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
);
270 struct bt_field_class
*bt_field_class_signed_enumeration_create(void)
272 return create_enumeration_field_class(
273 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
);
276 uint64_t bt_field_class_enumeration_get_mapping_count(struct bt_field_class
*fc
)
278 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
280 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
281 BT_ASSERT_PRE_FC_IS_ENUM(fc
, "Field class");
282 return (uint64_t) enum_fc
->mappings
->len
;
285 void bt_field_class_unsigned_enumeration_borrow_mapping_by_index(
286 struct bt_field_class
*fc
, uint64_t index
,
288 struct bt_field_class_unsigned_enumeration_mapping_ranges
**ranges
)
290 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
291 struct bt_field_class_enumeration_mapping
*mapping
;
293 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
294 BT_ASSERT_PRE_NON_NULL(name
, "Name (output)");
295 BT_ASSERT_PRE_NON_NULL(ranges
, "Ranges (output)");
296 BT_ASSERT_PRE_VALID_INDEX(index
, enum_fc
->mappings
->len
);
297 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
299 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
300 *name
= mapping
->label
->str
;
301 *ranges
= (void *) mapping
;
304 void bt_field_class_signed_enumeration_borrow_mapping_by_index(
305 struct bt_field_class
*fc
, uint64_t index
,
307 struct bt_field_class_signed_enumeration_mapping_ranges
**ranges
)
309 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
310 struct bt_field_class_enumeration_mapping
*mapping
;
312 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
313 BT_ASSERT_PRE_NON_NULL(name
, "Name (output)");
314 BT_ASSERT_PRE_NON_NULL(ranges
, "Ranges (output)");
315 BT_ASSERT_PRE_VALID_INDEX(index
, enum_fc
->mappings
->len
);
316 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
318 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
319 *name
= mapping
->label
->str
;
320 *ranges
= (void *) mapping
;
324 uint64_t get_enumeration_field_class_mapping_range_count(
325 struct bt_field_class_enumeration_mapping
*mapping
)
327 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
328 return (uint64_t) mapping
->ranges
->len
;
331 uint64_t bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count(
332 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
)
334 return get_enumeration_field_class_mapping_range_count((void *) ranges
);
337 uint64_t bt_field_class_signed_enumeration_mapping_ranges_get_range_count(
338 struct bt_field_class_signed_enumeration_mapping_ranges
*ranges
)
340 return get_enumeration_field_class_mapping_range_count((void *) ranges
);
344 void get_enumeration_field_class_mapping_range_at_index(
345 struct bt_field_class_enumeration_mapping
*mapping
,
346 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
348 struct bt_field_class_enumeration_mapping_range
*range
;
350 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
351 BT_ASSERT_PRE_NON_NULL(lower
, "Range's lower (output)");
352 BT_ASSERT_PRE_NON_NULL(upper
, "Range's upper (output)");
353 BT_ASSERT_PRE_VALID_INDEX(index
, mapping
->ranges
->len
);
354 range
= BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping
, index
);
355 *lower
= range
->lower
.u
;
356 *upper
= range
->upper
.u
;
359 void bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index(
360 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
,
361 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
363 get_enumeration_field_class_mapping_range_at_index((void *) ranges
,
364 index
, lower
, upper
);
367 void bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index(
368 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
,
369 uint64_t index
, int64_t *lower
, int64_t *upper
)
371 get_enumeration_field_class_mapping_range_at_index((void *) ranges
,
372 index
, (uint64_t *) lower
, (uint64_t *) upper
);
377 int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value(
378 struct bt_field_class
*fc
, uint64_t value
,
379 bt_field_class_enumeration_mapping_label_array
*label_array
,
382 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
385 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
386 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
387 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
388 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
390 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
392 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
394 struct bt_field_class_enumeration_mapping
*mapping
=
395 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
397 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
398 struct bt_field_class_enumeration_mapping_range
*range
=
399 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
402 if (value
>= range
->lower
.u
&&
403 value
<= range
->upper
.u
) {
404 g_ptr_array_add(enum_fc
->label_buf
,
405 mapping
->label
->str
);
411 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
412 *count
= (uint64_t) enum_fc
->label_buf
->len
;
416 int bt_field_class_signed_enumeration_get_mapping_labels_by_value(
417 struct bt_field_class
*fc
, int64_t value
,
418 bt_field_class_enumeration_mapping_label_array
*label_array
,
421 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
424 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
425 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
426 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
427 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
429 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
431 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
433 struct bt_field_class_enumeration_mapping
*mapping
=
434 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
436 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
437 struct bt_field_class_enumeration_mapping_range
*range
=
438 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
441 if (value
>= range
->lower
.i
&&
442 value
<= range
->upper
.i
) {
443 g_ptr_array_add(enum_fc
->label_buf
,
444 mapping
->label
->str
);
450 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
451 *count
= (uint64_t) enum_fc
->label_buf
->len
;
456 int add_mapping_to_enumeration_field_class(struct bt_field_class
*fc
,
457 const char *label
, uint64_t lower
, uint64_t upper
)
461 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
462 struct bt_field_class_enumeration_mapping
*mapping
= NULL
;
463 struct bt_field_class_enumeration_mapping_range
*range
;
466 BT_ASSERT_PRE_NON_NULL(label
, "Label");
468 /* Find existing mapping identified by this label */
469 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
470 struct bt_field_class_enumeration_mapping
*mapping_candidate
=
471 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
473 if (strcmp(mapping_candidate
->label
->str
, label
) == 0) {
474 mapping
= mapping_candidate
;
480 /* Create new mapping for this label */
481 g_array_set_size(enum_fc
->mappings
, enum_fc
->mappings
->len
+ 1);
482 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
,
483 enum_fc
->mappings
->len
- 1);
484 mapping
->ranges
= g_array_new(FALSE
, TRUE
,
485 sizeof(struct bt_field_class_enumeration_mapping_range
));
486 if (!mapping
->ranges
) {
487 finalize_enumeration_field_class_mapping(mapping
);
488 g_array_set_size(enum_fc
->mappings
,
489 enum_fc
->mappings
->len
- 1);
494 mapping
->label
= g_string_new(label
);
495 if (!mapping
->label
) {
496 finalize_enumeration_field_class_mapping(mapping
);
497 g_array_set_size(enum_fc
->mappings
,
498 enum_fc
->mappings
->len
- 1);
506 g_array_set_size(mapping
->ranges
, mapping
->ranges
->len
+ 1);
507 range
= BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping
,
508 mapping
->ranges
->len
- 1);
509 range
->lower
.u
= lower
;
510 range
->upper
.u
= upper
;
511 BT_LIB_LOGV("Added mapping to enumeration field classe: "
512 "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64
", "
513 "upper-unsigned=%" PRIu64
, fc
, label
, lower
, upper
);
519 int bt_field_class_unsigned_enumeration_map_range(
520 struct bt_field_class
*fc
, const char *label
,
521 uint64_t range_lower
, uint64_t range_upper
)
523 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
525 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
526 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
528 BT_ASSERT_PRE(range_lower
<= range_upper
,
529 "Range's upper bound is less than lower bound: "
530 "upper=%" PRIu64
", lower=%" PRIu64
,
531 range_lower
, range_upper
);
532 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc
->common
.range
,
534 "Range's lower bound is outside the enumeration field classe's value range: "
535 "%![fc-]+F, lower=%" PRIu64
, fc
, range_lower
);
536 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc
->common
.range
,
538 "Range's upper bound is outside the enumeration field classe's value range: "
539 "%![fc-]+F, upper=%" PRIu64
, fc
, range_upper
);
540 return add_mapping_to_enumeration_field_class(fc
, label
, range_lower
,
544 int bt_field_class_signed_enumeration_map_range(
545 struct bt_field_class
*fc
, const char *label
,
546 int64_t range_lower
, int64_t range_upper
)
548 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
550 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
551 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
553 BT_ASSERT_PRE(range_lower
<= range_upper
,
554 "Range's upper bound is less than lower bound: "
555 "upper=%" PRId64
", lower=%" PRId64
,
556 range_lower
, range_upper
);
557 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc
->common
.range
,
559 "Range's lower bound is outside the enumeration field classe's value range: "
560 "%![fc-]+F, lower=%" PRId64
, fc
, range_lower
);
561 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc
->common
.range
,
563 "Range's upper bound is outside the enumeration field classe's value range: "
564 "%![fc-]+F, upper=%" PRId64
, fc
, range_upper
);
565 return add_mapping_to_enumeration_field_class(fc
, label
, range_lower
,
570 void destroy_real_field_class(struct bt_object
*obj
)
573 BT_LIB_LOGD("Destroying real field classe object: %!+F", obj
);
577 struct bt_field_class
*bt_field_class_real_create(void)
579 struct bt_field_class_real
*real_fc
= NULL
;
581 BT_LOGD_STR("Creating default real field classe object.");
582 real_fc
= g_new0(struct bt_field_class_real
, 1);
584 BT_LOGE_STR("Failed to allocate one real field classe.");
588 init_field_class((void *) real_fc
, BT_FIELD_CLASS_TYPE_REAL
,
589 destroy_real_field_class
);
590 BT_LIB_LOGD("Created real field classe object: %!+F", real_fc
);
597 return (void *) real_fc
;
600 bt_bool
bt_field_class_real_is_single_precision(struct bt_field_class
*fc
)
602 struct bt_field_class_real
*real_fc
= (void *) fc
;
604 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
605 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
606 return real_fc
->is_single_precision
;
609 int bt_field_class_real_set_is_single_precision(struct bt_field_class
*fc
,
610 bt_bool is_single_precision
)
612 struct bt_field_class_real
*real_fc
= (void *) fc
;
614 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
615 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
616 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
617 real_fc
->is_single_precision
= (bool) is_single_precision
;
618 BT_LIB_LOGV("Set real field classe's \"is single precision\" property: "
624 int init_named_field_classes_container(
625 struct bt_field_class_named_field_class_container
*fc
,
626 enum bt_field_class_type type
, bt_object_release_func release_func
)
630 init_field_class((void *) fc
, type
, release_func
);
631 fc
->named_fcs
= g_array_new(FALSE
, TRUE
,
632 sizeof(struct bt_named_field_class
));
633 if (!fc
->named_fcs
) {
634 BT_LOGE_STR("Failed to allocate a GArray.");
639 fc
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
640 if (!fc
->name_to_index
) {
641 BT_LOGE_STR("Failed to allocate a GHashTable.");
651 void finalize_named_field_class(struct bt_named_field_class
*named_fc
)
654 BT_LIB_LOGD("Finalizing named field classe: "
655 "addr=%p, name=\"%s\", %![fc-]+F",
656 named_fc
, named_fc
->name
? named_fc
->name
->str
: NULL
,
659 if (named_fc
->name
) {
660 g_string_free(named_fc
->name
, TRUE
);
663 BT_LOGD_STR("Putting named field classe's field classe.");
664 bt_put(named_fc
->fc
);
668 void finalize_named_field_classes_container(
669 struct bt_field_class_named_field_class_container
*fc
)
676 for (i
= 0; i
< fc
->named_fcs
->len
; i
++) {
677 finalize_named_field_class(
678 &g_array_index(fc
->named_fcs
,
679 struct bt_named_field_class
, i
));
682 g_array_free(fc
->named_fcs
, TRUE
);
685 if (fc
->name_to_index
) {
686 g_hash_table_destroy(fc
->name_to_index
);
691 void destroy_structure_field_class(struct bt_object
*obj
)
694 BT_LIB_LOGD("Destroying string field classe object: %!+F", obj
);
695 finalize_named_field_classes_container((void *) obj
);
699 struct bt_field_class
*bt_field_class_structure_create(void)
702 struct bt_field_class_structure
*struct_fc
= NULL
;
704 BT_LOGD_STR("Creating default structure field classe object.");
705 struct_fc
= g_new0(struct bt_field_class_structure
, 1);
707 BT_LOGE_STR("Failed to allocate one structure field classe.");
711 ret
= init_named_field_classes_container((void *) struct_fc
,
712 BT_FIELD_CLASS_TYPE_STRUCTURE
, destroy_structure_field_class
);
717 BT_LIB_LOGD("Created structure field classe object: %!+F", struct_fc
);
724 return (void *) struct_fc
;
728 int append_named_field_class_to_container_field_class(
729 struct bt_field_class_named_field_class_container
*container_fc
,
730 const char *name
, struct bt_field_class
*fc
)
733 struct bt_named_field_class
*named_fc
;
736 BT_ASSERT(container_fc
);
737 BT_ASSERT_PRE_FC_HOT(container_fc
, "Field class");
738 BT_ASSERT_PRE_NON_NULL(name
, "Name");
739 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
740 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc
->name_to_index
,
742 "Duplicate member/option name in structure/variant field classe: "
743 "%![container-fc-]+F, name=\"%s\"", container_fc
, name
);
744 name_str
= g_string_new(name
);
746 BT_LOGE_STR("Failed to allocate a GString.");
751 g_array_set_size(container_fc
->named_fcs
,
752 container_fc
->named_fcs
->len
+ 1);
753 named_fc
= &g_array_index(container_fc
->named_fcs
,
754 struct bt_named_field_class
, container_fc
->named_fcs
->len
- 1);
755 named_fc
->name
= name_str
;
756 named_fc
->fc
= bt_get(fc
);
757 g_hash_table_insert(container_fc
->name_to_index
, named_fc
->name
->str
,
758 GUINT_TO_POINTER(container_fc
->named_fcs
->len
- 1));
759 bt_field_class_freeze(fc
);
765 int bt_field_class_structure_append_member(struct bt_field_class
*fc
,
766 const char *name
, struct bt_field_class
*member_fc
)
768 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
769 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
770 return append_named_field_class_to_container_field_class((void *) fc
,
774 uint64_t bt_field_class_structure_get_member_count(struct bt_field_class
*fc
)
776 struct bt_field_class_structure
*struct_fc
= (void *) fc
;
778 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
779 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
780 return (uint64_t) struct_fc
->common
.named_fcs
->len
;
784 void borrow_named_field_class_from_container_field_class_at_index(
785 struct bt_field_class_named_field_class_container
*fc
,
786 uint64_t index
, const char **name
,
787 struct bt_field_class
**out_fc
)
789 struct bt_named_field_class
*named_fc
;
792 BT_ASSERT_PRE_NON_NULL(name
, "Name");
793 BT_ASSERT_PRE_NON_NULL(out_fc
, "Field class (output)");
794 BT_ASSERT_PRE_VALID_INDEX(index
, fc
->named_fcs
->len
);
795 named_fc
= BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc
, index
);
796 *name
= named_fc
->name
->str
;
797 *out_fc
= named_fc
->fc
;
800 void bt_field_class_structure_borrow_member_by_index(
801 struct bt_field_class
*fc
, uint64_t index
,
802 const char **name
, struct bt_field_class
**out_fc
)
804 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
805 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
806 borrow_named_field_class_from_container_field_class_at_index((void *) fc
,
807 index
, name
, out_fc
);
811 struct bt_field_class
*borrow_field_class_from_container_field_class_by_name(
812 struct bt_field_class_named_field_class_container
*fc
,
815 struct bt_field_class
*ret_fc
= NULL
;
816 struct bt_named_field_class
*named_fc
;
821 BT_ASSERT_PRE_NON_NULL(name
, "Name");
822 if (!g_hash_table_lookup_extended(fc
->name_to_index
, name
, &orig_key
,
827 named_fc
= BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc
,
828 GPOINTER_TO_UINT(value
));
829 ret_fc
= named_fc
->fc
;
835 struct bt_field_class
*bt_field_class_structure_borrow_member_field_class_by_name(
836 struct bt_field_class
*fc
, const char *name
)
838 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
839 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
840 return borrow_field_class_from_container_field_class_by_name((void *) fc
,
845 void destroy_variant_field_class(struct bt_object
*obj
)
847 struct bt_field_class_variant
*fc
= (void *) obj
;
850 BT_LIB_LOGD("Destroying variant field classe object: %!+F", fc
);
851 finalize_named_field_classes_container((void *) fc
);
852 BT_LOGD_STR("Putting selector field path.");
853 bt_put(fc
->selector_field_path
);
857 struct bt_field_class
*bt_field_class_variant_create(void)
860 struct bt_field_class_variant
*var_fc
= NULL
;
862 BT_LOGD_STR("Creating default variant field classe object.");
863 var_fc
= g_new0(struct bt_field_class_variant
, 1);
865 BT_LOGE_STR("Failed to allocate one variant field classe.");
869 ret
= init_named_field_classes_container((void *) var_fc
,
870 BT_FIELD_CLASS_TYPE_VARIANT
, destroy_variant_field_class
);
875 BT_LIB_LOGD("Created variant field classe object: %!+F", var_fc
);
882 return (void *) var_fc
;
885 int bt_field_class_variant_set_selector_field_class(
886 struct bt_field_class
*fc
, struct bt_field_class
*selector_fc
)
888 struct bt_field_class_variant
*var_fc
= (void *) fc
;
890 BT_ASSERT_PRE_NON_NULL(fc
, "Variant field classe");
891 BT_ASSERT_PRE_NON_NULL(selector_fc
, "Selector field classe");
892 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
893 BT_ASSERT_PRE_FC_IS_ENUM(selector_fc
, "Selector field classe");
894 BT_ASSERT_PRE_FC_HOT(fc
, "Variant field classe");
895 var_fc
->selector_fc
= selector_fc
;
896 bt_field_class_freeze(selector_fc
);
900 int bt_field_class_variant_append_option(struct bt_field_class
*fc
,
901 const char *name
, struct bt_field_class
*option_fc
)
903 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
904 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
905 return append_named_field_class_to_container_field_class((void *) fc
,
909 struct bt_field_class
*bt_field_class_variant_borrow_option_field_class_by_name(
910 struct bt_field_class
*fc
, const char *name
)
912 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
913 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
914 return borrow_field_class_from_container_field_class_by_name((void *) fc
,
918 uint64_t bt_field_class_variant_get_option_count(struct bt_field_class
*fc
)
920 struct bt_field_class_variant
*var_fc
= (void *) fc
;
922 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
923 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
924 return (uint64_t) var_fc
->common
.named_fcs
->len
;
927 void bt_field_class_variant_borrow_option_by_index(
928 struct bt_field_class
*fc
, uint64_t index
,
929 const char **name
, struct bt_field_class
**out_fc
)
931 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
932 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
933 borrow_named_field_class_from_container_field_class_at_index((void *) fc
,
934 index
, name
, out_fc
);
937 struct bt_field_path
*bt_field_class_variant_borrow_selector_field_path(
938 struct bt_field_class
*fc
)
940 struct bt_field_class_variant
*var_fc
= (void *) fc
;
942 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
943 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
,
945 return var_fc
->selector_field_path
;
949 void init_array_field_class(struct bt_field_class_array
*fc
,
950 enum bt_field_class_type type
, bt_object_release_func release_func
,
951 struct bt_field_class
*element_fc
)
953 BT_ASSERT(element_fc
);
954 init_field_class((void *) fc
, type
, release_func
);
955 fc
->element_fc
= bt_get(element_fc
);
956 bt_field_class_freeze(element_fc
);
960 void finalize_array_field_class(struct bt_field_class_array
*array_fc
)
963 BT_LOGD_STR("Putting element field classe.");
964 bt_put(array_fc
->element_fc
);
968 void destroy_static_array_field_class(struct bt_object
*obj
)
971 BT_LIB_LOGD("Destroying static array field classe object: %!+F", obj
);
972 finalize_array_field_class((void *) obj
);
976 struct bt_field_class
*bt_field_class_static_array_create(
977 struct bt_field_class
*element_fc
, uint64_t length
)
979 struct bt_field_class_static_array
*array_fc
= NULL
;
981 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field classe");
982 BT_LOGD_STR("Creating default static array field classe object.");
983 array_fc
= g_new0(struct bt_field_class_static_array
, 1);
985 BT_LOGE_STR("Failed to allocate one static array field classe.");
989 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
990 destroy_static_array_field_class
, element_fc
);
991 array_fc
->length
= length
;
992 BT_LIB_LOGD("Created static array field classe object: %!+F", array_fc
);
999 return (void *) array_fc
;
1002 struct bt_field_class
*bt_field_class_array_borrow_element_field_class(
1003 struct bt_field_class
*fc
)
1005 struct bt_field_class_array
*array_fc
= (void *) fc
;
1007 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1008 BT_ASSERT_PRE_FC_IS_ARRAY(fc
, "Field class");
1009 return array_fc
->element_fc
;
1012 uint64_t bt_field_class_static_array_get_length(struct bt_field_class
*fc
)
1014 struct bt_field_class_static_array
*array_fc
= (void *) fc
;
1016 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1017 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1019 return (uint64_t) array_fc
->length
;
1023 void destroy_dynamic_array_field_class(struct bt_object
*obj
)
1025 struct bt_field_class_dynamic_array
*fc
= (void *) obj
;
1028 BT_LIB_LOGD("Destroying dynamic array field classe object: %!+F", fc
);
1029 finalize_array_field_class((void *) fc
);
1030 BT_LOGD_STR("Putting length field path.");
1031 bt_put(fc
->length_field_path
);
1035 struct bt_field_class
*bt_field_class_dynamic_array_create(
1036 struct bt_field_class
*element_fc
)
1038 struct bt_field_class_dynamic_array
*array_fc
= NULL
;
1040 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field classe");
1041 BT_LOGD_STR("Creating default dynamic array field classe object.");
1042 array_fc
= g_new0(struct bt_field_class_dynamic_array
, 1);
1044 BT_LOGE_STR("Failed to allocate one dynamic array field classe.");
1048 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1049 destroy_dynamic_array_field_class
, element_fc
);
1050 BT_LIB_LOGD("Created dynamic array field classe object: %!+F", array_fc
);
1057 return (void *) array_fc
;
1060 int bt_field_class_dynamic_array_set_length_field_class(struct bt_field_class
*fc
,
1061 struct bt_field_class
*length_fc
)
1063 struct bt_field_class_dynamic_array
*array_fc
= (void *) fc
;
1065 BT_ASSERT_PRE_NON_NULL(fc
, "Dynamic array field classe");
1066 BT_ASSERT_PRE_NON_NULL(length_fc
, "Length field classe");
1067 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1069 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc
, "Length field classe");
1070 BT_ASSERT_PRE_FC_HOT(fc
, "Dynamic array field classe");
1071 array_fc
->length_fc
= length_fc
;
1072 bt_field_class_freeze(length_fc
);
1076 struct bt_field_path
*bt_field_class_dynamic_array_borrow_length_field_path(
1077 struct bt_field_class
*fc
)
1079 struct bt_field_class_dynamic_array
*seq_fc
= (void *) fc
;
1081 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1082 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1084 return seq_fc
->length_field_path
;
1088 void destroy_string_field_class(struct bt_object
*obj
)
1091 BT_LIB_LOGD("Destroying string field classe object: %!+F", obj
);
1095 struct bt_field_class
*bt_field_class_string_create(void)
1097 struct bt_field_class_string
*string_fc
= NULL
;
1099 BT_LOGD_STR("Creating default string field classe object.");
1100 string_fc
= g_new0(struct bt_field_class_string
, 1);
1102 BT_LOGE_STR("Failed to allocate one string field classe.");
1106 init_field_class((void *) string_fc
, BT_FIELD_CLASS_TYPE_STRING
,
1107 destroy_string_field_class
);
1108 BT_LIB_LOGD("Created string field classe object: %!+F", string_fc
);
1115 return (void *) string_fc
;
1119 void _bt_field_class_freeze(struct bt_field_class
*fc
)
1122 * Element/member/option field classes are frozen when added to
1130 void _bt_field_class_make_part_of_trace(struct bt_field_class
*fc
)
1133 BT_ASSERT_PRE(!fc
->part_of_trace
,
1134 "Field class is already part of a trace: %!+F", fc
);
1135 fc
->part_of_trace
= true;
1138 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1139 case BT_FIELD_CLASS_TYPE_VARIANT
:
1141 struct bt_field_class_named_field_class_container
*container_fc
=
1145 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1146 struct bt_named_field_class
*named_fc
=
1147 BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
1150 bt_field_class_make_part_of_trace(named_fc
->fc
);
1155 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY
:
1156 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
:
1158 struct bt_field_class_array
*array_fc
= (void *) fc
;
1160 bt_field_class_make_part_of_trace(array_fc
->element_fc
);