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 init_integer_field_class(struct bt_field_class_integer
*fc
,
69 enum bt_field_class_type type
,
70 bt_object_release_func release_func
)
72 init_field_class((void *) fc
, type
, release_func
);
74 fc
->base
= BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL
;
78 void destroy_integer_field_class(struct bt_object
*obj
)
81 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj
);
86 struct bt_field_class
*create_integer_field_class(bt_trace_class
*trace_class
,
87 enum bt_field_class_type type
)
89 struct bt_field_class_integer
*int_fc
= NULL
;
91 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
92 BT_LOGD("Creating default integer field class object: type=%s",
93 bt_common_field_class_type_string(type
));
94 int_fc
= g_new0(struct bt_field_class_integer
, 1);
96 BT_LIB_LOGE_APPEND_CAUSE(
97 "Failed to allocate one integer field class.");
101 init_integer_field_class(int_fc
, type
, destroy_integer_field_class
);
102 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc
);
106 BT_OBJECT_PUT_REF_AND_RESET(int_fc
);
109 return (void *) int_fc
;
112 struct bt_field_class
*bt_field_class_unsigned_integer_create(
113 bt_trace_class
*trace_class
)
115 return create_integer_field_class(trace_class
,
116 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
);
119 struct bt_field_class
*bt_field_class_signed_integer_create(
120 bt_trace_class
*trace_class
)
122 return create_integer_field_class(trace_class
,
123 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
);
126 uint64_t bt_field_class_integer_get_field_value_range(
127 const struct bt_field_class
*fc
)
129 const struct bt_field_class_integer
*int_fc
= (const void *) fc
;
131 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
132 BT_ASSERT_PRE_DEV_FC_IS_INT(fc
, "Field class");
133 return int_fc
->range
;
137 bool size_is_valid_for_enumeration_field_class(struct bt_field_class
*fc
,
144 void bt_field_class_integer_set_field_value_range(
145 struct bt_field_class
*fc
, uint64_t size
)
147 struct bt_field_class_integer
*int_fc
= (void *) fc
;
149 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
150 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
151 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
152 BT_ASSERT_PRE(size
<= 64,
153 "Unsupported size for integer field class's field value range "
154 "(maximum is 64): size=%" PRIu64
, size
);
156 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
157 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
||
158 size_is_valid_for_enumeration_field_class(fc
, size
),
159 "Invalid field value range for enumeration field class: "
160 "at least one of the current mapping ranges contains values "
161 "which are outside this range: %!+F, size=%" PRIu64
, fc
, size
);
162 int_fc
->range
= size
;
163 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc
);
166 enum bt_field_class_integer_preferred_display_base
167 bt_field_class_integer_get_preferred_display_base(const struct bt_field_class
*fc
)
169 const struct bt_field_class_integer
*int_fc
= (const void *) fc
;
171 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
172 BT_ASSERT_PRE_DEV_FC_IS_INT(fc
, "Field class");
176 void bt_field_class_integer_set_preferred_display_base(
177 struct bt_field_class
*fc
,
178 enum bt_field_class_integer_preferred_display_base base
)
180 struct bt_field_class_integer
*int_fc
= (void *) fc
;
182 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
183 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
184 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
186 BT_LIB_LOGD("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
);
197 mapping
->label
= NULL
;
200 BT_OBJECT_PUT_REF_AND_RESET(mapping
->range_set
);
204 void destroy_enumeration_field_class(struct bt_object
*obj
)
206 struct bt_field_class_enumeration
*fc
= (void *) obj
;
209 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc
);
214 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
215 finalize_enumeration_field_class_mapping(
216 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
));
219 g_array_free(fc
->mappings
, TRUE
);
224 g_ptr_array_free(fc
->label_buf
, TRUE
);
225 fc
->label_buf
= NULL
;
232 struct bt_field_class
*create_enumeration_field_class(
233 bt_trace_class
*trace_class
, enum bt_field_class_type type
)
235 struct bt_field_class_enumeration
*enum_fc
= NULL
;
237 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
238 BT_LOGD("Creating default enumeration field class object: type=%s",
239 bt_common_field_class_type_string(type
));
240 enum_fc
= g_new0(struct bt_field_class_enumeration
, 1);
242 BT_LIB_LOGE_APPEND_CAUSE(
243 "Failed to allocate one enumeration field class.");
247 init_integer_field_class((void *) enum_fc
, type
,
248 destroy_enumeration_field_class
);
249 enum_fc
->mappings
= g_array_new(FALSE
, TRUE
,
250 sizeof(struct bt_field_class_enumeration_mapping
));
251 if (!enum_fc
->mappings
) {
252 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
256 enum_fc
->label_buf
= g_ptr_array_new();
257 if (!enum_fc
->label_buf
) {
258 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
262 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc
);
266 BT_OBJECT_PUT_REF_AND_RESET(enum_fc
);
269 return (void *) enum_fc
;
272 struct bt_field_class
*bt_field_class_unsigned_enumeration_create(
273 bt_trace_class
*trace_class
)
275 return create_enumeration_field_class(trace_class
,
276 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
);
279 struct bt_field_class
*bt_field_class_signed_enumeration_create(
280 bt_trace_class
*trace_class
)
282 return create_enumeration_field_class(trace_class
,
283 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
);
286 uint64_t bt_field_class_enumeration_get_mapping_count(
287 const struct bt_field_class
*fc
)
289 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
291 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
292 BT_ASSERT_PRE_DEV_FC_IS_ENUM(fc
, "Field class");
293 return (uint64_t) enum_fc
->mappings
->len
;
296 const struct bt_field_class_unsigned_enumeration_mapping
*
297 bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
298 const struct bt_field_class
*fc
, uint64_t index
)
300 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
302 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
303 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, enum_fc
->mappings
->len
);
304 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
306 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
309 const struct bt_field_class_signed_enumeration_mapping
*
310 bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
311 const struct bt_field_class
*fc
, uint64_t index
)
313 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
315 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
316 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, enum_fc
->mappings
->len
);
317 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
319 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
323 const struct bt_field_class_enumeration_mapping
*
324 borrow_enumeration_field_class_mapping_by_label(
325 const struct bt_field_class_enumeration
*fc
, const char *label
)
327 struct bt_field_class_enumeration_mapping
*mapping
= NULL
;
331 BT_ASSERT_PRE_DEV_NON_NULL(label
, "Label");
333 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
334 struct bt_field_class_enumeration_mapping
*this_mapping
=
335 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
);
337 if (strcmp(this_mapping
->label
->str
, label
) == 0) {
338 mapping
= this_mapping
;
347 const struct bt_field_class_signed_enumeration_mapping
*
348 bt_field_class_signed_enumeration_borrow_mapping_by_label_const(
349 const struct bt_field_class
*fc
, const char *label
)
351 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
352 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
354 return (const void *) borrow_enumeration_field_class_mapping_by_label(
355 (const void *) fc
, label
);
358 const struct bt_field_class_unsigned_enumeration_mapping
*
359 bt_field_class_unsigned_enumeration_borrow_mapping_by_label_const(
360 const struct bt_field_class
*fc
, const char *label
)
362 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
363 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
364 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
, "Field class");
365 return (const void *) borrow_enumeration_field_class_mapping_by_label(
366 (const void *) fc
, label
);
369 const char *bt_field_class_enumeration_mapping_get_label(
370 const struct bt_field_class_enumeration_mapping
*mapping
)
372 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
373 return mapping
->label
->str
;
376 const struct bt_integer_range_set_unsigned
*
377 bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
378 const struct bt_field_class_unsigned_enumeration_mapping
*u_mapping
)
380 const struct bt_field_class_enumeration_mapping
*mapping
=
381 (const void *) u_mapping
;
383 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
384 return (const void *) mapping
->range_set
;
387 const struct bt_integer_range_set_signed
*
388 bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
389 const struct bt_field_class_signed_enumeration_mapping
*s_mapping
)
391 const struct bt_field_class_enumeration_mapping
*mapping
=
392 (const void *) s_mapping
;
394 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
395 return (const void *) mapping
->range_set
;
398 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
399 bt_field_class_unsigned_enumeration_get_mapping_labels_for_value(
400 const struct bt_field_class
*fc
, uint64_t value
,
401 bt_field_class_enumeration_mapping_label_array
*label_array
,
404 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
407 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
408 BT_ASSERT_PRE_DEV_NON_NULL(label_array
, "Label array (output)");
409 BT_ASSERT_PRE_DEV_NON_NULL(count
, "Count (output)");
410 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
412 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
414 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
416 const struct bt_field_class_enumeration_mapping
*mapping
=
417 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
419 for (j
= 0; j
< mapping
->range_set
->ranges
->len
; j
++) {
420 const struct bt_integer_range
*range
= (const void *)
421 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
422 mapping
->range_set
, j
);
424 if (value
>= range
->lower
.u
&&
425 value
<= range
->upper
.u
) {
426 g_ptr_array_add(enum_fc
->label_buf
,
427 mapping
->label
->str
);
433 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
434 *count
= (uint64_t) enum_fc
->label_buf
->len
;
435 return BT_FUNC_STATUS_OK
;
438 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
439 bt_field_class_signed_enumeration_get_mapping_labels_for_value(
440 const struct bt_field_class
*fc
, int64_t value
,
441 bt_field_class_enumeration_mapping_label_array
*label_array
,
444 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
447 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
448 BT_ASSERT_PRE_DEV_NON_NULL(label_array
, "Label array (output)");
449 BT_ASSERT_PRE_DEV_NON_NULL(count
, "Count (output)");
450 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
452 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
454 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
456 const struct bt_field_class_enumeration_mapping
*mapping
=
457 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
459 for (j
= 0; j
< mapping
->range_set
->ranges
->len
; j
++) {
460 const struct bt_integer_range
*range
= (const void *)
461 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
462 mapping
->range_set
, j
);
464 if (value
>= range
->lower
.i
&&
465 value
<= range
->upper
.i
) {
466 g_ptr_array_add(enum_fc
->label_buf
,
467 mapping
->label
->str
);
473 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
474 *count
= (uint64_t) enum_fc
->label_buf
->len
;
475 return BT_FUNC_STATUS_OK
;
479 bool enumeration_field_class_has_mapping_with_label(
480 const struct bt_field_class_enumeration
*enum_fc
,
489 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
490 struct bt_field_class_enumeration_mapping
*mapping_candidate
=
491 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
493 if (strcmp(mapping_candidate
->label
->str
, label
) == 0) {
504 enum bt_field_class_enumeration_add_mapping_status
505 add_mapping_to_enumeration_field_class(struct bt_field_class
*fc
,
506 const char *label
, const struct bt_integer_range_set
*range_set
)
508 enum bt_field_class_enumeration_add_mapping_status status
=
510 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
511 struct bt_field_class_enumeration_mapping mapping
= { 0 };
514 BT_ASSERT_PRE_NON_NULL(label
, "Label");
515 BT_ASSERT_PRE_NON_NULL(range_set
, "Range set");
516 BT_ASSERT_PRE(!enumeration_field_class_has_mapping_with_label(
518 "Duplicate mapping name in enumeration field class: "
519 "%![enum-fc-]+F, label=\"%s\"", fc
, label
);
520 mapping
.range_set
= range_set
;
521 bt_object_get_ref(mapping
.range_set
);
522 mapping
.label
= g_string_new(label
);
523 if (!mapping
.label
) {
524 finalize_enumeration_field_class_mapping(&mapping
);
525 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
529 g_array_append_val(enum_fc
->mappings
, mapping
);
530 BT_LIB_LOGD("Added mapping to enumeration field class: "
531 "%![fc-]+F, label=\"%s\"", fc
, label
);
537 enum bt_field_class_enumeration_add_mapping_status
538 bt_field_class_unsigned_enumeration_add_mapping(
539 struct bt_field_class
*fc
, const char *label
,
540 const struct bt_integer_range_set_unsigned
*range_set
)
542 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
543 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
545 return add_mapping_to_enumeration_field_class(fc
, label
,
546 (const void *) range_set
);
549 enum bt_field_class_enumeration_add_mapping_status
550 bt_field_class_signed_enumeration_add_mapping(
551 struct bt_field_class
*fc
, const char *label
,
552 const struct bt_integer_range_set_signed
*range_set
)
554 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
555 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
557 return add_mapping_to_enumeration_field_class(fc
, label
,
558 (const void *) range_set
);
562 void destroy_real_field_class(struct bt_object
*obj
)
565 BT_LIB_LOGD("Destroying real field class object: %!+F", obj
);
569 struct bt_field_class
*bt_field_class_real_create(bt_trace_class
*trace_class
)
571 struct bt_field_class_real
*real_fc
= NULL
;
573 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
574 BT_LOGD_STR("Creating default real field class object.");
575 real_fc
= g_new0(struct bt_field_class_real
, 1);
577 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
581 init_field_class((void *) real_fc
, BT_FIELD_CLASS_TYPE_REAL
,
582 destroy_real_field_class
);
583 BT_LIB_LOGD("Created real field class object: %!+F", real_fc
);
587 BT_OBJECT_PUT_REF_AND_RESET(real_fc
);
590 return (void *) real_fc
;
593 bt_bool
bt_field_class_real_is_single_precision(const struct bt_field_class
*fc
)
595 const struct bt_field_class_real
*real_fc
= (const void *) fc
;
597 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
598 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
599 return real_fc
->is_single_precision
;
602 void bt_field_class_real_set_is_single_precision(struct bt_field_class
*fc
,
603 bt_bool is_single_precision
)
605 struct bt_field_class_real
*real_fc
= (void *) fc
;
607 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
608 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
609 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
610 real_fc
->is_single_precision
= (bool) is_single_precision
;
611 BT_LIB_LOGD("Set real field class's \"is single precision\" property: "
616 int init_named_field_classes_container(
617 struct bt_field_class_named_field_class_container
*fc
,
618 enum bt_field_class_type type
,
619 bt_object_release_func fc_release_func
,
620 GDestroyNotify named_fc_destroy_func
)
624 init_field_class((void *) fc
, type
, fc_release_func
);
625 fc
->named_fcs
= g_ptr_array_new_with_free_func(named_fc_destroy_func
);
626 if (!fc
->named_fcs
) {
627 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
632 fc
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
633 if (!fc
->name_to_index
) {
634 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
644 void finalize_named_field_class(struct bt_named_field_class
*named_fc
)
647 BT_LIB_LOGD("Finalizing named field class: "
648 "addr=%p, name=\"%s\", %![fc-]+F",
649 named_fc
, named_fc
->name
? named_fc
->name
->str
: NULL
,
652 if (named_fc
->name
) {
653 g_string_free(named_fc
->name
, TRUE
);
654 named_fc
->name
= NULL
;
657 BT_LOGD_STR("Putting named field class's field class.");
658 BT_OBJECT_PUT_REF_AND_RESET(named_fc
->fc
);
662 void destroy_named_field_class(gpointer ptr
)
665 finalize_named_field_class(ptr
);
671 void destroy_variant_with_selector_option(gpointer ptr
)
673 struct bt_field_class_variant_with_selector_option
*opt
= ptr
;
676 finalize_named_field_class(&opt
->common
);
677 BT_OBJECT_PUT_REF_AND_RESET(opt
->range_set
);
683 void finalize_named_field_classes_container(
684 struct bt_field_class_named_field_class_container
*fc
)
689 g_ptr_array_free(fc
->named_fcs
, TRUE
);
690 fc
->named_fcs
= NULL
;
694 if (fc
->name_to_index
) {
695 g_hash_table_destroy(fc
->name_to_index
);
696 fc
->name_to_index
= NULL
;
701 void destroy_structure_field_class(struct bt_object
*obj
)
704 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj
);
705 finalize_named_field_classes_container((void *) obj
);
709 struct bt_field_class
*bt_field_class_structure_create(
710 bt_trace_class
*trace_class
)
713 struct bt_field_class_structure
*struct_fc
= NULL
;
715 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
716 BT_LOGD_STR("Creating default structure field class object.");
717 struct_fc
= g_new0(struct bt_field_class_structure
, 1);
719 BT_LIB_LOGE_APPEND_CAUSE(
720 "Failed to allocate one structure field class.");
724 ret
= init_named_field_classes_container((void *) struct_fc
,
725 BT_FIELD_CLASS_TYPE_STRUCTURE
, destroy_structure_field_class
,
726 destroy_named_field_class
);
728 /* init_named_field_classes_container() logs errors */
732 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc
);
736 BT_OBJECT_PUT_REF_AND_RESET(struct_fc
);
739 return (void *) struct_fc
;
743 int init_named_field_class(struct bt_named_field_class
*named_fc
,
744 const char *name
, struct bt_field_class
*fc
)
746 int status
= BT_FUNC_STATUS_OK
;
751 named_fc
->name
= g_string_new(name
);
752 if (!named_fc
->name
) {
753 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
754 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
759 bt_object_get_no_null_check(named_fc
->fc
);
760 bt_named_field_class_freeze(named_fc
);
767 struct bt_named_field_class
*create_named_field_class(const char *name
,
768 struct bt_field_class
*fc
)
770 struct bt_named_field_class
*named_fc
= g_new0(
771 struct bt_named_field_class
, 1);
774 BT_LIB_LOGE_APPEND_CAUSE(
775 "Failed to allocate a named field class.");
779 if (init_named_field_class(named_fc
, name
, fc
)) {
780 /* init_named_field_class() logs errors */
787 destroy_named_field_class(named_fc
);
795 struct bt_field_class_variant_with_selector_option
*
796 create_variant_with_selector_option(
797 const char *name
, struct bt_field_class
*fc
,
798 const struct bt_integer_range_set
*range_set
)
800 struct bt_field_class_variant_with_selector_option
*opt
= g_new0(
801 struct bt_field_class_variant_with_selector_option
, 1);
803 BT_ASSERT(range_set
);
806 BT_LIB_LOGE_APPEND_CAUSE(
807 "Failed to allocate a named field class.");
811 if (init_named_field_class(&opt
->common
, name
, fc
)) {
815 opt
->range_set
= range_set
;
816 bt_object_get_no_null_check(opt
->range_set
);
817 bt_integer_range_set_freeze(range_set
);
821 destroy_variant_with_selector_option(opt
);
829 int append_named_field_class_to_container_field_class(
830 struct bt_field_class_named_field_class_container
*container_fc
,
831 struct bt_named_field_class
*named_fc
)
833 BT_ASSERT(container_fc
);
835 BT_ASSERT_PRE_DEV_FC_HOT(container_fc
, "Field class");
836 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc
->name_to_index
,
837 named_fc
->name
->str
),
838 "Duplicate member/option name in structure/variant field class: "
839 "%![container-fc-]+F, name=\"%s\"", container_fc
,
840 named_fc
->name
->str
);
841 g_ptr_array_add(container_fc
->named_fcs
, named_fc
);
842 g_hash_table_insert(container_fc
->name_to_index
, named_fc
->name
->str
,
843 GUINT_TO_POINTER(container_fc
->named_fcs
->len
- 1));
844 return BT_FUNC_STATUS_OK
;
847 enum bt_field_class_structure_append_member_status
848 bt_field_class_structure_append_member(
849 struct bt_field_class
*fc
, const char *name
,
850 struct bt_field_class
*member_fc
)
852 enum bt_field_class_structure_append_member_status status
;
853 struct bt_named_field_class
*named_fc
= NULL
;
855 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
856 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
858 named_fc
= create_named_field_class(name
, member_fc
);
860 /* create_named_field_class() logs errors */
861 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
865 status
= append_named_field_class_to_container_field_class((void *) fc
,
867 if (status
== BT_FUNC_STATUS_OK
) {
868 /* Moved to the container */
876 uint64_t bt_field_class_structure_get_member_count(
877 const struct bt_field_class
*fc
)
879 struct bt_field_class_structure
*struct_fc
= (void *) fc
;
881 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
882 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
884 return (uint64_t) struct_fc
->common
.named_fcs
->len
;
888 struct bt_named_field_class
*
889 borrow_named_field_class_from_container_field_class_at_index(
890 struct bt_field_class_named_field_class_container
*fc
,
894 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, fc
->named_fcs
->len
);
895 return fc
->named_fcs
->pdata
[index
];
898 const struct bt_field_class_structure_member
*
899 bt_field_class_structure_borrow_member_by_index_const(
900 const struct bt_field_class
*fc
, uint64_t index
)
902 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
903 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
905 return (const void *)
906 borrow_named_field_class_from_container_field_class_at_index(
910 struct bt_field_class_structure_member
*
911 bt_field_class_structure_borrow_member_by_index(
912 struct bt_field_class
*fc
, uint64_t index
)
914 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
915 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
918 borrow_named_field_class_from_container_field_class_at_index(
923 struct bt_named_field_class
*
924 borrow_named_field_class_from_container_field_class_by_name(
925 struct bt_field_class_named_field_class_container
*fc
,
928 struct bt_named_field_class
*named_fc
= NULL
;
933 BT_ASSERT_PRE_DEV_NON_NULL(name
, "Name");
934 if (!g_hash_table_lookup_extended(fc
->name_to_index
, name
, &orig_key
,
939 named_fc
= fc
->named_fcs
->pdata
[GPOINTER_TO_UINT(value
)];
945 const struct bt_field_class_structure_member
*
946 bt_field_class_structure_borrow_member_by_name_const(
947 const struct bt_field_class
*fc
, const char *name
)
949 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
950 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
952 return (const void *)
953 borrow_named_field_class_from_container_field_class_by_name(
957 struct bt_field_class_structure_member
*
958 bt_field_class_structure_borrow_member_by_name(
959 struct bt_field_class
*fc
, const char *name
)
961 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
962 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
965 borrow_named_field_class_from_container_field_class_by_name(
969 const char *bt_field_class_structure_member_get_name(
970 const struct bt_field_class_structure_member
*member
)
972 const struct bt_named_field_class
*named_fc
= (const void *) member
;
974 BT_ASSERT_PRE_DEV_NON_NULL(member
, "Structure field class member");
975 return named_fc
->name
->str
;
978 const struct bt_field_class
*
979 bt_field_class_structure_member_borrow_field_class_const(
980 const struct bt_field_class_structure_member
*member
)
982 const struct bt_named_field_class
*named_fc
= (const void *) member
;
984 BT_ASSERT_PRE_DEV_NON_NULL(member
, "Structure field class member");
989 void finalize_variant_field_class(struct bt_field_class_variant
*var_fc
)
992 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc
);
993 finalize_named_field_classes_container((void *) var_fc
);
997 void destroy_variant_field_class(struct bt_object
*obj
)
999 struct bt_field_class_variant
*fc
= (void *) obj
;
1002 finalize_variant_field_class(fc
);
1007 void destroy_variant_with_selector_field_class(struct bt_object
*obj
)
1009 struct bt_field_class_variant_with_selector
*fc
= (void *) obj
;
1012 finalize_variant_field_class(&fc
->common
);
1013 BT_LOGD_STR("Putting selector field path.");
1014 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_field_path
);
1015 BT_LOGD_STR("Putting selector field class.");
1016 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_fc
);
1020 struct bt_field_class
*bt_field_class_variant_create(
1021 bt_trace_class
*trace_class
, bt_field_class
*selector_fc
)
1024 struct bt_field_class_variant
*var_fc
= NULL
;
1025 struct bt_field_class_variant_with_selector
*var_with_sel_fc
= NULL
;
1026 enum bt_field_class_type fc_type
;
1028 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1031 BT_ASSERT_PRE_FC_IS_INT(selector_fc
, "Selector field class");
1034 BT_LIB_LOGD("Creating default variant field class: %![sel-fc-]+F",
1038 var_with_sel_fc
= g_new0(
1039 struct bt_field_class_variant_with_selector
, 1);
1040 if (!var_with_sel_fc
) {
1041 BT_LIB_LOGE_APPEND_CAUSE(
1042 "Failed to allocate one variant field class with selector.");
1046 if (selector_fc
->type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
1047 selector_fc
->type
== BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
) {
1048 fc_type
= BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
;
1050 fc_type
= BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
;
1053 ret
= init_named_field_classes_container(
1054 (void *) var_with_sel_fc
, fc_type
,
1055 destroy_variant_with_selector_field_class
,
1056 destroy_variant_with_selector_option
);
1058 /* init_named_field_classes_container() logs errors */
1062 var_with_sel_fc
->selector_fc
= selector_fc
;
1063 bt_object_get_no_null_check(var_with_sel_fc
->selector_fc
);
1064 bt_field_class_freeze(selector_fc
);
1065 var_fc
= (void *) var_with_sel_fc
;
1067 var_fc
= g_new0(struct bt_field_class_variant
, 1);
1069 BT_LIB_LOGE_APPEND_CAUSE(
1070 "Failed to allocate one variant field class without selector.");
1074 ret
= init_named_field_classes_container((void *) var_fc
,
1075 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
,
1076 destroy_variant_field_class
, destroy_named_field_class
);
1078 /* init_named_field_classes_container() logs errors */
1084 BT_LIB_LOGD("Created default variant field class with selector object: "
1085 "%![var-fc-]+F, %![sel-fc-]+F", var_fc
, selector_fc
);
1089 BT_OBJECT_PUT_REF_AND_RESET(var_fc
);
1092 return (void *) var_fc
;
1095 enum bt_field_class_variant_without_selector_append_option_status
1096 bt_field_class_variant_without_selector_append_option(struct bt_field_class
*fc
,
1097 const char *name
, struct bt_field_class
*option_fc
)
1099 enum bt_field_class_variant_without_selector_append_option_status status
;
1100 struct bt_named_field_class
*named_fc
= NULL
;
1102 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1103 BT_ASSERT_PRE_NON_NULL(name
, "Name");
1104 BT_ASSERT_PRE_NON_NULL(option_fc
, "Option field class");
1105 BT_ASSERT_PRE_FC_HAS_ID(fc
,
1106 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
, "Field class");
1107 named_fc
= create_named_field_class(name
, option_fc
);
1109 /* create_named_field_class() logs errors */
1110 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1114 status
= append_named_field_class_to_container_field_class((void *) fc
,
1116 if (status
== BT_FUNC_STATUS_OK
) {
1117 /* Moved to the container */
1123 destroy_named_field_class(named_fc
);
1130 int ranges_overlap(GPtrArray
*var_fc_opts
, const struct bt_integer_range_set
*range_set
,
1131 bool is_signed
, bool *has_overlap
)
1133 int status
= BT_FUNC_STATUS_OK
;
1134 struct bt_integer_range_set
*full_range_set
;
1137 *has_overlap
= false;
1140 * Build a single range set with all the ranges and test for
1144 full_range_set
= (void *) bt_integer_range_set_signed_create();
1146 full_range_set
= (void *) bt_integer_range_set_unsigned_create();
1149 if (!full_range_set
) {
1150 BT_LOGE_STR("Failed to create a range set.");
1151 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1155 /* Add existing option ranges */
1156 for (i
= 0; i
< var_fc_opts
->len
; i
++) {
1157 struct bt_field_class_variant_with_selector_option
*opt
=
1158 var_fc_opts
->pdata
[i
];
1161 for (j
= 0; j
< opt
->range_set
->ranges
->len
; j
++) {
1162 struct bt_integer_range
*range
= BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1166 status
= bt_integer_range_set_signed_add_range(
1167 (void *) full_range_set
, range
->lower
.i
,
1170 status
= bt_integer_range_set_unsigned_add_range(
1171 (void *) full_range_set
, range
->lower
.u
,
1181 /* Add new ranges */
1182 for (i
= 0; i
< range_set
->ranges
->len
; i
++) {
1183 struct bt_integer_range
*range
= BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1187 status
= bt_integer_range_set_signed_add_range(
1188 (void *) full_range_set
, range
->lower
.i
,
1191 status
= bt_integer_range_set_unsigned_add_range(
1192 (void *) full_range_set
, range
->lower
.u
,
1201 /* Check overlaps */
1203 *has_overlap
= bt_integer_range_set_signed_has_overlaps(full_range_set
);
1205 *has_overlap
= bt_integer_range_set_unsigned_has_overlaps(
1210 bt_object_put_ref(full_range_set
);
1215 int append_option_to_variant_with_selector_field_class(
1216 struct bt_field_class
*fc
, const char *name
,
1217 struct bt_field_class
*option_fc
,
1218 const struct bt_integer_range_set
*range_set
,
1219 enum bt_field_class_type expected_type
)
1222 struct bt_field_class_variant_with_selector
*var_fc
= (void *) fc
;
1223 struct bt_field_class_variant_with_selector_option
*opt
= NULL
;
1226 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1227 BT_ASSERT_PRE_NON_NULL(name
, "Name");
1228 BT_ASSERT_PRE_NON_NULL(option_fc
, "Option field class");
1229 BT_ASSERT_PRE_NON_NULL(range_set
, "Range set");
1230 BT_ASSERT_PRE_FC_HAS_ID(fc
, expected_type
, "Field class");
1231 BT_ASSERT_PRE(range_set
->ranges
->len
> 0,
1232 "Range set is empty: addr=%p", range_set
);
1233 status
= ranges_overlap(var_fc
->common
.common
.named_fcs
, range_set
,
1234 expected_type
== BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1237 /* ranges_overlap() logs errors */
1241 BT_ASSERT_PRE(!has_overlap
,
1242 "Range set's ranges and existing ranges have an overlap: "
1243 "addr=%p", range_set
);
1244 opt
= create_variant_with_selector_option(name
, option_fc
, range_set
);
1246 /* create_variant_with_selector_option() logs errors */
1247 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1251 status
= append_named_field_class_to_container_field_class((void *) fc
,
1253 if (status
== BT_FUNC_STATUS_OK
) {
1254 /* Moved to the container */
1260 destroy_variant_with_selector_option(opt
);
1266 enum bt_field_class_variant_with_selector_append_option_status
1267 bt_field_class_variant_with_unsigned_selector_append_option(
1268 struct bt_field_class
*fc
, const char *name
,
1269 struct bt_field_class
*option_fc
,
1270 const struct bt_integer_range_set_unsigned
*range_set
)
1272 return append_option_to_variant_with_selector_field_class(fc
,
1273 name
, option_fc
, (const void *) range_set
,
1274 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
);
1277 enum bt_field_class_variant_with_selector_append_option_status
1278 bt_field_class_variant_with_signed_selector_append_option(
1279 struct bt_field_class
*fc
, const char *name
,
1280 struct bt_field_class
*option_fc
,
1281 const struct bt_integer_range_set_signed
*range_set
)
1283 return append_option_to_variant_with_selector_field_class(fc
,
1284 name
, option_fc
, (const void *) range_set
,
1285 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
);
1288 uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class
*fc
)
1290 const struct bt_field_class_variant
*var_fc
= (const void *) fc
;
1292 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1293 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1294 return (uint64_t) var_fc
->common
.named_fcs
->len
;
1297 const struct bt_field_class_variant_option
*
1298 bt_field_class_variant_borrow_option_by_name_const(
1299 const struct bt_field_class
*fc
, const char *name
)
1301 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1302 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1303 return (const void *)
1304 borrow_named_field_class_from_container_field_class_by_name(
1308 const struct bt_field_class_variant_option
*
1309 bt_field_class_variant_borrow_option_by_index_const(
1310 const struct bt_field_class
*fc
, uint64_t index
)
1312 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1313 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1314 return (const void *)
1315 borrow_named_field_class_from_container_field_class_at_index(
1316 (void *) fc
, index
);
1319 const struct bt_field_class_variant_with_unsigned_selector_option
*
1320 bt_field_class_variant_with_unsigned_selector_borrow_option_by_name_const(
1321 const struct bt_field_class
*fc
, const char *name
)
1323 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1324 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1325 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
,
1327 return (const void *)
1328 borrow_named_field_class_from_container_field_class_by_name(
1332 const struct bt_field_class_variant_with_unsigned_selector_option
*
1333 bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
1334 const struct bt_field_class
*fc
, uint64_t index
)
1336 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1337 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1338 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
,
1340 return (const void *)
1341 borrow_named_field_class_from_container_field_class_at_index(
1342 (void *) fc
, index
);
1345 const struct bt_field_class_variant_with_signed_selector_option
*
1346 bt_field_class_variant_with_signed_selector_borrow_option_by_name_const(
1347 const struct bt_field_class
*fc
, const char *name
)
1349 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1350 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1351 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1353 return (const void *)
1354 borrow_named_field_class_from_container_field_class_by_name(
1358 const struct bt_field_class_variant_with_signed_selector_option
*
1359 bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
1360 const struct bt_field_class
*fc
, uint64_t index
)
1362 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1363 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1364 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1366 return (const void *)
1367 borrow_named_field_class_from_container_field_class_at_index(
1368 (void *) fc
, index
);
1371 const char *bt_field_class_variant_option_get_name(
1372 const struct bt_field_class_variant_option
*option
)
1374 const struct bt_named_field_class
*named_fc
= (const void *) option
;
1376 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1377 return named_fc
->name
->str
;
1380 const struct bt_field_class
*
1381 bt_field_class_variant_option_borrow_field_class_const(
1382 const struct bt_field_class_variant_option
*option
)
1384 const struct bt_named_field_class
*named_fc
= (const void *) option
;
1386 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1387 return named_fc
->fc
;
1390 const struct bt_integer_range_set_unsigned
*
1391 bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
1392 const struct bt_field_class_variant_with_unsigned_selector_option
*option
)
1394 const struct bt_field_class_variant_with_selector_option
*opt
=
1395 (const void *) option
;
1397 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1398 return (const void *) opt
->range_set
;
1401 const struct bt_integer_range_set_signed
*
1402 bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
1403 const struct bt_field_class_variant_with_signed_selector_option
*option
)
1405 const struct bt_field_class_variant_with_selector_option
*opt
=
1406 (const void *) option
;
1408 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1409 return (const void *) opt
->range_set
;
1412 const struct bt_field_path
*
1413 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
1414 const struct bt_field_class
*fc
)
1416 const struct bt_field_class_variant_with_selector
*var_fc
=
1419 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1420 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL(fc
, "Field class");
1421 return var_fc
->selector_field_path
;
1425 void init_array_field_class(struct bt_field_class_array
*fc
,
1426 enum bt_field_class_type type
, bt_object_release_func release_func
,
1427 struct bt_field_class
*element_fc
)
1429 BT_ASSERT(element_fc
);
1430 init_field_class((void *) fc
, type
, release_func
);
1431 fc
->element_fc
= element_fc
;
1432 bt_object_get_no_null_check(fc
->element_fc
);
1433 bt_field_class_freeze(element_fc
);
1437 void finalize_array_field_class(struct bt_field_class_array
*array_fc
)
1439 BT_ASSERT(array_fc
);
1440 BT_LOGD_STR("Putting element field class.");
1441 BT_OBJECT_PUT_REF_AND_RESET(array_fc
->element_fc
);
1445 void destroy_static_array_field_class(struct bt_object
*obj
)
1448 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj
);
1449 finalize_array_field_class((void *) obj
);
1453 struct bt_field_class
*
1454 bt_field_class_static_array_create(bt_trace_class
*trace_class
,
1455 struct bt_field_class
*element_fc
, uint64_t length
)
1457 struct bt_field_class_static_array
*array_fc
= NULL
;
1459 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1460 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1461 BT_LOGD_STR("Creating default static array field class object.");
1462 array_fc
= g_new0(struct bt_field_class_static_array
, 1);
1464 BT_LIB_LOGE_APPEND_CAUSE(
1465 "Failed to allocate one static array field class.");
1469 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1470 destroy_static_array_field_class
, element_fc
);
1471 array_fc
->length
= length
;
1472 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc
);
1476 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1479 return (void *) array_fc
;
1482 const struct bt_field_class
*
1483 bt_field_class_array_borrow_element_field_class_const(
1484 const struct bt_field_class
*fc
)
1486 const struct bt_field_class_array
*array_fc
= (const void *) fc
;
1488 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1489 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc
, "Field class");
1490 return array_fc
->element_fc
;
1493 struct bt_field_class
*
1494 bt_field_class_array_borrow_element_field_class(struct bt_field_class
*fc
)
1496 struct bt_field_class_array
*array_fc
= (void *) fc
;
1498 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1499 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc
, "Field class");
1500 return array_fc
->element_fc
;
1503 uint64_t bt_field_class_static_array_get_length(const struct bt_field_class
*fc
)
1505 const struct bt_field_class_static_array
*array_fc
= (const void *) fc
;
1507 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1508 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1510 return (uint64_t) array_fc
->length
;
1514 void destroy_dynamic_array_field_class(struct bt_object
*obj
)
1516 struct bt_field_class_dynamic_array
*fc
= (void *) obj
;
1519 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc
);
1520 finalize_array_field_class((void *) fc
);
1521 BT_LOGD_STR("Putting length field path.");
1522 BT_OBJECT_PUT_REF_AND_RESET(fc
->length_field_path
);
1523 BT_LOGD_STR("Putting length field class.");
1524 BT_OBJECT_PUT_REF_AND_RESET(fc
->length_fc
);
1528 struct bt_field_class
*bt_field_class_dynamic_array_create(
1529 struct bt_trace_class
*trace_class
,
1530 struct bt_field_class
*element_fc
,
1531 struct bt_field_class
*length_fc
)
1533 struct bt_field_class_dynamic_array
*array_fc
= NULL
;
1535 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1536 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1537 BT_LOGD_STR("Creating default dynamic array field class object.");
1538 array_fc
= g_new0(struct bt_field_class_dynamic_array
, 1);
1540 BT_LIB_LOGE_APPEND_CAUSE(
1541 "Failed to allocate one dynamic array field class.");
1545 init_array_field_class((void *) array_fc
,
1546 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1547 destroy_dynamic_array_field_class
, element_fc
);
1550 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc
,
1551 "Length field class");
1552 array_fc
->length_fc
= length_fc
;
1553 bt_object_get_no_null_check(array_fc
->length_fc
);
1554 bt_field_class_freeze(length_fc
);
1557 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc
);
1561 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1564 return (void *) array_fc
;
1567 const struct bt_field_path
*
1568 bt_field_class_dynamic_array_borrow_length_field_path_const(
1569 const struct bt_field_class
*fc
)
1571 const struct bt_field_class_dynamic_array
*seq_fc
= (const void *) fc
;
1573 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1574 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1576 return seq_fc
->length_field_path
;
1580 void destroy_string_field_class(struct bt_object
*obj
)
1583 BT_LIB_LOGD("Destroying string field class object: %!+F", obj
);
1587 struct bt_field_class
*bt_field_class_string_create(bt_trace_class
*trace_class
)
1589 struct bt_field_class_string
*string_fc
= NULL
;
1591 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1592 BT_LOGD_STR("Creating default string field class object.");
1593 string_fc
= g_new0(struct bt_field_class_string
, 1);
1595 BT_LIB_LOGE_APPEND_CAUSE(
1596 "Failed to allocate one string field class.");
1600 init_field_class((void *) string_fc
, BT_FIELD_CLASS_TYPE_STRING
,
1601 destroy_string_field_class
);
1602 BT_LIB_LOGD("Created string field class object: %!+F", string_fc
);
1606 BT_OBJECT_PUT_REF_AND_RESET(string_fc
);
1609 return (void *) string_fc
;
1613 void _bt_field_class_freeze(const struct bt_field_class
*c_fc
)
1615 struct bt_field_class
*fc
= (void *) c_fc
;
1618 * Element/member/option field classes are frozen when added to
1625 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1626 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
:
1627 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
:
1628 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
:
1630 struct bt_field_class_named_field_class_container
*container_fc
=
1634 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1635 bt_named_field_class_freeze(
1636 container_fc
->named_fcs
->pdata
[i
]);
1647 void _bt_named_field_class_freeze(const struct bt_named_field_class
*named_fc
)
1649 BT_ASSERT(named_fc
);
1650 ((struct bt_named_field_class
*) named_fc
)->frozen
= true;
1651 bt_field_class_freeze(named_fc
->fc
);
1655 void bt_field_class_make_part_of_trace_class(const struct bt_field_class
*c_fc
)
1657 struct bt_field_class
*fc
= (void *) c_fc
;
1660 BT_ASSERT_PRE(!fc
->part_of_trace_class
,
1661 "Field class is already part of a trace: %!+F", fc
);
1662 fc
->part_of_trace_class
= true;
1665 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1666 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
:
1667 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
:
1668 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
:
1670 struct bt_field_class_named_field_class_container
*container_fc
=
1674 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1675 struct bt_named_field_class
*named_fc
=
1676 container_fc
->named_fcs
->pdata
[i
];
1678 bt_field_class_make_part_of_trace_class(named_fc
->fc
);
1683 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY
:
1684 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
:
1686 struct bt_field_class_array
*array_fc
= (void *) fc
;
1688 bt_field_class_make_part_of_trace_class(array_fc
->element_fc
);
1696 void bt_field_class_get_ref(const struct bt_field_class
*field_class
)
1698 bt_object_get_ref(field_class
);
1701 void bt_field_class_put_ref(const struct bt_field_class
*field_class
)
1703 bt_object_put_ref(field_class
);