1 #ifndef BABELTRACE_CTF_IR_FIELDS_INTERNAL_H
2 #define BABELTRACE_CTF_IR_FIELDS_INTERNAL_H
5 * Babeltrace - CTF IR: Event Fields internal
7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include <babeltrace/assert-pre-internal.h>
31 #include <babeltrace/common-internal.h>
32 #include <babeltrace/ctf-ir/field-types-internal.h>
33 #include <babeltrace/ctf-ir/utils-internal.h>
34 #include <babeltrace/object-internal.h>
35 #include <babeltrace/babeltrace-internal.h>
36 #include <babeltrace/types.h>
42 #define BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(_field, _type_id, _name) \
43 BT_ASSERT_PRE((_field)->type->id == (_type_id), \
44 _name " has the wrong type ID: expected-type-id=%s, " \
45 "%![field-]+_f", bt_common_field_type_id_string(_type_id), \
48 #define BT_ASSERT_PRE_FIELD_COMMON_IS_SET(_field, _name) \
49 BT_ASSERT_PRE(bt_field_common_is_set_recursive(_field), \
50 _name " is not set: %!+_f", (_field))
52 #define BT_ASSERT_PRE_FIELD_COMMON_HOT(_field, _name) \
53 BT_ASSERT_PRE_HOT((_field), (_name), ": +%!+_f", (_field))
56 struct bt_field_common
;
58 typedef void (*bt_field_common_method_freeze
)(struct bt_field_common
*);
59 typedef int (*bt_field_common_method_validate
)(struct bt_field_common
*);
60 typedef struct bt_field_common
*(*bt_field_common_method_copy
)(
61 struct bt_field_common
*);
62 typedef bt_bool (*bt_field_common_method_is_set
)(struct bt_field_common
*);
63 typedef void (*bt_field_common_method_reset
)(struct bt_field_common
*);
65 struct bt_field_common_methods
{
66 bt_field_common_method_freeze freeze
;
67 bt_field_common_method_validate validate
;
68 bt_field_common_method_copy copy
;
69 bt_field_common_method_is_set is_set
;
70 bt_field_common_method_reset reset
;
73 struct bt_field_common
{
74 struct bt_object base
;
75 struct bt_field_type_common
*type
;
76 struct bt_field_common_methods
*methods
;
81 * Specialized data for either CTF IR or CTF writer APIs.
82 * See comment in `field-types-internal.h` for more details.
93 struct bt_field_common_integer
{
94 struct bt_field_common common
;
101 struct bt_field_common_enumeration
{
102 struct bt_field_common common
;
103 struct bt_field_common
*payload
;
106 struct bt_field_common_floating_point
{
107 struct bt_field_common common
;
111 struct bt_field_common_structure
{
112 struct bt_field_common common
;
113 GPtrArray
*fields
; /* Array of pointers to struct bt_field_common */
116 struct bt_field_common_variant
{
117 struct bt_field_common common
;
118 struct bt_field_common
*tag
;
119 struct bt_field_common
*payload
;
122 struct bt_field_common_array
{
123 struct bt_field_common common
;
124 GPtrArray
*elements
; /* Array of pointers to struct bt_field_common */
127 struct bt_field_common_sequence
{
128 struct bt_field_common common
;
129 struct bt_field_common
*length
;
130 GPtrArray
*elements
; /* Array of pointers to struct bt_field_common */
133 struct bt_field_common_string
{
134 struct bt_field_common common
;
139 struct bt_field_type
*bt_field_borrow_type(struct bt_field
*field
)
141 struct bt_field_common
*field_common
= (void *) field
;
144 return (void *) field_common
->type
;
148 int64_t bt_field_sequence_get_int_length(struct bt_field
*field
);
151 struct bt_field_common
*bt_field_common_copy(struct bt_field_common
*field
);
154 int bt_field_common_structure_initialize(struct bt_field_common
*field
,
155 struct bt_field_type_common
*type
,
156 bt_object_release_func release_func
,
157 struct bt_field_common_methods
*methods
,
158 bt_field_common_create_func field_create_func
);
161 int bt_field_common_array_initialize(struct bt_field_common
*field
,
162 struct bt_field_type_common
*type
,
163 bt_object_release_func release_func
,
164 struct bt_field_common_methods
*methods
);
167 int bt_field_common_generic_validate(struct bt_field_common
*field
);
170 int bt_field_common_enumeration_validate_recursive(
171 struct bt_field_common
*field
);
174 int bt_field_common_structure_validate_recursive(struct bt_field_common
*field
);
177 int bt_field_common_variant_validate_recursive(struct bt_field_common
*field
);
180 int bt_field_common_array_validate_recursive(struct bt_field_common
*field
);
183 int bt_field_common_sequence_validate_recursive(struct bt_field_common
*field
);
186 void bt_field_common_generic_reset(struct bt_field_common
*field
);
189 void bt_field_common_enumeration_reset_recursive(struct bt_field_common
*field
);
192 void bt_field_common_structure_reset_recursive(struct bt_field_common
*field
);
195 void bt_field_common_variant_reset_recursive(struct bt_field_common
*field
);
198 void bt_field_common_array_reset_recursive(struct bt_field_common
*field
);
201 void bt_field_common_sequence_reset_recursive(struct bt_field_common
*field
);
204 void bt_field_common_string_reset(struct bt_field_common
*field
);
207 void bt_field_common_generic_freeze(struct bt_field_common
*field
);
210 void bt_field_common_enumeration_freeze_recursive(struct bt_field_common
*field
);
213 void bt_field_common_structure_freeze_recursive(struct bt_field_common
*field
);
216 void bt_field_common_variant_freeze_recursive(struct bt_field_common
*field
);
219 void bt_field_common_array_freeze_recursive(struct bt_field_common
*field
);
222 void bt_field_common_sequence_freeze_recursive(struct bt_field_common
*field
);
225 void _bt_field_common_freeze_recursive(struct bt_field_common
*field
);
228 bt_bool
bt_field_common_generic_is_set(struct bt_field_common
*field
);
231 bt_bool
bt_field_common_enumeration_is_set_recursive(
232 struct bt_field_common
*field
);
235 bt_bool
bt_field_common_structure_is_set_recursive(
236 struct bt_field_common
*field
);
239 bt_bool
bt_field_common_variant_is_set_recursive(struct bt_field_common
*field
);
242 bt_bool
bt_field_common_array_is_set_recursive(struct bt_field_common
*field
);
245 bt_bool
bt_field_common_sequence_is_set_recursive(struct bt_field_common
*field
);
248 void bt_field_common_integer_destroy(struct bt_object
*obj
);
251 void bt_field_common_enumeration_destroy_recursive(struct bt_object
*obj
);
254 void bt_field_common_floating_point_destroy(struct bt_object
*obj
);
257 void bt_field_common_structure_destroy_recursive(struct bt_object
*obj
);
260 void bt_field_common_variant_destroy_recursive(struct bt_object
*obj
);
263 void bt_field_common_array_destroy_recursive(struct bt_object
*obj
);
266 void bt_field_common_sequence_destroy_recursive(struct bt_object
*obj
);
269 void bt_field_common_string_destroy(struct bt_object
*obj
);
272 # define bt_field_common_validate_recursive _bt_field_common_validate_recursive
273 # define bt_field_common_freeze_recursive _bt_field_common_freeze_recursive
274 # define bt_field_common_is_set_recursive _bt_field_common_is_set_recursive
275 # define bt_field_common_reset_recursive _bt_field_common_reset_recursive
276 # define bt_field_common_set _bt_field_common_set
277 # define bt_field_validate_recursive _bt_field_validate_recursive
278 # define bt_field_freeze_recursive _bt_field_freeze_recursive
279 # define bt_field_is_set_recursive _bt_field_is_set_recursive
280 # define bt_field_reset_recursive _bt_field_reset_recursive
281 # define bt_field_set _bt_field_set
283 # define bt_field_common_validate_recursive(_field) (-1)
284 # define bt_field_common_freeze_recursive(_field)
285 # define bt_field_common_is_set_recursive(_field) (BT_FALSE)
286 # define bt_field_common_reset_recursive(_field) (BT_TRUE)
287 # define bt_field_common_set(_field, _val)
288 # define bt_field_validate_recursive(_field) (-1)
289 # define bt_field_freeze_recursive(_field)
290 # define bt_field_is_set_recursive(_field) (BT_FALSE)
291 # define bt_field_reset_recursive(_field) (BT_TRUE)
292 # define bt_field_set(_field, _val)
296 static inline bool field_type_common_has_known_id(
297 struct bt_field_type_common
*ft
)
299 return ft
->id
> BT_FIELD_TYPE_ID_UNKNOWN
||
300 ft
->id
< BT_FIELD_TYPE_ID_NR
;
304 int _bt_field_common_validate_recursive(struct bt_field_common
*field
)
309 BT_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
314 BT_ASSERT(field_type_common_has_known_id(field
->type
));
316 if (field
->methods
->validate
) {
317 ret
= field
->methods
->validate(field
);
325 void _bt_field_common_reset_recursive(struct bt_field_common
*field
)
328 BT_ASSERT(field
->methods
->reset
);
329 field
->methods
->reset(field
);
333 void _bt_field_common_set(struct bt_field_common
*field
, bool value
)
336 field
->payload_set
= value
;
340 bt_bool
_bt_field_common_is_set_recursive(struct bt_field_common
*field
)
342 bt_bool is_set
= BT_FALSE
;
348 BT_ASSERT(field_type_common_has_known_id(field
->type
));
349 BT_ASSERT(field
->methods
->is_set
);
350 is_set
= field
->methods
->is_set(field
);
357 void bt_field_common_initialize(struct bt_field_common
*field
,
358 struct bt_field_type_common
*ft
,
359 bt_object_release_func release_func
,
360 struct bt_field_common_methods
*methods
)
364 bt_object_init(field
, release_func
);
365 field
->methods
= methods
;
366 field
->type
= bt_get(ft
);
370 struct bt_field_type_common
*bt_field_common_get_type(
371 struct bt_field_common
*field
)
373 struct bt_field_type_common
*ret
= NULL
;
375 BT_ASSERT_PRE_NON_NULL(field
, "Field");
376 ret
= bt_get(field
->type
);
381 int64_t bt_field_common_sequence_get_int_length(struct bt_field_common
*field
)
383 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
387 BT_ASSERT(field
->type
->id
== BT_FIELD_TYPE_ID_SEQUENCE
);
388 if (!sequence
->length
) {
393 ret
= (int64_t) sequence
->elements
->len
;
400 struct bt_field_common
*bt_field_common_sequence_get_length(
401 struct bt_field_common
*field
)
403 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
405 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
406 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_SEQUENCE
,
408 return bt_get(sequence
->length
);
412 int bt_field_common_sequence_set_length(struct bt_field_common
*field
,
413 struct bt_field_common
*length_field
)
416 struct bt_field_common_integer
*length
= BT_FROM_COMMON(length_field
);
417 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
418 uint64_t sequence_length
;
420 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
421 BT_ASSERT_PRE_NON_NULL(length_field
, "Length field");
422 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Sequence field");
423 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(length_field
,
424 BT_FIELD_TYPE_ID_INTEGER
, "Length field");
426 !bt_field_type_common_integer_is_signed(length
->common
.type
),
427 "Length field's type is signed: %!+_f", length_field
);
428 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(length_field
, "Length field");
429 sequence_length
= length
->payload
.unsignd
;
430 if (sequence
->elements
) {
431 g_ptr_array_free(sequence
->elements
, TRUE
);
432 bt_put(sequence
->length
);
435 sequence
->elements
= g_ptr_array_sized_new((size_t) sequence_length
);
436 if (!sequence
->elements
) {
437 BT_LOGE_STR("Failed to allocate a GPtrArray.");
442 g_ptr_array_set_free_func(sequence
->elements
,
443 (GDestroyNotify
) bt_put
);
444 g_ptr_array_set_size(sequence
->elements
, (size_t) sequence_length
);
445 bt_get(length_field
);
446 sequence
->length
= length_field
;
447 bt_field_common_freeze_recursive(length_field
);
454 struct bt_field_common
*bt_field_common_structure_get_field_by_name(
455 struct bt_field_common
*field
, const char *name
)
457 struct bt_field_common
*ret
= NULL
;
459 struct bt_field_type_common_structure
*structure_ft
;
460 struct bt_field_common_structure
*structure
= BT_FROM_COMMON(field
);
462 GHashTable
*field_name_to_index
;
464 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
465 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
466 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
467 BT_FIELD_TYPE_ID_STRUCT
, "Field");
468 structure_ft
= BT_FROM_COMMON(field
->type
);
469 field_name_to_index
= structure_ft
->field_name_to_index
;
470 field_quark
= g_quark_from_string(name
);
471 if (!g_hash_table_lookup_extended(field_name_to_index
,
472 GUINT_TO_POINTER(field_quark
),
473 NULL
, (gpointer
*) &index
)) {
474 BT_LOGV("Invalid parameter: no such field in structure field's type: "
475 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
476 field
, field
->type
, name
);
480 ret
= bt_get(structure
->fields
->pdata
[index
]);
488 struct bt_field_common
*bt_field_common_structure_get_field_by_index(
489 struct bt_field_common
*field
, uint64_t index
)
491 struct bt_field_common_structure
*structure
= BT_FROM_COMMON(field
);
493 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
494 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
495 BT_FIELD_TYPE_ID_STRUCT
, "Field");
496 BT_ASSERT_PRE(index
< structure
->fields
->len
,
497 "Index is out of bound: %![struct-field-]+_f, "
498 "index=%" PRIu64
", count=%u", field
, index
,
499 structure
->fields
->len
);
500 return bt_get(structure
->fields
->pdata
[index
]);
504 static inline bool field_to_set_has_expected_type(
505 struct bt_field_common
*struct_field
,
506 const char *name
, struct bt_field_common
*value
)
509 struct bt_field_type_common
*expected_field_type
= NULL
;
511 expected_field_type
=
512 bt_field_type_common_structure_get_field_type_by_name(
513 struct_field
->type
, name
);
515 if (bt_field_type_common_compare(expected_field_type
, value
->type
)) {
516 BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
517 "%![value-ft-]+_F, %![expected-ft-]+_F", value
->type
,
518 expected_field_type
);
524 bt_put(expected_field_type
);
529 int bt_field_common_structure_set_field_by_name(struct bt_field_common
*field
,
530 const char *name
, struct bt_field_common
*value
)
534 struct bt_field_common_structure
*structure
= BT_FROM_COMMON(field
);
536 GHashTable
*field_name_to_index
;
537 struct bt_field_type_common_structure
*structure_ft
;
539 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
540 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
541 BT_ASSERT_PRE_NON_NULL(value
, "Value field");
542 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRUCT
,
544 BT_ASSERT_PRE(field_to_set_has_expected_type(field
, name
, value
),
545 "Value field's type is different from the expected field type.");
546 field_quark
= g_quark_from_string(name
);
547 structure_ft
= BT_FROM_COMMON(field
->type
);
548 field_name_to_index
= structure_ft
->field_name_to_index
;
549 if (!g_hash_table_lookup_extended(field_name_to_index
,
550 GUINT_TO_POINTER(field_quark
), NULL
,
551 (gpointer
*) &index
)) {
552 BT_LOGV("Invalid parameter: no such field in structure field's type: "
553 "struct-field-addr=%p, struct-ft-addr=%p, "
554 "field-ft-addr=%p, name=\"%s\"",
555 field
, field
->type
, value
->type
, name
);
560 BT_MOVE(structure
->fields
->pdata
[index
], value
);
567 struct bt_field_common
*bt_field_common_array_get_field(
568 struct bt_field_common
*field
, uint64_t index
,
569 bt_field_common_create_func field_create_func
)
571 struct bt_field_common
*new_field
= NULL
;
572 struct bt_field_type_common
*field_type
= NULL
;
573 struct bt_field_common_array
*array
= BT_FROM_COMMON(field
);
575 BT_ASSERT_PRE_NON_NULL(field
, "Array field");
576 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_ARRAY
, "Field");
577 BT_ASSERT_PRE(index
< array
->elements
->len
,
578 "Index is out of bound: %![array-field-]+_f, "
579 "index=%" PRIu64
", count=%u", field
,
580 index
, array
->elements
->len
);
582 field_type
= bt_field_type_common_array_get_element_field_type(
584 if (array
->elements
->pdata
[(size_t) index
]) {
585 new_field
= array
->elements
->pdata
[(size_t) index
];
589 /* We don't want to modify this field if it's frozen */
590 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Array field");
591 new_field
= field_create_func(field_type
);
592 array
->elements
->pdata
[(size_t) index
] = new_field
;
601 struct bt_field_common
*bt_field_common_sequence_get_field(
602 struct bt_field_common
*field
, uint64_t index
,
603 bt_field_common_create_func field_create_func
)
605 struct bt_field_common
*new_field
= NULL
;
606 struct bt_field_type_common
*field_type
= NULL
;
607 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
609 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
610 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_SEQUENCE
,
612 BT_ASSERT_PRE_NON_NULL(sequence
->elements
, "Sequence field's element array");
613 BT_ASSERT_PRE(index
< sequence
->elements
->len
,
614 "Index is out of bound: %![seq-field-]+_f, "
615 "index=%" PRIu64
", count=%u", field
, index
,
616 sequence
->elements
->len
);
617 field_type
= bt_field_type_common_sequence_get_element_field_type(
619 if (sequence
->elements
->pdata
[(size_t) index
]) {
620 new_field
= sequence
->elements
->pdata
[(size_t) index
];
624 /* We don't want to modify this field if it's frozen */
625 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Sequence field");
626 new_field
= field_create_func(field_type
);
627 sequence
->elements
->pdata
[(size_t) index
] = new_field
;
636 struct bt_field_common
*bt_field_common_enumeration_get_container(
637 struct bt_field_common
*field
,
638 bt_field_common_create_func field_create_func
)
640 struct bt_field_common_enumeration
*enumeration
= BT_FROM_COMMON(field
);
642 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
643 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
644 BT_FIELD_TYPE_ID_ENUM
, "Field");
646 if (!enumeration
->payload
) {
647 struct bt_field_type_common_enumeration
*enumeration_type
;
649 /* We don't want to modify this field if it's frozen */
650 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Enumeration field");
652 enumeration_type
= BT_FROM_COMMON(field
->type
);
653 enumeration
->payload
=
655 BT_TO_COMMON(enumeration_type
->container_ft
));
658 return bt_get(enumeration
->payload
);
662 struct bt_field_common
*bt_field_common_variant_get_field(
663 struct bt_field_common
*field
,
664 struct bt_field_common
*tag_field
,
665 bt_field_common_create_func field_create_func
)
667 struct bt_field_common
*new_field
= NULL
;
668 struct bt_field_common_variant
*variant
= BT_FROM_COMMON(field
);
669 struct bt_field_type_common_variant
*variant_type
;
670 struct bt_field_type_common
*field_type
;
671 struct bt_field_common
*tag_enum
= NULL
;
672 struct bt_field_common_integer
*tag_enum_integer
=
673 BT_FROM_COMMON(field
);
674 int64_t tag_enum_value
;
676 BT_ASSERT_PRE_NON_NULL(field
, "Variant field");
677 BT_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
678 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_VARIANT
,
680 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(tag_field
, BT_FIELD_TYPE_ID_ENUM
,
682 variant_type
= BT_FROM_COMMON(field
->type
);
683 tag_enum
= bt_field_common_enumeration_get_container(tag_field
,
685 BT_ASSERT_PRE_NON_NULL(tag_enum
, "Tag field's container");
686 tag_enum_integer
= BT_FROM_COMMON(tag_enum
);
687 BT_ASSERT_PRE(bt_field_common_validate_recursive(tag_field
) == 0,
688 "Tag field is invalid: %!+_f", tag_field
);
689 tag_enum_value
= tag_enum_integer
->payload
.signd
;
692 * If the variant currently has a tag and a payload, and if the
693 * requested tag value is the same as the current one, return
694 * the current payload instead of creating a fresh one.
696 if (variant
->tag
&& variant
->payload
) {
697 struct bt_field_common
*cur_tag_container
= NULL
;
698 struct bt_field_common_integer
*cur_tag_enum_integer
;
699 int64_t cur_tag_value
;
702 bt_field_common_enumeration_get_container(variant
->tag
,
704 BT_ASSERT(cur_tag_container
);
705 cur_tag_enum_integer
= BT_FROM_COMMON(cur_tag_container
);
706 bt_put(cur_tag_container
);
707 cur_tag_value
= cur_tag_enum_integer
->payload
.signd
;
709 if (cur_tag_value
== tag_enum_value
) {
710 new_field
= variant
->payload
;
716 /* We don't want to modify this field if it's frozen */
717 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Variant field");
718 field_type
= bt_field_type_common_variant_get_field_type_signed(
719 variant_type
, tag_enum_value
);
721 /* It's the caller's job to make sure the tag's value is valid */
722 BT_ASSERT_PRE(field_type
,
723 "Variant field's type does not contain a field type for "
724 "this tag value: tag-value-signed=%" PRId64
", "
725 "%![var-ft-]+_F, %![tag-field-]+_f", tag_enum_value
,
726 variant_type
, tag_field
);
728 new_field
= field_create_func(field_type
);
730 BT_LOGW("Cannot create field: "
731 "variant-field-addr=%p, variant-ft-addr=%p, "
732 "field-ft-addr=%p", field
, field
->type
, field_type
);
736 bt_put(variant
->tag
);
737 bt_put(variant
->payload
);
740 variant
->tag
= tag_field
;
741 variant
->payload
= new_field
;
749 struct bt_field_common
*bt_field_common_variant_get_current_field(
750 struct bt_field_common
*variant_field
)
752 struct bt_field_common_variant
*variant
= BT_FROM_COMMON(variant_field
);
754 BT_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
755 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
756 BT_FIELD_TYPE_ID_VARIANT
, "Field");
757 return bt_get(variant
->payload
);
761 struct bt_field_common
*bt_field_common_variant_get_tag(
762 struct bt_field_common
*variant_field
)
764 struct bt_field_common_variant
*variant
= BT_FROM_COMMON(variant_field
);
766 BT_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
767 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
768 BT_FIELD_TYPE_ID_VARIANT
, "Field");
769 return bt_get(variant
->tag
);
773 int bt_field_common_integer_signed_get_value(struct bt_field_common
*field
,
776 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
778 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
779 BT_ASSERT_PRE_NON_NULL(value
, "Value");
780 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "Integer field");
781 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
782 BT_FIELD_TYPE_ID_INTEGER
, "Field");
783 BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(field
->type
),
784 "Field's type is unsigned: %!+_f", field
);
785 *value
= integer
->payload
.signd
;
790 static inline bool value_is_in_range_signed(unsigned int size
, int64_t value
)
793 int64_t min_value
, max_value
;
795 min_value
= -(1ULL << (size
- 1));
796 max_value
= (1ULL << (size
- 1)) - 1;
797 if (value
< min_value
|| value
> max_value
) {
798 BT_LOGF("Value is out of bounds: value=%" PRId64
", "
799 "min-value=%" PRId64
", max-value=%" PRId64
,
800 value
, min_value
, max_value
);
808 int bt_field_common_integer_signed_set_value(struct bt_field_common
*field
,
812 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
813 struct bt_field_type_common_integer
*integer_type
;
815 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
816 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Integer field");
817 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
818 BT_FIELD_TYPE_ID_INTEGER
, "Field");
819 integer_type
= BT_FROM_COMMON(field
->type
);
820 BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(field
->type
),
821 "Field's type is unsigned: %!+_f", field
);
822 BT_ASSERT_PRE(value_is_in_range_signed(integer_type
->size
, value
),
823 "Value is out of bounds: value=%" PRId64
", %![field-]+_f",
825 integer
->payload
.signd
= value
;
826 bt_field_common_set(field
, true);
831 int bt_field_common_integer_unsigned_get_value(struct bt_field_common
*field
,
834 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
836 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
837 BT_ASSERT_PRE_NON_NULL(value
, "Value");
838 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "Integer field");
839 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
840 BT_FIELD_TYPE_ID_INTEGER
, "Field");
841 BT_ASSERT_PRE(!bt_field_type_common_integer_is_signed(field
->type
),
842 "Field's type is signed: %!+_f", field
);
843 *value
= integer
->payload
.unsignd
;
848 static inline bool value_is_in_range_unsigned(unsigned int size
, uint64_t value
)
853 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t) 1 << size
) - 1;
854 if (value
> max_value
) {
855 BT_LOGF("Value is out of bounds: value=%" PRIu64
", "
856 "max-value=%" PRIu64
,
865 int bt_field_common_integer_unsigned_set_value(struct bt_field_common
*field
,
868 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
869 struct bt_field_type_common_integer
*integer_type
;
871 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
872 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Integer field");
873 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
874 BT_FIELD_TYPE_ID_INTEGER
, "Field");
875 integer_type
= BT_FROM_COMMON(field
->type
);
876 BT_ASSERT_PRE(!bt_field_type_common_integer_is_signed(field
->type
),
877 "Field's type is signed: %!+_f", field
);
878 BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type
->size
, value
),
879 "Value is out of bounds: value=%" PRIu64
", %![field-]+_f",
881 integer
->payload
.unsignd
= value
;
882 bt_field_common_set(field
, true);
887 struct bt_field_type_enumeration_mapping_iterator
*
888 bt_field_common_enumeration_get_mappings(struct bt_field_common
*field
,
889 bt_field_common_create_func field_create_func
)
892 struct bt_field_common
*container
= NULL
;
893 struct bt_field_type_common_integer
*integer_type
= NULL
;
894 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
896 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
897 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
898 BT_FIELD_TYPE_ID_ENUM
, "Field");
899 container
= bt_field_common_enumeration_get_container(field
,
901 BT_ASSERT_PRE(container
,
902 "Enumeration field has no container field: %!+_f", field
);
903 BT_ASSERT(container
->type
);
904 integer_type
= BT_FROM_COMMON(container
->type
);
905 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(container
,
906 "Enumeration field's payload field");
908 if (!integer_type
->is_signed
) {
911 ret
= bt_field_common_integer_unsigned_get_value(container
,
914 iter
= bt_field_type_common_enumeration_unsigned_find_mappings_by_value(
919 ret
= bt_field_common_integer_signed_get_value(container
, &value
);
921 iter
= bt_field_type_common_enumeration_signed_find_mappings_by_value(
930 int bt_field_common_floating_point_get_value(struct bt_field_common
*field
,
933 struct bt_field_common_floating_point
*floating_point
=
934 BT_FROM_COMMON(field
);
936 BT_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
937 BT_ASSERT_PRE_NON_NULL(value
, "Value");
938 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "Floating point number field");
939 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
940 BT_FIELD_TYPE_ID_FLOAT
, "Field");
941 *value
= floating_point
->payload
;
946 int bt_field_common_floating_point_set_value(struct bt_field_common
*field
,
949 struct bt_field_common_floating_point
*floating_point
=
950 BT_FROM_COMMON(field
);
952 BT_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
953 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Floating point number field");
954 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
955 BT_FIELD_TYPE_ID_FLOAT
, "Field");
956 floating_point
->payload
= value
;
957 bt_field_common_set(field
, true);
962 const char *bt_field_common_string_get_value(struct bt_field_common
*field
)
964 struct bt_field_common_string
*string
= BT_FROM_COMMON(field
);
966 BT_ASSERT_PRE_NON_NULL(field
, "String field");
967 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "String field");
968 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
969 BT_FIELD_TYPE_ID_STRING
, "Field");
970 return string
->payload
->str
;
974 int bt_field_common_string_set_value(struct bt_field_common
*field
,
977 struct bt_field_common_string
*string
= BT_FROM_COMMON(field
);
979 BT_ASSERT_PRE_NON_NULL(field
, "String field");
980 BT_ASSERT_PRE_NON_NULL(value
, "Value");
981 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "String field");
982 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
983 BT_FIELD_TYPE_ID_STRING
, "Field");
985 if (string
->payload
) {
986 g_string_assign(string
->payload
, value
);
988 string
->payload
= g_string_new(value
);
991 bt_field_common_set(field
, true);
996 int bt_field_common_string_append(struct bt_field_common
*field
,
999 struct bt_field_common_string
*string_field
= BT_FROM_COMMON(field
);
1001 BT_ASSERT_PRE_NON_NULL(field
, "String field");
1002 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1003 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "String field");
1004 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
1005 BT_FIELD_TYPE_ID_STRING
, "Field");
1007 if (string_field
->payload
) {
1008 g_string_append(string_field
->payload
, value
);
1010 string_field
->payload
= g_string_new(value
);
1013 bt_field_common_set(field
, true);
1018 int bt_field_common_string_append_len(struct bt_field_common
*field
,
1019 const char *value
, unsigned int length
)
1021 struct bt_field_common_string
*string_field
= BT_FROM_COMMON(field
);
1023 BT_ASSERT_PRE_NON_NULL(field
, "String field");
1024 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1025 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "String field");
1026 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
1027 BT_FIELD_TYPE_ID_STRING
, "Field");
1029 /* make sure no null bytes are appended */
1030 BT_ASSERT_PRE(memchr(value
, '\0', length
) == NULL
,
1031 "String value to append contains a null character: "
1032 "partial-value=\"%.32s\", length=%u", value
, length
);
1034 if (string_field
->payload
) {
1035 g_string_append_len(string_field
->payload
, value
, length
);
1037 string_field
->payload
= g_string_new_len(value
, length
);
1040 bt_field_common_set(field
, true);
1045 int _bt_field_validate_recursive(struct bt_field
*field
)
1047 return _bt_field_common_validate_recursive((void *) field
);
1051 void _bt_field_freeze_recursive(struct bt_field
*field
)
1053 return _bt_field_common_freeze_recursive((void *) field
);
1057 bt_bool
_bt_field_is_set_recursive(struct bt_field
*field
)
1059 return _bt_field_common_is_set_recursive((void *) field
);
1063 void _bt_field_reset_recursive(struct bt_field
*field
)
1065 _bt_field_common_reset_recursive((void *) field
);
1069 void _bt_field_set(struct bt_field
*field
, bool value
)
1071 _bt_field_common_set((void *) field
, value
);
1074 #endif /* BABELTRACE_CTF_IR_FIELDS_INTERNAL_H */