2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
3 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 #define BT_LOG_TAG "LIB/FIELD-CLASS"
25 #include "lib/logging.h"
27 #include "lib/assert-pre.h"
28 #include <babeltrace2/trace-ir/field-class.h>
29 #include <babeltrace2/trace-ir/field-class-const.h>
30 #include <babeltrace2/trace-ir/field-const.h>
31 #include <babeltrace2/trace-ir/field.h>
32 #include <babeltrace2/trace-ir/clock-class.h>
33 #include "lib/object.h"
34 #include "compat/compiler.h"
35 #include "compat/endian.h"
36 #include "common/assert.h"
37 #include "compat/glib.h"
42 #include "clock-class.h"
43 #include "field-class.h"
45 #include "field-path.h"
47 #include "lib/func-status.h"
48 #include "lib/integer-range-set.h"
50 enum bt_field_class_type
bt_field_class_get_type(
51 const struct bt_field_class
*fc
)
53 BT_ASSERT_PRE_DEV_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(release_func
);
63 bt_object_init_shared(&fc
->base
, release_func
);
68 void destroy_bool_field_class(struct bt_object
*obj
)
71 BT_LIB_LOGD("Destroying boolean field class object: %!+F", obj
);
75 struct bt_field_class
*bt_field_class_bool_create(
76 bt_trace_class
*trace_class
)
78 struct bt_field_class_bool
*bool_fc
= NULL
;
80 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
81 BT_LOGD("Creating default boolean field class object.");
82 bool_fc
= g_new0(struct bt_field_class_bool
, 1);
84 BT_LIB_LOGE_APPEND_CAUSE(
85 "Failed to allocate one boolean field class.");
89 init_field_class((void *) bool_fc
, BT_FIELD_CLASS_TYPE_BOOL
,
90 destroy_bool_field_class
);
91 BT_LIB_LOGD("Created boolean field class object: %!+F", bool_fc
);
95 BT_OBJECT_PUT_REF_AND_RESET(bool_fc
);
98 return (void *) bool_fc
;
102 void init_integer_field_class(struct bt_field_class_integer
*fc
,
103 enum bt_field_class_type type
,
104 bt_object_release_func release_func
)
106 init_field_class((void *) fc
, type
, release_func
);
108 fc
->base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
112 void destroy_integer_field_class(struct bt_object
*obj
)
115 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj
);
120 struct bt_field_class
*create_integer_field_class(bt_trace_class
*trace_class
,
121 enum bt_field_class_type type
)
123 struct bt_field_class_integer
*int_fc
= NULL
;
125 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
126 BT_LOGD("Creating default integer field class object: type=%s",
127 bt_common_field_class_type_string(type
));
128 int_fc
= g_new0(struct bt_field_class_integer
, 1);
130 BT_LIB_LOGE_APPEND_CAUSE(
131 "Failed to allocate one integer field class.");
135 init_integer_field_class(int_fc
, type
, destroy_integer_field_class
);
136 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc
);
140 BT_OBJECT_PUT_REF_AND_RESET(int_fc
);
143 return (void *) int_fc
;
146 struct bt_field_class
*bt_field_class_integer_unsigned_create(
147 bt_trace_class
*trace_class
)
149 return create_integer_field_class(trace_class
,
150 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
);
153 struct bt_field_class
*bt_field_class_integer_signed_create(
154 bt_trace_class
*trace_class
)
156 return create_integer_field_class(trace_class
,
157 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
);
160 uint64_t bt_field_class_integer_get_field_value_range(
161 const struct bt_field_class
*fc
)
163 const struct bt_field_class_integer
*int_fc
= (const void *) fc
;
165 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
166 BT_ASSERT_PRE_DEV_FC_IS_INT(fc
, "Field class");
167 return int_fc
->range
;
171 bool size_is_valid_for_enumeration_field_class(struct bt_field_class
*fc
,
178 void bt_field_class_integer_set_field_value_range(
179 struct bt_field_class
*fc
, uint64_t size
)
181 struct bt_field_class_integer
*int_fc
= (void *) fc
;
183 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
184 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
185 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
186 BT_ASSERT_PRE(size
<= 64,
187 "Unsupported size for integer field class's field value range "
188 "(maximum is 64): size=%" PRIu64
, size
);
190 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
191 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
||
192 size_is_valid_for_enumeration_field_class(fc
, size
),
193 "Invalid field value range for enumeration field class: "
194 "at least one of the current mapping ranges contains values "
195 "which are outside this range: %!+F, size=%" PRIu64
, fc
, size
);
196 int_fc
->range
= size
;
197 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc
);
200 enum bt_field_class_integer_preferred_display_base
201 bt_field_class_integer_get_preferred_display_base(const struct bt_field_class
*fc
)
203 const struct bt_field_class_integer
*int_fc
= (const void *) fc
;
205 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
206 BT_ASSERT_PRE_DEV_FC_IS_INT(fc
, "Field class");
210 void bt_field_class_integer_set_preferred_display_base(
211 struct bt_field_class
*fc
,
212 enum bt_field_class_integer_preferred_display_base base
)
214 struct bt_field_class_integer
*int_fc
= (void *) fc
;
216 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
217 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
218 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
220 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc
);
224 void finalize_enumeration_field_class_mapping(
225 struct bt_field_class_enumeration_mapping
*mapping
)
229 if (mapping
->label
) {
230 g_string_free(mapping
->label
, TRUE
);
231 mapping
->label
= NULL
;
234 BT_OBJECT_PUT_REF_AND_RESET(mapping
->range_set
);
238 void destroy_enumeration_field_class(struct bt_object
*obj
)
240 struct bt_field_class_enumeration
*fc
= (void *) obj
;
243 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc
);
248 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
249 finalize_enumeration_field_class_mapping(
250 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
));
253 g_array_free(fc
->mappings
, TRUE
);
258 g_ptr_array_free(fc
->label_buf
, TRUE
);
259 fc
->label_buf
= NULL
;
266 struct bt_field_class
*create_enumeration_field_class(
267 bt_trace_class
*trace_class
, enum bt_field_class_type type
)
269 struct bt_field_class_enumeration
*enum_fc
= NULL
;
271 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
272 BT_LOGD("Creating default enumeration field class object: type=%s",
273 bt_common_field_class_type_string(type
));
274 enum_fc
= g_new0(struct bt_field_class_enumeration
, 1);
276 BT_LIB_LOGE_APPEND_CAUSE(
277 "Failed to allocate one enumeration field class.");
281 init_integer_field_class((void *) enum_fc
, type
,
282 destroy_enumeration_field_class
);
283 enum_fc
->mappings
= g_array_new(FALSE
, TRUE
,
284 sizeof(struct bt_field_class_enumeration_mapping
));
285 if (!enum_fc
->mappings
) {
286 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
290 enum_fc
->label_buf
= g_ptr_array_new();
291 if (!enum_fc
->label_buf
) {
292 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
296 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc
);
300 BT_OBJECT_PUT_REF_AND_RESET(enum_fc
);
303 return (void *) enum_fc
;
306 struct bt_field_class
*bt_field_class_enumeration_unsigned_create(
307 bt_trace_class
*trace_class
)
309 return create_enumeration_field_class(trace_class
,
310 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
);
313 struct bt_field_class
*bt_field_class_enumeration_signed_create(
314 bt_trace_class
*trace_class
)
316 return create_enumeration_field_class(trace_class
,
317 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
);
320 uint64_t bt_field_class_enumeration_get_mapping_count(
321 const struct bt_field_class
*fc
)
323 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
325 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
326 BT_ASSERT_PRE_DEV_FC_IS_ENUM(fc
, "Field class");
327 return (uint64_t) enum_fc
->mappings
->len
;
330 const struct bt_field_class_enumeration_unsigned_mapping
*
331 bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
332 const struct bt_field_class
*fc
, uint64_t index
)
334 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
336 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
337 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, enum_fc
->mappings
->len
);
338 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
340 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
343 const struct bt_field_class_enumeration_signed_mapping
*
344 bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
345 const struct bt_field_class
*fc
, uint64_t index
)
347 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
349 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
350 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, enum_fc
->mappings
->len
);
351 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
353 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
357 const struct bt_field_class_enumeration_mapping
*
358 borrow_enumeration_field_class_mapping_by_label(
359 const struct bt_field_class_enumeration
*fc
, const char *label
)
361 struct bt_field_class_enumeration_mapping
*mapping
= NULL
;
365 BT_ASSERT_PRE_DEV_NON_NULL(label
, "Label");
367 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
368 struct bt_field_class_enumeration_mapping
*this_mapping
=
369 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
);
371 if (strcmp(this_mapping
->label
->str
, label
) == 0) {
372 mapping
= this_mapping
;
381 const struct bt_field_class_enumeration_signed_mapping
*
382 bt_field_class_enumeration_signed_borrow_mapping_by_label_const(
383 const struct bt_field_class
*fc
, const char *label
)
385 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
386 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
388 return (const void *) borrow_enumeration_field_class_mapping_by_label(
389 (const void *) fc
, label
);
392 const struct bt_field_class_enumeration_unsigned_mapping
*
393 bt_field_class_enumeration_unsigned_borrow_mapping_by_label_const(
394 const struct bt_field_class
*fc
, const char *label
)
396 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
397 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
398 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
, "Field class");
399 return (const void *) borrow_enumeration_field_class_mapping_by_label(
400 (const void *) fc
, label
);
403 const char *bt_field_class_enumeration_mapping_get_label(
404 const struct bt_field_class_enumeration_mapping
*mapping
)
406 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
407 return mapping
->label
->str
;
410 const struct bt_integer_range_set_unsigned
*
411 bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
412 const struct bt_field_class_enumeration_unsigned_mapping
*u_mapping
)
414 const struct bt_field_class_enumeration_mapping
*mapping
=
415 (const void *) u_mapping
;
417 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
418 return (const void *) mapping
->range_set
;
421 const struct bt_integer_range_set_signed
*
422 bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
423 const struct bt_field_class_enumeration_signed_mapping
*s_mapping
)
425 const struct bt_field_class_enumeration_mapping
*mapping
=
426 (const void *) s_mapping
;
428 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
429 return (const void *) mapping
->range_set
;
432 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
433 bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
434 const struct bt_field_class
*fc
, uint64_t value
,
435 bt_field_class_enumeration_mapping_label_array
*label_array
,
438 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
441 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
442 BT_ASSERT_PRE_DEV_NON_NULL(label_array
, "Label array (output)");
443 BT_ASSERT_PRE_DEV_NON_NULL(count
, "Count (output)");
444 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
446 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
448 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
450 const struct bt_field_class_enumeration_mapping
*mapping
=
451 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
453 for (j
= 0; j
< mapping
->range_set
->ranges
->len
; j
++) {
454 const struct bt_integer_range
*range
= (const void *)
455 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
456 mapping
->range_set
, j
);
458 if (value
>= range
->lower
.u
&&
459 value
<= range
->upper
.u
) {
460 g_ptr_array_add(enum_fc
->label_buf
,
461 mapping
->label
->str
);
467 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
468 *count
= (uint64_t) enum_fc
->label_buf
->len
;
469 return BT_FUNC_STATUS_OK
;
472 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
473 bt_field_class_enumeration_signed_get_mapping_labels_for_value(
474 const struct bt_field_class
*fc
, int64_t value
,
475 bt_field_class_enumeration_mapping_label_array
*label_array
,
478 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
481 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
482 BT_ASSERT_PRE_DEV_NON_NULL(label_array
, "Label array (output)");
483 BT_ASSERT_PRE_DEV_NON_NULL(count
, "Count (output)");
484 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
486 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
488 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
490 const struct bt_field_class_enumeration_mapping
*mapping
=
491 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
493 for (j
= 0; j
< mapping
->range_set
->ranges
->len
; j
++) {
494 const struct bt_integer_range
*range
= (const void *)
495 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
496 mapping
->range_set
, j
);
498 if (value
>= range
->lower
.i
&&
499 value
<= range
->upper
.i
) {
500 g_ptr_array_add(enum_fc
->label_buf
,
501 mapping
->label
->str
);
507 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
508 *count
= (uint64_t) enum_fc
->label_buf
->len
;
509 return BT_FUNC_STATUS_OK
;
513 bool enumeration_field_class_has_mapping_with_label(
514 const struct bt_field_class_enumeration
*enum_fc
,
523 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
524 struct bt_field_class_enumeration_mapping
*mapping_candidate
=
525 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
527 if (strcmp(mapping_candidate
->label
->str
, label
) == 0) {
538 enum bt_field_class_enumeration_add_mapping_status
539 add_mapping_to_enumeration_field_class(struct bt_field_class
*fc
,
540 const char *label
, const struct bt_integer_range_set
*range_set
)
542 enum bt_field_class_enumeration_add_mapping_status status
=
544 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
545 struct bt_field_class_enumeration_mapping mapping
= { 0 };
548 BT_ASSERT_PRE_NON_NULL(label
, "Label");
549 BT_ASSERT_PRE_NON_NULL(range_set
, "Integer range set");
550 BT_ASSERT_PRE(!enumeration_field_class_has_mapping_with_label(
552 "Duplicate mapping name in enumeration field class: "
553 "%![enum-fc-]+F, label=\"%s\"", fc
, label
);
554 mapping
.range_set
= range_set
;
555 bt_object_get_ref(mapping
.range_set
);
556 mapping
.label
= g_string_new(label
);
557 if (!mapping
.label
) {
558 finalize_enumeration_field_class_mapping(&mapping
);
559 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
563 g_array_append_val(enum_fc
->mappings
, mapping
);
564 BT_LIB_LOGD("Added mapping to enumeration field class: "
565 "%![fc-]+F, label=\"%s\"", fc
, label
);
571 enum bt_field_class_enumeration_add_mapping_status
572 bt_field_class_enumeration_unsigned_add_mapping(
573 struct bt_field_class
*fc
, const char *label
,
574 const struct bt_integer_range_set_unsigned
*range_set
)
576 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
577 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
579 return add_mapping_to_enumeration_field_class(fc
, label
,
580 (const void *) range_set
);
583 enum bt_field_class_enumeration_add_mapping_status
584 bt_field_class_enumeration_signed_add_mapping(
585 struct bt_field_class
*fc
, const char *label
,
586 const struct bt_integer_range_set_signed
*range_set
)
588 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
589 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
591 return add_mapping_to_enumeration_field_class(fc
, label
,
592 (const void *) range_set
);
596 void destroy_real_field_class(struct bt_object
*obj
)
599 BT_LIB_LOGD("Destroying real field class object: %!+F", obj
);
603 struct bt_field_class
*bt_field_class_real_create(bt_trace_class
*trace_class
)
605 struct bt_field_class_real
*real_fc
= NULL
;
607 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
608 BT_LOGD_STR("Creating default real field class object.");
609 real_fc
= g_new0(struct bt_field_class_real
, 1);
611 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
615 init_field_class((void *) real_fc
, BT_FIELD_CLASS_TYPE_REAL
,
616 destroy_real_field_class
);
617 BT_LIB_LOGD("Created real field class object: %!+F", real_fc
);
621 BT_OBJECT_PUT_REF_AND_RESET(real_fc
);
624 return (void *) real_fc
;
627 bt_bool
bt_field_class_real_is_single_precision(const struct bt_field_class
*fc
)
629 const struct bt_field_class_real
*real_fc
= (const void *) fc
;
631 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
632 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
633 return real_fc
->is_single_precision
;
636 void bt_field_class_real_set_is_single_precision(struct bt_field_class
*fc
,
637 bt_bool is_single_precision
)
639 struct bt_field_class_real
*real_fc
= (void *) fc
;
641 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
642 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
643 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
644 real_fc
->is_single_precision
= (bool) is_single_precision
;
645 BT_LIB_LOGD("Set real field class's \"is single precision\" property: "
650 int init_named_field_classes_container(
651 struct bt_field_class_named_field_class_container
*fc
,
652 enum bt_field_class_type type
,
653 bt_object_release_func fc_release_func
,
654 GDestroyNotify named_fc_destroy_func
)
658 init_field_class((void *) fc
, type
, fc_release_func
);
659 fc
->named_fcs
= g_ptr_array_new_with_free_func(named_fc_destroy_func
);
660 if (!fc
->named_fcs
) {
661 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
666 fc
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
667 if (!fc
->name_to_index
) {
668 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
678 void finalize_named_field_class(struct bt_named_field_class
*named_fc
)
681 BT_LIB_LOGD("Finalizing named field class: "
682 "addr=%p, name=\"%s\", %![fc-]+F",
683 named_fc
, named_fc
->name
? named_fc
->name
->str
: NULL
,
686 if (named_fc
->name
) {
687 g_string_free(named_fc
->name
, TRUE
);
688 named_fc
->name
= NULL
;
691 BT_LOGD_STR("Putting named field class's field class.");
692 BT_OBJECT_PUT_REF_AND_RESET(named_fc
->fc
);
696 void destroy_named_field_class(gpointer ptr
)
699 finalize_named_field_class(ptr
);
705 void destroy_variant_with_selector_option(gpointer ptr
)
707 struct bt_field_class_variant_with_selector_option
*opt
= ptr
;
710 finalize_named_field_class(&opt
->common
);
711 BT_OBJECT_PUT_REF_AND_RESET(opt
->range_set
);
717 void finalize_named_field_classes_container(
718 struct bt_field_class_named_field_class_container
*fc
)
723 g_ptr_array_free(fc
->named_fcs
, TRUE
);
724 fc
->named_fcs
= NULL
;
728 if (fc
->name_to_index
) {
729 g_hash_table_destroy(fc
->name_to_index
);
730 fc
->name_to_index
= NULL
;
735 void destroy_structure_field_class(struct bt_object
*obj
)
738 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj
);
739 finalize_named_field_classes_container((void *) obj
);
743 struct bt_field_class
*bt_field_class_structure_create(
744 bt_trace_class
*trace_class
)
747 struct bt_field_class_structure
*struct_fc
= NULL
;
749 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
750 BT_LOGD_STR("Creating default structure field class object.");
751 struct_fc
= g_new0(struct bt_field_class_structure
, 1);
753 BT_LIB_LOGE_APPEND_CAUSE(
754 "Failed to allocate one structure field class.");
758 ret
= init_named_field_classes_container((void *) struct_fc
,
759 BT_FIELD_CLASS_TYPE_STRUCTURE
, destroy_structure_field_class
,
760 destroy_named_field_class
);
762 /* init_named_field_classes_container() logs errors */
766 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc
);
770 BT_OBJECT_PUT_REF_AND_RESET(struct_fc
);
773 return (void *) struct_fc
;
777 int init_named_field_class(struct bt_named_field_class
*named_fc
,
778 const char *name
, struct bt_field_class
*fc
)
780 int status
= BT_FUNC_STATUS_OK
;
785 named_fc
->name
= g_string_new(name
);
786 if (!named_fc
->name
) {
787 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
788 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
793 bt_object_get_no_null_check(named_fc
->fc
);
794 bt_named_field_class_freeze(named_fc
);
801 struct bt_named_field_class
*create_named_field_class(const char *name
,
802 struct bt_field_class
*fc
)
804 struct bt_named_field_class
*named_fc
= g_new0(
805 struct bt_named_field_class
, 1);
808 BT_LIB_LOGE_APPEND_CAUSE(
809 "Failed to allocate a named field class.");
813 if (init_named_field_class(named_fc
, name
, fc
)) {
814 /* init_named_field_class() logs errors */
821 destroy_named_field_class(named_fc
);
829 struct bt_field_class_variant_with_selector_option
*
830 create_variant_with_selector_option(
831 const char *name
, struct bt_field_class
*fc
,
832 const struct bt_integer_range_set
*range_set
)
834 struct bt_field_class_variant_with_selector_option
*opt
= g_new0(
835 struct bt_field_class_variant_with_selector_option
, 1);
837 BT_ASSERT(range_set
);
840 BT_LIB_LOGE_APPEND_CAUSE(
841 "Failed to allocate a named field class.");
845 if (init_named_field_class(&opt
->common
, name
, fc
)) {
849 opt
->range_set
= range_set
;
850 bt_object_get_no_null_check(opt
->range_set
);
851 bt_integer_range_set_freeze(range_set
);
855 destroy_variant_with_selector_option(opt
);
863 int append_named_field_class_to_container_field_class(
864 struct bt_field_class_named_field_class_container
*container_fc
,
865 struct bt_named_field_class
*named_fc
)
867 BT_ASSERT(container_fc
);
869 BT_ASSERT_PRE_DEV_FC_HOT(container_fc
, "Field class");
870 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc
->name_to_index
,
871 named_fc
->name
->str
),
872 "Duplicate member/option name in structure/variant field class: "
873 "%![container-fc-]+F, name=\"%s\"", container_fc
,
874 named_fc
->name
->str
);
875 g_ptr_array_add(container_fc
->named_fcs
, named_fc
);
876 g_hash_table_insert(container_fc
->name_to_index
, named_fc
->name
->str
,
877 GUINT_TO_POINTER(container_fc
->named_fcs
->len
- 1));
878 return BT_FUNC_STATUS_OK
;
881 enum bt_field_class_structure_append_member_status
882 bt_field_class_structure_append_member(
883 struct bt_field_class
*fc
, const char *name
,
884 struct bt_field_class
*member_fc
)
886 enum bt_field_class_structure_append_member_status status
;
887 struct bt_named_field_class
*named_fc
= NULL
;
889 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
890 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
892 named_fc
= create_named_field_class(name
, member_fc
);
894 /* create_named_field_class() logs errors */
895 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
899 status
= append_named_field_class_to_container_field_class((void *) fc
,
901 if (status
== BT_FUNC_STATUS_OK
) {
902 /* Moved to the container */
910 uint64_t bt_field_class_structure_get_member_count(
911 const struct bt_field_class
*fc
)
913 struct bt_field_class_structure
*struct_fc
= (void *) fc
;
915 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
916 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
918 return (uint64_t) struct_fc
->common
.named_fcs
->len
;
922 struct bt_named_field_class
*
923 borrow_named_field_class_from_container_field_class_at_index(
924 struct bt_field_class_named_field_class_container
*fc
,
928 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, fc
->named_fcs
->len
);
929 return fc
->named_fcs
->pdata
[index
];
932 const struct bt_field_class_structure_member
*
933 bt_field_class_structure_borrow_member_by_index_const(
934 const struct bt_field_class
*fc
, uint64_t index
)
936 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
937 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
939 return (const void *)
940 borrow_named_field_class_from_container_field_class_at_index(
944 struct bt_field_class_structure_member
*
945 bt_field_class_structure_borrow_member_by_index(
946 struct bt_field_class
*fc
, uint64_t index
)
948 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
949 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
952 borrow_named_field_class_from_container_field_class_at_index(
957 struct bt_named_field_class
*
958 borrow_named_field_class_from_container_field_class_by_name(
959 struct bt_field_class_named_field_class_container
*fc
,
962 struct bt_named_field_class
*named_fc
= NULL
;
967 BT_ASSERT_PRE_DEV_NON_NULL(name
, "Name");
968 if (!g_hash_table_lookup_extended(fc
->name_to_index
, name
, &orig_key
,
973 named_fc
= fc
->named_fcs
->pdata
[GPOINTER_TO_UINT(value
)];
979 const struct bt_field_class_structure_member
*
980 bt_field_class_structure_borrow_member_by_name_const(
981 const struct bt_field_class
*fc
, const char *name
)
983 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
984 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
986 return (const void *)
987 borrow_named_field_class_from_container_field_class_by_name(
991 struct bt_field_class_structure_member
*
992 bt_field_class_structure_borrow_member_by_name(
993 struct bt_field_class
*fc
, const char *name
)
995 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
996 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
999 borrow_named_field_class_from_container_field_class_by_name(
1003 const char *bt_field_class_structure_member_get_name(
1004 const struct bt_field_class_structure_member
*member
)
1006 const struct bt_named_field_class
*named_fc
= (const void *) member
;
1008 BT_ASSERT_PRE_DEV_NON_NULL(member
, "Structure field class member");
1009 return named_fc
->name
->str
;
1012 const struct bt_field_class
*
1013 bt_field_class_structure_member_borrow_field_class_const(
1014 const struct bt_field_class_structure_member
*member
)
1016 const struct bt_named_field_class
*named_fc
= (const void *) member
;
1018 BT_ASSERT_PRE_DEV_NON_NULL(member
, "Structure field class member");
1019 return named_fc
->fc
;
1023 void destroy_option_field_class(struct bt_object
*obj
)
1025 struct bt_field_class_option
*fc
= (void *) obj
;
1028 BT_LIB_LOGD("Destroying option field class object: %!+F", fc
);
1029 BT_LOGD_STR("Putting content field class.");
1030 BT_OBJECT_PUT_REF_AND_RESET(fc
->content_fc
);
1031 BT_LOGD_STR("Putting selector field path.");
1032 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_field_path
);
1033 BT_LOGD_STR("Putting selector field class.");
1034 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_fc
);
1038 struct bt_field_class
*bt_field_class_option_create(bt_trace_class
*trace_class
,
1039 bt_field_class
*content_fc
, bt_field_class
*selector_fc
)
1041 struct bt_field_class_option
*opt_fc
= NULL
;
1043 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1044 BT_ASSERT_PRE_NON_NULL(content_fc
, "Content field class");
1045 BT_LIB_LOGD("Creating option field class: "
1046 "%![content-fc-]+F, %![sel-fc-]+F", content_fc
, selector_fc
);
1047 opt_fc
= g_new0(struct bt_field_class_option
, 1);
1049 BT_LIB_LOGE_APPEND_CAUSE(
1050 "Failed to allocate one option field class.");
1054 init_field_class((void *) opt_fc
, BT_FIELD_CLASS_TYPE_OPTION
,
1055 destroy_option_field_class
);
1056 opt_fc
->content_fc
= content_fc
;
1057 bt_object_get_no_null_check(opt_fc
->content_fc
);
1058 bt_field_class_freeze(opt_fc
->content_fc
);
1061 BT_ASSERT_PRE_FC_HAS_ID(selector_fc
, BT_FIELD_CLASS_TYPE_BOOL
,
1062 "Selector field class");
1063 opt_fc
->selector_fc
= selector_fc
;
1064 bt_object_get_no_null_check(opt_fc
->selector_fc
);
1065 bt_field_class_freeze(selector_fc
);
1068 BT_LIB_LOGD("Created option field class object: "
1069 "%![opt-fc-]+F, %![sel-fc-]+F", opt_fc
, selector_fc
);
1073 BT_OBJECT_PUT_REF_AND_RESET(opt_fc
);
1076 return (void *) opt_fc
;
1079 const struct bt_field_class
*bt_field_class_option_borrow_field_class_const(
1080 const struct bt_field_class
*fc
)
1082 struct bt_field_class_option
*opt_fc
= (void *) fc
;
1084 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1085 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_OPTION
,
1087 return opt_fc
->content_fc
;
1090 const struct bt_field_path
*
1091 bt_field_class_option_borrow_selector_field_path_const(
1092 const struct bt_field_class
*fc
)
1094 struct bt_field_class_option
*opt_fc
= (void *) fc
;
1096 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1097 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_OPTION
,
1099 return opt_fc
->selector_field_path
;
1103 void finalize_variant_field_class(struct bt_field_class_variant
*var_fc
)
1106 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc
);
1107 finalize_named_field_classes_container((void *) var_fc
);
1111 void destroy_variant_field_class(struct bt_object
*obj
)
1113 struct bt_field_class_variant
*fc
= (void *) obj
;
1116 finalize_variant_field_class(fc
);
1121 void destroy_variant_with_selector_field_class(struct bt_object
*obj
)
1123 struct bt_field_class_variant_with_selector
*fc
= (void *) obj
;
1126 finalize_variant_field_class(&fc
->common
);
1127 BT_LOGD_STR("Putting selector field path.");
1128 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_field_path
);
1129 BT_LOGD_STR("Putting selector field class.");
1130 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_fc
);
1134 struct bt_field_class
*bt_field_class_variant_create(
1135 bt_trace_class
*trace_class
, bt_field_class
*selector_fc
)
1138 struct bt_field_class_variant
*var_fc
= NULL
;
1139 struct bt_field_class_variant_with_selector
*var_with_sel_fc
= NULL
;
1140 enum bt_field_class_type fc_type
;
1142 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1145 BT_ASSERT_PRE_FC_IS_INT(selector_fc
, "Selector field class");
1148 BT_LIB_LOGD("Creating default variant field class: %![sel-fc-]+F",
1152 var_with_sel_fc
= g_new0(
1153 struct bt_field_class_variant_with_selector
, 1);
1154 if (!var_with_sel_fc
) {
1155 BT_LIB_LOGE_APPEND_CAUSE(
1156 "Failed to allocate one variant field class with selector.");
1160 if (selector_fc
->type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
1161 selector_fc
->type
== BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
) {
1162 fc_type
= BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
;
1164 fc_type
= BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
;
1167 ret
= init_named_field_classes_container(
1168 (void *) var_with_sel_fc
, fc_type
,
1169 destroy_variant_with_selector_field_class
,
1170 destroy_variant_with_selector_option
);
1172 /* init_named_field_classes_container() logs errors */
1176 var_with_sel_fc
->selector_fc
= selector_fc
;
1177 bt_object_get_no_null_check(var_with_sel_fc
->selector_fc
);
1178 bt_field_class_freeze(selector_fc
);
1179 var_fc
= (void *) var_with_sel_fc
;
1181 var_fc
= g_new0(struct bt_field_class_variant
, 1);
1183 BT_LIB_LOGE_APPEND_CAUSE(
1184 "Failed to allocate one variant field class without selector.");
1188 ret
= init_named_field_classes_container((void *) var_fc
,
1189 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
,
1190 destroy_variant_field_class
, destroy_named_field_class
);
1192 /* init_named_field_classes_container() logs errors */
1198 BT_LIB_LOGD("Created default variant field class with selector object: "
1199 "%![var-fc-]+F, %![sel-fc-]+F", var_fc
, selector_fc
);
1203 BT_OBJECT_PUT_REF_AND_RESET(var_fc
);
1206 return (void *) var_fc
;
1209 enum bt_field_class_variant_without_selector_append_option_status
1210 bt_field_class_variant_without_selector_append_option(struct bt_field_class
*fc
,
1211 const char *name
, struct bt_field_class
*option_fc
)
1213 enum bt_field_class_variant_without_selector_append_option_status status
;
1214 struct bt_named_field_class
*named_fc
= NULL
;
1216 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1217 BT_ASSERT_PRE_NON_NULL(name
, "Name");
1218 BT_ASSERT_PRE_NON_NULL(option_fc
, "Option field class");
1219 BT_ASSERT_PRE_FC_HAS_ID(fc
,
1220 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
, "Field class");
1221 named_fc
= create_named_field_class(name
, option_fc
);
1223 /* create_named_field_class() logs errors */
1224 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1228 status
= append_named_field_class_to_container_field_class((void *) fc
,
1230 if (status
== BT_FUNC_STATUS_OK
) {
1231 /* Moved to the container */
1237 destroy_named_field_class(named_fc
);
1244 int ranges_overlap(GPtrArray
*var_fc_opts
, const struct bt_integer_range_set
*range_set
,
1245 bool is_signed
, bool *has_overlap
)
1247 int status
= BT_FUNC_STATUS_OK
;
1248 struct bt_integer_range_set
*full_range_set
;
1251 *has_overlap
= false;
1254 * Build a single range set with all the ranges and test for
1258 full_range_set
= (void *) bt_integer_range_set_signed_create();
1260 full_range_set
= (void *) bt_integer_range_set_unsigned_create();
1263 if (!full_range_set
) {
1264 BT_LOGE_STR("Failed to create a range set.");
1265 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1269 /* Add existing option ranges */
1270 for (i
= 0; i
< var_fc_opts
->len
; i
++) {
1271 struct bt_field_class_variant_with_selector_option
*opt
=
1272 var_fc_opts
->pdata
[i
];
1275 for (j
= 0; j
< opt
->range_set
->ranges
->len
; j
++) {
1276 struct bt_integer_range
*range
= BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1280 status
= bt_integer_range_set_signed_add_range(
1281 (void *) full_range_set
, range
->lower
.i
,
1284 status
= bt_integer_range_set_unsigned_add_range(
1285 (void *) full_range_set
, range
->lower
.u
,
1295 /* Add new ranges */
1296 for (i
= 0; i
< range_set
->ranges
->len
; i
++) {
1297 struct bt_integer_range
*range
= BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1301 status
= bt_integer_range_set_signed_add_range(
1302 (void *) full_range_set
, range
->lower
.i
,
1305 status
= bt_integer_range_set_unsigned_add_range(
1306 (void *) full_range_set
, range
->lower
.u
,
1315 /* Check overlaps */
1317 *has_overlap
= bt_integer_range_set_signed_has_overlaps(full_range_set
);
1319 *has_overlap
= bt_integer_range_set_unsigned_has_overlaps(
1324 bt_object_put_ref(full_range_set
);
1329 int append_option_to_variant_with_selector_field_class(
1330 struct bt_field_class
*fc
, const char *name
,
1331 struct bt_field_class
*option_fc
,
1332 const struct bt_integer_range_set
*range_set
,
1333 enum bt_field_class_type expected_type
)
1336 struct bt_field_class_variant_with_selector
*var_fc
= (void *) fc
;
1337 struct bt_field_class_variant_with_selector_option
*opt
= NULL
;
1340 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1341 BT_ASSERT_PRE_NON_NULL(name
, "Name");
1342 BT_ASSERT_PRE_NON_NULL(option_fc
, "Option field class");
1343 BT_ASSERT_PRE_NON_NULL(range_set
, "Integer range set");
1344 BT_ASSERT_PRE_FC_HAS_ID(fc
, expected_type
, "Field class");
1345 BT_ASSERT_PRE(range_set
->ranges
->len
> 0,
1346 "Integer range set is empty: %!+R", range_set
);
1347 status
= ranges_overlap(var_fc
->common
.common
.named_fcs
, range_set
,
1348 expected_type
== BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1351 /* ranges_overlap() logs errors */
1355 BT_ASSERT_PRE(!has_overlap
,
1356 "Integer range set's ranges and existing ranges have an overlap: "
1358 opt
= create_variant_with_selector_option(name
, option_fc
, range_set
);
1360 /* create_variant_with_selector_option() logs errors */
1361 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1365 status
= append_named_field_class_to_container_field_class((void *) fc
,
1367 if (status
== BT_FUNC_STATUS_OK
) {
1368 /* Moved to the container */
1374 destroy_variant_with_selector_option(opt
);
1380 enum bt_field_class_variant_with_selector_append_option_status
1381 bt_field_class_variant_with_selector_unsigned_append_option(
1382 struct bt_field_class
*fc
, const char *name
,
1383 struct bt_field_class
*option_fc
,
1384 const struct bt_integer_range_set_unsigned
*range_set
)
1386 return append_option_to_variant_with_selector_field_class(fc
,
1387 name
, option_fc
, (const void *) range_set
,
1388 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
);
1391 enum bt_field_class_variant_with_selector_append_option_status
1392 bt_field_class_variant_with_selector_signed_append_option(
1393 struct bt_field_class
*fc
, const char *name
,
1394 struct bt_field_class
*option_fc
,
1395 const struct bt_integer_range_set_signed
*range_set
)
1397 return append_option_to_variant_with_selector_field_class(fc
,
1398 name
, option_fc
, (const void *) range_set
,
1399 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
);
1402 uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class
*fc
)
1404 const struct bt_field_class_variant
*var_fc
= (const void *) fc
;
1406 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1407 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1408 return (uint64_t) var_fc
->common
.named_fcs
->len
;
1411 const struct bt_field_class_variant_option
*
1412 bt_field_class_variant_borrow_option_by_name_const(
1413 const struct bt_field_class
*fc
, const char *name
)
1415 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1416 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1417 return (const void *)
1418 borrow_named_field_class_from_container_field_class_by_name(
1422 const struct bt_field_class_variant_option
*
1423 bt_field_class_variant_borrow_option_by_index_const(
1424 const struct bt_field_class
*fc
, uint64_t index
)
1426 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1427 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1428 return (const void *)
1429 borrow_named_field_class_from_container_field_class_at_index(
1430 (void *) fc
, index
);
1433 const struct bt_field_class_variant_with_selector_unsigned_option
*
1434 bt_field_class_variant_with_selector_unsigned_borrow_option_by_name_const(
1435 const struct bt_field_class
*fc
, const char *name
)
1437 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1438 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1439 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
,
1441 return (const void *)
1442 borrow_named_field_class_from_container_field_class_by_name(
1446 const struct bt_field_class_variant_with_selector_unsigned_option
*
1447 bt_field_class_variant_with_selector_unsigned_borrow_option_by_index_const(
1448 const struct bt_field_class
*fc
, uint64_t index
)
1450 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1451 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1452 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
,
1454 return (const void *)
1455 borrow_named_field_class_from_container_field_class_at_index(
1456 (void *) fc
, index
);
1459 const struct bt_field_class_variant_with_selector_signed_option
*
1460 bt_field_class_variant_with_selector_signed_borrow_option_by_name_const(
1461 const struct bt_field_class
*fc
, const char *name
)
1463 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1464 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1465 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1467 return (const void *)
1468 borrow_named_field_class_from_container_field_class_by_name(
1472 const struct bt_field_class_variant_with_selector_signed_option
*
1473 bt_field_class_variant_with_selector_signed_borrow_option_by_index_const(
1474 const struct bt_field_class
*fc
, uint64_t index
)
1476 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1477 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1478 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1480 return (const void *)
1481 borrow_named_field_class_from_container_field_class_at_index(
1482 (void *) fc
, index
);
1485 const char *bt_field_class_variant_option_get_name(
1486 const struct bt_field_class_variant_option
*option
)
1488 const struct bt_named_field_class
*named_fc
= (const void *) option
;
1490 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1491 return named_fc
->name
->str
;
1494 const struct bt_field_class
*
1495 bt_field_class_variant_option_borrow_field_class_const(
1496 const struct bt_field_class_variant_option
*option
)
1498 const struct bt_named_field_class
*named_fc
= (const void *) option
;
1500 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1501 return named_fc
->fc
;
1504 const struct bt_integer_range_set_unsigned
*
1505 bt_field_class_variant_with_selector_unsigned_option_borrow_ranges_const(
1506 const struct bt_field_class_variant_with_selector_unsigned_option
*option
)
1508 const struct bt_field_class_variant_with_selector_option
*opt
=
1509 (const void *) option
;
1511 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1512 return (const void *) opt
->range_set
;
1515 const struct bt_integer_range_set_signed
*
1516 bt_field_class_variant_with_selector_signed_option_borrow_ranges_const(
1517 const struct bt_field_class_variant_with_selector_signed_option
*option
)
1519 const struct bt_field_class_variant_with_selector_option
*opt
=
1520 (const void *) option
;
1522 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1523 return (const void *) opt
->range_set
;
1526 const struct bt_field_path
*
1527 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
1528 const struct bt_field_class
*fc
)
1530 const struct bt_field_class_variant_with_selector
*var_fc
=
1533 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1534 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL(fc
, "Field class");
1535 return var_fc
->selector_field_path
;
1539 void init_array_field_class(struct bt_field_class_array
*fc
,
1540 enum bt_field_class_type type
, bt_object_release_func release_func
,
1541 struct bt_field_class
*element_fc
)
1543 BT_ASSERT(element_fc
);
1544 init_field_class((void *) fc
, type
, release_func
);
1545 fc
->element_fc
= element_fc
;
1546 bt_object_get_no_null_check(fc
->element_fc
);
1547 bt_field_class_freeze(element_fc
);
1551 void finalize_array_field_class(struct bt_field_class_array
*array_fc
)
1553 BT_ASSERT(array_fc
);
1554 BT_LOGD_STR("Putting element field class.");
1555 BT_OBJECT_PUT_REF_AND_RESET(array_fc
->element_fc
);
1559 void destroy_static_array_field_class(struct bt_object
*obj
)
1562 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj
);
1563 finalize_array_field_class((void *) obj
);
1567 struct bt_field_class
*
1568 bt_field_class_array_static_create(bt_trace_class
*trace_class
,
1569 struct bt_field_class
*element_fc
, uint64_t length
)
1571 struct bt_field_class_array_static
*array_fc
= NULL
;
1573 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1574 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1575 BT_LOGD_STR("Creating default static array field class object.");
1576 array_fc
= g_new0(struct bt_field_class_array_static
, 1);
1578 BT_LIB_LOGE_APPEND_CAUSE(
1579 "Failed to allocate one static array field class.");
1583 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1584 destroy_static_array_field_class
, element_fc
);
1585 array_fc
->length
= length
;
1586 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc
);
1590 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1593 return (void *) array_fc
;
1596 const struct bt_field_class
*
1597 bt_field_class_array_borrow_element_field_class_const(
1598 const struct bt_field_class
*fc
)
1600 const struct bt_field_class_array
*array_fc
= (const void *) fc
;
1602 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1603 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc
, "Field class");
1604 return array_fc
->element_fc
;
1607 struct bt_field_class
*
1608 bt_field_class_array_borrow_element_field_class(struct bt_field_class
*fc
)
1610 struct bt_field_class_array
*array_fc
= (void *) fc
;
1612 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1613 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc
, "Field class");
1614 return array_fc
->element_fc
;
1617 uint64_t bt_field_class_array_static_get_length(const struct bt_field_class
*fc
)
1619 const struct bt_field_class_array_static
*array_fc
= (const void *) fc
;
1621 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1622 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1624 return (uint64_t) array_fc
->length
;
1628 void destroy_dynamic_array_field_class(struct bt_object
*obj
)
1630 struct bt_field_class_array_dynamic
*fc
= (void *) obj
;
1633 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc
);
1634 finalize_array_field_class((void *) fc
);
1635 BT_LOGD_STR("Putting length field path.");
1636 BT_OBJECT_PUT_REF_AND_RESET(fc
->length_field_path
);
1637 BT_LOGD_STR("Putting length field class.");
1638 BT_OBJECT_PUT_REF_AND_RESET(fc
->length_fc
);
1642 struct bt_field_class
*bt_field_class_array_dynamic_create(
1643 struct bt_trace_class
*trace_class
,
1644 struct bt_field_class
*element_fc
,
1645 struct bt_field_class
*length_fc
)
1647 struct bt_field_class_array_dynamic
*array_fc
= NULL
;
1649 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1650 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1651 BT_LOGD_STR("Creating default dynamic array field class object.");
1652 array_fc
= g_new0(struct bt_field_class_array_dynamic
, 1);
1654 BT_LIB_LOGE_APPEND_CAUSE(
1655 "Failed to allocate one dynamic array field class.");
1659 init_array_field_class((void *) array_fc
,
1660 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1661 destroy_dynamic_array_field_class
, element_fc
);
1664 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc
,
1665 "Length field class");
1666 array_fc
->length_fc
= length_fc
;
1667 bt_object_get_no_null_check(array_fc
->length_fc
);
1668 bt_field_class_freeze(length_fc
);
1671 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc
);
1675 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1678 return (void *) array_fc
;
1681 const struct bt_field_path
*
1682 bt_field_class_array_dynamic_borrow_length_field_path_const(
1683 const struct bt_field_class
*fc
)
1685 const struct bt_field_class_array_dynamic
*seq_fc
= (const void *) fc
;
1687 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1688 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1690 return seq_fc
->length_field_path
;
1694 void destroy_string_field_class(struct bt_object
*obj
)
1697 BT_LIB_LOGD("Destroying string field class object: %!+F", obj
);
1701 struct bt_field_class
*bt_field_class_string_create(bt_trace_class
*trace_class
)
1703 struct bt_field_class_string
*string_fc
= NULL
;
1705 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1706 BT_LOGD_STR("Creating default string field class object.");
1707 string_fc
= g_new0(struct bt_field_class_string
, 1);
1709 BT_LIB_LOGE_APPEND_CAUSE(
1710 "Failed to allocate one string field class.");
1714 init_field_class((void *) string_fc
, BT_FIELD_CLASS_TYPE_STRING
,
1715 destroy_string_field_class
);
1716 BT_LIB_LOGD("Created string field class object: %!+F", string_fc
);
1720 BT_OBJECT_PUT_REF_AND_RESET(string_fc
);
1723 return (void *) string_fc
;
1727 void _bt_field_class_freeze(const struct bt_field_class
*c_fc
)
1729 struct bt_field_class
*fc
= (void *) c_fc
;
1732 * Element/member/option field classes are frozen when added to
1739 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1740 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
:
1741 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
:
1742 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
:
1744 struct bt_field_class_named_field_class_container
*container_fc
=
1748 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1749 bt_named_field_class_freeze(
1750 container_fc
->named_fcs
->pdata
[i
]);
1761 void _bt_named_field_class_freeze(const struct bt_named_field_class
*named_fc
)
1763 BT_ASSERT(named_fc
);
1764 ((struct bt_named_field_class
*) named_fc
)->frozen
= true;
1765 bt_field_class_freeze(named_fc
->fc
);
1769 void bt_field_class_make_part_of_trace_class(const struct bt_field_class
*c_fc
)
1771 struct bt_field_class
*fc
= (void *) c_fc
;
1774 BT_ASSERT_PRE(!fc
->part_of_trace_class
,
1775 "Field class is already part of a trace: %!+F", fc
);
1776 fc
->part_of_trace_class
= true;
1779 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1780 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
:
1781 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
:
1782 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
:
1784 struct bt_field_class_named_field_class_container
*container_fc
=
1788 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1789 struct bt_named_field_class
*named_fc
=
1790 container_fc
->named_fcs
->pdata
[i
];
1792 bt_field_class_make_part_of_trace_class(named_fc
->fc
);
1797 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY
:
1798 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
:
1800 struct bt_field_class_array
*array_fc
= (void *) fc
;
1802 bt_field_class_make_part_of_trace_class(array_fc
->element_fc
);
1810 void bt_field_class_get_ref(const struct bt_field_class
*field_class
)
1812 bt_object_get_ref(field_class
);
1815 void bt_field_class_put_ref(const struct bt_field_class
*field_class
)
1817 bt_object_put_ref(field_class
);