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>
40 #include <babeltrace/assert-internal.h>
41 #include <babeltrace/assert-pre-internal.h>
45 struct bt_field
*bt_field_integer_create(struct bt_field_type
*);
47 struct bt_field
*bt_field_enumeration_create(struct bt_field_type
*);
49 struct bt_field
*bt_field_floating_point_create(struct bt_field_type
*);
51 struct bt_field
*bt_field_structure_create(struct bt_field_type
*);
53 struct bt_field
*bt_field_variant_create(struct bt_field_type
*);
55 struct bt_field
*bt_field_array_create(struct bt_field_type
*);
57 struct bt_field
*bt_field_sequence_create(struct bt_field_type
*);
59 struct bt_field
*bt_field_string_create(struct bt_field_type
*);
62 void bt_field_destroy(struct bt_object
*);
64 void bt_field_integer_destroy(struct bt_field
*);
66 void bt_field_enumeration_destroy_recursive(struct bt_field
*);
68 void bt_field_floating_point_destroy(struct bt_field
*);
70 void bt_field_structure_destroy_recursive(struct bt_field
*);
72 void bt_field_variant_destroy_recursive(struct bt_field
*);
74 void bt_field_array_destroy_recursive(struct bt_field
*);
76 void bt_field_sequence_destroy_recursive(struct bt_field
*);
78 void bt_field_string_destroy(struct bt_field
*);
81 int bt_field_generic_validate(struct bt_field
*);
83 int bt_field_structure_validate_recursive(struct bt_field
*);
85 int bt_field_variant_validate_recursive(struct bt_field
*);
87 int bt_field_enumeration_validate_recursive(struct bt_field
*);
89 int bt_field_array_validate_recursive(struct bt_field
*);
91 int bt_field_sequence_validate_recursive(struct bt_field
*);
94 void bt_field_generic_reset(struct bt_field
*);
96 void bt_field_structure_reset_recursive(struct bt_field
*);
98 void bt_field_variant_reset_recursive(struct bt_field
*);
100 void bt_field_enumeration_reset_recursive(struct bt_field
*);
102 void bt_field_array_reset_recursive(struct bt_field
*);
104 void bt_field_sequence_reset_recursive(struct bt_field
*);
106 void bt_field_string_reset_recursive(struct bt_field
*);
109 int bt_field_integer_serialize(struct bt_field
*,
110 struct bt_stream_pos
*, enum bt_byte_order
);
112 int bt_field_enumeration_serialize_recursive(struct bt_field
*,
113 struct bt_stream_pos
*, enum bt_byte_order
);
115 int bt_field_floating_point_serialize(struct bt_field
*,
116 struct bt_stream_pos
*, enum bt_byte_order
);
118 int bt_field_structure_serialize_recursive(struct bt_field
*,
119 struct bt_stream_pos
*, enum bt_byte_order
);
121 int bt_field_variant_serialize_recursive(struct bt_field
*,
122 struct bt_stream_pos
*, enum bt_byte_order
);
124 int bt_field_array_serialize_recursive(struct bt_field
*,
125 struct bt_stream_pos
*, enum bt_byte_order
);
127 int bt_field_sequence_serialize_recursive(struct bt_field
*,
128 struct bt_stream_pos
*, enum bt_byte_order
);
130 int bt_field_string_serialize(struct bt_field
*,
131 struct bt_stream_pos
*, enum bt_byte_order
);
134 int bt_field_integer_copy(struct bt_field
*, struct bt_field
*);
136 int bt_field_enumeration_copy_recursive(struct bt_field
*, struct bt_field
*);
138 int bt_field_floating_point_copy(struct bt_field
*, struct bt_field
*);
140 int bt_field_structure_copy_recursive(struct bt_field
*, struct bt_field
*);
142 int bt_field_variant_copy_recursive(struct bt_field
*, struct bt_field
*);
144 int bt_field_array_copy_recursive(struct bt_field
*, struct bt_field
*);
146 int bt_field_sequence_copy_recursive(struct bt_field
*, struct bt_field
*);
148 int bt_field_string_copy_recursive(struct bt_field
*, struct bt_field
*);
151 void generic_field_freeze(struct bt_field
*);
153 void bt_field_enumeration_freeze_recursive(struct bt_field
*);
155 void bt_field_structure_freeze_recursive(struct bt_field
*);
157 void bt_field_variant_freeze_recursive(struct bt_field
*);
159 void bt_field_array_freeze_recursive(struct bt_field
*);
161 void bt_field_sequence_freeze_recursive(struct bt_field
*);
164 bt_bool
bt_field_generic_is_set(struct bt_field
*);
166 bt_bool
bt_field_structure_is_set_recursive(struct bt_field
*);
168 bt_bool
bt_field_variant_is_set_recursive(struct bt_field
*);
170 bt_bool
bt_field_enumeration_is_set_recursive(struct bt_field
*);
172 bt_bool
bt_field_array_is_set_recursive(struct bt_field
*);
174 bt_bool
bt_field_sequence_is_set_recursive(struct bt_field
*);
177 int increase_packet_size(struct bt_stream_pos
*pos
);
180 struct bt_field
*(* const field_create_funcs
[])(struct bt_field_type
*) = {
181 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_create
,
182 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_create
,
183 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_floating_point_create
,
184 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_create
,
185 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_create
,
186 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_create
,
187 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_create
,
188 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_create
,
192 void (* const field_destroy_funcs
[])(struct bt_field
*) = {
193 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_destroy
,
194 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_destroy_recursive
,
195 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_floating_point_destroy
,
196 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_destroy_recursive
,
197 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_destroy_recursive
,
198 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_destroy_recursive
,
199 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_destroy_recursive
,
200 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_destroy
,
204 int (* const field_validate_funcs
[])(struct bt_field
*) = {
205 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_generic_validate
,
206 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_validate_recursive
,
207 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_generic_validate
,
208 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_validate_recursive
,
209 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_validate_recursive
,
210 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_validate_recursive
,
211 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_validate_recursive
,
212 [BT_FIELD_TYPE_ID_STRING
] = bt_field_generic_validate
,
216 void (* const field_reset_funcs
[])(struct bt_field
*) = {
217 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_generic_reset
,
218 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_reset_recursive
,
219 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_generic_reset
,
220 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_reset_recursive
,
221 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_reset_recursive
,
222 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_reset_recursive
,
223 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_reset_recursive
,
224 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_reset_recursive
,
228 int (* const field_serialize_funcs
[])(struct bt_field
*,
229 struct bt_stream_pos
*, enum bt_byte_order
) = {
230 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_serialize
,
231 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_serialize_recursive
,
232 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_floating_point_serialize
,
233 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_serialize_recursive
,
234 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_serialize_recursive
,
235 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_serialize_recursive
,
236 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_serialize_recursive
,
237 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_serialize
,
241 int (* const field_copy_funcs
[])(struct bt_field
*,
242 struct bt_field
*) = {
243 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_integer_copy
,
244 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_copy_recursive
,
245 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_floating_point_copy
,
246 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_copy_recursive
,
247 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_copy_recursive
,
248 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_copy_recursive
,
249 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_copy_recursive
,
250 [BT_FIELD_TYPE_ID_STRING
] = bt_field_string_copy_recursive
,
254 void (* const field_freeze_funcs
[])(struct bt_field
*) = {
255 [BT_FIELD_TYPE_ID_INTEGER
] = generic_field_freeze
,
256 [BT_FIELD_TYPE_ID_FLOAT
] = generic_field_freeze
,
257 [BT_FIELD_TYPE_ID_STRING
] = generic_field_freeze
,
258 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_freeze_recursive
,
259 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_freeze_recursive
,
260 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_freeze_recursive
,
261 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_freeze_recursive
,
262 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_freeze_recursive
,
266 bt_bool (* const field_is_set_funcs
[])(struct bt_field
*) = {
267 [BT_FIELD_TYPE_ID_INTEGER
] = bt_field_generic_is_set
,
268 [BT_FIELD_TYPE_ID_ENUM
] = bt_field_enumeration_is_set_recursive
,
269 [BT_FIELD_TYPE_ID_FLOAT
] = bt_field_generic_is_set
,
270 [BT_FIELD_TYPE_ID_STRUCT
] = bt_field_structure_is_set_recursive
,
271 [BT_FIELD_TYPE_ID_VARIANT
] = bt_field_variant_is_set_recursive
,
272 [BT_FIELD_TYPE_ID_ARRAY
] = bt_field_array_is_set_recursive
,
273 [BT_FIELD_TYPE_ID_SEQUENCE
] = bt_field_sequence_is_set_recursive
,
274 [BT_FIELD_TYPE_ID_STRING
] = bt_field_generic_is_set
,
278 static inline bool field_type_has_known_id(struct bt_field_type
*ft
)
280 return ft
->id
> BT_FIELD_TYPE_ID_UNKNOWN
||
281 ft
->id
< BT_FIELD_TYPE_ID_NR
;
284 #define BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(_field, _type_id, _name) \
285 BT_ASSERT_PRE((_field)->type->id == (_type_id), \
286 _name " has the wrong type ID: expected-type-id=%s, " \
287 "%![field-]+f", bt_field_type_id_string(_type_id), \
290 #define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name) \
291 BT_ASSERT_PRE(bt_field_is_set_recursive(_field), \
292 _name " is not set: %!+f", (_field))
294 #define BT_ASSERT_PRE_FIELD_HOT(_field, _name) \
295 BT_ASSERT_PRE_HOT((_field), (_name), ": +%!+f", (_field))
297 struct bt_field
*bt_field_create(struct bt_field_type
*type
)
299 struct bt_field
*field
= NULL
;
300 enum bt_field_type_id type_id
;
302 BT_ASSERT_PRE_NON_NULL(type
, "Field type");
303 BT_ASSERT(field_type_has_known_id(type
));
304 BT_ASSERT_PRE(bt_field_type_validate(type
) == 0,
305 "Field type is invalid: %!+F", type
);
307 type_id
= bt_field_type_get_type_id(type
);
308 field
= field_create_funcs
[type_id
](type
);
313 /* The type's declaration can't change after this point */
314 bt_field_type_freeze(type
);
316 bt_object_init(field
, bt_field_destroy
);
322 /* Pre-2.0 CTF writer backward compatibility */
323 void bt_ctf_field_get(struct bt_field
*field
)
328 /* Pre-2.0 CTF writer backward compatibility */
329 void bt_ctf_field_put(struct bt_field
*field
)
334 struct bt_field_type
*bt_field_get_type(struct bt_field
*field
)
336 struct bt_field_type
*ret
= NULL
;
338 BT_ASSERT_PRE_NON_NULL(field
, "Field");
344 enum bt_field_type_id
bt_field_get_type_id(struct bt_field
*field
)
346 BT_ASSERT_PRE_NON_NULL(field
, "Field");
347 return bt_field_type_get_type_id(field
->type
);
350 bt_bool
bt_field_is_integer(struct bt_field
*field
)
352 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_INTEGER
;
355 bt_bool
bt_field_is_floating_point(struct bt_field
*field
)
357 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_FLOAT
;
360 bt_bool
bt_field_is_enumeration(struct bt_field
*field
)
362 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_ENUM
;
365 bt_bool
bt_field_is_string(struct bt_field
*field
)
367 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_STRING
;
370 bt_bool
bt_field_is_structure(struct bt_field
*field
)
372 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_STRUCT
;
375 bt_bool
bt_field_is_array(struct bt_field
*field
)
377 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_ARRAY
;
380 bt_bool
bt_field_is_sequence(struct bt_field
*field
)
382 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_SEQUENCE
;
385 bt_bool
bt_field_is_variant(struct bt_field
*field
)
387 return bt_field_get_type_id(field
) == BT_FIELD_TYPE_ID_VARIANT
;
391 int64_t bt_field_sequence_get_int_length(struct bt_field
*field
)
393 struct bt_field_sequence
*sequence
;
397 BT_ASSERT(bt_field_type_get_type_id(field
->type
) ==
398 BT_FIELD_TYPE_ID_SEQUENCE
);
399 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
400 if (!sequence
->length
) {
405 ret
= (int64_t) sequence
->elements
->len
;
411 struct bt_field
*bt_field_sequence_get_length(
412 struct bt_field
*field
)
414 struct bt_field
*ret
= NULL
;
415 struct bt_field_sequence
*sequence
;
417 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
418 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_SEQUENCE
,
420 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
421 ret
= sequence
->length
;
426 int bt_field_sequence_set_length(struct bt_field
*field
,
427 struct bt_field
*length_field
)
430 struct bt_field_integer
*length
;
431 struct bt_field_sequence
*sequence
;
432 uint64_t sequence_length
;
434 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
435 BT_ASSERT_PRE_NON_NULL(length_field
, "Length field");
436 BT_ASSERT_PRE_FIELD_HOT(field
, "Sequence field");
437 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(length_field
, BT_FIELD_TYPE_ID_INTEGER
,
439 BT_ASSERT_PRE(!bt_field_type_integer_is_signed(length_field
->type
),
440 "Length field's type is signed: %!+f", length_field
);
441 BT_ASSERT_PRE_FIELD_IS_SET(length_field
, "Length field");
443 length
= container_of(length_field
, struct bt_field_integer
,
445 sequence_length
= length
->payload
.unsignd
;
446 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
447 if (sequence
->elements
) {
448 g_ptr_array_free(sequence
->elements
, TRUE
);
449 bt_put(sequence
->length
);
452 sequence
->elements
= g_ptr_array_sized_new((size_t) sequence_length
);
453 if (!sequence
->elements
) {
454 BT_LOGE_STR("Failed to allocate a GPtrArray.");
459 g_ptr_array_set_free_func(sequence
->elements
,
460 (GDestroyNotify
) bt_put
);
461 g_ptr_array_set_size(sequence
->elements
, (size_t) sequence_length
);
462 bt_get(length_field
);
463 sequence
->length
= length_field
;
464 bt_field_freeze_recursive(length_field
);
470 struct bt_field
*bt_field_structure_get_field_by_name(
471 struct bt_field
*field
, const char *name
)
473 struct bt_field
*ret
= NULL
;
475 struct bt_field_structure
*structure
;
477 GHashTable
*field_name_to_index
;
479 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
480 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
481 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRUCT
, "Field");
482 field_name_to_index
=
483 container_of(field
->type
, struct bt_field_type_structure
,
484 parent
)->field_name_to_index
;
485 field_quark
= g_quark_from_string(name
);
486 structure
= container_of(field
, struct bt_field_structure
, parent
);
487 if (!g_hash_table_lookup_extended(field_name_to_index
,
488 GUINT_TO_POINTER(field_quark
),
489 NULL
, (gpointer
*)&index
)) {
490 BT_LOGV("Invalid parameter: no such field in structure field's type: "
491 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
492 field
, field
->type
, name
);
496 ret
= bt_get(structure
->fields
->pdata
[index
]);
503 struct bt_field
*bt_field_structure_get_field_by_index(
504 struct bt_field
*field
, uint64_t index
)
506 struct bt_field_structure
*structure
;
507 struct bt_field
*ret
= NULL
;
509 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
510 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRUCT
, "Field");
511 structure
= container_of(field
, struct bt_field_structure
, parent
);
512 BT_ASSERT_PRE(index
< structure
->fields
->len
,
513 "Index is out of bound: %![struct-field-]+f, "
514 "index=%" PRIu64
", count=%u", field
, index
,
515 structure
->fields
->len
);
516 ret
= bt_get(structure
->fields
->pdata
[index
]);
521 static inline bool field_to_set_has_expected_type(struct bt_field
*struct_field
,
522 const char *name
, struct bt_field
*value
)
525 struct bt_field_type
*expected_field_type
= NULL
;
527 expected_field_type
=
528 bt_field_type_structure_get_field_type_by_name(
529 struct_field
->type
, name
);
531 if (bt_field_type_compare(expected_field_type
, value
->type
)) {
532 BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
533 "%![value-ft-]+F, %![expected-ft-]+F", value
->type
,
534 expected_field_type
);
540 bt_put(expected_field_type
);
544 int bt_field_structure_set_field_by_name(struct bt_field
*field
,
545 const char *name
, struct bt_field
*value
)
549 struct bt_field_structure
*structure
;
551 GHashTable
*field_name_to_index
;
553 BT_ASSERT_PRE_NON_NULL(field
, "Structure field");
554 BT_ASSERT_PRE_NON_NULL(name
, "Field name");
555 BT_ASSERT_PRE_NON_NULL(value
, "Value field");
556 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRUCT
,
558 BT_ASSERT_PRE(field_to_set_has_expected_type(field
, name
, value
),
559 "Value field's type is different from the expected field type.");
560 field_quark
= g_quark_from_string(name
);
561 structure
= container_of(field
, struct bt_field_structure
, parent
);
562 field_name_to_index
=
563 container_of(field
->type
, struct bt_field_type_structure
,
564 parent
)->field_name_to_index
;
565 if (!g_hash_table_lookup_extended(field_name_to_index
,
566 GUINT_TO_POINTER(field_quark
), NULL
,
567 (gpointer
*) &index
)) {
568 BT_LOGV("Invalid parameter: no such field in structure field's type: "
569 "struct-field-addr=%p, struct-ft-addr=%p, "
570 "field-ft-addr=%p, name=\"%s\"",
571 field
, field
->type
, value
->type
, name
);
576 BT_MOVE(structure
->fields
->pdata
[index
], value
);
582 struct bt_field
*bt_field_array_get_field(struct bt_field
*field
,
585 struct bt_field
*new_field
= NULL
;
586 struct bt_field_type
*field_type
= NULL
;
587 struct bt_field_array
*array
;
589 BT_ASSERT_PRE_NON_NULL(field
, "Array field");
590 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_ARRAY
, "Field");
591 array
= container_of(field
, struct bt_field_array
, parent
);
592 BT_ASSERT_PRE(index
< array
->elements
->len
,
593 "Index is out of bound: %![array-field-]+f, "
594 "index=%" PRIu64
", count=%u", field
,
595 index
, array
->elements
->len
);
597 field_type
= bt_field_type_array_get_element_type(field
->type
);
598 if (array
->elements
->pdata
[(size_t) index
]) {
599 new_field
= array
->elements
->pdata
[(size_t) index
];
603 /* We don't want to modify this field if it's frozen */
604 BT_ASSERT_PRE_FIELD_HOT(field
, "Array field");
605 new_field
= bt_field_create(field_type
);
606 array
->elements
->pdata
[(size_t)index
] = new_field
;
614 struct bt_field
*bt_field_sequence_get_field(struct bt_field
*field
,
617 struct bt_field
*new_field
= NULL
;
618 struct bt_field_type
*field_type
= NULL
;
619 struct bt_field_sequence
*sequence
;
621 BT_ASSERT_PRE_NON_NULL(field
, "Sequence field");
622 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_SEQUENCE
,
624 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
625 BT_ASSERT_PRE_NON_NULL(sequence
->elements
, "Sequence field's element array");
626 BT_ASSERT_PRE(index
< sequence
->elements
->len
,
627 "Index is out of bound: %![seq-field-]+f, "
628 "index=%" PRIu64
", count=%u", field
, index
,
629 sequence
->elements
->len
);
630 field_type
= bt_field_type_sequence_get_element_type(field
->type
);
631 if (sequence
->elements
->pdata
[(size_t) index
]) {
632 new_field
= sequence
->elements
->pdata
[(size_t) index
];
636 /* We don't want to modify this field if it's frozen */
637 BT_ASSERT_PRE_FIELD_HOT(field
, "Sequence field");
638 new_field
= bt_field_create(field_type
);
639 sequence
->elements
->pdata
[(size_t) index
] = new_field
;
647 struct bt_field
*bt_field_variant_get_field(struct bt_field
*field
,
648 struct bt_field
*tag_field
)
650 struct bt_field
*new_field
= NULL
;
651 struct bt_field_variant
*variant
;
652 struct bt_field_type_variant
*variant_type
;
653 struct bt_field_type
*field_type
;
654 struct bt_field
*tag_enum
= NULL
;
655 struct bt_field_integer
*tag_enum_integer
;
656 int64_t tag_enum_value
;
658 BT_ASSERT_PRE_NON_NULL(field
, "Variant field");
659 BT_ASSERT_PRE_NON_NULL(tag_field
, "Tag field");
660 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_VARIANT
,
662 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(tag_field
, BT_FIELD_TYPE_ID_ENUM
,
664 variant
= container_of(field
, struct bt_field_variant
, parent
);
665 variant_type
= container_of(field
->type
,
666 struct bt_field_type_variant
, parent
);
667 tag_enum
= bt_field_enumeration_get_container(tag_field
);
668 BT_ASSERT_PRE_NON_NULL(tag_enum
, "Tag field's container");
669 tag_enum_integer
= container_of(tag_enum
, struct bt_field_integer
,
671 BT_ASSERT_PRE(bt_field_validate_recursive(tag_field
) == 0,
672 "Tag field is invalid: %!+f", tag_field
);
673 tag_enum_value
= tag_enum_integer
->payload
.signd
;
676 * If the variant currently has a tag and a payload, and if the
677 * requested tag value is the same as the current one, return
678 * the current payload instead of creating a fresh one.
680 if (variant
->tag
&& variant
->payload
) {
681 struct bt_field
*cur_tag_container
= NULL
;
682 struct bt_field_integer
*cur_tag_enum_integer
;
683 int64_t cur_tag_value
;
686 bt_field_enumeration_get_container(variant
->tag
);
687 BT_ASSERT(cur_tag_container
);
688 cur_tag_enum_integer
= container_of(cur_tag_container
,
689 struct bt_field_integer
, parent
);
690 bt_put(cur_tag_container
);
691 cur_tag_value
= cur_tag_enum_integer
->payload
.signd
;
693 if (cur_tag_value
== tag_enum_value
) {
694 new_field
= variant
->payload
;
700 /* We don't want to modify this field if it's frozen */
701 BT_ASSERT_PRE_FIELD_HOT(field
, "Variant field");
702 field_type
= bt_field_type_variant_get_field_type_signed(
703 variant_type
, tag_enum_value
);
705 /* It's the caller's job to make sure the tag's value is valid */
706 BT_ASSERT_PRE(field_type
,
707 "Variant field's type does not contain a field type for "
708 "this tag value: tag-value-signed=%" PRId64
", "
709 "%![var-ft-]+F, %![tag-field-]+f", tag_enum_value
,
710 variant_type
, tag_field
);
712 new_field
= bt_field_create(field_type
);
714 BT_LOGW("Cannot create field: "
715 "variant-field-addr=%p, variant-ft-addr=%p, "
716 "field-ft-addr=%p", field
, field
->type
, field_type
);
720 bt_put(variant
->tag
);
721 bt_put(variant
->payload
);
724 variant
->tag
= tag_field
;
725 variant
->payload
= new_field
;
732 struct bt_field
*bt_field_variant_get_current_field(
733 struct bt_field
*variant_field
)
735 struct bt_field_variant
*variant
;
737 BT_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
738 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(variant_field
, BT_FIELD_TYPE_ID_VARIANT
,
740 variant
= container_of(variant_field
, struct bt_field_variant
,
742 return bt_get(variant
->payload
);
745 struct bt_field
*bt_field_variant_get_tag(struct bt_field
*variant_field
)
747 struct bt_field_variant
*variant
;
749 BT_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
750 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(variant_field
, BT_FIELD_TYPE_ID_VARIANT
,
752 variant
= container_of(variant_field
, struct bt_field_variant
,
754 return bt_get(variant
->tag
);
757 struct bt_field
*bt_field_enumeration_get_container(struct bt_field
*field
)
759 struct bt_field
*container
= NULL
;
760 struct bt_field_enumeration
*enumeration
;
762 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
763 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_ENUM
, "Field");
764 enumeration
= container_of(field
, struct bt_field_enumeration
,
766 if (!enumeration
->payload
) {
767 struct bt_field_type_enumeration
*enumeration_type
;
769 /* We don't want to modify this field if it's frozen */
770 BT_ASSERT_PRE_FIELD_HOT(field
, "Enumeration field");
772 enumeration_type
= container_of(field
->type
,
773 struct bt_field_type_enumeration
, parent
);
774 enumeration
->payload
=
775 bt_field_create(enumeration_type
->container
);
778 container
= enumeration
->payload
;
779 return bt_get(container
);
782 struct bt_field_type_enumeration_mapping_iterator
*
783 bt_field_enumeration_get_mappings(struct bt_field
*field
)
786 struct bt_field
*container
= NULL
;
787 struct bt_field_type_integer
*integer_type
= NULL
;
788 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
790 BT_ASSERT_PRE_NON_NULL(field
, "Enumeration field");
791 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_ENUM
, "Field");
792 container
= bt_field_enumeration_get_container(field
);
793 BT_ASSERT_PRE(container
,
794 "Enumeration field has no container field: %!+f", field
);
795 BT_ASSERT(container
->type
);
796 integer_type
= container_of(container
->type
,
797 struct bt_field_type_integer
, parent
);
798 BT_ASSERT_PRE_FIELD_IS_SET(container
,
799 "Enumeration field's payload field");
801 if (!integer_type
->is_signed
) {
804 ret
= bt_field_unsigned_integer_get_value(container
, &value
);
806 iter
= bt_field_type_enumeration_find_mappings_by_unsigned_value(
811 ret
= bt_field_signed_integer_get_value(container
, &value
);
813 iter
= bt_field_type_enumeration_find_mappings_by_signed_value(
821 int bt_field_signed_integer_get_value(struct bt_field
*field
, int64_t *value
)
823 struct bt_field_integer
*integer
;
824 struct bt_field_type_integer
*integer_type
;
826 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
827 BT_ASSERT_PRE_NON_NULL(value
, "Value");
828 BT_ASSERT_PRE_FIELD_IS_SET(field
, "Integer field");
829 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_INTEGER
, "Field");
830 integer_type
= container_of(field
->type
,
831 struct bt_field_type_integer
, parent
);
832 BT_ASSERT_PRE(bt_field_type_integer_is_signed(field
->type
),
833 "Field's type is unsigned: %!+f", field
);
834 integer
= container_of(field
,
835 struct bt_field_integer
, parent
);
836 *value
= integer
->payload
.signd
;
841 static inline bool value_is_in_range_signed(unsigned int size
, int64_t value
)
844 int64_t min_value
, max_value
;
846 min_value
= -(1ULL << (size
- 1));
847 max_value
= (1ULL << (size
- 1)) - 1;
848 if (value
< min_value
|| value
> max_value
) {
849 BT_LOGF("Value is out of bounds: value=%" PRId64
", "
850 "min-value=%" PRId64
", max-value=%" PRId64
,
851 value
, min_value
, max_value
);
858 int bt_field_signed_integer_set_value(struct bt_field
*field
, int64_t value
)
861 struct bt_field_integer
*integer
;
862 struct bt_field_type_integer
*integer_type
;
864 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
865 BT_ASSERT_PRE_FIELD_HOT(field
, "Integer field");
866 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_INTEGER
, "Field");
867 integer
= container_of(field
, struct bt_field_integer
, parent
);
868 integer_type
= container_of(field
->type
,
869 struct bt_field_type_integer
, parent
);
870 BT_ASSERT_PRE(bt_field_type_integer_is_signed(field
->type
),
871 "Field's type is unsigned: %!+f", field
);
872 BT_ASSERT_PRE(value_is_in_range_signed(integer_type
->size
, value
),
873 "Value is out of bounds: value=%" PRId64
", %![field-]+f",
875 integer
->payload
.signd
= value
;
876 bt_field_set(field
, true);
880 int bt_field_unsigned_integer_get_value(struct bt_field
*field
, uint64_t *value
)
882 struct bt_field_integer
*integer
;
883 struct bt_field_type_integer
*integer_type
;
885 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
886 BT_ASSERT_PRE_NON_NULL(value
, "Value");
887 BT_ASSERT_PRE_FIELD_IS_SET(field
, "Integer field");
888 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_INTEGER
, "Field");
889 integer_type
= container_of(field
->type
,
890 struct bt_field_type_integer
, parent
);
891 BT_ASSERT_PRE(!bt_field_type_integer_is_signed(field
->type
),
892 "Field's type is signed: %!+f", field
);
893 integer
= container_of(field
, struct bt_field_integer
, parent
);
894 *value
= integer
->payload
.unsignd
;
899 static inline bool value_is_in_range_unsigned(unsigned int size
, uint64_t value
)
904 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t) 1 << size
) - 1;
905 if (value
> max_value
) {
906 BT_LOGF("Value is out of bounds: value=%" PRIu64
", "
907 "max-value=%" PRIu64
,
915 int bt_field_unsigned_integer_set_value(struct bt_field
*field
, uint64_t value
)
917 struct bt_field_integer
*integer
;
918 struct bt_field_type_integer
*integer_type
;
920 BT_ASSERT_PRE_NON_NULL(field
, "Integer field");
921 BT_ASSERT_PRE_FIELD_HOT(field
, "Integer field");
922 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_INTEGER
, "Field");
923 integer
= container_of(field
, struct bt_field_integer
, parent
);
924 integer_type
= container_of(field
->type
,
925 struct bt_field_type_integer
, parent
);
926 BT_ASSERT_PRE(!bt_field_type_integer_is_signed(field
->type
),
927 "Field's type is signed: %!+f", field
);
928 BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type
->size
, value
),
929 "Value is out of bounds: value=%" PRIu64
", %![field-]+f",
931 integer
->payload
.unsignd
= value
;
932 bt_field_set(field
, true);
936 int bt_field_floating_point_get_value(struct bt_field
*field
, double *value
)
938 struct bt_field_floating_point
*floating_point
;
940 BT_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
941 BT_ASSERT_PRE_NON_NULL(value
, "Value");
942 BT_ASSERT_PRE_FIELD_IS_SET(field
, "Floating point number field");
943 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_FLOAT
, "Field");
944 floating_point
= container_of(field
,
945 struct bt_field_floating_point
, parent
);
946 *value
= floating_point
->payload
;
950 int bt_field_floating_point_set_value(struct bt_field
*field
, double value
)
952 struct bt_field_floating_point
*floating_point
;
954 BT_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
955 BT_ASSERT_PRE_FIELD_HOT(field
, "Floating point number field");
956 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_FLOAT
, "Field");
957 floating_point
= container_of(field
, struct bt_field_floating_point
,
959 floating_point
->payload
= value
;
960 bt_field_set(field
, true);
964 const char *bt_field_string_get_value(struct bt_field
*field
)
966 struct bt_field_string
*string
;
968 BT_ASSERT_PRE_NON_NULL(field
, "String field");
969 BT_ASSERT_PRE_FIELD_IS_SET(field
, "String field");
970 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRING
, "Field");
971 string
= container_of(field
, struct bt_field_string
, parent
);
972 return string
->payload
->str
;
975 int bt_field_string_set_value(struct bt_field
*field
, const char *value
)
977 struct bt_field_string
*string
;
979 BT_ASSERT_PRE_NON_NULL(field
, "String field");
980 BT_ASSERT_PRE_NON_NULL(value
, "Value");
981 BT_ASSERT_PRE_FIELD_HOT(field
, "String field");
982 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRING
, "Field");
983 string
= container_of(field
, struct bt_field_string
, parent
);
984 if (string
->payload
) {
985 g_string_assign(string
->payload
, value
);
987 string
->payload
= g_string_new(value
);
990 bt_field_set(field
, true);
994 int bt_field_string_append(struct bt_field
*field
, const char *value
)
996 struct bt_field_string
*string_field
;
998 BT_ASSERT_PRE_NON_NULL(field
, "String field");
999 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1000 BT_ASSERT_PRE_FIELD_HOT(field
, "String field");
1001 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRING
, "Field");
1002 string_field
= container_of(field
, struct bt_field_string
, parent
);
1003 if (string_field
->payload
) {
1004 g_string_append(string_field
->payload
, value
);
1006 string_field
->payload
= g_string_new(value
);
1009 bt_field_set(field
, true);
1013 int bt_field_string_append_len(struct bt_field
*field
, const char *value
,
1014 unsigned int length
)
1016 struct bt_field_string
*string_field
;
1018 BT_ASSERT_PRE_NON_NULL(field
, "String field");
1019 BT_ASSERT_PRE_NON_NULL(value
, "Value");
1020 BT_ASSERT_PRE_FIELD_HOT(field
, "String field");
1021 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field
, BT_FIELD_TYPE_ID_STRING
, "Field");
1022 string_field
= container_of(field
, struct bt_field_string
, parent
);
1024 /* make sure no null bytes are appended */
1025 BT_ASSERT_PRE(memchr(value
, '\0', length
) == NULL
,
1026 "String value to append contains a null character: "
1027 "partial-value=\"%.32s\", length=%u", value
, length
);
1029 if (string_field
->payload
) {
1030 g_string_append_len(string_field
->payload
, value
, length
);
1032 string_field
->payload
= g_string_new_len(value
, length
);
1035 bt_field_set(field
, true);
1040 int _bt_field_validate_recursive(struct bt_field
*field
)
1043 enum bt_field_type_id type_id
;
1046 BT_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
1051 BT_ASSERT(field_type_has_known_id(field
->type
));
1052 type_id
= bt_field_type_get_type_id(field
->type
);
1053 ret
= field_validate_funcs
[type_id
](field
);
1060 void _bt_field_reset_recursive(struct bt_field
*field
)
1062 field_reset_funcs
[field
->type
->id
](field
);
1066 void _bt_field_set(struct bt_field
*field
, bool value
)
1069 field
->payload_set
= value
;
1073 int bt_field_serialize_recursive(struct bt_field
*field
, struct bt_stream_pos
*pos
,
1074 enum bt_byte_order native_byte_order
)
1076 enum bt_field_type_id type_id
;
1079 BT_ASSERT_PRE_NON_NULL(field
, "Field");
1080 BT_ASSERT(field_type_has_known_id(field
->type
));
1081 type_id
= bt_field_type_get_type_id(field
->type
);
1082 return field_serialize_funcs
[type_id
](field
, pos
, native_byte_order
);
1086 bt_bool
_bt_field_is_set_recursive(struct bt_field
*field
)
1088 bt_bool is_set
= BT_FALSE
;
1089 enum bt_field_type_id type_id
;
1095 BT_ASSERT(field_type_has_known_id(field
->type
));
1096 type_id
= bt_field_type_get_type_id(field
->type
);
1097 is_set
= field_is_set_funcs
[type_id
](field
);
1103 struct bt_field
*bt_field_copy(struct bt_field
*field
)
1106 struct bt_field
*copy
= NULL
;
1107 enum bt_field_type_id type_id
;
1109 BT_ASSERT_PRE_NON_NULL(field
, "Field");
1110 BT_ASSERT(field_type_has_known_id(field
->type
));
1111 copy
= bt_field_create(field
->type
);
1113 BT_LOGW("Cannot create field: ft-addr=%p", field
->type
);
1117 bt_field_set(copy
, field
->payload_set
);
1118 type_id
= bt_field_type_get_type_id(field
->type
);
1119 ret
= field_copy_funcs
[type_id
](field
, copy
);
1129 struct bt_field
*bt_field_integer_create(struct bt_field_type
*type
)
1131 struct bt_field_integer
*integer
= g_new0(
1132 struct bt_field_integer
, 1);
1134 BT_LOGD("Creating integer field object: ft-addr=%p", type
);
1137 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
1138 &integer
->parent
, type
);
1140 BT_LOGE_STR("Failed to allocate one integer field.");
1143 return integer
? &integer
->parent
: NULL
;
1147 struct bt_field
*bt_field_enumeration_create(
1148 struct bt_field_type
*type
)
1150 struct bt_field_enumeration
*enumeration
= g_new0(
1151 struct bt_field_enumeration
, 1);
1153 BT_LOGD("Creating enumeration field object: ft-addr=%p", type
);
1156 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
1157 &enumeration
->parent
, type
);
1159 BT_LOGE_STR("Failed to allocate one enumeration field.");
1162 return enumeration
? &enumeration
->parent
: NULL
;
1166 struct bt_field
*bt_field_floating_point_create(
1167 struct bt_field_type
*type
)
1169 struct bt_field_floating_point
*floating_point
;
1171 BT_LOGD("Creating floating point number field object: ft-addr=%p", type
);
1172 floating_point
= g_new0(struct bt_field_floating_point
, 1);
1174 if (floating_point
) {
1175 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
1176 &floating_point
->parent
, type
);
1178 BT_LOGE_STR("Failed to allocate one floating point number field.");
1181 return floating_point
? &floating_point
->parent
: NULL
;
1185 struct bt_field
*bt_field_structure_create(
1186 struct bt_field_type
*type
)
1188 struct bt_field_type_structure
*structure_type
= container_of(type
,
1189 struct bt_field_type_structure
, parent
);
1190 struct bt_field_structure
*structure
= g_new0(
1191 struct bt_field_structure
, 1);
1192 struct bt_field
*ret
= NULL
;
1195 BT_LOGD("Creating structure field object: ft-addr=%p", type
);
1198 BT_LOGE_STR("Failed to allocate one structure field.");
1202 structure
->fields
= g_ptr_array_new_with_free_func(
1203 (GDestroyNotify
) bt_put
);
1204 g_ptr_array_set_size(structure
->fields
,
1205 structure_type
->fields
->len
);
1207 /* Create all fields contained by the structure field. */
1208 for (i
= 0; i
< structure_type
->fields
->len
; i
++) {
1209 struct bt_field
*field
;
1210 struct structure_field
*field_type
=
1211 g_ptr_array_index(structure_type
->fields
, i
);
1213 field
= bt_field_create(field_type
->type
);
1215 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
1216 g_quark_to_string(field_type
->name
), i
);
1217 bt_field_structure_destroy_recursive(&structure
->parent
);
1221 g_ptr_array_index(structure
->fields
, i
) = field
;
1224 ret
= &structure
->parent
;
1225 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p", ret
,
1232 struct bt_field
*bt_field_variant_create(struct bt_field_type
*type
)
1234 struct bt_field_variant
*variant
= g_new0(
1235 struct bt_field_variant
, 1);
1237 BT_LOGD("Creating variant field object: ft-addr=%p", type
);
1240 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1241 &variant
->parent
, type
);
1243 BT_LOGE_STR("Failed to allocate one variant field.");
1246 return variant
? &variant
->parent
: NULL
;
1250 struct bt_field
*bt_field_array_create(struct bt_field_type
*type
)
1252 struct bt_field_array
*array
= g_new0(struct bt_field_array
, 1);
1253 struct bt_field_type_array
*array_type
;
1254 unsigned int array_length
;
1256 BT_LOGD("Creating array field object: ft-addr=%p", type
);
1260 BT_LOGE_STR("Failed to allocate one array field.");
1264 array_type
= container_of(type
, struct bt_field_type_array
, parent
);
1265 array_length
= array_type
->length
;
1266 array
->elements
= g_ptr_array_sized_new(array_length
);
1267 if (!array
->elements
) {
1271 g_ptr_array_set_free_func(array
->elements
,
1272 (GDestroyNotify
) bt_put
);
1273 g_ptr_array_set_size(array
->elements
, array_length
);
1274 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1275 &array
->parent
, type
);
1276 return &array
->parent
;
1283 struct bt_field
*bt_field_sequence_create(
1284 struct bt_field_type
*type
)
1286 struct bt_field_sequence
*sequence
= g_new0(
1287 struct bt_field_sequence
, 1);
1289 BT_LOGD("Creating sequence field object: ft-addr=%p", type
);
1292 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1293 &sequence
->parent
, type
);
1295 BT_LOGE_STR("Failed to allocate one sequence field.");
1298 return sequence
? &sequence
->parent
: NULL
;
1302 struct bt_field
*bt_field_string_create(struct bt_field_type
*type
)
1304 struct bt_field_string
*string
= g_new0(
1305 struct bt_field_string
, 1);
1307 BT_LOGD("Creating string field object: ft-addr=%p", type
);
1310 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1311 &string
->parent
, type
);
1313 BT_LOGE_STR("Failed to allocate one string field.");
1316 return string
? &string
->parent
: NULL
;
1320 void bt_field_destroy(struct bt_object
*obj
)
1322 struct bt_field
*field
;
1323 struct bt_field_type
*type
;
1324 enum bt_field_type_id type_id
;
1327 field
= container_of(obj
, struct bt_field
, base
);
1329 BT_ASSERT(field_type_has_known_id(type
));
1330 type_id
= bt_field_type_get_type_id(type
);
1331 field_destroy_funcs
[type_id
](field
);
1332 BT_LOGD_STR("Putting field's type.");
1337 void bt_field_integer_destroy(struct bt_field
*field
)
1339 struct bt_field_integer
*integer
;
1342 BT_LOGD("Destroying integer field object: addr=%p", field
);
1343 integer
= container_of(field
, struct bt_field_integer
, parent
);
1348 void bt_field_enumeration_destroy_recursive(struct bt_field
*field
)
1350 struct bt_field_enumeration
*enumeration
;
1353 BT_LOGD("Destroying enumeration field object: addr=%p", field
);
1354 enumeration
= container_of(field
, struct bt_field_enumeration
,
1356 BT_LOGD_STR("Putting payload field.");
1357 bt_put(enumeration
->payload
);
1358 g_free(enumeration
);
1362 void bt_field_floating_point_destroy(struct bt_field
*field
)
1364 struct bt_field_floating_point
*floating_point
;
1367 BT_LOGD("Destroying floating point number field object: addr=%p", field
);
1368 floating_point
= container_of(field
, struct bt_field_floating_point
,
1370 g_free(floating_point
);
1374 void bt_field_structure_destroy_recursive(struct bt_field
*field
)
1376 struct bt_field_structure
*structure
;
1379 BT_LOGD("Destroying structure field object: addr=%p", field
);
1380 structure
= container_of(field
, struct bt_field_structure
, parent
);
1381 g_ptr_array_free(structure
->fields
, TRUE
);
1386 void bt_field_variant_destroy_recursive(struct bt_field
*field
)
1388 struct bt_field_variant
*variant
;
1391 BT_LOGD("Destroying variant field object: addr=%p", field
);
1392 variant
= container_of(field
, struct bt_field_variant
, parent
);
1393 BT_LOGD_STR("Putting tag field.");
1394 bt_put(variant
->tag
);
1395 BT_LOGD_STR("Putting payload field.");
1396 bt_put(variant
->payload
);
1401 void bt_field_array_destroy_recursive(struct bt_field
*field
)
1403 struct bt_field_array
*array
;
1406 BT_LOGD("Destroying array field object: addr=%p", field
);
1407 array
= container_of(field
, struct bt_field_array
, parent
);
1408 g_ptr_array_free(array
->elements
, TRUE
);
1413 void bt_field_sequence_destroy_recursive(struct bt_field
*field
)
1415 struct bt_field_sequence
*sequence
;
1418 BT_LOGD("Destroying sequence field object: addr=%p", field
);
1419 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
1420 if (sequence
->elements
) {
1421 g_ptr_array_free(sequence
->elements
, TRUE
);
1423 BT_LOGD_STR("Putting length field.");
1424 bt_put(sequence
->length
);
1429 void bt_field_string_destroy(struct bt_field
*field
)
1431 struct bt_field_string
*string
;
1434 BT_LOGD("Destroying string field object: addr=%p", field
);
1435 string
= container_of(field
, struct bt_field_string
, parent
);
1436 if (string
->payload
) {
1437 g_string_free(string
->payload
, TRUE
);
1443 int bt_field_generic_validate(struct bt_field
*field
)
1445 return (field
&& field
->payload_set
) ? 0 : -1;
1449 int bt_field_enumeration_validate_recursive(struct bt_field
*field
)
1452 struct bt_field_enumeration
*enumeration
;
1455 enumeration
= container_of(field
, struct bt_field_enumeration
,
1457 if (!enumeration
->payload
) {
1458 BT_ASSERT_PRE_MSG("Invalid enumeration field: payload is not set: "
1464 ret
= bt_field_validate_recursive(enumeration
->payload
);
1471 int bt_field_structure_validate_recursive(struct bt_field
*field
)
1475 struct bt_field_structure
*structure
;
1478 structure
= container_of(field
, struct bt_field_structure
, parent
);
1480 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1481 ret
= bt_field_validate_recursive(
1482 (void *) structure
->fields
->pdata
[i
]);
1488 this_ret
= bt_field_type_structure_get_field_by_index(
1489 field
->type
, &name
, NULL
, i
);
1490 BT_ASSERT(this_ret
== 0);
1491 BT_ASSERT_PRE_MSG("Invalid structure field's field: "
1492 "%![struct-field-]+f, field-name=\"%s\", "
1493 "index=%" PRId64
", %![field-]+f",
1494 field
, name
, i
, structure
->fields
->pdata
[i
]);
1504 int bt_field_variant_validate_recursive(struct bt_field
*field
)
1507 struct bt_field_variant
*variant
;
1510 variant
= container_of(field
, struct bt_field_variant
, parent
);
1511 ret
= bt_field_validate_recursive(variant
->payload
);
1513 BT_ASSERT_PRE_MSG("Invalid variant field's payload field: "
1514 "%![variant-field-]+f, %![payload-field-]+f",
1515 field
, variant
->payload
);
1522 int bt_field_array_validate_recursive(struct bt_field
*field
)
1526 struct bt_field_array
*array
;
1529 array
= container_of(field
, struct bt_field_array
, parent
);
1530 for (i
= 0; i
< array
->elements
->len
; i
++) {
1531 ret
= bt_field_validate_recursive((void *) array
->elements
->pdata
[i
]);
1533 BT_ASSERT_PRE_MSG("Invalid array field's element field: "
1534 "%![array-field-]+f, " PRId64
", "
1535 "%![elem-field-]+f",
1536 field
, i
, array
->elements
->pdata
[i
]);
1546 int bt_field_sequence_validate_recursive(struct bt_field
*field
)
1550 struct bt_field_sequence
*sequence
;
1553 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
1554 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1555 ret
= bt_field_validate_recursive(
1556 (void *) sequence
->elements
->pdata
[i
]);
1558 BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
1559 "%![seq-field-]+f, " PRId64
", "
1560 "%![elem-field-]+f",
1561 field
, i
, sequence
->elements
->pdata
[i
]);
1570 void bt_field_generic_reset(struct bt_field
*field
)
1573 field
->payload_set
= false;
1577 void bt_field_enumeration_reset_recursive(struct bt_field
*field
)
1579 struct bt_field_enumeration
*enumeration
;
1582 enumeration
= container_of(field
, struct bt_field_enumeration
,
1584 if (!enumeration
->payload
) {
1588 bt_field_reset_recursive(enumeration
->payload
);
1592 void bt_field_structure_reset_recursive(struct bt_field
*field
)
1595 struct bt_field_structure
*structure
;
1598 structure
= container_of(field
, struct bt_field_structure
, parent
);
1600 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1601 struct bt_field
*member
= structure
->fields
->pdata
[i
];
1605 * Structure members are lazily initialized;
1606 * skip if this member has not been allocated
1612 bt_field_reset_recursive(member
);
1617 void bt_field_variant_reset_recursive(struct bt_field
*field
)
1619 struct bt_field_variant
*variant
;
1622 variant
= container_of(field
, struct bt_field_variant
, parent
);
1623 BT_PUT(variant
->tag
);
1624 BT_PUT(variant
->payload
);
1628 void bt_field_array_reset_recursive(struct bt_field
*field
)
1631 struct bt_field_array
*array
;
1634 array
= container_of(field
, struct bt_field_array
, parent
);
1636 for (i
= 0; i
< array
->elements
->len
; i
++) {
1637 struct bt_field
*member
= array
->elements
->pdata
[i
];
1641 * Array elements are lazily initialized; skip
1642 * if this member has not been allocated yet.
1647 bt_field_reset_recursive(member
);
1652 void bt_field_sequence_reset_recursive(struct bt_field
*field
)
1654 struct bt_field_sequence
*sequence
;
1657 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
1659 if (sequence
->elements
) {
1660 g_ptr_array_free(sequence
->elements
, TRUE
);
1661 sequence
->elements
= NULL
;
1664 BT_PUT(sequence
->length
);
1668 void bt_field_string_reset_recursive(struct bt_field
*field
)
1670 struct bt_field_string
*string
;
1673 bt_field_generic_reset(field
);
1674 string
= container_of(field
, struct bt_field_string
, parent
);
1675 if (string
->payload
) {
1676 g_string_truncate(string
->payload
, 0);
1681 int bt_field_integer_serialize(struct bt_field
*field
,
1682 struct bt_stream_pos
*pos
,
1683 enum bt_byte_order native_byte_order
)
1686 struct bt_field_integer
*integer
= container_of(field
,
1687 struct bt_field_integer
, parent
);
1689 BT_ASSERT_PRE_FIELD_IS_SET(field
, "Integer field");
1690 BT_LOGV("Serializing integer field: addr=%p, pos-offset=%" PRId64
", "
1691 "native-bo=%s", field
, pos
->offset
,
1692 bt_byte_order_string(native_byte_order
));
1695 ret
= bt_field_integer_write(integer
, pos
, native_byte_order
);
1696 if (ret
== -EFAULT
) {
1698 * The field is too large to fit in the current packet's
1699 * remaining space. Bump the packet size and retry.
1701 ret
= increase_packet_size(pos
);
1703 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
1714 int bt_field_enumeration_serialize_recursive(struct bt_field
*field
,
1715 struct bt_stream_pos
*pos
,
1716 enum bt_byte_order native_byte_order
)
1718 struct bt_field_enumeration
*enumeration
= container_of(
1719 field
, struct bt_field_enumeration
, parent
);
1721 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64
", "
1722 "native-bo=%s", field
, pos
->offset
,
1723 bt_byte_order_string(native_byte_order
));
1724 BT_LOGV_STR("Serializing enumeration field's payload field.");
1725 return bt_field_serialize_recursive(enumeration
->payload
, pos
,
1730 int bt_field_floating_point_serialize(struct bt_field
*field
,
1731 struct bt_stream_pos
*pos
,
1732 enum bt_byte_order native_byte_order
)
1735 struct bt_field_floating_point
*floating_point
= container_of(field
,
1736 struct bt_field_floating_point
, parent
);
1738 BT_ASSERT_PRE_FIELD_IS_SET(field
, "Floating point number field");
1739 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64
", "
1740 "native-bo=%s", field
, pos
->offset
,
1741 bt_byte_order_string(native_byte_order
));
1744 ret
= bt_field_floating_point_write(floating_point
, pos
,
1746 if (ret
== -EFAULT
) {
1748 * The field is too large to fit in the current packet's
1749 * remaining space. Bump the packet size and retry.
1751 ret
= increase_packet_size(pos
);
1753 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
1764 int bt_field_structure_serialize_recursive(struct bt_field
*field
,
1765 struct bt_stream_pos
*pos
,
1766 enum bt_byte_order native_byte_order
)
1770 struct bt_field_structure
*structure
= container_of(
1771 field
, struct bt_field_structure
, parent
);
1773 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64
", "
1774 "native-bo=%s", field
, pos
->offset
,
1775 bt_byte_order_string(native_byte_order
));
1777 while (!bt_stream_pos_access_ok(pos
,
1778 offset_align(pos
->offset
, field
->type
->alignment
))) {
1779 ret
= increase_packet_size(pos
);
1781 BT_LOGE("Cannot increase packet size: ret=%d", ret
);
1786 if (!bt_stream_pos_align(pos
, field
->type
->alignment
)) {
1787 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64
", "
1788 "align=%u", pos
->offset
, field
->type
->alignment
);
1793 for (i
= 0; i
< structure
->fields
->len
; i
++) {
1794 struct bt_field
*member
= g_ptr_array_index(
1795 structure
->fields
, i
);
1796 const char *field_name
= NULL
;
1798 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64
", "
1799 "field-addr=%p, index=%" PRId64
,
1800 pos
->offset
, member
, i
);
1803 ret
= bt_field_type_structure_get_field_by_index(
1804 field
->type
, &field_name
, NULL
, i
);
1805 BT_ASSERT(ret
== 0);
1806 BT_LOGW("Cannot serialize structure field's field: field is not set: "
1807 "struct-field-addr=%p, "
1808 "field-name=\"%s\", index=%" PRId64
,
1809 field
, field_name
, i
);
1814 ret
= bt_field_serialize_recursive(member
, pos
,
1817 ret
= bt_field_type_structure_get_field_by_index(
1818 field
->type
, &field_name
, NULL
, i
);
1819 BT_ASSERT(ret
== 0);
1820 BT_LOGW("Cannot serialize structure field's field: "
1821 "struct-field-addr=%p, field-addr=%p, "
1822 "field-name=\"%s\", index=%" PRId64
,
1823 field
->type
, member
, field_name
, i
);
1833 int bt_field_variant_serialize_recursive(struct bt_field
*field
,
1834 struct bt_stream_pos
*pos
,
1835 enum bt_byte_order native_byte_order
)
1837 struct bt_field_variant
*variant
= container_of(
1838 field
, struct bt_field_variant
, parent
);
1840 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64
", "
1841 "native-bo=%s", field
, pos
->offset
,
1842 bt_byte_order_string(native_byte_order
));
1843 BT_LOGV_STR("Serializing variant field's payload field.");
1844 return bt_field_serialize_recursive(variant
->payload
, pos
,
1849 int bt_field_array_serialize_recursive(struct bt_field
*field
,
1850 struct bt_stream_pos
*pos
,
1851 enum bt_byte_order native_byte_order
)
1855 struct bt_field_array
*array
= container_of(
1856 field
, struct bt_field_array
, parent
);
1858 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64
", "
1859 "native-bo=%s", field
, pos
->offset
,
1860 bt_byte_order_string(native_byte_order
));
1862 for (i
= 0; i
< array
->elements
->len
; i
++) {
1863 struct bt_field
*elem_field
=
1864 g_ptr_array_index(array
->elements
, i
);
1866 BT_LOGV("Serializing array field's element field: "
1867 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
1868 pos
->offset
, elem_field
, i
);
1869 ret
= bt_field_serialize_recursive(elem_field
, pos
,
1872 BT_LOGW("Cannot serialize array field's element field: "
1873 "array-field-addr=%p, field-addr=%p, "
1874 "index=%" PRId64
, field
, elem_field
, i
);
1884 int bt_field_sequence_serialize_recursive(struct bt_field
*field
,
1885 struct bt_stream_pos
*pos
,
1886 enum bt_byte_order native_byte_order
)
1890 struct bt_field_sequence
*sequence
= container_of(
1891 field
, struct bt_field_sequence
, parent
);
1893 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64
", "
1894 "native-bo=%s", field
, pos
->offset
,
1895 bt_byte_order_string(native_byte_order
));
1897 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
1898 struct bt_field
*elem_field
=
1899 g_ptr_array_index(sequence
->elements
, i
);
1901 BT_LOGV("Serializing sequence field's element field: "
1902 "pos-offset=%" PRId64
", field-addr=%p, index=%" PRId64
,
1903 pos
->offset
, elem_field
, i
);
1904 ret
= bt_field_serialize_recursive(elem_field
, pos
,
1907 BT_LOGW("Cannot serialize sequence field's element field: "
1908 "sequence-field-addr=%p, field-addr=%p, "
1909 "index=%" PRId64
, field
, elem_field
, i
);
1919 int bt_field_string_serialize(struct bt_field
*field
, struct bt_stream_pos
*pos
,
1920 enum bt_byte_order native_byte_order
)
1924 struct bt_field_string
*string
= container_of(field
,
1925 struct bt_field_string
, parent
);
1926 struct bt_field_type
*character_type
=
1927 get_field_type(FIELD_TYPE_ALIAS_UINT8_T
);
1928 struct bt_field
*character
;
1930 BT_ASSERT_PRE_FIELD_IS_SET(field
, "String field");
1931 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64
", "
1932 "native-bo=%s", field
, pos
->offset
,
1933 bt_byte_order_string(native_byte_order
));
1935 BT_LOGV_STR("Creating character field from string field's character field type.");
1936 character
= bt_field_create(character_type
);
1938 for (i
= 0; i
< string
->payload
->len
+ 1; i
++) {
1939 const uint64_t chr
= (uint64_t) string
->payload
->str
[i
];
1941 ret
= bt_field_unsigned_integer_set_value(character
, chr
);
1942 BT_ASSERT(ret
== 0);
1943 BT_LOGV("Serializing string field's character field: "
1944 "pos-offset=%" PRId64
", field-addr=%p, "
1945 "index=%" PRId64
", char-int=%" PRIu64
,
1946 pos
->offset
, character
, i
, chr
);
1947 ret
= bt_field_integer_serialize(character
, pos
,
1950 BT_LOGW_STR("Cannot serialize character field.");
1957 bt_put(character_type
);
1962 int bt_field_integer_copy(struct bt_field
*src
, struct bt_field
*dst
)
1964 struct bt_field_integer
*integer_src
, *integer_dst
;
1966 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
1968 integer_src
= container_of(src
, struct bt_field_integer
, parent
);
1969 integer_dst
= container_of(dst
, struct bt_field_integer
, parent
);
1970 integer_dst
->payload
= integer_src
->payload
;
1971 BT_LOGD_STR("Copied integer field.");
1976 int bt_field_enumeration_copy_recursive(struct bt_field
*src
,
1977 struct bt_field
*dst
)
1980 struct bt_field_enumeration
*enum_src
, *enum_dst
;
1982 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
1984 enum_src
= container_of(src
, struct bt_field_enumeration
, parent
);
1985 enum_dst
= container_of(dst
, struct bt_field_enumeration
, parent
);
1987 if (enum_src
->payload
) {
1988 BT_LOGD_STR("Copying enumeration field's payload field.");
1989 enum_dst
->payload
= bt_field_copy(enum_src
->payload
);
1990 if (!enum_dst
->payload
) {
1991 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
1997 BT_LOGD_STR("Copied enumeration field.");
2003 int bt_field_floating_point_copy(struct bt_field
*src
, struct bt_field
*dst
)
2005 struct bt_field_floating_point
*float_src
, *float_dst
;
2007 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2009 float_src
= container_of(src
, struct bt_field_floating_point
,
2011 float_dst
= container_of(dst
, struct bt_field_floating_point
,
2013 float_dst
->payload
= float_src
->payload
;
2014 BT_LOGD_STR("Copied floating point number field.");
2019 int bt_field_structure_copy_recursive(struct bt_field
*src
,
2020 struct bt_field
*dst
)
2024 struct bt_field_structure
*struct_src
, *struct_dst
;
2026 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2028 struct_src
= container_of(src
, struct bt_field_structure
, parent
);
2029 struct_dst
= container_of(dst
, struct bt_field_structure
, parent
);
2031 g_ptr_array_set_size(struct_dst
->fields
, struct_src
->fields
->len
);
2033 for (i
= 0; i
< struct_src
->fields
->len
; i
++) {
2034 struct bt_field
*field
=
2035 g_ptr_array_index(struct_src
->fields
, i
);
2036 struct bt_field
*field_copy
= NULL
;
2039 BT_LOGD("Copying structure field's field: src-field-addr=%p"
2040 "index=%" PRId64
, field
, i
);
2041 field_copy
= bt_field_copy(field
);
2043 BT_LOGE("Cannot copy structure field's field: "
2044 "src-field-addr=%p, index=%" PRId64
,
2051 BT_MOVE(g_ptr_array_index(struct_dst
->fields
, i
), field_copy
);
2054 BT_LOGD_STR("Copied structure field.");
2061 int bt_field_variant_copy_recursive(struct bt_field
*src
,
2062 struct bt_field
*dst
)
2065 struct bt_field_variant
*variant_src
, *variant_dst
;
2067 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2069 variant_src
= container_of(src
, struct bt_field_variant
, parent
);
2070 variant_dst
= container_of(dst
, struct bt_field_variant
, parent
);
2072 if (variant_src
->tag
) {
2073 BT_LOGD_STR("Copying variant field's tag field.");
2074 variant_dst
->tag
= bt_field_copy(variant_src
->tag
);
2075 if (!variant_dst
->tag
) {
2076 BT_LOGE_STR("Cannot copy variant field's tag field.");
2081 if (variant_src
->payload
) {
2082 BT_LOGD_STR("Copying variant field's payload field.");
2083 variant_dst
->payload
= bt_field_copy(variant_src
->payload
);
2084 if (!variant_dst
->payload
) {
2085 BT_LOGE_STR("Cannot copy variant field's payload field.");
2091 BT_LOGD_STR("Copied variant field.");
2098 int bt_field_array_copy_recursive(struct bt_field
*src
,
2099 struct bt_field
*dst
)
2103 struct bt_field_array
*array_src
, *array_dst
;
2105 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2107 array_src
= container_of(src
, struct bt_field_array
, parent
);
2108 array_dst
= container_of(dst
, struct bt_field_array
, parent
);
2110 g_ptr_array_set_size(array_dst
->elements
, array_src
->elements
->len
);
2111 for (i
= 0; i
< array_src
->elements
->len
; i
++) {
2112 struct bt_field
*field
=
2113 g_ptr_array_index(array_src
->elements
, i
);
2114 struct bt_field
*field_copy
= NULL
;
2117 BT_LOGD("Copying array field's element field: field-addr=%p, "
2118 "index=%" PRId64
, field
, i
);
2119 field_copy
= bt_field_copy(field
);
2121 BT_LOGE("Cannot copy array field's element field: "
2122 "src-field-addr=%p, index=%" PRId64
,
2129 g_ptr_array_index(array_dst
->elements
, i
) = field_copy
;
2132 BT_LOGD_STR("Copied array field.");
2139 int bt_field_sequence_copy_recursive(struct bt_field
*src
,
2140 struct bt_field
*dst
)
2144 struct bt_field_sequence
*sequence_src
, *sequence_dst
;
2145 struct bt_field
*src_length
;
2146 struct bt_field
*dst_length
;
2148 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2150 sequence_src
= container_of(src
, struct bt_field_sequence
, parent
);
2151 sequence_dst
= container_of(dst
, struct bt_field_sequence
, parent
);
2153 src_length
= bt_field_sequence_get_length(src
);
2155 /* no length set yet: keep destination sequence empty */
2159 /* copy source length */
2160 BT_LOGD_STR("Copying sequence field's length field.");
2161 dst_length
= bt_field_copy(src_length
);
2164 BT_LOGE_STR("Cannot copy sequence field's length field.");
2169 /* this will initialize the destination sequence's internal array */
2170 ret
= bt_field_sequence_set_length(dst
, dst_length
);
2173 BT_LOGE("Cannot set sequence field copy's length field: "
2174 "dst-length-field-addr=%p", dst_length
);
2179 BT_ASSERT(sequence_dst
->elements
->len
== sequence_src
->elements
->len
);
2181 for (i
= 0; i
< sequence_src
->elements
->len
; i
++) {
2182 struct bt_field
*field
=
2183 g_ptr_array_index(sequence_src
->elements
, i
);
2184 struct bt_field
*field_copy
= NULL
;
2187 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2188 "index=%" PRId64
, field
, i
);
2189 field_copy
= bt_field_copy(field
);
2191 BT_LOGE("Cannot copy sequence field's element field: "
2192 "src-field-addr=%p, index=%" PRId64
,
2199 g_ptr_array_index(sequence_dst
->elements
, i
) = field_copy
;
2202 BT_LOGD_STR("Copied sequence field.");
2209 int bt_field_string_copy_recursive(struct bt_field
*src
,
2210 struct bt_field
*dst
)
2213 struct bt_field_string
*string_src
, *string_dst
;
2215 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
2217 string_src
= container_of(src
, struct bt_field_string
, parent
);
2218 string_dst
= container_of(dst
, struct bt_field_string
, parent
);
2220 if (string_src
->payload
) {
2221 string_dst
->payload
= g_string_new(string_src
->payload
->str
);
2222 if (!string_dst
->payload
) {
2223 BT_LOGE_STR("Failed to allocate a GString.");
2229 BT_LOGD_STR("Copied string field.");
2236 int increase_packet_size(struct bt_stream_pos
*pos
)
2241 BT_LOGV("Increasing packet size: pos-offset=%" PRId64
", "
2242 "cur-packet-size=%" PRIu64
,
2243 pos
->offset
, pos
->packet_size
);
2244 ret
= munmap_align(pos
->base_mma
);
2246 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
2251 pos
->packet_size
+= PACKET_LEN_INCREMENT
;
2253 ret
= bt_posix_fallocate(pos
->fd
, pos
->mmap_offset
,
2254 pos
->packet_size
/ CHAR_BIT
);
2255 } while (ret
== EINTR
);
2257 BT_LOGE_ERRNO("Failed to preallocate memory space",
2264 pos
->base_mma
= mmap_align(pos
->packet_size
/ CHAR_BIT
, pos
->prot
,
2265 pos
->flags
, pos
->fd
, pos
->mmap_offset
);
2266 if (pos
->base_mma
== MAP_FAILED
) {
2267 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
2272 BT_LOGV("Increased packet size: pos-offset=%" PRId64
", "
2273 "new-packet-size=%" PRIu64
,
2274 pos
->offset
, pos
->packet_size
);
2275 BT_ASSERT(pos
->packet_size
% 8 == 0);
2282 void generic_field_freeze(struct bt_field
*field
)
2284 field
->frozen
= true;
2288 void bt_field_enumeration_freeze_recursive(struct bt_field
*field
)
2290 struct bt_field_enumeration
*enum_field
=
2291 container_of(field
, struct bt_field_enumeration
, parent
);
2293 BT_LOGD("Freezing enumeration field object: addr=%p", field
);
2294 BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field
->payload
);
2295 bt_field_freeze_recursive(enum_field
->payload
);
2296 generic_field_freeze(field
);
2300 void bt_field_structure_freeze_recursive(struct bt_field
*field
)
2303 struct bt_field_structure
*structure_field
=
2304 container_of(field
, struct bt_field_structure
, parent
);
2306 BT_LOGD("Freezing structure field object: addr=%p", field
);
2308 for (i
= 0; i
< structure_field
->fields
->len
; i
++) {
2309 struct bt_field
*field
=
2310 g_ptr_array_index(structure_field
->fields
, i
);
2312 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64
,
2314 bt_field_freeze_recursive(field
);
2317 generic_field_freeze(field
);
2321 void bt_field_variant_freeze_recursive(struct bt_field
*field
)
2323 struct bt_field_variant
*variant_field
=
2324 container_of(field
, struct bt_field_variant
, parent
);
2326 BT_LOGD("Freezing variant field object: addr=%p", field
);
2327 BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field
->tag
);
2328 bt_field_freeze_recursive(variant_field
->tag
);
2329 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field
->payload
);
2330 bt_field_freeze_recursive(variant_field
->payload
);
2331 generic_field_freeze(field
);
2335 void bt_field_array_freeze_recursive(struct bt_field
*field
)
2338 struct bt_field_array
*array_field
=
2339 container_of(field
, struct bt_field_array
, parent
);
2341 BT_LOGD("Freezing array field object: addr=%p", field
);
2343 for (i
= 0; i
< array_field
->elements
->len
; i
++) {
2344 struct bt_field
*elem_field
=
2345 g_ptr_array_index(array_field
->elements
, i
);
2347 BT_LOGD("Freezing array field object's element field: "
2348 "element-field-addr=%p, index=%" PRId64
,
2350 bt_field_freeze_recursive(elem_field
);
2353 generic_field_freeze(field
);
2357 void bt_field_sequence_freeze_recursive(struct bt_field
*field
)
2360 struct bt_field_sequence
*sequence_field
=
2361 container_of(field
, struct bt_field_sequence
, parent
);
2363 BT_LOGD("Freezing sequence field object: addr=%p", field
);
2364 BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p",
2365 sequence_field
->length
);
2366 bt_field_freeze_recursive(sequence_field
->length
);
2368 for (i
= 0; i
< sequence_field
->elements
->len
; i
++) {
2369 struct bt_field
*elem_field
=
2370 g_ptr_array_index(sequence_field
->elements
, i
);
2372 BT_LOGD("Freezing sequence field object's element field: "
2373 "element-field-addr=%p, index=%" PRId64
,
2375 bt_field_freeze_recursive(elem_field
);
2378 generic_field_freeze(field
);
2382 void _bt_field_freeze_recursive(struct bt_field
*field
)
2384 enum bt_field_type_id type_id
;
2390 if (field
->frozen
) {
2394 BT_LOGD("Freezing field object: addr=%p", field
);
2395 BT_ASSERT(field_type_has_known_id(field
->type
));
2396 type_id
= bt_field_get_type_id(field
);
2397 field_freeze_funcs
[type_id
](field
);
2403 bt_bool
bt_field_generic_is_set(struct bt_field
*field
)
2405 return field
&& field
->payload_set
;
2409 bt_bool
bt_field_enumeration_is_set_recursive(struct bt_field
*field
)
2411 bt_bool is_set
= BT_FALSE
;
2412 struct bt_field_enumeration
*enumeration
;
2415 enumeration
= container_of(field
, struct bt_field_enumeration
,
2417 if (!enumeration
->payload
) {
2421 is_set
= bt_field_is_set_recursive(enumeration
->payload
);
2427 bt_bool
bt_field_structure_is_set_recursive(struct bt_field
*field
)
2429 bt_bool is_set
= BT_FALSE
;
2431 struct bt_field_structure
*structure
;
2434 structure
= container_of(field
, struct bt_field_structure
, parent
);
2435 for (i
= 0; i
< structure
->fields
->len
; i
++) {
2436 is_set
= bt_field_is_set_recursive(
2437 structure
->fields
->pdata
[i
]);
2447 bt_bool
bt_field_variant_is_set_recursive(struct bt_field
*field
)
2449 struct bt_field_variant
*variant
;
2452 variant
= container_of(field
, struct bt_field_variant
, parent
);
2453 return bt_field_is_set_recursive(variant
->payload
);
2457 bt_bool
bt_field_array_is_set_recursive(struct bt_field
*field
)
2460 bt_bool is_set
= BT_FALSE
;
2461 struct bt_field_array
*array
;
2464 array
= container_of(field
, struct bt_field_array
, parent
);
2465 for (i
= 0; i
< array
->elements
->len
; i
++) {
2466 is_set
= bt_field_is_set_recursive(array
->elements
->pdata
[i
]);
2476 bt_bool
bt_field_sequence_is_set_recursive(struct bt_field
*field
)
2479 bt_bool is_set
= BT_FALSE
;
2480 struct bt_field_sequence
*sequence
;
2483 sequence
= container_of(field
, struct bt_field_sequence
, parent
);
2484 if (!sequence
->elements
) {
2488 for (i
= 0; i
< sequence
->elements
->len
; i
++) {
2489 is_set
= bt_field_is_set_recursive(sequence
->elements
->pdata
[i
]);