2 * SPDX-License-Identifier: MIT
4 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 #define BT_LOG_TAG "CTF-WRITER/FIELDS"
15 #include <babeltrace2-ctf-writer/object.h>
17 #include "common/align.h"
18 #include "common/assert.h"
19 #include "compat/compiler.h"
20 #include "compat/endian.h"
21 #include "compat/fcntl.h"
22 #include "ctfser/ctfser.h"
24 #include "assert-pre.h"
26 #include "field-types.h"
29 #define BT_CTF_ASSERT_PRE_CTF_FIELD_IS_INT_OR_ENUM(_field, _name) \
30 BT_CTF_ASSERT_PRE((_field)->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || \
31 (_field)->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, \
32 _name " is not an integer or an enumeration field: " \
33 "field-addr=%p", (_field))
35 struct bt_ctf_field_common
*bt_ctf_field_common_copy(struct bt_ctf_field_common
*field
)
37 struct bt_ctf_field_common
*copy
= NULL
;
39 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
40 BT_ASSERT_DBG(field_type_common_has_known_id(field
->type
));
41 BT_ASSERT_DBG(field
->methods
->copy
);
42 copy
= field
->methods
->copy(field
);
44 BT_LOGW("Cannot create field: ft-addr=%p", field
->type
);
48 bt_ctf_field_common_set(copy
, field
->payload_set
);
54 int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common
*field
,
55 struct bt_ctf_field_type_common
*type
,
56 bool is_shared
, bt_ctf_object_release_func release_func
,
57 struct bt_ctf_field_common_methods
*methods
,
58 bt_ctf_field_common_create_func field_create_func
,
59 GDestroyNotify field_release_func
)
62 struct bt_ctf_field_type_common_structure
*structure_type
=
63 BT_CTF_FROM_COMMON(type
);
64 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
67 BT_LOGD("Initializing common structure field object: ft-addr=%p", type
);
68 bt_ctf_field_common_initialize(field
, type
, is_shared
,
69 release_func
, methods
);
70 structure
->fields
= g_ptr_array_new_with_free_func(field_release_func
);
71 g_ptr_array_set_size(structure
->fields
, structure_type
->fields
->len
);
73 /* Create all fields contained in the structure field. */
74 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
75 struct bt_ctf_field_common
*member_field
;
76 struct bt_ctf_field_type_common_structure_field
*struct_field
=
77 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
79 member_field
= field_create_func(struct_field
->type
);
81 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
82 g_quark_to_string(struct_field
->name
), i
);
87 g_ptr_array_index(structure
->fields
, i
) = member_field
;
90 BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
97 int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common
*field
,
98 struct bt_ctf_field_type_common
*type
,
99 bool is_shared
, bt_ctf_object_release_func release_func
,
100 struct bt_ctf_field_common_methods
*methods
,
101 bt_ctf_field_common_create_func field_create_func
,
102 GDestroyNotify field_release_func
)
105 struct bt_ctf_field_type_common_variant
*variant_type
=
106 BT_CTF_FROM_COMMON(type
);
107 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
110 BT_LOGD("Initializing common variant field object: ft-addr=%p", type
);
111 bt_ctf_field_common_initialize(field
, type
, is_shared
,
112 release_func
, methods
);
113 ret
= bt_ctf_field_type_common_variant_update_choices(type
);
115 BT_LOGE("Cannot update common variant field type choices: "
120 variant
->fields
= g_ptr_array_new_with_free_func(field_release_func
);
121 g_ptr_array_set_size(variant
->fields
, variant_type
->choices
->len
);
123 /* Create all fields contained in the variant field. */
124 for (i
= 0; i
< variant_type
->choices
->len
; i
++) {
125 struct bt_ctf_field_common
*member_field
;
126 struct bt_ctf_field_type_common_variant_choice
*var_choice
=
127 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
130 member_field
= field_create_func(var_choice
->type
);
132 BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
133 g_quark_to_string(var_choice
->name
), i
);
138 g_ptr_array_index(variant
->fields
, i
) = member_field
;
141 BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
148 int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common
*field
,
149 struct bt_ctf_field_type_common
*type
,
150 bool is_shared
, bt_ctf_object_release_func release_func
,
151 struct bt_ctf_field_common_methods
*methods
)
154 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
156 BT_LOGD("Initializing common string field object: ft-addr=%p", type
);
157 bt_ctf_field_common_initialize(field
, type
, is_shared
,
158 release_func
, methods
);
159 string
->buf
= g_array_sized_new(FALSE
, FALSE
, sizeof(char), 1);
165 g_array_index(string
->buf
, char, 0) = '\0';
166 BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
173 int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common
*field
,
174 struct bt_ctf_field_type_common
*type
,
175 bool is_shared
, bt_ctf_object_release_func release_func
,
176 struct bt_ctf_field_common_methods
*methods
,
177 bt_ctf_field_common_create_func field_create_func
,
178 GDestroyNotify field_destroy_func
)
180 struct bt_ctf_field_type_common_array
*array_type
= BT_CTF_FROM_COMMON(type
);
181 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
182 unsigned int array_length
;
186 BT_LOGD("Initializing common array field object: ft-addr=%p", type
);
188 bt_ctf_field_common_initialize(field
, type
, is_shared
,
189 release_func
, methods
);
190 array_length
= array_type
->length
;
191 array
->elements
= g_ptr_array_sized_new(array_length
);
192 if (!array
->elements
) {
197 g_ptr_array_set_free_func(array
->elements
, field_destroy_func
);
198 g_ptr_array_set_size(array
->elements
, array_length
);
200 for (i
= 0; i
< array_length
; i
++) {
201 array
->elements
->pdata
[i
] = field_create_func(
202 array_type
->element_ft
);
203 if (!array
->elements
->pdata
[i
]) {
209 BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
216 int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common
*field
,
217 struct bt_ctf_field_type_common
*type
,
218 bool is_shared
, bt_ctf_object_release_func release_func
,
219 struct bt_ctf_field_common_methods
*methods
,
220 GDestroyNotify field_destroy_func
)
222 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
225 BT_LOGD("Initializing common sequence field object: ft-addr=%p", type
);
227 bt_ctf_field_common_initialize(field
, type
, is_shared
,
228 release_func
, methods
);
229 sequence
->elements
= g_ptr_array_new();
230 if (!sequence
->elements
) {
235 g_ptr_array_set_free_func(sequence
->elements
, field_destroy_func
);
236 BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
243 int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common
*field
)
245 return (field
&& field
->payload_set
) ? 0 : -1;
248 int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common
*field
)
252 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
254 BT_ASSERT_DBG(field
);
256 for (i
= 0; i
< structure
->fields
->len
; i
++) {
257 ret
= bt_ctf_field_common_validate_recursive(
258 (void *) structure
->fields
->pdata
[i
]);
264 this_ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
265 field
->type
, &name
, NULL
, i
);
266 BT_ASSERT_DBG(this_ret
== 0);
267 BT_CTF_ASSERT_PRE_MSG("Invalid structure field's field: "
268 "struct-field-addr=%p, field-name=\"%s\", "
269 "index=%" PRId64
", field-addr=%p",
270 field
, name
, i
, structure
->fields
->pdata
[i
]);
279 int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common
*field
)
282 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
284 BT_ASSERT_DBG(field
);
286 if (!variant
->current_field
) {
291 ret
= bt_ctf_field_common_validate_recursive(variant
->current_field
);
297 int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common
*field
)
301 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
303 BT_ASSERT_DBG(field
);
305 for (i
= 0; i
< array
->elements
->len
; i
++) {
306 ret
= bt_ctf_field_common_validate_recursive((void *) array
->elements
->pdata
[i
]);
308 BT_CTF_ASSERT_PRE_MSG("Invalid array field's element field: "
309 "array-field-addr=%p, %" PRId64
", "
310 "elem-field-addr=%p",
311 field
, i
, array
->elements
->pdata
[i
]);
320 int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common
*field
)
324 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
326 BT_ASSERT_DBG(field
);
328 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
329 ret
= bt_ctf_field_common_validate_recursive(
330 (void *) sequence
->elements
->pdata
[i
]);
332 BT_CTF_ASSERT_PRE_MSG("Invalid sequence field's element field: "
333 "seq-field-addr=%p, %" PRId64
", "
334 "elem-field-addr=%p",
335 field
, i
, sequence
->elements
->pdata
[i
]);
343 void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common
*field
)
345 BT_ASSERT_DBG(field
);
346 field
->payload_set
= false;
349 void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common
*field
)
352 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
354 BT_ASSERT_DBG(field
);
356 for (i
= 0; i
< structure
->fields
->len
; i
++) {
357 struct bt_ctf_field_common
*member
= structure
->fields
->pdata
[i
];
361 * Structure members are lazily initialized;
362 * skip if this member has not been allocated
368 bt_ctf_field_common_reset_recursive(member
);
372 void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common
*field
)
374 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
376 BT_ASSERT_DBG(field
);
377 variant
->current_field
= NULL
;
380 void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common
*field
)
383 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
385 BT_ASSERT_DBG(field
);
387 for (i
= 0; i
< array
->elements
->len
; i
++) {
388 struct bt_ctf_field_common
*member
= array
->elements
->pdata
[i
];
392 * Array elements are lazily initialized; skip
393 * if this member has not been allocated yet.
398 bt_ctf_field_common_reset_recursive(member
);
402 void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common
*field
)
404 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
407 BT_ASSERT_DBG(field
);
409 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
410 if (sequence
->elements
->pdata
[i
]) {
411 bt_ctf_field_common_reset_recursive(
412 sequence
->elements
->pdata
[i
]);
416 sequence
->length
= 0;
419 void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common
*field
,
422 field
->frozen
= is_frozen
;
425 void bt_ctf_field_common_structure_set_is_frozen_recursive(
426 struct bt_ctf_field_common
*field
, bool is_frozen
)
429 struct bt_ctf_field_common_structure
*structure_field
=
430 BT_CTF_FROM_COMMON(field
);
432 BT_LOGD("Freezing structure field object: addr=%p", field
);
434 for (i
= 0; i
< structure_field
->fields
->len
; i
++) {
435 struct bt_ctf_field_common
*struct_field
=
436 g_ptr_array_index(structure_field
->fields
, i
);
438 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64
,
440 bt_ctf_field_common_set_is_frozen_recursive(struct_field
,
444 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
447 void bt_ctf_field_common_variant_set_is_frozen_recursive(
448 struct bt_ctf_field_common
*field
, bool is_frozen
)
451 struct bt_ctf_field_common_variant
*variant_field
= BT_CTF_FROM_COMMON(field
);
453 BT_LOGD("Freezing variant field object: addr=%p", field
);
455 for (i
= 0; i
< variant_field
->fields
->len
; i
++) {
456 struct bt_ctf_field_common
*var_field
=
457 g_ptr_array_index(variant_field
->fields
, i
);
459 BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64
,
461 bt_ctf_field_common_set_is_frozen_recursive(var_field
, is_frozen
);
464 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
467 void bt_ctf_field_common_array_set_is_frozen_recursive(
468 struct bt_ctf_field_common
*field
, bool is_frozen
)
471 struct bt_ctf_field_common_array
*array_field
= BT_CTF_FROM_COMMON(field
);
473 BT_LOGD("Freezing array field object: addr=%p", field
);
475 for (i
= 0; i
< array_field
->elements
->len
; i
++) {
476 struct bt_ctf_field_common
*elem_field
=
477 g_ptr_array_index(array_field
->elements
, i
);
479 BT_LOGD("Freezing array field object's element field: "
480 "element-field-addr=%p, index=%" PRId64
,
482 bt_ctf_field_common_set_is_frozen_recursive(elem_field
, is_frozen
);
485 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
488 void bt_ctf_field_common_sequence_set_is_frozen_recursive(
489 struct bt_ctf_field_common
*field
, bool is_frozen
)
492 struct bt_ctf_field_common_sequence
*sequence_field
=
493 BT_CTF_FROM_COMMON(field
);
495 BT_LOGD("Freezing sequence field object: addr=%p", field
);
497 for (i
= 0; i
< sequence_field
->length
; i
++) {
498 struct bt_ctf_field_common
*elem_field
=
499 g_ptr_array_index(sequence_field
->elements
, i
);
501 BT_LOGD("Freezing sequence field object's element field: "
502 "element-field-addr=%p, index=%" PRId64
,
504 bt_ctf_field_common_set_is_frozen_recursive(elem_field
, is_frozen
);
507 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
510 void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
517 BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
519 BT_ASSERT_DBG(field_type_common_has_known_id(field
->type
));
520 BT_ASSERT_DBG(field
->methods
->set_is_frozen
);
521 field
->methods
->set_is_frozen(field
, is_frozen
);
527 bt_ctf_bool
bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common
*field
)
529 return field
&& field
->payload_set
;
532 bt_ctf_bool
bt_ctf_field_common_structure_is_set_recursive(
533 struct bt_ctf_field_common
*field
)
535 bt_ctf_bool is_set
= BT_CTF_FALSE
;
537 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
539 BT_ASSERT_DBG(field
);
541 for (i
= 0; i
< structure
->fields
->len
; i
++) {
542 is_set
= bt_ctf_field_common_is_set_recursive(
543 structure
->fields
->pdata
[i
]);
553 bt_ctf_bool
bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common
*field
)
555 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
556 bt_ctf_bool is_set
= BT_CTF_FALSE
;
558 BT_ASSERT_DBG(field
);
560 if (variant
->current_field
) {
561 is_set
= bt_ctf_field_common_is_set_recursive(
562 variant
->current_field
);
568 bt_ctf_bool
bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common
*field
)
571 bt_ctf_bool is_set
= BT_CTF_FALSE
;
572 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
574 BT_ASSERT_DBG(field
);
576 for (i
= 0; i
< array
->elements
->len
; i
++) {
577 is_set
= bt_ctf_field_common_is_set_recursive(array
->elements
->pdata
[i
]);
587 bt_ctf_bool
bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common
*field
)
590 bt_ctf_bool is_set
= BT_CTF_FALSE
;
591 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
593 BT_ASSERT_DBG(field
);
595 if (!sequence
->elements
) {
599 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
600 is_set
= bt_ctf_field_common_is_set_recursive(
601 sequence
->elements
->pdata
[i
]);
611 static struct bt_ctf_field_common_methods bt_ctf_field_integer_methods
= {
612 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
613 .validate
= bt_ctf_field_common_generic_validate
,
615 .is_set
= bt_ctf_field_common_generic_is_set
,
616 .reset
= bt_ctf_field_common_generic_reset
,
619 static struct bt_ctf_field_common_methods bt_ctf_field_floating_point_methods
= {
620 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
621 .validate
= bt_ctf_field_common_generic_validate
,
623 .is_set
= bt_ctf_field_common_generic_is_set
,
624 .reset
= bt_ctf_field_common_generic_reset
,
628 void bt_ctf_field_enumeration_set_is_frozen_recursive(
629 struct bt_ctf_field_common
*field
, bool is_frozen
);
632 int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common
*field
);
635 bt_ctf_bool
bt_ctf_field_enumeration_is_set_recursive(
636 struct bt_ctf_field_common
*field
);
639 void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common
*field
);
641 static struct bt_ctf_field_common_methods bt_ctf_field_enumeration_methods
= {
642 .set_is_frozen
= bt_ctf_field_enumeration_set_is_frozen_recursive
,
643 .validate
= bt_ctf_field_enumeration_validate_recursive
,
645 .is_set
= bt_ctf_field_enumeration_is_set_recursive
,
646 .reset
= bt_ctf_field_enumeration_reset_recursive
,
649 static struct bt_ctf_field_common_methods bt_ctf_field_string_methods
= {
650 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
651 .validate
= bt_ctf_field_common_generic_validate
,
653 .is_set
= bt_ctf_field_common_generic_is_set
,
654 .reset
= bt_ctf_field_common_generic_reset
,
657 static struct bt_ctf_field_common_methods bt_ctf_field_structure_methods
= {
658 .set_is_frozen
= bt_ctf_field_common_structure_set_is_frozen_recursive
,
659 .validate
= bt_ctf_field_common_structure_validate_recursive
,
661 .is_set
= bt_ctf_field_common_structure_is_set_recursive
,
662 .reset
= bt_ctf_field_common_structure_reset_recursive
,
665 static struct bt_ctf_field_common_methods bt_ctf_field_sequence_methods
= {
666 .set_is_frozen
= bt_ctf_field_common_sequence_set_is_frozen_recursive
,
667 .validate
= bt_ctf_field_common_sequence_validate_recursive
,
669 .is_set
= bt_ctf_field_common_sequence_is_set_recursive
,
670 .reset
= bt_ctf_field_common_sequence_reset_recursive
,
673 static struct bt_ctf_field_common_methods bt_ctf_field_array_methods
= {
674 .set_is_frozen
= bt_ctf_field_common_array_set_is_frozen_recursive
,
675 .validate
= bt_ctf_field_common_array_validate_recursive
,
677 .is_set
= bt_ctf_field_common_array_is_set_recursive
,
678 .reset
= bt_ctf_field_common_array_reset_recursive
,
682 void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
686 int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common
*field
);
689 bt_ctf_bool
bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common
*field
);
692 void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common
*field
);
694 static struct bt_ctf_field_common_methods bt_ctf_field_variant_methods
= {
695 .set_is_frozen
= bt_ctf_field_variant_set_is_frozen_recursive
,
696 .validate
= bt_ctf_field_variant_validate_recursive
,
698 .is_set
= bt_ctf_field_variant_is_set_recursive
,
699 .reset
= bt_ctf_field_variant_reset_recursive
,
703 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*);
706 struct bt_ctf_field
*bt_ctf_field_enumeration_create(struct bt_ctf_field_type
*);
709 struct bt_ctf_field
*bt_ctf_field_floating_point_create(struct bt_ctf_field_type
*);
712 struct bt_ctf_field
*bt_ctf_field_structure_create(struct bt_ctf_field_type
*);
715 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*);
718 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*);
721 struct bt_ctf_field
*bt_ctf_field_sequence_create(struct bt_ctf_field_type
*);
724 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*);
727 struct bt_ctf_field
*(* const field_create_funcs
[])(struct bt_ctf_field_type
*) = {
728 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_integer_create
,
729 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_enumeration_create
,
730 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = bt_ctf_field_floating_point_create
,
731 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_structure_create
,
732 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_variant_create
,
733 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_array_create
,
734 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_sequence_create
,
735 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_string_create
,
738 typedef int (*bt_ctf_field_serialize_recursive_func
)(
739 struct bt_ctf_field_common
*, struct bt_ctfser
*,
740 enum bt_ctf_byte_order
);
743 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*field
)
745 BT_LOGD("Destroying CTF writer integer field object: addr=%p", field
);
746 bt_ctf_field_common_integer_finalize((void *) field
);
751 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*field
)
753 BT_LOGD("Destroying CTF writer floating point field object: addr=%p",
755 bt_ctf_field_common_floating_point_finalize((void *) field
);
760 void bt_ctf_field_enumeration_destroy_recursive(struct bt_ctf_field
*field
)
762 struct bt_ctf_field_enumeration
*enumeration
= BT_CTF_FROM_COMMON(field
);
764 BT_LOGD("Destroying CTF writer enumeration field object: addr=%p",
766 BT_LOGD_STR("Putting container field.");
767 bt_ctf_object_put_ref(enumeration
->container
);
768 bt_ctf_field_common_finalize((void *) field
);
773 void bt_ctf_field_structure_destroy_recursive(struct bt_ctf_field
*field
)
775 BT_LOGD("Destroying CTF writer structure field object: addr=%p", field
);
776 bt_ctf_field_common_structure_finalize_recursive((void *) field
);
781 void bt_ctf_field_variant_destroy_recursive(struct bt_ctf_field
*field
)
783 struct bt_ctf_field_variant
*variant
= BT_CTF_FROM_COMMON(field
);
785 BT_LOGD("Destroying CTF writer variant field object: addr=%p", field
);
786 BT_LOGD_STR("Putting tag field.");
787 bt_ctf_object_put_ref(variant
->tag
);
788 bt_ctf_field_common_variant_finalize_recursive((void *) field
);
793 void bt_ctf_field_array_destroy_recursive(struct bt_ctf_field
*field
)
795 BT_LOGD("Destroying CTF writer array field object: addr=%p", field
);
796 bt_ctf_field_common_array_finalize_recursive((void *) field
);
801 void bt_ctf_field_sequence_destroy_recursive(struct bt_ctf_field
*field
)
803 BT_LOGD("Destroying CTF writer sequence field object: addr=%p", field
);
804 bt_ctf_field_common_sequence_finalize_recursive((void *) field
);
809 void bt_ctf_field_string_destroy(struct bt_ctf_field
*field
)
811 BT_LOGD("Destroying CTF writer string field object: addr=%p", field
);
812 bt_ctf_field_common_string_finalize((void *) field
);
816 int bt_ctf_field_serialize_recursive(struct bt_ctf_field
*field
,
817 struct bt_ctfser
*ctfser
,
818 enum bt_ctf_byte_order native_byte_order
)
820 struct bt_ctf_field_common
*field_common
= (void *) field
;
821 bt_ctf_field_serialize_recursive_func serialize_func
;
823 BT_ASSERT_DBG(ctfser
);
824 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
825 BT_ASSERT_DBG(field_common
->spec
.writer
.serialize_func
);
826 serialize_func
= field_common
->spec
.writer
.serialize_func
;
827 return serialize_func(field_common
, ctfser
,
832 int bt_ctf_field_integer_serialize(struct bt_ctf_field_common
*field
,
833 struct bt_ctfser
*ctfser
,
834 enum bt_ctf_byte_order native_byte_order
)
837 struct bt_ctf_field_type_common_integer
*int_type
=
838 BT_CTF_FROM_COMMON(field
->type
);
839 struct bt_ctf_field_common_integer
*int_field
=
840 BT_CTF_FROM_COMMON(field
);
841 enum bt_ctf_byte_order byte_order
;
843 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Integer field");
844 BT_LOGT("Serializing CTF writer integer field: addr=%p, native-bo=%s",
846 bt_ctf_byte_order_string(native_byte_order
));
847 byte_order
= int_type
->user_byte_order
;
848 if (byte_order
== BT_CTF_BYTE_ORDER_NATIVE
) {
849 byte_order
= native_byte_order
;
852 if (int_type
->is_signed
) {
853 ret
= bt_ctfser_write_signed_int(ctfser
,
854 int_field
->payload
.signd
, int_type
->common
.alignment
,
856 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
857 LITTLE_ENDIAN
: BIG_ENDIAN
);
859 ret
= bt_ctfser_write_unsigned_int(ctfser
,
860 int_field
->payload
.unsignd
, int_type
->common
.alignment
,
862 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
863 LITTLE_ENDIAN
: BIG_ENDIAN
);
866 if (G_UNLIKELY(ret
)) {
867 BT_LOGE("Cannot serialize integer field: ret=%d", ret
);
876 int bt_ctf_field_enumeration_serialize_recursive(
877 struct bt_ctf_field_common
*field
, struct bt_ctfser
*ctfser
,
878 enum bt_ctf_byte_order native_byte_order
)
880 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
882 BT_LOGT("Serializing enumeration field: addr=%p, native-bo=%s",
883 field
, bt_ctf_byte_order_string(native_byte_order
));
884 BT_LOGT_STR("Serializing enumeration field's payload field.");
885 return bt_ctf_field_serialize_recursive(
886 (void *) enumeration
->container
, ctfser
, native_byte_order
);
890 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field_common
*field
,
891 struct bt_ctfser
*ctfser
,
892 enum bt_ctf_byte_order native_byte_order
)
895 struct bt_ctf_field_type_common_floating_point
*flt_type
=
896 BT_CTF_FROM_COMMON(field
->type
);
897 struct bt_ctf_field_common_floating_point
*flt_field
= BT_CTF_FROM_COMMON(field
);
898 enum bt_ctf_byte_order byte_order
;
900 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Floating point number field");
901 BT_LOGT("Serializing floating point number field: "
902 "addr=%p, native-bo=%s", field
,
903 bt_ctf_byte_order_string(native_byte_order
));
905 byte_order
= flt_type
->user_byte_order
;
906 if (byte_order
== BT_CTF_BYTE_ORDER_NATIVE
) {
907 byte_order
= native_byte_order
;
910 if (flt_type
->mant_dig
== FLT_MANT_DIG
) {
911 ret
= bt_ctfser_write_float32(ctfser
, flt_field
->payload
,
912 flt_type
->common
.alignment
,
913 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
914 LITTLE_ENDIAN
: BIG_ENDIAN
);
915 } else if (flt_type
->mant_dig
== DBL_MANT_DIG
) {
916 ret
= bt_ctfser_write_float64(ctfser
, flt_field
->payload
,
917 flt_type
->common
.alignment
,
918 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
919 LITTLE_ENDIAN
: BIG_ENDIAN
);
924 if (G_UNLIKELY(ret
)) {
925 BT_LOGE("Cannot serialize floating point number field: "
935 int bt_ctf_field_structure_serialize_recursive(struct bt_ctf_field_common
*field
,
936 struct bt_ctfser
*ctfser
,
937 enum bt_ctf_byte_order native_byte_order
)
941 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
943 BT_LOGT("Serializing structure field: addr=%p, native-bo=%s",
944 field
, bt_ctf_byte_order_string(native_byte_order
));
945 ret
= bt_ctfser_align_offset_in_current_packet(ctfser
,
946 field
->type
->alignment
);
947 if (G_UNLIKELY(ret
)) {
948 BT_LOGE("Cannot align offset before serializing structure field: "
953 for (i
= 0; i
< structure
->fields
->len
; i
++) {
954 struct bt_ctf_field_common
*member
= g_ptr_array_index(
955 structure
->fields
, i
);
956 const char *field_name
= NULL
;
958 BT_LOGT("Serializing structure field's field: ser-offset=%" PRIu64
", "
959 "field-addr=%p, index=%" PRIu64
,
960 bt_ctfser_get_offset_in_current_packet_bits(ctfser
),
963 if (G_UNLIKELY(!member
)) {
964 ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
965 field
->type
, &field_name
, NULL
, i
);
966 BT_ASSERT_DBG(ret
== 0);
967 BT_LOGW("Cannot serialize structure field's field: field is not set: "
968 "struct-field-addr=%p, "
969 "field-name=\"%s\", index=%" PRId64
,
970 field
, field_name
, i
);
975 ret
= bt_ctf_field_serialize_recursive((void *) member
, ctfser
,
977 if (G_UNLIKELY(ret
)) {
978 ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
979 field
->type
, &field_name
, NULL
, i
);
980 BT_ASSERT_DBG(ret
== 0);
981 BT_LOGW("Cannot serialize structure field's field: "
982 "struct-field-addr=%p, field-addr=%p, "
983 "field-name=\"%s\", index=%" PRId64
,
984 field
->type
, member
, field_name
, i
);
994 int bt_ctf_field_variant_serialize_recursive(struct bt_ctf_field_common
*field
,
995 struct bt_ctfser
*ctfser
,
996 enum bt_ctf_byte_order native_byte_order
)
998 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
1000 BT_LOGT("Serializing variant field: addr=%p, native-bo=%s",
1001 field
, bt_ctf_byte_order_string(native_byte_order
));
1002 BT_LOGT_STR("Serializing variant field's payload field.");
1003 return bt_ctf_field_serialize_recursive(
1004 (void *) variant
->current_field
, ctfser
, native_byte_order
);
1008 int bt_ctf_field_array_serialize_recursive(struct bt_ctf_field_common
*field
,
1009 struct bt_ctfser
*ctfser
,
1010 enum bt_ctf_byte_order native_byte_order
)
1014 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
1016 BT_LOGT("Serializing array field: addr=%p, native-bo=%s",
1017 field
, bt_ctf_byte_order_string(native_byte_order
));
1019 for (i
= 0; i
< array
->elements
->len
; i
++) {
1020 struct bt_ctf_field_common
*elem_field
=
1021 g_ptr_array_index(array
->elements
, i
);
1023 BT_LOGT("Serializing array field's element field: "
1024 "ser-offset=%" PRIu64
", field-addr=%p, index=%" PRId64
,
1025 bt_ctfser_get_offset_in_current_packet_bits(ctfser
),
1027 ret
= bt_ctf_field_serialize_recursive(
1028 (void *) elem_field
, ctfser
, native_byte_order
);
1029 if (G_UNLIKELY(ret
)) {
1030 BT_LOGW("Cannot serialize array field's element field: "
1031 "array-field-addr=%p, field-addr=%p, "
1032 "index=%" PRId64
, field
, elem_field
, i
);
1042 int bt_ctf_field_sequence_serialize_recursive(struct bt_ctf_field_common
*field
,
1043 struct bt_ctfser
*ctfser
,
1044 enum bt_ctf_byte_order native_byte_order
)
1048 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
1050 BT_LOGT("Serializing sequence field: addr=%p, native-bo=%s",
1051 field
, bt_ctf_byte_order_string(native_byte_order
));
1053 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1054 struct bt_ctf_field_common
*elem_field
=
1055 g_ptr_array_index(sequence
->elements
, i
);
1057 BT_LOGT("Serializing sequence field's element field: "
1058 "ser-offset=%" PRIu64
", field-addr=%p, index=%" PRId64
,
1059 bt_ctfser_get_offset_in_current_packet_bits(ctfser
),
1061 ret
= bt_ctf_field_serialize_recursive(
1062 (void *) elem_field
, ctfser
, native_byte_order
);
1063 if (G_UNLIKELY(ret
)) {
1064 BT_LOGW("Cannot serialize sequence field's element field: "
1065 "sequence-field-addr=%p, field-addr=%p, "
1066 "index=%" PRId64
, field
, elem_field
, i
);
1076 int bt_ctf_field_string_serialize(struct bt_ctf_field_common
*field
,
1077 struct bt_ctfser
*ctfser
,
1078 enum bt_ctf_byte_order native_byte_order
)
1081 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
1083 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "String field");
1084 BT_LOGT("Serializing string field: addr=%p, native-bo=%s",
1085 field
, bt_ctf_byte_order_string((int) native_byte_order
));
1086 ret
= bt_ctfser_write_string(ctfser
, (const char *) string
->buf
->data
);
1087 if (G_UNLIKELY(ret
)) {
1088 BT_LOGE("Cannot serialize string field: ret=%d", ret
);
1097 struct bt_ctf_field
*bt_ctf_field_create(struct bt_ctf_field_type
*type
)
1099 struct bt_ctf_field
*field
= NULL
;
1100 enum bt_ctf_field_type_id type_id
;
1102 BT_CTF_ASSERT_PRE_NON_NULL(type
, "Field type");
1103 BT_ASSERT_DBG(field_type_common_has_known_id((void *) type
));
1104 BT_CTF_ASSERT_PRE(bt_ctf_field_type_common_validate((void *) type
) == 0,
1105 "Field type is invalid: ft-addr=%p", type
);
1106 type_id
= bt_ctf_field_type_get_type_id(type
);
1107 field
= field_create_funcs
[type_id
](type
);
1112 bt_ctf_field_type_common_freeze((void *) type
);
1119 struct bt_ctf_field_type
*bt_ctf_field_get_type(struct bt_ctf_field
*field
)
1121 return bt_ctf_object_get_ref(bt_ctf_field_common_borrow_type((void *) field
));
1125 enum bt_ctf_field_type_id
bt_ctf_field_get_type_id(struct bt_ctf_field
*field
)
1127 struct bt_ctf_field_common
*field_common
= (void *) field
;
1129 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
1130 return (int) field_common
->type
->id
;
1134 int bt_ctf_field_sequence_set_length(struct bt_ctf_field
*field
,
1135 struct bt_ctf_field
*length_field
)
1138 struct bt_ctf_field_common
*common_length_field
= (void *) length_field
;
1141 BT_CTF_ASSERT_PRE_NON_NULL(length_field
, "Length field");
1142 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) length_field
, "Length field");
1143 BT_CTF_ASSERT_PRE(common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_INTEGER
||
1144 common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_ENUM
,
1145 "Length field must be an integer or enumeration field: field-addr=%p",
1148 if (common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_ENUM
) {
1149 struct bt_ctf_field_enumeration
*enumeration
= (void *)
1152 length_field
= (void *) enumeration
->container
;
1155 ret
= bt_ctf_field_integer_unsigned_get_value(length_field
, &length
);
1156 BT_ASSERT_DBG(ret
== 0);
1157 return bt_ctf_field_common_sequence_set_length((void *) field
,
1158 length
, (bt_ctf_field_common_create_func
) bt_ctf_field_create
);
1162 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_index(
1163 struct bt_ctf_field
*field
, uint64_t index
)
1165 return bt_ctf_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_index(
1166 (void *) field
, index
));
1170 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_name(
1171 struct bt_ctf_field
*field
, const char *name
)
1173 return bt_ctf_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_name(
1174 (void *) field
, name
));
1178 struct bt_ctf_field
*bt_ctf_field_array_get_field(
1179 struct bt_ctf_field
*field
, uint64_t index
)
1181 return bt_ctf_object_get_ref(
1182 bt_ctf_field_common_array_borrow_field((void *) field
, index
));
1186 struct bt_ctf_field
*bt_ctf_field_sequence_get_field(
1187 struct bt_ctf_field
*field
, uint64_t index
)
1189 return bt_ctf_object_get_ref(
1190 bt_ctf_field_common_sequence_borrow_field((void *) field
, index
));
1194 struct bt_ctf_field
*bt_ctf_field_variant_get_field(struct bt_ctf_field
*field
,
1195 struct bt_ctf_field
*tag_field
)
1197 struct bt_ctf_field_variant
*variant_field
= (void *) field
;
1198 struct bt_ctf_field_enumeration
*enum_field
= (void *) tag_field
;
1199 struct bt_ctf_field_type_common_variant
*variant_ft
;
1200 struct bt_ctf_field_type_common_enumeration
*tag_ft
;
1201 struct bt_ctf_field
*current_field
= NULL
;
1202 bt_ctf_bool is_signed
;
1206 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Variant field");
1207 BT_CTF_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
1208 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) tag_field
, "Tag field");
1209 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1210 (struct bt_ctf_field_common
*) tag_field
,
1211 BT_CTF_FIELD_TYPE_ID_ENUM
, "Tag field");
1212 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1213 (struct bt_ctf_field_common
*) field
,
1214 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
1216 bt_ctf_field_common_validate_recursive((void *) tag_field
) == 0,
1217 "Tag field is invalid: field-addr=%p", tag_field
);
1218 variant_ft
= BT_CTF_FROM_COMMON(variant_field
->common
.common
.type
);
1219 BT_CTF_ASSERT_PRE(bt_ctf_field_type_common_compare(
1220 BT_CTF_TO_COMMON(variant_ft
->tag_ft
), enum_field
->common
.type
) == 0,
1221 "Unexpected tag field's type: expected-ft-addr=%p, "
1222 "tag-ft-addr=%p", variant_ft
->tag_ft
,
1223 enum_field
->common
.type
);
1224 tag_ft
= BT_CTF_FROM_COMMON(enum_field
->common
.type
);
1225 is_signed
= tag_ft
->container_ft
->is_signed
;
1230 ret
= bt_ctf_field_integer_signed_get_value(
1231 (void *) enum_field
->container
, &tag_ival
);
1232 tag_uval
= (uint64_t) tag_ival
;
1234 ret
= bt_ctf_field_integer_unsigned_get_value(
1235 (void *) enum_field
->container
, &tag_uval
);
1238 BT_ASSERT_DBG(ret
== 0);
1239 ret
= bt_ctf_field_common_variant_set_tag((void *) field
, tag_uval
,
1245 bt_ctf_object_put_ref(variant_field
->tag
);
1246 variant_field
->tag
= bt_ctf_object_get_ref(tag_field
);
1247 current_field
= bt_ctf_field_variant_get_current_field(field
);
1248 BT_ASSERT_DBG(current_field
);
1251 return current_field
;
1255 struct bt_ctf_field
*bt_ctf_field_variant_get_current_field(
1256 struct bt_ctf_field
*variant_field
)
1258 return bt_ctf_object_get_ref(bt_ctf_field_common_variant_borrow_current_field(
1259 (void *) variant_field
));
1262 struct bt_ctf_field
*bt_ctf_field_enumeration_borrow_container(
1263 struct bt_ctf_field
*field
)
1265 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1267 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
1268 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID((struct bt_ctf_field_common
*) field
,
1269 BT_CTF_FIELD_TYPE_ID_ENUM
, "Field");
1270 BT_ASSERT_DBG(enumeration
->container
);
1271 return (void *) enumeration
->container
;
1275 struct bt_ctf_field
*bt_ctf_field_enumeration_get_container(
1276 struct bt_ctf_field
*field
)
1278 return bt_ctf_object_get_ref(bt_ctf_field_enumeration_borrow_container(field
));
1282 int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field
*field
,
1285 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1287 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1288 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
1289 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer
), "Integer field");
1290 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1291 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1292 BT_CTF_ASSERT_PRE(bt_ctf_field_type_common_integer_is_signed(
1293 integer
->common
.type
),
1294 "Field's type is unsigned: field-addr=%p", field
);
1295 *value
= integer
->payload
.signd
;
1300 int bt_ctf_field_integer_signed_set_value(struct bt_ctf_field
*field
,
1304 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1305 struct bt_ctf_field_type_common_integer
*integer_type
;
1307 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1308 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer
), "Integer field");
1309 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1310 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1311 integer_type
= BT_CTF_FROM_COMMON(integer
->common
.type
);
1313 bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1314 "Field's type is unsigned: field-addr=%p", field
);
1315 BT_CTF_ASSERT_PRE(value_is_in_range_signed(integer_type
->size
, value
),
1316 "Value is out of bounds: value=%" PRId64
", field-addr=%p",
1318 integer
->payload
.signd
= value
;
1319 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer
), true);
1324 int bt_ctf_field_integer_unsigned_get_value(struct bt_ctf_field
*field
,
1327 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1329 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1330 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
1331 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer
), "Integer field");
1332 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1333 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1335 !bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1336 "Field's type is signed: field-addr=%p", field
);
1337 *value
= integer
->payload
.unsignd
;
1342 int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field
*field
,
1345 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1346 struct bt_ctf_field_type_common_integer
*integer_type
;
1348 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1349 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer
), "Integer field");
1350 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1351 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1352 integer_type
= BT_CTF_FROM_COMMON(integer
->common
.type
);
1354 !bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1355 "Field's type is signed: field-addr=%p", field
);
1356 BT_CTF_ASSERT_PRE(value_is_in_range_unsigned(integer_type
->size
, value
),
1357 "Value is out of bounds: value=%" PRIu64
", field-addr=%p",
1359 integer
->payload
.unsignd
= value
;
1360 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer
), true);
1365 int bt_ctf_field_floating_point_get_value(struct bt_ctf_field
*field
,
1368 return bt_ctf_field_common_floating_point_get_value((void *) field
, value
);
1372 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field
*field
,
1375 return bt_ctf_field_common_floating_point_set_value((void *) field
, value
);
1379 const char *bt_ctf_field_string_get_value(struct bt_ctf_field
*field
)
1381 return bt_ctf_field_common_string_get_value((void *) field
);
1385 int bt_ctf_field_string_set_value(struct bt_ctf_field
*field
, const char *value
)
1387 return bt_ctf_field_common_string_set_value((void *) field
, value
);
1391 int bt_ctf_field_string_append(struct bt_ctf_field
*field
, const char *value
)
1393 return bt_ctf_field_common_string_append((void *) field
, value
);
1397 int bt_ctf_field_string_append_len(struct bt_ctf_field
*field
,
1398 const char *value
, unsigned int length
)
1400 return bt_ctf_field_common_string_append_len((void *) field
, value
, length
);
1404 struct bt_ctf_field
*bt_ctf_field_copy(struct bt_ctf_field
*field
)
1406 return (void *) bt_ctf_field_common_copy((void *) field
);
1410 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*type
)
1412 struct bt_ctf_field_common_integer
*integer
=
1413 g_new0(struct bt_ctf_field_common_integer
, 1);
1415 BT_LOGD("Creating CTF writer integer field object: ft-addr=%p", type
);
1418 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(integer
), (void *) type
,
1420 (bt_ctf_object_release_func
) bt_ctf_field_integer_destroy
,
1421 &bt_ctf_field_integer_methods
);
1422 integer
->common
.spec
.writer
.serialize_func
=
1423 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_integer_serialize
;
1424 BT_LOGD("Created CTF writer integer field object: addr=%p, ft-addr=%p",
1427 BT_LOGE_STR("Failed to allocate one integer field.");
1430 return (void *) integer
;
1434 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
1435 struct bt_ctf_field_type
*type
)
1437 struct bt_ctf_field_type_common_enumeration
*enum_ft
= (void *) type
;
1438 struct bt_ctf_field_enumeration
*enumeration
= g_new0(
1439 struct bt_ctf_field_enumeration
, 1);
1441 BT_LOGD("Creating CTF writer enumeration field object: ft-addr=%p", type
);
1444 BT_LOGE_STR("Failed to allocate one enumeration field.");
1448 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(enumeration
),
1450 true, (bt_ctf_object_release_func
)
1451 bt_ctf_field_enumeration_destroy_recursive
,
1452 &bt_ctf_field_enumeration_methods
);
1453 enumeration
->container
= (void *) bt_ctf_field_create(
1454 BT_CTF_FROM_COMMON(enum_ft
->container_ft
));
1455 if (!enumeration
->container
) {
1456 BT_CTF_OBJECT_PUT_REF_AND_RESET(enumeration
);
1460 enumeration
->common
.spec
.writer
.serialize_func
=
1461 (bt_ctf_field_serialize_recursive_func
)
1462 bt_ctf_field_enumeration_serialize_recursive
;
1463 BT_LOGD("Created CTF writer enumeration field object: addr=%p, ft-addr=%p",
1467 return (void *) enumeration
;
1471 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
1472 struct bt_ctf_field_type
*type
)
1474 struct bt_ctf_field_common_floating_point
*floating_point
;
1476 BT_LOGD("Creating CTF writer floating point number field object: ft-addr=%p", type
);
1477 floating_point
= g_new0(struct bt_ctf_field_common_floating_point
, 1);
1479 if (floating_point
) {
1480 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(floating_point
),
1482 true, (bt_ctf_object_release_func
)
1483 bt_ctf_field_floating_point_destroy
,
1484 &bt_ctf_field_floating_point_methods
);
1485 floating_point
->common
.spec
.writer
.serialize_func
=
1486 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_floating_point_serialize
;
1487 BT_LOGD("Created CTF writer floating point number field object: addr=%p, ft-addr=%p",
1488 floating_point
, type
);
1490 BT_LOGE_STR("Failed to allocate one floating point number field.");
1493 return (void *) floating_point
;
1497 struct bt_ctf_field
*bt_ctf_field_structure_create(
1498 struct bt_ctf_field_type
*type
)
1500 struct bt_ctf_field_common_structure
*structure
= g_new0(
1501 struct bt_ctf_field_common_structure
, 1);
1504 BT_LOGD("Creating CTF writer structure field object: ft-addr=%p", type
);
1507 BT_LOGE_STR("Failed to allocate one structure field.");
1511 iret
= bt_ctf_field_common_structure_initialize(BT_CTF_TO_COMMON(structure
),
1513 true, (bt_ctf_object_release_func
)
1514 bt_ctf_field_structure_destroy_recursive
,
1515 &bt_ctf_field_structure_methods
,
1516 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1517 (GDestroyNotify
) bt_ctf_object_put_ref
);
1518 structure
->common
.spec
.writer
.serialize_func
=
1519 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_structure_serialize_recursive
;
1521 BT_CTF_OBJECT_PUT_REF_AND_RESET(structure
);
1525 BT_LOGD("Created CTF writer structure field object: addr=%p, ft-addr=%p",
1529 return (void *) structure
;
1533 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*type
)
1535 struct bt_ctf_field_type_common_variant
*var_ft
= (void *) type
;
1536 struct bt_ctf_field_variant
*variant
= g_new0(
1537 struct bt_ctf_field_variant
, 1);
1539 BT_LOGD("Creating CTF writer variant field object: ft-addr=%p", type
);
1542 BT_LOGE_STR("Failed to allocate one variant field.");
1546 bt_ctf_field_common_variant_initialize(BT_CTF_TO_COMMON(BT_CTF_TO_COMMON(variant
)),
1548 true, (bt_ctf_object_release_func
)
1549 bt_ctf_field_variant_destroy_recursive
,
1550 &bt_ctf_field_variant_methods
,
1551 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1552 (GDestroyNotify
) bt_ctf_object_put_ref
);
1553 variant
->tag
= (void *) bt_ctf_field_create(
1554 BT_CTF_FROM_COMMON(var_ft
->tag_ft
));
1555 variant
->common
.common
.spec
.writer
.serialize_func
=
1556 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_variant_serialize_recursive
;
1557 BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p",
1561 return (void *) variant
;
1565 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*type
)
1567 struct bt_ctf_field_common_array
*array
=
1568 g_new0(struct bt_ctf_field_common_array
, 1);
1571 BT_LOGD("Creating CTF writer array field object: ft-addr=%p", type
);
1572 BT_ASSERT_DBG(type
);
1575 BT_LOGE_STR("Failed to allocate one array field.");
1579 ret
= bt_ctf_field_common_array_initialize(BT_CTF_TO_COMMON(array
),
1581 true, (bt_ctf_object_release_func
)
1582 bt_ctf_field_array_destroy_recursive
,
1583 &bt_ctf_field_array_methods
,
1584 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1585 (GDestroyNotify
) bt_ctf_object_put_ref
);
1586 array
->common
.spec
.writer
.serialize_func
=
1587 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_array_serialize_recursive
;
1589 BT_CTF_OBJECT_PUT_REF_AND_RESET(array
);
1593 BT_LOGD("Created CTF writer array field object: addr=%p, ft-addr=%p",
1597 return (void *) array
;
1601 struct bt_ctf_field
*bt_ctf_field_sequence_create(struct bt_ctf_field_type
*type
)
1603 struct bt_ctf_field_common_sequence
*sequence
= g_new0(
1604 struct bt_ctf_field_common_sequence
, 1);
1606 BT_LOGD("Creating CTF writer sequence field object: ft-addr=%p", type
);
1609 bt_ctf_field_common_sequence_initialize(BT_CTF_TO_COMMON(sequence
),
1611 true, (bt_ctf_object_release_func
)
1612 bt_ctf_field_sequence_destroy_recursive
,
1613 &bt_ctf_field_sequence_methods
,
1614 (GDestroyNotify
) bt_ctf_object_put_ref
);
1615 sequence
->common
.spec
.writer
.serialize_func
=
1616 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_sequence_serialize_recursive
;
1617 BT_LOGD("Created CTF writer sequence field object: addr=%p, ft-addr=%p",
1620 BT_LOGE_STR("Failed to allocate one sequence field.");
1623 return (void *) sequence
;
1627 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*type
)
1629 struct bt_ctf_field_common_string
*string
= g_new0(
1630 struct bt_ctf_field_common_string
, 1);
1632 BT_LOGD("Creating CTF writer string field object: ft-addr=%p", type
);
1635 bt_ctf_field_common_string_initialize(BT_CTF_TO_COMMON(string
),
1637 true, (bt_ctf_object_release_func
)
1638 bt_ctf_field_string_destroy
,
1639 &bt_ctf_field_string_methods
);
1640 string
->common
.spec
.writer
.serialize_func
=
1641 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_string_serialize
;
1642 BT_LOGD("Created CTF writer string field object: addr=%p, ft-addr=%p",
1645 BT_LOGE_STR("Failed to allocate one string field.");
1648 return (void *) string
;
1652 void bt_ctf_field_enumeration_set_is_frozen_recursive(
1653 struct bt_ctf_field_common
*field
, bool is_frozen
)
1655 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1657 if (enumeration
->container
) {
1658 bt_ctf_field_common_set_is_frozen_recursive(
1659 (void *) enumeration
->container
, is_frozen
);
1662 bt_ctf_field_common_generic_set_is_frozen((void *) field
, is_frozen
);
1666 int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common
*field
)
1669 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1671 if (enumeration
->container
) {
1672 ret
= bt_ctf_field_common_validate_recursive(
1673 (void *) enumeration
->container
);
1680 bt_ctf_bool
bt_ctf_field_enumeration_is_set_recursive(struct bt_ctf_field_common
*field
)
1682 bt_ctf_bool is_set
= BT_CTF_FALSE
;
1683 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1685 if (enumeration
->container
) {
1686 is_set
= bt_ctf_field_common_is_set_recursive(
1687 (void *) enumeration
->container
);
1694 void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common
*field
)
1696 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1698 if (enumeration
->container
) {
1699 bt_ctf_field_common_reset_recursive(
1700 (void *) enumeration
->container
);
1703 bt_ctf_field_common_generic_reset((void *) field
);
1707 void bt_ctf_field_variant_set_is_frozen_recursive(
1708 struct bt_ctf_field_common
*field
, bool is_frozen
)
1710 struct bt_ctf_field_variant
*variant
= (void *) field
;
1713 bt_ctf_field_common_set_is_frozen_recursive(
1714 (void *) variant
->tag
, is_frozen
);
1717 bt_ctf_field_common_variant_set_is_frozen_recursive((void *) field
,
1722 int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common
*field
)
1725 struct bt_ctf_field_variant
*variant
= (void *) field
;
1728 ret
= bt_ctf_field_common_validate_recursive(
1729 (void *) variant
->tag
);
1735 ret
= bt_ctf_field_common_variant_validate_recursive((void *) field
);
1742 bt_ctf_bool
bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common
*field
)
1745 struct bt_ctf_field_variant
*variant
= (void *) field
;
1748 is_set
= bt_ctf_field_common_is_set_recursive(
1749 (void *) variant
->tag
);
1755 is_set
= bt_ctf_field_common_variant_is_set_recursive((void *) field
);
1762 void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common
*field
)
1764 struct bt_ctf_field_variant
*variant
= (void *) field
;
1767 bt_ctf_field_common_reset_recursive(
1768 (void *) variant
->tag
);
1771 bt_ctf_field_common_variant_reset_recursive((void *) field
);
1774 BT_CTF_ASSERT_PRE_FUNC
1775 static inline bool field_to_set_has_expected_type(
1776 struct bt_ctf_field_common
*struct_field
,
1777 const char *name
, struct bt_ctf_field_common
*value
)
1780 struct bt_ctf_field_type_common
*expected_field_type
= NULL
;
1782 expected_field_type
=
1783 bt_ctf_field_type_common_structure_borrow_field_type_by_name(
1784 struct_field
->type
, name
);
1786 if (bt_ctf_field_type_common_compare(expected_field_type
, value
->type
)) {
1787 BT_CTF_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
1788 "value-ft-addr=%p, expected-ft-addr=%p", value
->type
,
1789 expected_field_type
);
1798 int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field
*field
,
1799 const char *name
, struct bt_ctf_field
*value
)
1803 struct bt_ctf_field_common
*common_field
= (void *) field
;
1804 struct bt_ctf_field_common_structure
*structure
=
1805 BT_CTF_FROM_COMMON(common_field
);
1806 struct bt_ctf_field_common
*common_value
= (void *) value
;
1808 GHashTable
*field_name_to_index
;
1809 struct bt_ctf_field_type_common_structure
*structure_ft
;
1811 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Parent field");
1812 BT_CTF_ASSERT_PRE_NON_NULL(name
, "Field name");
1813 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value field");
1814 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(common_field
,
1815 BT_CTF_FIELD_TYPE_ID_STRUCT
, "Parent field");
1816 BT_CTF_ASSERT_PRE(field_to_set_has_expected_type(common_field
,
1817 name
, common_value
),
1818 "Value field's type is different from the expected field type.");
1819 field_quark
= g_quark_from_string(name
);
1820 structure_ft
= BT_CTF_FROM_COMMON(common_field
->type
);
1821 field_name_to_index
= structure_ft
->field_name_to_index
;
1822 if (!g_hash_table_lookup_extended(field_name_to_index
,
1823 GUINT_TO_POINTER(field_quark
), NULL
,
1824 (gpointer
*) &index
)) {
1825 BT_LOGT("Invalid parameter: no such field in structure field's type: "
1826 "struct-field-addr=%p, struct-ft-addr=%p, "
1827 "field-ft-addr=%p, name=\"%s\"",
1828 field
, common_field
->type
, common_value
->type
, name
);
1832 bt_ctf_object_get_ref(value
);
1833 BT_CTF_OBJECT_MOVE_REF(structure
->fields
->pdata
[index
], value
);