4 * Babeltrace CTF Writer
6 * Copyright 2013 EfficiOS Inc.
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-writer/event-fields-internal.h>
31 #include <babeltrace/ctf-writer/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
||
183 type_id
>= NR_CTF_TYPES
) {
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 int bt_ctf_field_sequence_set_length(struct bt_ctf_field
*field
,
216 struct bt_ctf_field
*length_field
)
219 struct bt_ctf_field_type_integer
*length_type
;
220 struct bt_ctf_field_integer
*length
;
221 struct bt_ctf_field_sequence
*sequence
;
222 uint64_t sequence_length
;
224 if (!field
|| !length_field
) {
228 if (bt_ctf_field_type_get_type_id(length_field
->type
) !=
234 length_type
= container_of(length_field
->type
,
235 struct bt_ctf_field_type_integer
, parent
);
236 if (length_type
->declaration
.signedness
) {
241 length
= container_of(length_field
, struct bt_ctf_field_integer
,
243 sequence_length
= length
->definition
.value
._unsigned
;
244 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
245 if (sequence
->elements
) {
246 g_ptr_array_free(sequence
->elements
, TRUE
);
247 bt_ctf_field_put(sequence
->length
);
250 sequence
->elements
= g_ptr_array_sized_new((size_t)sequence_length
);
251 if (!sequence
->elements
) {
256 g_ptr_array_set_free_func(sequence
->elements
,
257 (GDestroyNotify
)bt_ctf_field_put
);
258 g_ptr_array_set_size(sequence
->elements
, (size_t)sequence_length
);
259 bt_ctf_field_get(length_field
);
260 sequence
->length
= length_field
;
265 struct bt_ctf_field
*bt_ctf_field_structure_get_field(
266 struct bt_ctf_field
*field
, const char *name
)
268 struct bt_ctf_field
*new_field
= NULL
;
270 struct bt_ctf_field_structure
*structure
;
271 struct bt_ctf_field_type_structure
*structure_type
;
272 struct bt_ctf_field_type
*field_type
;
275 if (!field
|| !name
||
276 bt_ctf_field_type_get_type_id(field
->type
) !=
281 field_quark
= g_quark_from_string(name
);
282 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
283 structure_type
= container_of(field
->type
,
284 struct bt_ctf_field_type_structure
, parent
);
285 field_type
= bt_ctf_field_type_structure_get_type(structure_type
, name
);
286 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
287 GUINT_TO_POINTER(field_quark
), NULL
, (gpointer
*)&index
)) {
291 if (structure
->fields
->pdata
[index
]) {
292 new_field
= structure
->fields
->pdata
[index
];
296 new_field
= bt_ctf_field_create(field_type
);
301 structure
->fields
->pdata
[index
] = new_field
;
303 bt_ctf_field_get(new_field
);
309 int bt_ctf_field_structure_set_field(struct bt_ctf_field
*field
,
310 const char *name
, struct bt_ctf_field
*value
)
314 struct bt_ctf_field_structure
*structure
;
315 struct bt_ctf_field_type_structure
*structure_type
;
316 struct bt_ctf_field_type
*expected_field_type
;
319 if (!field
|| !name
|| !value
||
320 bt_ctf_field_type_get_type_id(field
->type
) !=
326 field_quark
= g_quark_from_string(name
);
327 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
328 structure_type
= container_of(field
->type
,
329 struct bt_ctf_field_type_structure
, parent
);
330 expected_field_type
= bt_ctf_field_type_structure_get_type(
331 structure_type
, name
);
332 if (expected_field_type
!= value
->type
) {
337 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
338 GUINT_TO_POINTER(field_quark
), NULL
, (gpointer
*) &index
)) {
342 if (structure
->fields
->pdata
[index
]) {
343 bt_ctf_field_put(structure
->fields
->pdata
[index
]);
346 structure
->fields
->pdata
[index
] = value
;
347 bt_ctf_field_get(value
);
352 struct bt_ctf_field
*bt_ctf_field_array_get_field(struct bt_ctf_field
*field
,
355 struct bt_ctf_field
*new_field
= NULL
;
356 struct bt_ctf_field_array
*array
;
357 struct bt_ctf_field_type_array
*array_type
;
358 struct bt_ctf_field_type
*field_type
;
360 if (!field
|| bt_ctf_field_type_get_type_id(field
->type
) !=
365 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
366 if (index
>= array
->elements
->len
) {
370 array_type
= container_of(field
->type
, struct bt_ctf_field_type_array
,
372 field_type
= bt_ctf_field_type_array_get_element_type(array_type
);
373 if (array
->elements
->pdata
[(size_t)index
]) {
374 new_field
= array
->elements
->pdata
[(size_t)index
];
378 new_field
= bt_ctf_field_create(field_type
);
379 bt_ctf_field_get(new_field
);
380 array
->elements
->pdata
[(size_t)index
] = new_field
;
385 struct bt_ctf_field
*bt_ctf_field_sequence_get_field(struct bt_ctf_field
*field
,
388 struct bt_ctf_field
*new_field
= NULL
;
389 struct bt_ctf_field_sequence
*sequence
;
390 struct bt_ctf_field_type_sequence
*sequence_type
;
391 struct bt_ctf_field_type
*field_type
;
393 if (!field
|| bt_ctf_field_type_get_type_id(field
->type
) !=
398 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
399 if (!sequence
->elements
|| sequence
->elements
->len
<= index
) {
403 sequence_type
= container_of(field
->type
,
404 struct bt_ctf_field_type_sequence
, parent
);
405 field_type
= bt_ctf_field_type_sequence_get_element_type(sequence_type
);
406 if (sequence
->elements
->pdata
[(size_t)index
]) {
407 new_field
= sequence
->elements
->pdata
[(size_t)index
];
411 new_field
= bt_ctf_field_create(field_type
);
412 bt_ctf_field_get(new_field
);
413 sequence
->elements
->pdata
[(size_t)index
] = new_field
;
418 struct bt_ctf_field
*bt_ctf_field_variant_get_field(struct bt_ctf_field
*field
,
419 struct bt_ctf_field
*tag_field
)
421 struct bt_ctf_field
*new_field
= NULL
;
422 struct bt_ctf_field_variant
*variant
;
423 struct bt_ctf_field_type_variant
*variant_type
;
424 struct bt_ctf_field_type
*field_type
;
425 struct bt_ctf_field
*tag_enum
= NULL
;
426 struct bt_ctf_field_integer
*tag_enum_integer
;
427 int64_t tag_enum_value
;
429 if (!field
|| !tag_field
||
430 bt_ctf_field_type_get_type_id(field
->type
) !=
432 bt_ctf_field_type_get_type_id(tag_field
->type
) !=
437 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
438 variant_type
= container_of(field
->type
,
439 struct bt_ctf_field_type_variant
, parent
);
440 tag_enum
= bt_ctf_field_enumeration_get_container(tag_field
);
445 tag_enum_integer
= container_of(tag_enum
, struct bt_ctf_field_integer
,
448 if (!bt_ctf_field_validate(variant
->tag
)) {
452 tag_enum_value
= tag_enum_integer
->definition
.value
._signed
;
453 field_type
= bt_ctf_field_type_variant_get_field_type(variant_type
,
459 new_field
= bt_ctf_field_create(field_type
);
464 bt_ctf_field_put(variant
->tag
);
465 bt_ctf_field_put(variant
->payload
);
466 bt_ctf_field_get(new_field
);
467 bt_ctf_field_get(tag_field
);
468 variant
->tag
= tag_field
;
469 variant
->payload
= new_field
;
471 bt_ctf_field_put(tag_enum
);
475 struct bt_ctf_field
*bt_ctf_field_enumeration_get_container(
476 struct bt_ctf_field
*field
)
478 struct bt_ctf_field
*container
= NULL
;
479 struct bt_ctf_field_enumeration
*enumeration
;
485 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
487 if (!enumeration
->payload
) {
488 struct bt_ctf_field_type_enumeration
*enumeration_type
=
489 container_of(field
->type
,
490 struct bt_ctf_field_type_enumeration
, parent
);
491 enumeration
->payload
=
492 bt_ctf_field_create(enumeration_type
->container
);
495 container
= enumeration
->payload
;
496 bt_ctf_field_get(container
);
501 int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field
*field
,
505 struct bt_ctf_field_integer
*integer
;
506 struct bt_ctf_field_type_integer
*integer_type
;
508 int64_t min_value
, max_value
;
511 bt_ctf_field_type_get_type_id(field
->type
) !=
517 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
518 integer_type
= container_of(field
->type
,
519 struct bt_ctf_field_type_integer
, parent
);
520 if (!integer_type
->declaration
.signedness
) {
525 size
= integer_type
->declaration
.len
;
526 min_value
= -((int64_t)1 << (size
- 1));
527 max_value
= ((int64_t)1 << (size
- 1)) - 1;
528 if (value
< min_value
|| value
> max_value
) {
533 integer
->definition
.value
._signed
= value
;
534 integer
->parent
.payload_set
= 1;
539 int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field
*field
,
543 struct bt_ctf_field_integer
*integer
;
544 struct bt_ctf_field_type_integer
*integer_type
;
549 bt_ctf_field_type_get_type_id(field
->type
) !=
555 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
556 integer_type
= container_of(field
->type
,
557 struct bt_ctf_field_type_integer
, parent
);
558 if (integer_type
->declaration
.signedness
) {
563 size
= integer_type
->declaration
.len
;
564 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t)1 << size
) - 1;
565 if (value
> max_value
) {
570 integer
->definition
.value
._unsigned
= value
;
571 integer
->parent
.payload_set
= 1;
576 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field
*field
,
580 struct bt_ctf_field_floating_point
*floating_point
;
583 bt_ctf_field_type_get_type_id(field
->type
) !=
588 floating_point
= container_of(field
, struct bt_ctf_field_floating_point
,
590 floating_point
->definition
.value
= value
;
591 floating_point
->parent
.payload_set
= 1;
596 int bt_ctf_field_string_set_value(struct bt_ctf_field
*field
,
600 struct bt_ctf_field_string
*string
;
602 if (!field
|| !value
||
603 bt_ctf_field_type_get_type_id(field
->type
) !=
609 string
= container_of(field
, struct bt_ctf_field_string
, parent
);
610 if (string
->payload
) {
611 g_string_free(string
->payload
, TRUE
);
614 string
->payload
= g_string_new(value
);
615 string
->parent
.payload_set
= 1;
621 int bt_ctf_field_validate(struct bt_ctf_field
*field
)
624 enum ctf_type_id type_id
;
631 type_id
= bt_ctf_field_type_get_type_id(field
->type
);
632 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
) {
637 ret
= field_validate_funcs
[type_id
](field
);
643 int bt_ctf_field_serialize(struct bt_ctf_field
*field
,
644 struct ctf_stream_pos
*pos
)
647 enum ctf_type_id type_id
;
649 if (!field
|| !pos
) {
654 type_id
= bt_ctf_field_type_get_type_id(field
->type
);
655 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
) {
660 ret
= field_serialize_funcs
[type_id
](field
, pos
);
666 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*type
)
668 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
669 struct bt_ctf_field_type_integer
, parent
);
670 struct bt_ctf_field_integer
*integer
= g_new0(
671 struct bt_ctf_field_integer
, 1);
674 integer
->definition
.declaration
= &integer_type
->declaration
;
677 return integer
? &integer
->parent
: NULL
;
681 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
682 struct bt_ctf_field_type
*type
)
684 struct bt_ctf_field_enumeration
*enumeration
= g_new0(
685 struct bt_ctf_field_enumeration
, 1);
687 return enumeration
? &enumeration
->parent
: NULL
;
691 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
692 struct bt_ctf_field_type
*type
)
694 struct bt_ctf_field_floating_point
*floating_point
;
695 struct bt_ctf_field_type_floating_point
*floating_point_type
;
697 floating_point
= g_new0(struct bt_ctf_field_floating_point
, 1);
698 if (!floating_point
) {
702 floating_point_type
= container_of(type
,
703 struct bt_ctf_field_type_floating_point
, parent
);
704 floating_point
->definition
.declaration
= container_of(
705 type
->declaration
, struct declaration_float
, p
);
708 floating_point
->definition
.sign
= &floating_point
->sign
;
709 floating_point
->sign
.declaration
= &floating_point_type
->sign
;
710 floating_point
->definition
.sign
->p
.declaration
=
711 &floating_point_type
->sign
.p
;
713 floating_point
->definition
.mantissa
= &floating_point
->mantissa
;
714 floating_point
->mantissa
.declaration
= &floating_point_type
->mantissa
;
715 floating_point
->definition
.mantissa
->p
.declaration
=
716 &floating_point_type
->mantissa
.p
;
718 floating_point
->definition
.exp
= &floating_point
->exp
;
719 floating_point
->exp
.declaration
= &floating_point_type
->exp
;
720 floating_point
->definition
.exp
->p
.declaration
=
721 &floating_point_type
->exp
.p
;
724 return floating_point
? &floating_point
->parent
: NULL
;
728 struct bt_ctf_field
*bt_ctf_field_structure_create(
729 struct bt_ctf_field_type
*type
)
731 struct bt_ctf_field_type_structure
*structure_type
= container_of(type
,
732 struct bt_ctf_field_type_structure
, parent
);
733 struct bt_ctf_field_structure
*structure
= g_new0(
734 struct bt_ctf_field_structure
, 1);
735 struct bt_ctf_field
*field
= NULL
;
737 if (!structure
|| !structure_type
->fields
->len
) {
741 structure
->field_name_to_index
= structure_type
->field_name_to_index
;
742 structure
->fields
= g_ptr_array_new_with_free_func(
743 (GDestroyNotify
)bt_ctf_field_put
);
744 g_ptr_array_set_size(structure
->fields
,
745 g_hash_table_size(structure
->field_name_to_index
));
746 field
= &structure
->parent
;
752 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*type
)
754 struct bt_ctf_field_variant
*variant
= g_new0(
755 struct bt_ctf_field_variant
, 1);
756 return variant
? &variant
->parent
: NULL
;
760 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*type
)
762 struct bt_ctf_field_array
*array
= g_new0(struct bt_ctf_field_array
, 1);
763 struct bt_ctf_field_type_array
*array_type
;
764 unsigned int array_length
;
766 if (!array
|| !type
) {
770 array_type
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
771 array_length
= array_type
->length
;
772 array
->elements
= g_ptr_array_sized_new(array_length
);
773 if (!array
->elements
) {
777 g_ptr_array_set_free_func(array
->elements
,
778 (GDestroyNotify
)bt_ctf_field_put
);
779 g_ptr_array_set_size(array
->elements
, array_length
);
780 return &array
->parent
;
787 struct bt_ctf_field
*bt_ctf_field_sequence_create(
788 struct bt_ctf_field_type
*type
)
790 struct bt_ctf_field_sequence
*sequence
= g_new0(
791 struct bt_ctf_field_sequence
, 1);
792 return sequence
? &sequence
->parent
: NULL
;
796 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*type
)
798 struct bt_ctf_field_string
*string
= g_new0(
799 struct bt_ctf_field_string
, 1);
800 return string
? &string
->parent
: NULL
;
804 void bt_ctf_field_destroy(struct bt_ctf_ref
*ref
)
806 struct bt_ctf_field
*field
;
807 struct bt_ctf_field_type
*type
;
808 enum ctf_type_id type_id
;
814 field
= container_of(ref
, struct bt_ctf_field
, ref_count
);
816 type_id
= bt_ctf_field_type_get_type_id(type
);
817 if (type_id
<= CTF_TYPE_UNKNOWN
||
818 type_id
>= NR_CTF_TYPES
) {
822 field_destroy_funcs
[type_id
](field
);
824 bt_ctf_field_type_put(type
);
829 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*field
)
831 struct bt_ctf_field_integer
*integer
;
837 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
842 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field
*field
)
844 struct bt_ctf_field_enumeration
*enumeration
;
850 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
852 bt_ctf_field_put(enumeration
->payload
);
857 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*field
)
859 struct bt_ctf_field_floating_point
*floating_point
;
865 floating_point
= container_of(field
, struct bt_ctf_field_floating_point
,
867 g_free(floating_point
);
871 void bt_ctf_field_structure_destroy(struct bt_ctf_field
*field
)
873 struct bt_ctf_field_structure
*structure
;
879 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
880 g_ptr_array_free(structure
->fields
, TRUE
);
885 void bt_ctf_field_variant_destroy(struct bt_ctf_field
*field
)
887 struct bt_ctf_field_variant
*variant
;
893 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
894 bt_ctf_field_put(variant
->tag
);
895 bt_ctf_field_put(variant
->payload
);
900 void bt_ctf_field_array_destroy(struct bt_ctf_field
*field
)
902 struct bt_ctf_field_array
*array
;
908 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
909 g_ptr_array_free(array
->elements
, TRUE
);
914 void bt_ctf_field_sequence_destroy(struct bt_ctf_field
*field
)
916 struct bt_ctf_field_sequence
*sequence
;
922 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
923 g_ptr_array_free(sequence
->elements
, TRUE
);
924 bt_ctf_field_put(sequence
->length
);
929 void bt_ctf_field_string_destroy(struct bt_ctf_field
*field
)
931 struct bt_ctf_field_string
*string
;
936 string
= container_of(field
, struct bt_ctf_field_string
, parent
);
937 g_string_free(string
->payload
, TRUE
);
942 int bt_ctf_field_generic_validate(struct bt_ctf_field
*field
)
944 return !(field
&& field
->payload_set
);
948 int bt_ctf_field_enumeration_validate(struct bt_ctf_field
*field
)
951 struct bt_ctf_field_enumeration
*enumeration
;
958 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
960 if (!enumeration
->payload
) {
965 ret
= bt_ctf_field_validate(enumeration
->payload
);
971 int bt_ctf_field_structure_validate(struct bt_ctf_field
*field
)
975 struct bt_ctf_field_structure
*structure
;
982 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
983 for (i
= 0; i
< structure
->fields
->len
; i
++) {
984 ret
= bt_ctf_field_validate(structure
->fields
->pdata
[i
]);
994 int bt_ctf_field_variant_validate(struct bt_ctf_field
*field
)
997 struct bt_ctf_field_variant
*variant
;
1004 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
1005 ret
= bt_ctf_field_validate(variant
->payload
);
1011 int bt_ctf_field_array_validate(struct bt_ctf_field
*field
)
1015 struct bt_ctf_field_array
*array
;
1022 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
1023 for (i
= 0; i
< array
->elements
->len
; i
++) {
1024 ret
= bt_ctf_field_validate(array
->elements
->pdata
[i
]);
1034 int bt_ctf_field_sequence_validate(struct bt_ctf_field
*field
)
1038 struct bt_ctf_field_sequence
*sequence
;
1045 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
1046 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1047 ret
= bt_ctf_field_validate(sequence
->elements
->pdata
[i
]);
1057 int bt_ctf_field_integer_serialize(struct bt_ctf_field
*field
,
1058 struct ctf_stream_pos
*pos
)
1061 struct bt_ctf_field_integer
*integer
= container_of(field
,
1062 struct bt_ctf_field_integer
, parent
);
1065 ret
= ctf_integer_write(&pos
->parent
, &integer
->definition
.p
);
1066 if (ret
== -EFAULT
) {
1068 * The field is too large to fit in the current packet's
1069 * remaining space. Bump the packet size and retry.
1071 ret
= increase_packet_size(pos
);
1082 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field
*field
,
1083 struct ctf_stream_pos
*pos
)
1085 struct bt_ctf_field_enumeration
*enumeration
= container_of(
1086 field
, struct bt_ctf_field_enumeration
, parent
);
1088 return bt_ctf_field_serialize(enumeration
->payload
, pos
);
1092 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field
*field
,
1093 struct ctf_stream_pos
*pos
)
1096 struct bt_ctf_field_floating_point
*floating_point
= container_of(field
,
1097 struct bt_ctf_field_floating_point
, parent
);
1100 ret
= ctf_float_write(&pos
->parent
, &floating_point
->definition
.p
);
1101 if (ret
== -EFAULT
) {
1103 * The field is too large to fit in the current packet's
1104 * remaining space. Bump the packet size and retry.
1106 ret
= increase_packet_size(pos
);
1117 int bt_ctf_field_structure_serialize(struct bt_ctf_field
*field
,
1118 struct ctf_stream_pos
*pos
)
1122 struct bt_ctf_field_structure
*structure
= container_of(
1123 field
, struct bt_ctf_field_structure
, parent
);
1125 while (!ctf_pos_access_ok(pos
,
1126 offset_align(pos
->offset
,
1127 field
->type
->declaration
->alignment
))) {
1128 ret
= increase_packet_size(pos
);
1134 ctf_align_pos(pos
, field
->type
->declaration
->alignment
);
1136 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1137 struct bt_ctf_field
*field
= g_ptr_array_index(
1138 structure
->fields
, i
);
1140 ret
= bt_ctf_field_serialize(field
, pos
);
1150 int bt_ctf_field_variant_serialize(struct bt_ctf_field
*field
,
1151 struct ctf_stream_pos
*pos
)
1153 struct bt_ctf_field_variant
*variant
= container_of(
1154 field
, struct bt_ctf_field_variant
, parent
);
1156 return bt_ctf_field_serialize(variant
->payload
, pos
);
1160 int bt_ctf_field_array_serialize(struct bt_ctf_field
*field
,
1161 struct ctf_stream_pos
*pos
)
1165 struct bt_ctf_field_array
*array
= container_of(
1166 field
, struct bt_ctf_field_array
, parent
);
1168 for (i
= 0; i
< array
->elements
->len
; i
++) {
1169 ret
= bt_ctf_field_serialize(
1170 g_ptr_array_index(array
->elements
, i
), pos
);
1180 int bt_ctf_field_sequence_serialize(struct bt_ctf_field
*field
,
1181 struct ctf_stream_pos
*pos
)
1185 struct bt_ctf_field_sequence
*sequence
= container_of(
1186 field
, struct bt_ctf_field_sequence
, parent
);
1188 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1189 ret
= bt_ctf_field_serialize(
1190 g_ptr_array_index(sequence
->elements
, i
), pos
);
1200 int bt_ctf_field_string_serialize(struct bt_ctf_field
*field
,
1201 struct ctf_stream_pos
*pos
)
1205 struct bt_ctf_field_string
*string
= container_of(field
,
1206 struct bt_ctf_field_string
, parent
);
1207 struct bt_ctf_field_type
*character_type
=
1208 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
1209 struct bt_ctf_field
*character
= bt_ctf_field_create(character_type
);
1211 for (i
= 0; i
< string
->payload
->len
+ 1; i
++) {
1212 ret
= bt_ctf_field_unsigned_integer_set_value(character
,
1213 (uint64_t) string
->payload
->str
[i
]);
1218 ret
= bt_ctf_field_integer_serialize(character
, pos
);
1224 bt_ctf_field_put(character
);
1225 bt_ctf_field_type_put(character_type
);
1230 int increase_packet_size(struct ctf_stream_pos
*pos
)
1235 ret
= munmap_align(pos
->base_mma
);
1240 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
1241 ret
= posix_fallocate(pos
->fd
, pos
->mmap_offset
,
1242 pos
->packet_size
/ CHAR_BIT
);
1247 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
1248 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
1249 if (pos
->base_mma
== MAP_FAILED
) {