4 * Babeltrace CTF IR - Event Fields
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 #define BT_LOG_TAG "FIELDS"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/ctf-ir/fields-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-writer/serialize-internal.h>
35 #include <babeltrace/object-internal.h>
36 #include <babeltrace/ref.h>
37 #include <babeltrace/compiler-internal.h>
38 #include <babeltrace/compat/fcntl-internal.h>
39 #include <babeltrace/align-internal.h>
43 struct bt_field
*bt_field_integer_create(struct bt_field_type
*);
45 struct bt_field
*bt_field_enumeration_create(
46 struct bt_field_type
*);
48 struct bt_field
*bt_field_floating_point_create(
49 struct bt_field_type
*);
51 struct bt_field
*bt_field_structure_create(
52 struct bt_field_type
*);
54 struct bt_field
*bt_field_variant_create(
55 struct bt_field_type
*);
57 struct bt_field
*bt_field_array_create(
58 struct bt_field_type
*);
60 struct bt_field
*bt_field_sequence_create(
61 struct bt_field_type
*);
63 struct bt_field
*bt_field_string_create(struct bt_field_type
*);
66 void bt_field_destroy(struct bt_object
*);
68 void bt_field_integer_destroy(struct bt_field
*);
70 void bt_field_enumeration_destroy(struct bt_field
*);
72 void bt_field_floating_point_destroy(struct bt_field
*);
74 void bt_field_structure_destroy(struct bt_field
*);
76 void bt_field_variant_destroy(struct bt_field
*);
78 void bt_field_array_destroy(struct bt_field
*);
80 void bt_field_sequence_destroy(struct bt_field
*);
82 void bt_field_string_destroy(struct bt_field
*);
85 int bt_field_generic_validate(struct bt_field
*);
87 int bt_field_structure_validate(struct bt_field
*);
89 int bt_field_variant_validate(struct bt_field
*);
91 int bt_field_enumeration_validate(struct bt_field
*);
93 int bt_field_array_validate(struct bt_field
*);
95 int bt_field_sequence_validate(struct bt_field
*);
98 int bt_field_generic_reset(struct bt_field
*);
100 int bt_field_structure_reset(struct bt_field
*);
102 int bt_field_variant_reset(struct bt_field
*);
104 int bt_field_enumeration_reset(struct bt_field
*);
106 int bt_field_array_reset(struct bt_field
*);
108 int bt_field_sequence_reset(struct bt_field
*);
110 int bt_field_string_reset(struct bt_field
*);
113 int bt_field_integer_serialize(struct bt_field
*,
114 struct bt_stream_pos
*, enum bt_byte_order
);
116 int bt_field_enumeration_serialize(struct bt_field
*,
117 struct bt_stream_pos
*, enum bt_byte_order
);
119 int bt_field_floating_point_serialize(struct bt_field
*,
120 struct bt_stream_pos
*, enum bt_byte_order
);
122 int bt_field_structure_serialize(struct bt_field
*,
123 struct bt_stream_pos
*, enum bt_byte_order
);
125 int bt_field_variant_serialize(struct bt_field
*,
126 struct bt_stream_pos
*, enum bt_byte_order
);
128 int bt_field_array_serialize(struct bt_field
*,
129 struct bt_stream_pos
*, enum bt_byte_order
);
131 int bt_field_sequence_serialize(struct bt_field
*,
132 struct bt_stream_pos
*, enum bt_byte_order
);
134 int bt_field_string_serialize(struct bt_field
*,
135 struct bt_stream_pos
*, enum bt_byte_order
);
138 int bt_field_integer_copy(struct bt_field
*, struct bt_field
*);
140 int bt_field_enumeration_copy(struct bt_field
*, struct bt_field
*);
142 int bt_field_floating_point_copy(struct bt_field
*,
145 int bt_field_structure_copy(struct bt_field
*, struct bt_field
*);
147 int bt_field_variant_copy(struct bt_field
*, struct bt_field
*);
149 int bt_field_array_copy(struct bt_field
*, struct bt_field
*);
151 int bt_field_sequence_copy(struct bt_field
*, struct bt_field
*);
153 int bt_field_string_copy(struct bt_field
*, struct bt_field
*);
156 void generic_field_freeze(struct bt_field
*);
158 void bt_field_enumeration_freeze(struct bt_field
*);
160 void bt_field_structure_freeze(struct bt_field
*);
162 void bt_field_variant_freeze(struct bt_field
*);
164 void bt_field_array_freeze(struct bt_field
*);
166 void bt_field_sequence_freeze(struct bt_field
*);
169 bt_bool
bt_field_generic_is_set(struct bt_field
*);
171 bt_bool
bt_field_structure_is_set(struct bt_field
*);
173 bt_bool
bt_field_variant_is_set(struct bt_field
*);
175 bt_bool
bt_field_enumeration_is_set(struct bt_field
*);
177 bt_bool
bt_field_array_is_set(struct bt_field
*);
179 bt_bool
bt_field_sequence_is_set(struct bt_field
*);
182 int increase_packet_size(struct bt_stream_pos
*pos
);
185 struct bt_field
*(* const field_create_funcs
[])(
186 struct bt_field_type
*) = {
187 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_create
,
188 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_create
,
189 [BT_FIELD_TYPE_ID_FLOAT
] =
190 bt_field_floating_point_create
,
191 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_create
,
192 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_create
,
193 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_create
,
194 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_create
,
195 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_create
,
199 void (* const field_destroy_funcs
[])(struct bt_field
*) = {
200 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_destroy
,
201 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_destroy
,
202 [BT_FIELD_TYPE_ID_FLOAT
] =
203 bt_field_floating_point_destroy
,
204 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_destroy
,
205 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_destroy
,
206 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_destroy
,
207 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_destroy
,
208 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_destroy
,
212 int (* const field_validate_funcs
[])(struct bt_field
*) = {
213 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_generic_validate
,
214 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_validate
,
215 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_generic_validate
,
216 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_validate
,
217 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_validate
,
218 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_validate
,
219 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_validate
,
220 [BT_FIELD_TYPE_ID_STRING
] = bt_field_generic_validate
,
224 int (* const field_reset_funcs
[])(struct bt_field
*) = {
225 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_generic_reset
,
226 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_reset
,
227 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_generic_reset
,
228 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_reset
,
229 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_reset
,
230 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_reset
,
231 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_reset
,
232 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_reset
,
236 int (* const field_serialize_funcs
[])(struct bt_field
*,
237 struct bt_stream_pos
*, enum bt_byte_order
) = {
238 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_serialize
,
239 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_serialize
,
240 [BT_FIELD_TYPE_ID_FLOAT
] =
241 bt_field_floating_point_serialize
,
242 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_serialize
,
243 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_serialize
,
244 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_serialize
,
245 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_serialize
,
246 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_serialize
,
250 int (* const field_copy_funcs
[])(struct bt_field
*,
251 struct bt_field
*) = {
252 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_copy
,
253 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_copy
,
254 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_floating_point_copy
,
255 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_copy
,
256 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_copy
,
257 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_copy
,
258 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_copy
,
259 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_copy
,
263 void (* const field_freeze_funcs
[])(struct bt_field
*) = {
264 [BT_FIELD_TYPE_ID_INTEGER
] = generic_field_freeze
,
265 [BT_FIELD_TYPE_ID_FLOAT
] = generic_field_freeze
,
266 [BT_FIELD_TYPE_ID_STRING
] = generic_field_freeze
,
267 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_freeze
,
268 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_freeze
,
269 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_freeze
,
270 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_freeze
,
271 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_freeze
,
275 bt_bool (* const field_is_set_funcs
[])(struct bt_field
*) = {
276 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_generic_is_set
,
277 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_is_set
,
278 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_generic_is_set
,
279 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_is_set
,
280 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_is_set
,
281 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_is_set
,
282 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_is_set
,
283 [BT_FIELD_TYPE_ID_STRING
] = bt_field_generic_is_set
,
286 struct bt_field
*bt_field_create(struct bt_field_type
*type
)
288 struct bt_field
*field
= NULL
;
289 enum bt_field_type_id type_id
;
293 BT_LOGW_STR("Invalid parameter: field type is NULL.");
297 type_id
= bt_field_type_get_type_id(type
);
298 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
||
299 type_id
>= BT_FIELD_TYPE_ID_NR
) {
300 BT_LOGW("Invalid parameter: unknown field type ID: "
301 "ft-addr=%p, ft-id=%d", type
, type_id
);
305 /* Field class MUST be valid */
306 ret
= bt_field_type_validate(type
);
309 BT_LOGW("Invalid parameter: field type is invalid: "
314 field
= field_create_funcs
[type_id
](type
);
319 /* The type's declaration can't change after this point */
320 bt_field_type_freeze(type
);
322 bt_object_init(field
, bt_field_destroy
);
328 /* Pre-2.0 CTF writer backward compatibility */
329 void bt_ctf_field_get(struct bt_field
*field
)
334 /* Pre-2.0 CTF writer backward compatibility */
335 void bt_ctf_field_put(struct bt_field
*field
)
340 struct bt_field_type
*bt_field_get_type(struct bt_field
*field
)
342 struct bt_field_type
*ret
= NULL
;
345 BT_LOGW_STR("Invalid parameter: field is NULL.");
355 enum bt_field_type_id
bt_field_get_type_id(struct bt_field
*field
)
357 enum bt_field_type_id ret
= BT_FIELD_TYPE_ID_UNKNOWN
;
360 BT_LOGW_STR("Invalid parameter: field is NULL.");
364 ret
= bt_field_type_get_type_id(field
->type
);
369 bt_bool
bt_field_is_integer(struct bt_field
*field
)
371 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_INTEGER
;
374 bt_bool
bt_field_is_floating_point(struct bt_field
*field
)
376 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_FLOAT
;
379 bt_bool
bt_field_is_enumeration(struct bt_field
*field
)
381 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_ENUM
;
384 bt_bool
bt_field_is_string(struct bt_field
*field
)
386 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_STRING
;
389 bt_bool
bt_field_is_structure(struct bt_field
*field
)
391 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_STRUCT
;
394 bt_bool
bt_field_is_array(struct bt_field
*field
)
396 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_ARRAY
;
399 bt_bool
bt_field_is_sequence(struct bt_field
*field
)
401 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_SEQUENCE
;
404 bt_bool
bt_field_is_variant(struct bt_field
*field
)
406 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_VARIANT
;
409 struct bt_field
*bt_field_sequence_get_length(
410 struct bt_field
*field
)
412 struct bt_field
*ret
= NULL
;
413 struct bt_field_sequence
*sequence
;
416 BT_LOGW_STR("Invalid parameter: field is NULL.");
420 if (bt_field_type_get_type_id(field
->type
) !=
421 BT_FIELD_TYPE_ID_SEQUENCE
) {
422 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
423 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
425 bt_field_type_id_string(field
->type
->id
));
429 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
430 ret
= sequence
->length
;
436 int bt_field_sequence_set_length(struct bt_field
*field
,
437 struct bt_field
*length_field
)
440 struct bt_field_type_integer
*length_type
;
441 struct bt_field_integer
*length
;
442 struct bt_field_sequence
*sequence
;
443 uint64_t sequence_length
;
446 BT_LOGW_STR("Invalid parameter: field is NULL.");
452 BT_LOGW_STR("Invalid parameter: length field is NULL.");
458 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
464 if (bt_field_type_get_type_id(length_field
->type
) !=
465 BT_FIELD_TYPE_ID_INTEGER
) {
466 BT_LOGW("Invalid parameter: length field's type is not an integer field type: "
467 "field-addr=%p, length-field-addr=%p, length-ft-addr=%p, length-ft-id=%s",
468 field
, length_field
, length_field
->type
,
469 bt_field_type_id_string(length_field
->type
->id
));
474 length_type
= container_of(length_field
->type
,
475 struct bt_field_type_integer
, parent
);
476 /* The length field must be unsigned */
477 if (length_type
->is_signed
) {
478 BT_LOGW("Invalid parameter: length field's type is signed: "
479 "field-addr=%p, length-field-addr=%p, "
480 "length-field-ft-addr=%p", field
, length_field
,
486 if (!bt_field_is_set(length_field
)) {
487 BT_LOGW("Invalid parameter: length field's value is not set: "
488 "field-addr=%p, length-field-addr=%p, "
489 "length-field-ft-addr=%p", field
, length_field
,
495 length
= container_of(length_field
, struct bt_field_integer
,
497 sequence_length
= length
->payload
.unsignd
;
498 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
499 if (sequence
->elements
) {
500 g_ptr_array_free(sequence
->elements
, TRUE
);
501 bt_put(sequence
->length
);
504 sequence
->elements
= g_ptr_array_sized_new((size_t) sequence_length
);
505 if (!sequence
->elements
) {
506 BT_LOGE_STR("Failed to allocate a GPtrArray.");
511 g_ptr_array_set_free_func(sequence
->elements
,
512 (GDestroyNotify
) bt_put
);
513 g_ptr_array_set_size(sequence
->elements
, (size_t) sequence_length
);
514 bt_get(length_field
);
515 sequence
->length
= length_field
;
516 bt_field_freeze(length_field
);
521 struct bt_field
*bt_field_structure_get_field_by_name(
522 struct bt_field
*field
, const char *name
)
524 struct bt_field
*ret
= NULL
;
526 struct bt_field_structure
*structure
;
528 GHashTable
*field_name_to_index
;
531 BT_LOGW_STR("Invalid parameter: field is NULL.");
536 BT_LOGW_STR("Invalid parameter: field name is NULL.");
540 if (bt_field_type_get_type_id(field
->type
) !=
541 BT_FIELD_TYPE_ID_STRUCT
) {
542 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
543 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
545 bt_field_type_id_string(field
->type
->id
));
549 field_name_to_index
=
550 container_of(field
->type
, struct bt_field_type_structure
,
551 parent
)->field_name_to_index
;
552 field_quark
= g_quark_from_string(name
);
553 structure
= container_of(field
, struct bt_field_structure
, parent
);
554 if (!g_hash_table_lookup_extended(field_name_to_index
,
555 GUINT_TO_POINTER(field_quark
),
556 NULL
, (gpointer
*)&index
)) {
557 BT_LOGV("Invalid parameter: no such field in structure field's type: "
558 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
559 field
, field
->type
, name
);
563 ret
= bt_get(structure
->fields
->pdata
[index
]);
569 struct bt_field
*bt_field_structure_get_field_by_index(
570 struct bt_field
*field
, uint64_t index
)
572 struct bt_field_structure
*structure
;
573 struct bt_field
*ret
= NULL
;
576 BT_LOGW_STR("Invalid parameter: field is NULL.");
580 if (bt_field_type_get_type_id(field
->type
) !=
581 BT_FIELD_TYPE_ID_STRUCT
) {
582 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
583 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
585 bt_field_type_id_string(field
->type
->id
));
589 structure
= container_of(field
, struct bt_field_structure
, parent
);
590 if (index
>= structure
->fields
->len
) {
591 BT_LOGW("Invalid parameter: index is out of bounds: "
592 "addr=%p, index=%" PRIu64
", count=%u",
593 field
, index
, structure
->fields
->len
);
597 ret
= bt_get(structure
->fields
->pdata
[index
]);
602 int bt_field_structure_set_field_by_name(struct bt_field
*field
,
603 const char *name
, struct bt_field
*value
)
607 struct bt_field_structure
*structure
;
608 struct bt_field_type
*expected_field_type
= NULL
;
610 GHashTable
*field_name_to_index
;
613 BT_LOGW_STR("Invalid parameter: structure field is NULL.");
619 BT_LOGW_STR("Invalid parameter: field name is NULL.");
625 BT_LOGW_STR("Invalid parameter: field is NULL.");
630 if (bt_field_type_get_type_id(field
->type
) !=
631 BT_FIELD_TYPE_ID_STRUCT
) {
632 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
633 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
635 bt_field_type_id_string(field
->type
->id
));
640 field_quark
= g_quark_from_string(name
);
641 structure
= container_of(field
, struct bt_field_structure
, parent
);
642 expected_field_type
=
643 bt_field_type_structure_get_field_type_by_name(field
->type
,
646 if (bt_field_type_compare(expected_field_type
, value
->type
)) {
647 BT_LOGW("Invalid parameter: field type of field to set is different from the expected field type: "
648 "struct-field-addr=%p, field-addr=%p, "
649 "field-ft-addr=%p, expected-ft-addr=%p",
650 field
, value
, value
->type
, expected_field_type
);
655 field_name_to_index
=
656 container_of(field
->type
, struct bt_field_type_structure
,
657 parent
)->field_name_to_index
;
658 if (!g_hash_table_lookup_extended(field_name_to_index
,
659 GUINT_TO_POINTER(field_quark
), NULL
,
660 (gpointer
*) &index
)) {
661 BT_LOGV("Invalid parameter: no such field in structure field's type: "
662 "struct-field-addr=%p, struct-ft-addr=%p, "
663 "field-ft-addr=%p, name=\"%s\"",
664 field
, field
->type
, value
->type
, name
);
669 BT_MOVE(structure
->fields
->pdata
[index
], value
);
671 if (expected_field_type
) {
672 bt_put(expected_field_type
);
677 struct bt_field
*bt_field_array_get_field(struct bt_field
*field
,
680 struct bt_field
*new_field
= NULL
;
681 struct bt_field_type
*field_type
= NULL
;
682 struct bt_field_array
*array
;
685 BT_LOGW_STR("Invalid parameter: field is NULL.");
689 if (bt_field_type_get_type_id(field
->type
) !=
690 BT_FIELD_TYPE_ID_ARRAY
) {
691 BT_LOGW("Invalid parameter: field's type is not an array field type: "
692 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
694 bt_field_type_id_string(field
->type
->id
));
698 array
= container_of(field
, struct bt_field_array
, parent
);
699 if (index
>= array
->elements
->len
) {
700 BT_LOGW("Invalid parameter: index is out of bounds: "
701 "addr=%p, index=%" PRIu64
", count=%u",
702 field
, index
, array
->elements
->len
);
706 field_type
= bt_field_type_array_get_element_type(field
->type
);
707 if (array
->elements
->pdata
[(size_t)index
]) {
708 new_field
= array
->elements
->pdata
[(size_t)index
];
712 /* We don't want to modify this field if it's frozen */
715 * Not logging a warning here because the user could
716 * legitimately check if a array field is set with
717 * this function: if the preconditions are satisfied,
718 * a NULL return value means this.
720 BT_LOGV("Not creating a field because array field is frozen: "
721 "array-field-addr=%p, index=%" PRIu64
, field
, index
);
725 new_field
= bt_field_create(field_type
);
726 array
->elements
->pdata
[(size_t)index
] = new_field
;
737 struct bt_field
*bt_field_sequence_get_field(struct bt_field
*field
,
740 struct bt_field
*new_field
= NULL
;
741 struct bt_field_type
*field_type
= NULL
;
742 struct bt_field_sequence
*sequence
;
745 BT_LOGW_STR("Invalid parameter: field is NULL.");
749 if (bt_field_type_get_type_id(field
->type
) !=
750 BT_FIELD_TYPE_ID_SEQUENCE
) {
751 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
752 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
754 bt_field_type_id_string(field
->type
->id
));
758 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
759 if (!sequence
->elements
) {
760 BT_LOGV("Sequence field's elements do not exist: addr=%p",
765 if (index
>= sequence
->elements
->len
) {
766 BT_LOGW("Invalid parameter: index is out of bounds: "
767 "addr=%p, index=%" PRIu64
", count=%u",
768 field
, index
, sequence
->elements
->len
);
772 field_type
= bt_field_type_sequence_get_element_type(field
->type
);
773 if (sequence
->elements
->pdata
[(size_t) index
]) {
774 new_field
= sequence
->elements
->pdata
[(size_t) index
];
778 /* We don't want to modify this field if it's frozen */
781 * Not logging a warning here because the user could
782 * legitimately check if a sequence field is set with
783 * this function: if the preconditions are satisfied,
784 * a NULL return value means this.
786 BT_LOGV("Not creating a field because sequence field is frozen: "
787 "sequence-field-addr=%p, index=%" PRIu64
, field
, index
);
791 new_field
= bt_field_create(field_type
);
792 sequence
->elements
->pdata
[(size_t) index
] = new_field
;
803 struct bt_field
*bt_field_variant_get_field(struct bt_field
*field
,
804 struct bt_field
*tag_field
)
806 struct bt_field
*new_field
= NULL
;
807 struct bt_field_variant
*variant
;
808 struct bt_field_type_variant
*variant_type
;
809 struct bt_field_type
*field_type
;
810 struct bt_field
*tag_enum
= NULL
;
811 struct bt_field_integer
*tag_enum_integer
;
812 int64_t tag_enum_value
;
815 BT_LOGW_STR("Invalid parameter: field is NULL.");
820 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
824 if (bt_field_type_get_type_id(field
->type
) !=
825 BT_FIELD_TYPE_ID_VARIANT
) {
826 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
827 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
829 bt_field_type_id_string(field
->type
->id
));
833 if (bt_field_type_get_type_id(tag_field
->type
) !=
834 BT_FIELD_TYPE_ID_ENUM
) {
835 BT_LOGW("Invalid parameter: tag field's type is not an enumeration field type: "
836 "field-addr=%p, ft-addr=%p, ft-id=%s", tag_field
,
838 bt_field_type_id_string(tag_field
->type
->id
));
842 variant
= container_of(field
, struct bt_field_variant
, parent
);
843 variant_type
= container_of(field
->type
,
844 struct bt_field_type_variant
, parent
);
845 tag_enum
= bt_field_enumeration_get_container(tag_field
);
850 tag_enum_integer
= container_of(tag_enum
, struct bt_field_integer
,
853 if (bt_field_validate(tag_field
) < 0) {
854 BT_LOGW("Invalid parameter: tag field is invalid: "
855 "variant-field-addr=%p, tag-field-addr=%p",
860 tag_enum_value
= tag_enum_integer
->payload
.signd
;
863 * If the variant currently has a tag and a payload, and if the
864 * requested tag value is the same as the current one, return
865 * the current payload instead of creating a fresh one.
867 if (variant
->tag
&& variant
->payload
) {
868 struct bt_field
*cur_tag_container
= NULL
;
869 struct bt_field_integer
*cur_tag_enum_integer
;
870 int64_t cur_tag_value
;
873 bt_field_enumeration_get_container(variant
->tag
);
874 assert(cur_tag_container
);
875 cur_tag_enum_integer
= container_of(cur_tag_container
,
876 struct bt_field_integer
, parent
);
877 bt_put(cur_tag_container
);
878 cur_tag_value
= cur_tag_enum_integer
->payload
.signd
;
880 if (cur_tag_value
== tag_enum_value
) {
881 new_field
= variant
->payload
;
887 /* We don't want to modify this field if it's frozen */
890 * Not logging a warning here because the user could
891 * legitimately check if a variant field is set with
892 * this function: if the preconditions are satisfied,
893 * a NULL return value means this.
895 BT_LOGV("Not creating a field because variant field is frozen: "
896 "variant-field-addr=%p, tag-field-addr=%p",
901 field_type
= bt_field_type_variant_get_field_type_signed(
902 variant_type
, tag_enum_value
);
904 BT_LOGW("Cannot get variant field type's field: "
905 "variant-field-addr=%p, variant-ft-addr=%p, "
906 "tag-value-signed=%" PRId64
,
907 field
, variant_type
, tag_enum_value
);
911 new_field
= bt_field_create(field_type
);
913 BT_LOGW("Cannot create field: "
914 "variant-field-addr=%p, variant-ft-addr=%p, "
915 "field-ft-addr=%p", field
, field
->type
, field_type
);
919 bt_put(variant
->tag
);
920 bt_put(variant
->payload
);
923 variant
->tag
= tag_field
;
924 variant
->payload
= new_field
;
930 struct bt_field
*bt_field_variant_get_current_field(
931 struct bt_field
*variant_field
)
933 struct bt_field
*current_field
= NULL
;
934 struct bt_field_variant
*variant
;
936 if (!variant_field
) {
937 BT_LOGW_STR("Invalid parameter: field is NULL.");
941 if (bt_field_type_get_type_id(variant_field
->type
) !=
942 BT_FIELD_TYPE_ID_VARIANT
) {
943 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
944 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field
,
946 bt_field_type_id_string(variant_field
->type
->id
));
950 variant
= container_of(variant_field
, struct bt_field_variant
,
953 if (variant
->payload
) {
954 current_field
= variant
->payload
;
955 bt_get(current_field
);
960 return current_field
;
963 struct bt_field
*bt_field_variant_get_tag(
964 struct bt_field
*variant_field
)
966 struct bt_field
*tag
= NULL
;
967 struct bt_field_variant
*variant
;
969 if (!variant_field
) {
970 BT_LOGW_STR("Invalid parameter: field is NULL.");
974 if (bt_field_type_get_type_id(variant_field
->type
) !=
975 BT_FIELD_TYPE_ID_VARIANT
) {
976 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
977 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field
,
979 bt_field_type_id_string(variant_field
->type
->id
));
983 variant
= container_of(variant_field
, struct bt_field_variant
,
986 tag
= bt_get(variant
->tag
);
992 struct bt_field
*bt_field_enumeration_get_container(
993 struct bt_field
*field
)
995 struct bt_field
*container
= NULL
;
996 struct bt_field_enumeration
*enumeration
;
999 BT_LOGW_STR("Invalid parameter: field is NULL.");
1003 if (bt_field_type_get_type_id(field
->type
) !=
1004 BT_FIELD_TYPE_ID_ENUM
) {
1005 BT_LOGW("Invalid parameter: field's type is not an enumeration field type: "
1006 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1008 bt_field_type_id_string(field
->type
->id
));
1012 enumeration
= container_of(field
, struct bt_field_enumeration
,
1014 if (!enumeration
->payload
) {
1015 /* We don't want to modify this field if it's frozen */
1016 if (field
->frozen
) {
1018 * Not logging a warning here because the user
1019 * could legitimately check if an enumeration's
1020 * container field is set with this function: if
1021 * the preconditions are satisfied, a NULL
1022 * return value means this.
1024 BT_LOGV("Not creating a field because enumeration field is frozen: "
1025 "enum-field-addr=%p", field
);
1029 struct bt_field_type_enumeration
*enumeration_type
=
1030 container_of(field
->type
,
1031 struct bt_field_type_enumeration
, parent
);
1032 enumeration
->payload
=
1033 bt_field_create(enumeration_type
->container
);
1036 container
= enumeration
->payload
;
1042 struct bt_field_type_enumeration_mapping_iterator
*
1043 bt_field_enumeration_get_mappings(struct bt_field
*field
)
1046 struct bt_field
*container
= NULL
;
1047 struct bt_field_type
*container_type
= NULL
;
1048 struct bt_field_type_integer
*integer_type
= NULL
;
1049 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1051 container
= bt_field_enumeration_get_container(field
);
1053 BT_LOGW("Invalid parameter: enumeration field has no container field: "
1058 container_type
= bt_field_get_type(container
);
1059 assert(container_type
);
1060 integer_type
= container_of(container_type
,
1061 struct bt_field_type_integer
, parent
);
1063 if (!integer_type
->is_signed
) {
1066 ret
= bt_field_unsigned_integer_get_value(container
,
1069 BT_LOGW("Cannot get value from signed enumeration field's payload field: "
1070 "enum-field-addr=%p, payload-field-addr=%p",
1072 goto error_put_container_type
;
1074 iter
= bt_field_type_enumeration_find_mappings_by_unsigned_value(
1075 field
->type
, value
);
1079 ret
= bt_field_signed_integer_get_value(container
,
1082 BT_LOGW("Cannot get value from unsigned enumeration field's payload field: "
1083 "enum-field-addr=%p, payload-field-addr=%p",
1085 goto error_put_container_type
;
1087 iter
= bt_field_type_enumeration_find_mappings_by_signed_value(
1088 field
->type
, value
);
1091 error_put_container_type
:
1092 bt_put(container_type
);
1098 int bt_field_signed_integer_get_value(struct bt_field
*field
,
1102 struct bt_field_integer
*integer
;
1103 struct bt_field_type_integer
*integer_type
;
1106 BT_LOGW_STR("Invalid parameter: field is NULL.");
1112 BT_LOGW_STR("Invalid parameter: value is NULL.");
1117 if (!field
->payload_set
) {
1118 BT_LOGV("Field's payload is not set: addr=%p", field
);
1123 if (bt_field_type_get_type_id(field
->type
) !=
1124 BT_FIELD_TYPE_ID_INTEGER
) {
1125 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1126 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1128 bt_field_type_id_string(field
->type
->id
));
1133 integer_type
= container_of(field
->type
,
1134 struct bt_field_type_integer
, parent
);
1135 if (!integer_type
->is_signed
) {
1136 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1137 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1142 integer
= container_of(field
,
1143 struct bt_field_integer
, parent
);
1144 *value
= integer
->payload
.signd
;
1149 int bt_field_signed_integer_set_value(struct bt_field
*field
,
1153 struct bt_field_integer
*integer
;
1154 struct bt_field_type_integer
*integer_type
;
1156 int64_t min_value
, max_value
;
1159 BT_LOGW_STR("Invalid parameter: field is NULL.");
1164 if (field
->frozen
) {
1165 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1171 if (bt_field_type_get_type_id(field
->type
) !=
1172 BT_FIELD_TYPE_ID_INTEGER
) {
1173 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1174 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1176 bt_field_type_id_string(field
->type
->id
));
1181 integer
= container_of(field
, struct bt_field_integer
, parent
);
1182 integer_type
= container_of(field
->type
,
1183 struct bt_field_type_integer
, parent
);
1184 if (!integer_type
->is_signed
) {
1185 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1186 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1191 size
= integer_type
->size
;
1192 min_value
= -(1ULL << (size
- 1));
1193 max_value
= (1ULL << (size
- 1)) - 1;
1194 if (value
< min_value
|| value
> max_value
) {
1195 BT_LOGW("Invalid parameter: value is out of bounds: "
1196 "addr=%p, value=%" PRId64
", "
1197 "min-value=%" PRId64
", max-value=%" PRId64
,
1198 field
, value
, min_value
, max_value
);
1203 integer
->payload
.signd
= value
;
1204 integer
->parent
.payload_set
= true;
1209 int bt_field_unsigned_integer_get_value(struct bt_field
*field
,
1213 struct bt_field_integer
*integer
;
1214 struct bt_field_type_integer
*integer_type
;
1217 BT_LOGW_STR("Invalid parameter: field is NULL.");
1223 BT_LOGW_STR("Invalid parameter: value is NULL.");
1228 if (!field
->payload_set
) {
1229 BT_LOGV("Field's payload is not set: addr=%p", field
);
1234 if (bt_field_type_get_type_id(field
->type
) !=
1235 BT_FIELD_TYPE_ID_INTEGER
) {
1236 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1237 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1239 bt_field_type_id_string(field
->type
->id
));
1244 integer_type
= container_of(field
->type
,
1245 struct bt_field_type_integer
, parent
);
1246 if (integer_type
->is_signed
) {
1247 BT_LOGW("Invalid parameter: integer field's type is signed: "
1248 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1253 integer
= container_of(field
,
1254 struct bt_field_integer
, parent
);
1255 *value
= integer
->payload
.unsignd
;
1260 int bt_field_unsigned_integer_set_value(struct bt_field
*field
,
1264 struct bt_field_integer
*integer
;
1265 struct bt_field_type_integer
*integer_type
;
1270 BT_LOGW_STR("Invalid parameter: field is NULL.");
1275 if (field
->frozen
) {
1276 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1282 if (bt_field_type_get_type_id(field
->type
) !=
1283 BT_FIELD_TYPE_ID_INTEGER
) {
1284 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1285 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1287 bt_field_type_id_string(field
->type
->id
));
1292 integer
= container_of(field
, struct bt_field_integer
, parent
);
1293 integer_type
= container_of(field
->type
,
1294 struct bt_field_type_integer
, parent
);
1295 if (integer_type
->is_signed
) {
1296 BT_LOGW("Invalid parameter: integer field's type is signed: "
1297 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1302 size
= integer_type
->size
;
1303 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t) 1 << size
) - 1;
1304 if (value
> max_value
) {
1305 BT_LOGW("Invalid parameter: value is out of bounds: "
1306 "addr=%p, value=%" PRIu64
", "
1307 "min-value=%" PRIu64
", max-value=%" PRIu64
,
1308 field
, value
, (uint64_t) 0, max_value
);
1313 integer
->payload
.unsignd
= value
;
1314 integer
->parent
.payload_set
= true;
1319 int bt_field_floating_point_get_value(struct bt_field
*field
,
1323 struct bt_field_floating_point
*floating_point
;
1326 BT_LOGW_STR("Invalid parameter: field is NULL.");
1332 BT_LOGW_STR("Invalid parameter: value is NULL.");
1337 if (!field
->payload_set
) {
1338 BT_LOGV("Field's payload is not set: addr=%p", field
);
1343 if (bt_field_type_get_type_id(field
->type
) !=
1344 BT_FIELD_TYPE_ID_FLOAT
) {
1345 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1346 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1348 bt_field_type_id_string(field
->type
->id
));
1353 floating_point
= container_of(field
,
1354 struct bt_field_floating_point
, parent
);
1355 *value
= floating_point
->payload
;
1360 int bt_field_floating_point_set_value(struct bt_field
*field
,
1364 struct bt_field_floating_point
*floating_point
;
1367 BT_LOGW_STR("Invalid parameter: field is NULL.");
1372 if (field
->frozen
) {
1373 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1379 if (bt_field_type_get_type_id(field
->type
) !=
1380 BT_FIELD_TYPE_ID_FLOAT
) {
1381 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1382 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1384 bt_field_type_id_string(field
->type
->id
));
1389 floating_point
= container_of(field
, struct bt_field_floating_point
,
1391 floating_point
->payload
= value
;
1392 floating_point
->parent
.payload_set
= true;
1397 const char *bt_field_string_get_value(struct bt_field
*field
)
1399 const char *ret
= NULL
;
1400 struct bt_field_string
*string
;
1403 BT_LOGW_STR("Invalid parameter: field is NULL.");
1407 if (!field
->payload_set
) {
1408 BT_LOGV("Field's payload is not set: addr=%p", field
);
1412 if (bt_field_type_get_type_id(field
->type
) !=
1413 BT_FIELD_TYPE_ID_STRING
) {
1414 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1415 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1417 bt_field_type_id_string(field
->type
->id
));
1421 string
= container_of(field
,
1422 struct bt_field_string
, parent
);
1423 ret
= string
->payload
->str
;
1428 int bt_field_string_set_value(struct bt_field
*field
,
1432 struct bt_field_string
*string
;
1435 BT_LOGW_STR("Invalid parameter: field is NULL.");
1441 BT_LOGW_STR("Invalid parameter: value is NULL.");
1446 if (field
->frozen
) {
1447 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1453 if (bt_field_type_get_type_id(field
->type
) !=
1454 BT_FIELD_TYPE_ID_STRING
) {
1455 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1456 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1458 bt_field_type_id_string(field
->type
->id
));
1463 string
= container_of(field
, struct bt_field_string
, parent
);
1464 if (string
->payload
) {
1465 g_string_assign(string
->payload
, value
);
1467 string
->payload
= g_string_new(value
);
1470 string
->parent
.payload_set
= true;
1475 int bt_field_string_append(struct bt_field
*field
,
1479 struct bt_field_string
*string_field
;
1482 BT_LOGW_STR("Invalid parameter: field is NULL.");
1488 BT_LOGW_STR("Invalid parameter: value is NULL.");
1493 if (field
->frozen
) {
1494 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1500 if (bt_field_type_get_type_id(field
->type
) !=
1501 BT_FIELD_TYPE_ID_STRING
) {
1502 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1503 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1505 bt_field_type_id_string(field
->type
->id
));
1510 string_field
= container_of(field
, struct bt_field_string
, parent
);
1512 if (string_field
->payload
) {
1513 g_string_append(string_field
->payload
, value
);
1515 string_field
->payload
= g_string_new(value
);
1518 string_field
->parent
.payload_set
= true;
1524 int bt_field_string_append_len(struct bt_field
*field
,
1525 const char *value
, unsigned int length
)
1529 unsigned int effective_length
= length
;
1530 struct bt_field_string
*string_field
;
1533 BT_LOGW_STR("Invalid parameter: field is NULL.");
1539 BT_LOGW_STR("Invalid parameter: value is NULL.");
1544 if (field
->frozen
) {
1545 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1551 if (bt_field_type_get_type_id(field
->type
) !=
1552 BT_FIELD_TYPE_ID_STRING
) {
1553 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1554 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1556 bt_field_type_id_string(field
->type
->id
));
1561 string_field
= container_of(field
, struct bt_field_string
, parent
);
1563 /* make sure no null bytes are appended */
1564 for (i
= 0; i
< length
; ++i
) {
1565 if (value
[i
] == '\0') {
1566 effective_length
= i
;
1571 if (string_field
->payload
) {
1572 g_string_append_len(string_field
->payload
, value
,
1575 string_field
->payload
= g_string_new_len(value
,
1579 string_field
->parent
.payload_set
= true;
1586 int bt_field_validate(struct bt_field
*field
)
1589 enum bt_field_type_id type_id
;
1592 BT_LOGD_STR("Invalid parameter: field is NULL.");
1597 type_id
= bt_field_type_get_type_id(field
->type
);
1598 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1599 BT_LOGW("Invalid parameter: unknown field type ID: "
1600 "addr=%p, ft-addr=%p, ft-id=%d",
1601 field
, field
->type
, type_id
);
1606 ret
= field_validate_funcs
[type_id
](field
);
1611 int bt_field_reset(struct bt_field
*field
)
1614 enum bt_field_type_id type_id
;
1617 BT_LOGD_STR("Invalid parameter: field is NULL.");
1622 if (field
->frozen
) {
1623 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1629 type_id
= bt_field_type_get_type_id(field
->type
);
1630 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1631 BT_LOGW("Invalid parameter: unknown field type ID: "
1632 "addr=%p, ft-addr=%p, ft-id=%d",
1633 field
, field
->type
, type_id
);
1638 ret
= field_reset_funcs
[type_id
](field
);
1644 int bt_field_serialize(struct bt_field
*field
,
1645 struct bt_stream_pos
*pos
,
1646 enum bt_byte_order native_byte_order
)
1649 enum bt_field_type_id type_id
;
1654 BT_LOGD_STR("Invalid parameter: field is NULL.");
1659 type_id
= bt_field_type_get_type_id(field
->type
);
1660 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1661 BT_LOGW("Invalid parameter: unknown field type ID: "
1662 "addr=%p, ft-addr=%p, ft-id=%d",
1663 field
, field
->type
, type_id
);
1668 ret
= field_serialize_funcs
[type_id
](field
, pos
, native_byte_order
);
1673 bt_bool
bt_field_is_set(struct bt_field
*field
)
1675 bt_bool is_set
= BT_FALSE
;
1676 enum bt_field_type_id type_id
;
1682 type_id
= bt_field_type_get_type_id(field
->type
);
1683 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1684 BT_LOGW("Invalid parameter: unknown field type ID: "
1685 "field-addr=%p, ft-addr=%p, ft-id=%d",
1686 field
, field
->type
, type_id
);
1690 is_set
= field_is_set_funcs
[type_id
](field
);
1695 struct bt_field
*bt_field_copy(struct bt_field
*field
)
1698 struct bt_field
*copy
= NULL
;
1699 enum bt_field_type_id type_id
;
1702 BT_LOGW_STR("Invalid parameter: field is NULL.");
1706 type_id
= bt_field_type_get_type_id(field
->type
);
1707 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1708 BT_LOGW("Invalid parameter: unknown field type ID: "
1709 "field-addr=%p, ft-addr=%p, ft-id=%d",
1710 field
, field
->type
, type_id
);
1714 copy
= bt_field_create(field
->type
);
1716 BT_LOGW("Cannot create field: ft-addr=%p", field
->type
);
1720 copy
->payload_set
= field
->payload_set
;
1721 ret
= field_copy_funcs
[type_id
](field
, copy
);
1731 struct bt_field
*bt_field_integer_create(struct bt_field_type
*type
)
1733 struct bt_field_integer
*integer
= g_new0(
1734 struct bt_field_integer
, 1);
1736 BT_LOGD("Creating integer field object: ft-addr=%p", type
);
1739 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
1740 &integer
->parent
, type
);
1742 BT_LOGE_STR("Failed to allocate one integer field.");
1745 return integer
? &integer
->parent
: NULL
;
1749 struct bt_field
*bt_field_enumeration_create(
1750 struct bt_field_type
*type
)
1752 struct bt_field_enumeration
*enumeration
= g_new0(
1753 struct bt_field_enumeration
, 1);
1755 BT_LOGD("Creating enumeration field object: ft-addr=%p", type
);
1758 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
1759 &enumeration
->parent
, type
);
1761 BT_LOGE_STR("Failed to allocate one enumeration field.");
1764 return enumeration
? &enumeration
->parent
: NULL
;
1768 struct bt_field
*bt_field_floating_point_create(
1769 struct bt_field_type
*type
)
1771 struct bt_field_floating_point
*floating_point
;
1773 BT_LOGD("Creating floating point number field object: ft-addr=%p", type
);
1774 floating_point
= g_new0(struct bt_field_floating_point
, 1);
1776 if (floating_point
) {
1777 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
1778 &floating_point
->parent
, type
);
1780 BT_LOGE_STR("Failed to allocate one floating point number field.");
1783 return floating_point
? &floating_point
->parent
: NULL
;
1787 struct bt_field
*bt_field_structure_create(
1788 struct bt_field_type
*type
)
1790 struct bt_field_type_structure
*structure_type
= container_of(type
,
1791 struct bt_field_type_structure
, parent
);
1792 struct bt_field_structure
*structure
= g_new0(
1793 struct bt_field_structure
, 1);
1794 struct bt_field
*ret
= NULL
;
1797 BT_LOGD("Creating structure field object: ft-addr=%p", type
);
1800 BT_LOGE_STR("Failed to allocate one structure field.");
1804 structure
->fields
= g_ptr_array_new_with_free_func(
1805 (GDestroyNotify
) bt_put
);
1806 g_ptr_array_set_size(structure
->fields
,
1807 structure_type
->fields
->len
);
1809 /* Create all fields contained by the structure field. */
1810 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
1811 struct bt_field
*field
;
1812 struct structure_field
*field_type
=
1813 g_ptr_array_index(structure_type
->fields
, i
);
1815 field
= bt_field_create(field_type
->type
);
1817 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
1818 g_quark_to_string(field_type
->name
), i
);
1819 bt_field_structure_destroy(&structure
->parent
);
1823 g_ptr_array_index(structure
->fields
, i
) = field
;
1826 ret
= &structure
->parent
;
1827 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p", ret
,
1834 struct bt_field
*bt_field_variant_create(struct bt_field_type
*type
)
1836 struct bt_field_variant
*variant
= g_new0(
1837 struct bt_field_variant
, 1);
1839 BT_LOGD("Creating variant field object: ft-addr=%p", type
);
1842 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1843 &variant
->parent
, type
);
1845 BT_LOGE_STR("Failed to allocate one variant field.");
1848 return variant
? &variant
->parent
: NULL
;
1852 struct bt_field
*bt_field_array_create(struct bt_field_type
*type
)
1854 struct bt_field_array
*array
= g_new0(struct bt_field_array
, 1);
1855 struct bt_field_type_array
*array_type
;
1856 unsigned int array_length
;
1858 BT_LOGD("Creating array field object: ft-addr=%p", type
);
1862 BT_LOGE_STR("Failed to allocate one array field.");
1866 array_type
= container_of(type
, struct bt_field_type_array
, parent
);
1867 array_length
= array_type
->length
;
1868 array
->elements
= g_ptr_array_sized_new(array_length
);
1869 if (!array
->elements
) {
1873 g_ptr_array_set_free_func(array
->elements
,
1874 (GDestroyNotify
) bt_put
);
1875 g_ptr_array_set_size(array
->elements
, array_length
);
1876 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1877 &array
->parent
, type
);
1878 return &array
->parent
;
1885 struct bt_field
*bt_field_sequence_create(
1886 struct bt_field_type
*type
)
1888 struct bt_field_sequence
*sequence
= g_new0(
1889 struct bt_field_sequence
, 1);
1891 BT_LOGD("Creating sequence field object: ft-addr=%p", type
);
1894 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1895 &sequence
->parent
, type
);
1897 BT_LOGE_STR("Failed to allocate one sequence field.");
1900 return sequence
? &sequence
->parent
: NULL
;
1904 struct bt_field
*bt_field_string_create(struct bt_field_type
*type
)
1906 struct bt_field_string
*string
= g_new0(
1907 struct bt_field_string
, 1);
1909 BT_LOGD("Creating string field object: ft-addr=%p", type
);
1912 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1913 &string
->parent
, type
);
1915 BT_LOGE_STR("Failed to allocate one string field.");
1918 return string
? &string
->parent
: NULL
;
1922 void bt_field_destroy(struct bt_object
*obj
)
1924 struct bt_field
*field
;
1925 struct bt_field_type
*type
;
1926 enum bt_field_type_id type_id
;
1928 field
= container_of(obj
, struct bt_field
, base
);
1930 type_id
= bt_field_type_get_type_id(type
);
1931 assert(type_id
> BT_FIELD_TYPE_ID_UNKNOWN
&&
1932 type_id
< BT_FIELD_TYPE_ID_NR
);
1933 field_destroy_funcs
[type_id
](field
);
1934 BT_LOGD_STR("Putting field's type.");
1939 void bt_field_integer_destroy(struct bt_field
*field
)
1941 struct bt_field_integer
*integer
;
1947 BT_LOGD("Destroying integer field object: addr=%p", field
);
1948 integer
= container_of(field
, struct bt_field_integer
, parent
);
1953 void bt_field_enumeration_destroy(struct bt_field
*field
)
1955 struct bt_field_enumeration
*enumeration
;
1961 BT_LOGD("Destroying enumeration field object: addr=%p", field
);
1962 enumeration
= container_of(field
, struct bt_field_enumeration
,
1964 BT_LOGD_STR("Putting payload field.");
1965 bt_put(enumeration
->payload
);
1966 g_free(enumeration
);
1970 void bt_field_floating_point_destroy(struct bt_field
*field
)
1972 struct bt_field_floating_point
*floating_point
;
1978 BT_LOGD("Destroying floating point number field object: addr=%p", field
);
1979 floating_point
= container_of(field
, struct bt_field_floating_point
,
1981 g_free(floating_point
);
1985 void bt_field_structure_destroy(struct bt_field
*field
)
1987 struct bt_field_structure
*structure
;
1993 BT_LOGD("Destroying structure field object: addr=%p", field
);
1994 structure
= container_of(field
, struct bt_field_structure
, parent
);
1995 g_ptr_array_free(structure
->fields
, TRUE
);
2000 void bt_field_variant_destroy(struct bt_field
*field
)
2002 struct bt_field_variant
*variant
;
2008 BT_LOGD("Destroying variant field object: addr=%p", field
);
2009 variant
= container_of(field
, struct bt_field_variant
, parent
);
2010 BT_LOGD_STR("Putting tag field.");
2011 bt_put(variant
->tag
);
2012 BT_LOGD_STR("Putting payload field.");
2013 bt_put(variant
->payload
);
2018 void bt_field_array_destroy(struct bt_field
*field
)
2020 struct bt_field_array
*array
;
2026 BT_LOGD("Destroying array field object: addr=%p", field
);
2027 array
= container_of(field
, struct bt_field_array
, parent
);
2028 g_ptr_array_free(array
->elements
, TRUE
);
2033 void bt_field_sequence_destroy(struct bt_field
*field
)
2035 struct bt_field_sequence
*sequence
;
2041 BT_LOGD("Destroying sequence field object: addr=%p", field
);
2042 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2043 if (sequence
->elements
) {
2044 g_ptr_array_free(sequence
->elements
, TRUE
);
2046 BT_LOGD_STR("Putting length field.");
2047 bt_put(sequence
->length
);
2052 void bt_field_string_destroy(struct bt_field
*field
)
2054 struct bt_field_string
*string
;
2060 BT_LOGD("Destroying string field object: addr=%p", field
);
2061 string
= container_of(field
, struct bt_field_string
, parent
);
2062 if (string
->payload
) {
2063 g_string_free(string
->payload
, TRUE
);
2069 int bt_field_generic_validate(struct bt_field
*field
)
2071 return (field
&& field
->payload_set
) ? 0 : -1;
2075 int bt_field_enumeration_validate(struct bt_field
*field
)
2078 struct bt_field_enumeration
*enumeration
;
2081 BT_LOGD_STR("Invalid parameter: field is NULL.");
2086 enumeration
= container_of(field
, struct bt_field_enumeration
,
2088 if (!enumeration
->payload
) {
2089 BT_LOGW("Invalid enumeration field: payload is not set: "
2095 ret
= bt_field_validate(enumeration
->payload
);
2101 int bt_field_structure_validate(struct bt_field
*field
)
2105 struct bt_field_structure
*structure
;
2108 BT_LOGD_STR("Invalid parameter: field is NULL.");
2113 structure
= container_of(field
, struct bt_field_structure
, parent
);
2114 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2115 struct bt_field
*entry_field
= structure
->fields
->pdata
[i
];
2116 ret
= bt_field_validate(entry_field
);
2121 struct bt_field_type
*field_type
=
2122 bt_field_get_type(field
);
2124 this_ret
= bt_field_type_structure_get_field_by_index(
2125 field_type
, &name
, NULL
, i
);
2126 assert(this_ret
== 0);
2127 BT_LOGW("Invalid structure field's field: "
2128 "struct-field-addr=%p, field-addr=%p, "
2129 "field-name=\"%s\", index=%" PRId64
,
2130 field
, entry_field
, name
, i
);
2140 int bt_field_variant_validate(struct bt_field
*field
)
2143 struct bt_field_variant
*variant
;
2146 BT_LOGD_STR("Invalid parameter: field is NULL.");
2151 variant
= container_of(field
, struct bt_field_variant
, parent
);
2152 ret
= bt_field_validate(variant
->payload
);
2154 BT_LOGW("Invalid variant field's payload field: "
2155 "variant-field-addr=%p, variant-payload-field-addr=%p",
2156 field
, variant
->payload
);
2163 int bt_field_array_validate(struct bt_field
*field
)
2167 struct bt_field_array
*array
;
2170 BT_LOGD_STR("Invalid parameter: field is NULL.");
2175 array
= container_of(field
, struct bt_field_array
, parent
);
2176 for (i
= 0; i
< array
->elements
->len
; i
++) {
2177 struct bt_field
*elem_field
= array
->elements
->pdata
[i
];
2179 ret
= bt_field_validate(elem_field
);
2181 BT_LOGW("Invalid array field's element field: "
2182 "array-field-addr=%p, field-addr=%p, "
2183 "index=%" PRId64
, field
, elem_field
, i
);
2192 int bt_field_sequence_validate(struct bt_field
*field
)
2196 struct bt_field_sequence
*sequence
;
2199 BT_LOGD_STR("Invalid parameter: field is NULL.");
2204 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2205 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
2206 struct bt_field
*elem_field
= sequence
->elements
->pdata
[i
];
2208 ret
= bt_field_validate(elem_field
);
2210 BT_LOGW("Invalid sequence field's element field: "
2211 "sequence-field-addr=%p, field-addr=%p, "
2212 "index=%zu", field
, elem_field
, i
);
2221 int bt_field_generic_reset(struct bt_field
*field
)
2226 BT_LOGD_STR("Invalid parameter: field is NULL.");
2231 field
->payload_set
= false;
2237 int bt_field_enumeration_reset(struct bt_field
*field
)
2240 struct bt_field_enumeration
*enumeration
;
2243 BT_LOGD_STR("Invalid parameter: field is NULL.");
2248 enumeration
= container_of(field
, struct bt_field_enumeration
,
2250 if (!enumeration
->payload
) {
2254 ret
= bt_field_reset(enumeration
->payload
);
2260 int bt_field_structure_reset(struct bt_field
*field
)
2264 struct bt_field_structure
*structure
;
2267 BT_LOGD_STR("Invalid parameter: field is NULL.");
2272 structure
= container_of(field
, struct bt_field_structure
, parent
);
2273 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2274 struct bt_field
*member
= structure
->fields
->pdata
[i
];
2278 * Structure members are lazily initialized; skip if
2279 * this member has not been allocated yet.
2284 ret
= bt_field_reset(member
);
2286 BT_LOGE("Failed to reset structure field's field: "
2287 "struct-field-addr=%p, field-addr=%p, "
2288 "index=%" PRId64
, field
, member
, i
);
2297 int bt_field_variant_reset(struct bt_field
*field
)
2300 struct bt_field_variant
*variant
;
2303 BT_LOGD_STR("Invalid parameter: field is NULL.");
2308 variant
= container_of(field
, struct bt_field_variant
, parent
);
2309 BT_PUT(variant
->tag
);
2310 BT_PUT(variant
->payload
);
2316 int bt_field_array_reset(struct bt_field
*field
)
2320 struct bt_field_array
*array
;
2323 BT_LOGD_STR("Invalid parameter: field is NULL.");
2328 array
= container_of(field
, struct bt_field_array
, parent
);
2329 for (i
= 0; i
< array
->elements
->len
; i
++) {
2330 struct bt_field
*member
= array
->elements
->pdata
[i
];
2334 * Array elements are lazily initialized; skip if
2335 * this member has not been allocated yet.
2340 ret
= bt_field_reset(member
);
2342 BT_LOGE("Failed to reset array field's field: "
2343 "array-field-addr=%p, field-addr=%p, "
2344 "index=%zu", field
, member
, i
);
2353 int bt_field_sequence_reset(struct bt_field
*field
)
2356 struct bt_field_sequence
*sequence
;
2359 BT_LOGD_STR("Invalid parameter: field is NULL.");
2364 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2365 if (sequence
->elements
) {
2366 g_ptr_array_free(sequence
->elements
, TRUE
);
2367 sequence
->elements
= NULL
;
2369 BT_PUT(sequence
->length
);
2375 int bt_field_string_reset(struct bt_field
*field
)
2378 struct bt_field_string
*string
;
2381 BT_LOGD_STR("Invalid parameter: field is NULL.");
2386 ret
= bt_field_generic_reset(field
);
2391 string
= container_of(field
, struct bt_field_string
, parent
);
2392 if (string
->payload
) {
2393 g_string_truncate(string
->payload
, 0);
2400 int bt_field_integer_serialize(struct bt_field
*field
,
2401 struct bt_stream_pos
*pos
,
2402 enum bt_byte_order native_byte_order
)
2405 struct bt_field_integer
*integer
= container_of(field
,
2406 struct bt_field_integer
, parent
);
2408 BT_LOGV("Serializing integer field: addr=%p, pos-offset=%" PRId64
", "
2409 "native-bo=%s", field
, pos
->offset
,
2410 bt_byte_order_string(native_byte_order
));
2412 if (!bt_field_generic_is_set(field
)) {
2413 BT_LOGW_STR("Field's payload is not set.");
2418 ret
= bt_field_integer_write(integer
, pos
, native_byte_order
);
2419 if (ret
== -EFAULT
) {
2421 * The field is too large to fit in the current packet's
2422 * remaining space. Bump the packet size and retry.
2424 ret
= increase_packet_size(pos
);
2426 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
2436 int bt_field_enumeration_serialize(struct bt_field
*field
,
2437 struct bt_stream_pos
*pos
,
2438 enum bt_byte_order native_byte_order
)
2440 struct bt_field_enumeration
*enumeration
= container_of(
2441 field
, struct bt_field_enumeration
, parent
);
2443 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64
", "
2444 "native-bo=%s", field
, pos
->offset
,
2445 bt_byte_order_string(native_byte_order
));
2446 BT_LOGV_STR("Serializing enumeration field's payload field.");
2447 return bt_field_serialize(enumeration
->payload
, pos
,
2452 int bt_field_floating_point_serialize(struct bt_field
*field
,
2453 struct bt_stream_pos
*pos
,
2454 enum bt_byte_order native_byte_order
)
2457 struct bt_field_floating_point
*floating_point
= container_of(field
,
2458 struct bt_field_floating_point
, parent
);
2460 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64
", "
2461 "native-bo=%s", field
, pos
->offset
,
2462 bt_byte_order_string(native_byte_order
));
2464 if (!bt_field_generic_is_set(field
)) {
2465 BT_LOGW_STR("Field's payload is not set.");
2470 ret
= bt_field_floating_point_write(floating_point
, pos
,
2472 if (ret
== -EFAULT
) {
2474 * The field is too large to fit in the current packet's
2475 * remaining space. Bump the packet size and retry.
2477 ret
= increase_packet_size(pos
);
2479 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
2489 int bt_field_structure_serialize(struct bt_field
*field
,
2490 struct bt_stream_pos
*pos
,
2491 enum bt_byte_order native_byte_order
)
2495 struct bt_field_structure
*structure
= container_of(
2496 field
, struct bt_field_structure
, parent
);
2498 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64
", "
2499 "native-bo=%s", field
, pos
->offset
,
2500 bt_byte_order_string(native_byte_order
));
2502 while (!bt_stream_pos_access_ok(pos
,
2503 offset_align(pos
->offset
, field
->type
->alignment
))) {
2504 ret
= increase_packet_size(pos
);
2506 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
2511 if (!bt_stream_pos_align(pos
, field
->type
->alignment
)) {
2512 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64
", "
2513 "align=%u", pos
->offset
, field
->type
->alignment
);
2518 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2519 struct bt_field
*member
= g_ptr_array_index(
2520 structure
->fields
, i
);
2521 const char *field_name
= NULL
;
2523 if (BT_LOG_ON_WARN
) {
2524 ret
= bt_field_type_structure_get_field_by_index(
2525 field
->type
, &field_name
, NULL
, i
);
2529 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64
", "
2530 "field-addr=%p, index=%" PRId64
,
2531 pos
->offset
, member
, i
);
2534 BT_LOGW("Cannot serialize structure field's field: field is not set: "
2535 "struct-field-addr=%p, "
2536 "field-name=\"%s\", index=%" PRId64
,
2537 field
, field_name
, i
);
2542 ret
= bt_field_serialize(member
, pos
, native_byte_order
);
2544 BT_LOGW("Cannot serialize structure field's field: "
2545 "struct-field-addr=%p, field-addr=%p, "
2546 "field-name=\"%s\", index=%" PRId64
,
2547 field
->type
, member
, field_name
, i
);
2556 int bt_field_variant_serialize(struct bt_field
*field
,
2557 struct bt_stream_pos
*pos
,
2558 enum bt_byte_order native_byte_order
)
2560 struct bt_field_variant
*variant
= container_of(
2561 field
, struct bt_field_variant
, parent
);
2563 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64
", "
2564 "native-bo=%s", field
, pos
->offset
,
2565 bt_byte_order_string(native_byte_order
));
2566 BT_LOGV_STR("Serializing variant field's payload field.");
2567 return bt_field_serialize(variant
->payload
, pos
,
2572 int bt_field_array_serialize(struct bt_field
*field
,
2573 struct bt_stream_pos
*pos
,
2574 enum bt_byte_order native_byte_order
)
2578 struct bt_field_array
*array
= container_of(
2579 field
, struct bt_field_array
, parent
);
2581 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64
", "
2582 "native-bo=%s", field
, pos
->offset
,
2583 bt_byte_order_string(native_byte_order
));
2585 for (i
= 0; i
< array
->elements
->len
; i
++) {
2586 struct bt_field
*elem_field
=
2587 g_ptr_array_index(array
->elements
, i
);
2589 BT_LOGV("Serializing array field's element field: "
2590 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
2591 pos
->offset
, elem_field
, i
);
2592 ret
= bt_field_serialize(elem_field
, pos
,
2595 BT_LOGW("Cannot serialize array field's element field: "
2596 "array-field-addr=%p, field-addr=%p, "
2597 "index=%" PRId64
, field
, elem_field
, i
);
2606 int bt_field_sequence_serialize(struct bt_field
*field
,
2607 struct bt_stream_pos
*pos
,
2608 enum bt_byte_order native_byte_order
)
2612 struct bt_field_sequence
*sequence
= container_of(
2613 field
, struct bt_field_sequence
, parent
);
2615 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64
", "
2616 "native-bo=%s", field
, pos
->offset
,
2617 bt_byte_order_string(native_byte_order
));
2619 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
2620 struct bt_field
*elem_field
=
2621 g_ptr_array_index(sequence
->elements
, i
);
2623 BT_LOGV("Serializing sequence field's element field: "
2624 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
2625 pos
->offset
, elem_field
, i
);
2626 ret
= bt_field_serialize(elem_field
, pos
,
2629 BT_LOGW("Cannot serialize sequence field's element field: "
2630 "sequence-field-addr=%p, field-addr=%p, "
2631 "index=%" PRId64
, field
, elem_field
, i
);
2640 int bt_field_string_serialize(struct bt_field
*field
,
2641 struct bt_stream_pos
*pos
,
2642 enum bt_byte_order native_byte_order
)
2646 struct bt_field_string
*string
= container_of(field
,
2647 struct bt_field_string
, parent
);
2648 struct bt_field_type
*character_type
=
2649 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
2650 struct bt_field
*character
;
2652 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64
", "
2653 "native-bo=%s", field
, pos
->offset
,
2654 bt_byte_order_string(native_byte_order
));
2656 BT_LOGV_STR("Creating character field from string field's character field type.");
2657 character
= bt_field_create(character_type
);
2659 for (i
= 0; i
< string
->payload
->len
+ 1; i
++) {
2660 const uint64_t chr
= (uint64_t) string
->payload
->str
[i
];
2662 ret
= bt_field_unsigned_integer_set_value(character
, chr
);
2664 BT_LOGW("Cannot set character field's value: "
2665 "pos-offset=%" PRId64
", field-addr=%p, "
2666 "index=%" PRId64
", char-int=%" PRIu64
,
2667 pos
->offset
, character
, i
, chr
);
2671 BT_LOGV("Serializing string field's character field: "
2672 "pos-offset=%" PRId64
", field-addr=%p, "
2673 "index=%" PRId64
", char-int=%" PRIu64
,
2674 pos
->offset
, character
, i
, chr
);
2675 ret
= bt_field_integer_serialize(character
, pos
,
2678 BT_LOGW_STR("Cannot serialize character field.");
2684 bt_put(character_type
);
2689 int bt_field_integer_copy(struct bt_field
*src
,
2690 struct bt_field
*dst
)
2692 struct bt_field_integer
*integer_src
, *integer_dst
;
2694 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
2696 integer_src
= container_of(src
, struct bt_field_integer
, parent
);
2697 integer_dst
= container_of(dst
, struct bt_field_integer
, parent
);
2698 integer_dst
->payload
= integer_src
->payload
;
2699 BT_LOGD_STR("Copied integer field.");
2704 int bt_field_enumeration_copy(struct bt_field
*src
,
2705 struct bt_field
*dst
)
2708 struct bt_field_enumeration
*enum_src
, *enum_dst
;
2710 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
2712 enum_src
= container_of(src
, struct bt_field_enumeration
, parent
);
2713 enum_dst
= container_of(dst
, struct bt_field_enumeration
, parent
);
2715 if (enum_src
->payload
) {
2716 BT_LOGD_STR("Copying enumeration field's payload field.");
2717 enum_dst
->payload
= bt_field_copy(enum_src
->payload
);
2718 if (!enum_dst
->payload
) {
2719 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
2725 BT_LOGD_STR("Copied enumeration field.");
2731 int bt_field_floating_point_copy(
2732 struct bt_field
*src
, struct bt_field
*dst
)
2734 struct bt_field_floating_point
*float_src
, *float_dst
;
2736 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2738 float_src
= container_of(src
, struct bt_field_floating_point
,
2740 float_dst
= container_of(dst
, struct bt_field_floating_point
,
2742 float_dst
->payload
= float_src
->payload
;
2743 BT_LOGD_STR("Copied floating point number field.");
2748 int bt_field_structure_copy(struct bt_field
*src
,
2749 struct bt_field
*dst
)
2753 struct bt_field_structure
*struct_src
, *struct_dst
;
2755 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2757 struct_src
= container_of(src
, struct bt_field_structure
, parent
);
2758 struct_dst
= container_of(dst
, struct bt_field_structure
, parent
);
2760 g_ptr_array_set_size(struct_dst
->fields
, struct_src
->fields
->len
);
2762 for (i
= 0; i
< struct_src
->fields
->len
; i
++) {
2763 struct bt_field
*field
=
2764 g_ptr_array_index(struct_src
->fields
, i
);
2765 struct bt_field
*field_copy
= NULL
;
2768 BT_LOGD("Copying structure field's field: src-field-addr=%p"
2769 "index=%" PRId64
, field
, i
);
2770 field_copy
= bt_field_copy(field
);
2772 BT_LOGE("Cannot copy structure field's field: "
2773 "src-field-addr=%p, index=%" PRId64
,
2780 BT_MOVE(g_ptr_array_index(struct_dst
->fields
, i
), field_copy
);
2783 BT_LOGD_STR("Copied structure field.");
2790 int bt_field_variant_copy(struct bt_field
*src
,
2791 struct bt_field
*dst
)
2794 struct bt_field_variant
*variant_src
, *variant_dst
;
2796 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2798 variant_src
= container_of(src
, struct bt_field_variant
, parent
);
2799 variant_dst
= container_of(dst
, struct bt_field_variant
, parent
);
2801 if (variant_src
->tag
) {
2802 BT_LOGD_STR("Copying variant field's tag field.");
2803 variant_dst
->tag
= bt_field_copy(variant_src
->tag
);
2804 if (!variant_dst
->tag
) {
2805 BT_LOGE_STR("Cannot copy variant field's tag field.");
2810 if (variant_src
->payload
) {
2811 BT_LOGD_STR("Copying variant field's payload field.");
2812 variant_dst
->payload
= bt_field_copy(variant_src
->payload
);
2813 if (!variant_dst
->payload
) {
2814 BT_LOGE_STR("Cannot copy variant field's payload field.");
2820 BT_LOGD_STR("Copied variant field.");
2827 int bt_field_array_copy(struct bt_field
*src
,
2828 struct bt_field
*dst
)
2832 struct bt_field_array
*array_src
, *array_dst
;
2834 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2836 array_src
= container_of(src
, struct bt_field_array
, parent
);
2837 array_dst
= container_of(dst
, struct bt_field_array
, parent
);
2839 g_ptr_array_set_size(array_dst
->elements
, array_src
->elements
->len
);
2840 for (i
= 0; i
< array_src
->elements
->len
; i
++) {
2841 struct bt_field
*field
=
2842 g_ptr_array_index(array_src
->elements
, i
);
2843 struct bt_field
*field_copy
= NULL
;
2846 BT_LOGD("Copying array field's element field: field-addr=%p, "
2847 "index=%" PRId64
, field
, i
);
2848 field_copy
= bt_field_copy(field
);
2850 BT_LOGE("Cannot copy array field's element field: "
2851 "src-field-addr=%p, index=%" PRId64
,
2858 g_ptr_array_index(array_dst
->elements
, i
) = field_copy
;
2861 BT_LOGD_STR("Copied array field.");
2868 int bt_field_sequence_copy(struct bt_field
*src
,
2869 struct bt_field
*dst
)
2873 struct bt_field_sequence
*sequence_src
, *sequence_dst
;
2874 struct bt_field
*src_length
;
2875 struct bt_field
*dst_length
;
2877 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2879 sequence_src
= container_of(src
, struct bt_field_sequence
, parent
);
2880 sequence_dst
= container_of(dst
, struct bt_field_sequence
, parent
);
2882 src_length
= bt_field_sequence_get_length(src
);
2884 /* no length set yet: keep destination sequence empty */
2888 /* copy source length */
2889 BT_LOGD_STR("Copying sequence field's length field.");
2890 dst_length
= bt_field_copy(src_length
);
2893 BT_LOGE_STR("Cannot copy sequence field's length field.");
2898 /* this will initialize the destination sequence's internal array */
2899 ret
= bt_field_sequence_set_length(dst
, dst_length
);
2902 BT_LOGE("Cannot set sequence field copy's length field: "
2903 "dst-length-field-addr=%p", dst_length
);
2908 assert(sequence_dst
->elements
->len
== sequence_src
->elements
->len
);
2910 for (i
= 0; i
< sequence_src
->elements
->len
; i
++) {
2911 struct bt_field
*field
=
2912 g_ptr_array_index(sequence_src
->elements
, i
);
2913 struct bt_field
*field_copy
= NULL
;
2916 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2917 "index=%" PRId64
, field
, i
);
2918 field_copy
= bt_field_copy(field
);
2920 BT_LOGE("Cannot copy sequence field's element field: "
2921 "src-field-addr=%p, index=%" PRId64
,
2928 g_ptr_array_index(sequence_dst
->elements
, i
) = field_copy
;
2931 BT_LOGD_STR("Copied sequence field.");
2938 int bt_field_string_copy(struct bt_field
*src
,
2939 struct bt_field
*dst
)
2942 struct bt_field_string
*string_src
, *string_dst
;
2944 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
2946 string_src
= container_of(src
, struct bt_field_string
, parent
);
2947 string_dst
= container_of(dst
, struct bt_field_string
, parent
);
2949 if (string_src
->payload
) {
2950 string_dst
->payload
= g_string_new(string_src
->payload
->str
);
2951 if (!string_dst
->payload
) {
2952 BT_LOGE_STR("Failed to allocate a GString.");
2958 BT_LOGD_STR("Copied string field.");
2965 int increase_packet_size(struct bt_stream_pos
*pos
)
2970 BT_LOGV("Increasing packet size: pos-offset=%" PRId64
", "
2971 "cur-packet-size=%" PRIu64
,
2972 pos
->offset
, pos
->packet_size
);
2973 ret
= munmap_align(pos
->base_mma
);
2975 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
2980 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
2982 ret
= bt_posix_fallocate(pos
->fd
, pos
->mmap_offset
,
2983 pos
->packet_size
/ CHAR_BIT
);
2984 } while (ret
== EINTR
);
2986 BT_LOGE_ERRNO("Failed to preallocate memory space",
2993 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
2994 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
2995 if (pos
->base_mma
== MAP_FAILED
) {
2996 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
3001 BT_LOGV("Increased packet size: pos-offset=%" PRId64
", "
3002 "new-packet-size=%" PRIu64
,
3003 pos
->offset
, pos
->packet_size
);
3004 assert(pos
->packet_size
% 8 == 0);
3011 void generic_field_freeze(struct bt_field
*field
)
3013 field
->frozen
= true;
3017 void bt_field_enumeration_freeze(struct bt_field
*field
)
3019 struct bt_field_enumeration
*enum_field
=
3020 container_of(field
, struct bt_field_enumeration
, parent
);
3022 BT_LOGD("Freezing enumeration field object: addr=%p", field
);
3023 BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field
->payload
);
3024 bt_field_freeze(enum_field
->payload
);
3025 generic_field_freeze(field
);
3029 void bt_field_structure_freeze(struct bt_field
*field
)
3032 struct bt_field_structure
*structure_field
=
3033 container_of(field
, struct bt_field_structure
, parent
);
3035 BT_LOGD("Freezing structure field object: addr=%p", field
);
3037 for (i
= 0; i
< structure_field
->fields
->len
; i
++) {
3038 struct bt_field
*field
=
3039 g_ptr_array_index(structure_field
->fields
, i
);
3041 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64
,
3043 bt_field_freeze(field
);
3046 generic_field_freeze(field
);
3050 void bt_field_variant_freeze(struct bt_field
*field
)
3052 struct bt_field_variant
*variant_field
=
3053 container_of(field
, struct bt_field_variant
, parent
);
3055 BT_LOGD("Freezing variant field object: addr=%p", field
);
3056 BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field
->tag
);
3057 bt_field_freeze(variant_field
->tag
);
3058 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field
->payload
);
3059 bt_field_freeze(variant_field
->payload
);
3060 generic_field_freeze(field
);
3064 void bt_field_array_freeze(struct bt_field
*field
)
3067 struct bt_field_array
*array_field
=
3068 container_of(field
, struct bt_field_array
, parent
);
3070 BT_LOGD("Freezing array field object: addr=%p", field
);
3072 for (i
= 0; i
< array_field
->elements
->len
; i
++) {
3073 struct bt_field
*elem_field
=
3074 g_ptr_array_index(array_field
->elements
, i
);
3076 BT_LOGD("Freezing array field object's element field: "
3077 "element-field-addr=%p, index=%" PRId64
,
3079 bt_field_freeze(elem_field
);
3082 generic_field_freeze(field
);
3086 void bt_field_sequence_freeze(struct bt_field
*field
)
3089 struct bt_field_sequence
*sequence_field
=
3090 container_of(field
, struct bt_field_sequence
, parent
);
3092 BT_LOGD("Freezing sequence field object: addr=%p", field
);
3093 BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p",
3094 sequence_field
->length
);
3095 bt_field_freeze(sequence_field
->length
);
3097 for (i
= 0; i
< sequence_field
->elements
->len
; i
++) {
3098 struct bt_field
*elem_field
=
3099 g_ptr_array_index(sequence_field
->elements
, i
);
3101 BT_LOGD("Freezing sequence field object's element field: "
3102 "element-field-addr=%p, index=%" PRId64
,
3104 bt_field_freeze(elem_field
);
3107 generic_field_freeze(field
);
3111 void bt_field_freeze(struct bt_field
*field
)
3113 enum bt_field_type_id type_id
;
3119 if (field
->frozen
) {
3123 BT_LOGD("Freezing field object: addr=%p", field
);
3124 type_id
= bt_field_get_type_id(field
);
3125 assert(type_id
> BT_FIELD_TYPE_ID_UNKNOWN
&&
3126 type_id
< BT_FIELD_TYPE_ID_NR
);
3127 field_freeze_funcs
[type_id
](field
);
3133 bt_bool
bt_field_generic_is_set(struct bt_field
*field
)
3135 return field
&& field
->payload_set
;
3139 bt_bool
bt_field_enumeration_is_set(struct bt_field
*field
)
3141 bt_bool is_set
= BT_FALSE
;
3142 struct bt_field_enumeration
*enumeration
;
3148 enumeration
= container_of(field
, struct bt_field_enumeration
,
3150 if (!enumeration
->payload
) {
3154 is_set
= bt_field_is_set(enumeration
->payload
);
3160 bt_bool
bt_field_structure_is_set(struct bt_field
*field
)
3162 bt_bool is_set
= BT_FALSE
;
3164 struct bt_field_structure
*structure
;
3170 structure
= container_of(field
, struct bt_field_structure
, parent
);
3171 for (i
= 0; i
< structure
->fields
->len
; i
++) {
3172 is_set
= bt_field_is_set(
3173 structure
->fields
->pdata
[i
]);
3183 bt_bool
bt_field_variant_is_set(struct bt_field
*field
)
3185 bt_bool is_set
= BT_FALSE
;
3186 struct bt_field_variant
*variant
;
3192 variant
= container_of(field
, struct bt_field_variant
, parent
);
3193 is_set
= bt_field_is_set(variant
->payload
);
3199 bt_bool
bt_field_array_is_set(struct bt_field
*field
)
3202 bt_bool is_set
= BT_FALSE
;
3203 struct bt_field_array
*array
;
3209 array
= container_of(field
, struct bt_field_array
, parent
);
3210 for (i
= 0; i
< array
->elements
->len
; i
++) {
3211 is_set
= bt_field_is_set(array
->elements
->pdata
[i
]);
3221 bt_bool
bt_field_sequence_is_set(struct bt_field
*field
)
3224 bt_bool is_set
= BT_FALSE
;
3225 struct bt_field_sequence
*sequence
;
3231 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
3232 if (!sequence
->elements
) {
3236 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
3237 is_set
= bt_field_is_set(sequence
->elements
->pdata
[i
]);