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 int64_t bt_field_sequence_get_int_length(struct bt_field
*field
);
142 struct bt_field_common
*bt_field_common_copy(struct bt_field_common
*field
);
145 int bt_field_common_structure_initialize(struct bt_field_common
*field
,
146 struct bt_field_type_common
*type
,
147 bt_object_release_func release_func
,
148 struct bt_field_common_methods
*methods
,
149 bt_field_common_create_func field_create_func
);
152 int bt_field_common_array_initialize(struct bt_field_common
*field
,
153 struct bt_field_type_common
*type
,
154 bt_object_release_func release_func
,
155 struct bt_field_common_methods
*methods
);
158 int bt_field_common_generic_validate(struct bt_field_common
*field
);
161 int bt_field_common_enumeration_validate_recursive(
162 struct bt_field_common
*field
);
165 int bt_field_common_structure_validate_recursive(struct bt_field_common
*field
);
168 int bt_field_common_variant_validate_recursive(struct bt_field_common
*field
);
171 int bt_field_common_array_validate_recursive(struct bt_field_common
*field
);
174 int bt_field_common_sequence_validate_recursive(struct bt_field_common
*field
);
177 void bt_field_common_generic_reset(struct bt_field_common
*field
);
180 void bt_field_common_enumeration_reset_recursive(struct bt_field_common
*field
);
183 void bt_field_common_structure_reset_recursive(struct bt_field_common
*field
);
186 void bt_field_common_variant_reset_recursive(struct bt_field_common
*field
);
189 void bt_field_common_array_reset_recursive(struct bt_field_common
*field
);
192 void bt_field_common_sequence_reset_recursive(struct bt_field_common
*field
);
195 void bt_field_common_string_reset(struct bt_field_common
*field
);
198 void bt_field_common_generic_freeze(struct bt_field_common
*field
);
201 void bt_field_common_enumeration_freeze_recursive(struct bt_field_common
*field
);
204 void bt_field_common_structure_freeze_recursive(struct bt_field_common
*field
);
207 void bt_field_common_variant_freeze_recursive(struct bt_field_common
*field
);
210 void bt_field_common_array_freeze_recursive(struct bt_field_common
*field
);
213 void bt_field_common_sequence_freeze_recursive(struct bt_field_common
*field
);
216 void _bt_field_common_freeze_recursive(struct bt_field_common
*field
);
219 bt_bool
bt_field_common_generic_is_set(struct bt_field_common
*field
);
222 bt_bool
bt_field_common_enumeration_is_set_recursive(
223 struct bt_field_common
*field
);
226 bt_bool
bt_field_common_structure_is_set_recursive(
227 struct bt_field_common
*field
);
230 bt_bool
bt_field_common_variant_is_set_recursive(struct bt_field_common
*field
);
233 bt_bool
bt_field_common_array_is_set_recursive(struct bt_field_common
*field
);
236 bt_bool
bt_field_common_sequence_is_set_recursive(struct bt_field_common
*field
);
239 void bt_field_common_integer_destroy(struct bt_object
*obj
);
242 void bt_field_common_enumeration_destroy_recursive(struct bt_object
*obj
);
245 void bt_field_common_floating_point_destroy(struct bt_object
*obj
);
248 void bt_field_common_structure_destroy_recursive(struct bt_object
*obj
);
251 void bt_field_common_variant_destroy_recursive(struct bt_object
*obj
);
254 void bt_field_common_array_destroy_recursive(struct bt_object
*obj
);
257 void bt_field_common_sequence_destroy_recursive(struct bt_object
*obj
);
260 void bt_field_common_string_destroy(struct bt_object
*obj
);
263 # define bt_field_common_validate_recursive _bt_field_common_validate_recursive
264 # define bt_field_common_freeze_recursive _bt_field_common_freeze_recursive
265 # define bt_field_common_is_set_recursive _bt_field_common_is_set_recursive
266 # define bt_field_common_reset_recursive _bt_field_common_reset_recursive
267 # define bt_field_common_set _bt_field_common_set
268 # define bt_field_validate_recursive _bt_field_validate_recursive
269 # define bt_field_freeze_recursive _bt_field_freeze_recursive
270 # define bt_field_is_set_recursive _bt_field_is_set_recursive
271 # define bt_field_reset_recursive _bt_field_reset_recursive
272 # define bt_field_set _bt_field_set
274 # define bt_field_common_validate_recursive(_field) (-1)
275 # define bt_field_common_freeze_recursive(_field)
276 # define bt_field_common_is_set_recursive(_field) (BT_FALSE)
277 # define bt_field_common_reset_recursive(_field) (BT_TRUE)
278 # define bt_field_common_set(_field, _val)
279 # define bt_field_validate_recursive(_field) (-1)
280 # define bt_field_freeze_recursive(_field)
281 # define bt_field_is_set_recursive(_field) (BT_FALSE)
282 # define bt_field_reset_recursive(_field) (BT_TRUE)
283 # define bt_field_set(_field, _val)
287 static inline bool field_type_common_has_known_id(
288 struct bt_field_type_common
*ft
)
290 return ft
->id
> BT_FIELD_TYPE_ID_UNKNOWN
||
291 ft
->id
< BT_FIELD_TYPE_ID_NR
;
295 int _bt_field_common_validate_recursive(struct bt_field_common
*field
)
300 BT_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
305 BT_ASSERT(field_type_common_has_known_id(field
->type
));
307 if (field
->methods
->validate
) {
308 ret
= field
->methods
->validate(field
);
316 void _bt_field_common_reset_recursive(struct bt_field_common
*field
)
319 BT_ASSERT(field
->methods
->reset
);
320 field
->methods
->reset(field
);
324 void _bt_field_common_set(struct bt_field_common
*field
, bool value
)
327 field
->payload_set
= value
;
331 bt_bool
_bt_field_common_is_set_recursive(struct bt_field_common
*field
)
333 bt_bool is_set
= BT_FALSE
;
339 BT_ASSERT(field_type_common_has_known_id(field
->type
));
340 BT_ASSERT(field
->methods
->is_set
);
341 is_set
= field
->methods
->is_set(field
);
348 void bt_field_common_initialize(struct bt_field_common
*field
,
349 struct bt_field_type_common
*ft
,
350 bt_object_release_func release_func
,
351 struct bt_field_common_methods
*methods
)
355 bt_object_init(field
, release_func
);
356 field
->methods
= methods
;
357 field
->type
= bt_get(ft
);
361 struct bt_field_type_common
*bt_field_common_borrow_type(
362 struct bt_field_common
*field
)
364 struct bt_field_type_common
*ret
= NULL
;
366 BT_ASSERT_PRE_NON_NULL(field
, "Field");
372 int64_t bt_field_common_sequence_get_int_length(struct bt_field_common
*field
)
374 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
378 BT_ASSERT(field
->type
->id
== BT_FIELD_TYPE_ID_SEQUENCE
);
379 if (!sequence
->length
) {
384 ret
= (int64_t) sequence
->elements
->len
;
391 struct bt_field_common
*bt_field_common_sequence_borrow_length(
392 struct bt_field_common
*field
)
394 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
396 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
397 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_SEQUENCE
,
399 return sequence
->length
;
403 int bt_field_common_sequence_set_length(struct bt_field_common
*field
,
404 struct bt_field_common
*length_field
)
407 struct bt_field_common_integer
*length
= BT_FROM_COMMON(length_field
);
408 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
409 uint64_t sequence_length
;
411 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
412 BT_ASSERT_PRE_NON_NULL(length_field
, "Length field");
413 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Sequence field");
414 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(length_field
,
415 BT_FIELD_TYPE_ID_INTEGER
, "Length field");
417 !bt_field_type_common_integer_is_signed(length
->common
.type
),
418 "Length field's type is signed: %!+_f", length_field
);
419 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(length_field
, "Length field");
420 sequence_length
= length
->payload
.unsignd
;
421 if (sequence
->elements
) {
422 g_ptr_array_free(sequence
->elements
, TRUE
);
423 bt_put(sequence
->length
);
426 sequence
->elements
= g_ptr_array_sized_new((size_t) sequence_length
);
427 if (!sequence
->elements
) {
428 BT_LOGE_STR("Failed to allocate a GPtrArray.");
433 g_ptr_array_set_free_func(sequence
->elements
,
434 (GDestroyNotify
) bt_put
);
435 g_ptr_array_set_size(sequence
->elements
, (size_t) sequence_length
);
436 bt_get(length_field
);
437 sequence
->length
= length_field
;
438 bt_field_common_freeze_recursive(length_field
);
445 struct bt_field_common
*bt_field_common_structure_borrow_field_by_name(
446 struct bt_field_common
*field
, const char *name
)
448 struct bt_field_common
*ret
= NULL
;
450 struct bt_field_type_common_structure
*structure_ft
;
451 struct bt_field_common_structure
*structure
= BT_FROM_COMMON(field
);
453 GHashTable
*field_name_to_index
;
455 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
456 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
457 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
458 BT_FIELD_TYPE_ID_STRUCT
, "Field");
459 structure_ft
= BT_FROM_COMMON(field
->type
);
460 field_name_to_index
= structure_ft
->field_name_to_index
;
461 field_quark
= g_quark_from_string(name
);
462 if (!g_hash_table_lookup_extended(field_name_to_index
,
463 GUINT_TO_POINTER(field_quark
),
464 NULL
, (gpointer
*) &index
)) {
465 BT_LOGV("Invalid parameter: no such field in structure field's type: "
466 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
467 field
, field
->type
, name
);
471 ret
= structure
->fields
->pdata
[index
];
479 struct bt_field_common
*bt_field_common_structure_borrow_field_by_index(
480 struct bt_field_common
*field
, uint64_t index
)
482 struct bt_field_common_structure
*structure
= BT_FROM_COMMON(field
);
484 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
485 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
486 BT_FIELD_TYPE_ID_STRUCT
, "Field");
487 BT_ASSERT_PRE(index
< structure
->fields
->len
,
488 "Index is out of bound: %![struct-field-]+_f, "
489 "index=%" PRIu64
", count=%u", field
, index
,
490 structure
->fields
->len
);
491 return structure
->fields
->pdata
[index
];
495 static inline bool field_to_set_has_expected_type(
496 struct bt_field_common
*struct_field
,
497 const char *name
, struct bt_field_common
*value
)
500 struct bt_field_type_common
*expected_field_type
= NULL
;
502 expected_field_type
=
503 bt_field_type_common_structure_borrow_field_type_by_name(
504 struct_field
->type
, name
);
506 if (bt_field_type_common_compare(expected_field_type
, value
->type
)) {
507 BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
508 "%![value-ft-]+_F, %![expected-ft-]+_F", value
->type
,
509 expected_field_type
);
519 int bt_field_common_structure_set_field_by_name(struct bt_field_common
*field
,
520 const char *name
, struct bt_field_common
*value
)
524 struct bt_field_common_structure
*structure
= BT_FROM_COMMON(field
);
526 GHashTable
*field_name_to_index
;
527 struct bt_field_type_common_structure
*structure_ft
;
529 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
530 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
531 BT_ASSERT_PRE_NON_NULL(value
, "Value field");
532 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRUCT
,
534 BT_ASSERT_PRE(field_to_set_has_expected_type(field
, name
, value
),
535 "Value field's type is different from the expected field type.");
536 field_quark
= g_quark_from_string(name
);
537 structure_ft
= BT_FROM_COMMON(field
->type
);
538 field_name_to_index
= structure_ft
->field_name_to_index
;
539 if (!g_hash_table_lookup_extended(field_name_to_index
,
540 GUINT_TO_POINTER(field_quark
), NULL
,
541 (gpointer
*) &index
)) {
542 BT_LOGV("Invalid parameter: no such field in structure field's type: "
543 "struct-field-addr=%p, struct-ft-addr=%p, "
544 "field-ft-addr=%p, name=\"%s\"",
545 field
, field
->type
, value
->type
, name
);
550 BT_MOVE(structure
->fields
->pdata
[index
], value
);
557 struct bt_field_common
*bt_field_common_array_borrow_field(
558 struct bt_field_common
*field
, uint64_t index
,
559 bt_field_common_create_func field_create_func
)
561 struct bt_field_common
*new_field
= NULL
;
562 struct bt_field_type_common
*field_type
= NULL
;
563 struct bt_field_common_array
*array
= BT_FROM_COMMON(field
);
565 BT_ASSERT_PRE_NON_NULL(field
, "Array field");
566 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_ARRAY
, "Field");
567 BT_ASSERT_PRE(index
< array
->elements
->len
,
568 "Index is out of bound: %![array-field-]+_f, "
569 "index=%" PRIu64
", count=%u", field
,
570 index
, array
->elements
->len
);
572 field_type
= bt_field_type_common_array_borrow_element_field_type(
574 if (array
->elements
->pdata
[(size_t) index
]) {
575 new_field
= array
->elements
->pdata
[(size_t) index
];
579 /* We don't want to modify this field if it's frozen */
580 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Array field");
581 new_field
= field_create_func(field_type
);
582 array
->elements
->pdata
[(size_t) index
] = new_field
;
589 struct bt_field_common
*bt_field_common_sequence_borrow_field(
590 struct bt_field_common
*field
, uint64_t index
,
591 bt_field_common_create_func field_create_func
)
593 struct bt_field_common
*new_field
= NULL
;
594 struct bt_field_type_common
*field_type
= NULL
;
595 struct bt_field_common_sequence
*sequence
= BT_FROM_COMMON(field
);
597 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
598 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_SEQUENCE
,
600 BT_ASSERT_PRE_NON_NULL(sequence
->elements
, "Sequence field's element array");
601 BT_ASSERT_PRE(index
< sequence
->elements
->len
,
602 "Index is out of bound: %![seq-field-]+_f, "
603 "index=%" PRIu64
", count=%u", field
, index
,
604 sequence
->elements
->len
);
605 field_type
= bt_field_type_common_sequence_borrow_element_field_type(
607 if (sequence
->elements
->pdata
[(size_t) index
]) {
608 new_field
= sequence
->elements
->pdata
[(size_t) index
];
612 /* We don't want to modify this field if it's frozen */
613 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Sequence field");
614 new_field
= field_create_func(field_type
);
615 sequence
->elements
->pdata
[(size_t) index
] = new_field
;
622 struct bt_field_common
*bt_field_common_enumeration_borrow_container(
623 struct bt_field_common
*field
,
624 bt_field_common_create_func field_create_func
)
626 struct bt_field_common_enumeration
*enumeration
= BT_FROM_COMMON(field
);
628 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
629 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
630 BT_FIELD_TYPE_ID_ENUM
, "Field");
632 if (!enumeration
->payload
) {
633 struct bt_field_type_common_enumeration
*enumeration_type
;
635 /* We don't want to modify this field if it's frozen */
636 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Enumeration field");
638 enumeration_type
= BT_FROM_COMMON(field
->type
);
639 enumeration
->payload
=
641 BT_TO_COMMON(enumeration_type
->container_ft
));
644 return enumeration
->payload
;
648 struct bt_field_common
*bt_field_common_variant_borrow_field(
649 struct bt_field_common
*field
,
650 struct bt_field_common
*tag_field
,
651 bt_field_common_create_func field_create_func
)
653 struct bt_field_common
*new_field
= NULL
;
654 struct bt_field_common_variant
*variant
= BT_FROM_COMMON(field
);
655 struct bt_field_type_common_variant
*variant_type
;
656 struct bt_field_type_common
*field_type
;
657 struct bt_field_common
*tag_enum
= NULL
;
658 struct bt_field_common_integer
*tag_enum_integer
=
659 BT_FROM_COMMON(field
);
660 int64_t tag_enum_value
;
662 BT_ASSERT_PRE_NON_NULL(field
, "Variant field");
663 BT_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
664 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_VARIANT
,
666 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(tag_field
, BT_FIELD_TYPE_ID_ENUM
,
668 variant_type
= BT_FROM_COMMON(field
->type
);
669 tag_enum
= bt_field_common_enumeration_borrow_container(tag_field
,
671 BT_ASSERT_PRE_NON_NULL(tag_enum
, "Tag field's container");
672 tag_enum_integer
= BT_FROM_COMMON(tag_enum
);
673 BT_ASSERT_PRE(bt_field_common_validate_recursive(tag_field
) == 0,
674 "Tag field is invalid: %!+_f", tag_field
);
675 tag_enum_value
= tag_enum_integer
->payload
.signd
;
678 * If the variant currently has a tag and a payload, and if the
679 * requested tag value is the same as the current one, return
680 * the current payload instead of creating a fresh one.
682 if (variant
->tag
&& variant
->payload
) {
683 struct bt_field_common
*cur_tag_container
= NULL
;
684 struct bt_field_common_integer
*cur_tag_enum_integer
;
685 int64_t cur_tag_value
;
688 bt_field_common_enumeration_borrow_container(
689 variant
->tag
, field_create_func
);
690 BT_ASSERT(cur_tag_container
);
691 cur_tag_enum_integer
= BT_FROM_COMMON(cur_tag_container
);
692 cur_tag_value
= cur_tag_enum_integer
->payload
.signd
;
694 if (cur_tag_value
== tag_enum_value
) {
695 new_field
= variant
->payload
;
700 /* We don't want to modify this field if it's frozen */
701 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Variant field");
702 field_type
= bt_field_type_common_variant_borrow_field_type_signed(
703 variant_type
, tag_enum_value
);
705 /* It's the caller's job to make sure the tag's value is valid */
706 BT_ASSERT_PRE(field_type
,
707 "Variant field's type does not contain a field type for "
708 "this tag value: tag-value-signed=%" PRId64
", "
709 "%![var-ft-]+_F, %![tag-field-]+_f", tag_enum_value
,
710 variant_type
, tag_field
);
712 new_field
= field_create_func(field_type
);
714 BT_LOGW("Cannot create field: "
715 "variant-field-addr=%p, variant-ft-addr=%p, "
716 "field-ft-addr=%p", field
, field
->type
, field_type
);
720 bt_put(variant
->tag
);
721 bt_put(variant
->payload
);
722 variant
->tag
= bt_get(tag_field
);
723 variant
->payload
= new_field
;
730 struct bt_field_common
*bt_field_common_variant_borrow_current_field(
731 struct bt_field_common
*variant_field
)
733 struct bt_field_common_variant
*variant
= BT_FROM_COMMON(variant_field
);
735 BT_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
736 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
737 BT_FIELD_TYPE_ID_VARIANT
, "Field");
738 return variant
->payload
;
742 struct bt_field_common
*bt_field_common_variant_borrow_tag(
743 struct bt_field_common
*variant_field
)
745 struct bt_field_common_variant
*variant
= BT_FROM_COMMON(variant_field
);
747 BT_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
748 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
749 BT_FIELD_TYPE_ID_VARIANT
, "Field");
754 int bt_field_common_integer_signed_get_value(struct bt_field_common
*field
,
757 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
759 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
760 BT_ASSERT_PRE_NON_NULL(value
, "Value");
761 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "Integer field");
762 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
763 BT_FIELD_TYPE_ID_INTEGER
, "Field");
764 BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(field
->type
),
765 "Field's type is unsigned: %!+_f", field
);
766 *value
= integer
->payload
.signd
;
771 static inline bool value_is_in_range_signed(unsigned int size
, int64_t value
)
774 int64_t min_value
, max_value
;
776 min_value
= -(1ULL << (size
- 1));
777 max_value
= (1ULL << (size
- 1)) - 1;
778 if (value
< min_value
|| value
> max_value
) {
779 BT_LOGF("Value is out of bounds: value=%" PRId64
", "
780 "min-value=%" PRId64
", max-value=%" PRId64
,
781 value
, min_value
, max_value
);
789 int bt_field_common_integer_signed_set_value(struct bt_field_common
*field
,
793 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
794 struct bt_field_type_common_integer
*integer_type
;
796 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
797 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Integer field");
798 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
799 BT_FIELD_TYPE_ID_INTEGER
, "Field");
800 integer_type
= BT_FROM_COMMON(field
->type
);
801 BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(field
->type
),
802 "Field's type is unsigned: %!+_f", field
);
803 BT_ASSERT_PRE(value_is_in_range_signed(integer_type
->size
, value
),
804 "Value is out of bounds: value=%" PRId64
", %![field-]+_f",
806 integer
->payload
.signd
= value
;
807 bt_field_common_set(field
, true);
812 int bt_field_common_integer_unsigned_get_value(struct bt_field_common
*field
,
815 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
817 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
818 BT_ASSERT_PRE_NON_NULL(value
, "Value");
819 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "Integer field");
820 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
821 BT_FIELD_TYPE_ID_INTEGER
, "Field");
822 BT_ASSERT_PRE(!bt_field_type_common_integer_is_signed(field
->type
),
823 "Field's type is signed: %!+_f", field
);
824 *value
= integer
->payload
.unsignd
;
829 static inline bool value_is_in_range_unsigned(unsigned int size
, uint64_t value
)
834 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t) 1 << size
) - 1;
835 if (value
> max_value
) {
836 BT_LOGF("Value is out of bounds: value=%" PRIu64
", "
837 "max-value=%" PRIu64
,
846 int bt_field_common_integer_unsigned_set_value(struct bt_field_common
*field
,
849 struct bt_field_common_integer
*integer
= BT_FROM_COMMON(field
);
850 struct bt_field_type_common_integer
*integer_type
;
852 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
853 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Integer field");
854 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
855 BT_FIELD_TYPE_ID_INTEGER
, "Field");
856 integer_type
= BT_FROM_COMMON(field
->type
);
857 BT_ASSERT_PRE(!bt_field_type_common_integer_is_signed(field
->type
),
858 "Field's type is signed: %!+_f", field
);
859 BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type
->size
, value
),
860 "Value is out of bounds: value=%" PRIu64
", %![field-]+_f",
862 integer
->payload
.unsignd
= value
;
863 bt_field_common_set(field
, true);
868 struct bt_field_type_enumeration_mapping_iterator
*
869 bt_field_common_enumeration_get_mappings(struct bt_field_common
*field
,
870 bt_field_common_create_func field_create_func
)
873 struct bt_field_common
*container
= NULL
;
874 struct bt_field_type_common_integer
*integer_type
= NULL
;
875 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
877 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
878 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
879 BT_FIELD_TYPE_ID_ENUM
, "Field");
880 container
= bt_field_common_enumeration_borrow_container(field
,
882 BT_ASSERT_PRE(container
,
883 "Enumeration field has no container field: %!+_f", field
);
884 BT_ASSERT(container
->type
);
885 integer_type
= BT_FROM_COMMON(container
->type
);
886 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(container
,
887 "Enumeration field's payload field");
889 if (!integer_type
->is_signed
) {
892 ret
= bt_field_common_integer_unsigned_get_value(container
,
895 iter
= bt_field_type_common_enumeration_unsigned_find_mappings_by_value(
900 ret
= bt_field_common_integer_signed_get_value(container
, &value
);
902 iter
= bt_field_type_common_enumeration_signed_find_mappings_by_value(
910 int bt_field_common_floating_point_get_value(struct bt_field_common
*field
,
913 struct bt_field_common_floating_point
*floating_point
=
914 BT_FROM_COMMON(field
);
916 BT_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
917 BT_ASSERT_PRE_NON_NULL(value
, "Value");
918 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "Floating point number field");
919 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
920 BT_FIELD_TYPE_ID_FLOAT
, "Field");
921 *value
= floating_point
->payload
;
926 int bt_field_common_floating_point_set_value(struct bt_field_common
*field
,
929 struct bt_field_common_floating_point
*floating_point
=
930 BT_FROM_COMMON(field
);
932 BT_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
933 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "Floating point number field");
934 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
935 BT_FIELD_TYPE_ID_FLOAT
, "Field");
936 floating_point
->payload
= value
;
937 bt_field_common_set(field
, true);
942 const char *bt_field_common_string_get_value(struct bt_field_common
*field
)
944 struct bt_field_common_string
*string
= BT_FROM_COMMON(field
);
946 BT_ASSERT_PRE_NON_NULL(field
, "String field");
947 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field
, "String field");
948 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
949 BT_FIELD_TYPE_ID_STRING
, "Field");
950 return string
->payload
->str
;
954 int bt_field_common_string_set_value(struct bt_field_common
*field
,
957 struct bt_field_common_string
*string
= BT_FROM_COMMON(field
);
959 BT_ASSERT_PRE_NON_NULL(field
, "String field");
960 BT_ASSERT_PRE_NON_NULL(value
, "Value");
961 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "String field");
962 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
963 BT_FIELD_TYPE_ID_STRING
, "Field");
965 if (string
->payload
) {
966 g_string_assign(string
->payload
, value
);
968 string
->payload
= g_string_new(value
);
971 bt_field_common_set(field
, true);
976 int bt_field_common_string_append(struct bt_field_common
*field
,
979 struct bt_field_common_string
*string_field
= BT_FROM_COMMON(field
);
981 BT_ASSERT_PRE_NON_NULL(field
, "String field");
982 BT_ASSERT_PRE_NON_NULL(value
, "Value");
983 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "String field");
984 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
985 BT_FIELD_TYPE_ID_STRING
, "Field");
987 if (string_field
->payload
) {
988 g_string_append(string_field
->payload
, value
);
990 string_field
->payload
= g_string_new(value
);
993 bt_field_common_set(field
, true);
998 int bt_field_common_string_append_len(struct bt_field_common
*field
,
999 const char *value
, unsigned int length
)
1001 struct bt_field_common_string
*string_field
= BT_FROM_COMMON(field
);
1003 BT_ASSERT_PRE_NON_NULL(field
, "String field");
1004 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1005 BT_ASSERT_PRE_FIELD_COMMON_HOT(field
, "String field");
1006 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field
,
1007 BT_FIELD_TYPE_ID_STRING
, "Field");
1009 /* make sure no null bytes are appended */
1010 BT_ASSERT_PRE(memchr(value
, '\0', length
) == NULL
,
1011 "String value to append contains a null character: "
1012 "partial-value=\"%.32s\", length=%u", value
, length
);
1014 if (string_field
->payload
) {
1015 g_string_append_len(string_field
->payload
, value
, length
);
1017 string_field
->payload
= g_string_new_len(value
, length
);
1020 bt_field_common_set(field
, true);
1025 int _bt_field_validate_recursive(struct bt_field
*field
)
1027 return _bt_field_common_validate_recursive((void *) field
);
1031 void _bt_field_freeze_recursive(struct bt_field
*field
)
1033 return _bt_field_common_freeze_recursive((void *) field
);
1037 bt_bool
_bt_field_is_set_recursive(struct bt_field
*field
)
1039 return _bt_field_common_is_set_recursive((void *) field
);
1043 void _bt_field_reset_recursive(struct bt_field
*field
)
1045 _bt_field_common_reset_recursive((void *) field
);
1049 void _bt_field_set(struct bt_field
*field
, bool value
)
1051 _bt_field_common_set((void *) field
, value
);
1054 #endif /* BABELTRACE_CTF_IR_FIELDS_INTERNAL_H */