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"
32 #include <babeltrace2/ctf-writer/object.h>
34 #include "common/align.h"
35 #include "common/assert.h"
36 #include "compat/compiler.h"
37 #include "compat/endian.h"
38 #include "compat/fcntl.h"
39 #include "ctfser/ctfser.h"
41 #include "assert-pre.h"
43 #include "field-types.h"
46 #define BT_CTF_ASSERT_PRE_CTF_FIELD_IS_INT_OR_ENUM(_field, _name) \
47 BT_CTF_ASSERT_PRE((_field)->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || \
48 (_field)->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, \
49 _name " is not an integer or an enumeration field: " \
50 "field-addr=%p", (_field))
53 struct bt_ctf_field_common
*bt_ctf_field_common_copy(struct bt_ctf_field_common
*field
)
55 struct bt_ctf_field_common
*copy
= NULL
;
57 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
58 BT_ASSERT(field_type_common_has_known_id(field
->type
));
59 BT_ASSERT(field
->methods
->copy
);
60 copy
= field
->methods
->copy(field
);
62 BT_LOGW("Cannot create field: ft-addr=%p", field
->type
);
66 bt_ctf_field_common_set(copy
, field
->payload_set
);
73 int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common
*field
,
74 struct bt_ctf_field_type_common
*type
,
75 bool is_shared
, bt_ctf_object_release_func release_func
,
76 struct bt_ctf_field_common_methods
*methods
,
77 bt_ctf_field_common_create_func field_create_func
,
78 GDestroyNotify field_release_func
)
81 struct bt_ctf_field_type_common_structure
*structure_type
=
82 BT_CTF_FROM_COMMON(type
);
83 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
86 BT_LOGD("Initializing common structure field object: ft-addr=%p", type
);
87 bt_ctf_field_common_initialize(field
, type
, is_shared
,
88 release_func
, methods
);
89 structure
->fields
= g_ptr_array_new_with_free_func(field_release_func
);
90 g_ptr_array_set_size(structure
->fields
, structure_type
->fields
->len
);
92 /* Create all fields contained in the structure field. */
93 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
94 struct bt_ctf_field_common
*field
;
95 struct bt_ctf_field_type_common_structure_field
*struct_field
=
96 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
98 field
= field_create_func(struct_field
->type
);
100 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
101 g_quark_to_string(struct_field
->name
), i
);
106 g_ptr_array_index(structure
->fields
, i
) = field
;
109 BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
117 int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common
*field
,
118 struct bt_ctf_field_type_common
*type
,
119 bool is_shared
, bt_ctf_object_release_func release_func
,
120 struct bt_ctf_field_common_methods
*methods
,
121 bt_ctf_field_common_create_func field_create_func
,
122 GDestroyNotify field_release_func
)
125 struct bt_ctf_field_type_common_variant
*variant_type
=
126 BT_CTF_FROM_COMMON(type
);
127 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
130 BT_LOGD("Initializing common variant field object: ft-addr=%p", type
);
131 bt_ctf_field_common_initialize(field
, type
, is_shared
,
132 release_func
, methods
);
133 ret
= bt_ctf_field_type_common_variant_update_choices(type
);
135 BT_LOGE("Cannot update common variant field type choices: "
140 variant
->fields
= g_ptr_array_new_with_free_func(field_release_func
);
141 g_ptr_array_set_size(variant
->fields
, variant_type
->choices
->len
);
143 /* Create all fields contained in the variant field. */
144 for (i
= 0; i
< variant_type
->choices
->len
; i
++) {
145 struct bt_ctf_field_common
*field
;
146 struct bt_ctf_field_type_common_variant_choice
*var_choice
=
147 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
150 field
= field_create_func(var_choice
->type
);
152 BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
153 g_quark_to_string(var_choice
->name
), i
);
158 g_ptr_array_index(variant
->fields
, i
) = field
;
161 BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
169 int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common
*field
,
170 struct bt_ctf_field_type_common
*type
,
171 bool is_shared
, bt_ctf_object_release_func release_func
,
172 struct bt_ctf_field_common_methods
*methods
)
175 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
177 BT_LOGD("Initializing common string field object: ft-addr=%p", type
);
178 bt_ctf_field_common_initialize(field
, type
, is_shared
,
179 release_func
, methods
);
180 string
->buf
= g_array_sized_new(FALSE
, FALSE
, sizeof(char), 1);
186 g_array_index(string
->buf
, char, 0) = '\0';
187 BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
195 int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common
*field
,
196 struct bt_ctf_field_type_common
*type
,
197 bool is_shared
, bt_ctf_object_release_func release_func
,
198 struct bt_ctf_field_common_methods
*methods
,
199 bt_ctf_field_common_create_func field_create_func
,
200 GDestroyNotify field_destroy_func
)
202 struct bt_ctf_field_type_common_array
*array_type
= BT_CTF_FROM_COMMON(type
);
203 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
204 unsigned int array_length
;
208 BT_LOGD("Initializing common array field object: ft-addr=%p", type
);
210 bt_ctf_field_common_initialize(field
, type
, is_shared
,
211 release_func
, methods
);
212 array_length
= array_type
->length
;
213 array
->elements
= g_ptr_array_sized_new(array_length
);
214 if (!array
->elements
) {
219 g_ptr_array_set_free_func(array
->elements
, field_destroy_func
);
220 g_ptr_array_set_size(array
->elements
, array_length
);
222 for (i
= 0; i
< array_length
; i
++) {
223 array
->elements
->pdata
[i
] = field_create_func(
224 array_type
->element_ft
);
225 if (!array
->elements
->pdata
[i
]) {
231 BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
239 int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common
*field
,
240 struct bt_ctf_field_type_common
*type
,
241 bool is_shared
, bt_ctf_object_release_func release_func
,
242 struct bt_ctf_field_common_methods
*methods
,
243 GDestroyNotify field_destroy_func
)
245 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
248 BT_LOGD("Initializing common sequence field object: ft-addr=%p", type
);
250 bt_ctf_field_common_initialize(field
, type
, is_shared
,
251 release_func
, methods
);
252 sequence
->elements
= g_ptr_array_new();
253 if (!sequence
->elements
) {
258 g_ptr_array_set_free_func(sequence
->elements
, field_destroy_func
);
259 BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
267 int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common
*field
)
269 return (field
&& field
->payload_set
) ? 0 : -1;
273 int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common
*field
)
277 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
281 for (i
= 0; i
< structure
->fields
->len
; i
++) {
282 ret
= bt_ctf_field_common_validate_recursive(
283 (void *) structure
->fields
->pdata
[i
]);
289 this_ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
290 field
->type
, &name
, NULL
, i
);
291 BT_ASSERT(this_ret
== 0);
292 BT_CTF_ASSERT_PRE_MSG("Invalid structure field's field: "
293 "struct-field-addr=%p, field-name=\"%s\", "
294 "index=%" PRId64
", field-addr=%p",
295 field
, name
, i
, structure
->fields
->pdata
[i
]);
305 int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common
*field
)
308 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
312 if (!variant
->current_field
) {
317 ret
= bt_ctf_field_common_validate_recursive(variant
->current_field
);
324 int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common
*field
)
328 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
332 for (i
= 0; i
< array
->elements
->len
; i
++) {
333 ret
= bt_ctf_field_common_validate_recursive((void *) array
->elements
->pdata
[i
]);
335 BT_CTF_ASSERT_PRE_MSG("Invalid array field's element field: "
336 "array-field-addr=%p, %" PRId64
", "
337 "elem-field-addr=%p",
338 field
, i
, array
->elements
->pdata
[i
]);
348 int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common
*field
)
352 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
356 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
357 ret
= bt_ctf_field_common_validate_recursive(
358 (void *) sequence
->elements
->pdata
[i
]);
360 BT_CTF_ASSERT_PRE_MSG("Invalid sequence field's element field: "
361 "seq-field-addr=%p, %" PRId64
", "
362 "elem-field-addr=%p",
363 field
, i
, sequence
->elements
->pdata
[i
]);
372 void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common
*field
)
375 field
->payload_set
= false;
379 void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common
*field
)
382 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
386 for (i
= 0; i
< structure
->fields
->len
; i
++) {
387 struct bt_ctf_field_common
*member
= structure
->fields
->pdata
[i
];
391 * Structure members are lazily initialized;
392 * skip if this member has not been allocated
398 bt_ctf_field_common_reset_recursive(member
);
403 void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common
*field
)
405 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
408 variant
->current_field
= NULL
;
412 void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common
*field
)
415 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
419 for (i
= 0; i
< array
->elements
->len
; i
++) {
420 struct bt_ctf_field_common
*member
= array
->elements
->pdata
[i
];
424 * Array elements are lazily initialized; skip
425 * if this member has not been allocated yet.
430 bt_ctf_field_common_reset_recursive(member
);
435 void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common
*field
)
437 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
442 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
443 if (sequence
->elements
->pdata
[i
]) {
444 bt_ctf_field_common_reset_recursive(
445 sequence
->elements
->pdata
[i
]);
449 sequence
->length
= 0;
453 void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common
*field
,
456 field
->frozen
= is_frozen
;
460 void bt_ctf_field_common_structure_set_is_frozen_recursive(
461 struct bt_ctf_field_common
*field
, bool is_frozen
)
464 struct bt_ctf_field_common_structure
*structure_field
=
465 BT_CTF_FROM_COMMON(field
);
467 BT_LOGD("Freezing structure field object: addr=%p", field
);
469 for (i
= 0; i
< structure_field
->fields
->len
; i
++) {
470 struct bt_ctf_field_common
*struct_field
=
471 g_ptr_array_index(structure_field
->fields
, i
);
473 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64
,
475 bt_ctf_field_common_set_is_frozen_recursive(struct_field
,
479 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
483 void bt_ctf_field_common_variant_set_is_frozen_recursive(
484 struct bt_ctf_field_common
*field
, bool is_frozen
)
487 struct bt_ctf_field_common_variant
*variant_field
= BT_CTF_FROM_COMMON(field
);
489 BT_LOGD("Freezing variant field object: addr=%p", field
);
491 for (i
= 0; i
< variant_field
->fields
->len
; i
++) {
492 struct bt_ctf_field_common
*var_field
=
493 g_ptr_array_index(variant_field
->fields
, i
);
495 BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64
,
497 bt_ctf_field_common_set_is_frozen_recursive(var_field
, is_frozen
);
500 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
504 void bt_ctf_field_common_array_set_is_frozen_recursive(
505 struct bt_ctf_field_common
*field
, bool is_frozen
)
508 struct bt_ctf_field_common_array
*array_field
= BT_CTF_FROM_COMMON(field
);
510 BT_LOGD("Freezing array field object: addr=%p", field
);
512 for (i
= 0; i
< array_field
->elements
->len
; i
++) {
513 struct bt_ctf_field_common
*elem_field
=
514 g_ptr_array_index(array_field
->elements
, i
);
516 BT_LOGD("Freezing array field object's element field: "
517 "element-field-addr=%p, index=%" PRId64
,
519 bt_ctf_field_common_set_is_frozen_recursive(elem_field
, is_frozen
);
522 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
526 void bt_ctf_field_common_sequence_set_is_frozen_recursive(
527 struct bt_ctf_field_common
*field
, bool is_frozen
)
530 struct bt_ctf_field_common_sequence
*sequence_field
=
531 BT_CTF_FROM_COMMON(field
);
533 BT_LOGD("Freezing sequence field object: addr=%p", field
);
535 for (i
= 0; i
< sequence_field
->length
; i
++) {
536 struct bt_ctf_field_common
*elem_field
=
537 g_ptr_array_index(sequence_field
->elements
, i
);
539 BT_LOGD("Freezing sequence field object's element field: "
540 "element-field-addr=%p, index=%" PRId64
,
542 bt_ctf_field_common_set_is_frozen_recursive(elem_field
, is_frozen
);
545 bt_ctf_field_common_generic_set_is_frozen(field
, is_frozen
);
549 void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
556 BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
558 BT_ASSERT(field_type_common_has_known_id(field
->type
));
559 BT_ASSERT(field
->methods
->set_is_frozen
);
560 field
->methods
->set_is_frozen(field
, is_frozen
);
567 bt_bool
bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common
*field
)
569 return field
&& field
->payload_set
;
573 bt_bool
bt_ctf_field_common_structure_is_set_recursive(
574 struct bt_ctf_field_common
*field
)
576 bt_bool is_set
= BT_FALSE
;
578 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
582 for (i
= 0; i
< structure
->fields
->len
; i
++) {
583 is_set
= bt_ctf_field_common_is_set_recursive(
584 structure
->fields
->pdata
[i
]);
595 bt_bool
bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common
*field
)
597 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
598 bt_bool is_set
= BT_FALSE
;
602 if (variant
->current_field
) {
603 is_set
= bt_ctf_field_common_is_set_recursive(
604 variant
->current_field
);
611 bt_bool
bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common
*field
)
614 bt_bool is_set
= BT_FALSE
;
615 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
619 for (i
= 0; i
< array
->elements
->len
; i
++) {
620 is_set
= bt_ctf_field_common_is_set_recursive(array
->elements
->pdata
[i
]);
631 bt_bool
bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common
*field
)
634 bt_bool is_set
= BT_FALSE
;
635 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
639 if (!sequence
->elements
) {
643 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
644 is_set
= bt_ctf_field_common_is_set_recursive(
645 sequence
->elements
->pdata
[i
]);
655 static struct bt_ctf_field_common_methods bt_ctf_field_integer_methods
= {
656 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
657 .validate
= bt_ctf_field_common_generic_validate
,
659 .is_set
= bt_ctf_field_common_generic_is_set
,
660 .reset
= bt_ctf_field_common_generic_reset
,
663 static struct bt_ctf_field_common_methods bt_ctf_field_floating_point_methods
= {
664 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
665 .validate
= bt_ctf_field_common_generic_validate
,
667 .is_set
= bt_ctf_field_common_generic_is_set
,
668 .reset
= bt_ctf_field_common_generic_reset
,
672 void bt_ctf_field_enumeration_set_is_frozen_recursive(
673 struct bt_ctf_field_common
*field
, bool is_frozen
);
676 int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common
*field
);
679 bt_bool
bt_ctf_field_enumeration_is_set_recursive(
680 struct bt_ctf_field_common
*field
);
683 void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common
*field
);
685 static struct bt_ctf_field_common_methods bt_ctf_field_enumeration_methods
= {
686 .set_is_frozen
= bt_ctf_field_enumeration_set_is_frozen_recursive
,
687 .validate
= bt_ctf_field_enumeration_validate_recursive
,
689 .is_set
= bt_ctf_field_enumeration_is_set_recursive
,
690 .reset
= bt_ctf_field_enumeration_reset_recursive
,
693 static struct bt_ctf_field_common_methods bt_ctf_field_string_methods
= {
694 .set_is_frozen
= bt_ctf_field_common_generic_set_is_frozen
,
695 .validate
= bt_ctf_field_common_generic_validate
,
697 .is_set
= bt_ctf_field_common_generic_is_set
,
698 .reset
= bt_ctf_field_common_generic_reset
,
701 static struct bt_ctf_field_common_methods bt_ctf_field_structure_methods
= {
702 .set_is_frozen
= bt_ctf_field_common_structure_set_is_frozen_recursive
,
703 .validate
= bt_ctf_field_common_structure_validate_recursive
,
705 .is_set
= bt_ctf_field_common_structure_is_set_recursive
,
706 .reset
= bt_ctf_field_common_structure_reset_recursive
,
709 static struct bt_ctf_field_common_methods bt_ctf_field_sequence_methods
= {
710 .set_is_frozen
= bt_ctf_field_common_sequence_set_is_frozen_recursive
,
711 .validate
= bt_ctf_field_common_sequence_validate_recursive
,
713 .is_set
= bt_ctf_field_common_sequence_is_set_recursive
,
714 .reset
= bt_ctf_field_common_sequence_reset_recursive
,
717 static struct bt_ctf_field_common_methods bt_ctf_field_array_methods
= {
718 .set_is_frozen
= bt_ctf_field_common_array_set_is_frozen_recursive
,
719 .validate
= bt_ctf_field_common_array_validate_recursive
,
721 .is_set
= bt_ctf_field_common_array_is_set_recursive
,
722 .reset
= bt_ctf_field_common_array_reset_recursive
,
726 void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
730 int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common
*field
);
733 bt_bool
bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common
*field
);
736 void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common
*field
);
738 static struct bt_ctf_field_common_methods bt_ctf_field_variant_methods
= {
739 .set_is_frozen
= bt_ctf_field_variant_set_is_frozen_recursive
,
740 .validate
= bt_ctf_field_variant_validate_recursive
,
742 .is_set
= bt_ctf_field_variant_is_set_recursive
,
743 .reset
= bt_ctf_field_variant_reset_recursive
,
747 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*);
750 struct bt_ctf_field
*bt_ctf_field_enumeration_create(struct bt_ctf_field_type
*);
753 struct bt_ctf_field
*bt_ctf_field_floating_point_create(struct bt_ctf_field_type
*);
756 struct bt_ctf_field
*bt_ctf_field_structure_create(struct bt_ctf_field_type
*);
759 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*);
762 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*);
765 struct bt_ctf_field
*bt_ctf_field_sequence_create(struct bt_ctf_field_type
*);
768 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*);
771 struct bt_ctf_field
*(* const field_create_funcs
[])(struct bt_ctf_field_type
*) = {
772 [BT_CTF_FIELD_TYPE_ID_INTEGER
] = bt_ctf_field_integer_create
,
773 [BT_CTF_FIELD_TYPE_ID_ENUM
] = bt_ctf_field_enumeration_create
,
774 [BT_CTF_FIELD_TYPE_ID_FLOAT
] = bt_ctf_field_floating_point_create
,
775 [BT_CTF_FIELD_TYPE_ID_STRUCT
] = bt_ctf_field_structure_create
,
776 [BT_CTF_FIELD_TYPE_ID_VARIANT
] = bt_ctf_field_variant_create
,
777 [BT_CTF_FIELD_TYPE_ID_ARRAY
] = bt_ctf_field_array_create
,
778 [BT_CTF_FIELD_TYPE_ID_SEQUENCE
] = bt_ctf_field_sequence_create
,
779 [BT_CTF_FIELD_TYPE_ID_STRING
] = bt_ctf_field_string_create
,
782 typedef int (*bt_ctf_field_serialize_recursive_func
)(
783 struct bt_ctf_field_common
*, struct bt_ctfser
*,
784 enum bt_ctf_byte_order
);
787 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*field
)
789 BT_LOGD("Destroying CTF writer integer field object: addr=%p", field
);
790 bt_ctf_field_common_integer_finalize((void *) field
);
795 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*field
)
797 BT_LOGD("Destroying CTF writer floating point field object: addr=%p",
799 bt_ctf_field_common_floating_point_finalize((void *) field
);
804 void bt_ctf_field_enumeration_destroy_recursive(struct bt_ctf_field
*field
)
806 struct bt_ctf_field_enumeration
*enumeration
= BT_CTF_FROM_COMMON(field
);
808 BT_LOGD("Destroying CTF writer enumeration field object: addr=%p",
810 BT_LOGD_STR("Putting container field.");
811 bt_ctf_object_put_ref(enumeration
->container
);
812 bt_ctf_field_common_finalize((void *) field
);
817 void bt_ctf_field_structure_destroy_recursive(struct bt_ctf_field
*field
)
819 BT_LOGD("Destroying CTF writer structure field object: addr=%p", field
);
820 bt_ctf_field_common_structure_finalize_recursive((void *) field
);
825 void bt_ctf_field_variant_destroy_recursive(struct bt_ctf_field
*field
)
827 struct bt_ctf_field_variant
*variant
= BT_CTF_FROM_COMMON(field
);
829 BT_LOGD("Destroying CTF writer variant field object: addr=%p", field
);
830 BT_LOGD_STR("Putting tag field.");
831 bt_ctf_object_put_ref(variant
->tag
);
832 bt_ctf_field_common_variant_finalize_recursive((void *) field
);
837 void bt_ctf_field_array_destroy_recursive(struct bt_ctf_field
*field
)
839 BT_LOGD("Destroying CTF writer array field object: addr=%p", field
);
840 bt_ctf_field_common_array_finalize_recursive((void *) field
);
845 void bt_ctf_field_sequence_destroy_recursive(struct bt_ctf_field
*field
)
847 BT_LOGD("Destroying CTF writer sequence field object: addr=%p", field
);
848 bt_ctf_field_common_sequence_finalize_recursive((void *) field
);
853 void bt_ctf_field_string_destroy(struct bt_ctf_field
*field
)
855 BT_LOGD("Destroying CTF writer string field object: addr=%p", field
);
856 bt_ctf_field_common_string_finalize((void *) field
);
861 int bt_ctf_field_serialize_recursive(struct bt_ctf_field
*field
,
862 struct bt_ctfser
*ctfser
,
863 enum bt_ctf_byte_order native_byte_order
)
865 struct bt_ctf_field_common
*field_common
= (void *) field
;
866 bt_ctf_field_serialize_recursive_func serialize_func
;
869 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
870 BT_ASSERT(field_common
->spec
.writer
.serialize_func
);
871 serialize_func
= field_common
->spec
.writer
.serialize_func
;
872 return serialize_func(field_common
, ctfser
,
877 int bt_ctf_field_integer_serialize(struct bt_ctf_field_common
*field
,
878 struct bt_ctfser
*ctfser
,
879 enum bt_ctf_byte_order native_byte_order
)
882 struct bt_ctf_field_type_common_integer
*int_type
=
883 BT_CTF_FROM_COMMON(field
->type
);
884 struct bt_ctf_field_common_integer
*int_field
=
885 BT_CTF_FROM_COMMON(field
);
886 enum bt_ctf_byte_order byte_order
;
888 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Integer field");
889 BT_LOGV("Serializing CTF writer integer field: addr=%p, native-bo=%s",
891 bt_ctf_byte_order_string(native_byte_order
));
892 byte_order
= int_type
->user_byte_order
;
893 if (byte_order
== BT_CTF_BYTE_ORDER_NATIVE
) {
894 byte_order
= native_byte_order
;
897 if (int_type
->is_signed
) {
898 ret
= bt_ctfser_write_signed_int(ctfser
,
899 int_field
->payload
.signd
, int_type
->common
.alignment
,
901 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
902 LITTLE_ENDIAN
: BIG_ENDIAN
);
904 ret
= bt_ctfser_write_unsigned_int(ctfser
,
905 int_field
->payload
.unsignd
, int_type
->common
.alignment
,
907 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
908 LITTLE_ENDIAN
: BIG_ENDIAN
);
911 if (G_UNLIKELY(ret
)) {
912 BT_LOGE("Cannot serialize integer field: ret=%d", ret
);
921 int bt_ctf_field_enumeration_serialize_recursive(
922 struct bt_ctf_field_common
*field
, struct bt_ctfser
*ctfser
,
923 enum bt_ctf_byte_order native_byte_order
)
925 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
927 BT_LOGV("Serializing enumeration field: addr=%p, native-bo=%s",
928 field
, bt_ctf_byte_order_string(native_byte_order
));
929 BT_LOGV_STR("Serializing enumeration field's payload field.");
930 return bt_ctf_field_serialize_recursive(
931 (void *) enumeration
->container
, ctfser
, native_byte_order
);
935 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field_common
*field
,
936 struct bt_ctfser
*ctfser
,
937 enum bt_ctf_byte_order native_byte_order
)
940 struct bt_ctf_field_type_common_floating_point
*flt_type
=
941 BT_CTF_FROM_COMMON(field
->type
);
942 struct bt_ctf_field_common_floating_point
*flt_field
= BT_CTF_FROM_COMMON(field
);
943 enum bt_ctf_byte_order byte_order
;
945 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Floating point number field");
946 BT_LOGV("Serializing floating point number field: "
947 "addr=%p, native-bo=%s", field
,
948 bt_ctf_byte_order_string(native_byte_order
));
950 byte_order
= flt_type
->user_byte_order
;
951 if (byte_order
== BT_CTF_BYTE_ORDER_NATIVE
) {
952 byte_order
= native_byte_order
;
955 if (flt_type
->mant_dig
== FLT_MANT_DIG
) {
956 ret
= bt_ctfser_write_float32(ctfser
, flt_field
->payload
,
957 flt_type
->common
.alignment
,
958 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
959 LITTLE_ENDIAN
: BIG_ENDIAN
);
960 } else if (flt_type
->mant_dig
== DBL_MANT_DIG
) {
961 ret
= bt_ctfser_write_float64(ctfser
, flt_field
->payload
,
962 flt_type
->common
.alignment
,
963 byte_order
== BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
?
964 LITTLE_ENDIAN
: BIG_ENDIAN
);
969 if (G_UNLIKELY(ret
)) {
970 BT_LOGE("Cannot serialize floating point number field: "
980 int bt_ctf_field_structure_serialize_recursive(struct bt_ctf_field_common
*field
,
981 struct bt_ctfser
*ctfser
,
982 enum bt_ctf_byte_order native_byte_order
)
986 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
988 BT_LOGV("Serializing structure field: addr=%p, native-bo=%s",
989 field
, bt_ctf_byte_order_string(native_byte_order
));
990 ret
= bt_ctfser_align_offset_in_current_packet(ctfser
,
991 field
->type
->alignment
);
992 if (G_UNLIKELY(ret
)) {
993 BT_LOGE("Cannot align offset before serializing structure field: "
998 for (i
= 0; i
< structure
->fields
->len
; i
++) {
999 struct bt_ctf_field_common
*member
= g_ptr_array_index(
1000 structure
->fields
, i
);
1001 const char *field_name
= NULL
;
1003 BT_LOGV("Serializing structure field's field: ser-offset=%" PRIu64
", "
1004 "field-addr=%p, index=%" PRIu64
,
1005 bt_ctfser_get_offset_in_current_packet_bits(ctfser
),
1008 if (G_UNLIKELY(!member
)) {
1009 ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
1010 field
->type
, &field_name
, NULL
, i
);
1011 BT_ASSERT(ret
== 0);
1012 BT_LOGW("Cannot serialize structure field's field: field is not set: "
1013 "struct-field-addr=%p, "
1014 "field-name=\"%s\", index=%" PRId64
,
1015 field
, field_name
, i
);
1020 ret
= bt_ctf_field_serialize_recursive((void *) member
, ctfser
,
1022 if (G_UNLIKELY(ret
)) {
1023 ret
= bt_ctf_field_type_common_structure_borrow_field_by_index(
1024 field
->type
, &field_name
, NULL
, i
);
1025 BT_ASSERT(ret
== 0);
1026 BT_LOGW("Cannot serialize structure field's field: "
1027 "struct-field-addr=%p, field-addr=%p, "
1028 "field-name=\"%s\", index=%" PRId64
,
1029 field
->type
, member
, field_name
, i
);
1039 int bt_ctf_field_variant_serialize_recursive(struct bt_ctf_field_common
*field
,
1040 struct bt_ctfser
*ctfser
,
1041 enum bt_ctf_byte_order native_byte_order
)
1043 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
1045 BT_LOGV("Serializing variant field: addr=%p, native-bo=%s",
1046 field
, bt_ctf_byte_order_string(native_byte_order
));
1047 BT_LOGV_STR("Serializing variant field's payload field.");
1048 return bt_ctf_field_serialize_recursive(
1049 (void *) variant
->current_field
, ctfser
, native_byte_order
);
1053 int bt_ctf_field_array_serialize_recursive(struct bt_ctf_field_common
*field
,
1054 struct bt_ctfser
*ctfser
,
1055 enum bt_ctf_byte_order native_byte_order
)
1059 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
1061 BT_LOGV("Serializing array field: addr=%p, native-bo=%s",
1062 field
, bt_ctf_byte_order_string(native_byte_order
));
1064 for (i
= 0; i
< array
->elements
->len
; i
++) {
1065 struct bt_ctf_field_common
*elem_field
=
1066 g_ptr_array_index(array
->elements
, i
);
1068 BT_LOGV("Serializing array field's element field: "
1069 "ser-offset=%" PRIu64
", field-addr=%p, index=%" PRId64
,
1070 bt_ctfser_get_offset_in_current_packet_bits(ctfser
),
1072 ret
= bt_ctf_field_serialize_recursive(
1073 (void *) elem_field
, ctfser
, native_byte_order
);
1074 if (G_UNLIKELY(ret
)) {
1075 BT_LOGW("Cannot serialize array field's element field: "
1076 "array-field-addr=%p, field-addr=%p, "
1077 "index=%" PRId64
, field
, elem_field
, i
);
1087 int bt_ctf_field_sequence_serialize_recursive(struct bt_ctf_field_common
*field
,
1088 struct bt_ctfser
*ctfser
,
1089 enum bt_ctf_byte_order native_byte_order
)
1093 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
1095 BT_LOGV("Serializing sequence field: addr=%p, native-bo=%s",
1096 field
, bt_ctf_byte_order_string(native_byte_order
));
1098 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1099 struct bt_ctf_field_common
*elem_field
=
1100 g_ptr_array_index(sequence
->elements
, i
);
1102 BT_LOGV("Serializing sequence field's element field: "
1103 "ser-offset=%" PRIu64
", field-addr=%p, index=%" PRId64
,
1104 bt_ctfser_get_offset_in_current_packet_bits(ctfser
),
1106 ret
= bt_ctf_field_serialize_recursive(
1107 (void *) elem_field
, ctfser
, native_byte_order
);
1108 if (G_UNLIKELY(ret
)) {
1109 BT_LOGW("Cannot serialize sequence field's element field: "
1110 "sequence-field-addr=%p, field-addr=%p, "
1111 "index=%" PRId64
, field
, elem_field
, i
);
1121 int bt_ctf_field_string_serialize(struct bt_ctf_field_common
*field
,
1122 struct bt_ctfser
*ctfser
,
1123 enum bt_ctf_byte_order native_byte_order
)
1126 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
1128 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "String field");
1129 BT_LOGV("Serializing string field: addr=%p, native-bo=%s",
1130 field
, bt_ctf_byte_order_string((int) native_byte_order
));
1131 ret
= bt_ctfser_write_string(ctfser
, (const char *) string
->buf
->data
);
1132 if (G_UNLIKELY(ret
)) {
1133 BT_LOGE("Cannot serialize string field: ret=%d", ret
);
1141 struct bt_ctf_field
*bt_ctf_field_create(struct bt_ctf_field_type
*type
)
1143 struct bt_ctf_field
*field
= NULL
;
1144 enum bt_ctf_field_type_id type_id
;
1146 BT_CTF_ASSERT_PRE_NON_NULL(type
, "Field type");
1147 BT_ASSERT(field_type_common_has_known_id((void *) type
));
1148 BT_CTF_ASSERT_PRE(bt_ctf_field_type_common_validate((void *) type
) == 0,
1149 "Field type is invalid: ft-addr=%p", type
);
1150 type_id
= bt_ctf_field_type_get_type_id(type
);
1151 field
= field_create_funcs
[type_id
](type
);
1156 bt_ctf_field_type_common_freeze((void *) type
);
1162 struct bt_ctf_field_type
*bt_ctf_field_get_type(struct bt_ctf_field
*field
)
1164 return bt_ctf_object_get_ref(bt_ctf_field_common_borrow_type((void *) field
));
1167 enum bt_ctf_field_type_id
bt_ctf_field_get_type_id(struct bt_ctf_field
*field
)
1169 struct bt_ctf_field_common
*field_common
= (void *) field
;
1171 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
1172 return (int) field_common
->type
->id
;
1175 int bt_ctf_field_sequence_set_length(struct bt_ctf_field
*field
,
1176 struct bt_ctf_field
*length_field
)
1179 struct bt_ctf_field_common
*common_length_field
= (void *) length_field
;
1182 BT_CTF_ASSERT_PRE_NON_NULL(length_field
, "Length field");
1183 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) length_field
, "Length field");
1184 BT_CTF_ASSERT_PRE(common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_INTEGER
||
1185 common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_ENUM
,
1186 "Length field must be an integer or enumeration field: field-addr=%p",
1189 if (common_length_field
->type
->id
== BT_CTF_FIELD_TYPE_ID_ENUM
) {
1190 struct bt_ctf_field_enumeration
*enumeration
= (void *)
1193 length_field
= (void *) enumeration
->container
;
1196 ret
= bt_ctf_field_integer_unsigned_get_value(length_field
, &length
);
1197 BT_ASSERT(ret
== 0);
1198 return bt_ctf_field_common_sequence_set_length((void *) field
,
1199 length
, (bt_ctf_field_common_create_func
) bt_ctf_field_create
);
1202 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_index(
1203 struct bt_ctf_field
*field
, uint64_t index
)
1205 return bt_ctf_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_index(
1206 (void *) field
, index
));
1209 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_name(
1210 struct bt_ctf_field
*field
, const char *name
)
1212 return bt_ctf_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_name(
1213 (void *) field
, name
));
1216 struct bt_ctf_field
*bt_ctf_field_array_get_field(
1217 struct bt_ctf_field
*field
, uint64_t index
)
1219 return bt_ctf_object_get_ref(
1220 bt_ctf_field_common_array_borrow_field((void *) field
, index
));
1223 struct bt_ctf_field
*bt_ctf_field_sequence_get_field(
1224 struct bt_ctf_field
*field
, uint64_t index
)
1226 return bt_ctf_object_get_ref(
1227 bt_ctf_field_common_sequence_borrow_field((void *) field
, index
));
1230 struct bt_ctf_field
*bt_ctf_field_variant_get_field(struct bt_ctf_field
*field
,
1231 struct bt_ctf_field
*tag_field
)
1233 struct bt_ctf_field_variant
*variant_field
= (void *) field
;
1234 struct bt_ctf_field_enumeration
*enum_field
= (void *) tag_field
;
1235 struct bt_ctf_field_type_common_variant
*variant_ft
;
1236 struct bt_ctf_field_type_common_enumeration
*tag_ft
;
1237 struct bt_ctf_field
*current_field
= NULL
;
1242 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Variant field");
1243 BT_CTF_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
1244 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) tag_field
, "Tag field");
1245 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1246 (struct bt_ctf_field_common
*) tag_field
,
1247 BT_CTF_FIELD_TYPE_ID_ENUM
, "Tag field");
1248 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1249 (struct bt_ctf_field_common
*) field
,
1250 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
1252 bt_ctf_field_common_validate_recursive((void *) tag_field
) == 0,
1253 "Tag field is invalid: field-addr=%p", tag_field
);
1254 variant_ft
= BT_CTF_FROM_COMMON(variant_field
->common
.common
.type
);
1255 BT_CTF_ASSERT_PRE(bt_ctf_field_type_common_compare(
1256 BT_CTF_TO_COMMON(variant_ft
->tag_ft
), enum_field
->common
.type
) == 0,
1257 "Unexpected tag field's type: expected-ft-addr=%p, "
1258 "tag-ft-addr=%p", variant_ft
->tag_ft
,
1259 enum_field
->common
.type
);
1260 tag_ft
= BT_CTF_FROM_COMMON(enum_field
->common
.type
);
1261 is_signed
= tag_ft
->container_ft
->is_signed
;
1266 ret
= bt_ctf_field_integer_signed_get_value(
1267 (void *) enum_field
->container
, &tag_ival
);
1268 tag_uval
= (uint64_t) tag_ival
;
1270 ret
= bt_ctf_field_integer_unsigned_get_value(
1271 (void *) enum_field
->container
, &tag_uval
);
1274 BT_ASSERT(ret
== 0);
1275 ret
= bt_ctf_field_common_variant_set_tag((void *) field
, tag_uval
,
1281 bt_ctf_object_put_ref(variant_field
->tag
);
1282 variant_field
->tag
= bt_ctf_object_get_ref(tag_field
);
1283 current_field
= bt_ctf_field_variant_get_current_field(field
);
1284 BT_ASSERT(current_field
);
1287 return current_field
;
1290 struct bt_ctf_field
*bt_ctf_field_variant_get_current_field(
1291 struct bt_ctf_field
*variant_field
)
1293 return bt_ctf_object_get_ref(bt_ctf_field_common_variant_borrow_current_field(
1294 (void *) variant_field
));
1298 struct bt_ctf_field
*bt_ctf_field_enumeration_borrow_container(
1299 struct bt_ctf_field
*field
)
1301 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1303 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
1304 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID((struct bt_ctf_field_common
*) field
,
1305 BT_CTF_FIELD_TYPE_ID_ENUM
, "Field");
1306 BT_ASSERT(enumeration
->container
);
1307 return (void *) enumeration
->container
;
1310 struct bt_ctf_field
*bt_ctf_field_enumeration_get_container(
1311 struct bt_ctf_field
*field
)
1313 return bt_ctf_object_get_ref(bt_ctf_field_enumeration_borrow_container(field
));
1316 int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field
*field
,
1319 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1321 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1322 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
1323 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer
), "Integer field");
1324 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1325 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1326 BT_CTF_ASSERT_PRE(bt_ctf_field_type_common_integer_is_signed(
1327 integer
->common
.type
),
1328 "Field's type is unsigned: field-addr=%p", field
);
1329 *value
= integer
->payload
.signd
;
1333 int bt_ctf_field_integer_signed_set_value(struct bt_ctf_field
*field
,
1337 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1338 struct bt_ctf_field_type_common_integer
*integer_type
;
1340 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1341 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer
), "Integer field");
1342 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1343 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1344 integer_type
= BT_CTF_FROM_COMMON(integer
->common
.type
);
1346 bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1347 "Field's type is unsigned: field-addr=%p", field
);
1348 BT_CTF_ASSERT_PRE(value_is_in_range_signed(integer_type
->size
, value
),
1349 "Value is out of bounds: value=%" PRId64
", field-addr=%p",
1351 integer
->payload
.signd
= value
;
1352 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer
), true);
1356 int bt_ctf_field_integer_unsigned_get_value(struct bt_ctf_field
*field
,
1359 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1361 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1362 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
1363 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer
), "Integer field");
1364 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1365 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1367 !bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1368 "Field's type is signed: field-addr=%p", field
);
1369 *value
= integer
->payload
.unsignd
;
1373 int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field
*field
,
1376 struct bt_ctf_field_common_integer
*integer
= (void *) field
;
1377 struct bt_ctf_field_type_common_integer
*integer_type
;
1379 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Integer field");
1380 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer
), "Integer field");
1381 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer
),
1382 BT_CTF_FIELD_TYPE_ID_INTEGER
, "Field");
1383 integer_type
= BT_CTF_FROM_COMMON(integer
->common
.type
);
1385 !bt_ctf_field_type_common_integer_is_signed(integer
->common
.type
),
1386 "Field's type is signed: field-addr=%p", field
);
1387 BT_CTF_ASSERT_PRE(value_is_in_range_unsigned(integer_type
->size
, value
),
1388 "Value is out of bounds: value=%" PRIu64
", field-addr=%p",
1390 integer
->payload
.unsignd
= value
;
1391 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer
), true);
1395 int bt_ctf_field_floating_point_get_value(struct bt_ctf_field
*field
,
1398 return bt_ctf_field_common_floating_point_get_value((void *) field
, value
);
1401 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field
*field
,
1404 return bt_ctf_field_common_floating_point_set_value((void *) field
, value
);
1407 const char *bt_ctf_field_string_get_value(struct bt_ctf_field
*field
)
1409 return bt_ctf_field_common_string_get_value((void *) field
);
1412 int bt_ctf_field_string_set_value(struct bt_ctf_field
*field
, const char *value
)
1414 return bt_ctf_field_common_string_set_value((void *) field
, value
);
1417 int bt_ctf_field_string_append(struct bt_ctf_field
*field
, const char *value
)
1419 return bt_ctf_field_common_string_append((void *) field
, value
);
1422 int bt_ctf_field_string_append_len(struct bt_ctf_field
*field
,
1423 const char *value
, unsigned int length
)
1425 return bt_ctf_field_common_string_append_len((void *) field
, value
, length
);
1428 struct bt_ctf_field
*bt_ctf_field_copy(struct bt_ctf_field
*field
)
1430 return (void *) bt_ctf_field_common_copy((void *) field
);
1434 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*type
)
1436 struct bt_ctf_field_common_integer
*integer
=
1437 g_new0(struct bt_ctf_field_common_integer
, 1);
1439 BT_LOGD("Creating CTF writer integer field object: ft-addr=%p", type
);
1442 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(integer
), (void *) type
,
1444 (bt_ctf_object_release_func
) bt_ctf_field_integer_destroy
,
1445 &bt_ctf_field_integer_methods
);
1446 integer
->common
.spec
.writer
.serialize_func
=
1447 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_integer_serialize
;
1448 BT_LOGD("Created CTF writer integer field object: addr=%p, ft-addr=%p",
1451 BT_LOGE_STR("Failed to allocate one integer field.");
1454 return (void *) integer
;
1458 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
1459 struct bt_ctf_field_type
*type
)
1461 struct bt_ctf_field_type_common_enumeration
*enum_ft
= (void *) type
;
1462 struct bt_ctf_field_enumeration
*enumeration
= g_new0(
1463 struct bt_ctf_field_enumeration
, 1);
1465 BT_LOGD("Creating CTF writer enumeration field object: ft-addr=%p", type
);
1468 BT_LOGE_STR("Failed to allocate one enumeration field.");
1472 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(enumeration
),
1474 true, (bt_ctf_object_release_func
)
1475 bt_ctf_field_enumeration_destroy_recursive
,
1476 &bt_ctf_field_enumeration_methods
);
1477 enumeration
->container
= (void *) bt_ctf_field_create(
1478 BT_CTF_FROM_COMMON(enum_ft
->container_ft
));
1479 if (!enumeration
->container
) {
1480 BT_CTF_OBJECT_PUT_REF_AND_RESET(enumeration
);
1484 enumeration
->common
.spec
.writer
.serialize_func
=
1485 (bt_ctf_field_serialize_recursive_func
)
1486 bt_ctf_field_enumeration_serialize_recursive
;
1487 BT_LOGD("Created CTF writer enumeration field object: addr=%p, ft-addr=%p",
1491 return (void *) enumeration
;
1495 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
1496 struct bt_ctf_field_type
*type
)
1498 struct bt_ctf_field_common_floating_point
*floating_point
;
1500 BT_LOGD("Creating CTF writer floating point number field object: ft-addr=%p", type
);
1501 floating_point
= g_new0(struct bt_ctf_field_common_floating_point
, 1);
1503 if (floating_point
) {
1504 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(floating_point
),
1506 true, (bt_ctf_object_release_func
)
1507 bt_ctf_field_floating_point_destroy
,
1508 &bt_ctf_field_floating_point_methods
);
1509 floating_point
->common
.spec
.writer
.serialize_func
=
1510 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_floating_point_serialize
;
1511 BT_LOGD("Created CTF writer floating point number field object: addr=%p, ft-addr=%p",
1512 floating_point
, type
);
1514 BT_LOGE_STR("Failed to allocate one floating point number field.");
1517 return (void *) floating_point
;
1521 struct bt_ctf_field
*bt_ctf_field_structure_create(
1522 struct bt_ctf_field_type
*type
)
1524 struct bt_ctf_field_common_structure
*structure
= g_new0(
1525 struct bt_ctf_field_common_structure
, 1);
1528 BT_LOGD("Creating CTF writer structure field object: ft-addr=%p", type
);
1531 BT_LOGE_STR("Failed to allocate one structure field.");
1535 iret
= bt_ctf_field_common_structure_initialize(BT_CTF_TO_COMMON(structure
),
1537 true, (bt_ctf_object_release_func
)
1538 bt_ctf_field_structure_destroy_recursive
,
1539 &bt_ctf_field_structure_methods
,
1540 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1541 (GDestroyNotify
) bt_ctf_object_put_ref
);
1542 structure
->common
.spec
.writer
.serialize_func
=
1543 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_structure_serialize_recursive
;
1545 BT_CTF_OBJECT_PUT_REF_AND_RESET(structure
);
1549 BT_LOGD("Created CTF writer structure field object: addr=%p, ft-addr=%p",
1553 return (void *) structure
;
1557 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*type
)
1559 struct bt_ctf_field_type_common_variant
*var_ft
= (void *) type
;
1560 struct bt_ctf_field_variant
*variant
= g_new0(
1561 struct bt_ctf_field_variant
, 1);
1563 BT_LOGD("Creating CTF writer variant field object: ft-addr=%p", type
);
1566 BT_LOGE_STR("Failed to allocate one variant field.");
1570 bt_ctf_field_common_variant_initialize(BT_CTF_TO_COMMON(BT_CTF_TO_COMMON(variant
)),
1572 true, (bt_ctf_object_release_func
)
1573 bt_ctf_field_variant_destroy_recursive
,
1574 &bt_ctf_field_variant_methods
,
1575 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1576 (GDestroyNotify
) bt_ctf_object_put_ref
);
1577 variant
->tag
= (void *) bt_ctf_field_create(
1578 BT_CTF_FROM_COMMON(var_ft
->tag_ft
));
1579 variant
->common
.common
.spec
.writer
.serialize_func
=
1580 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_variant_serialize_recursive
;
1581 BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p",
1585 return (void *) variant
;
1589 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*type
)
1591 struct bt_ctf_field_common_array
*array
=
1592 g_new0(struct bt_ctf_field_common_array
, 1);
1595 BT_LOGD("Creating CTF writer array field object: ft-addr=%p", type
);
1599 BT_LOGE_STR("Failed to allocate one array field.");
1603 ret
= bt_ctf_field_common_array_initialize(BT_CTF_TO_COMMON(array
),
1605 true, (bt_ctf_object_release_func
)
1606 bt_ctf_field_array_destroy_recursive
,
1607 &bt_ctf_field_array_methods
,
1608 (bt_ctf_field_common_create_func
) bt_ctf_field_create
,
1609 (GDestroyNotify
) bt_ctf_object_put_ref
);
1610 array
->common
.spec
.writer
.serialize_func
=
1611 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_array_serialize_recursive
;
1613 BT_CTF_OBJECT_PUT_REF_AND_RESET(array
);
1617 BT_LOGD("Created CTF writer array field object: addr=%p, ft-addr=%p",
1621 return (void *) array
;
1625 struct bt_ctf_field
*bt_ctf_field_sequence_create(struct bt_ctf_field_type
*type
)
1627 struct bt_ctf_field_common_sequence
*sequence
= g_new0(
1628 struct bt_ctf_field_common_sequence
, 1);
1630 BT_LOGD("Creating CTF writer sequence field object: ft-addr=%p", type
);
1633 bt_ctf_field_common_sequence_initialize(BT_CTF_TO_COMMON(sequence
),
1635 true, (bt_ctf_object_release_func
)
1636 bt_ctf_field_sequence_destroy_recursive
,
1637 &bt_ctf_field_sequence_methods
,
1638 (GDestroyNotify
) bt_ctf_object_put_ref
);
1639 sequence
->common
.spec
.writer
.serialize_func
=
1640 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_sequence_serialize_recursive
;
1641 BT_LOGD("Created CTF writer sequence field object: addr=%p, ft-addr=%p",
1644 BT_LOGE_STR("Failed to allocate one sequence field.");
1647 return (void *) sequence
;
1651 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*type
)
1653 struct bt_ctf_field_common_string
*string
= g_new0(
1654 struct bt_ctf_field_common_string
, 1);
1656 BT_LOGD("Creating CTF writer string field object: ft-addr=%p", type
);
1659 bt_ctf_field_common_string_initialize(BT_CTF_TO_COMMON(string
),
1661 true, (bt_ctf_object_release_func
)
1662 bt_ctf_field_string_destroy
,
1663 &bt_ctf_field_string_methods
);
1664 string
->common
.spec
.writer
.serialize_func
=
1665 (bt_ctf_field_serialize_recursive_func
) bt_ctf_field_string_serialize
;
1666 BT_LOGD("Created CTF writer string field object: addr=%p, ft-addr=%p",
1669 BT_LOGE_STR("Failed to allocate one string field.");
1672 return (void *) string
;
1676 void bt_ctf_field_enumeration_set_is_frozen_recursive(
1677 struct bt_ctf_field_common
*field
, bool is_frozen
)
1679 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1681 if (enumeration
->container
) {
1682 bt_ctf_field_common_set_is_frozen_recursive(
1683 (void *) enumeration
->container
, is_frozen
);
1686 bt_ctf_field_common_generic_set_is_frozen((void *) field
, is_frozen
);
1690 int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common
*field
)
1693 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1695 if (enumeration
->container
) {
1696 ret
= bt_ctf_field_common_validate_recursive(
1697 (void *) enumeration
->container
);
1704 bt_bool
bt_ctf_field_enumeration_is_set_recursive(struct bt_ctf_field_common
*field
)
1706 bt_bool is_set
= BT_FALSE
;
1707 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1709 if (enumeration
->container
) {
1710 is_set
= bt_ctf_field_common_is_set_recursive(
1711 (void *) enumeration
->container
);
1718 void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common
*field
)
1720 struct bt_ctf_field_enumeration
*enumeration
= (void *) field
;
1722 if (enumeration
->container
) {
1723 bt_ctf_field_common_reset_recursive(
1724 (void *) enumeration
->container
);
1727 bt_ctf_field_common_generic_reset((void *) field
);
1731 void bt_ctf_field_variant_set_is_frozen_recursive(
1732 struct bt_ctf_field_common
*field
, bool is_frozen
)
1734 struct bt_ctf_field_variant
*variant
= (void *) field
;
1737 bt_ctf_field_common_set_is_frozen_recursive(
1738 (void *) variant
->tag
, is_frozen
);
1741 bt_ctf_field_common_variant_set_is_frozen_recursive((void *) field
,
1746 int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common
*field
)
1749 struct bt_ctf_field_variant
*variant
= (void *) field
;
1752 ret
= bt_ctf_field_common_validate_recursive(
1753 (void *) variant
->tag
);
1759 ret
= bt_ctf_field_common_variant_validate_recursive((void *) field
);
1766 bt_bool
bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common
*field
)
1769 struct bt_ctf_field_variant
*variant
= (void *) field
;
1772 is_set
= bt_ctf_field_common_is_set_recursive(
1773 (void *) variant
->tag
);
1779 is_set
= bt_ctf_field_common_variant_is_set_recursive((void *) field
);
1786 void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common
*field
)
1788 struct bt_ctf_field_variant
*variant
= (void *) field
;
1791 bt_ctf_field_common_reset_recursive(
1792 (void *) variant
->tag
);
1795 bt_ctf_field_common_variant_reset_recursive((void *) field
);
1798 BT_CTF_ASSERT_PRE_FUNC
1799 static inline bool field_to_set_has_expected_type(
1800 struct bt_ctf_field_common
*struct_field
,
1801 const char *name
, struct bt_ctf_field_common
*value
)
1804 struct bt_ctf_field_type_common
*expected_field_type
= NULL
;
1806 expected_field_type
=
1807 bt_ctf_field_type_common_structure_borrow_field_type_by_name(
1808 struct_field
->type
, name
);
1810 if (bt_ctf_field_type_common_compare(expected_field_type
, value
->type
)) {
1811 BT_CTF_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
1812 "value-ft-addr=%p, expected-ft-addr=%p", value
->type
,
1813 expected_field_type
);
1823 int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field
*field
,
1824 const char *name
, struct bt_ctf_field
*value
)
1828 struct bt_ctf_field_common
*common_field
= (void *) field
;
1829 struct bt_ctf_field_common_structure
*structure
=
1830 BT_CTF_FROM_COMMON(common_field
);
1831 struct bt_ctf_field_common
*common_value
= (void *) value
;
1833 GHashTable
*field_name_to_index
;
1834 struct bt_ctf_field_type_common_structure
*structure_ft
;
1836 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Parent field");
1837 BT_CTF_ASSERT_PRE_NON_NULL(name
, "Field name");
1838 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value field");
1839 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(common_field
,
1840 BT_CTF_FIELD_TYPE_ID_STRUCT
, "Parent field");
1841 BT_CTF_ASSERT_PRE(field_to_set_has_expected_type(common_field
,
1842 name
, common_value
),
1843 "Value field's type is different from the expected field type.");
1844 field_quark
= g_quark_from_string(name
);
1845 structure_ft
= BT_CTF_FROM_COMMON(common_field
->type
);
1846 field_name_to_index
= structure_ft
->field_name_to_index
;
1847 if (!g_hash_table_lookup_extended(field_name_to_index
,
1848 GUINT_TO_POINTER(field_quark
), NULL
,
1849 (gpointer
*) &index
)) {
1850 BT_LOGV("Invalid parameter: no such field in structure field's type: "
1851 "struct-field-addr=%p, struct-ft-addr=%p, "
1852 "field-ft-addr=%p, name=\"%s\"",
1853 field
, common_field
->type
, common_value
->type
, name
);
1857 bt_ctf_object_get_ref(value
);
1858 BT_CTF_OBJECT_MOVE_REF(structure
->fields
->pdata
[index
], value
);