2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #define BT_LOG_TAG "FIELD-CLASSES"
26 #include <babeltrace/lib-logging-internal.h>
28 #include <babeltrace/assert-pre-internal.h>
29 #include <babeltrace/trace-ir/private-field-classes.h>
30 #include <babeltrace/trace-ir/field-classes-internal.h>
31 #include <babeltrace/trace-ir/field-path-internal.h>
32 #include <babeltrace/trace-ir/fields-internal.h>
33 #include <babeltrace/trace-ir/private-fields.h>
34 #include <babeltrace/trace-ir/fields.h>
35 #include <babeltrace/trace-ir/utils-internal.h>
36 #include <babeltrace/object.h>
37 #include <babeltrace/trace-ir/clock-class.h>
38 #include <babeltrace/trace-ir/clock-class-internal.h>
39 #include <babeltrace/object-internal.h>
40 #include <babeltrace/object.h>
41 #include <babeltrace/compiler-internal.h>
42 #include <babeltrace/endian-internal.h>
43 #include <babeltrace/assert-internal.h>
44 #include <babeltrace/compat/glib-internal.h>
49 enum bt_field_class_type
bt_field_class_get_type(struct bt_field_class
*fc
)
51 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
56 void init_field_class(struct bt_field_class
*fc
, enum bt_field_class_type type
,
57 bt_object_release_func release_func
)
60 BT_ASSERT(bt_field_class_has_known_type(fc
));
61 BT_ASSERT(release_func
);
62 bt_object_init_shared(&fc
->base
, release_func
);
67 void init_integer_field_class(struct bt_field_class_integer
*fc
,
68 enum bt_field_class_type type
,
69 bt_object_release_func release_func
)
71 init_field_class((void *) fc
, type
, release_func
);
73 fc
->base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
77 void destroy_integer_field_class(struct bt_object
*obj
)
80 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj
);
85 struct bt_field_class
*create_integer_field_class(enum bt_field_class_type type
)
87 struct bt_field_class_integer
*int_fc
= NULL
;
89 BT_LOGD("Creating default integer field class object: type=%s",
90 bt_common_field_class_type_string(type
));
91 int_fc
= g_new0(struct bt_field_class_integer
, 1);
93 BT_LOGE_STR("Failed to allocate one integer field class.");
97 init_integer_field_class(int_fc
, type
, destroy_integer_field_class
);
98 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc
);
102 BT_OBJECT_PUT_REF_AND_RESET(int_fc
);
105 return (void *) int_fc
;
108 struct bt_private_field_class
*
109 bt_private_field_class_unsigned_integer_create(void)
111 return (void *) create_integer_field_class(
112 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
);
115 struct bt_private_field_class
*bt_private_field_class_signed_integer_create(void)
117 return (void *) create_integer_field_class(
118 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
);
121 uint64_t bt_field_class_integer_get_field_value_range(
122 struct bt_field_class
*fc
)
124 struct bt_field_class_integer
*int_fc
= (void *) fc
;
126 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
127 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
128 return int_fc
->range
;
133 bool size_is_valid_for_enumeration_field_class(struct bt_field_class
*fc
,
140 int bt_private_field_class_integer_set_field_value_range(
141 struct bt_private_field_class
*priv_fc
, uint64_t size
)
143 struct bt_field_class
*fc
= (void *) priv_fc
;
144 struct bt_field_class_integer
*int_fc
= (void *) fc
;
146 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
147 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
148 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
149 BT_ASSERT_PRE(size
<= 64,
150 "Unsupported size for integer field class's field value range "
151 "(maximum is 64): size=%" PRIu64
, size
);
153 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
154 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
||
155 size_is_valid_for_enumeration_field_class(fc
, size
),
156 "Invalid field value range for enumeration field class: "
157 "at least one of the current mapping ranges contains values "
158 "which are outside this range: %!+F, size=%" PRIu64
, fc
, size
);
159 int_fc
->range
= size
;
160 BT_LIB_LOGV("Set integer field class's field value range: %!+F", fc
);
164 enum bt_field_class_integer_preferred_display_base
165 bt_field_class_integer_get_preferred_display_base(struct bt_field_class
*fc
)
167 struct bt_field_class_integer
*int_fc
= (void *) fc
;
169 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
170 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
174 int bt_private_field_class_integer_set_preferred_display_base(
175 struct bt_private_field_class
*priv_fc
,
176 enum bt_field_class_integer_preferred_display_base base
)
178 struct bt_field_class
*fc
= (void *) priv_fc
;
179 struct bt_field_class_integer
*int_fc
= (void *) fc
;
181 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
182 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
183 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
185 BT_LIB_LOGV("Set integer field class's preferred display base: %!+F", fc
);
190 void finalize_enumeration_field_class_mapping(
191 struct bt_field_class_enumeration_mapping
*mapping
)
195 if (mapping
->label
) {
196 g_string_free(mapping
->label
, TRUE
);
199 if (mapping
->ranges
) {
200 g_array_free(mapping
->ranges
, TRUE
);
205 void destroy_enumeration_field_class(struct bt_object
*obj
)
207 struct bt_field_class_enumeration
*fc
= (void *) obj
;
210 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc
);
215 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
216 finalize_enumeration_field_class_mapping(
217 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
));
220 g_array_free(fc
->mappings
, TRUE
);
224 g_ptr_array_free(fc
->label_buf
, TRUE
);
231 struct bt_field_class
*create_enumeration_field_class(enum bt_field_class_type type
)
233 struct bt_field_class_enumeration
*enum_fc
= NULL
;
235 BT_LOGD("Creating default enumeration field class object: type=%s",
236 bt_common_field_class_type_string(type
));
237 enum_fc
= g_new0(struct bt_field_class_enumeration
, 1);
239 BT_LOGE_STR("Failed to allocate one enumeration field class.");
243 init_integer_field_class((void *) enum_fc
, type
,
244 destroy_enumeration_field_class
);
245 enum_fc
->mappings
= g_array_new(FALSE
, TRUE
,
246 sizeof(struct bt_field_class_enumeration_mapping
));
247 if (!enum_fc
->mappings
) {
248 BT_LOGE_STR("Failed to allocate a GArray.");
252 enum_fc
->label_buf
= g_ptr_array_new();
253 if (!enum_fc
->label_buf
) {
254 BT_LOGE_STR("Failed to allocate a GArray.");
258 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc
);
262 BT_OBJECT_PUT_REF_AND_RESET(enum_fc
);
265 return (void *) enum_fc
;
268 struct bt_private_field_class
*
269 bt_private_field_class_unsigned_enumeration_create(void)
271 return (void *) create_enumeration_field_class(
272 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
);
275 struct bt_private_field_class
*
276 bt_private_field_class_signed_enumeration_create(void)
278 return (void *) create_enumeration_field_class(
279 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
);
282 uint64_t bt_field_class_enumeration_get_mapping_count(struct bt_field_class
*fc
)
284 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
286 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
287 BT_ASSERT_PRE_FC_IS_ENUM(fc
, "Field class");
288 return (uint64_t) enum_fc
->mappings
->len
;
291 void bt_field_class_unsigned_enumeration_borrow_mapping_by_index(
292 struct bt_field_class
*fc
, uint64_t index
,
294 struct bt_field_class_unsigned_enumeration_mapping_ranges
**ranges
)
296 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
297 struct bt_field_class_enumeration_mapping
*mapping
;
299 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
300 BT_ASSERT_PRE_NON_NULL(name
, "Name (output)");
301 BT_ASSERT_PRE_NON_NULL(ranges
, "Ranges (output)");
302 BT_ASSERT_PRE_VALID_INDEX(index
, enum_fc
->mappings
->len
);
303 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
305 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
306 *name
= mapping
->label
->str
;
307 *ranges
= (void *) mapping
;
310 void bt_field_class_signed_enumeration_borrow_mapping_by_index(
311 struct bt_field_class
*fc
, uint64_t index
,
313 struct bt_field_class_signed_enumeration_mapping_ranges
**ranges
)
315 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
316 struct bt_field_class_enumeration_mapping
*mapping
;
318 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
319 BT_ASSERT_PRE_NON_NULL(name
, "Name (output)");
320 BT_ASSERT_PRE_NON_NULL(ranges
, "Ranges (output)");
321 BT_ASSERT_PRE_VALID_INDEX(index
, enum_fc
->mappings
->len
);
322 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
324 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
325 *name
= mapping
->label
->str
;
326 *ranges
= (void *) mapping
;
330 uint64_t get_enumeration_field_class_mapping_range_count(
331 struct bt_field_class_enumeration_mapping
*mapping
)
333 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
334 return (uint64_t) mapping
->ranges
->len
;
337 uint64_t bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count(
338 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
)
340 return get_enumeration_field_class_mapping_range_count((void *) ranges
);
343 uint64_t bt_field_class_signed_enumeration_mapping_ranges_get_range_count(
344 struct bt_field_class_signed_enumeration_mapping_ranges
*ranges
)
346 return get_enumeration_field_class_mapping_range_count((void *) ranges
);
350 void get_enumeration_field_class_mapping_range_at_index(
351 struct bt_field_class_enumeration_mapping
*mapping
,
352 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
354 struct bt_field_class_enumeration_mapping_range
*range
;
356 BT_ASSERT_PRE_NON_NULL(mapping
, "Ranges");
357 BT_ASSERT_PRE_NON_NULL(lower
, "Range's lower (output)");
358 BT_ASSERT_PRE_NON_NULL(upper
, "Range's upper (output)");
359 BT_ASSERT_PRE_VALID_INDEX(index
, mapping
->ranges
->len
);
360 range
= BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping
, index
);
361 *lower
= range
->lower
.u
;
362 *upper
= range
->upper
.u
;
365 void bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index(
366 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
,
367 uint64_t index
, uint64_t *lower
, uint64_t *upper
)
369 get_enumeration_field_class_mapping_range_at_index((void *) ranges
,
370 index
, lower
, upper
);
373 void bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index(
374 struct bt_field_class_unsigned_enumeration_mapping_ranges
*ranges
,
375 uint64_t index
, int64_t *lower
, int64_t *upper
)
377 get_enumeration_field_class_mapping_range_at_index((void *) ranges
,
378 index
, (uint64_t *) lower
, (uint64_t *) upper
);
383 int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value(
384 struct bt_field_class
*fc
, uint64_t value
,
385 bt_field_class_enumeration_mapping_label_array
*label_array
,
388 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
391 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
392 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
393 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
394 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
396 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
398 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
400 struct bt_field_class_enumeration_mapping
*mapping
=
401 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
403 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
404 struct bt_field_class_enumeration_mapping_range
*range
=
405 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
408 if (value
>= range
->lower
.u
&&
409 value
<= range
->upper
.u
) {
410 g_ptr_array_add(enum_fc
->label_buf
,
411 mapping
->label
->str
);
417 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
418 *count
= (uint64_t) enum_fc
->label_buf
->len
;
422 int bt_field_class_signed_enumeration_get_mapping_labels_by_value(
423 struct bt_field_class
*fc
, int64_t value
,
424 bt_field_class_enumeration_mapping_label_array
*label_array
,
427 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
430 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
431 BT_ASSERT_PRE_NON_NULL(label_array
, "Label array (output)");
432 BT_ASSERT_PRE_NON_NULL(count
, "Count (output)");
433 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
435 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
437 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
439 struct bt_field_class_enumeration_mapping
*mapping
=
440 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
442 for (j
= 0; j
< mapping
->ranges
->len
; j
++) {
443 struct bt_field_class_enumeration_mapping_range
*range
=
444 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
447 if (value
>= range
->lower
.i
&&
448 value
<= range
->upper
.i
) {
449 g_ptr_array_add(enum_fc
->label_buf
,
450 mapping
->label
->str
);
456 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
457 *count
= (uint64_t) enum_fc
->label_buf
->len
;
462 int add_mapping_to_enumeration_field_class(struct bt_field_class
*fc
,
463 const char *label
, uint64_t lower
, uint64_t upper
)
467 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
468 struct bt_field_class_enumeration_mapping
*mapping
= NULL
;
469 struct bt_field_class_enumeration_mapping_range
*range
;
472 BT_ASSERT_PRE_NON_NULL(label
, "Label");
474 /* Find existing mapping identified by this label */
475 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
476 struct bt_field_class_enumeration_mapping
*mapping_candidate
=
477 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
479 if (strcmp(mapping_candidate
->label
->str
, label
) == 0) {
480 mapping
= mapping_candidate
;
486 /* Create new mapping for this label */
487 g_array_set_size(enum_fc
->mappings
, enum_fc
->mappings
->len
+ 1);
488 mapping
= BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
,
489 enum_fc
->mappings
->len
- 1);
490 mapping
->ranges
= g_array_new(FALSE
, TRUE
,
491 sizeof(struct bt_field_class_enumeration_mapping_range
));
492 if (!mapping
->ranges
) {
493 finalize_enumeration_field_class_mapping(mapping
);
494 g_array_set_size(enum_fc
->mappings
,
495 enum_fc
->mappings
->len
- 1);
500 mapping
->label
= g_string_new(label
);
501 if (!mapping
->label
) {
502 finalize_enumeration_field_class_mapping(mapping
);
503 g_array_set_size(enum_fc
->mappings
,
504 enum_fc
->mappings
->len
- 1);
512 g_array_set_size(mapping
->ranges
, mapping
->ranges
->len
+ 1);
513 range
= BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping
,
514 mapping
->ranges
->len
- 1);
515 range
->lower
.u
= lower
;
516 range
->upper
.u
= upper
;
517 BT_LIB_LOGV("Added mapping to enumeration field class: "
518 "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64
", "
519 "upper-unsigned=%" PRIu64
, fc
, label
, lower
, upper
);
525 int bt_private_field_class_unsigned_enumeration_map_range(
526 struct bt_private_field_class
*priv_fc
, const char *label
,
527 uint64_t range_lower
, uint64_t range_upper
)
529 struct bt_field_class
*fc
= (void *) priv_fc
;
530 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
532 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
533 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
535 BT_ASSERT_PRE(range_lower
<= range_upper
,
536 "Range's upper bound is less than lower bound: "
537 "upper=%" PRIu64
", lower=%" PRIu64
,
538 range_lower
, range_upper
);
539 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc
->common
.range
,
541 "Range's lower bound is outside the enumeration field class's value range: "
542 "%![fc-]+F, lower=%" PRIu64
, fc
, range_lower
);
543 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc
->common
.range
,
545 "Range's upper bound is outside the enumeration field class's value range: "
546 "%![fc-]+F, upper=%" PRIu64
, fc
, range_upper
);
547 return add_mapping_to_enumeration_field_class(fc
, label
, range_lower
,
551 int bt_private_field_class_signed_enumeration_map_range(
552 struct bt_private_field_class
*priv_fc
, const char *label
,
553 int64_t range_lower
, int64_t range_upper
)
555 struct bt_field_class
*fc
= (void *) priv_fc
;
556 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
558 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
559 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
561 BT_ASSERT_PRE(range_lower
<= range_upper
,
562 "Range's upper bound is less than lower bound: "
563 "upper=%" PRId64
", lower=%" PRId64
,
564 range_lower
, range_upper
);
565 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc
->common
.range
,
567 "Range's lower bound is outside the enumeration field class's value range: "
568 "%![fc-]+F, lower=%" PRId64
, fc
, range_lower
);
569 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc
->common
.range
,
571 "Range's upper bound is outside the enumeration field class's value range: "
572 "%![fc-]+F, upper=%" PRId64
, fc
, range_upper
);
573 return add_mapping_to_enumeration_field_class(fc
, label
, range_lower
,
578 void destroy_real_field_class(struct bt_object
*obj
)
581 BT_LIB_LOGD("Destroying real field class object: %!+F", obj
);
585 struct bt_private_field_class
*bt_private_field_class_real_create(void)
587 struct bt_field_class_real
*real_fc
= NULL
;
589 BT_LOGD_STR("Creating default real field class object.");
590 real_fc
= g_new0(struct bt_field_class_real
, 1);
592 BT_LOGE_STR("Failed to allocate one real field class.");
596 init_field_class((void *) real_fc
, BT_FIELD_CLASS_TYPE_REAL
,
597 destroy_real_field_class
);
598 BT_LIB_LOGD("Created real field class object: %!+F", real_fc
);
602 BT_OBJECT_PUT_REF_AND_RESET(real_fc
);
605 return (void *) real_fc
;
608 bt_bool
bt_field_class_real_is_single_precision(struct bt_field_class
*fc
)
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_TYPE_REAL
, "Field class");
614 return real_fc
->is_single_precision
;
617 int bt_private_field_class_real_set_is_single_precision(
618 struct bt_private_field_class
*priv_fc
,
619 bt_bool is_single_precision
)
621 struct bt_field_class
*fc
= (void *) priv_fc
;
622 struct bt_field_class_real
*real_fc
= (void *) fc
;
624 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
625 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
626 BT_ASSERT_PRE_FC_HOT(fc
, "Field class");
627 real_fc
->is_single_precision
= (bool) is_single_precision
;
628 BT_LIB_LOGV("Set real field class's \"is single precision\" property: "
634 int init_named_field_classes_container(
635 struct bt_field_class_named_field_class_container
*fc
,
636 enum bt_field_class_type type
, bt_object_release_func release_func
)
640 init_field_class((void *) fc
, type
, release_func
);
641 fc
->named_fcs
= g_array_new(FALSE
, TRUE
,
642 sizeof(struct bt_named_field_class
));
643 if (!fc
->named_fcs
) {
644 BT_LOGE_STR("Failed to allocate a GArray.");
649 fc
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
650 if (!fc
->name_to_index
) {
651 BT_LOGE_STR("Failed to allocate a GHashTable.");
661 void finalize_named_field_class(struct bt_named_field_class
*named_fc
)
664 BT_LIB_LOGD("Finalizing named field class: "
665 "addr=%p, name=\"%s\", %![fc-]+F",
666 named_fc
, named_fc
->name
? named_fc
->name
->str
: NULL
,
669 if (named_fc
->name
) {
670 g_string_free(named_fc
->name
, TRUE
);
673 BT_LOGD_STR("Putting named field class's field class.");
674 bt_object_put_ref(named_fc
->fc
);
678 void finalize_named_field_classes_container(
679 struct bt_field_class_named_field_class_container
*fc
)
686 for (i
= 0; i
< fc
->named_fcs
->len
; i
++) {
687 finalize_named_field_class(
688 &g_array_index(fc
->named_fcs
,
689 struct bt_named_field_class
, i
));
692 g_array_free(fc
->named_fcs
, TRUE
);
695 if (fc
->name_to_index
) {
696 g_hash_table_destroy(fc
->name_to_index
);
701 void destroy_structure_field_class(struct bt_object
*obj
)
704 BT_LIB_LOGD("Destroying string field class object: %!+F", obj
);
705 finalize_named_field_classes_container((void *) obj
);
709 struct bt_private_field_class
*bt_private_field_class_structure_create(void)
712 struct bt_field_class_structure
*struct_fc
= NULL
;
714 BT_LOGD_STR("Creating default structure field class object.");
715 struct_fc
= g_new0(struct bt_field_class_structure
, 1);
717 BT_LOGE_STR("Failed to allocate one structure field class.");
721 ret
= init_named_field_classes_container((void *) struct_fc
,
722 BT_FIELD_CLASS_TYPE_STRUCTURE
, destroy_structure_field_class
);
727 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc
);
731 BT_OBJECT_PUT_REF_AND_RESET(struct_fc
);
734 return (void *) struct_fc
;
738 int append_named_field_class_to_container_field_class(
739 struct bt_field_class_named_field_class_container
*container_fc
,
740 const char *name
, struct bt_field_class
*fc
)
743 struct bt_named_field_class
*named_fc
;
746 BT_ASSERT(container_fc
);
747 BT_ASSERT_PRE_FC_HOT(container_fc
, "Field class");
748 BT_ASSERT_PRE_NON_NULL(name
, "Name");
749 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
750 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc
->name_to_index
,
752 "Duplicate member/option name in structure/variant field class: "
753 "%![container-fc-]+F, name=\"%s\"", container_fc
, name
);
754 name_str
= g_string_new(name
);
756 BT_LOGE_STR("Failed to allocate a GString.");
761 g_array_set_size(container_fc
->named_fcs
,
762 container_fc
->named_fcs
->len
+ 1);
763 named_fc
= &g_array_index(container_fc
->named_fcs
,
764 struct bt_named_field_class
, container_fc
->named_fcs
->len
- 1);
765 named_fc
->name
= name_str
;
766 named_fc
->fc
= bt_object_get_ref(fc
);
767 g_hash_table_insert(container_fc
->name_to_index
, named_fc
->name
->str
,
768 GUINT_TO_POINTER(container_fc
->named_fcs
->len
- 1));
769 bt_field_class_freeze(fc
);
775 int bt_private_field_class_structure_append_member(
776 struct bt_private_field_class
*priv_fc
,
777 const char *name
, struct bt_private_field_class
*member_fc
)
779 struct bt_field_class
*fc
= (void *) priv_fc
;
781 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
782 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
783 return append_named_field_class_to_container_field_class((void *) fc
,
784 name
, (void *) member_fc
);
787 uint64_t bt_field_class_structure_get_member_count(struct bt_field_class
*fc
)
789 struct bt_field_class_structure
*struct_fc
= (void *) fc
;
791 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
792 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
793 return (uint64_t) struct_fc
->common
.named_fcs
->len
;
797 void borrow_named_field_class_from_container_field_class_at_index(
798 struct bt_field_class_named_field_class_container
*fc
,
799 uint64_t index
, const char **name
,
800 struct bt_field_class
**out_fc
)
802 struct bt_named_field_class
*named_fc
;
805 BT_ASSERT_PRE_NON_NULL(name
, "Name");
806 BT_ASSERT_PRE_NON_NULL(out_fc
, "Field class (output)");
807 BT_ASSERT_PRE_VALID_INDEX(index
, fc
->named_fcs
->len
);
808 named_fc
= BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc
, index
);
809 *name
= named_fc
->name
->str
;
810 *out_fc
= named_fc
->fc
;
813 void bt_field_class_structure_borrow_member_by_index(
814 struct bt_field_class
*fc
, uint64_t index
,
815 const char **name
, struct bt_field_class
**out_fc
)
817 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
818 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
819 borrow_named_field_class_from_container_field_class_at_index((void *) fc
,
820 index
, name
, out_fc
);
823 void bt_private_field_class_structure_borrow_member_by_index(
824 struct bt_private_field_class
*fc
, uint64_t index
,
825 const char **name
, struct bt_private_field_class
**out_fc
)
827 bt_field_class_structure_borrow_member_by_index((void *) fc
,
828 index
, name
, (void *) out_fc
);
832 struct bt_field_class
*borrow_field_class_from_container_field_class_by_name(
833 struct bt_field_class_named_field_class_container
*fc
,
836 struct bt_field_class
*ret_fc
= NULL
;
837 struct bt_named_field_class
*named_fc
;
842 BT_ASSERT_PRE_NON_NULL(name
, "Name");
843 if (!g_hash_table_lookup_extended(fc
->name_to_index
, name
, &orig_key
,
848 named_fc
= BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc
,
849 GPOINTER_TO_UINT(value
));
850 ret_fc
= named_fc
->fc
;
856 struct bt_field_class
*bt_field_class_structure_borrow_member_field_class_by_name(
857 struct bt_field_class
*fc
, const char *name
)
859 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
860 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
, "Field class");
861 return borrow_field_class_from_container_field_class_by_name((void *) fc
,
865 struct bt_private_field_class
*
866 bt_private_field_class_structure_borrow_member_field_class_by_name(
867 struct bt_private_field_class
*fc
, const char *name
)
869 return (void *) bt_field_class_structure_borrow_member_field_class_by_name(
874 void destroy_variant_field_class(struct bt_object
*obj
)
876 struct bt_field_class_variant
*fc
= (void *) obj
;
879 BT_LIB_LOGD("Destroying variant field class object: %!+F", fc
);
880 finalize_named_field_classes_container((void *) fc
);
881 BT_LOGD_STR("Putting selector field path.");
882 bt_object_put_ref(fc
->selector_field_path
);
886 struct bt_private_field_class
*bt_private_field_class_variant_create(void)
889 struct bt_field_class_variant
*var_fc
= NULL
;
891 BT_LOGD_STR("Creating default variant field class object.");
892 var_fc
= g_new0(struct bt_field_class_variant
, 1);
894 BT_LOGE_STR("Failed to allocate one variant field class.");
898 ret
= init_named_field_classes_container((void *) var_fc
,
899 BT_FIELD_CLASS_TYPE_VARIANT
, destroy_variant_field_class
);
904 BT_LIB_LOGD("Created variant field class object: %!+F", var_fc
);
908 BT_OBJECT_PUT_REF_AND_RESET(var_fc
);
911 return (void *) var_fc
;
914 int bt_private_field_class_variant_set_selector_field_class(
915 struct bt_private_field_class
*priv_fc
,
916 struct bt_private_field_class
*selector_fc
)
918 struct bt_field_class
*fc
= (void *) priv_fc
;
919 struct bt_field_class_variant
*var_fc
= (void *) fc
;
921 BT_ASSERT_PRE_NON_NULL(fc
, "Variant field class");
922 BT_ASSERT_PRE_NON_NULL(selector_fc
, "Selector field class");
923 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
924 BT_ASSERT_PRE_FC_IS_ENUM(selector_fc
, "Selector field class");
925 BT_ASSERT_PRE_FC_HOT(fc
, "Variant field class");
926 var_fc
->selector_fc
= (void *) selector_fc
;
927 bt_field_class_freeze((void *) selector_fc
);
931 int bt_private_field_class_variant_append_private_option(
932 struct bt_private_field_class
*priv_fc
,
933 const char *name
, struct bt_private_field_class
*option_fc
)
935 struct bt_field_class
*fc
= (void *) priv_fc
;
937 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
938 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
939 return append_named_field_class_to_container_field_class((void *) fc
,
940 name
, (void *) option_fc
);
943 struct bt_field_class
*bt_field_class_variant_borrow_option_field_class_by_name(
944 struct bt_field_class
*fc
, const char *name
)
946 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
947 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
948 return borrow_field_class_from_container_field_class_by_name((void *) fc
,
952 struct bt_private_field_class
*
953 bt_private_field_class_variant_borrow_option_field_class_by_name(
954 struct bt_private_field_class
*fc
, const char *name
)
956 return (void *) bt_field_class_variant_borrow_option_field_class_by_name(
960 uint64_t bt_field_class_variant_get_option_count(struct bt_field_class
*fc
)
962 struct bt_field_class_variant
*var_fc
= (void *) fc
;
964 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
965 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
966 return (uint64_t) var_fc
->common
.named_fcs
->len
;
969 void bt_field_class_variant_borrow_option_by_index(
970 struct bt_field_class
*fc
, uint64_t index
,
971 const char **name
, struct bt_field_class
**out_fc
)
973 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
974 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
, "Field class");
975 borrow_named_field_class_from_container_field_class_at_index((void *) fc
,
976 index
, name
, out_fc
);
979 void bt_private_field_class_variant_borrow_option_by_index(
980 struct bt_private_field_class
*fc
, uint64_t index
,
981 const char **name
, struct bt_private_field_class
**out_fc
)
983 bt_field_class_variant_borrow_option_by_index((void *) fc
,
984 index
, name
, (void *) out_fc
);
987 struct bt_field_path
*bt_field_class_variant_borrow_selector_field_path(
988 struct bt_field_class
*fc
)
990 struct bt_field_class_variant
*var_fc
= (void *) fc
;
992 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
993 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_VARIANT
,
995 return var_fc
->selector_field_path
;
999 void init_array_field_class(struct bt_field_class_array
*fc
,
1000 enum bt_field_class_type type
, bt_object_release_func release_func
,
1001 struct bt_field_class
*element_fc
)
1003 BT_ASSERT(element_fc
);
1004 init_field_class((void *) fc
, type
, release_func
);
1005 fc
->element_fc
= bt_object_get_ref(element_fc
);
1006 bt_field_class_freeze(element_fc
);
1010 void finalize_array_field_class(struct bt_field_class_array
*array_fc
)
1012 BT_ASSERT(array_fc
);
1013 BT_LOGD_STR("Putting element field class.");
1014 bt_object_put_ref(array_fc
->element_fc
);
1018 void destroy_static_array_field_class(struct bt_object
*obj
)
1021 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj
);
1022 finalize_array_field_class((void *) obj
);
1026 struct bt_private_field_class
*
1027 bt_private_field_class_static_array_create(
1028 struct bt_private_field_class
*priv_element_fc
,
1031 struct bt_field_class
*element_fc
= (void *) priv_element_fc
;
1032 struct bt_field_class_static_array
*array_fc
= NULL
;
1034 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1035 BT_LOGD_STR("Creating default static array field class object.");
1036 array_fc
= g_new0(struct bt_field_class_static_array
, 1);
1038 BT_LOGE_STR("Failed to allocate one static array field class.");
1042 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1043 destroy_static_array_field_class
, element_fc
);
1044 array_fc
->length
= length
;
1045 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc
);
1049 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1052 return (void *) array_fc
;
1055 struct bt_field_class
*bt_field_class_array_borrow_element_field_class(
1056 struct bt_field_class
*fc
)
1058 struct bt_field_class_array
*array_fc
= (void *) fc
;
1060 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1061 BT_ASSERT_PRE_FC_IS_ARRAY(fc
, "Field class");
1062 return array_fc
->element_fc
;
1065 struct bt_private_field_class
*
1066 bt_private_field_class_array_borrow_element_field_class(
1067 struct bt_private_field_class
*fc
)
1069 return (void *) bt_field_class_array_borrow_element_field_class(
1073 uint64_t bt_field_class_static_array_get_length(struct bt_field_class
*fc
)
1075 struct bt_field_class_static_array
*array_fc
= (void *) fc
;
1077 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1078 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1080 return (uint64_t) array_fc
->length
;
1084 void destroy_dynamic_array_field_class(struct bt_object
*obj
)
1086 struct bt_field_class_dynamic_array
*fc
= (void *) obj
;
1089 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc
);
1090 finalize_array_field_class((void *) fc
);
1091 BT_LOGD_STR("Putting length field path.");
1092 bt_object_put_ref(fc
->length_field_path
);
1096 struct bt_private_field_class
*bt_private_field_class_dynamic_array_create(
1097 struct bt_private_field_class
*priv_element_fc
)
1099 struct bt_field_class
*element_fc
= (void *) priv_element_fc
;
1100 struct bt_field_class_dynamic_array
*array_fc
= NULL
;
1102 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1103 BT_LOGD_STR("Creating default dynamic array field class object.");
1104 array_fc
= g_new0(struct bt_field_class_dynamic_array
, 1);
1106 BT_LOGE_STR("Failed to allocate one dynamic array field class.");
1110 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1111 destroy_dynamic_array_field_class
, element_fc
);
1112 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc
);
1116 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1119 return (void *) array_fc
;
1122 int bt_private_field_class_dynamic_array_set_length_field_class(
1123 struct bt_private_field_class
*priv_fc
,
1124 struct bt_private_field_class
*priv_length_fc
)
1126 struct bt_field_class
*fc
= (void *) priv_fc
;
1127 struct bt_field_class
*length_fc
= (void *) priv_length_fc
;
1128 struct bt_field_class_dynamic_array
*array_fc
= (void *) fc
;
1130 BT_ASSERT_PRE_NON_NULL(fc
, "Dynamic array field class");
1131 BT_ASSERT_PRE_NON_NULL(length_fc
, "Length field class");
1132 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1134 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc
, "Length field class");
1135 BT_ASSERT_PRE_FC_HOT(fc
, "Dynamic array field class");
1136 array_fc
->length_fc
= length_fc
;
1137 bt_field_class_freeze(length_fc
);
1141 struct bt_field_path
*bt_field_class_dynamic_array_borrow_length_field_path(
1142 struct bt_field_class
*fc
)
1144 struct bt_field_class_dynamic_array
*seq_fc
= (void *) fc
;
1146 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1147 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1149 return seq_fc
->length_field_path
;
1153 void destroy_string_field_class(struct bt_object
*obj
)
1156 BT_LIB_LOGD("Destroying string field class object: %!+F", obj
);
1160 struct bt_private_field_class
*bt_private_field_class_string_create(void)
1162 struct bt_field_class_string
*string_fc
= NULL
;
1164 BT_LOGD_STR("Creating default string field class object.");
1165 string_fc
= g_new0(struct bt_field_class_string
, 1);
1167 BT_LOGE_STR("Failed to allocate one string field class.");
1171 init_field_class((void *) string_fc
, BT_FIELD_CLASS_TYPE_STRING
,
1172 destroy_string_field_class
);
1173 BT_LIB_LOGD("Created string field class object: %!+F", string_fc
);
1177 BT_OBJECT_PUT_REF_AND_RESET(string_fc
);
1180 return (void *) string_fc
;
1184 void _bt_field_class_freeze(struct bt_field_class
*fc
)
1187 * Element/member/option field classes are frozen when added to
1195 void _bt_field_class_make_part_of_trace(struct bt_field_class
*fc
)
1198 BT_ASSERT_PRE(!fc
->part_of_trace
,
1199 "Field class is already part of a trace: %!+F", fc
);
1200 fc
->part_of_trace
= true;
1203 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1204 case BT_FIELD_CLASS_TYPE_VARIANT
:
1206 struct bt_field_class_named_field_class_container
*container_fc
=
1210 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1211 struct bt_named_field_class
*named_fc
=
1212 BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
1215 bt_field_class_make_part_of_trace(named_fc
->fc
);
1220 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY
:
1221 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
:
1223 struct bt_field_class_array
*array_fc
= (void *) fc
;
1225 bt_field_class_make_part_of_trace(array_fc
->element_fc
);