4 * Babeltrace CTF Writer
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/ctf-writer/event-fields.h>
30 #include <babeltrace/ctf-ir/event-fields-internal.h>
31 #include <babeltrace/ctf-ir/event-types-internal.h>
32 #include <babeltrace/compiler.h>
34 #define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
37 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*);
39 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
40 struct bt_ctf_field_type
*);
42 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
43 struct bt_ctf_field_type
*);
45 struct bt_ctf_field
*bt_ctf_field_structure_create(
46 struct bt_ctf_field_type
*);
48 struct bt_ctf_field
*bt_ctf_field_variant_create(
49 struct bt_ctf_field_type
*);
51 struct bt_ctf_field
*bt_ctf_field_array_create(
52 struct bt_ctf_field_type
*);
54 struct bt_ctf_field
*bt_ctf_field_sequence_create(
55 struct bt_ctf_field_type
*);
57 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*);
60 void bt_ctf_field_destroy(struct bt_ctf_ref
*);
62 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*);
64 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field
*);
66 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*);
68 void bt_ctf_field_structure_destroy(struct bt_ctf_field
*);
70 void bt_ctf_field_variant_destroy(struct bt_ctf_field
*);
72 void bt_ctf_field_array_destroy(struct bt_ctf_field
*);
74 void bt_ctf_field_sequence_destroy(struct bt_ctf_field
*);
76 void bt_ctf_field_string_destroy(struct bt_ctf_field
*);
79 int bt_ctf_field_generic_validate(struct bt_ctf_field
*field
);
81 int bt_ctf_field_structure_validate(struct bt_ctf_field
*field
);
83 int bt_ctf_field_variant_validate(struct bt_ctf_field
*field
);
85 int bt_ctf_field_enumeration_validate(struct bt_ctf_field
*field
);
87 int bt_ctf_field_array_validate(struct bt_ctf_field
*field
);
89 int bt_ctf_field_sequence_validate(struct bt_ctf_field
*field
);
92 int bt_ctf_field_integer_serialize(struct bt_ctf_field
*,
93 struct ctf_stream_pos
*);
95 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field
*,
96 struct ctf_stream_pos
*);
98 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field
*,
99 struct ctf_stream_pos
*);
101 int bt_ctf_field_structure_serialize(struct bt_ctf_field
*,
102 struct ctf_stream_pos
*);
104 int bt_ctf_field_variant_serialize(struct bt_ctf_field
*,
105 struct ctf_stream_pos
*);
107 int bt_ctf_field_array_serialize(struct bt_ctf_field
*,
108 struct ctf_stream_pos
*);
110 int bt_ctf_field_sequence_serialize(struct bt_ctf_field
*,
111 struct ctf_stream_pos
*);
113 int bt_ctf_field_string_serialize(struct bt_ctf_field
*,
114 struct ctf_stream_pos
*);
117 int increase_packet_size(struct ctf_stream_pos
*pos
);
120 struct bt_ctf_field
*(*field_create_funcs
[])(
121 struct bt_ctf_field_type
*) = {
122 [CTF_TYPE_INTEGER
] = bt_ctf_field_integer_create
,
123 [CTF_TYPE_ENUM
] = bt_ctf_field_enumeration_create
,
125 bt_ctf_field_floating_point_create
,
126 [CTF_TYPE_STRUCT
] = bt_ctf_field_structure_create
,
127 [CTF_TYPE_VARIANT
] = bt_ctf_field_variant_create
,
128 [CTF_TYPE_ARRAY
] = bt_ctf_field_array_create
,
129 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_sequence_create
,
130 [CTF_TYPE_STRING
] = bt_ctf_field_string_create
,
134 void (*field_destroy_funcs
[])(struct bt_ctf_field
*) = {
135 [CTF_TYPE_INTEGER
] = bt_ctf_field_integer_destroy
,
136 [CTF_TYPE_ENUM
] = bt_ctf_field_enumeration_destroy
,
138 bt_ctf_field_floating_point_destroy
,
139 [CTF_TYPE_STRUCT
] = bt_ctf_field_structure_destroy
,
140 [CTF_TYPE_VARIANT
] = bt_ctf_field_variant_destroy
,
141 [CTF_TYPE_ARRAY
] = bt_ctf_field_array_destroy
,
142 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_sequence_destroy
,
143 [CTF_TYPE_STRING
] = bt_ctf_field_string_destroy
,
147 int (*field_validate_funcs
[])(struct bt_ctf_field
*) = {
148 [CTF_TYPE_INTEGER
] = bt_ctf_field_generic_validate
,
149 [CTF_TYPE_ENUM
] = bt_ctf_field_enumeration_validate
,
150 [CTF_TYPE_FLOAT
] = bt_ctf_field_generic_validate
,
151 [CTF_TYPE_STRUCT
] = bt_ctf_field_structure_validate
,
152 [CTF_TYPE_VARIANT
] = bt_ctf_field_variant_validate
,
153 [CTF_TYPE_ARRAY
] = bt_ctf_field_array_validate
,
154 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_sequence_validate
,
155 [CTF_TYPE_STRING
] = bt_ctf_field_generic_validate
,
159 int (*field_serialize_funcs
[])(struct bt_ctf_field
*,
160 struct ctf_stream_pos
*) = {
161 [CTF_TYPE_INTEGER
] = bt_ctf_field_integer_serialize
,
162 [CTF_TYPE_ENUM
] = bt_ctf_field_enumeration_serialize
,
164 bt_ctf_field_floating_point_serialize
,
165 [CTF_TYPE_STRUCT
] = bt_ctf_field_structure_serialize
,
166 [CTF_TYPE_VARIANT
] = bt_ctf_field_variant_serialize
,
167 [CTF_TYPE_ARRAY
] = bt_ctf_field_array_serialize
,
168 [CTF_TYPE_SEQUENCE
] = bt_ctf_field_sequence_serialize
,
169 [CTF_TYPE_STRING
] = bt_ctf_field_string_serialize
,
172 struct bt_ctf_field
*bt_ctf_field_create(struct bt_ctf_field_type
*type
)
174 struct bt_ctf_field
*field
= NULL
;
175 enum ctf_type_id type_id
;
181 type_id
= bt_ctf_field_type_get_type_id(type
);
182 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
||
183 bt_ctf_field_type_validate(type
)) {
187 field
= field_create_funcs
[type_id
](type
);
192 /* The type's declaration can't change after this point */
193 bt_ctf_field_type_freeze(type
);
194 bt_ctf_field_type_get(type
);
195 bt_ctf_ref_init(&field
->ref_count
);
201 void bt_ctf_field_get(struct bt_ctf_field
*field
)
204 bt_ctf_ref_get(&field
->ref_count
);
208 void bt_ctf_field_put(struct bt_ctf_field
*field
)
211 bt_ctf_ref_put(&field
->ref_count
, bt_ctf_field_destroy
);
215 struct bt_ctf_field_type
*bt_ctf_field_get_type(struct bt_ctf_field
*field
)
217 struct bt_ctf_field_type
*ret
= NULL
;
224 bt_ctf_field_type_get(ret
);
229 struct bt_ctf_field
*bt_ctf_field_sequence_get_length(
230 struct bt_ctf_field
*field
)
232 struct bt_ctf_field
*ret
= NULL
;
233 struct bt_ctf_field_sequence
*sequence
;
239 if (bt_ctf_field_type_get_type_id(field
->type
) !=
244 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
245 ret
= sequence
->length
;
246 bt_ctf_field_get(ret
);
251 int bt_ctf_field_sequence_set_length(struct bt_ctf_field
*field
,
252 struct bt_ctf_field
*length_field
)
255 struct bt_ctf_field_type_integer
*length_type
;
256 struct bt_ctf_field_integer
*length
;
257 struct bt_ctf_field_sequence
*sequence
;
258 uint64_t sequence_length
;
260 if (!field
|| !length_field
) {
264 if (bt_ctf_field_type_get_type_id(length_field
->type
) !=
270 length_type
= container_of(length_field
->type
,
271 struct bt_ctf_field_type_integer
, parent
);
272 /* The length field must be unsigned */
273 if (length_type
->declaration
.signedness
) {
278 length
= container_of(length_field
, struct bt_ctf_field_integer
,
280 sequence_length
= length
->definition
.value
._unsigned
;
281 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
282 if (sequence
->elements
) {
283 g_ptr_array_free(sequence
->elements
, TRUE
);
284 bt_ctf_field_put(sequence
->length
);
287 sequence
->elements
= g_ptr_array_sized_new((size_t)sequence_length
);
288 if (!sequence
->elements
) {
293 g_ptr_array_set_free_func(sequence
->elements
,
294 (GDestroyNotify
)bt_ctf_field_put
);
295 g_ptr_array_set_size(sequence
->elements
, (size_t)sequence_length
);
296 bt_ctf_field_get(length_field
);
297 sequence
->length
= length_field
;
302 struct bt_ctf_field
*bt_ctf_field_structure_get_field(
303 struct bt_ctf_field
*field
, const char *name
)
305 struct bt_ctf_field
*new_field
= NULL
;
307 struct bt_ctf_field_structure
*structure
;
308 struct bt_ctf_field_type_structure
*structure_type
;
309 struct bt_ctf_field_type
*field_type
;
312 if (!field
|| !name
||
313 bt_ctf_field_type_get_type_id(field
->type
) !=
318 field_quark
= g_quark_from_string(name
);
319 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
320 structure_type
= container_of(field
->type
,
321 struct bt_ctf_field_type_structure
, parent
);
322 field_type
= bt_ctf_field_type_structure_get_type(structure_type
, name
);
323 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
324 GUINT_TO_POINTER(field_quark
), NULL
, (gpointer
*)&index
)) {
328 if (structure
->fields
->pdata
[index
]) {
329 new_field
= structure
->fields
->pdata
[index
];
333 new_field
= bt_ctf_field_create(field_type
);
338 structure
->fields
->pdata
[index
] = new_field
;
340 bt_ctf_field_get(new_field
);
345 struct bt_ctf_field
*bt_ctf_field_structure_get_field_by_index(
346 struct bt_ctf_field
*field
, size_t index
)
349 const char *field_name
;
350 struct bt_ctf_field_structure
*structure
;
351 struct bt_ctf_field_type
*structure_type
;
352 struct bt_ctf_field_type
*field_type
= NULL
;
353 struct bt_ctf_field
*ret_field
= NULL
;
356 bt_ctf_field_type_get_type_id(field
->type
) != CTF_TYPE_STRUCT
) {
360 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
361 if (index
>= structure
->fields
->len
) {
365 ret_field
= structure
->fields
->pdata
[index
];
370 /* Field has not been instanciated yet, create it */
371 structure_type
= bt_ctf_field_get_type(field
);
372 if (!structure_type
) {
376 ret
= bt_ctf_field_type_structure_get_field(structure_type
,
377 &field_name
, &field_type
, index
);
378 bt_ctf_field_type_put(structure_type
);
383 ret_field
= bt_ctf_field_create(field_type
);
388 structure
->fields
->pdata
[index
] = ret_field
;
390 bt_ctf_field_get(ret_field
);
393 bt_ctf_field_type_put(field_type
);
399 int bt_ctf_field_structure_set_field(struct bt_ctf_field
*field
,
400 const char *name
, struct bt_ctf_field
*value
)
404 struct bt_ctf_field_structure
*structure
;
405 struct bt_ctf_field_type_structure
*structure_type
;
406 struct bt_ctf_field_type
*expected_field_type
;
409 if (!field
|| !name
|| !value
||
410 bt_ctf_field_type_get_type_id(field
->type
) !=
416 field_quark
= g_quark_from_string(name
);
417 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
418 structure_type
= container_of(field
->type
,
419 struct bt_ctf_field_type_structure
, parent
);
420 expected_field_type
= bt_ctf_field_type_structure_get_type(
421 structure_type
, name
);
422 if (expected_field_type
!= value
->type
) {
427 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
428 GUINT_TO_POINTER(field_quark
), NULL
, (gpointer
*) &index
)) {
432 if (structure
->fields
->pdata
[index
]) {
433 bt_ctf_field_put(structure
->fields
->pdata
[index
]);
436 structure
->fields
->pdata
[index
] = value
;
437 bt_ctf_field_get(value
);
442 struct bt_ctf_field
*bt_ctf_field_array_get_field(struct bt_ctf_field
*field
,
445 struct bt_ctf_field
*new_field
= NULL
;
446 struct bt_ctf_field_array
*array
;
447 struct bt_ctf_field_type_array
*array_type
;
448 struct bt_ctf_field_type
*field_type
;
450 if (!field
|| bt_ctf_field_type_get_type_id(field
->type
) !=
455 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
456 if (index
>= array
->elements
->len
) {
460 array_type
= container_of(field
->type
, struct bt_ctf_field_type_array
,
462 field_type
= bt_ctf_field_type_array_get_element_type(array_type
);
463 if (array
->elements
->pdata
[(size_t)index
]) {
464 new_field
= array
->elements
->pdata
[(size_t)index
];
468 new_field
= bt_ctf_field_create(field_type
);
469 bt_ctf_field_get(new_field
);
470 array
->elements
->pdata
[(size_t)index
] = new_field
;
475 struct bt_ctf_field
*bt_ctf_field_sequence_get_field(struct bt_ctf_field
*field
,
478 struct bt_ctf_field
*new_field
= NULL
;
479 struct bt_ctf_field_sequence
*sequence
;
480 struct bt_ctf_field_type_sequence
*sequence_type
;
481 struct bt_ctf_field_type
*field_type
;
483 if (!field
|| bt_ctf_field_type_get_type_id(field
->type
) !=
488 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
489 if (!sequence
->elements
|| sequence
->elements
->len
<= index
) {
493 sequence_type
= container_of(field
->type
,
494 struct bt_ctf_field_type_sequence
, parent
);
495 field_type
= bt_ctf_field_type_sequence_get_element_type(sequence_type
);
496 if (sequence
->elements
->pdata
[(size_t)index
]) {
497 new_field
= sequence
->elements
->pdata
[(size_t)index
];
501 new_field
= bt_ctf_field_create(field_type
);
502 bt_ctf_field_get(new_field
);
503 sequence
->elements
->pdata
[(size_t)index
] = new_field
;
508 struct bt_ctf_field
*bt_ctf_field_variant_get_field(struct bt_ctf_field
*field
,
509 struct bt_ctf_field
*tag_field
)
511 struct bt_ctf_field
*new_field
= NULL
;
512 struct bt_ctf_field_variant
*variant
;
513 struct bt_ctf_field_type_variant
*variant_type
;
514 struct bt_ctf_field_type
*field_type
;
515 struct bt_ctf_field
*tag_enum
= NULL
;
516 struct bt_ctf_field_integer
*tag_enum_integer
;
517 int64_t tag_enum_value
;
519 if (!field
|| !tag_field
||
520 bt_ctf_field_type_get_type_id(field
->type
) !=
522 bt_ctf_field_type_get_type_id(tag_field
->type
) !=
527 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
528 variant_type
= container_of(field
->type
,
529 struct bt_ctf_field_type_variant
, parent
);
530 tag_enum
= bt_ctf_field_enumeration_get_container(tag_field
);
535 tag_enum_integer
= container_of(tag_enum
, struct bt_ctf_field_integer
,
538 if (!bt_ctf_field_validate(variant
->tag
)) {
542 tag_enum_value
= tag_enum_integer
->definition
.value
._signed
;
543 field_type
= bt_ctf_field_type_variant_get_field_type(variant_type
,
549 new_field
= bt_ctf_field_create(field_type
);
554 bt_ctf_field_put(variant
->tag
);
555 bt_ctf_field_put(variant
->payload
);
556 bt_ctf_field_get(new_field
);
557 bt_ctf_field_get(tag_field
);
558 variant
->tag
= tag_field
;
559 variant
->payload
= new_field
;
561 bt_ctf_field_put(tag_enum
);
565 struct bt_ctf_field
*bt_ctf_field_enumeration_get_container(
566 struct bt_ctf_field
*field
)
568 struct bt_ctf_field
*container
= NULL
;
569 struct bt_ctf_field_enumeration
*enumeration
;
575 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
577 if (!enumeration
->payload
) {
578 struct bt_ctf_field_type_enumeration
*enumeration_type
=
579 container_of(field
->type
,
580 struct bt_ctf_field_type_enumeration
, parent
);
581 enumeration
->payload
=
582 bt_ctf_field_create(enumeration_type
->container
);
585 container
= enumeration
->payload
;
586 bt_ctf_field_get(container
);
591 const char *bt_ctf_field_enumeration_get_mapping_name(
592 struct bt_ctf_field
*field
)
595 const char *name
= NULL
;
596 struct bt_ctf_field
*container
= NULL
;
597 struct bt_ctf_field_type
*container_type
= NULL
;
598 struct bt_ctf_field_type_integer
*integer_type
= NULL
;
599 struct bt_ctf_field_type_enumeration
*enumeration_type
= NULL
;
601 container
= bt_ctf_field_enumeration_get_container(field
);
606 container_type
= bt_ctf_field_get_type(container
);
607 if (!container_type
) {
608 goto error_put_container
;
611 integer_type
= container_of(container_type
,
612 struct bt_ctf_field_type_integer
, parent
);
613 enumeration_type
= container_of(field
->type
,
614 struct bt_ctf_field_type_enumeration
, parent
);
616 if (!integer_type
->declaration
.signedness
) {
618 ret
= bt_ctf_field_unsigned_integer_get_value(container
,
621 goto error_put_container_type
;
624 name
= bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
625 enumeration_type
, value
);
628 ret
= bt_ctf_field_signed_integer_get_value(container
,
631 goto error_put_container_type
;
634 name
= bt_ctf_field_type_enumeration_get_mapping_name_signed(
635 enumeration_type
, value
);
638 error_put_container_type
:
639 bt_ctf_field_type_put(container_type
);
641 bt_ctf_field_put(container
);
646 int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field
*field
,
650 struct bt_ctf_field_integer
*integer
;
651 struct bt_ctf_field_type_integer
*integer_type
;
653 if (!field
|| !value
|| !field
->payload_set
||
654 bt_ctf_field_type_get_type_id(field
->type
) !=
660 integer_type
= container_of(field
->type
,
661 struct bt_ctf_field_type_integer
, parent
);
662 if (!integer_type
->declaration
.signedness
) {
667 integer
= container_of(field
,
668 struct bt_ctf_field_integer
, parent
);
669 *value
= integer
->definition
.value
._signed
;
674 int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field
*field
,
678 struct bt_ctf_field_integer
*integer
;
679 struct bt_ctf_field_type_integer
*integer_type
;
681 int64_t min_value
, max_value
;
684 bt_ctf_field_type_get_type_id(field
->type
) !=
690 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
691 integer_type
= container_of(field
->type
,
692 struct bt_ctf_field_type_integer
, parent
);
693 if (!integer_type
->declaration
.signedness
) {
698 size
= integer_type
->declaration
.len
;
699 min_value
= -((int64_t)1 << (size
- 1));
700 max_value
= ((int64_t)1 << (size
- 1)) - 1;
701 if (value
< min_value
|| value
> max_value
) {
706 integer
->definition
.value
._signed
= value
;
707 integer
->parent
.payload_set
= 1;
712 int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field
*field
,
716 struct bt_ctf_field_integer
*integer
;
717 struct bt_ctf_field_type_integer
*integer_type
;
719 if (!field
|| !value
|| !field
->payload_set
||
720 bt_ctf_field_type_get_type_id(field
->type
) !=
726 integer_type
= container_of(field
->type
,
727 struct bt_ctf_field_type_integer
, parent
);
728 if (integer_type
->declaration
.signedness
) {
733 integer
= container_of(field
,
734 struct bt_ctf_field_integer
, parent
);
735 *value
= integer
->definition
.value
._unsigned
;
740 int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field
*field
,
744 struct bt_ctf_field_integer
*integer
;
745 struct bt_ctf_field_type_integer
*integer_type
;
750 bt_ctf_field_type_get_type_id(field
->type
) !=
756 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
757 integer_type
= container_of(field
->type
,
758 struct bt_ctf_field_type_integer
, parent
);
759 if (integer_type
->declaration
.signedness
) {
764 size
= integer_type
->declaration
.len
;
765 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t)1 << size
) - 1;
766 if (value
> max_value
) {
771 integer
->definition
.value
._unsigned
= value
;
772 integer
->parent
.payload_set
= 1;
777 int bt_ctf_field_floating_point_get_value(struct bt_ctf_field
*field
,
781 struct bt_ctf_field_floating_point
*floating_point
;
783 if (!field
|| !value
|| !field
->payload_set
||
784 bt_ctf_field_type_get_type_id(field
->type
) !=
790 floating_point
= container_of(field
,
791 struct bt_ctf_field_floating_point
, parent
);
792 *value
= floating_point
->definition
.value
;
797 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field
*field
,
801 struct bt_ctf_field_floating_point
*floating_point
;
804 bt_ctf_field_type_get_type_id(field
->type
) !=
809 floating_point
= container_of(field
, struct bt_ctf_field_floating_point
,
811 floating_point
->definition
.value
= value
;
812 floating_point
->parent
.payload_set
= 1;
817 const char *bt_ctf_field_string_get_value(struct bt_ctf_field
*field
)
819 const char *ret
= NULL
;
820 struct bt_ctf_field_string
*string
;
822 if (!field
|| !field
->payload_set
||
823 bt_ctf_field_type_get_type_id(field
->type
) !=
828 string
= container_of(field
,
829 struct bt_ctf_field_string
, parent
);
830 ret
= string
->payload
->str
;
835 int bt_ctf_field_string_set_value(struct bt_ctf_field
*field
,
839 struct bt_ctf_field_string
*string
;
841 if (!field
|| !value
||
842 bt_ctf_field_type_get_type_id(field
->type
) !=
848 string
= container_of(field
, struct bt_ctf_field_string
, parent
);
849 if (string
->payload
) {
850 g_string_free(string
->payload
, TRUE
);
853 string
->payload
= g_string_new(value
);
854 string
->parent
.payload_set
= 1;
860 int bt_ctf_field_validate(struct bt_ctf_field
*field
)
863 enum ctf_type_id type_id
;
870 type_id
= bt_ctf_field_type_get_type_id(field
->type
);
871 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
) {
876 ret
= field_validate_funcs
[type_id
](field
);
882 int bt_ctf_field_serialize(struct bt_ctf_field
*field
,
883 struct ctf_stream_pos
*pos
)
886 enum ctf_type_id type_id
;
888 if (!field
|| !pos
) {
893 type_id
= bt_ctf_field_type_get_type_id(field
->type
);
894 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
) {
899 ret
= field_serialize_funcs
[type_id
](field
, pos
);
905 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*type
)
907 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
908 struct bt_ctf_field_type_integer
, parent
);
909 struct bt_ctf_field_integer
*integer
= g_new0(
910 struct bt_ctf_field_integer
, 1);
913 integer
->definition
.declaration
= &integer_type
->declaration
;
916 return integer
? &integer
->parent
: NULL
;
920 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
921 struct bt_ctf_field_type
*type
)
923 struct bt_ctf_field_enumeration
*enumeration
= g_new0(
924 struct bt_ctf_field_enumeration
, 1);
926 return enumeration
? &enumeration
->parent
: NULL
;
930 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
931 struct bt_ctf_field_type
*type
)
933 struct bt_ctf_field_floating_point
*floating_point
;
934 struct bt_ctf_field_type_floating_point
*floating_point_type
;
936 floating_point
= g_new0(struct bt_ctf_field_floating_point
, 1);
937 if (!floating_point
) {
941 floating_point_type
= container_of(type
,
942 struct bt_ctf_field_type_floating_point
, parent
);
943 floating_point
->definition
.declaration
= container_of(
944 type
->declaration
, struct declaration_float
, p
);
947 floating_point
->definition
.sign
= &floating_point
->sign
;
948 floating_point
->sign
.declaration
= &floating_point_type
->sign
;
949 floating_point
->definition
.sign
->p
.declaration
=
950 &floating_point_type
->sign
.p
;
952 floating_point
->definition
.mantissa
= &floating_point
->mantissa
;
953 floating_point
->mantissa
.declaration
= &floating_point_type
->mantissa
;
954 floating_point
->definition
.mantissa
->p
.declaration
=
955 &floating_point_type
->mantissa
.p
;
957 floating_point
->definition
.exp
= &floating_point
->exp
;
958 floating_point
->exp
.declaration
= &floating_point_type
->exp
;
959 floating_point
->definition
.exp
->p
.declaration
=
960 &floating_point_type
->exp
.p
;
963 return floating_point
? &floating_point
->parent
: NULL
;
967 struct bt_ctf_field
*bt_ctf_field_structure_create(
968 struct bt_ctf_field_type
*type
)
970 struct bt_ctf_field_type_structure
*structure_type
= container_of(type
,
971 struct bt_ctf_field_type_structure
, parent
);
972 struct bt_ctf_field_structure
*structure
= g_new0(
973 struct bt_ctf_field_structure
, 1);
974 struct bt_ctf_field
*field
= NULL
;
976 if (!structure
|| !structure_type
->fields
->len
) {
980 structure
->field_name_to_index
= structure_type
->field_name_to_index
;
981 structure
->fields
= g_ptr_array_new_with_free_func(
982 (GDestroyNotify
)bt_ctf_field_put
);
983 g_ptr_array_set_size(structure
->fields
,
984 g_hash_table_size(structure
->field_name_to_index
));
985 field
= &structure
->parent
;
991 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*type
)
993 struct bt_ctf_field_variant
*variant
= g_new0(
994 struct bt_ctf_field_variant
, 1);
995 return variant
? &variant
->parent
: NULL
;
999 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*type
)
1001 struct bt_ctf_field_array
*array
= g_new0(struct bt_ctf_field_array
, 1);
1002 struct bt_ctf_field_type_array
*array_type
;
1003 unsigned int array_length
;
1005 if (!array
|| !type
) {
1009 array_type
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
1010 array_length
= array_type
->length
;
1011 array
->elements
= g_ptr_array_sized_new(array_length
);
1012 if (!array
->elements
) {
1016 g_ptr_array_set_free_func(array
->elements
,
1017 (GDestroyNotify
)bt_ctf_field_put
);
1018 g_ptr_array_set_size(array
->elements
, array_length
);
1019 return &array
->parent
;
1026 struct bt_ctf_field
*bt_ctf_field_sequence_create(
1027 struct bt_ctf_field_type
*type
)
1029 struct bt_ctf_field_sequence
*sequence
= g_new0(
1030 struct bt_ctf_field_sequence
, 1);
1031 return sequence
? &sequence
->parent
: NULL
;
1035 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*type
)
1037 struct bt_ctf_field_string
*string
= g_new0(
1038 struct bt_ctf_field_string
, 1);
1039 return string
? &string
->parent
: NULL
;
1043 void bt_ctf_field_destroy(struct bt_ctf_ref
*ref
)
1045 struct bt_ctf_field
*field
;
1046 struct bt_ctf_field_type
*type
;
1047 enum ctf_type_id type_id
;
1053 field
= container_of(ref
, struct bt_ctf_field
, ref_count
);
1055 type_id
= bt_ctf_field_type_get_type_id(type
);
1056 if (type_id
<= CTF_TYPE_UNKNOWN
||
1057 type_id
>= NR_CTF_TYPES
) {
1061 field_destroy_funcs
[type_id
](field
);
1063 bt_ctf_field_type_put(type
);
1068 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*field
)
1070 struct bt_ctf_field_integer
*integer
;
1076 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
1081 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field
*field
)
1083 struct bt_ctf_field_enumeration
*enumeration
;
1089 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
1091 bt_ctf_field_put(enumeration
->payload
);
1092 g_free(enumeration
);
1096 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*field
)
1098 struct bt_ctf_field_floating_point
*floating_point
;
1104 floating_point
= container_of(field
, struct bt_ctf_field_floating_point
,
1106 g_free(floating_point
);
1110 void bt_ctf_field_structure_destroy(struct bt_ctf_field
*field
)
1112 struct bt_ctf_field_structure
*structure
;
1118 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
1119 g_ptr_array_free(structure
->fields
, TRUE
);
1124 void bt_ctf_field_variant_destroy(struct bt_ctf_field
*field
)
1126 struct bt_ctf_field_variant
*variant
;
1132 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
1133 bt_ctf_field_put(variant
->tag
);
1134 bt_ctf_field_put(variant
->payload
);
1139 void bt_ctf_field_array_destroy(struct bt_ctf_field
*field
)
1141 struct bt_ctf_field_array
*array
;
1147 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
1148 g_ptr_array_free(array
->elements
, TRUE
);
1153 void bt_ctf_field_sequence_destroy(struct bt_ctf_field
*field
)
1155 struct bt_ctf_field_sequence
*sequence
;
1161 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
1162 g_ptr_array_free(sequence
->elements
, TRUE
);
1163 bt_ctf_field_put(sequence
->length
);
1168 void bt_ctf_field_string_destroy(struct bt_ctf_field
*field
)
1170 struct bt_ctf_field_string
*string
;
1175 string
= container_of(field
, struct bt_ctf_field_string
, parent
);
1176 g_string_free(string
->payload
, TRUE
);
1181 int bt_ctf_field_generic_validate(struct bt_ctf_field
*field
)
1183 return (field
&& field
->payload_set
) ? 0 : -1;
1187 int bt_ctf_field_enumeration_validate(struct bt_ctf_field
*field
)
1190 struct bt_ctf_field_enumeration
*enumeration
;
1197 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
1199 if (!enumeration
->payload
) {
1204 ret
= bt_ctf_field_validate(enumeration
->payload
);
1210 int bt_ctf_field_structure_validate(struct bt_ctf_field
*field
)
1214 struct bt_ctf_field_structure
*structure
;
1221 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
1222 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1223 ret
= bt_ctf_field_validate(structure
->fields
->pdata
[i
]);
1233 int bt_ctf_field_variant_validate(struct bt_ctf_field
*field
)
1236 struct bt_ctf_field_variant
*variant
;
1243 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
1244 ret
= bt_ctf_field_validate(variant
->payload
);
1250 int bt_ctf_field_array_validate(struct bt_ctf_field
*field
)
1254 struct bt_ctf_field_array
*array
;
1261 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
1262 for (i
= 0; i
< array
->elements
->len
; i
++) {
1263 ret
= bt_ctf_field_validate(array
->elements
->pdata
[i
]);
1273 int bt_ctf_field_sequence_validate(struct bt_ctf_field
*field
)
1277 struct bt_ctf_field_sequence
*sequence
;
1284 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
1285 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1286 ret
= bt_ctf_field_validate(sequence
->elements
->pdata
[i
]);
1296 int bt_ctf_field_integer_serialize(struct bt_ctf_field
*field
,
1297 struct ctf_stream_pos
*pos
)
1300 struct bt_ctf_field_integer
*integer
= container_of(field
,
1301 struct bt_ctf_field_integer
, parent
);
1304 ret
= ctf_integer_write(&pos
->parent
, &integer
->definition
.p
);
1305 if (ret
== -EFAULT
) {
1307 * The field is too large to fit in the current packet's
1308 * remaining space. Bump the packet size and retry.
1310 ret
= increase_packet_size(pos
);
1321 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field
*field
,
1322 struct ctf_stream_pos
*pos
)
1324 struct bt_ctf_field_enumeration
*enumeration
= container_of(
1325 field
, struct bt_ctf_field_enumeration
, parent
);
1327 return bt_ctf_field_serialize(enumeration
->payload
, pos
);
1331 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field
*field
,
1332 struct ctf_stream_pos
*pos
)
1335 struct bt_ctf_field_floating_point
*floating_point
= container_of(field
,
1336 struct bt_ctf_field_floating_point
, parent
);
1339 ret
= ctf_float_write(&pos
->parent
, &floating_point
->definition
.p
);
1340 if (ret
== -EFAULT
) {
1342 * The field is too large to fit in the current packet's
1343 * remaining space. Bump the packet size and retry.
1345 ret
= increase_packet_size(pos
);
1356 int bt_ctf_field_structure_serialize(struct bt_ctf_field
*field
,
1357 struct ctf_stream_pos
*pos
)
1361 struct bt_ctf_field_structure
*structure
= container_of(
1362 field
, struct bt_ctf_field_structure
, parent
);
1364 while (!ctf_pos_access_ok(pos
,
1365 offset_align(pos
->offset
,
1366 field
->type
->declaration
->alignment
))) {
1367 ret
= increase_packet_size(pos
);
1373 if (!ctf_align_pos(pos
, field
->type
->declaration
->alignment
)) {
1378 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1379 struct bt_ctf_field
*field
= g_ptr_array_index(
1380 structure
->fields
, i
);
1382 ret
= bt_ctf_field_serialize(field
, pos
);
1392 int bt_ctf_field_variant_serialize(struct bt_ctf_field
*field
,
1393 struct ctf_stream_pos
*pos
)
1395 struct bt_ctf_field_variant
*variant
= container_of(
1396 field
, struct bt_ctf_field_variant
, parent
);
1398 return bt_ctf_field_serialize(variant
->payload
, pos
);
1402 int bt_ctf_field_array_serialize(struct bt_ctf_field
*field
,
1403 struct ctf_stream_pos
*pos
)
1407 struct bt_ctf_field_array
*array
= container_of(
1408 field
, struct bt_ctf_field_array
, parent
);
1410 for (i
= 0; i
< array
->elements
->len
; i
++) {
1411 ret
= bt_ctf_field_serialize(
1412 g_ptr_array_index(array
->elements
, i
), pos
);
1422 int bt_ctf_field_sequence_serialize(struct bt_ctf_field
*field
,
1423 struct ctf_stream_pos
*pos
)
1427 struct bt_ctf_field_sequence
*sequence
= container_of(
1428 field
, struct bt_ctf_field_sequence
, parent
);
1430 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1431 ret
= bt_ctf_field_serialize(
1432 g_ptr_array_index(sequence
->elements
, i
), pos
);
1442 int bt_ctf_field_string_serialize(struct bt_ctf_field
*field
,
1443 struct ctf_stream_pos
*pos
)
1447 struct bt_ctf_field_string
*string
= container_of(field
,
1448 struct bt_ctf_field_string
, parent
);
1449 struct bt_ctf_field_type
*character_type
=
1450 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
1451 struct bt_ctf_field
*character
= bt_ctf_field_create(character_type
);
1453 for (i
= 0; i
< string
->payload
->len
+ 1; i
++) {
1454 ret
= bt_ctf_field_unsigned_integer_set_value(character
,
1455 (uint64_t) string
->payload
->str
[i
]);
1460 ret
= bt_ctf_field_integer_serialize(character
, pos
);
1466 bt_ctf_field_put(character
);
1467 bt_ctf_field_type_put(character_type
);
1472 int increase_packet_size(struct ctf_stream_pos
*pos
)
1477 ret
= munmap_align(pos
->base_mma
);
1482 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
1483 ret
= posix_fallocate(pos
->fd
, pos
->mmap_offset
,
1484 pos
->packet_size
/ CHAR_BIT
);
1489 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
1490 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
1491 if (pos
->base_mma
== MAP_FAILED
) {