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
;
138 bool size_is_valid_for_enumeration_field_class(struct bt_field_class
*fc
,
145 void bt_field_class_integer_set_field_value_range(
146 struct bt_field_class
*fc
, uint64_t size
)
148 struct bt_field_class_integer
*int_fc
= (void *) fc
;
150 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
151 BT_ASSERT_PRE_FC_IS_INT(fc
, "Field class");
152 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
153 BT_ASSERT_PRE(size
<= 64,
154 "Unsupported size for integer field class's field value range "
155 "(maximum is 64): size=%" PRIu64
, size
);
157 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
158 int_fc
->common
.type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
||
159 size_is_valid_for_enumeration_field_class(fc
, size
),
160 "Invalid field value range for enumeration field class: "
161 "at least one of the current mapping ranges contains values "
162 "which are outside this range: %!+F, size=%" PRIu64
, fc
, size
);
163 int_fc
->range
= size
;
164 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc
);
167 enum bt_field_class_integer_preferred_display_base
168 bt_field_class_integer_get_preferred_display_base(const struct bt_field_class
*fc
)
170 const struct bt_field_class_integer
*int_fc
= (const void *) fc
;
172 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
173 BT_ASSERT_PRE_DEV_FC_IS_INT(fc
, "Field class");
177 void bt_field_class_integer_set_preferred_display_base(
178 struct bt_field_class
*fc
,
179 enum bt_field_class_integer_preferred_display_base base
)
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");
187 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc
);
191 void finalize_enumeration_field_class_mapping(
192 struct bt_field_class_enumeration_mapping
*mapping
)
196 if (mapping
->label
) {
197 g_string_free(mapping
->label
, TRUE
);
198 mapping
->label
= NULL
;
201 BT_OBJECT_PUT_REF_AND_RESET(mapping
->range_set
);
205 void destroy_enumeration_field_class(struct bt_object
*obj
)
207 struct bt_field_class_enumeration
*fc
= (void *) obj
;
210 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc
);
215 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
216 finalize_enumeration_field_class_mapping(
217 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
));
220 g_array_free(fc
->mappings
, TRUE
);
225 g_ptr_array_free(fc
->label_buf
, TRUE
);
226 fc
->label_buf
= NULL
;
233 struct bt_field_class
*create_enumeration_field_class(
234 bt_trace_class
*trace_class
, enum bt_field_class_type type
)
236 struct bt_field_class_enumeration
*enum_fc
= NULL
;
238 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
239 BT_LOGD("Creating default enumeration field class object: type=%s",
240 bt_common_field_class_type_string(type
));
241 enum_fc
= g_new0(struct bt_field_class_enumeration
, 1);
243 BT_LIB_LOGE_APPEND_CAUSE(
244 "Failed to allocate one enumeration field class.");
248 init_integer_field_class((void *) enum_fc
, type
,
249 destroy_enumeration_field_class
);
250 enum_fc
->mappings
= g_array_new(FALSE
, TRUE
,
251 sizeof(struct bt_field_class_enumeration_mapping
));
252 if (!enum_fc
->mappings
) {
253 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
257 enum_fc
->label_buf
= g_ptr_array_new();
258 if (!enum_fc
->label_buf
) {
259 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
263 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc
);
267 BT_OBJECT_PUT_REF_AND_RESET(enum_fc
);
270 return (void *) enum_fc
;
273 struct bt_field_class
*bt_field_class_unsigned_enumeration_create(
274 bt_trace_class
*trace_class
)
276 return create_enumeration_field_class(trace_class
,
277 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
);
280 struct bt_field_class
*bt_field_class_signed_enumeration_create(
281 bt_trace_class
*trace_class
)
283 return create_enumeration_field_class(trace_class
,
284 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
);
287 uint64_t bt_field_class_enumeration_get_mapping_count(
288 const struct bt_field_class
*fc
)
290 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
292 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
293 BT_ASSERT_PRE_DEV_FC_IS_ENUM(fc
, "Field class");
294 return (uint64_t) enum_fc
->mappings
->len
;
297 const struct bt_field_class_unsigned_enumeration_mapping
*
298 bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
299 const struct bt_field_class
*fc
, uint64_t index
)
301 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
303 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
304 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, enum_fc
->mappings
->len
);
305 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
307 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
310 const struct bt_field_class_signed_enumeration_mapping
*
311 bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
312 const struct bt_field_class
*fc
, uint64_t index
)
314 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
316 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
317 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, enum_fc
->mappings
->len
);
318 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
320 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, index
);
324 const struct bt_field_class_enumeration_mapping
*
325 borrow_enumeration_field_class_mapping_by_label(
326 const struct bt_field_class_enumeration
*fc
, const char *label
)
328 struct bt_field_class_enumeration_mapping
*mapping
= NULL
;
332 BT_ASSERT_PRE_DEV_NON_NULL(label
, "Label");
334 for (i
= 0; i
< fc
->mappings
->len
; i
++) {
335 struct bt_field_class_enumeration_mapping
*this_mapping
=
336 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc
, i
);
338 if (strcmp(this_mapping
->label
->str
, label
) == 0) {
339 mapping
= this_mapping
;
348 const struct bt_field_class_signed_enumeration_mapping
*
349 bt_field_class_signed_enumeration_borrow_mapping_by_label_const(
350 const struct bt_field_class
*fc
, const char *label
)
352 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
353 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
355 return (const void *) borrow_enumeration_field_class_mapping_by_label(
356 (const void *) fc
, label
);
359 const struct bt_field_class_unsigned_enumeration_mapping
*
360 bt_field_class_unsigned_enumeration_borrow_mapping_by_label_const(
361 const struct bt_field_class
*fc
, const char *label
)
363 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
364 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
365 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
, "Field class");
366 return (const void *) borrow_enumeration_field_class_mapping_by_label(
367 (const void *) fc
, label
);
370 const char *bt_field_class_enumeration_mapping_get_label(
371 const struct bt_field_class_enumeration_mapping
*mapping
)
373 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
374 return mapping
->label
->str
;
377 const struct bt_integer_range_set_unsigned
*
378 bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
379 const struct bt_field_class_unsigned_enumeration_mapping
*u_mapping
)
381 const struct bt_field_class_enumeration_mapping
*mapping
=
382 (const void *) u_mapping
;
384 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
385 return (const void *) mapping
->range_set
;
388 const struct bt_integer_range_set_signed
*
389 bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
390 const struct bt_field_class_signed_enumeration_mapping
*s_mapping
)
392 const struct bt_field_class_enumeration_mapping
*mapping
=
393 (const void *) s_mapping
;
395 BT_ASSERT_PRE_DEV_NON_NULL(mapping
, "Enumeration field class mapping");
396 return (const void *) mapping
->range_set
;
399 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
400 bt_field_class_unsigned_enumeration_get_mapping_labels_for_value(
401 const struct bt_field_class
*fc
, uint64_t value
,
402 bt_field_class_enumeration_mapping_label_array
*label_array
,
405 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
408 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
409 BT_ASSERT_PRE_DEV_NON_NULL(label_array
, "Label array (output)");
410 BT_ASSERT_PRE_DEV_NON_NULL(count
, "Count (output)");
411 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
413 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
415 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
417 const struct bt_field_class_enumeration_mapping
*mapping
=
418 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
420 for (j
= 0; j
< mapping
->range_set
->ranges
->len
; j
++) {
421 const struct bt_integer_range
*range
= (const void *)
422 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
423 mapping
->range_set
, j
);
425 if (value
>= range
->lower
.u
&&
426 value
<= range
->upper
.u
) {
427 g_ptr_array_add(enum_fc
->label_buf
,
428 mapping
->label
->str
);
434 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
435 *count
= (uint64_t) enum_fc
->label_buf
->len
;
436 return BT_FUNC_STATUS_OK
;
439 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
440 bt_field_class_signed_enumeration_get_mapping_labels_for_value(
441 const struct bt_field_class
*fc
, int64_t value
,
442 bt_field_class_enumeration_mapping_label_array
*label_array
,
445 const struct bt_field_class_enumeration
*enum_fc
= (const void *) fc
;
448 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
449 BT_ASSERT_PRE_DEV_NON_NULL(label_array
, "Label array (output)");
450 BT_ASSERT_PRE_DEV_NON_NULL(count
, "Count (output)");
451 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
453 g_ptr_array_set_size(enum_fc
->label_buf
, 0);
455 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
457 const struct bt_field_class_enumeration_mapping
*mapping
=
458 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
460 for (j
= 0; j
< mapping
->range_set
->ranges
->len
; j
++) {
461 const struct bt_integer_range
*range
= (const void *)
462 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
463 mapping
->range_set
, j
);
465 if (value
>= range
->lower
.i
&&
466 value
<= range
->upper
.i
) {
467 g_ptr_array_add(enum_fc
->label_buf
,
468 mapping
->label
->str
);
474 *label_array
= (void *) enum_fc
->label_buf
->pdata
;
475 *count
= (uint64_t) enum_fc
->label_buf
->len
;
476 return BT_FUNC_STATUS_OK
;
480 bool enumeration_field_class_has_mapping_with_label(
481 const struct bt_field_class_enumeration
*enum_fc
,
490 for (i
= 0; i
< enum_fc
->mappings
->len
; i
++) {
491 struct bt_field_class_enumeration_mapping
*mapping_candidate
=
492 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc
, i
);
494 if (strcmp(mapping_candidate
->label
->str
, label
) == 0) {
505 enum bt_field_class_enumeration_add_mapping_status
506 add_mapping_to_enumeration_field_class(struct bt_field_class
*fc
,
507 const char *label
, const struct bt_integer_range_set
*range_set
)
509 enum bt_field_class_enumeration_add_mapping_status status
=
511 struct bt_field_class_enumeration
*enum_fc
= (void *) fc
;
512 struct bt_field_class_enumeration_mapping mapping
= { 0 };
515 BT_ASSERT_PRE_NON_NULL(label
, "Label");
516 BT_ASSERT_PRE_NON_NULL(range_set
, "Range set");
517 BT_ASSERT_PRE(!enumeration_field_class_has_mapping_with_label(
519 "Duplicate mapping name in enumeration field class: "
520 "%![enum-fc-]+F, label=\"%s\"", fc
, label
);
521 mapping
.range_set
= range_set
;
522 bt_object_get_ref(mapping
.range_set
);
523 mapping
.label
= g_string_new(label
);
524 if (!mapping
.label
) {
525 finalize_enumeration_field_class_mapping(&mapping
);
526 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
530 g_array_append_val(enum_fc
->mappings
, mapping
);
531 BT_LIB_LOGD("Added mapping to enumeration field class: "
532 "%![fc-]+F, label=\"%s\"", fc
, label
);
538 enum bt_field_class_enumeration_add_mapping_status
539 bt_field_class_unsigned_enumeration_add_mapping(
540 struct bt_field_class
*fc
, const char *label
,
541 const struct bt_integer_range_set_unsigned
*range_set
)
543 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
544 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
,
546 return add_mapping_to_enumeration_field_class(fc
, label
,
547 (const void *) range_set
);
550 enum bt_field_class_enumeration_add_mapping_status
551 bt_field_class_signed_enumeration_add_mapping(
552 struct bt_field_class
*fc
, const char *label
,
553 const struct bt_integer_range_set_signed
*range_set
)
555 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
556 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
,
558 return add_mapping_to_enumeration_field_class(fc
, label
,
559 (const void *) range_set
);
563 void destroy_real_field_class(struct bt_object
*obj
)
566 BT_LIB_LOGD("Destroying real field class object: %!+F", obj
);
570 struct bt_field_class
*bt_field_class_real_create(bt_trace_class
*trace_class
)
572 struct bt_field_class_real
*real_fc
= NULL
;
574 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
575 BT_LOGD_STR("Creating default real field class object.");
576 real_fc
= g_new0(struct bt_field_class_real
, 1);
578 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
582 init_field_class((void *) real_fc
, BT_FIELD_CLASS_TYPE_REAL
,
583 destroy_real_field_class
);
584 BT_LIB_LOGD("Created real field class object: %!+F", real_fc
);
588 BT_OBJECT_PUT_REF_AND_RESET(real_fc
);
591 return (void *) real_fc
;
594 bt_bool
bt_field_class_real_is_single_precision(const struct bt_field_class
*fc
)
596 const struct bt_field_class_real
*real_fc
= (const void *) fc
;
598 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
599 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
600 return real_fc
->is_single_precision
;
603 void bt_field_class_real_set_is_single_precision(struct bt_field_class
*fc
,
604 bt_bool is_single_precision
)
606 struct bt_field_class_real
*real_fc
= (void *) fc
;
608 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
609 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_REAL
, "Field class");
610 BT_ASSERT_PRE_DEV_FC_HOT(fc
, "Field class");
611 real_fc
->is_single_precision
= (bool) is_single_precision
;
612 BT_LIB_LOGD("Set real field class's \"is single precision\" property: "
617 int init_named_field_classes_container(
618 struct bt_field_class_named_field_class_container
*fc
,
619 enum bt_field_class_type type
,
620 bt_object_release_func fc_release_func
,
621 GDestroyNotify named_fc_destroy_func
)
625 init_field_class((void *) fc
, type
, fc_release_func
);
626 fc
->named_fcs
= g_ptr_array_new_with_free_func(named_fc_destroy_func
);
627 if (!fc
->named_fcs
) {
628 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
633 fc
->name_to_index
= g_hash_table_new(g_str_hash
, g_str_equal
);
634 if (!fc
->name_to_index
) {
635 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
645 void finalize_named_field_class(struct bt_named_field_class
*named_fc
)
648 BT_LIB_LOGD("Finalizing named field class: "
649 "addr=%p, name=\"%s\", %![fc-]+F",
650 named_fc
, named_fc
->name
? named_fc
->name
->str
: NULL
,
653 if (named_fc
->name
) {
654 g_string_free(named_fc
->name
, TRUE
);
655 named_fc
->name
= NULL
;
658 BT_LOGD_STR("Putting named field class's field class.");
659 BT_OBJECT_PUT_REF_AND_RESET(named_fc
->fc
);
663 void destroy_named_field_class(gpointer ptr
)
666 finalize_named_field_class(ptr
);
672 void destroy_variant_with_selector_option(gpointer ptr
)
674 struct bt_field_class_variant_with_selector_option
*opt
= ptr
;
677 finalize_named_field_class(&opt
->common
);
678 BT_OBJECT_PUT_REF_AND_RESET(opt
->range_set
);
684 void finalize_named_field_classes_container(
685 struct bt_field_class_named_field_class_container
*fc
)
690 g_ptr_array_free(fc
->named_fcs
, TRUE
);
691 fc
->named_fcs
= NULL
;
695 if (fc
->name_to_index
) {
696 g_hash_table_destroy(fc
->name_to_index
);
697 fc
->name_to_index
= NULL
;
702 void destroy_structure_field_class(struct bt_object
*obj
)
705 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj
);
706 finalize_named_field_classes_container((void *) obj
);
710 struct bt_field_class
*bt_field_class_structure_create(
711 bt_trace_class
*trace_class
)
714 struct bt_field_class_structure
*struct_fc
= NULL
;
716 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
717 BT_LOGD_STR("Creating default structure field class object.");
718 struct_fc
= g_new0(struct bt_field_class_structure
, 1);
720 BT_LIB_LOGE_APPEND_CAUSE(
721 "Failed to allocate one structure field class.");
725 ret
= init_named_field_classes_container((void *) struct_fc
,
726 BT_FIELD_CLASS_TYPE_STRUCTURE
, destroy_structure_field_class
,
727 destroy_named_field_class
);
729 /* init_named_field_classes_container() logs errors */
733 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc
);
737 BT_OBJECT_PUT_REF_AND_RESET(struct_fc
);
740 return (void *) struct_fc
;
744 int init_named_field_class(struct bt_named_field_class
*named_fc
,
745 const char *name
, struct bt_field_class
*fc
)
747 int status
= BT_FUNC_STATUS_OK
;
752 named_fc
->name
= g_string_new(name
);
753 if (!named_fc
->name
) {
754 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
755 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
760 bt_object_get_no_null_check(named_fc
->fc
);
761 bt_named_field_class_freeze(named_fc
);
768 struct bt_named_field_class
*create_named_field_class(const char *name
,
769 struct bt_field_class
*fc
)
771 struct bt_named_field_class
*named_fc
= g_new0(
772 struct bt_named_field_class
, 1);
775 BT_LIB_LOGE_APPEND_CAUSE(
776 "Failed to allocate a named field class.");
780 if (init_named_field_class(named_fc
, name
, fc
)) {
781 /* init_named_field_class() logs errors */
788 destroy_named_field_class(named_fc
);
796 struct bt_field_class_variant_with_selector_option
*
797 create_variant_with_selector_option(
798 const char *name
, struct bt_field_class
*fc
,
799 const struct bt_integer_range_set
*range_set
)
801 struct bt_field_class_variant_with_selector_option
*opt
= g_new0(
802 struct bt_field_class_variant_with_selector_option
, 1);
804 BT_ASSERT(range_set
);
807 BT_LIB_LOGE_APPEND_CAUSE(
808 "Failed to allocate a named field class.");
812 if (init_named_field_class(&opt
->common
, name
, fc
)) {
816 opt
->range_set
= range_set
;
817 bt_object_get_no_null_check(opt
->range_set
);
818 bt_integer_range_set_freeze(range_set
);
822 destroy_variant_with_selector_option(opt
);
830 int append_named_field_class_to_container_field_class(
831 struct bt_field_class_named_field_class_container
*container_fc
,
832 struct bt_named_field_class
*named_fc
)
834 BT_ASSERT(container_fc
);
836 BT_ASSERT_PRE_DEV_FC_HOT(container_fc
, "Field class");
837 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc
->name_to_index
,
838 named_fc
->name
->str
),
839 "Duplicate member/option name in structure/variant field class: "
840 "%![container-fc-]+F, name=\"%s\"", container_fc
,
841 named_fc
->name
->str
);
842 g_ptr_array_add(container_fc
->named_fcs
, named_fc
);
843 g_hash_table_insert(container_fc
->name_to_index
, named_fc
->name
->str
,
844 GUINT_TO_POINTER(container_fc
->named_fcs
->len
- 1));
845 return BT_FUNC_STATUS_OK
;
848 enum bt_field_class_structure_append_member_status
849 bt_field_class_structure_append_member(
850 struct bt_field_class
*fc
, const char *name
,
851 struct bt_field_class
*member_fc
)
853 enum bt_field_class_structure_append_member_status status
;
854 struct bt_named_field_class
*named_fc
= NULL
;
856 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
857 BT_ASSERT_PRE_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
859 named_fc
= create_named_field_class(name
, member_fc
);
861 /* create_named_field_class() logs errors */
862 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
866 status
= append_named_field_class_to_container_field_class((void *) fc
,
868 if (status
== BT_FUNC_STATUS_OK
) {
869 /* Moved to the container */
877 uint64_t bt_field_class_structure_get_member_count(
878 const struct bt_field_class
*fc
)
880 struct bt_field_class_structure
*struct_fc
= (void *) fc
;
882 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
883 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
885 return (uint64_t) struct_fc
->common
.named_fcs
->len
;
889 struct bt_named_field_class
*
890 borrow_named_field_class_from_container_field_class_at_index(
891 struct bt_field_class_named_field_class_container
*fc
,
895 BT_ASSERT_PRE_DEV_VALID_INDEX(index
, fc
->named_fcs
->len
);
896 return fc
->named_fcs
->pdata
[index
];
899 const struct bt_field_class_structure_member
*
900 bt_field_class_structure_borrow_member_by_index_const(
901 const struct bt_field_class
*fc
, uint64_t index
)
903 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
904 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
906 return (const void *)
907 borrow_named_field_class_from_container_field_class_at_index(
911 struct bt_field_class_structure_member
*
912 bt_field_class_structure_borrow_member_by_index(
913 struct bt_field_class
*fc
, uint64_t index
)
915 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
916 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
919 borrow_named_field_class_from_container_field_class_at_index(
924 struct bt_named_field_class
*
925 borrow_named_field_class_from_container_field_class_by_name(
926 struct bt_field_class_named_field_class_container
*fc
,
929 struct bt_named_field_class
*named_fc
= NULL
;
934 BT_ASSERT_PRE_DEV_NON_NULL(name
, "Name");
935 if (!g_hash_table_lookup_extended(fc
->name_to_index
, name
, &orig_key
,
940 named_fc
= fc
->named_fcs
->pdata
[GPOINTER_TO_UINT(value
)];
946 const struct bt_field_class_structure_member
*
947 bt_field_class_structure_borrow_member_by_name_const(
948 const struct bt_field_class
*fc
, const char *name
)
950 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
951 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
953 return (const void *)
954 borrow_named_field_class_from_container_field_class_by_name(
958 struct bt_field_class_structure_member
*
959 bt_field_class_structure_borrow_member_by_name(
960 struct bt_field_class
*fc
, const char *name
)
962 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
963 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STRUCTURE
,
966 borrow_named_field_class_from_container_field_class_by_name(
970 const char *bt_field_class_structure_member_get_name(
971 const struct bt_field_class_structure_member
*member
)
973 const struct bt_named_field_class
*named_fc
= (const void *) member
;
975 BT_ASSERT_PRE_DEV_NON_NULL(member
, "Structure field class member");
976 return named_fc
->name
->str
;
979 const struct bt_field_class
*
980 bt_field_class_structure_member_borrow_field_class_const(
981 const struct bt_field_class_structure_member
*member
)
983 const struct bt_named_field_class
*named_fc
= (const void *) member
;
985 BT_ASSERT_PRE_DEV_NON_NULL(member
, "Structure field class member");
990 void finalize_variant_field_class(struct bt_field_class_variant
*var_fc
)
993 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc
);
994 finalize_named_field_classes_container((void *) var_fc
);
998 void destroy_variant_field_class(struct bt_object
*obj
)
1000 struct bt_field_class_variant
*fc
= (void *) obj
;
1003 finalize_variant_field_class(fc
);
1008 void destroy_variant_with_selector_field_class(struct bt_object
*obj
)
1010 struct bt_field_class_variant_with_selector
*fc
= (void *) obj
;
1013 finalize_variant_field_class(&fc
->common
);
1014 BT_LOGD_STR("Putting selector field path.");
1015 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_field_path
);
1016 BT_LOGD_STR("Putting selector field class.");
1017 BT_OBJECT_PUT_REF_AND_RESET(fc
->selector_fc
);
1021 struct bt_field_class
*bt_field_class_variant_create(
1022 bt_trace_class
*trace_class
, bt_field_class
*selector_fc
)
1025 struct bt_field_class_variant
*var_fc
= NULL
;
1026 struct bt_field_class_variant_with_selector
*var_with_sel_fc
= NULL
;
1027 enum bt_field_class_type fc_type
;
1029 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1032 BT_ASSERT_PRE_FC_IS_INT(selector_fc
, "Selector field class");
1035 BT_LIB_LOGD("Creating default variant field class: %![sel-fc-]+F",
1039 var_with_sel_fc
= g_new0(
1040 struct bt_field_class_variant_with_selector
, 1);
1041 if (!var_with_sel_fc
) {
1042 BT_LIB_LOGE_APPEND_CAUSE(
1043 "Failed to allocate one variant field class with selector.");
1047 if (selector_fc
->type
== BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
||
1048 selector_fc
->type
== BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
) {
1049 fc_type
= BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
;
1051 fc_type
= BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
;
1054 ret
= init_named_field_classes_container(
1055 (void *) var_with_sel_fc
, fc_type
,
1056 destroy_variant_with_selector_field_class
,
1057 destroy_variant_with_selector_option
);
1059 /* init_named_field_classes_container() logs errors */
1063 var_with_sel_fc
->selector_fc
= selector_fc
;
1064 bt_object_get_no_null_check(var_with_sel_fc
->selector_fc
);
1065 bt_field_class_freeze(selector_fc
);
1066 var_fc
= (void *) var_with_sel_fc
;
1068 var_fc
= g_new0(struct bt_field_class_variant
, 1);
1070 BT_LIB_LOGE_APPEND_CAUSE(
1071 "Failed to allocate one variant field class without selector.");
1075 ret
= init_named_field_classes_container((void *) var_fc
,
1076 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
,
1077 destroy_variant_field_class
, destroy_named_field_class
);
1079 /* init_named_field_classes_container() logs errors */
1085 BT_LIB_LOGD("Created default variant field class with selector object: "
1086 "%![var-fc-]+F, %![sel-fc-]+F", var_fc
, selector_fc
);
1090 BT_OBJECT_PUT_REF_AND_RESET(var_fc
);
1093 return (void *) var_fc
;
1096 enum bt_field_class_variant_without_selector_append_option_status
1097 bt_field_class_variant_without_selector_append_option(struct bt_field_class
*fc
,
1098 const char *name
, struct bt_field_class
*option_fc
)
1100 enum bt_field_class_variant_without_selector_append_option_status status
;
1101 struct bt_named_field_class
*named_fc
= NULL
;
1103 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1104 BT_ASSERT_PRE_NON_NULL(name
, "Name");
1105 BT_ASSERT_PRE_NON_NULL(option_fc
, "Option field class");
1106 BT_ASSERT_PRE_FC_HAS_ID(fc
,
1107 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
, "Field class");
1108 named_fc
= create_named_field_class(name
, option_fc
);
1110 /* create_named_field_class() logs errors */
1111 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1115 status
= append_named_field_class_to_container_field_class((void *) fc
,
1117 if (status
== BT_FUNC_STATUS_OK
) {
1118 /* Moved to the container */
1124 destroy_named_field_class(named_fc
);
1131 int ranges_overlap(GPtrArray
*var_fc_opts
, const struct bt_integer_range_set
*range_set
,
1132 bool is_signed
, bool *has_overlap
)
1134 int status
= BT_FUNC_STATUS_OK
;
1135 struct bt_integer_range_set
*full_range_set
;
1138 *has_overlap
= false;
1141 * Build a single range set with all the ranges and test for
1145 full_range_set
= (void *) bt_integer_range_set_signed_create();
1147 full_range_set
= (void *) bt_integer_range_set_unsigned_create();
1150 if (!full_range_set
) {
1151 BT_LOGE_STR("Failed to create a range set.");
1152 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1156 /* Add existing option ranges */
1157 for (i
= 0; i
< var_fc_opts
->len
; i
++) {
1158 struct bt_field_class_variant_with_selector_option
*opt
=
1159 var_fc_opts
->pdata
[i
];
1162 for (j
= 0; j
< opt
->range_set
->ranges
->len
; j
++) {
1163 struct bt_integer_range
*range
= BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1167 status
= bt_integer_range_set_signed_add_range(
1168 (void *) full_range_set
, range
->lower
.i
,
1171 status
= bt_integer_range_set_unsigned_add_range(
1172 (void *) full_range_set
, range
->lower
.u
,
1182 /* Add new ranges */
1183 for (i
= 0; i
< range_set
->ranges
->len
; i
++) {
1184 struct bt_integer_range
*range
= BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1188 status
= bt_integer_range_set_signed_add_range(
1189 (void *) full_range_set
, range
->lower
.i
,
1192 status
= bt_integer_range_set_unsigned_add_range(
1193 (void *) full_range_set
, range
->lower
.u
,
1202 /* Check overlaps */
1204 *has_overlap
= bt_integer_range_set_signed_has_overlaps(full_range_set
);
1206 *has_overlap
= bt_integer_range_set_unsigned_has_overlaps(
1211 bt_object_put_ref(full_range_set
);
1216 int append_option_to_variant_with_selector_field_class(
1217 struct bt_field_class
*fc
, const char *name
,
1218 struct bt_field_class
*option_fc
,
1219 const struct bt_integer_range_set
*range_set
,
1220 enum bt_field_class_type expected_type
)
1223 struct bt_field_class_variant_with_selector
*var_fc
= (void *) fc
;
1224 struct bt_field_class_variant_with_selector_option
*opt
= NULL
;
1227 BT_ASSERT_PRE_NON_NULL(fc
, "Field class");
1228 BT_ASSERT_PRE_NON_NULL(name
, "Name");
1229 BT_ASSERT_PRE_NON_NULL(option_fc
, "Option field class");
1230 BT_ASSERT_PRE_NON_NULL(range_set
, "Range set");
1231 BT_ASSERT_PRE_FC_HAS_ID(fc
, expected_type
, "Field class");
1232 BT_ASSERT_PRE(range_set
->ranges
->len
> 0,
1233 "Range set is empty: addr=%p", range_set
);
1234 status
= ranges_overlap(var_fc
->common
.common
.named_fcs
, range_set
,
1235 expected_type
== BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1238 /* ranges_overlap() logs errors */
1242 BT_ASSERT_PRE(!has_overlap
,
1243 "Range set's ranges and existing ranges have an overlap: "
1244 "addr=%p", range_set
);
1245 opt
= create_variant_with_selector_option(name
, option_fc
, range_set
);
1247 /* create_variant_with_selector_option() logs errors */
1248 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
1252 status
= append_named_field_class_to_container_field_class((void *) fc
,
1254 if (status
== BT_FUNC_STATUS_OK
) {
1255 /* Moved to the container */
1261 destroy_variant_with_selector_option(opt
);
1267 enum bt_field_class_variant_with_selector_append_option_status
1268 bt_field_class_variant_with_unsigned_selector_append_option(
1269 struct bt_field_class
*fc
, const char *name
,
1270 struct bt_field_class
*option_fc
,
1271 const struct bt_integer_range_set_unsigned
*range_set
)
1273 return append_option_to_variant_with_selector_field_class(fc
,
1274 name
, option_fc
, (const void *) range_set
,
1275 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
);
1278 enum bt_field_class_variant_with_selector_append_option_status
1279 bt_field_class_variant_with_signed_selector_append_option(
1280 struct bt_field_class
*fc
, const char *name
,
1281 struct bt_field_class
*option_fc
,
1282 const struct bt_integer_range_set_signed
*range_set
)
1284 return append_option_to_variant_with_selector_field_class(fc
,
1285 name
, option_fc
, (const void *) range_set
,
1286 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
);
1289 uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class
*fc
)
1291 const struct bt_field_class_variant
*var_fc
= (const void *) fc
;
1293 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1294 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1295 return (uint64_t) var_fc
->common
.named_fcs
->len
;
1298 const struct bt_field_class_variant_option
*
1299 bt_field_class_variant_borrow_option_by_name_const(
1300 const struct bt_field_class
*fc
, const char *name
)
1302 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1303 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1304 return (const void *)
1305 borrow_named_field_class_from_container_field_class_by_name(
1309 const struct bt_field_class_variant_option
*
1310 bt_field_class_variant_borrow_option_by_index_const(
1311 const struct bt_field_class
*fc
, uint64_t index
)
1313 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1314 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc
, "Field class");
1315 return (const void *)
1316 borrow_named_field_class_from_container_field_class_at_index(
1317 (void *) fc
, index
);
1320 const struct bt_field_class_variant_with_unsigned_selector_option
*
1321 bt_field_class_variant_with_unsigned_selector_borrow_option_by_name_const(
1322 const struct bt_field_class
*fc
, const char *name
)
1324 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1325 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1326 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
,
1328 return (const void *)
1329 borrow_named_field_class_from_container_field_class_by_name(
1333 const struct bt_field_class_variant_with_unsigned_selector_option
*
1334 bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
1335 const struct bt_field_class
*fc
, uint64_t index
)
1337 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1338 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1339 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
,
1341 return (const void *)
1342 borrow_named_field_class_from_container_field_class_at_index(
1343 (void *) fc
, index
);
1346 const struct bt_field_class_variant_with_signed_selector_option
*
1347 bt_field_class_variant_with_signed_selector_borrow_option_by_name_const(
1348 const struct bt_field_class
*fc
, const char *name
)
1350 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1351 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1352 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1354 return (const void *)
1355 borrow_named_field_class_from_container_field_class_by_name(
1359 const struct bt_field_class_variant_with_signed_selector_option
*
1360 bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
1361 const struct bt_field_class
*fc
, uint64_t index
)
1363 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1364 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
,
1365 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
,
1367 return (const void *)
1368 borrow_named_field_class_from_container_field_class_at_index(
1369 (void *) fc
, index
);
1372 const char *bt_field_class_variant_option_get_name(
1373 const struct bt_field_class_variant_option
*option
)
1375 const struct bt_named_field_class
*named_fc
= (const void *) option
;
1377 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1378 return named_fc
->name
->str
;
1381 const struct bt_field_class
*
1382 bt_field_class_variant_option_borrow_field_class_const(
1383 const struct bt_field_class_variant_option
*option
)
1385 const struct bt_named_field_class
*named_fc
= (const void *) option
;
1387 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1388 return named_fc
->fc
;
1391 const struct bt_integer_range_set_unsigned
*
1392 bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
1393 const struct bt_field_class_variant_with_unsigned_selector_option
*option
)
1395 const struct bt_field_class_variant_with_selector_option
*opt
=
1396 (const void *) option
;
1398 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1399 return (const void *) opt
->range_set
;
1402 const struct bt_integer_range_set_signed
*
1403 bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
1404 const struct bt_field_class_variant_with_signed_selector_option
*option
)
1406 const struct bt_field_class_variant_with_selector_option
*opt
=
1407 (const void *) option
;
1409 BT_ASSERT_PRE_DEV_NON_NULL(option
, "Variant field class option");
1410 return (const void *) opt
->range_set
;
1413 const struct bt_field_path
*
1414 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
1415 const struct bt_field_class
*fc
)
1417 const struct bt_field_class_variant_with_selector
*var_fc
=
1420 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1421 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL(fc
, "Field class");
1422 return var_fc
->selector_field_path
;
1426 void init_array_field_class(struct bt_field_class_array
*fc
,
1427 enum bt_field_class_type type
, bt_object_release_func release_func
,
1428 struct bt_field_class
*element_fc
)
1430 BT_ASSERT(element_fc
);
1431 init_field_class((void *) fc
, type
, release_func
);
1432 fc
->element_fc
= element_fc
;
1433 bt_object_get_no_null_check(fc
->element_fc
);
1434 bt_field_class_freeze(element_fc
);
1438 void finalize_array_field_class(struct bt_field_class_array
*array_fc
)
1440 BT_ASSERT(array_fc
);
1441 BT_LOGD_STR("Putting element field class.");
1442 BT_OBJECT_PUT_REF_AND_RESET(array_fc
->element_fc
);
1446 void destroy_static_array_field_class(struct bt_object
*obj
)
1449 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj
);
1450 finalize_array_field_class((void *) obj
);
1454 struct bt_field_class
*
1455 bt_field_class_static_array_create(bt_trace_class
*trace_class
,
1456 struct bt_field_class
*element_fc
, uint64_t length
)
1458 struct bt_field_class_static_array
*array_fc
= NULL
;
1460 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1461 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1462 BT_LOGD_STR("Creating default static array field class object.");
1463 array_fc
= g_new0(struct bt_field_class_static_array
, 1);
1465 BT_LIB_LOGE_APPEND_CAUSE(
1466 "Failed to allocate one static array field class.");
1470 init_array_field_class((void *) array_fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1471 destroy_static_array_field_class
, element_fc
);
1472 array_fc
->length
= length
;
1473 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc
);
1477 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1480 return (void *) array_fc
;
1483 const struct bt_field_class
*
1484 bt_field_class_array_borrow_element_field_class_const(
1485 const struct bt_field_class
*fc
)
1487 const struct bt_field_class_array
*array_fc
= (const void *) fc
;
1489 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1490 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc
, "Field class");
1491 return array_fc
->element_fc
;
1494 struct bt_field_class
*
1495 bt_field_class_array_borrow_element_field_class(struct bt_field_class
*fc
)
1497 struct bt_field_class_array
*array_fc
= (void *) fc
;
1499 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1500 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc
, "Field class");
1501 return array_fc
->element_fc
;
1504 uint64_t bt_field_class_static_array_get_length(const struct bt_field_class
*fc
)
1506 const struct bt_field_class_static_array
*array_fc
= (const void *) fc
;
1508 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1509 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_STATIC_ARRAY
,
1511 return (uint64_t) array_fc
->length
;
1515 void destroy_dynamic_array_field_class(struct bt_object
*obj
)
1517 struct bt_field_class_dynamic_array
*fc
= (void *) obj
;
1520 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc
);
1521 finalize_array_field_class((void *) fc
);
1522 BT_LOGD_STR("Putting length field path.");
1523 BT_OBJECT_PUT_REF_AND_RESET(fc
->length_field_path
);
1524 BT_LOGD_STR("Putting length field class.");
1525 BT_OBJECT_PUT_REF_AND_RESET(fc
->length_fc
);
1529 struct bt_field_class
*bt_field_class_dynamic_array_create(
1530 struct bt_trace_class
*trace_class
,
1531 struct bt_field_class
*element_fc
,
1532 struct bt_field_class
*length_fc
)
1534 struct bt_field_class_dynamic_array
*array_fc
= NULL
;
1536 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1537 BT_ASSERT_PRE_NON_NULL(element_fc
, "Element field class");
1538 BT_LOGD_STR("Creating default dynamic array field class object.");
1539 array_fc
= g_new0(struct bt_field_class_dynamic_array
, 1);
1541 BT_LIB_LOGE_APPEND_CAUSE(
1542 "Failed to allocate one dynamic array field class.");
1546 init_array_field_class((void *) array_fc
,
1547 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1548 destroy_dynamic_array_field_class
, element_fc
);
1551 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc
,
1552 "Length field class");
1553 array_fc
->length_fc
= length_fc
;
1554 bt_object_get_no_null_check(array_fc
->length_fc
);
1555 bt_field_class_freeze(length_fc
);
1558 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc
);
1562 BT_OBJECT_PUT_REF_AND_RESET(array_fc
);
1565 return (void *) array_fc
;
1568 const struct bt_field_path
*
1569 bt_field_class_dynamic_array_borrow_length_field_path_const(
1570 const struct bt_field_class
*fc
)
1572 const struct bt_field_class_dynamic_array
*seq_fc
= (const void *) fc
;
1574 BT_ASSERT_PRE_DEV_NON_NULL(fc
, "Field class");
1575 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc
, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
,
1577 return seq_fc
->length_field_path
;
1581 void destroy_string_field_class(struct bt_object
*obj
)
1584 BT_LIB_LOGD("Destroying string field class object: %!+F", obj
);
1588 struct bt_field_class
*bt_field_class_string_create(bt_trace_class
*trace_class
)
1590 struct bt_field_class_string
*string_fc
= NULL
;
1592 BT_ASSERT_PRE_NON_NULL(trace_class
, "Trace class");
1593 BT_LOGD_STR("Creating default string field class object.");
1594 string_fc
= g_new0(struct bt_field_class_string
, 1);
1596 BT_LIB_LOGE_APPEND_CAUSE(
1597 "Failed to allocate one string field class.");
1601 init_field_class((void *) string_fc
, BT_FIELD_CLASS_TYPE_STRING
,
1602 destroy_string_field_class
);
1603 BT_LIB_LOGD("Created string field class object: %!+F", string_fc
);
1607 BT_OBJECT_PUT_REF_AND_RESET(string_fc
);
1610 return (void *) string_fc
;
1614 void _bt_field_class_freeze(const struct bt_field_class
*c_fc
)
1616 struct bt_field_class
*fc
= (void *) c_fc
;
1619 * Element/member/option field classes are frozen when added to
1626 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1627 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
:
1628 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
:
1629 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
:
1631 struct bt_field_class_named_field_class_container
*container_fc
=
1635 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1636 bt_named_field_class_freeze(
1637 container_fc
->named_fcs
->pdata
[i
]);
1648 void _bt_named_field_class_freeze(const struct bt_named_field_class
*named_fc
)
1650 BT_ASSERT(named_fc
);
1651 ((struct bt_named_field_class
*) named_fc
)->frozen
= true;
1652 bt_field_class_freeze(named_fc
->fc
);
1656 void bt_field_class_make_part_of_trace_class(const struct bt_field_class
*c_fc
)
1658 struct bt_field_class
*fc
= (void *) c_fc
;
1661 BT_ASSERT_PRE(!fc
->part_of_trace_class
,
1662 "Field class is already part of a trace: %!+F", fc
);
1663 fc
->part_of_trace_class
= true;
1666 case BT_FIELD_CLASS_TYPE_STRUCTURE
:
1667 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR
:
1668 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR
:
1669 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR
:
1671 struct bt_field_class_named_field_class_container
*container_fc
=
1675 for (i
= 0; i
< container_fc
->named_fcs
->len
; i
++) {
1676 struct bt_named_field_class
*named_fc
=
1677 container_fc
->named_fcs
->pdata
[i
];
1679 bt_field_class_make_part_of_trace_class(named_fc
->fc
);
1684 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY
:
1685 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY
:
1687 struct bt_field_class_array
*array_fc
= (void *) fc
;
1689 bt_field_class_make_part_of_trace_class(array_fc
->element_fc
);
1697 void bt_field_class_get_ref(const struct bt_field_class
*field_class
)
1699 bt_object_get_ref(field_class
);
1702 void bt_field_class_put_ref(const struct bt_field_class
*field_class
)
1704 bt_object_put_ref(field_class
);