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
;
410 int64_t bt_field_sequence_get_int_length(struct bt_field
*field
)
412 struct bt_field_sequence
*sequence
;
416 assert(bt_field_type_get_type_id(field
->type
) ==
417 BT_FIELD_TYPE_ID_SEQUENCE
);
418 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
419 if (!sequence
->length
) {
424 ret
= (int64_t) sequence
->elements
->len
;
430 struct bt_field
*bt_field_sequence_get_length(
431 struct bt_field
*field
)
433 struct bt_field
*ret
= NULL
;
434 struct bt_field_sequence
*sequence
;
437 BT_LOGW_STR("Invalid parameter: field is NULL.");
441 if (bt_field_type_get_type_id(field
->type
) !=
442 BT_FIELD_TYPE_ID_SEQUENCE
) {
443 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
444 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
446 bt_field_type_id_string(field
->type
->id
));
450 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
451 ret
= sequence
->length
;
457 int bt_field_sequence_set_length(struct bt_field
*field
,
458 struct bt_field
*length_field
)
461 struct bt_field_type_integer
*length_type
;
462 struct bt_field_integer
*length
;
463 struct bt_field_sequence
*sequence
;
464 uint64_t sequence_length
;
467 BT_LOGW_STR("Invalid parameter: field is NULL.");
473 BT_LOGW_STR("Invalid parameter: length field is NULL.");
479 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
485 if (bt_field_type_get_type_id(length_field
->type
) !=
486 BT_FIELD_TYPE_ID_INTEGER
) {
487 BT_LOGW("Invalid parameter: length field's type is not an integer field type: "
488 "field-addr=%p, length-field-addr=%p, length-ft-addr=%p, length-ft-id=%s",
489 field
, length_field
, length_field
->type
,
490 bt_field_type_id_string(length_field
->type
->id
));
495 length_type
= container_of(length_field
->type
,
496 struct bt_field_type_integer
, parent
);
497 /* The length field must be unsigned */
498 if (length_type
->is_signed
) {
499 BT_LOGW("Invalid parameter: length field's type is signed: "
500 "field-addr=%p, length-field-addr=%p, "
501 "length-field-ft-addr=%p", field
, length_field
,
507 if (!bt_field_is_set(length_field
)) {
508 BT_LOGW("Invalid parameter: length field's value is not set: "
509 "field-addr=%p, length-field-addr=%p, "
510 "length-field-ft-addr=%p", field
, length_field
,
516 length
= container_of(length_field
, struct bt_field_integer
,
518 sequence_length
= length
->payload
.unsignd
;
519 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
520 if (sequence
->elements
) {
521 g_ptr_array_free(sequence
->elements
, TRUE
);
522 bt_put(sequence
->length
);
525 sequence
->elements
= g_ptr_array_sized_new((size_t) sequence_length
);
526 if (!sequence
->elements
) {
527 BT_LOGE_STR("Failed to allocate a GPtrArray.");
532 g_ptr_array_set_free_func(sequence
->elements
,
533 (GDestroyNotify
) bt_put
);
534 g_ptr_array_set_size(sequence
->elements
, (size_t) sequence_length
);
535 bt_get(length_field
);
536 sequence
->length
= length_field
;
537 bt_field_freeze(length_field
);
542 struct bt_field
*bt_field_structure_get_field_by_name(
543 struct bt_field
*field
, const char *name
)
545 struct bt_field
*ret
= NULL
;
547 struct bt_field_structure
*structure
;
549 GHashTable
*field_name_to_index
;
552 BT_LOGW_STR("Invalid parameter: field is NULL.");
557 BT_LOGW_STR("Invalid parameter: field name is NULL.");
561 if (bt_field_type_get_type_id(field
->type
) !=
562 BT_FIELD_TYPE_ID_STRUCT
) {
563 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
564 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
566 bt_field_type_id_string(field
->type
->id
));
570 field_name_to_index
=
571 container_of(field
->type
, struct bt_field_type_structure
,
572 parent
)->field_name_to_index
;
573 field_quark
= g_quark_from_string(name
);
574 structure
= container_of(field
, struct bt_field_structure
, parent
);
575 if (!g_hash_table_lookup_extended(field_name_to_index
,
576 GUINT_TO_POINTER(field_quark
),
577 NULL
, (gpointer
*)&index
)) {
578 BT_LOGV("Invalid parameter: no such field in structure field's type: "
579 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
580 field
, field
->type
, name
);
584 ret
= bt_get(structure
->fields
->pdata
[index
]);
590 struct bt_field
*bt_field_structure_get_field_by_index(
591 struct bt_field
*field
, uint64_t index
)
593 struct bt_field_structure
*structure
;
594 struct bt_field
*ret
= NULL
;
597 BT_LOGW_STR("Invalid parameter: field is NULL.");
601 if (bt_field_type_get_type_id(field
->type
) !=
602 BT_FIELD_TYPE_ID_STRUCT
) {
603 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
604 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
606 bt_field_type_id_string(field
->type
->id
));
610 structure
= container_of(field
, struct bt_field_structure
, parent
);
611 if (index
>= structure
->fields
->len
) {
612 BT_LOGW("Invalid parameter: index is out of bounds: "
613 "addr=%p, index=%" PRIu64
", count=%u",
614 field
, index
, structure
->fields
->len
);
618 ret
= bt_get(structure
->fields
->pdata
[index
]);
623 int bt_field_structure_set_field_by_name(struct bt_field
*field
,
624 const char *name
, struct bt_field
*value
)
628 struct bt_field_structure
*structure
;
629 struct bt_field_type
*expected_field_type
= NULL
;
631 GHashTable
*field_name_to_index
;
634 BT_LOGW_STR("Invalid parameter: structure field is NULL.");
640 BT_LOGW_STR("Invalid parameter: field name is NULL.");
646 BT_LOGW_STR("Invalid parameter: field is NULL.");
651 if (bt_field_type_get_type_id(field
->type
) !=
652 BT_FIELD_TYPE_ID_STRUCT
) {
653 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
654 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
656 bt_field_type_id_string(field
->type
->id
));
661 field_quark
= g_quark_from_string(name
);
662 structure
= container_of(field
, struct bt_field_structure
, parent
);
663 expected_field_type
=
664 bt_field_type_structure_get_field_type_by_name(field
->type
,
667 if (bt_field_type_compare(expected_field_type
, value
->type
)) {
668 BT_LOGW("Invalid parameter: field type of field to set is different from the expected field type: "
669 "struct-field-addr=%p, field-addr=%p, "
670 "field-ft-addr=%p, expected-ft-addr=%p",
671 field
, value
, value
->type
, expected_field_type
);
676 field_name_to_index
=
677 container_of(field
->type
, struct bt_field_type_structure
,
678 parent
)->field_name_to_index
;
679 if (!g_hash_table_lookup_extended(field_name_to_index
,
680 GUINT_TO_POINTER(field_quark
), NULL
,
681 (gpointer
*) &index
)) {
682 BT_LOGV("Invalid parameter: no such field in structure field's type: "
683 "struct-field-addr=%p, struct-ft-addr=%p, "
684 "field-ft-addr=%p, name=\"%s\"",
685 field
, field
->type
, value
->type
, name
);
690 BT_MOVE(structure
->fields
->pdata
[index
], value
);
692 if (expected_field_type
) {
693 bt_put(expected_field_type
);
698 struct bt_field
*bt_field_array_get_field(struct bt_field
*field
,
701 struct bt_field
*new_field
= NULL
;
702 struct bt_field_type
*field_type
= NULL
;
703 struct bt_field_array
*array
;
706 BT_LOGW_STR("Invalid parameter: field is NULL.");
710 if (bt_field_type_get_type_id(field
->type
) !=
711 BT_FIELD_TYPE_ID_ARRAY
) {
712 BT_LOGW("Invalid parameter: field's type is not an array field type: "
713 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
715 bt_field_type_id_string(field
->type
->id
));
719 array
= container_of(field
, struct bt_field_array
, parent
);
720 if (index
>= array
->elements
->len
) {
721 BT_LOGW("Invalid parameter: index is out of bounds: "
722 "addr=%p, index=%" PRIu64
", count=%u",
723 field
, index
, array
->elements
->len
);
727 field_type
= bt_field_type_array_get_element_type(field
->type
);
728 if (array
->elements
->pdata
[(size_t)index
]) {
729 new_field
= array
->elements
->pdata
[(size_t)index
];
733 /* We don't want to modify this field if it's frozen */
736 * Not logging a warning here because the user could
737 * legitimately check if a array field is set with
738 * this function: if the preconditions are satisfied,
739 * a NULL return value means this.
741 BT_LOGV("Not creating a field because array field is frozen: "
742 "array-field-addr=%p, index=%" PRIu64
, field
, index
);
746 new_field
= bt_field_create(field_type
);
747 array
->elements
->pdata
[(size_t)index
] = new_field
;
758 struct bt_field
*bt_field_sequence_get_field(struct bt_field
*field
,
761 struct bt_field
*new_field
= NULL
;
762 struct bt_field_type
*field_type
= NULL
;
763 struct bt_field_sequence
*sequence
;
766 BT_LOGW_STR("Invalid parameter: field is NULL.");
770 if (bt_field_type_get_type_id(field
->type
) !=
771 BT_FIELD_TYPE_ID_SEQUENCE
) {
772 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
773 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
775 bt_field_type_id_string(field
->type
->id
));
779 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
780 if (!sequence
->elements
) {
781 BT_LOGV("Sequence field's elements do not exist: addr=%p",
786 if (index
>= sequence
->elements
->len
) {
787 BT_LOGW("Invalid parameter: index is out of bounds: "
788 "addr=%p, index=%" PRIu64
", count=%u",
789 field
, index
, sequence
->elements
->len
);
793 field_type
= bt_field_type_sequence_get_element_type(field
->type
);
794 if (sequence
->elements
->pdata
[(size_t) index
]) {
795 new_field
= sequence
->elements
->pdata
[(size_t) index
];
799 /* We don't want to modify this field if it's frozen */
802 * Not logging a warning here because the user could
803 * legitimately check if a sequence field is set with
804 * this function: if the preconditions are satisfied,
805 * a NULL return value means this.
807 BT_LOGV("Not creating a field because sequence field is frozen: "
808 "sequence-field-addr=%p, index=%" PRIu64
, field
, index
);
812 new_field
= bt_field_create(field_type
);
813 sequence
->elements
->pdata
[(size_t) index
] = new_field
;
824 struct bt_field
*bt_field_variant_get_field(struct bt_field
*field
,
825 struct bt_field
*tag_field
)
827 struct bt_field
*new_field
= NULL
;
828 struct bt_field_variant
*variant
;
829 struct bt_field_type_variant
*variant_type
;
830 struct bt_field_type
*field_type
;
831 struct bt_field
*tag_enum
= NULL
;
832 struct bt_field_integer
*tag_enum_integer
;
833 int64_t tag_enum_value
;
836 BT_LOGW_STR("Invalid parameter: field is NULL.");
841 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
845 if (bt_field_type_get_type_id(field
->type
) !=
846 BT_FIELD_TYPE_ID_VARIANT
) {
847 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
848 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
850 bt_field_type_id_string(field
->type
->id
));
854 if (bt_field_type_get_type_id(tag_field
->type
) !=
855 BT_FIELD_TYPE_ID_ENUM
) {
856 BT_LOGW("Invalid parameter: tag field's type is not an enumeration field type: "
857 "field-addr=%p, ft-addr=%p, ft-id=%s", tag_field
,
859 bt_field_type_id_string(tag_field
->type
->id
));
863 variant
= container_of(field
, struct bt_field_variant
, parent
);
864 variant_type
= container_of(field
->type
,
865 struct bt_field_type_variant
, parent
);
866 tag_enum
= bt_field_enumeration_get_container(tag_field
);
871 tag_enum_integer
= container_of(tag_enum
, struct bt_field_integer
,
874 if (bt_field_validate(tag_field
) < 0) {
875 BT_LOGW("Invalid parameter: tag field is invalid: "
876 "variant-field-addr=%p, tag-field-addr=%p",
881 tag_enum_value
= tag_enum_integer
->payload
.signd
;
884 * If the variant currently has a tag and a payload, and if the
885 * requested tag value is the same as the current one, return
886 * the current payload instead of creating a fresh one.
888 if (variant
->tag
&& variant
->payload
) {
889 struct bt_field
*cur_tag_container
= NULL
;
890 struct bt_field_integer
*cur_tag_enum_integer
;
891 int64_t cur_tag_value
;
894 bt_field_enumeration_get_container(variant
->tag
);
895 assert(cur_tag_container
);
896 cur_tag_enum_integer
= container_of(cur_tag_container
,
897 struct bt_field_integer
, parent
);
898 bt_put(cur_tag_container
);
899 cur_tag_value
= cur_tag_enum_integer
->payload
.signd
;
901 if (cur_tag_value
== tag_enum_value
) {
902 new_field
= variant
->payload
;
908 /* We don't want to modify this field if it's frozen */
911 * Not logging a warning here because the user could
912 * legitimately check if a variant field is set with
913 * this function: if the preconditions are satisfied,
914 * a NULL return value means this.
916 BT_LOGV("Not creating a field because variant field is frozen: "
917 "variant-field-addr=%p, tag-field-addr=%p",
922 field_type
= bt_field_type_variant_get_field_type_signed(
923 variant_type
, tag_enum_value
);
925 BT_LOGW("Cannot get variant field type's field: "
926 "variant-field-addr=%p, variant-ft-addr=%p, "
927 "tag-value-signed=%" PRId64
,
928 field
, variant_type
, tag_enum_value
);
932 new_field
= bt_field_create(field_type
);
934 BT_LOGW("Cannot create field: "
935 "variant-field-addr=%p, variant-ft-addr=%p, "
936 "field-ft-addr=%p", field
, field
->type
, field_type
);
940 bt_put(variant
->tag
);
941 bt_put(variant
->payload
);
944 variant
->tag
= tag_field
;
945 variant
->payload
= new_field
;
951 struct bt_field
*bt_field_variant_get_current_field(
952 struct bt_field
*variant_field
)
954 struct bt_field
*current_field
= NULL
;
955 struct bt_field_variant
*variant
;
957 if (!variant_field
) {
958 BT_LOGW_STR("Invalid parameter: field is NULL.");
962 if (bt_field_type_get_type_id(variant_field
->type
) !=
963 BT_FIELD_TYPE_ID_VARIANT
) {
964 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
965 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field
,
967 bt_field_type_id_string(variant_field
->type
->id
));
971 variant
= container_of(variant_field
, struct bt_field_variant
,
974 if (variant
->payload
) {
975 current_field
= variant
->payload
;
976 bt_get(current_field
);
981 return current_field
;
984 struct bt_field
*bt_field_variant_get_tag(
985 struct bt_field
*variant_field
)
987 struct bt_field
*tag
= NULL
;
988 struct bt_field_variant
*variant
;
990 if (!variant_field
) {
991 BT_LOGW_STR("Invalid parameter: field is NULL.");
995 if (bt_field_type_get_type_id(variant_field
->type
) !=
996 BT_FIELD_TYPE_ID_VARIANT
) {
997 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
998 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field
,
1000 bt_field_type_id_string(variant_field
->type
->id
));
1004 variant
= container_of(variant_field
, struct bt_field_variant
,
1007 tag
= bt_get(variant
->tag
);
1013 struct bt_field
*bt_field_enumeration_get_container(
1014 struct bt_field
*field
)
1016 struct bt_field
*container
= NULL
;
1017 struct bt_field_enumeration
*enumeration
;
1020 BT_LOGW_STR("Invalid parameter: field is NULL.");
1024 if (bt_field_type_get_type_id(field
->type
) !=
1025 BT_FIELD_TYPE_ID_ENUM
) {
1026 BT_LOGW("Invalid parameter: field's type is not an enumeration field type: "
1027 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1029 bt_field_type_id_string(field
->type
->id
));
1033 enumeration
= container_of(field
, struct bt_field_enumeration
,
1035 if (!enumeration
->payload
) {
1036 /* We don't want to modify this field if it's frozen */
1037 if (field
->frozen
) {
1039 * Not logging a warning here because the user
1040 * could legitimately check if an enumeration's
1041 * container field is set with this function: if
1042 * the preconditions are satisfied, a NULL
1043 * return value means this.
1045 BT_LOGV("Not creating a field because enumeration field is frozen: "
1046 "enum-field-addr=%p", field
);
1050 struct bt_field_type_enumeration
*enumeration_type
=
1051 container_of(field
->type
,
1052 struct bt_field_type_enumeration
, parent
);
1053 enumeration
->payload
=
1054 bt_field_create(enumeration_type
->container
);
1057 container
= enumeration
->payload
;
1063 struct bt_field_type_enumeration_mapping_iterator
*
1064 bt_field_enumeration_get_mappings(struct bt_field
*field
)
1067 struct bt_field
*container
= NULL
;
1068 struct bt_field_type
*container_type
= NULL
;
1069 struct bt_field_type_integer
*integer_type
= NULL
;
1070 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
1072 container
= bt_field_enumeration_get_container(field
);
1074 BT_LOGW("Invalid parameter: enumeration field has no container field: "
1079 container_type
= bt_field_get_type(container
);
1080 assert(container_type
);
1081 integer_type
= container_of(container_type
,
1082 struct bt_field_type_integer
, parent
);
1084 if (!integer_type
->is_signed
) {
1087 ret
= bt_field_unsigned_integer_get_value(container
,
1090 BT_LOGW("Cannot get value from signed enumeration field's payload field: "
1091 "enum-field-addr=%p, payload-field-addr=%p",
1093 goto error_put_container_type
;
1095 iter
= bt_field_type_enumeration_find_mappings_by_unsigned_value(
1096 field
->type
, value
);
1100 ret
= bt_field_signed_integer_get_value(container
,
1103 BT_LOGW("Cannot get value from unsigned enumeration field's payload field: "
1104 "enum-field-addr=%p, payload-field-addr=%p",
1106 goto error_put_container_type
;
1108 iter
= bt_field_type_enumeration_find_mappings_by_signed_value(
1109 field
->type
, value
);
1112 error_put_container_type
:
1113 bt_put(container_type
);
1119 int bt_field_signed_integer_get_value(struct bt_field
*field
,
1123 struct bt_field_integer
*integer
;
1124 struct bt_field_type_integer
*integer_type
;
1127 BT_LOGW_STR("Invalid parameter: field is NULL.");
1133 BT_LOGW_STR("Invalid parameter: value is NULL.");
1138 if (!field
->payload_set
) {
1139 BT_LOGV("Field's payload is not set: addr=%p", field
);
1144 if (bt_field_type_get_type_id(field
->type
) !=
1145 BT_FIELD_TYPE_ID_INTEGER
) {
1146 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1147 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1149 bt_field_type_id_string(field
->type
->id
));
1154 integer_type
= container_of(field
->type
,
1155 struct bt_field_type_integer
, parent
);
1156 if (!integer_type
->is_signed
) {
1157 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1158 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1163 integer
= container_of(field
,
1164 struct bt_field_integer
, parent
);
1165 *value
= integer
->payload
.signd
;
1170 int bt_field_signed_integer_set_value(struct bt_field
*field
,
1174 struct bt_field_integer
*integer
;
1175 struct bt_field_type_integer
*integer_type
;
1177 int64_t min_value
, max_value
;
1180 BT_LOGW_STR("Invalid parameter: field is NULL.");
1185 if (field
->frozen
) {
1186 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1192 if (bt_field_type_get_type_id(field
->type
) !=
1193 BT_FIELD_TYPE_ID_INTEGER
) {
1194 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1195 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1197 bt_field_type_id_string(field
->type
->id
));
1202 integer
= container_of(field
, struct bt_field_integer
, parent
);
1203 integer_type
= container_of(field
->type
,
1204 struct bt_field_type_integer
, parent
);
1205 if (!integer_type
->is_signed
) {
1206 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1207 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1212 size
= integer_type
->size
;
1213 min_value
= -(1ULL << (size
- 1));
1214 max_value
= (1ULL << (size
- 1)) - 1;
1215 if (value
< min_value
|| value
> max_value
) {
1216 BT_LOGW("Invalid parameter: value is out of bounds: "
1217 "addr=%p, value=%" PRId64
", "
1218 "min-value=%" PRId64
", max-value=%" PRId64
,
1219 field
, value
, min_value
, max_value
);
1224 integer
->payload
.signd
= value
;
1225 integer
->parent
.payload_set
= true;
1230 int bt_field_unsigned_integer_get_value(struct bt_field
*field
,
1234 struct bt_field_integer
*integer
;
1235 struct bt_field_type_integer
*integer_type
;
1238 BT_LOGW_STR("Invalid parameter: field is NULL.");
1244 BT_LOGW_STR("Invalid parameter: value is NULL.");
1249 if (!field
->payload_set
) {
1250 BT_LOGV("Field's payload is not set: addr=%p", field
);
1255 if (bt_field_type_get_type_id(field
->type
) !=
1256 BT_FIELD_TYPE_ID_INTEGER
) {
1257 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1258 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1260 bt_field_type_id_string(field
->type
->id
));
1265 integer_type
= container_of(field
->type
,
1266 struct bt_field_type_integer
, parent
);
1267 if (integer_type
->is_signed
) {
1268 BT_LOGW("Invalid parameter: integer field's type is signed: "
1269 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1274 integer
= container_of(field
,
1275 struct bt_field_integer
, parent
);
1276 *value
= integer
->payload
.unsignd
;
1281 int bt_field_unsigned_integer_set_value(struct bt_field
*field
,
1285 struct bt_field_integer
*integer
;
1286 struct bt_field_type_integer
*integer_type
;
1291 BT_LOGW_STR("Invalid parameter: field is NULL.");
1296 if (field
->frozen
) {
1297 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1303 if (bt_field_type_get_type_id(field
->type
) !=
1304 BT_FIELD_TYPE_ID_INTEGER
) {
1305 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1306 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1308 bt_field_type_id_string(field
->type
->id
));
1313 integer
= container_of(field
, struct bt_field_integer
, parent
);
1314 integer_type
= container_of(field
->type
,
1315 struct bt_field_type_integer
, parent
);
1316 if (integer_type
->is_signed
) {
1317 BT_LOGW("Invalid parameter: integer field's type is signed: "
1318 "field-addr=%p, ft-addr=%p", field
, field
->type
);
1323 size
= integer_type
->size
;
1324 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t) 1 << size
) - 1;
1325 if (value
> max_value
) {
1326 BT_LOGW("Invalid parameter: value is out of bounds: "
1327 "addr=%p, value=%" PRIu64
", "
1328 "min-value=%" PRIu64
", max-value=%" PRIu64
,
1329 field
, value
, (uint64_t) 0, max_value
);
1334 integer
->payload
.unsignd
= value
;
1335 integer
->parent
.payload_set
= true;
1340 int bt_field_floating_point_get_value(struct bt_field
*field
,
1344 struct bt_field_floating_point
*floating_point
;
1347 BT_LOGW_STR("Invalid parameter: field is NULL.");
1353 BT_LOGW_STR("Invalid parameter: value is NULL.");
1358 if (!field
->payload_set
) {
1359 BT_LOGV("Field's payload is not set: addr=%p", field
);
1364 if (bt_field_type_get_type_id(field
->type
) !=
1365 BT_FIELD_TYPE_ID_FLOAT
) {
1366 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1367 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1369 bt_field_type_id_string(field
->type
->id
));
1374 floating_point
= container_of(field
,
1375 struct bt_field_floating_point
, parent
);
1376 *value
= floating_point
->payload
;
1381 int bt_field_floating_point_set_value(struct bt_field
*field
,
1385 struct bt_field_floating_point
*floating_point
;
1388 BT_LOGW_STR("Invalid parameter: field is NULL.");
1393 if (field
->frozen
) {
1394 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1400 if (bt_field_type_get_type_id(field
->type
) !=
1401 BT_FIELD_TYPE_ID_FLOAT
) {
1402 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1403 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1405 bt_field_type_id_string(field
->type
->id
));
1410 floating_point
= container_of(field
, struct bt_field_floating_point
,
1412 floating_point
->payload
= value
;
1413 floating_point
->parent
.payload_set
= true;
1418 const char *bt_field_string_get_value(struct bt_field
*field
)
1420 const char *ret
= NULL
;
1421 struct bt_field_string
*string
;
1424 BT_LOGW_STR("Invalid parameter: field is NULL.");
1428 if (!field
->payload_set
) {
1429 BT_LOGV("Field's payload is not set: addr=%p", field
);
1433 if (bt_field_type_get_type_id(field
->type
) !=
1434 BT_FIELD_TYPE_ID_STRING
) {
1435 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1436 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1438 bt_field_type_id_string(field
->type
->id
));
1442 string
= container_of(field
,
1443 struct bt_field_string
, parent
);
1444 ret
= string
->payload
->str
;
1449 int bt_field_string_set_value(struct bt_field
*field
,
1453 struct bt_field_string
*string
;
1456 BT_LOGW_STR("Invalid parameter: field is NULL.");
1462 BT_LOGW_STR("Invalid parameter: value is NULL.");
1467 if (field
->frozen
) {
1468 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1474 if (bt_field_type_get_type_id(field
->type
) !=
1475 BT_FIELD_TYPE_ID_STRING
) {
1476 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1477 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1479 bt_field_type_id_string(field
->type
->id
));
1484 string
= container_of(field
, struct bt_field_string
, parent
);
1485 if (string
->payload
) {
1486 g_string_assign(string
->payload
, value
);
1488 string
->payload
= g_string_new(value
);
1491 string
->parent
.payload_set
= true;
1496 int bt_field_string_append(struct bt_field
*field
,
1500 struct bt_field_string
*string_field
;
1503 BT_LOGW_STR("Invalid parameter: field is NULL.");
1509 BT_LOGW_STR("Invalid parameter: value is NULL.");
1514 if (field
->frozen
) {
1515 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1521 if (bt_field_type_get_type_id(field
->type
) !=
1522 BT_FIELD_TYPE_ID_STRING
) {
1523 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1524 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1526 bt_field_type_id_string(field
->type
->id
));
1531 string_field
= container_of(field
, struct bt_field_string
, parent
);
1533 if (string_field
->payload
) {
1534 g_string_append(string_field
->payload
, value
);
1536 string_field
->payload
= g_string_new(value
);
1539 string_field
->parent
.payload_set
= true;
1545 int bt_field_string_append_len(struct bt_field
*field
,
1546 const char *value
, unsigned int length
)
1550 unsigned int effective_length
= length
;
1551 struct bt_field_string
*string_field
;
1554 BT_LOGW_STR("Invalid parameter: field is NULL.");
1560 BT_LOGW_STR("Invalid parameter: value is NULL.");
1565 if (field
->frozen
) {
1566 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1572 if (bt_field_type_get_type_id(field
->type
) !=
1573 BT_FIELD_TYPE_ID_STRING
) {
1574 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1575 "field-addr=%p, ft-addr=%p, ft-id=%s", field
,
1577 bt_field_type_id_string(field
->type
->id
));
1582 string_field
= container_of(field
, struct bt_field_string
, parent
);
1584 /* make sure no null bytes are appended */
1585 for (i
= 0; i
< length
; ++i
) {
1586 if (value
[i
] == '\0') {
1587 effective_length
= i
;
1592 if (string_field
->payload
) {
1593 g_string_append_len(string_field
->payload
, value
,
1596 string_field
->payload
= g_string_new_len(value
,
1600 string_field
->parent
.payload_set
= true;
1607 int bt_field_validate(struct bt_field
*field
)
1610 enum bt_field_type_id type_id
;
1613 BT_LOGD_STR("Invalid parameter: field is NULL.");
1618 type_id
= bt_field_type_get_type_id(field
->type
);
1619 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1620 BT_LOGW("Invalid parameter: unknown field type ID: "
1621 "addr=%p, ft-addr=%p, ft-id=%d",
1622 field
, field
->type
, type_id
);
1627 ret
= field_validate_funcs
[type_id
](field
);
1632 int bt_field_reset(struct bt_field
*field
)
1635 enum bt_field_type_id type_id
;
1638 BT_LOGD_STR("Invalid parameter: field is NULL.");
1643 if (field
->frozen
) {
1644 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1650 type_id
= bt_field_type_get_type_id(field
->type
);
1651 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1652 BT_LOGW("Invalid parameter: unknown field type ID: "
1653 "addr=%p, ft-addr=%p, ft-id=%d",
1654 field
, field
->type
, type_id
);
1659 ret
= field_reset_funcs
[type_id
](field
);
1665 int bt_field_serialize(struct bt_field
*field
,
1666 struct bt_stream_pos
*pos
,
1667 enum bt_byte_order native_byte_order
)
1670 enum bt_field_type_id type_id
;
1675 BT_LOGD_STR("Invalid parameter: field is NULL.");
1680 type_id
= bt_field_type_get_type_id(field
->type
);
1681 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1682 BT_LOGW("Invalid parameter: unknown field type ID: "
1683 "addr=%p, ft-addr=%p, ft-id=%d",
1684 field
, field
->type
, type_id
);
1689 ret
= field_serialize_funcs
[type_id
](field
, pos
, native_byte_order
);
1694 bt_bool
bt_field_is_set(struct bt_field
*field
)
1696 bt_bool is_set
= BT_FALSE
;
1697 enum bt_field_type_id type_id
;
1703 type_id
= bt_field_type_get_type_id(field
->type
);
1704 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1705 BT_LOGW("Invalid parameter: unknown field type ID: "
1706 "field-addr=%p, ft-addr=%p, ft-id=%d",
1707 field
, field
->type
, type_id
);
1711 is_set
= field_is_set_funcs
[type_id
](field
);
1716 struct bt_field
*bt_field_copy(struct bt_field
*field
)
1719 struct bt_field
*copy
= NULL
;
1720 enum bt_field_type_id type_id
;
1723 BT_LOGW_STR("Invalid parameter: field is NULL.");
1727 type_id
= bt_field_type_get_type_id(field
->type
);
1728 if (type_id
<= BT_FIELD_TYPE_ID_UNKNOWN
|| type_id
>= BT_FIELD_TYPE_ID_NR
) {
1729 BT_LOGW("Invalid parameter: unknown field type ID: "
1730 "field-addr=%p, ft-addr=%p, ft-id=%d",
1731 field
, field
->type
, type_id
);
1735 copy
= bt_field_create(field
->type
);
1737 BT_LOGW("Cannot create field: ft-addr=%p", field
->type
);
1741 copy
->payload_set
= field
->payload_set
;
1742 ret
= field_copy_funcs
[type_id
](field
, copy
);
1752 struct bt_field
*bt_field_integer_create(struct bt_field_type
*type
)
1754 struct bt_field_integer
*integer
= g_new0(
1755 struct bt_field_integer
, 1);
1757 BT_LOGD("Creating integer field object: ft-addr=%p", type
);
1760 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
1761 &integer
->parent
, type
);
1763 BT_LOGE_STR("Failed to allocate one integer field.");
1766 return integer
? &integer
->parent
: NULL
;
1770 struct bt_field
*bt_field_enumeration_create(
1771 struct bt_field_type
*type
)
1773 struct bt_field_enumeration
*enumeration
= g_new0(
1774 struct bt_field_enumeration
, 1);
1776 BT_LOGD("Creating enumeration field object: ft-addr=%p", type
);
1779 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
1780 &enumeration
->parent
, type
);
1782 BT_LOGE_STR("Failed to allocate one enumeration field.");
1785 return enumeration
? &enumeration
->parent
: NULL
;
1789 struct bt_field
*bt_field_floating_point_create(
1790 struct bt_field_type
*type
)
1792 struct bt_field_floating_point
*floating_point
;
1794 BT_LOGD("Creating floating point number field object: ft-addr=%p", type
);
1795 floating_point
= g_new0(struct bt_field_floating_point
, 1);
1797 if (floating_point
) {
1798 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
1799 &floating_point
->parent
, type
);
1801 BT_LOGE_STR("Failed to allocate one floating point number field.");
1804 return floating_point
? &floating_point
->parent
: NULL
;
1808 struct bt_field
*bt_field_structure_create(
1809 struct bt_field_type
*type
)
1811 struct bt_field_type_structure
*structure_type
= container_of(type
,
1812 struct bt_field_type_structure
, parent
);
1813 struct bt_field_structure
*structure
= g_new0(
1814 struct bt_field_structure
, 1);
1815 struct bt_field
*ret
= NULL
;
1818 BT_LOGD("Creating structure field object: ft-addr=%p", type
);
1821 BT_LOGE_STR("Failed to allocate one structure field.");
1825 structure
->fields
= g_ptr_array_new_with_free_func(
1826 (GDestroyNotify
) bt_put
);
1827 g_ptr_array_set_size(structure
->fields
,
1828 structure_type
->fields
->len
);
1830 /* Create all fields contained by the structure field. */
1831 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
1832 struct bt_field
*field
;
1833 struct structure_field
*field_type
=
1834 g_ptr_array_index(structure_type
->fields
, i
);
1836 field
= bt_field_create(field_type
->type
);
1838 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
1839 g_quark_to_string(field_type
->name
), i
);
1840 bt_field_structure_destroy(&structure
->parent
);
1844 g_ptr_array_index(structure
->fields
, i
) = field
;
1847 ret
= &structure
->parent
;
1848 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p", ret
,
1855 struct bt_field
*bt_field_variant_create(struct bt_field_type
*type
)
1857 struct bt_field_variant
*variant
= g_new0(
1858 struct bt_field_variant
, 1);
1860 BT_LOGD("Creating variant field object: ft-addr=%p", type
);
1863 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1864 &variant
->parent
, type
);
1866 BT_LOGE_STR("Failed to allocate one variant field.");
1869 return variant
? &variant
->parent
: NULL
;
1873 struct bt_field
*bt_field_array_create(struct bt_field_type
*type
)
1875 struct bt_field_array
*array
= g_new0(struct bt_field_array
, 1);
1876 struct bt_field_type_array
*array_type
;
1877 unsigned int array_length
;
1879 BT_LOGD("Creating array field object: ft-addr=%p", type
);
1883 BT_LOGE_STR("Failed to allocate one array field.");
1887 array_type
= container_of(type
, struct bt_field_type_array
, parent
);
1888 array_length
= array_type
->length
;
1889 array
->elements
= g_ptr_array_sized_new(array_length
);
1890 if (!array
->elements
) {
1894 g_ptr_array_set_free_func(array
->elements
,
1895 (GDestroyNotify
) bt_put
);
1896 g_ptr_array_set_size(array
->elements
, array_length
);
1897 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1898 &array
->parent
, type
);
1899 return &array
->parent
;
1906 struct bt_field
*bt_field_sequence_create(
1907 struct bt_field_type
*type
)
1909 struct bt_field_sequence
*sequence
= g_new0(
1910 struct bt_field_sequence
, 1);
1912 BT_LOGD("Creating sequence field object: ft-addr=%p", type
);
1915 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1916 &sequence
->parent
, type
);
1918 BT_LOGE_STR("Failed to allocate one sequence field.");
1921 return sequence
? &sequence
->parent
: NULL
;
1925 struct bt_field
*bt_field_string_create(struct bt_field_type
*type
)
1927 struct bt_field_string
*string
= g_new0(
1928 struct bt_field_string
, 1);
1930 BT_LOGD("Creating string field object: ft-addr=%p", type
);
1933 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1934 &string
->parent
, type
);
1936 BT_LOGE_STR("Failed to allocate one string field.");
1939 return string
? &string
->parent
: NULL
;
1943 void bt_field_destroy(struct bt_object
*obj
)
1945 struct bt_field
*field
;
1946 struct bt_field_type
*type
;
1947 enum bt_field_type_id type_id
;
1949 field
= container_of(obj
, struct bt_field
, base
);
1951 type_id
= bt_field_type_get_type_id(type
);
1952 assert(type_id
> BT_FIELD_TYPE_ID_UNKNOWN
&&
1953 type_id
< BT_FIELD_TYPE_ID_NR
);
1954 field_destroy_funcs
[type_id
](field
);
1955 BT_LOGD_STR("Putting field's type.");
1960 void bt_field_integer_destroy(struct bt_field
*field
)
1962 struct bt_field_integer
*integer
;
1968 BT_LOGD("Destroying integer field object: addr=%p", field
);
1969 integer
= container_of(field
, struct bt_field_integer
, parent
);
1974 void bt_field_enumeration_destroy(struct bt_field
*field
)
1976 struct bt_field_enumeration
*enumeration
;
1982 BT_LOGD("Destroying enumeration field object: addr=%p", field
);
1983 enumeration
= container_of(field
, struct bt_field_enumeration
,
1985 BT_LOGD_STR("Putting payload field.");
1986 bt_put(enumeration
->payload
);
1987 g_free(enumeration
);
1991 void bt_field_floating_point_destroy(struct bt_field
*field
)
1993 struct bt_field_floating_point
*floating_point
;
1999 BT_LOGD("Destroying floating point number field object: addr=%p", field
);
2000 floating_point
= container_of(field
, struct bt_field_floating_point
,
2002 g_free(floating_point
);
2006 void bt_field_structure_destroy(struct bt_field
*field
)
2008 struct bt_field_structure
*structure
;
2014 BT_LOGD("Destroying structure field object: addr=%p", field
);
2015 structure
= container_of(field
, struct bt_field_structure
, parent
);
2016 g_ptr_array_free(structure
->fields
, TRUE
);
2021 void bt_field_variant_destroy(struct bt_field
*field
)
2023 struct bt_field_variant
*variant
;
2029 BT_LOGD("Destroying variant field object: addr=%p", field
);
2030 variant
= container_of(field
, struct bt_field_variant
, parent
);
2031 BT_LOGD_STR("Putting tag field.");
2032 bt_put(variant
->tag
);
2033 BT_LOGD_STR("Putting payload field.");
2034 bt_put(variant
->payload
);
2039 void bt_field_array_destroy(struct bt_field
*field
)
2041 struct bt_field_array
*array
;
2047 BT_LOGD("Destroying array field object: addr=%p", field
);
2048 array
= container_of(field
, struct bt_field_array
, parent
);
2049 g_ptr_array_free(array
->elements
, TRUE
);
2054 void bt_field_sequence_destroy(struct bt_field
*field
)
2056 struct bt_field_sequence
*sequence
;
2062 BT_LOGD("Destroying sequence field object: addr=%p", field
);
2063 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2064 if (sequence
->elements
) {
2065 g_ptr_array_free(sequence
->elements
, TRUE
);
2067 BT_LOGD_STR("Putting length field.");
2068 bt_put(sequence
->length
);
2073 void bt_field_string_destroy(struct bt_field
*field
)
2075 struct bt_field_string
*string
;
2081 BT_LOGD("Destroying string field object: addr=%p", field
);
2082 string
= container_of(field
, struct bt_field_string
, parent
);
2083 if (string
->payload
) {
2084 g_string_free(string
->payload
, TRUE
);
2090 int bt_field_generic_validate(struct bt_field
*field
)
2092 return (field
&& field
->payload_set
) ? 0 : -1;
2096 int bt_field_enumeration_validate(struct bt_field
*field
)
2099 struct bt_field_enumeration
*enumeration
;
2102 BT_LOGD_STR("Invalid parameter: field is NULL.");
2107 enumeration
= container_of(field
, struct bt_field_enumeration
,
2109 if (!enumeration
->payload
) {
2110 BT_LOGW("Invalid enumeration field: payload is not set: "
2116 ret
= bt_field_validate(enumeration
->payload
);
2122 int bt_field_structure_validate(struct bt_field
*field
)
2126 struct bt_field_structure
*structure
;
2129 BT_LOGD_STR("Invalid parameter: field is NULL.");
2134 structure
= container_of(field
, struct bt_field_structure
, parent
);
2135 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2136 struct bt_field
*entry_field
= structure
->fields
->pdata
[i
];
2137 ret
= bt_field_validate(entry_field
);
2142 struct bt_field_type
*field_type
=
2143 bt_field_get_type(field
);
2145 this_ret
= bt_field_type_structure_get_field_by_index(
2146 field_type
, &name
, NULL
, i
);
2147 assert(this_ret
== 0);
2148 BT_LOGW("Invalid structure field's field: "
2149 "struct-field-addr=%p, field-addr=%p, "
2150 "field-name=\"%s\", index=%" PRId64
,
2151 field
, entry_field
, name
, i
);
2161 int bt_field_variant_validate(struct bt_field
*field
)
2164 struct bt_field_variant
*variant
;
2167 BT_LOGD_STR("Invalid parameter: field is NULL.");
2172 variant
= container_of(field
, struct bt_field_variant
, parent
);
2173 ret
= bt_field_validate(variant
->payload
);
2175 BT_LOGW("Invalid variant field's payload field: "
2176 "variant-field-addr=%p, variant-payload-field-addr=%p",
2177 field
, variant
->payload
);
2184 int bt_field_array_validate(struct bt_field
*field
)
2188 struct bt_field_array
*array
;
2191 BT_LOGD_STR("Invalid parameter: field is NULL.");
2196 array
= container_of(field
, struct bt_field_array
, parent
);
2197 for (i
= 0; i
< array
->elements
->len
; i
++) {
2198 struct bt_field
*elem_field
= array
->elements
->pdata
[i
];
2200 ret
= bt_field_validate(elem_field
);
2202 BT_LOGW("Invalid array field's element field: "
2203 "array-field-addr=%p, field-addr=%p, "
2204 "index=%" PRId64
, field
, elem_field
, i
);
2213 int bt_field_sequence_validate(struct bt_field
*field
)
2217 struct bt_field_sequence
*sequence
;
2220 BT_LOGD_STR("Invalid parameter: field is NULL.");
2225 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2226 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
2227 struct bt_field
*elem_field
= sequence
->elements
->pdata
[i
];
2229 ret
= bt_field_validate(elem_field
);
2231 BT_LOGW("Invalid sequence field's element field: "
2232 "sequence-field-addr=%p, field-addr=%p, "
2233 "index=%zu", field
, elem_field
, i
);
2242 int bt_field_generic_reset(struct bt_field
*field
)
2247 BT_LOGD_STR("Invalid parameter: field is NULL.");
2252 field
->payload_set
= false;
2258 int bt_field_enumeration_reset(struct bt_field
*field
)
2261 struct bt_field_enumeration
*enumeration
;
2264 BT_LOGD_STR("Invalid parameter: field is NULL.");
2269 enumeration
= container_of(field
, struct bt_field_enumeration
,
2271 if (!enumeration
->payload
) {
2275 ret
= bt_field_reset(enumeration
->payload
);
2281 int bt_field_structure_reset(struct bt_field
*field
)
2285 struct bt_field_structure
*structure
;
2288 BT_LOGD_STR("Invalid parameter: field is NULL.");
2293 structure
= container_of(field
, struct bt_field_structure
, parent
);
2294 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2295 struct bt_field
*member
= structure
->fields
->pdata
[i
];
2299 * Structure members are lazily initialized; skip if
2300 * this member has not been allocated yet.
2305 ret
= bt_field_reset(member
);
2307 BT_LOGE("Failed to reset structure field's field: "
2308 "struct-field-addr=%p, field-addr=%p, "
2309 "index=%" PRId64
, field
, member
, i
);
2318 int bt_field_variant_reset(struct bt_field
*field
)
2321 struct bt_field_variant
*variant
;
2324 BT_LOGD_STR("Invalid parameter: field is NULL.");
2329 variant
= container_of(field
, struct bt_field_variant
, parent
);
2330 BT_PUT(variant
->tag
);
2331 BT_PUT(variant
->payload
);
2337 int bt_field_array_reset(struct bt_field
*field
)
2341 struct bt_field_array
*array
;
2344 BT_LOGD_STR("Invalid parameter: field is NULL.");
2349 array
= container_of(field
, struct bt_field_array
, parent
);
2350 for (i
= 0; i
< array
->elements
->len
; i
++) {
2351 struct bt_field
*member
= array
->elements
->pdata
[i
];
2355 * Array elements are lazily initialized; skip if
2356 * this member has not been allocated yet.
2361 ret
= bt_field_reset(member
);
2363 BT_LOGE("Failed to reset array field's field: "
2364 "array-field-addr=%p, field-addr=%p, "
2365 "index=%zu", field
, member
, i
);
2374 int bt_field_sequence_reset(struct bt_field
*field
)
2377 struct bt_field_sequence
*sequence
;
2380 BT_LOGD_STR("Invalid parameter: field is NULL.");
2385 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2386 if (sequence
->elements
) {
2387 g_ptr_array_free(sequence
->elements
, TRUE
);
2388 sequence
->elements
= NULL
;
2390 BT_PUT(sequence
->length
);
2396 int bt_field_string_reset(struct bt_field
*field
)
2399 struct bt_field_string
*string
;
2402 BT_LOGD_STR("Invalid parameter: field is NULL.");
2407 ret
= bt_field_generic_reset(field
);
2412 string
= container_of(field
, struct bt_field_string
, parent
);
2413 if (string
->payload
) {
2414 g_string_truncate(string
->payload
, 0);
2421 int bt_field_integer_serialize(struct bt_field
*field
,
2422 struct bt_stream_pos
*pos
,
2423 enum bt_byte_order native_byte_order
)
2426 struct bt_field_integer
*integer
= container_of(field
,
2427 struct bt_field_integer
, parent
);
2429 BT_LOGV("Serializing integer field: addr=%p, pos-offset=%" PRId64
", "
2430 "native-bo=%s", field
, pos
->offset
,
2431 bt_byte_order_string(native_byte_order
));
2433 if (!bt_field_generic_is_set(field
)) {
2434 BT_LOGW_STR("Field's payload is not set.");
2439 ret
= bt_field_integer_write(integer
, pos
, native_byte_order
);
2440 if (ret
== -EFAULT
) {
2442 * The field is too large to fit in the current packet's
2443 * remaining space. Bump the packet size and retry.
2445 ret
= increase_packet_size(pos
);
2447 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
2457 int bt_field_enumeration_serialize(struct bt_field
*field
,
2458 struct bt_stream_pos
*pos
,
2459 enum bt_byte_order native_byte_order
)
2461 struct bt_field_enumeration
*enumeration
= container_of(
2462 field
, struct bt_field_enumeration
, parent
);
2464 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64
", "
2465 "native-bo=%s", field
, pos
->offset
,
2466 bt_byte_order_string(native_byte_order
));
2467 BT_LOGV_STR("Serializing enumeration field's payload field.");
2468 return bt_field_serialize(enumeration
->payload
, pos
,
2473 int bt_field_floating_point_serialize(struct bt_field
*field
,
2474 struct bt_stream_pos
*pos
,
2475 enum bt_byte_order native_byte_order
)
2478 struct bt_field_floating_point
*floating_point
= container_of(field
,
2479 struct bt_field_floating_point
, parent
);
2481 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64
", "
2482 "native-bo=%s", field
, pos
->offset
,
2483 bt_byte_order_string(native_byte_order
));
2485 if (!bt_field_generic_is_set(field
)) {
2486 BT_LOGW_STR("Field's payload is not set.");
2491 ret
= bt_field_floating_point_write(floating_point
, pos
,
2493 if (ret
== -EFAULT
) {
2495 * The field is too large to fit in the current packet's
2496 * remaining space. Bump the packet size and retry.
2498 ret
= increase_packet_size(pos
);
2500 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
2510 int bt_field_structure_serialize(struct bt_field
*field
,
2511 struct bt_stream_pos
*pos
,
2512 enum bt_byte_order native_byte_order
)
2516 struct bt_field_structure
*structure
= container_of(
2517 field
, struct bt_field_structure
, parent
);
2519 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64
", "
2520 "native-bo=%s", field
, pos
->offset
,
2521 bt_byte_order_string(native_byte_order
));
2523 while (!bt_stream_pos_access_ok(pos
,
2524 offset_align(pos
->offset
, field
->type
->alignment
))) {
2525 ret
= increase_packet_size(pos
);
2527 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
2532 if (!bt_stream_pos_align(pos
, field
->type
->alignment
)) {
2533 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64
", "
2534 "align=%u", pos
->offset
, field
->type
->alignment
);
2539 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2540 struct bt_field
*member
= g_ptr_array_index(
2541 structure
->fields
, i
);
2542 const char *field_name
= NULL
;
2544 if (BT_LOG_ON_WARN
) {
2545 ret
= bt_field_type_structure_get_field_by_index(
2546 field
->type
, &field_name
, NULL
, i
);
2550 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64
", "
2551 "field-addr=%p, index=%" PRId64
,
2552 pos
->offset
, member
, i
);
2555 BT_LOGW("Cannot serialize structure field's field: field is not set: "
2556 "struct-field-addr=%p, "
2557 "field-name=\"%s\", index=%" PRId64
,
2558 field
, field_name
, i
);
2563 ret
= bt_field_serialize(member
, pos
, native_byte_order
);
2565 BT_LOGW("Cannot serialize structure field's field: "
2566 "struct-field-addr=%p, field-addr=%p, "
2567 "field-name=\"%s\", index=%" PRId64
,
2568 field
->type
, member
, field_name
, i
);
2577 int bt_field_variant_serialize(struct bt_field
*field
,
2578 struct bt_stream_pos
*pos
,
2579 enum bt_byte_order native_byte_order
)
2581 struct bt_field_variant
*variant
= container_of(
2582 field
, struct bt_field_variant
, parent
);
2584 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64
", "
2585 "native-bo=%s", field
, pos
->offset
,
2586 bt_byte_order_string(native_byte_order
));
2587 BT_LOGV_STR("Serializing variant field's payload field.");
2588 return bt_field_serialize(variant
->payload
, pos
,
2593 int bt_field_array_serialize(struct bt_field
*field
,
2594 struct bt_stream_pos
*pos
,
2595 enum bt_byte_order native_byte_order
)
2599 struct bt_field_array
*array
= container_of(
2600 field
, struct bt_field_array
, parent
);
2602 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64
", "
2603 "native-bo=%s", field
, pos
->offset
,
2604 bt_byte_order_string(native_byte_order
));
2606 for (i
= 0; i
< array
->elements
->len
; i
++) {
2607 struct bt_field
*elem_field
=
2608 g_ptr_array_index(array
->elements
, i
);
2610 BT_LOGV("Serializing array field's element field: "
2611 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
2612 pos
->offset
, elem_field
, i
);
2613 ret
= bt_field_serialize(elem_field
, pos
,
2616 BT_LOGW("Cannot serialize array field's element field: "
2617 "array-field-addr=%p, field-addr=%p, "
2618 "index=%" PRId64
, field
, elem_field
, i
);
2627 int bt_field_sequence_serialize(struct bt_field
*field
,
2628 struct bt_stream_pos
*pos
,
2629 enum bt_byte_order native_byte_order
)
2633 struct bt_field_sequence
*sequence
= container_of(
2634 field
, struct bt_field_sequence
, parent
);
2636 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64
", "
2637 "native-bo=%s", field
, pos
->offset
,
2638 bt_byte_order_string(native_byte_order
));
2640 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
2641 struct bt_field
*elem_field
=
2642 g_ptr_array_index(sequence
->elements
, i
);
2644 BT_LOGV("Serializing sequence field's element field: "
2645 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
2646 pos
->offset
, elem_field
, i
);
2647 ret
= bt_field_serialize(elem_field
, pos
,
2650 BT_LOGW("Cannot serialize sequence field's element field: "
2651 "sequence-field-addr=%p, field-addr=%p, "
2652 "index=%" PRId64
, field
, elem_field
, i
);
2661 int bt_field_string_serialize(struct bt_field
*field
,
2662 struct bt_stream_pos
*pos
,
2663 enum bt_byte_order native_byte_order
)
2667 struct bt_field_string
*string
= container_of(field
,
2668 struct bt_field_string
, parent
);
2669 struct bt_field_type
*character_type
=
2670 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
2671 struct bt_field
*character
;
2673 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64
", "
2674 "native-bo=%s", field
, pos
->offset
,
2675 bt_byte_order_string(native_byte_order
));
2677 BT_LOGV_STR("Creating character field from string field's character field type.");
2678 character
= bt_field_create(character_type
);
2680 for (i
= 0; i
< string
->payload
->len
+ 1; i
++) {
2681 const uint64_t chr
= (uint64_t) string
->payload
->str
[i
];
2683 ret
= bt_field_unsigned_integer_set_value(character
, chr
);
2685 BT_LOGW("Cannot set character field's value: "
2686 "pos-offset=%" PRId64
", field-addr=%p, "
2687 "index=%" PRId64
", char-int=%" PRIu64
,
2688 pos
->offset
, character
, i
, chr
);
2692 BT_LOGV("Serializing string field's character field: "
2693 "pos-offset=%" PRId64
", field-addr=%p, "
2694 "index=%" PRId64
", char-int=%" PRIu64
,
2695 pos
->offset
, character
, i
, chr
);
2696 ret
= bt_field_integer_serialize(character
, pos
,
2699 BT_LOGW_STR("Cannot serialize character field.");
2705 bt_put(character_type
);
2710 int bt_field_integer_copy(struct bt_field
*src
,
2711 struct bt_field
*dst
)
2713 struct bt_field_integer
*integer_src
, *integer_dst
;
2715 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
2717 integer_src
= container_of(src
, struct bt_field_integer
, parent
);
2718 integer_dst
= container_of(dst
, struct bt_field_integer
, parent
);
2719 integer_dst
->payload
= integer_src
->payload
;
2720 BT_LOGD_STR("Copied integer field.");
2725 int bt_field_enumeration_copy(struct bt_field
*src
,
2726 struct bt_field
*dst
)
2729 struct bt_field_enumeration
*enum_src
, *enum_dst
;
2731 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
2733 enum_src
= container_of(src
, struct bt_field_enumeration
, parent
);
2734 enum_dst
= container_of(dst
, struct bt_field_enumeration
, parent
);
2736 if (enum_src
->payload
) {
2737 BT_LOGD_STR("Copying enumeration field's payload field.");
2738 enum_dst
->payload
= bt_field_copy(enum_src
->payload
);
2739 if (!enum_dst
->payload
) {
2740 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
2746 BT_LOGD_STR("Copied enumeration field.");
2752 int bt_field_floating_point_copy(
2753 struct bt_field
*src
, struct bt_field
*dst
)
2755 struct bt_field_floating_point
*float_src
, *float_dst
;
2757 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2759 float_src
= container_of(src
, struct bt_field_floating_point
,
2761 float_dst
= container_of(dst
, struct bt_field_floating_point
,
2763 float_dst
->payload
= float_src
->payload
;
2764 BT_LOGD_STR("Copied floating point number field.");
2769 int bt_field_structure_copy(struct bt_field
*src
,
2770 struct bt_field
*dst
)
2774 struct bt_field_structure
*struct_src
, *struct_dst
;
2776 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2778 struct_src
= container_of(src
, struct bt_field_structure
, parent
);
2779 struct_dst
= container_of(dst
, struct bt_field_structure
, parent
);
2781 g_ptr_array_set_size(struct_dst
->fields
, struct_src
->fields
->len
);
2783 for (i
= 0; i
< struct_src
->fields
->len
; i
++) {
2784 struct bt_field
*field
=
2785 g_ptr_array_index(struct_src
->fields
, i
);
2786 struct bt_field
*field_copy
= NULL
;
2789 BT_LOGD("Copying structure field's field: src-field-addr=%p"
2790 "index=%" PRId64
, field
, i
);
2791 field_copy
= bt_field_copy(field
);
2793 BT_LOGE("Cannot copy structure field's field: "
2794 "src-field-addr=%p, index=%" PRId64
,
2801 BT_MOVE(g_ptr_array_index(struct_dst
->fields
, i
), field_copy
);
2804 BT_LOGD_STR("Copied structure field.");
2811 int bt_field_variant_copy(struct bt_field
*src
,
2812 struct bt_field
*dst
)
2815 struct bt_field_variant
*variant_src
, *variant_dst
;
2817 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2819 variant_src
= container_of(src
, struct bt_field_variant
, parent
);
2820 variant_dst
= container_of(dst
, struct bt_field_variant
, parent
);
2822 if (variant_src
->tag
) {
2823 BT_LOGD_STR("Copying variant field's tag field.");
2824 variant_dst
->tag
= bt_field_copy(variant_src
->tag
);
2825 if (!variant_dst
->tag
) {
2826 BT_LOGE_STR("Cannot copy variant field's tag field.");
2831 if (variant_src
->payload
) {
2832 BT_LOGD_STR("Copying variant field's payload field.");
2833 variant_dst
->payload
= bt_field_copy(variant_src
->payload
);
2834 if (!variant_dst
->payload
) {
2835 BT_LOGE_STR("Cannot copy variant field's payload field.");
2841 BT_LOGD_STR("Copied variant field.");
2848 int bt_field_array_copy(struct bt_field
*src
,
2849 struct bt_field
*dst
)
2853 struct bt_field_array
*array_src
, *array_dst
;
2855 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2857 array_src
= container_of(src
, struct bt_field_array
, parent
);
2858 array_dst
= container_of(dst
, struct bt_field_array
, parent
);
2860 g_ptr_array_set_size(array_dst
->elements
, array_src
->elements
->len
);
2861 for (i
= 0; i
< array_src
->elements
->len
; i
++) {
2862 struct bt_field
*field
=
2863 g_ptr_array_index(array_src
->elements
, i
);
2864 struct bt_field
*field_copy
= NULL
;
2867 BT_LOGD("Copying array field's element field: field-addr=%p, "
2868 "index=%" PRId64
, field
, i
);
2869 field_copy
= bt_field_copy(field
);
2871 BT_LOGE("Cannot copy array field's element field: "
2872 "src-field-addr=%p, index=%" PRId64
,
2879 g_ptr_array_index(array_dst
->elements
, i
) = field_copy
;
2882 BT_LOGD_STR("Copied array field.");
2889 int bt_field_sequence_copy(struct bt_field
*src
,
2890 struct bt_field
*dst
)
2894 struct bt_field_sequence
*sequence_src
, *sequence_dst
;
2895 struct bt_field
*src_length
;
2896 struct bt_field
*dst_length
;
2898 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2900 sequence_src
= container_of(src
, struct bt_field_sequence
, parent
);
2901 sequence_dst
= container_of(dst
, struct bt_field_sequence
, parent
);
2903 src_length
= bt_field_sequence_get_length(src
);
2905 /* no length set yet: keep destination sequence empty */
2909 /* copy source length */
2910 BT_LOGD_STR("Copying sequence field's length field.");
2911 dst_length
= bt_field_copy(src_length
);
2914 BT_LOGE_STR("Cannot copy sequence field's length field.");
2919 /* this will initialize the destination sequence's internal array */
2920 ret
= bt_field_sequence_set_length(dst
, dst_length
);
2923 BT_LOGE("Cannot set sequence field copy's length field: "
2924 "dst-length-field-addr=%p", dst_length
);
2929 assert(sequence_dst
->elements
->len
== sequence_src
->elements
->len
);
2931 for (i
= 0; i
< sequence_src
->elements
->len
; i
++) {
2932 struct bt_field
*field
=
2933 g_ptr_array_index(sequence_src
->elements
, i
);
2934 struct bt_field
*field_copy
= NULL
;
2937 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2938 "index=%" PRId64
, field
, i
);
2939 field_copy
= bt_field_copy(field
);
2941 BT_LOGE("Cannot copy sequence field's element field: "
2942 "src-field-addr=%p, index=%" PRId64
,
2949 g_ptr_array_index(sequence_dst
->elements
, i
) = field_copy
;
2952 BT_LOGD_STR("Copied sequence field.");
2959 int bt_field_string_copy(struct bt_field
*src
,
2960 struct bt_field
*dst
)
2963 struct bt_field_string
*string_src
, *string_dst
;
2965 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
2967 string_src
= container_of(src
, struct bt_field_string
, parent
);
2968 string_dst
= container_of(dst
, struct bt_field_string
, parent
);
2970 if (string_src
->payload
) {
2971 string_dst
->payload
= g_string_new(string_src
->payload
->str
);
2972 if (!string_dst
->payload
) {
2973 BT_LOGE_STR("Failed to allocate a GString.");
2979 BT_LOGD_STR("Copied string field.");
2986 int increase_packet_size(struct bt_stream_pos
*pos
)
2991 BT_LOGV("Increasing packet size: pos-offset=%" PRId64
", "
2992 "cur-packet-size=%" PRIu64
,
2993 pos
->offset
, pos
->packet_size
);
2994 ret
= munmap_align(pos
->base_mma
);
2996 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
3001 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
3003 ret
= bt_posix_fallocate(pos
->fd
, pos
->mmap_offset
,
3004 pos
->packet_size
/ CHAR_BIT
);
3005 } while (ret
== EINTR
);
3007 BT_LOGE_ERRNO("Failed to preallocate memory space",
3014 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
3015 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
3016 if (pos
->base_mma
== MAP_FAILED
) {
3017 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
3022 BT_LOGV("Increased packet size: pos-offset=%" PRId64
", "
3023 "new-packet-size=%" PRIu64
,
3024 pos
->offset
, pos
->packet_size
);
3025 assert(pos
->packet_size
% 8 == 0);
3032 void generic_field_freeze(struct bt_field
*field
)
3034 field
->frozen
= true;
3038 void bt_field_enumeration_freeze(struct bt_field
*field
)
3040 struct bt_field_enumeration
*enum_field
=
3041 container_of(field
, struct bt_field_enumeration
, parent
);
3043 BT_LOGD("Freezing enumeration field object: addr=%p", field
);
3044 BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field
->payload
);
3045 bt_field_freeze(enum_field
->payload
);
3046 generic_field_freeze(field
);
3050 void bt_field_structure_freeze(struct bt_field
*field
)
3053 struct bt_field_structure
*structure_field
=
3054 container_of(field
, struct bt_field_structure
, parent
);
3056 BT_LOGD("Freezing structure field object: addr=%p", field
);
3058 for (i
= 0; i
< structure_field
->fields
->len
; i
++) {
3059 struct bt_field
*field
=
3060 g_ptr_array_index(structure_field
->fields
, i
);
3062 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64
,
3064 bt_field_freeze(field
);
3067 generic_field_freeze(field
);
3071 void bt_field_variant_freeze(struct bt_field
*field
)
3073 struct bt_field_variant
*variant_field
=
3074 container_of(field
, struct bt_field_variant
, parent
);
3076 BT_LOGD("Freezing variant field object: addr=%p", field
);
3077 BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field
->tag
);
3078 bt_field_freeze(variant_field
->tag
);
3079 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field
->payload
);
3080 bt_field_freeze(variant_field
->payload
);
3081 generic_field_freeze(field
);
3085 void bt_field_array_freeze(struct bt_field
*field
)
3088 struct bt_field_array
*array_field
=
3089 container_of(field
, struct bt_field_array
, parent
);
3091 BT_LOGD("Freezing array field object: addr=%p", field
);
3093 for (i
= 0; i
< array_field
->elements
->len
; i
++) {
3094 struct bt_field
*elem_field
=
3095 g_ptr_array_index(array_field
->elements
, i
);
3097 BT_LOGD("Freezing array field object's element field: "
3098 "element-field-addr=%p, index=%" PRId64
,
3100 bt_field_freeze(elem_field
);
3103 generic_field_freeze(field
);
3107 void bt_field_sequence_freeze(struct bt_field
*field
)
3110 struct bt_field_sequence
*sequence_field
=
3111 container_of(field
, struct bt_field_sequence
, parent
);
3113 BT_LOGD("Freezing sequence field object: addr=%p", field
);
3114 BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p",
3115 sequence_field
->length
);
3116 bt_field_freeze(sequence_field
->length
);
3118 for (i
= 0; i
< sequence_field
->elements
->len
; i
++) {
3119 struct bt_field
*elem_field
=
3120 g_ptr_array_index(sequence_field
->elements
, i
);
3122 BT_LOGD("Freezing sequence field object's element field: "
3123 "element-field-addr=%p, index=%" PRId64
,
3125 bt_field_freeze(elem_field
);
3128 generic_field_freeze(field
);
3132 void bt_field_freeze(struct bt_field
*field
)
3134 enum bt_field_type_id type_id
;
3140 if (field
->frozen
) {
3144 BT_LOGD("Freezing field object: addr=%p", field
);
3145 type_id
= bt_field_get_type_id(field
);
3146 assert(type_id
> BT_FIELD_TYPE_ID_UNKNOWN
&&
3147 type_id
< BT_FIELD_TYPE_ID_NR
);
3148 field_freeze_funcs
[type_id
](field
);
3154 bt_bool
bt_field_generic_is_set(struct bt_field
*field
)
3156 return field
&& field
->payload_set
;
3160 bt_bool
bt_field_enumeration_is_set(struct bt_field
*field
)
3162 bt_bool is_set
= BT_FALSE
;
3163 struct bt_field_enumeration
*enumeration
;
3169 enumeration
= container_of(field
, struct bt_field_enumeration
,
3171 if (!enumeration
->payload
) {
3175 is_set
= bt_field_is_set(enumeration
->payload
);
3181 bt_bool
bt_field_structure_is_set(struct bt_field
*field
)
3183 bt_bool is_set
= BT_FALSE
;
3185 struct bt_field_structure
*structure
;
3191 structure
= container_of(field
, struct bt_field_structure
, parent
);
3192 for (i
= 0; i
< structure
->fields
->len
; i
++) {
3193 is_set
= bt_field_is_set(
3194 structure
->fields
->pdata
[i
]);
3204 bt_bool
bt_field_variant_is_set(struct bt_field
*field
)
3206 bt_bool is_set
= BT_FALSE
;
3207 struct bt_field_variant
*variant
;
3213 variant
= container_of(field
, struct bt_field_variant
, parent
);
3214 is_set
= bt_field_is_set(variant
->payload
);
3220 bt_bool
bt_field_array_is_set(struct bt_field
*field
)
3223 bt_bool is_set
= BT_FALSE
;
3224 struct bt_field_array
*array
;
3230 array
= container_of(field
, struct bt_field_array
, parent
);
3231 for (i
= 0; i
< array
->elements
->len
; i
++) {
3232 is_set
= bt_field_is_set(array
->elements
->pdata
[i
]);
3242 bt_bool
bt_field_sequence_is_set(struct bt_field
*field
)
3245 bt_bool is_set
= BT_FALSE
;
3246 struct bt_field_sequence
*sequence
;
3252 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
3253 if (!sequence
->elements
) {
3257 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
3258 is_set
= bt_field_is_set(sequence
->elements
->pdata
[i
]);