2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #define BT_LOG_TAG "CTF-WRITER-FIELDS"
26 #include <babeltrace/lib-logging-internal.h>
28 #include <babeltrace/assert-pre-internal.h>
29 #include <babeltrace/align-internal.h>
30 #include <babeltrace/assert-internal.h>
31 #include <babeltrace/compat/fcntl-internal.h>
32 #include <babeltrace/compiler-internal.h>
33 #include <babeltrace/ctf-writer/field-types-internal.h>
34 #include <babeltrace/ctf-writer/fields-internal.h>
35 #include <babeltrace/ctf-writer/serialize-internal.h>
36 #include <babeltrace/endian-internal.h>
37 #include <babeltrace/ctf-writer/object-internal.h>
38 #include <babeltrace/ctf-writer/object.h>
44 #define BT_ASSERT_PRE_CTF_FIELD_IS_INT_OR_ENUM(_field, _name) \
45 BT_ASSERT_PRE((_field)->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || \
46 (_field)->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, \
47 _name " is not an integer or an enumeration field: " \
48 "field-addr=%p", (_field))
51 struct bt_ctf_field_common
*bt_ctf_field_common_copy(struct bt_ctf_field_common
*field
)
53 struct bt_ctf_field_common
*copy
= NULL
;
55 BT_ASSERT_PRE_NON_NULL(field
, "Field");
56 BT_ASSERT(field_type_common_has_known_id(field
->type
));
57 BT_ASSERT(field
->methods
->copy
);
58 copy
= field
->methods
->copy(field
);
60 BT_LOGW("Cannot create field: ft-addr=%p", field
->type
);
64 bt_ctf_field_common_set(copy
, field
->payload_set
);
71 int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common
*field
,
72 struct bt_ctf_field_type_common
*type
,
73 bool is_shared
, bt_ctf_object_release_func release_func
,
74 struct bt_ctf_field_common_methods
*methods
,
75 bt_ctf_field_common_create_func field_create_func
,
76 GDestroyNotify field_release_func
)
79 struct bt_ctf_field_type_common_structure
*structure_type
=
80 BT_CTF_FROM_COMMON(type
);
81 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
84 BT_LOGD("Initializing common structure field object: ft-addr=%p", type
);
85 bt_ctf_field_common_initialize(field
, type
, is_shared
,
86 release_func
, methods
);
87 structure
->fields
= g_ptr_array_new_with_free_func(field_release_func
);
88 g_ptr_array_set_size(structure
->fields
, structure_type
->fields
->len
);
90 /* Create all fields contained in the structure field. */
91 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
92 struct bt_ctf_field_common
*field
;
93 struct bt_ctf_field_type_common_structure_field
*struct_field
=
94 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
96 field
= field_create_func(struct_field
->type
);
98 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
99 g_quark_to_string(struct_field
->name
), i
);
104 g_ptr_array_index(structure
->fields
, i
) = field
;
107 BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
115 int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common
*field
,
116 struct bt_ctf_field_type_common
*type
,
117 bool is_shared
, bt_ctf_object_release_func release_func
,
118 struct bt_ctf_field_common_methods
*methods
,
119 bt_ctf_field_common_create_func field_create_func
,
120 GDestroyNotify field_release_func
)
123 struct bt_ctf_field_type_common_variant
*variant_type
=
124 BT_CTF_FROM_COMMON(type
);
125 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
128 BT_LOGD("Initializing common variant field object: ft-addr=%p", type
);
129 bt_ctf_field_common_initialize(field
, type
, is_shared
,
130 release_func
, methods
);
131 ret
= bt_ctf_field_type_common_variant_update_choices(type
);
133 BT_LOGE("Cannot update common variant field type choices: "
138 variant
->fields
= g_ptr_array_new_with_free_func(field_release_func
);
139 g_ptr_array_set_size(variant
->fields
, variant_type
->choices
->len
);
141 /* Create all fields contained in the variant field. */
142 for (i
= 0; i
< variant_type
->choices
->len
; i
++) {
143 struct bt_ctf_field_common
*field
;
144 struct bt_ctf_field_type_common_variant_choice
*var_choice
=
145 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
148 field
= field_create_func(var_choice
->type
);
150 BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
151 g_quark_to_string(var_choice
->name
), i
);
156 g_ptr_array_index(variant
->fields
, i
) = field
;
159 BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
167 int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common
*field
,
168 struct bt_ctf_field_type_common
*type
,
169 bool is_shared
, bt_ctf_object_release_func release_func
,
170 struct bt_ctf_field_common_methods
*methods
)
173 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
175 BT_LOGD("Initializing common string field object: ft-addr=%p", type
);
176 bt_ctf_field_common_initialize(field
, type
, is_shared
,
177 release_func
, methods
);
178 string
->buf
= g_array_sized_new(FALSE
, FALSE
, sizeof(char), 1);
184 g_array_index(string
->buf
, char, 0) = '\0';
185 BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
193 int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common
*field
,
194 struct bt_ctf_field_type_common
*type
,
195 bool is_shared
, bt_ctf_object_release_func release_func
,
196 struct bt_ctf_field_common_methods
*methods
,
197 bt_ctf_field_common_create_func field_create_func
,
198 GDestroyNotify field_destroy_func
)
200 struct bt_ctf_field_type_common_array
*array_type
= BT_CTF_FROM_COMMON(type
);
201 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
202 unsigned int array_length
;
206 BT_LOGD("Initializing common array field object: ft-addr=%p", type
);
208 bt_ctf_field_common_initialize(field
, type
, is_shared
,
209 release_func
, methods
);
210 array_length
= array_type
->length
;
211 array
->elements
= g_ptr_array_sized_new(array_length
);
212 if (!array
->elements
) {
217 g_ptr_array_set_free_func(array
->elements
, field_destroy_func
);
218 g_ptr_array_set_size(array
->elements
, array_length
);
220 for (i
= 0; i
< array_length
; i
++) {
221 array
->elements
->pdata
[i
] = field_create_func(
222 array_type
->element_ft
);
223 if (!array
->elements
->pdata
[i
]) {
229 BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
237 int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common
*field
,
238 struct bt_ctf_field_type_common
*type
,
239 bool is_shared
, bt_ctf_object_release_func release_func
,
240 struct bt_ctf_field_common_methods
*methods
,
241 GDestroyNotify field_destroy_func
)
243 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
246 BT_LOGD("Initializing common sequence field object: ft-addr=%p", type
);
248 bt_ctf_field_common_initialize(field
, type
, is_shared
,
249 release_func
, methods
);
250 sequence
->elements
= g_ptr_array_new();
251 if (!sequence
->elements
) {
256 g_ptr_array_set_free_func(sequence
->elements
, field_destroy_func
);
257 BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
265 int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common
*field
)
267 return (field
&& field
->payload_set
) ? 0 : -1;
271 int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common
*field
)
275 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
279 for (i
= 0; i
< structure
->fields
->len
; i
++) {
280 ret
= bt_ctf_field_common_validate_recursive(
281 (void *) structure
->fields
->pdata
[i
]);
287 this_ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
288 field
->type
, &name
, NULL
, i
);
289 BT_ASSERT(this_ret
== 0);
290 BT_ASSERT_PRE_MSG("Invalid structure field's field: "
291 "struct-field-addr=%p, field-name=\"%s\", "
292 "index=%" PRId64
", field-addr=%p",
293 field
, name
, i
, structure
->fields
->pdata
[i
]);
303 int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common
*field
)
306 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
310 if (!variant
->current_field
) {
315 ret
= bt_ctf_field_common_validate_recursive(variant
->current_field
);
322 int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common
*field
)
326 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
330 for (i
= 0; i
< array
->elements
->len
; i
++) {
331 ret
= bt_ctf_field_common_validate_recursive((void *) array
->elements
->pdata
[i
]);
333 BT_ASSERT_PRE_MSG("Invalid array field's element field: "
334 "array-field-addr=%p, " PRId64
", "
335 "elem-field-addr=%p",
336 field
, i
, array
->elements
->pdata
[i
]);
346 int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common
*field
)
350 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
354 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
355 ret
= bt_ctf_field_common_validate_recursive(
356 (void *) sequence
->elements
->pdata
[i
]);
358 BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
359 "seq-field-addr=%p, " PRId64
", "
360 "elem-field-addr=%p",
361 field
, i
, sequence
->elements
->pdata
[i
]);
370 void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common
*field
)
373 field
->payload_set
= false;
377 void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common
*field
)
380 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
384 for (i
= 0; i
< structure
->fields
->len
; i
++) {
385 struct bt_ctf_field_common
*member
= structure
->fields
->pdata
[i
];
389 * Structure members are lazily initialized;
390 * skip if this member has not been allocated
396 bt_ctf_field_common_reset_recursive(member
);
401 void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common
*field
)
403 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
406 variant
->current_field
= NULL
;
410 void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common
*field
)
413 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
417 for (i
= 0; i
< array
->elements
->len
; i
++) {
418 struct bt_ctf_field_common
*member
= array
->elements
->pdata
[i
];
422 * Array elements are lazily initialized; skip
423 * if this member has not been allocated yet.
428 bt_ctf_field_common_reset_recursive(member
);
433 void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common
*field
)
435 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
440 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
441 if (sequence
->elements
->pdata
[i
]) {
442 bt_ctf_field_common_reset_recursive(
443 sequence
->elements
->pdata
[i
]);
447 sequence
->length
= 0;
451 void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common
*field
,
454 field
->frozen
= is_frozen
;
458 void bt_ctf_field_common_structure_set_is_frozen_recursive(
459 struct bt_ctf_field_common
*field
, bool is_frozen
)
462 struct bt_ctf_field_common_structure
*structure_field
=
463 BT_CTF_FROM_COMMON(field
);
465 BT_LOGD("Freezing structure field object: addr=%p", field
);
467 for (i
= 0; i
< structure_field
->fields
->len
; i
++) {
468 struct bt_ctf_field_common
*struct_field
=
469 g_ptr_array_index(structure_field
->fields
, i
);
471 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64
,
473 bt_ctf_field_common_set_is_frozen_recursive(struct_field
,
477 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
481 void bt_ctf_field_common_variant_set_is_frozen_recursive(
482 struct bt_ctf_field_common
*field
, bool is_frozen
)
485 struct bt_ctf_field_common_variant
*variant_field
= BT_CTF_FROM_COMMON(field
);
487 BT_LOGD("Freezing variant field object: addr=%p", field
);
489 for (i
= 0; i
< variant_field
->fields
->len
; i
++) {
490 struct bt_ctf_field_common
*var_field
=
491 g_ptr_array_index(variant_field
->fields
, i
);
493 BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64
,
495 bt_ctf_field_common_set_is_frozen_recursive(var_field
, is_frozen
);
498 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
502 void bt_ctf_field_common_array_set_is_frozen_recursive(
503 struct bt_ctf_field_common
*field
, bool is_frozen
)
506 struct bt_ctf_field_common_array
*array_field
= BT_CTF_FROM_COMMON(field
);
508 BT_LOGD("Freezing array field object: addr=%p", field
);
510 for (i
= 0; i
< array_field
->elements
->len
; i
++) {
511 struct bt_ctf_field_common
*elem_field
=
512 g_ptr_array_index(array_field
->elements
, i
);
514 BT_LOGD("Freezing array field object's element field: "
515 "element-field-addr=%p, index=%" PRId64
,
517 bt_ctf_field_common_set_is_frozen_recursive(elem_field
, is_frozen
);
520 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
524 void bt_ctf_field_common_sequence_set_is_frozen_recursive(
525 struct bt_ctf_field_common
*field
, bool is_frozen
)
528 struct bt_ctf_field_common_sequence
*sequence_field
=
529 BT_CTF_FROM_COMMON(field
);
531 BT_LOGD("Freezing sequence field object: addr=%p", field
);
533 for (i
= 0; i
< sequence_field
->length
; i
++) {
534 struct bt_ctf_field_common
*elem_field
=
535 g_ptr_array_index(sequence_field
->elements
, i
);
537 BT_LOGD("Freezing sequence field object's element field: "
538 "element-field-addr=%p, index=%" PRId64
,
540 bt_ctf_field_common_set_is_frozen_recursive(elem_field
, is_frozen
);
543 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
547 void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
554 BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
556 BT_ASSERT(field_type_common_has_known_id(field
->type
));
557 BT_ASSERT(field
->methods
->set_is_frozen
);
558 field
->methods
->set_is_frozen(field
, is_frozen
);
565 bt_bool
bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common
*field
)
567 return field
&& field
->payload_set
;
571 bt_bool
bt_ctf_field_common_structure_is_set_recursive(
572 struct bt_ctf_field_common
*field
)
574 bt_bool is_set
= BT_FALSE
;
576 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
580 for (i
= 0; i
< structure
->fields
->len
; i
++) {
581 is_set
= bt_ctf_field_common_is_set_recursive(
582 structure
->fields
->pdata
[i
]);
593 bt_bool
bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common
*field
)
595 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
596 bt_bool is_set
= BT_FALSE
;
600 if (variant
->current_field
) {
601 is_set
= bt_ctf_field_common_is_set_recursive(
602 variant
->current_field
);
609 bt_bool
bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common
*field
)
612 bt_bool is_set
= BT_FALSE
;
613 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
617 for (i
= 0; i
< array
->elements
->len
; i
++) {
618 is_set
= bt_ctf_field_common_is_set_recursive(array
->elements
->pdata
[i
]);
629 bt_bool
bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common
*field
)
632 bt_bool is_set
= BT_FALSE
;
633 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
637 if (!sequence
->elements
) {
641 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
642 is_set
= bt_ctf_field_common_is_set_recursive(
643 sequence
->elements
->pdata
[i
]);
653 static struct bt_ctf_field_common_methods bt_ctf_field_integer_methods
= {
654 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
655 .validate
= bt_ctf_field_common_generic_validate
,
657 .is_set
= bt_ctf_field_common_generic_is_set
,
658 .reset
= bt_ctf_field_common_generic_reset
,
661 static struct bt_ctf_field_common_methods bt_ctf_field_floating_point_methods
= {
662 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
663 .validate
= bt_ctf_field_common_generic_validate
,
665 .is_set
= bt_ctf_field_common_generic_is_set
,
666 .reset
= bt_ctf_field_common_generic_reset
,
670 void bt_ctf_field_enumeration_set_is_frozen_recursive(
671 struct bt_ctf_field_common
*field
, bool is_frozen
);
674 int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common
*field
);
677 bt_bool
bt_ctf_field_enumeration_is_set_recursive(
678 struct bt_ctf_field_common
*field
);
681 void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common
*field
);
683 static struct bt_ctf_field_common_methods bt_ctf_field_enumeration_methods
= {
684 .set_is_frozen
= bt_ctf_field_enumeration_set_is_frozen_recursive
,
685 .validate
= bt_ctf_field_enumeration_validate_recursive
,
687 .is_set
= bt_ctf_field_enumeration_is_set_recursive
,
688 .reset
= bt_ctf_field_enumeration_reset_recursive
,
691 static struct bt_ctf_field_common_methods bt_ctf_field_string_methods
= {
692 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
693 .validate
= bt_ctf_field_common_generic_validate
,
695 .is_set
= bt_ctf_field_common_generic_is_set
,
696 .reset
= bt_ctf_field_common_generic_reset
,
699 static struct bt_ctf_field_common_methods bt_ctf_field_structure_methods
= {
700 .set_is_frozen
= bt_ctf_field_common_structure_set_is_frozen_recursive
,
701 .validate
= bt_ctf_field_common_structure_validate_recursive
,
703 .is_set
= bt_ctf_field_common_structure_is_set_recursive
,
704 .reset
= bt_ctf_field_common_structure_reset_recursive
,
707 static struct bt_ctf_field_common_methods bt_ctf_field_sequence_methods
= {
708 .set_is_frozen
= bt_ctf_field_common_sequence_set_is_frozen_recursive
,
709 .validate
= bt_ctf_field_common_sequence_validate_recursive
,
711 .is_set
= bt_ctf_field_common_sequence_is_set_recursive
,
712 .reset
= bt_ctf_field_common_sequence_reset_recursive
,
715 static struct bt_ctf_field_common_methods bt_ctf_field_array_methods
= {
716 .set_is_frozen
= bt_ctf_field_common_array_set_is_frozen_recursive
,
717 .validate
= bt_ctf_field_common_array_validate_recursive
,
719 .is_set
= bt_ctf_field_common_array_is_set_recursive
,
720 .reset
= bt_ctf_field_common_array_reset_recursive
,
724 void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
728 int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common
*field
);
731 bt_bool
bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common
*field
);
734 void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common
*field
);
736 static struct bt_ctf_field_common_methods bt_ctf_field_variant_methods
= {
737 .set_is_frozen
= bt_ctf_field_variant_set_is_frozen_recursive
,
738 .validate
= bt_ctf_field_variant_validate_recursive
,
740 .is_set
= bt_ctf_field_variant_is_set_recursive
,
741 .reset
= bt_ctf_field_variant_reset_recursive
,
745 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*);
748 struct bt_ctf_field
*bt_ctf_field_enumeration_create(struct bt_ctf_field_type
*);
751 struct bt_ctf_field
*bt_ctf_field_floating_point_create(struct bt_ctf_field_type
*);
754 struct bt_ctf_field
*bt_ctf_field_structure_create(struct bt_ctf_field_type
*);
757 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*);
760 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*);
763 struct bt_ctf_field
*bt_ctf_field_sequence_create(struct bt_ctf_field_type
*);
766 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*);
769 struct bt_ctf_field
*(* const field_create_funcs
[])(struct bt_ctf_field_type
*) = {
770 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_integer_create
,
771 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_enumeration_create
,
772 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = bt_ctf_field_floating_point_create
,
773 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_structure_create
,
774 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_variant_create
,
775 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_array_create
,
776 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_sequence_create
,
777 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_string_create
,
780 typedef int (*bt_ctf_field_serialize_recursive_func
)(
781 struct bt_ctf_field_common
*, struct bt_ctf_stream_pos
*,
782 enum bt_ctf_byte_order
);
785 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*field
)
787 BT_LOGD("Destroying CTF writer integer field object: addr=%p", field
);
788 bt_ctf_field_common_integer_finalize((void *) field
);
793 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*field
)
795 BT_LOGD("Destroying CTF writer floating point field object: addr=%p",
797 bt_ctf_field_common_floating_point_finalize((void *) field
);
802 void bt_ctf_field_enumeration_destroy_recursive(struct bt_ctf_field
*field
)
804 struct bt_ctf_field_enumeration
*enumeration
= BT_CTF_FROM_COMMON(field
);
806 BT_LOGD("Destroying CTF writer enumeration field object: addr=%p",
808 BT_LOGD_STR("Putting container field.");
809 bt_ctf_object_put_ref(enumeration
->container
);
810 bt_ctf_field_common_finalize((void *) field
);
815 void bt_ctf_field_structure_destroy_recursive(struct bt_ctf_field
*field
)
817 BT_LOGD("Destroying CTF writer structure field object: addr=%p", field
);
818 bt_ctf_field_common_structure_finalize_recursive((void *) field
);
823 void bt_ctf_field_variant_destroy_recursive(struct bt_ctf_field
*field
)
825 struct bt_ctf_field_variant
*variant
= BT_CTF_FROM_COMMON(field
);
827 BT_LOGD("Destroying CTF writer variant field object: addr=%p", field
);
828 BT_LOGD_STR("Putting tag field.");
829 bt_ctf_object_put_ref(variant
->tag
);
830 bt_ctf_field_common_variant_finalize_recursive((void *) field
);
835 void bt_ctf_field_array_destroy_recursive(struct bt_ctf_field
*field
)
837 BT_LOGD("Destroying CTF writer array field object: addr=%p", field
);
838 bt_ctf_field_common_array_finalize_recursive((void *) field
);
843 void bt_ctf_field_sequence_destroy_recursive(struct bt_ctf_field
*field
)
845 BT_LOGD("Destroying CTF writer sequence field object: addr=%p", field
);
846 bt_ctf_field_common_sequence_finalize_recursive((void *) field
);
851 void bt_ctf_field_string_destroy(struct bt_ctf_field
*field
)
853 BT_LOGD("Destroying CTF writer string field object: addr=%p", field
);
854 bt_ctf_field_common_string_finalize((void *) field
);
859 int bt_ctf_field_serialize_recursive(struct bt_ctf_field
*field
,
860 struct bt_ctf_stream_pos
*pos
,
861 enum bt_ctf_byte_order native_byte_order
)
863 struct bt_ctf_field_common
*field_common
= (void *) field
;
864 bt_ctf_field_serialize_recursive_func serialize_func
;
867 BT_ASSERT_PRE_NON_NULL(field
, "Field");
868 BT_ASSERT(field_common
->spec
.writer
.serialize_func
);
869 serialize_func
= field_common
->spec
.writer
.serialize_func
;
870 return serialize_func(field_common
, pos
,
875 int increase_packet_size(struct bt_ctf_stream_pos
*pos
)
880 BT_LOGV("Increasing packet size: pos-offset=%" PRId64
", "
881 "cur-packet-size=%" PRIu64
,
882 pos
->offset
, pos
->packet_size
);
883 ret
= munmap_align(pos
->base_mma
);
885 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
890 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
892 ret
= bt_posix_fallocate(pos
->fd
, pos
->mmap_offset
,
893 pos
->packet_size
/ CHAR_BIT
);
894 } while (ret
== EINTR
);
896 BT_LOGE_ERRNO("Failed to preallocate memory space",
903 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
904 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
905 if (pos
->base_mma
== MAP_FAILED
) {
906 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
911 BT_LOGV("Increased packet size: pos-offset=%" PRId64
", "
912 "new-packet-size=%" PRIu64
,
913 pos
->offset
, pos
->packet_size
);
914 BT_ASSERT(pos
->packet_size
% 8 == 0);
921 int bt_ctf_field_integer_serialize(struct bt_ctf_field_common
*field
,
922 struct bt_ctf_stream_pos
*pos
,
923 enum bt_ctf_byte_order native_byte_order
)
927 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Integer field");
928 BT_LOGV("Serializing CTF writer integer field: addr=%p, pos-offset=%" PRId64
", "
929 "native-bo=%s", field
, pos
->offset
,
930 bt_ctf_byte_order_string((int) native_byte_order
));
933 ret
= bt_ctf_field_integer_write(field
, pos
, native_byte_order
);
934 if (ret
== -EFAULT
) {
936 * The field is too large to fit in the current packet's
937 * remaining space. Bump the packet size and retry.
939 ret
= increase_packet_size(pos
);
941 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
952 int bt_ctf_field_enumeration_serialize_recursive(struct bt_ctf_field_common
*field
,
953 struct bt_ctf_stream_pos
*pos
,
954 enum bt_ctf_byte_order native_byte_order
)
956 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
958 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64
", "
959 "native-bo=%s", field
, pos
->offset
,
960 bt_ctf_byte_order_string((int) native_byte_order
));
961 BT_LOGV_STR("Serializing enumeration field's payload field.");
962 return bt_ctf_field_serialize_recursive(
963 (void *) enumeration
->container
, pos
, native_byte_order
);
967 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field_common
*field
,
968 struct bt_ctf_stream_pos
*pos
,
969 enum bt_ctf_byte_order native_byte_order
)
973 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Floating point number field");
974 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64
", "
975 "native-bo=%s", field
, pos
->offset
,
976 bt_ctf_byte_order_string((int) native_byte_order
));
979 ret
= bt_ctf_field_floating_point_write(field
, pos
,
981 if (ret
== -EFAULT
) {
983 * The field is too large to fit in the current packet's
984 * remaining space. Bump the packet size and retry.
986 ret
= increase_packet_size(pos
);
988 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
999 int bt_ctf_field_structure_serialize_recursive(struct bt_ctf_field_common
*field
,
1000 struct bt_ctf_stream_pos
*pos
,
1001 enum bt_ctf_byte_order native_byte_order
)
1005 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
1007 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64
", "
1008 "native-bo=%s", field
, pos
->offset
,
1009 bt_ctf_byte_order_string((int) native_byte_order
));
1011 while (!bt_ctf_stream_pos_access_ok(pos
,
1012 offset_align(pos
->offset
, field
->type
->alignment
))) {
1013 ret
= increase_packet_size(pos
);
1015 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
1020 if (!bt_ctf_stream_pos_align(pos
, field
->type
->alignment
)) {
1021 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64
", "
1022 "align=%u", pos
->offset
, field
->type
->alignment
);
1027 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1028 struct bt_ctf_field_common
*member
= g_ptr_array_index(
1029 structure
->fields
, i
);
1030 const char *field_name
= NULL
;
1032 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64
", "
1033 "field-addr=%p, index=%" PRId64
,
1034 pos
->offset
, member
, i
);
1037 ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
1038 field
->type
, &field_name
, NULL
, i
);
1039 BT_ASSERT(ret
== 0);
1040 BT_LOGW("Cannot serialize structure field's field: field is not set: "
1041 "struct-field-addr=%p, "
1042 "field-name=\"%s\", index=%" PRId64
,
1043 field
, field_name
, i
);
1048 ret
= bt_ctf_field_serialize_recursive((void *) member
, pos
,
1051 ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
1052 field
->type
, &field_name
, NULL
, i
);
1053 BT_ASSERT(ret
== 0);
1054 BT_LOGW("Cannot serialize structure field's field: "
1055 "struct-field-addr=%p, field-addr=%p, "
1056 "field-name=\"%s\", index=%" PRId64
,
1057 field
->type
, member
, field_name
, i
);
1067 int bt_ctf_field_variant_serialize_recursive(struct bt_ctf_field_common
*field
,
1068 struct bt_ctf_stream_pos
*pos
,
1069 enum bt_ctf_byte_order native_byte_order
)
1071 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
1073 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64
", "
1074 "native-bo=%s", field
, pos
->offset
,
1075 bt_ctf_byte_order_string((int) native_byte_order
));
1076 BT_LOGV_STR("Serializing variant field's payload field.");
1077 return bt_ctf_field_serialize_recursive(
1078 (void *) variant
->current_field
, pos
, native_byte_order
);
1082 int bt_ctf_field_array_serialize_recursive(struct bt_ctf_field_common
*field
,
1083 struct bt_ctf_stream_pos
*pos
,
1084 enum bt_ctf_byte_order native_byte_order
)
1088 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
1090 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64
", "
1091 "native-bo=%s", field
, pos
->offset
,
1092 bt_ctf_byte_order_string((int) native_byte_order
));
1094 for (i
= 0; i
< array
->elements
->len
; i
++) {
1095 struct bt_ctf_field_common
*elem_field
=
1096 g_ptr_array_index(array
->elements
, i
);
1098 BT_LOGV("Serializing array field's element field: "
1099 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
1100 pos
->offset
, elem_field
, i
);
1101 ret
= bt_ctf_field_serialize_recursive(
1102 (void *) elem_field
, pos
, native_byte_order
);
1104 BT_LOGW("Cannot serialize array field's element field: "
1105 "array-field-addr=%p, field-addr=%p, "
1106 "index=%" PRId64
, field
, elem_field
, i
);
1116 int bt_ctf_field_sequence_serialize_recursive(struct bt_ctf_field_common
*field
,
1117 struct bt_ctf_stream_pos
*pos
,
1118 enum bt_ctf_byte_order native_byte_order
)
1122 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
1124 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64
", "
1125 "native-bo=%s", field
, pos
->offset
,
1126 bt_ctf_byte_order_string((int) native_byte_order
));
1128 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1129 struct bt_ctf_field_common
*elem_field
=
1130 g_ptr_array_index(sequence
->elements
, i
);
1132 BT_LOGV("Serializing sequence field's element field: "
1133 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
1134 pos
->offset
, elem_field
, i
);
1135 ret
= bt_ctf_field_serialize_recursive(
1136 (void *) elem_field
, pos
, native_byte_order
);
1138 BT_LOGW("Cannot serialize sequence field's element field: "
1139 "sequence-field-addr=%p, field-addr=%p, "
1140 "index=%" PRId64
, field
, elem_field
, i
);
1150 int bt_ctf_field_string_serialize(struct bt_ctf_field_common
*field
,
1151 struct bt_ctf_stream_pos
*pos
,
1152 enum bt_ctf_byte_order native_byte_order
)
1156 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
1157 struct bt_ctf_field_type
*character_type
=
1158 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
1159 struct bt_ctf_field
*character
;
1161 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "String field");
1162 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64
", "
1163 "native-bo=%s", field
, pos
->offset
,
1164 bt_ctf_byte_order_string((int) native_byte_order
));
1166 BT_LOGV_STR("Creating character field from string field's character field type.");
1167 character
= bt_ctf_field_create(character_type
);
1169 for (i
= 0; i
< string
->size
+ 1; i
++) {
1170 const uint64_t chr
= (uint64_t) ((char *) string
->buf
->data
)[i
];
1172 ret
= bt_ctf_field_integer_unsigned_set_value(character
, chr
);
1173 BT_ASSERT(ret
== 0);
1174 BT_LOGV("Serializing string field's character field: "
1175 "pos-offset=%" PRId64
", field-addr=%p, "
1176 "index=%" PRId64
", char-int=%" PRIu64
,
1177 pos
->offset
, character
, i
, chr
);
1178 ret
= bt_ctf_field_integer_serialize(
1179 (void *) character
, pos
, native_byte_order
);
1181 BT_LOGW_STR("Cannot serialize character field.");
1187 bt_ctf_object_put_ref(character
);
1188 bt_ctf_object_put_ref(character_type
);
1192 struct bt_ctf_field
*bt_ctf_field_create(struct bt_ctf_field_type
*type
)
1194 struct bt_ctf_field
*field
= NULL
;
1195 enum bt_ctf_field_type_id type_id
;
1197 BT_ASSERT_PRE_NON_NULL(type
, "Field type");
1198 BT_ASSERT(field_type_common_has_known_id((void *) type
));
1199 BT_ASSERT_PRE(bt_ctf_field_type_common_validate((void *) type
) == 0,
1200 "Field type is invalid: ft-addr=%p", type
);
1201 type_id
= bt_ctf_field_type_get_type_id(type
);
1202 field
= field_create_funcs
[type_id
](type
);
1207 bt_ctf_field_type_common_freeze((void *) type
);
1213 struct bt_ctf_field_type
*bt_ctf_field_get_type(struct bt_ctf_field
*field
)
1215 return bt_ctf_object_get_ref(bt_ctf_field_common_borrow_type((void *) field
));
1218 enum bt_ctf_field_type_id
bt_ctf_field_get_type_id(struct bt_ctf_field
*field
)
1220 struct bt_ctf_field_common
*field_common
= (void *) field
;
1222 BT_ASSERT_PRE_NON_NULL(field
, "Field");
1223 return (int) field_common
->type
->id
;
1226 int bt_ctf_field_sequence_set_length(struct bt_ctf_field
*field
,
1227 struct bt_ctf_field
*length_field
)
1230 struct bt_ctf_field_common
*common_length_field
= (void *) length_field
;
1233 BT_ASSERT_PRE_NON_NULL(length_field
, "Length field");
1234 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) length_field
, "Length field");
1235 BT_ASSERT_PRE(common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_INTEGER
||
1236 common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_ENUM
,
1237 "Length field must be an integer or enumeration field: field-addr=%p",
1240 if (common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_ENUM
) {
1241 struct bt_ctf_field_enumeration
*enumeration
= (void *)
1244 length_field
= (void *) enumeration
->container
;
1247 ret
= bt_ctf_field_integer_unsigned_get_value(length_field
, &length
);
1248 BT_ASSERT(ret
== 0);
1249 return bt_ctf_field_common_sequence_set_length((void *) field
,
1250 length
, (bt_ctf_field_common_create_func
) bt_ctf_field_create
);
1253 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_index(
1254 struct bt_ctf_field
*field
, uint64_t index
)
1256 return bt_ctf_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_index(
1257 (void *) field
, index
));
1260 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_name(
1261 struct bt_ctf_field
*field
, const char *name
)
1263 return bt_ctf_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_name(
1264 (void *) field
, name
));
1267 struct bt_ctf_field
*bt_ctf_field_array_get_field(
1268 struct bt_ctf_field
*field
, uint64_t index
)
1270 return bt_ctf_object_get_ref(
1271 bt_ctf_field_common_array_borrow_field((void *) field
, index
));
1274 struct bt_ctf_field
*bt_ctf_field_sequence_get_field(
1275 struct bt_ctf_field
*field
, uint64_t index
)
1277 return bt_ctf_object_get_ref(
1278 bt_ctf_field_common_sequence_borrow_field((void *) field
, index
));
1281 struct bt_ctf_field
*bt_ctf_field_variant_get_field(struct bt_ctf_field
*field
,
1282 struct bt_ctf_field
*tag_field
)
1284 struct bt_ctf_field_variant
*variant_field
= (void *) field
;
1285 struct bt_ctf_field_enumeration
*enum_field
= (void *) tag_field
;
1286 struct bt_ctf_field_type_common_variant
*variant_ft
;
1287 struct bt_ctf_field_type_common_enumeration
*tag_ft
;
1288 struct bt_ctf_field
*current_field
= NULL
;
1293 BT_ASSERT_PRE_NON_NULL(field
, "Variant field");
1294 BT_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
1295 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) tag_field
, "Tag field");
1296 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1297 (struct bt_ctf_field_common
*) tag_field
,
1298 BT_CTF_FIELD_TYPE_ID_ENUM
, "Tag field");
1299 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1300 (struct bt_ctf_field_common
*) field
,
1301 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
1303 bt_ctf_field_common_validate_recursive((void *) tag_field
) == 0,
1304 "Tag field is invalid: field-addr=%p", tag_field
);
1305 variant_ft
= BT_CTF_FROM_COMMON(variant_field
->common
.common
.type
);
1306 BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
1307 BT_CTF_TO_COMMON(variant_ft
->tag_ft
), enum_field
->common
.type
) == 0,
1308 "Unexpected tag field's type: expected-ft-addr=%p, "
1309 "tag-ft-addr=%p", variant_ft
->tag_ft
,
1310 enum_field
->common
.type
);
1311 tag_ft
= BT_CTF_FROM_COMMON(enum_field
->common
.type
);
1312 is_signed
= tag_ft
->container_ft
->is_signed
;
1317 ret
= bt_ctf_field_integer_signed_get_value(
1318 (void *) enum_field
->container
, &tag_ival
);
1319 tag_uval
= (uint64_t) tag_ival
;
1321 ret
= bt_ctf_field_integer_unsigned_get_value(
1322 (void *) enum_field
->container
, &tag_uval
);
1325 BT_ASSERT(ret
== 0);
1326 ret
= bt_ctf_field_common_variant_set_tag((void *) field
, tag_uval
,
1332 bt_ctf_object_put_ref(variant_field
->tag
);
1333 variant_field
->tag
= bt_ctf_object_get_ref(tag_field
);
1334 current_field
= bt_ctf_field_variant_get_current_field(field
);
1335 BT_ASSERT(current_field
);
1338 return current_field
;
1341 struct bt_ctf_field
*bt_ctf_field_variant_get_current_field(
1342 struct bt_ctf_field
*variant_field
)
1344 return bt_ctf_object_get_ref(bt_ctf_field_common_variant_borrow_current_field(
1345 (void *) variant_field
));
1349 struct bt_ctf_field
*bt_ctf_field_enumeration_borrow_container(
1350 struct bt_ctf_field
*field
)
1352 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1354 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
1355 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID((struct bt_ctf_field_common
*) field
,
1356 BT_CTF_FIELD_TYPE_ID_ENUM
, "Field");
1357 BT_ASSERT(enumeration
->container
);
1358 return (void *) enumeration
->container
;
1361 struct bt_ctf_field
*bt_ctf_field_enumeration_get_container(
1362 struct bt_ctf_field
*field
)
1364 return bt_ctf_object_get_ref(bt_ctf_field_enumeration_borrow_container(field
));
1367 int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field
*field
,
1370 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1372 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
1373 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1374 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer
), "Integer field");
1375 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1376 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1377 BT_ASSERT_PRE(bt_ctf_field_type_common_integer_is_signed(
1378 integer
->common
.type
),
1379 "Field's type is unsigned: field-addr=%p", field
);
1380 *value
= integer
->payload
.signd
;
1384 int bt_ctf_field_integer_signed_set_value(struct bt_ctf_field
*field
,
1388 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1389 struct bt_ctf_field_type_common_integer
*integer_type
;
1391 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
1392 BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer
), "Integer field");
1393 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1394 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1395 integer_type
= BT_CTF_FROM_COMMON(integer
->common
.type
);
1397 bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1398 "Field's type is unsigned: field-addr=%p", field
);
1399 BT_ASSERT_PRE(value_is_in_range_signed(integer_type
->size
, value
),
1400 "Value is out of bounds: value=%" PRId64
", field-addr=%p",
1402 integer
->payload
.signd
= value
;
1403 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer
), true);
1407 int bt_ctf_field_integer_unsigned_get_value(struct bt_ctf_field
*field
,
1410 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1412 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
1413 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1414 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer
), "Integer field");
1415 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1416 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1418 !bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1419 "Field's type is signed: field-addr=%p", field
);
1420 *value
= integer
->payload
.unsignd
;
1424 int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field
*field
,
1427 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1428 struct bt_ctf_field_type_common_integer
*integer_type
;
1430 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
1431 BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer
), "Integer field");
1432 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1433 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1434 integer_type
= BT_CTF_FROM_COMMON(integer
->common
.type
);
1436 !bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1437 "Field's type is signed: field-addr=%p", field
);
1438 BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type
->size
, value
),
1439 "Value is out of bounds: value=%" PRIu64
", field-addr=%p",
1441 integer
->payload
.unsignd
= value
;
1442 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer
), true);
1446 int bt_ctf_field_floating_point_get_value(struct bt_ctf_field
*field
,
1449 return bt_ctf_field_common_floating_point_get_value((void *) field
, value
);
1452 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field
*field
,
1455 return bt_ctf_field_common_floating_point_set_value((void *) field
, value
);
1458 const char *bt_ctf_field_string_get_value(struct bt_ctf_field
*field
)
1460 return bt_ctf_field_common_string_get_value((void *) field
);
1463 int bt_ctf_field_string_set_value(struct bt_ctf_field
*field
, const char *value
)
1465 return bt_ctf_field_common_string_set_value((void *) field
, value
);
1468 int bt_ctf_field_string_append(struct bt_ctf_field
*field
, const char *value
)
1470 return bt_ctf_field_common_string_append((void *) field
, value
);
1473 int bt_ctf_field_string_append_len(struct bt_ctf_field
*field
,
1474 const char *value
, unsigned int length
)
1476 return bt_ctf_field_common_string_append_len((void *) field
, value
, length
);
1479 struct bt_ctf_field
*bt_ctf_field_copy(struct bt_ctf_field
*field
)
1481 return (void *) bt_ctf_field_common_copy((void *) field
);
1485 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*type
)
1487 struct bt_ctf_field_common_integer
*integer
=
1488 g_new0(struct bt_ctf_field_common_integer
, 1);
1490 BT_LOGD("Creating CTF writer integer field object: ft-addr=%p", type
);
1493 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(integer
), (void *) type
,
1495 (bt_ctf_object_release_func
) bt_ctf_field_integer_destroy
,
1496 &bt_ctf_field_integer_methods
);
1497 integer
->common
.spec
.writer
.serialize_func
=
1498 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_integer_serialize
;
1499 BT_LOGD("Created CTF writer integer field object: addr=%p, ft-addr=%p",
1502 BT_LOGE_STR("Failed to allocate one integer field.");
1505 return (void *) integer
;
1509 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
1510 struct bt_ctf_field_type
*type
)
1512 struct bt_ctf_field_type_common_enumeration
*enum_ft
= (void *) type
;
1513 struct bt_ctf_field_enumeration
*enumeration
= g_new0(
1514 struct bt_ctf_field_enumeration
, 1);
1516 BT_LOGD("Creating CTF writer enumeration field object: ft-addr=%p", type
);
1519 BT_LOGE_STR("Failed to allocate one enumeration field.");
1523 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(enumeration
),
1525 true, (bt_ctf_object_release_func
)
1526 bt_ctf_field_enumeration_destroy_recursive
,
1527 &bt_ctf_field_enumeration_methods
);
1528 enumeration
->container
= (void *) bt_ctf_field_create(
1529 BT_CTF_FROM_COMMON(enum_ft
->container_ft
));
1530 if (!enumeration
->container
) {
1531 BT_CTF_OBJECT_PUT_REF_AND_RESET(enumeration
);
1535 enumeration
->common
.spec
.writer
.serialize_func
=
1536 (bt_ctf_field_serialize_recursive_func
)
1537 bt_ctf_field_enumeration_serialize_recursive
;
1538 BT_LOGD("Created CTF writer enumeration field object: addr=%p, ft-addr=%p",
1542 return (void *) enumeration
;
1546 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
1547 struct bt_ctf_field_type
*type
)
1549 struct bt_ctf_field_common_floating_point
*floating_point
;
1551 BT_LOGD("Creating CTF writer floating point number field object: ft-addr=%p", type
);
1552 floating_point
= g_new0(struct bt_ctf_field_common_floating_point
, 1);
1554 if (floating_point
) {
1555 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(floating_point
),
1557 true, (bt_ctf_object_release_func
)
1558 bt_ctf_field_floating_point_destroy
,
1559 &bt_ctf_field_floating_point_methods
);
1560 floating_point
->common
.spec
.writer
.serialize_func
=
1561 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_floating_point_serialize
;
1562 BT_LOGD("Created CTF writer floating point number field object: addr=%p, ft-addr=%p",
1563 floating_point
, type
);
1565 BT_LOGE_STR("Failed to allocate one floating point number field.");
1568 return (void *) floating_point
;
1572 struct bt_ctf_field
*bt_ctf_field_structure_create(
1573 struct bt_ctf_field_type
*type
)
1575 struct bt_ctf_field_common_structure
*structure
= g_new0(
1576 struct bt_ctf_field_common_structure
, 1);
1579 BT_LOGD("Creating CTF writer structure field object: ft-addr=%p", type
);
1582 BT_LOGE_STR("Failed to allocate one structure field.");
1586 iret
= bt_ctf_field_common_structure_initialize(BT_CTF_TO_COMMON(structure
),
1588 true, (bt_ctf_object_release_func
)
1589 bt_ctf_field_structure_destroy_recursive
,
1590 &bt_ctf_field_structure_methods
,
1591 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1592 (GDestroyNotify
) bt_ctf_object_put_ref
);
1593 structure
->common
.spec
.writer
.serialize_func
=
1594 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_structure_serialize_recursive
;
1596 BT_CTF_OBJECT_PUT_REF_AND_RESET(structure
);
1600 BT_LOGD("Created CTF writer structure field object: addr=%p, ft-addr=%p",
1604 return (void *) structure
;
1608 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*type
)
1610 struct bt_ctf_field_type_common_variant
*var_ft
= (void *) type
;
1611 struct bt_ctf_field_variant
*variant
= g_new0(
1612 struct bt_ctf_field_variant
, 1);
1614 BT_LOGD("Creating CTF writer variant field object: ft-addr=%p", type
);
1617 BT_LOGE_STR("Failed to allocate one variant field.");
1621 bt_ctf_field_common_variant_initialize(BT_CTF_TO_COMMON(BT_CTF_TO_COMMON(variant
)),
1623 true, (bt_ctf_object_release_func
)
1624 bt_ctf_field_variant_destroy_recursive
,
1625 &bt_ctf_field_variant_methods
,
1626 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1627 (GDestroyNotify
) bt_ctf_object_put_ref
);
1628 variant
->tag
= (void *) bt_ctf_field_create(
1629 BT_CTF_FROM_COMMON(var_ft
->tag_ft
));
1630 variant
->common
.common
.spec
.writer
.serialize_func
=
1631 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_variant_serialize_recursive
;
1632 BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p",
1636 return (void *) variant
;
1640 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*type
)
1642 struct bt_ctf_field_common_array
*array
=
1643 g_new0(struct bt_ctf_field_common_array
, 1);
1646 BT_LOGD("Creating CTF writer array field object: ft-addr=%p", type
);
1650 BT_LOGE_STR("Failed to allocate one array field.");
1654 ret
= bt_ctf_field_common_array_initialize(BT_CTF_TO_COMMON(array
),
1656 true, (bt_ctf_object_release_func
)
1657 bt_ctf_field_array_destroy_recursive
,
1658 &bt_ctf_field_array_methods
,
1659 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1660 (GDestroyNotify
) bt_ctf_object_put_ref
);
1661 array
->common
.spec
.writer
.serialize_func
=
1662 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_array_serialize_recursive
;
1664 BT_CTF_OBJECT_PUT_REF_AND_RESET(array
);
1668 BT_LOGD("Created CTF writer array field object: addr=%p, ft-addr=%p",
1672 return (void *) array
;
1676 struct bt_ctf_field
*bt_ctf_field_sequence_create(struct bt_ctf_field_type
*type
)
1678 struct bt_ctf_field_common_sequence
*sequence
= g_new0(
1679 struct bt_ctf_field_common_sequence
, 1);
1681 BT_LOGD("Creating CTF writer sequence field object: ft-addr=%p", type
);
1684 bt_ctf_field_common_sequence_initialize(BT_CTF_TO_COMMON(sequence
),
1686 true, (bt_ctf_object_release_func
)
1687 bt_ctf_field_sequence_destroy_recursive
,
1688 &bt_ctf_field_sequence_methods
,
1689 (GDestroyNotify
) bt_ctf_object_put_ref
);
1690 sequence
->common
.spec
.writer
.serialize_func
=
1691 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_sequence_serialize_recursive
;
1692 BT_LOGD("Created CTF writer sequence field object: addr=%p, ft-addr=%p",
1695 BT_LOGE_STR("Failed to allocate one sequence field.");
1698 return (void *) sequence
;
1702 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*type
)
1704 struct bt_ctf_field_common_string
*string
= g_new0(
1705 struct bt_ctf_field_common_string
, 1);
1707 BT_LOGD("Creating CTF writer string field object: ft-addr=%p", type
);
1710 bt_ctf_field_common_string_initialize(BT_CTF_TO_COMMON(string
),
1712 true, (bt_ctf_object_release_func
)
1713 bt_ctf_field_string_destroy
,
1714 &bt_ctf_field_string_methods
);
1715 string
->common
.spec
.writer
.serialize_func
=
1716 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_string_serialize
;
1717 BT_LOGD("Created CTF writer string field object: addr=%p, ft-addr=%p",
1720 BT_LOGE_STR("Failed to allocate one string field.");
1723 return (void *) string
;
1727 void bt_ctf_field_enumeration_set_is_frozen_recursive(
1728 struct bt_ctf_field_common
*field
, bool is_frozen
)
1730 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1732 if (enumeration
->container
) {
1733 bt_ctf_field_common_set_is_frozen_recursive(
1734 (void *) enumeration
->container
, is_frozen
);
1737 bt_ctf_field_common_generic_set_is_frozen((void *) field
, is_frozen
);
1741 int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common
*field
)
1744 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1746 if (enumeration
->container
) {
1747 ret
= bt_ctf_field_common_validate_recursive(
1748 (void *) enumeration
->container
);
1755 bt_bool
bt_ctf_field_enumeration_is_set_recursive(struct bt_ctf_field_common
*field
)
1757 bt_bool is_set
= BT_FALSE
;
1758 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1760 if (enumeration
->container
) {
1761 is_set
= bt_ctf_field_common_is_set_recursive(
1762 (void *) enumeration
->container
);
1769 void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common
*field
)
1771 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1773 if (enumeration
->container
) {
1774 bt_ctf_field_common_reset_recursive(
1775 (void *) enumeration
->container
);
1778 bt_ctf_field_common_generic_reset((void *) field
);
1782 void bt_ctf_field_variant_set_is_frozen_recursive(
1783 struct bt_ctf_field_common
*field
, bool is_frozen
)
1785 struct bt_ctf_field_variant
*variant
= (void *) field
;
1788 bt_ctf_field_common_set_is_frozen_recursive(
1789 (void *) variant
->tag
, is_frozen
);
1792 bt_ctf_field_common_variant_set_is_frozen_recursive((void *) field
,
1797 int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common
*field
)
1800 struct bt_ctf_field_variant
*variant
= (void *) field
;
1803 ret
= bt_ctf_field_common_validate_recursive(
1804 (void *) variant
->tag
);
1810 ret
= bt_ctf_field_common_variant_validate_recursive((void *) field
);
1817 bt_bool
bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common
*field
)
1820 struct bt_ctf_field_variant
*variant
= (void *) field
;
1823 is_set
= bt_ctf_field_common_is_set_recursive(
1824 (void *) variant
->tag
);
1830 is_set
= bt_ctf_field_common_variant_is_set_recursive((void *) field
);
1837 void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common
*field
)
1839 struct bt_ctf_field_variant
*variant
= (void *) field
;
1842 bt_ctf_field_common_reset_recursive(
1843 (void *) variant
->tag
);
1846 bt_ctf_field_common_variant_reset_recursive((void *) field
);
1850 static inline bool field_to_set_has_expected_type(
1851 struct bt_ctf_field_common
*struct_field
,
1852 const char *name
, struct bt_ctf_field_common
*value
)
1855 struct bt_ctf_field_type_common
*expected_field_type
= NULL
;
1857 expected_field_type
=
1858 bt_ctf_field_type_common_structure_borrow_field_type_by_name(
1859 struct_field
->type
, name
);
1861 if (bt_ctf_field_type_common_compare(expected_field_type
, value
->type
)) {
1862 BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
1863 "value-ft-addr=%p, expected-ft-addr=%p", value
->type
,
1864 expected_field_type
);
1874 int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field
*field
,
1875 const char *name
, struct bt_ctf_field
*value
)
1879 struct bt_ctf_field_common
*common_field
= (void *) field
;
1880 struct bt_ctf_field_common_structure
*structure
=
1881 BT_CTF_FROM_COMMON(common_field
);
1882 struct bt_ctf_field_common
*common_value
= (void *) value
;
1884 GHashTable
*field_name_to_index
;
1885 struct bt_ctf_field_type_common_structure
*structure_ft
;
1887 BT_ASSERT_PRE_NON_NULL(field
, "Parent field");
1888 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
1889 BT_ASSERT_PRE_NON_NULL(value
, "Value field");
1890 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(common_field
,
1891 BT_CTF_FIELD_TYPE_ID_STRUCT
, "Parent field");
1892 BT_ASSERT_PRE(field_to_set_has_expected_type(common_field
,
1893 name
, common_value
),
1894 "Value field's type is different from the expected field type.");
1895 field_quark
= g_quark_from_string(name
);
1896 structure_ft
= BT_CTF_FROM_COMMON(common_field
->type
);
1897 field_name_to_index
= structure_ft
->field_name_to_index
;
1898 if (!g_hash_table_lookup_extended(field_name_to_index
,
1899 GUINT_TO_POINTER(field_quark
), NULL
,
1900 (gpointer
*) &index
)) {
1901 BT_LOGV("Invalid parameter: no such field in structure field's type: "
1902 "struct-field-addr=%p, struct-ft-addr=%p, "
1903 "field-ft-addr=%p, name=\"%s\"",
1904 field
, common_field
->type
, common_value
->type
, name
);
1908 bt_ctf_object_get_ref(value
);
1909 BT_CTF_OBJECT_MOVE_REF(structure
->fields
->pdata
[index
], value
);