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_new_full((size_t)sequence_length
,
251 (GDestroyNotify
)bt_ctf_field_put
);
252 if (!sequence
->elements
) {
257 g_ptr_array_set_size(sequence
->elements
, (size_t)sequence_length
);
258 bt_ctf_field_get(length_field
);
259 sequence
->length
= length_field
;
264 struct bt_ctf_field
*bt_ctf_field_structure_get_field(
265 struct bt_ctf_field
*field
, const char *name
)
267 struct bt_ctf_field
*new_field
= NULL
;
269 struct bt_ctf_field_structure
*structure
;
270 struct bt_ctf_field_type_structure
*structure_type
;
271 struct bt_ctf_field_type
*field_type
;
274 if (!field
|| !name
||
275 bt_ctf_field_type_get_type_id(field
->type
) !=
280 field_quark
= g_quark_from_string(name
);
281 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
282 structure_type
= container_of(field
->type
,
283 struct bt_ctf_field_type_structure
, parent
);
284 field_type
= bt_ctf_field_type_structure_get_type(structure_type
, name
);
285 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
286 GUINT_TO_POINTER(field_quark
), NULL
, (gpointer
*)&index
)) {
290 if (structure
->fields
->pdata
[index
]) {
291 new_field
= structure
->fields
->pdata
[index
];
295 new_field
= bt_ctf_field_create(field_type
);
300 structure
->fields
->pdata
[index
] = new_field
;
302 bt_ctf_field_get(new_field
);
308 int bt_ctf_field_structure_set_field(struct bt_ctf_field
*field
,
309 const char *name
, struct bt_ctf_field
*value
)
313 struct bt_ctf_field_structure
*structure
;
314 struct bt_ctf_field_type_structure
*structure_type
;
315 struct bt_ctf_field_type
*expected_field_type
;
318 if (!field
|| !name
|| !value
||
319 bt_ctf_field_type_get_type_id(field
->type
) !=
325 field_quark
= g_quark_from_string(name
);
326 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
327 structure_type
= container_of(field
->type
,
328 struct bt_ctf_field_type_structure
, parent
);
329 expected_field_type
= bt_ctf_field_type_structure_get_type(
330 structure_type
, name
);
331 if (expected_field_type
!= value
->type
) {
336 if (!g_hash_table_lookup_extended(structure
->field_name_to_index
,
337 GUINT_TO_POINTER(field_quark
), NULL
, (gpointer
*) &index
)) {
341 if (structure
->fields
->pdata
[index
]) {
342 bt_ctf_field_put(structure
->fields
->pdata
[index
]);
345 structure
->fields
->pdata
[index
] = value
;
346 bt_ctf_field_get(value
);
351 struct bt_ctf_field
*bt_ctf_field_array_get_field(struct bt_ctf_field
*field
,
354 struct bt_ctf_field
*new_field
= NULL
;
355 struct bt_ctf_field_array
*array
;
356 struct bt_ctf_field_type_array
*array_type
;
357 struct bt_ctf_field_type
*field_type
;
359 if (!field
|| bt_ctf_field_type_get_type_id(field
->type
) !=
364 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
365 if (index
>= array
->elements
->len
) {
369 array_type
= container_of(field
->type
, struct bt_ctf_field_type_array
,
371 field_type
= bt_ctf_field_type_array_get_element_type(array_type
);
372 if (array
->elements
->pdata
[(size_t)index
]) {
373 new_field
= array
->elements
->pdata
[(size_t)index
];
377 new_field
= bt_ctf_field_create(field_type
);
378 bt_ctf_field_get(new_field
);
379 array
->elements
->pdata
[(size_t)index
] = new_field
;
384 struct bt_ctf_field
*bt_ctf_field_sequence_get_field(struct bt_ctf_field
*field
,
387 struct bt_ctf_field
*new_field
= NULL
;
388 struct bt_ctf_field_sequence
*sequence
;
389 struct bt_ctf_field_type_sequence
*sequence_type
;
390 struct bt_ctf_field_type
*field_type
;
392 if (!field
|| bt_ctf_field_type_get_type_id(field
->type
) !=
397 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
398 if (!sequence
->elements
|| sequence
->elements
->len
<= index
) {
402 sequence_type
= container_of(field
->type
,
403 struct bt_ctf_field_type_sequence
, parent
);
404 field_type
= bt_ctf_field_type_sequence_get_element_type(sequence_type
);
405 if (sequence
->elements
->pdata
[(size_t)index
]) {
406 new_field
= sequence
->elements
->pdata
[(size_t)index
];
410 new_field
= bt_ctf_field_create(field_type
);
411 bt_ctf_field_get(new_field
);
412 sequence
->elements
->pdata
[(size_t)index
] = new_field
;
417 struct bt_ctf_field
*bt_ctf_field_variant_get_field(struct bt_ctf_field
*field
,
418 struct bt_ctf_field
*tag_field
)
420 struct bt_ctf_field
*new_field
= NULL
;
421 struct bt_ctf_field_variant
*variant
;
422 struct bt_ctf_field_type_variant
*variant_type
;
423 struct bt_ctf_field_type
*field_type
;
424 struct bt_ctf_field
*tag_enum
= NULL
;
425 struct bt_ctf_field_integer
*tag_enum_integer
;
426 int64_t tag_enum_value
;
428 if (!field
|| !tag_field
||
429 bt_ctf_field_type_get_type_id(field
->type
) !=
431 bt_ctf_field_type_get_type_id(tag_field
->type
) !=
436 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
437 variant_type
= container_of(field
->type
,
438 struct bt_ctf_field_type_variant
, parent
);
439 tag_enum
= bt_ctf_field_enumeration_get_container(tag_field
);
444 tag_enum_integer
= container_of(tag_enum
, struct bt_ctf_field_integer
,
447 if (!bt_ctf_field_validate(variant
->tag
)) {
451 tag_enum_value
= tag_enum_integer
->definition
.value
._signed
;
452 field_type
= bt_ctf_field_type_variant_get_field_type(variant_type
,
458 new_field
= bt_ctf_field_create(field_type
);
463 bt_ctf_field_put(variant
->tag
);
464 bt_ctf_field_put(variant
->payload
);
465 bt_ctf_field_get(new_field
);
466 bt_ctf_field_get(tag_field
);
467 variant
->tag
= tag_field
;
468 variant
->payload
= new_field
;
470 bt_ctf_field_put(tag_enum
);
474 struct bt_ctf_field
*bt_ctf_field_enumeration_get_container(
475 struct bt_ctf_field
*field
)
477 struct bt_ctf_field
*container
= NULL
;
478 struct bt_ctf_field_enumeration
*enumeration
;
484 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
486 if (!enumeration
->payload
) {
487 struct bt_ctf_field_type_enumeration
*enumeration_type
=
488 container_of(field
->type
,
489 struct bt_ctf_field_type_enumeration
, parent
);
490 enumeration
->payload
=
491 bt_ctf_field_create(enumeration_type
->container
);
494 container
= enumeration
->payload
;
495 bt_ctf_field_get(container
);
500 int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field
*field
,
504 struct bt_ctf_field_integer
*integer
;
505 struct bt_ctf_field_type_integer
*integer_type
;
507 int64_t min_value
, max_value
;
510 bt_ctf_field_type_get_type_id(field
->type
) !=
516 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
517 integer_type
= container_of(field
->type
,
518 struct bt_ctf_field_type_integer
, parent
);
519 if (!integer_type
->declaration
.signedness
) {
524 size
= integer_type
->declaration
.len
;
525 min_value
= -((int64_t)1 << (size
- 1));
526 max_value
= ((int64_t)1 << (size
- 1)) - 1;
527 if (value
< min_value
|| value
> max_value
) {
532 integer
->definition
.value
._signed
= value
;
533 integer
->parent
.payload_set
= 1;
538 int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field
*field
,
542 struct bt_ctf_field_integer
*integer
;
543 struct bt_ctf_field_type_integer
*integer_type
;
548 bt_ctf_field_type_get_type_id(field
->type
) !=
554 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
555 integer_type
= container_of(field
->type
,
556 struct bt_ctf_field_type_integer
, parent
);
557 if (integer_type
->declaration
.signedness
) {
562 size
= integer_type
->declaration
.len
;
563 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t)1 << size
) - 1;
564 if (value
> max_value
) {
569 integer
->definition
.value
._unsigned
= value
;
570 integer
->parent
.payload_set
= 1;
575 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field
*field
,
579 struct bt_ctf_field_floating_point
*floating_point
;
582 bt_ctf_field_type_get_type_id(field
->type
) !=
587 floating_point
= container_of(field
, struct bt_ctf_field_floating_point
,
589 floating_point
->definition
.value
= value
;
590 floating_point
->parent
.payload_set
= 1;
595 int bt_ctf_field_string_set_value(struct bt_ctf_field
*field
,
599 struct bt_ctf_field_string
*string
;
601 if (!field
|| !value
||
602 bt_ctf_field_type_get_type_id(field
->type
) !=
608 string
= container_of(field
, struct bt_ctf_field_string
, parent
);
609 if (string
->payload
) {
610 g_string_free(string
->payload
, TRUE
);
613 string
->payload
= g_string_new(value
);
614 string
->parent
.payload_set
= 1;
620 int bt_ctf_field_validate(struct bt_ctf_field
*field
)
623 enum ctf_type_id type_id
;
630 type_id
= bt_ctf_field_type_get_type_id(field
->type
);
631 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
) {
636 ret
= field_validate_funcs
[type_id
](field
);
642 int bt_ctf_field_serialize(struct bt_ctf_field
*field
,
643 struct ctf_stream_pos
*pos
)
646 enum ctf_type_id type_id
;
648 if (!field
|| !pos
) {
653 type_id
= bt_ctf_field_type_get_type_id(field
->type
);
654 if (type_id
<= CTF_TYPE_UNKNOWN
|| type_id
>= NR_CTF_TYPES
) {
659 ret
= field_serialize_funcs
[type_id
](field
, pos
);
665 struct bt_ctf_field
*bt_ctf_field_integer_create(struct bt_ctf_field_type
*type
)
667 struct bt_ctf_field_type_integer
*integer_type
= container_of(type
,
668 struct bt_ctf_field_type_integer
, parent
);
669 struct bt_ctf_field_integer
*integer
= g_new0(
670 struct bt_ctf_field_integer
, 1);
673 integer
->definition
.declaration
= &integer_type
->declaration
;
676 return integer
? &integer
->parent
: NULL
;
680 struct bt_ctf_field
*bt_ctf_field_enumeration_create(
681 struct bt_ctf_field_type
*type
)
683 struct bt_ctf_field_enumeration
*enumeration
= g_new0(
684 struct bt_ctf_field_enumeration
, 1);
686 return enumeration
? &enumeration
->parent
: NULL
;
690 struct bt_ctf_field
*bt_ctf_field_floating_point_create(
691 struct bt_ctf_field_type
*type
)
693 struct bt_ctf_field_floating_point
*floating_point
;
694 struct bt_ctf_field_type_floating_point
*floating_point_type
;
696 floating_point
= g_new0(struct bt_ctf_field_floating_point
, 1);
697 if (!floating_point
) {
701 floating_point_type
= container_of(type
,
702 struct bt_ctf_field_type_floating_point
, parent
);
703 floating_point
->definition
.declaration
= container_of(
704 type
->declaration
, struct declaration_float
, p
);
707 floating_point
->definition
.sign
= &floating_point
->sign
;
708 floating_point
->sign
.declaration
= &floating_point_type
->sign
;
709 floating_point
->definition
.sign
->p
.declaration
=
710 &floating_point_type
->sign
.p
;
712 floating_point
->definition
.mantissa
= &floating_point
->mantissa
;
713 floating_point
->mantissa
.declaration
= &floating_point_type
->mantissa
;
714 floating_point
->definition
.mantissa
->p
.declaration
=
715 &floating_point_type
->mantissa
.p
;
717 floating_point
->definition
.exp
= &floating_point
->exp
;
718 floating_point
->exp
.declaration
= &floating_point_type
->exp
;
719 floating_point
->definition
.exp
->p
.declaration
=
720 &floating_point_type
->exp
.p
;
723 return floating_point
? &floating_point
->parent
: NULL
;
727 struct bt_ctf_field
*bt_ctf_field_structure_create(
728 struct bt_ctf_field_type
*type
)
730 struct bt_ctf_field_type_structure
*structure_type
= container_of(type
,
731 struct bt_ctf_field_type_structure
, parent
);
732 struct bt_ctf_field_structure
*structure
= g_new0(
733 struct bt_ctf_field_structure
, 1);
734 struct bt_ctf_field
*field
= NULL
;
736 if (!structure
|| !structure_type
->fields
->len
) {
740 structure
->field_name_to_index
= structure_type
->field_name_to_index
;
741 structure
->fields
= g_ptr_array_new_with_free_func(
742 (GDestroyNotify
)bt_ctf_field_put
);
743 g_ptr_array_set_size(structure
->fields
,
744 g_hash_table_size(structure
->field_name_to_index
));
745 field
= &structure
->parent
;
751 struct bt_ctf_field
*bt_ctf_field_variant_create(struct bt_ctf_field_type
*type
)
753 struct bt_ctf_field_variant
*variant
= g_new0(
754 struct bt_ctf_field_variant
, 1);
755 return variant
? &variant
->parent
: NULL
;
759 struct bt_ctf_field
*bt_ctf_field_array_create(struct bt_ctf_field_type
*type
)
761 struct bt_ctf_field_array
*array
= g_new0(struct bt_ctf_field_array
, 1);
762 struct bt_ctf_field_type_array
*array_type
;
763 unsigned int array_length
;
765 if (!array
|| !type
) {
769 array_type
= container_of(type
, struct bt_ctf_field_type_array
, parent
);
770 array_length
= array_type
->length
;
771 array
->elements
= g_ptr_array_new_full(array_length
,
772 (GDestroyNotify
)bt_ctf_field_put
);
773 if (!array
->elements
) {
777 g_ptr_array_set_size(array
->elements
, array_length
);
778 return &array
->parent
;
785 struct bt_ctf_field
*bt_ctf_field_sequence_create(
786 struct bt_ctf_field_type
*type
)
788 struct bt_ctf_field_sequence
*sequence
= g_new0(
789 struct bt_ctf_field_sequence
, 1);
790 return sequence
? &sequence
->parent
: NULL
;
794 struct bt_ctf_field
*bt_ctf_field_string_create(struct bt_ctf_field_type
*type
)
796 struct bt_ctf_field_string
*string
= g_new0(
797 struct bt_ctf_field_string
, 1);
798 return string
? &string
->parent
: NULL
;
802 void bt_ctf_field_destroy(struct bt_ctf_ref
*ref
)
804 struct bt_ctf_field
*field
;
805 struct bt_ctf_field_type
*type
;
806 enum ctf_type_id type_id
;
812 field
= container_of(ref
, struct bt_ctf_field
, ref_count
);
814 type_id
= bt_ctf_field_type_get_type_id(type
);
815 if (type_id
<= CTF_TYPE_UNKNOWN
||
816 type_id
>= NR_CTF_TYPES
) {
820 field_destroy_funcs
[type_id
](field
);
822 bt_ctf_field_type_put(type
);
827 void bt_ctf_field_integer_destroy(struct bt_ctf_field
*field
)
829 struct bt_ctf_field_integer
*integer
;
835 integer
= container_of(field
, struct bt_ctf_field_integer
, parent
);
840 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field
*field
)
842 struct bt_ctf_field_enumeration
*enumeration
;
848 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
850 bt_ctf_field_put(enumeration
->payload
);
855 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field
*field
)
857 struct bt_ctf_field_floating_point
*floating_point
;
863 floating_point
= container_of(field
, struct bt_ctf_field_floating_point
,
865 g_free(floating_point
);
869 void bt_ctf_field_structure_destroy(struct bt_ctf_field
*field
)
871 struct bt_ctf_field_structure
*structure
;
877 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
878 g_ptr_array_free(structure
->fields
, TRUE
);
883 void bt_ctf_field_variant_destroy(struct bt_ctf_field
*field
)
885 struct bt_ctf_field_variant
*variant
;
891 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
892 bt_ctf_field_put(variant
->tag
);
893 bt_ctf_field_put(variant
->payload
);
898 void bt_ctf_field_array_destroy(struct bt_ctf_field
*field
)
900 struct bt_ctf_field_array
*array
;
906 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
907 g_ptr_array_free(array
->elements
, TRUE
);
912 void bt_ctf_field_sequence_destroy(struct bt_ctf_field
*field
)
914 struct bt_ctf_field_sequence
*sequence
;
920 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
921 g_ptr_array_free(sequence
->elements
, TRUE
);
922 bt_ctf_field_put(sequence
->length
);
927 void bt_ctf_field_string_destroy(struct bt_ctf_field
*field
)
929 struct bt_ctf_field_string
*string
;
934 string
= container_of(field
, struct bt_ctf_field_string
, parent
);
935 g_string_free(string
->payload
, TRUE
);
940 int bt_ctf_field_generic_validate(struct bt_ctf_field
*field
)
942 return (field
&& field
->payload_set
) ? 0 : -1;
946 int bt_ctf_field_enumeration_validate(struct bt_ctf_field
*field
)
949 struct bt_ctf_field_enumeration
*enumeration
;
956 enumeration
= container_of(field
, struct bt_ctf_field_enumeration
,
958 if (!enumeration
->payload
) {
963 ret
= bt_ctf_field_validate(enumeration
->payload
);
969 int bt_ctf_field_structure_validate(struct bt_ctf_field
*field
)
973 struct bt_ctf_field_structure
*structure
;
980 structure
= container_of(field
, struct bt_ctf_field_structure
, parent
);
981 for (i
= 0; i
< structure
->fields
->len
; i
++) {
982 ret
= bt_ctf_field_validate(structure
->fields
->pdata
[i
]);
992 int bt_ctf_field_variant_validate(struct bt_ctf_field
*field
)
995 struct bt_ctf_field_variant
*variant
;
1002 variant
= container_of(field
, struct bt_ctf_field_variant
, parent
);
1003 ret
= bt_ctf_field_validate(variant
->payload
);
1009 int bt_ctf_field_array_validate(struct bt_ctf_field
*field
)
1013 struct bt_ctf_field_array
*array
;
1020 array
= container_of(field
, struct bt_ctf_field_array
, parent
);
1021 for (i
= 0; i
< array
->elements
->len
; i
++) {
1022 ret
= bt_ctf_field_validate(array
->elements
->pdata
[i
]);
1032 int bt_ctf_field_sequence_validate(struct bt_ctf_field
*field
)
1036 struct bt_ctf_field_sequence
*sequence
;
1043 sequence
= container_of(field
, struct bt_ctf_field_sequence
, parent
);
1044 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1045 ret
= bt_ctf_field_validate(sequence
->elements
->pdata
[i
]);
1055 int bt_ctf_field_integer_serialize(struct bt_ctf_field
*field
,
1056 struct ctf_stream_pos
*pos
)
1059 struct bt_ctf_field_integer
*integer
= container_of(field
,
1060 struct bt_ctf_field_integer
, parent
);
1063 ret
= ctf_integer_write(&pos
->parent
, &integer
->definition
.p
);
1064 if (ret
== -EFAULT
) {
1066 * The field is too large to fit in the current packet's
1067 * remaining space. Bump the packet size and retry.
1069 ret
= increase_packet_size(pos
);
1080 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field
*field
,
1081 struct ctf_stream_pos
*pos
)
1083 struct bt_ctf_field_enumeration
*enumeration
= container_of(
1084 field
, struct bt_ctf_field_enumeration
, parent
);
1086 return bt_ctf_field_serialize(enumeration
->payload
, pos
);
1090 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field
*field
,
1091 struct ctf_stream_pos
*pos
)
1094 struct bt_ctf_field_floating_point
*floating_point
= container_of(field
,
1095 struct bt_ctf_field_floating_point
, parent
);
1098 ret
= ctf_float_write(&pos
->parent
, &floating_point
->definition
.p
);
1099 if (ret
== -EFAULT
) {
1101 * The field is too large to fit in the current packet's
1102 * remaining space. Bump the packet size and retry.
1104 ret
= increase_packet_size(pos
);
1115 int bt_ctf_field_structure_serialize(struct bt_ctf_field
*field
,
1116 struct ctf_stream_pos
*pos
)
1120 struct bt_ctf_field_structure
*structure
= container_of(
1121 field
, struct bt_ctf_field_structure
, parent
);
1123 while (!ctf_pos_access_ok(pos
,
1124 offset_align(pos
->offset
,
1125 field
->type
->declaration
->alignment
))) {
1126 increase_packet_size(pos
);
1129 ctf_align_pos(pos
, field
->type
->declaration
->alignment
);
1131 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1132 struct bt_ctf_field
*field
= g_ptr_array_index(
1133 structure
->fields
, i
);
1135 ret
= bt_ctf_field_serialize(field
, pos
);
1145 int bt_ctf_field_variant_serialize(struct bt_ctf_field
*field
,
1146 struct ctf_stream_pos
*pos
)
1148 struct bt_ctf_field_variant
*variant
= container_of(
1149 field
, struct bt_ctf_field_variant
, parent
);
1151 return bt_ctf_field_serialize(variant
->payload
, pos
);
1155 int bt_ctf_field_array_serialize(struct bt_ctf_field
*field
,
1156 struct ctf_stream_pos
*pos
)
1160 struct bt_ctf_field_array
*array
= container_of(
1161 field
, struct bt_ctf_field_array
, parent
);
1163 for (i
= 0; i
< array
->elements
->len
; i
++) {
1164 ret
= bt_ctf_field_serialize(
1165 g_ptr_array_index(array
->elements
, i
), pos
);
1175 int bt_ctf_field_sequence_serialize(struct bt_ctf_field
*field
,
1176 struct ctf_stream_pos
*pos
)
1180 struct bt_ctf_field_sequence
*sequence
= container_of(
1181 field
, struct bt_ctf_field_sequence
, parent
);
1183 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1184 ret
= bt_ctf_field_serialize(
1185 g_ptr_array_index(sequence
->elements
, i
), pos
);
1195 int bt_ctf_field_string_serialize(struct bt_ctf_field
*field
,
1196 struct ctf_stream_pos
*pos
)
1200 struct bt_ctf_field_string
*string
= container_of(field
,
1201 struct bt_ctf_field_string
, parent
);
1202 struct bt_ctf_field_type
*character_type
=
1203 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
1204 struct bt_ctf_field
*character
= bt_ctf_field_create(character_type
);
1206 for (i
= 0; i
< string
->payload
->len
+ 1; i
++) {
1207 ret
= bt_ctf_field_unsigned_integer_set_value(character
,
1208 (uint64_t) string
->payload
->str
[i
]);
1213 ret
= bt_ctf_field_integer_serialize(character
, pos
);
1219 bt_ctf_field_put(character
);
1220 bt_ctf_field_type_put(character_type
);
1225 int increase_packet_size(struct ctf_stream_pos
*pos
)
1230 ret
= munmap_align(pos
->base_mma
);
1235 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
1236 ret
= posix_fallocate(pos
->fd
, pos
->mmap_offset
,
1237 pos
->packet_size
/ CHAR_BIT
);
1242 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
1243 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
1244 if (pos
->base_mma
== MAP_FAILED
) {