lib: metadata: transform fast path precond. checks to BT_ASSERT_PRE()
[babeltrace.git] / lib / ctf-ir / fields.c
CommitLineData
273b65be 1/*
2e33ac5a 2 * fields.c
273b65be 3 *
d2dc44b6 4 * Babeltrace CTF IR - Event Fields
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
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
26 * SOFTWARE.
27 */
28
fc25abce
PP
29#define BT_LOG_TAG "FIELDS"
30#include <babeltrace/lib-logging-internal.h>
31
2e33ac5a
PP
32#include <babeltrace/ctf-ir/fields-internal.h>
33#include <babeltrace/ctf-ir/field-types-internal.h>
dc3fffef 34#include <babeltrace/ctf-writer/serialize-internal.h>
83509119
JG
35#include <babeltrace/object-internal.h>
36#include <babeltrace/ref.h>
3d9990ac
PP
37#include <babeltrace/compiler-internal.h>
38#include <babeltrace/compat/fcntl-internal.h>
39#include <babeltrace/align-internal.h>
f6ccaed9
PP
40#include <babeltrace/assert-internal.h>
41#include <babeltrace/assert-pre-internal.h>
fc25abce 42#include <inttypes.h>
273b65be 43
273b65be 44static
50842bdc 45struct bt_field *bt_field_integer_create(struct bt_field_type *);
273b65be 46static
f6ccaed9 47struct bt_field *bt_field_enumeration_create(struct bt_field_type *);
273b65be 48static
f6ccaed9 49struct bt_field *bt_field_floating_point_create(struct bt_field_type *);
273b65be 50static
f6ccaed9 51struct bt_field *bt_field_structure_create(struct bt_field_type *);
273b65be 52static
f6ccaed9 53struct bt_field *bt_field_variant_create(struct bt_field_type *);
273b65be 54static
f6ccaed9 55struct bt_field *bt_field_array_create(struct bt_field_type *);
273b65be 56static
f6ccaed9 57struct bt_field *bt_field_sequence_create(struct bt_field_type *);
273b65be 58static
50842bdc 59struct bt_field *bt_field_string_create(struct bt_field_type *);
273b65be
JG
60
61static
50842bdc 62void bt_field_destroy(struct bt_object *);
273b65be 63static
50842bdc 64void bt_field_integer_destroy(struct bt_field *);
273b65be 65static
f6ccaed9 66void bt_field_enumeration_destroy_recursive(struct bt_field *);
273b65be 67static
50842bdc 68void bt_field_floating_point_destroy(struct bt_field *);
273b65be 69static
f6ccaed9 70void bt_field_structure_destroy_recursive(struct bt_field *);
273b65be 71static
f6ccaed9 72void bt_field_variant_destroy_recursive(struct bt_field *);
273b65be 73static
f6ccaed9 74void bt_field_array_destroy_recursive(struct bt_field *);
273b65be 75static
f6ccaed9 76void bt_field_sequence_destroy_recursive(struct bt_field *);
273b65be 77static
50842bdc 78void bt_field_string_destroy(struct bt_field *);
273b65be
JG
79
80static
50842bdc 81int bt_field_generic_validate(struct bt_field *);
273b65be 82static
f6ccaed9 83int bt_field_structure_validate_recursive(struct bt_field *);
273b65be 84static
f6ccaed9 85int bt_field_variant_validate_recursive(struct bt_field *);
273b65be 86static
f6ccaed9 87int bt_field_enumeration_validate_recursive(struct bt_field *);
273b65be 88static
f6ccaed9 89int bt_field_array_validate_recursive(struct bt_field *);
273b65be 90static
f6ccaed9 91int bt_field_sequence_validate_recursive(struct bt_field *);
273b65be 92
12c8a1a3 93static
f6ccaed9 94void bt_field_generic_reset(struct bt_field *);
12c8a1a3 95static
f6ccaed9 96void bt_field_structure_reset_recursive(struct bt_field *);
12c8a1a3 97static
f6ccaed9 98void bt_field_variant_reset_recursive(struct bt_field *);
12c8a1a3 99static
f6ccaed9 100void bt_field_enumeration_reset_recursive(struct bt_field *);
12c8a1a3 101static
f6ccaed9 102void bt_field_array_reset_recursive(struct bt_field *);
12c8a1a3 103static
f6ccaed9 104void bt_field_sequence_reset_recursive(struct bt_field *);
12c8a1a3 105static
f6ccaed9 106void bt_field_string_reset_recursive(struct bt_field *);
12c8a1a3 107
273b65be 108static
50842bdc
PP
109int bt_field_integer_serialize(struct bt_field *,
110 struct bt_stream_pos *, enum bt_byte_order);
273b65be 111static
f6ccaed9 112int bt_field_enumeration_serialize_recursive(struct bt_field *,
50842bdc 113 struct bt_stream_pos *, enum bt_byte_order);
273b65be 114static
50842bdc
PP
115int bt_field_floating_point_serialize(struct bt_field *,
116 struct bt_stream_pos *, enum bt_byte_order);
273b65be 117static
f6ccaed9 118int bt_field_structure_serialize_recursive(struct bt_field *,
50842bdc 119 struct bt_stream_pos *, enum bt_byte_order);
273b65be 120static
f6ccaed9 121int bt_field_variant_serialize_recursive(struct bt_field *,
50842bdc 122 struct bt_stream_pos *, enum bt_byte_order);
273b65be 123static
f6ccaed9 124int bt_field_array_serialize_recursive(struct bt_field *,
50842bdc 125 struct bt_stream_pos *, enum bt_byte_order);
273b65be 126static
f6ccaed9 127int bt_field_sequence_serialize_recursive(struct bt_field *,
50842bdc 128 struct bt_stream_pos *, enum bt_byte_order);
273b65be 129static
50842bdc
PP
130int bt_field_string_serialize(struct bt_field *,
131 struct bt_stream_pos *, enum bt_byte_order);
273b65be 132
87d43dc1 133static
50842bdc 134int bt_field_integer_copy(struct bt_field *, struct bt_field *);
87d43dc1 135static
f6ccaed9 136int bt_field_enumeration_copy_recursive(struct bt_field *, struct bt_field *);
87d43dc1 137static
f6ccaed9 138int bt_field_floating_point_copy(struct bt_field *, struct bt_field *);
87d43dc1 139static
f6ccaed9 140int bt_field_structure_copy_recursive(struct bt_field *, struct bt_field *);
87d43dc1 141static
f6ccaed9 142int bt_field_variant_copy_recursive(struct bt_field *, struct bt_field *);
87d43dc1 143static
f6ccaed9 144int bt_field_array_copy_recursive(struct bt_field *, struct bt_field *);
87d43dc1 145static
f6ccaed9 146int bt_field_sequence_copy_recursive(struct bt_field *, struct bt_field *);
87d43dc1 147static
f6ccaed9 148int bt_field_string_copy_recursive(struct bt_field *, struct bt_field *);
87d43dc1 149
918be005 150static
50842bdc 151void generic_field_freeze(struct bt_field *);
918be005 152static
f6ccaed9 153void bt_field_enumeration_freeze_recursive(struct bt_field *);
918be005 154static
f6ccaed9 155void bt_field_structure_freeze_recursive(struct bt_field *);
918be005 156static
f6ccaed9 157void bt_field_variant_freeze_recursive(struct bt_field *);
918be005 158static
f6ccaed9 159void bt_field_array_freeze_recursive(struct bt_field *);
918be005 160static
f6ccaed9 161void bt_field_sequence_freeze_recursive(struct bt_field *);
918be005 162
76f869ab 163static
50842bdc 164bt_bool bt_field_generic_is_set(struct bt_field *);
76f869ab 165static
f6ccaed9 166bt_bool bt_field_structure_is_set_recursive(struct bt_field *);
76f869ab 167static
f6ccaed9 168bt_bool bt_field_variant_is_set_recursive(struct bt_field *);
76f869ab 169static
f6ccaed9 170bt_bool bt_field_enumeration_is_set_recursive(struct bt_field *);
76f869ab 171static
f6ccaed9 172bt_bool bt_field_array_is_set_recursive(struct bt_field *);
76f869ab 173static
f6ccaed9 174bt_bool bt_field_sequence_is_set_recursive(struct bt_field *);
76f869ab 175
273b65be 176static
50842bdc 177int increase_packet_size(struct bt_stream_pos *pos);
273b65be
JG
178
179static
f6ccaed9 180struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
50842bdc
PP
181 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_create,
182 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_create,
f6ccaed9 183 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_create,
50842bdc
PP
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,
273b65be
JG
189};
190
191static
50842bdc
PP
192void (* const field_destroy_funcs[])(struct bt_field *) = {
193 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_destroy,
f6ccaed9
PP
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,
50842bdc 200 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_destroy,
273b65be
JG
201};
202
203static
50842bdc
PP
204int (* const field_validate_funcs[])(struct bt_field *) = {
205 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_generic_validate,
f6ccaed9 206 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_validate_recursive,
50842bdc 207 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_generic_validate,
f6ccaed9
PP
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,
50842bdc 212 [BT_FIELD_TYPE_ID_STRING] = bt_field_generic_validate,
273b65be
JG
213};
214
12c8a1a3 215static
f6ccaed9 216void (* const field_reset_funcs[])(struct bt_field *) = {
50842bdc 217 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_generic_reset,
f6ccaed9 218 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_reset_recursive,
50842bdc 219 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_generic_reset,
f6ccaed9
PP
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,
12c8a1a3
JG
225};
226
273b65be 227static
50842bdc
PP
228int (* 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,
f6ccaed9
PP
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,
50842bdc 237 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_serialize,
273b65be
JG
238};
239
87d43dc1 240static
50842bdc
PP
241int (* const field_copy_funcs[])(struct bt_field *,
242 struct bt_field *) = {
243 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_copy,
f6ccaed9 244 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_copy_recursive,
50842bdc 245 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_copy,
f6ccaed9
PP
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,
87d43dc1
JG
251};
252
918be005 253static
50842bdc
PP
254void (* 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,
f6ccaed9
PP
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,
918be005
PP
263};
264
76f869ab 265static
50842bdc
PP
266bt_bool (* const field_is_set_funcs[])(struct bt_field *) = {
267 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_generic_is_set,
f6ccaed9 268 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_is_set_recursive,
50842bdc 269 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_generic_is_set,
f6ccaed9
PP
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,
50842bdc 274 [BT_FIELD_TYPE_ID_STRING] = bt_field_generic_is_set,
76f869ab
JG
275};
276
f6ccaed9
PP
277BT_ASSERT_FUNC
278static inline bool field_type_has_known_id(struct bt_field_type *ft)
279{
280 return ft->id > BT_FIELD_TYPE_ID_UNKNOWN ||
281 ft->id < BT_FIELD_TYPE_ID_NR;
282}
283
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), \
288 (_field))
289
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))
293
294#define BT_ASSERT_PRE_FIELD_HOT(_field, _name) \
295 BT_ASSERT_PRE_HOT((_field), (_name), ": +%!+f", (_field))
296
50842bdc 297struct bt_field *bt_field_create(struct bt_field_type *type)
273b65be 298{
50842bdc
PP
299 struct bt_field *field = NULL;
300 enum bt_field_type_id type_id;
273b65be 301
f6ccaed9
PP
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);
273b65be 306
50842bdc 307 type_id = bt_field_type_get_type_id(type);
273b65be
JG
308 field = field_create_funcs[type_id](type);
309 if (!field) {
310 goto error;
311 }
312
313 /* The type's declaration can't change after this point */
50842bdc 314 bt_field_type_freeze(type);
83509119 315 bt_get(type);
50842bdc 316 bt_object_init(field, bt_field_destroy);
273b65be
JG
317 field->type = type;
318error:
319 return field;
320}
321
fc25abce 322/* Pre-2.0 CTF writer backward compatibility */
50842bdc 323void bt_ctf_field_get(struct bt_field *field)
273b65be 324{
83509119 325 bt_get(field);
273b65be
JG
326}
327
fc25abce 328/* Pre-2.0 CTF writer backward compatibility */
50842bdc 329void bt_ctf_field_put(struct bt_field *field)
273b65be 330{
83509119 331 bt_put(field);
273b65be
JG
332}
333
50842bdc 334struct bt_field_type *bt_field_get_type(struct bt_field *field)
cd95e351 335{
50842bdc 336 struct bt_field_type *ret = NULL;
cd95e351 337
f6ccaed9 338 BT_ASSERT_PRE_NON_NULL(field, "Field");
cd95e351 339 ret = field->type;
83509119 340 bt_get(ret);
cd95e351
JG
341 return ret;
342}
343
50842bdc 344enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
4ebcc695 345{
f6ccaed9
PP
346 BT_ASSERT_PRE_NON_NULL(field, "Field");
347 return bt_field_type_get_type_id(field->type);
4ebcc695
PP
348}
349
50842bdc 350bt_bool bt_field_is_integer(struct bt_field *field)
8f3553be 351{
50842bdc 352 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_INTEGER;
8f3553be
PP
353}
354
50842bdc 355bt_bool bt_field_is_floating_point(struct bt_field *field)
8f3553be 356{
50842bdc 357 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_FLOAT;
8f3553be
PP
358}
359
50842bdc 360bt_bool bt_field_is_enumeration(struct bt_field *field)
8f3553be 361{
50842bdc 362 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ENUM;
8f3553be
PP
363}
364
50842bdc 365bt_bool bt_field_is_string(struct bt_field *field)
8f3553be 366{
50842bdc 367 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRING;
8f3553be
PP
368}
369
50842bdc 370bt_bool bt_field_is_structure(struct bt_field *field)
8f3553be 371{
50842bdc 372 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRUCT;
8f3553be
PP
373}
374
50842bdc 375bt_bool bt_field_is_array(struct bt_field *field)
8f3553be 376{
50842bdc 377 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ARRAY;
8f3553be
PP
378}
379
50842bdc 380bt_bool bt_field_is_sequence(struct bt_field *field)
8f3553be 381{
50842bdc 382 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_SEQUENCE;
8f3553be
PP
383}
384
50842bdc 385bt_bool bt_field_is_variant(struct bt_field *field)
8f3553be 386{
50842bdc 387 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_VARIANT;
8f3553be
PP
388}
389
2e8876d3
PP
390BT_HIDDEN
391int64_t bt_field_sequence_get_int_length(struct bt_field *field)
392{
393 struct bt_field_sequence *sequence;
394 int64_t ret;
395
f6ccaed9
PP
396 BT_ASSERT(field);
397 BT_ASSERT(bt_field_type_get_type_id(field->type) ==
2e8876d3
PP
398 BT_FIELD_TYPE_ID_SEQUENCE);
399 sequence = container_of(field, struct bt_field_sequence, parent);
400 if (!sequence->length) {
401 ret = -1;
402 goto end;
403 }
404
405 ret = (int64_t) sequence->elements->len;
406
407end:
408 return ret;
409}
410
50842bdc
PP
411struct bt_field *bt_field_sequence_get_length(
412 struct bt_field *field)
cd95e351 413{
50842bdc
PP
414 struct bt_field *ret = NULL;
415 struct bt_field_sequence *sequence;
cd95e351 416
f6ccaed9
PP
417 BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
418 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE,
419 "Field");
50842bdc 420 sequence = container_of(field, struct bt_field_sequence, parent);
cd95e351 421 ret = sequence->length;
83509119 422 bt_get(ret);
cd95e351
JG
423 return ret;
424}
425
50842bdc
PP
426int bt_field_sequence_set_length(struct bt_field *field,
427 struct bt_field *length_field)
273b65be
JG
428{
429 int ret = 0;
50842bdc
PP
430 struct bt_field_integer *length;
431 struct bt_field_sequence *sequence;
273b65be
JG
432 uint64_t sequence_length;
433
f6ccaed9
PP
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,
438 "Length field");
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");
a54f72f0 442
50842bdc 443 length = container_of(length_field, struct bt_field_integer,
273b65be 444 parent);
dc3fffef 445 sequence_length = length->payload.unsignd;
50842bdc 446 sequence = container_of(field, struct bt_field_sequence, parent);
273b65be
JG
447 if (sequence->elements) {
448 g_ptr_array_free(sequence->elements, TRUE);
83509119 449 bt_put(sequence->length);
273b65be
JG
450 }
451
f6fcfe74 452 sequence->elements = g_ptr_array_sized_new((size_t) sequence_length);
273b65be 453 if (!sequence->elements) {
fc25abce 454 BT_LOGE_STR("Failed to allocate a GPtrArray.");
273b65be
JG
455 ret = -1;
456 goto end;
457 }
458
fe0fe95c 459 g_ptr_array_set_free_func(sequence->elements,
83509119
JG
460 (GDestroyNotify) bt_put);
461 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
462 bt_get(length_field);
273b65be 463 sequence->length = length_field;
f6ccaed9
PP
464 bt_field_freeze_recursive(length_field);
465
273b65be
JG
466end:
467 return ret;
468}
469
50842bdc
PP
470struct bt_field *bt_field_structure_get_field_by_name(
471 struct bt_field *field, const char *name)
273b65be 472{
50842bdc 473 struct bt_field *ret = NULL;
273b65be 474 GQuark field_quark;
50842bdc 475 struct bt_field_structure *structure;
273b65be 476 size_t index;
c58b9c62 477 GHashTable *field_name_to_index;
273b65be 478
f6ccaed9
PP
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");
c58b9c62 482 field_name_to_index =
50842bdc 483 container_of(field->type, struct bt_field_type_structure,
c58b9c62 484 parent)->field_name_to_index;
273b65be 485 field_quark = g_quark_from_string(name);
50842bdc 486 structure = container_of(field, struct bt_field_structure, parent);
c58b9c62 487 if (!g_hash_table_lookup_extended(field_name_to_index,
fc25abce
PP
488 GUINT_TO_POINTER(field_quark),
489 NULL, (gpointer *)&index)) {
6fa8d37b 490 BT_LOGV("Invalid parameter: no such field in structure field's type: "
c58b9c62
JG
491 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
492 field, field->type, name);
273b65be
JG
493 goto error;
494 }
495
c58b9c62 496 ret = bt_get(structure->fields->pdata[index]);
f6ccaed9
PP
497 BT_ASSERT(ret);
498
273b65be 499error:
c58b9c62 500 return ret;
273b65be
JG
501}
502
50842bdc
PP
503struct bt_field *bt_field_structure_get_field_by_index(
504 struct bt_field *field, uint64_t index)
cd95e351 505{
50842bdc
PP
506 struct bt_field_structure *structure;
507 struct bt_field *ret = NULL;
cd95e351 508
f6ccaed9
PP
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]);
517 return ret;
518}
fc25abce 519
f6ccaed9
PP
520BT_ASSERT_PRE_FUNC
521static inline bool field_to_set_has_expected_type(struct bt_field *struct_field,
522 const char *name, struct bt_field *value)
523{
524 bool ret = true;
525 struct bt_field_type *expected_field_type = NULL;
cd95e351 526
f6ccaed9
PP
527 expected_field_type =
528 bt_field_type_structure_get_field_type_by_name(
529 struct_field->type, name);
530
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);
535 ret = false;
918be005
PP
536 goto end;
537 }
538
cd95e351 539end:
f6ccaed9 540 bt_put(expected_field_type);
c58b9c62 541 return ret;
cd95e351
JG
542}
543
50842bdc
PP
544int bt_field_structure_set_field_by_name(struct bt_field *field,
545 const char *name, struct bt_field *value)
273b65be
JG
546{
547 int ret = 0;
548 GQuark field_quark;
50842bdc 549 struct bt_field_structure *structure;
273b65be 550 size_t index;
c58b9c62 551 GHashTable *field_name_to_index;
273b65be 552
f6ccaed9
PP
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,
557 "Parent field");
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.");
273b65be 560 field_quark = g_quark_from_string(name);
50842bdc 561 structure = container_of(field, struct bt_field_structure, parent);
c58b9c62 562 field_name_to_index =
50842bdc 563 container_of(field->type, struct bt_field_type_structure,
c58b9c62
JG
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)) {
6fa8d37b 568 BT_LOGV("Invalid parameter: no such field in structure field's type: "
fc25abce
PP
569 "struct-field-addr=%p, struct-ft-addr=%p, "
570 "field-ft-addr=%p, name=\"%s\"",
571 field, field->type, value->type, name);
572 ret = -1;
273b65be
JG
573 goto end;
574 }
83509119 575 bt_get(value);
c58b9c62 576 BT_MOVE(structure->fields->pdata[index], value);
f6ccaed9 577
273b65be
JG
578end:
579 return ret;
580}
581
50842bdc 582struct bt_field *bt_field_array_get_field(struct bt_field *field,
273b65be
JG
583 uint64_t index)
584{
50842bdc
PP
585 struct bt_field *new_field = NULL;
586 struct bt_field_type *field_type = NULL;
587 struct bt_field_array *array;
273b65be 588
f6ccaed9
PP
589 BT_ASSERT_PRE_NON_NULL(field, "Array field");
590 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_ARRAY, "Field");
50842bdc 591 array = container_of(field, struct bt_field_array, parent);
f6ccaed9
PP
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);
273b65be 596
50842bdc 597 field_type = bt_field_type_array_get_element_type(field->type);
f6ccaed9
PP
598 if (array->elements->pdata[(size_t) index]) {
599 new_field = array->elements->pdata[(size_t) index];
273b65be
JG
600 goto end;
601 }
602
918be005 603 /* We don't want to modify this field if it's frozen */
f6ccaed9 604 BT_ASSERT_PRE_FIELD_HOT(field, "Array field");
50842bdc 605 new_field = bt_field_create(field_type);
273b65be 606 array->elements->pdata[(size_t)index] = new_field;
f6ccaed9 607
273b65be 608end:
f6ccaed9
PP
609 bt_put(field_type);
610 bt_get(new_field);
273b65be
JG
611 return new_field;
612}
613
50842bdc 614struct bt_field *bt_field_sequence_get_field(struct bt_field *field,
273b65be
JG
615 uint64_t index)
616{
50842bdc
PP
617 struct bt_field *new_field = NULL;
618 struct bt_field_type *field_type = NULL;
619 struct bt_field_sequence *sequence;
273b65be 620
f6ccaed9
PP
621 BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
622 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE,
623 "Field");
50842bdc 624 sequence = container_of(field, struct bt_field_sequence, parent);
f6ccaed9
PP
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);
50842bdc 630 field_type = bt_field_type_sequence_get_element_type(field->type);
83509119
JG
631 if (sequence->elements->pdata[(size_t) index]) {
632 new_field = sequence->elements->pdata[(size_t) index];
273b65be
JG
633 goto end;
634 }
635
918be005 636 /* We don't want to modify this field if it's frozen */
f6ccaed9 637 BT_ASSERT_PRE_FIELD_HOT(field, "Sequence field");
50842bdc 638 new_field = bt_field_create(field_type);
83509119 639 sequence->elements->pdata[(size_t) index] = new_field;
f6ccaed9 640
273b65be 641end:
f6ccaed9
PP
642 bt_put(field_type);
643 bt_get(new_field);
273b65be
JG
644 return new_field;
645}
646
50842bdc
PP
647struct bt_field *bt_field_variant_get_field(struct bt_field *field,
648 struct bt_field *tag_field)
273b65be 649{
50842bdc
PP
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;
273b65be
JG
656 int64_t tag_enum_value;
657
f6ccaed9
PP
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,
661 "Variant field");
662 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(tag_field, BT_FIELD_TYPE_ID_ENUM,
663 "Tag field");
50842bdc 664 variant = container_of(field, struct bt_field_variant, parent);
273b65be 665 variant_type = container_of(field->type,
50842bdc
PP
666 struct bt_field_type_variant, parent);
667 tag_enum = bt_field_enumeration_get_container(tag_field);
f6ccaed9 668 BT_ASSERT_PRE_NON_NULL(tag_enum, "Tag field's container");
50842bdc 669 tag_enum_integer = container_of(tag_enum, struct bt_field_integer,
273b65be 670 parent);
f6ccaed9
PP
671 BT_ASSERT_PRE(bt_field_validate_recursive(tag_field) == 0,
672 "Tag field is invalid: %!+f", tag_field);
dc3fffef 673 tag_enum_value = tag_enum_integer->payload.signd;
2829190c
PP
674
675 /*
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.
679 */
680 if (variant->tag && variant->payload) {
50842bdc
PP
681 struct bt_field *cur_tag_container = NULL;
682 struct bt_field_integer *cur_tag_enum_integer;
2829190c
PP
683 int64_t cur_tag_value;
684
685 cur_tag_container =
50842bdc 686 bt_field_enumeration_get_container(variant->tag);
f6ccaed9 687 BT_ASSERT(cur_tag_container);
2829190c 688 cur_tag_enum_integer = container_of(cur_tag_container,
50842bdc 689 struct bt_field_integer, parent);
83509119 690 bt_put(cur_tag_container);
dc3fffef 691 cur_tag_value = cur_tag_enum_integer->payload.signd;
2829190c
PP
692
693 if (cur_tag_value == tag_enum_value) {
694 new_field = variant->payload;
83509119 695 bt_get(new_field);
2829190c
PP
696 goto end;
697 }
698 }
699
918be005 700 /* We don't want to modify this field if it's frozen */
f6ccaed9 701 BT_ASSERT_PRE_FIELD_HOT(field, "Variant field");
50842bdc 702 field_type = bt_field_type_variant_get_field_type_signed(
b92ddaaa 703 variant_type, tag_enum_value);
f6ccaed9
PP
704
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);
273b65be 711
50842bdc 712 new_field = bt_field_create(field_type);
273b65be 713 if (!new_field) {
fc25abce
PP
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);
273b65be
JG
717 goto end;
718 }
719
83509119
JG
720 bt_put(variant->tag);
721 bt_put(variant->payload);
722 bt_get(new_field);
723 bt_get(tag_field);
273b65be
JG
724 variant->tag = tag_field;
725 variant->payload = new_field;
f6ccaed9 726
273b65be 727end:
83509119 728 bt_put(tag_enum);
273b65be
JG
729 return new_field;
730}
731
50842bdc
PP
732struct bt_field *bt_field_variant_get_current_field(
733 struct bt_field *variant_field)
3f4a108d 734{
50842bdc 735 struct bt_field_variant *variant;
3f4a108d 736
f6ccaed9
PP
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,
739 "Field");
50842bdc 740 variant = container_of(variant_field, struct bt_field_variant,
3f4a108d 741 parent);
f6ccaed9 742 return bt_get(variant->payload);
3f4a108d
PP
743}
744
f6ccaed9 745struct bt_field *bt_field_variant_get_tag(struct bt_field *variant_field)
f78d67fb 746{
50842bdc 747 struct bt_field_variant *variant;
f78d67fb 748
f6ccaed9
PP
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,
751 "Field");
50842bdc 752 variant = container_of(variant_field, struct bt_field_variant,
f78d67fb 753 parent);
f6ccaed9 754 return bt_get(variant->tag);
f78d67fb
JG
755}
756
f6ccaed9 757struct bt_field *bt_field_enumeration_get_container(struct bt_field *field)
273b65be 758{
50842bdc
PP
759 struct bt_field *container = NULL;
760 struct bt_field_enumeration *enumeration;
273b65be 761
f6ccaed9
PP
762 BT_ASSERT_PRE_NON_NULL(field, "Enumeration field");
763 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_ENUM, "Field");
50842bdc 764 enumeration = container_of(field, struct bt_field_enumeration,
273b65be
JG
765 parent);
766 if (!enumeration->payload) {
f6ccaed9
PP
767 struct bt_field_type_enumeration *enumeration_type;
768
918be005 769 /* We don't want to modify this field if it's frozen */
f6ccaed9 770 BT_ASSERT_PRE_FIELD_HOT(field, "Enumeration field");
918be005 771
f6ccaed9 772 enumeration_type = container_of(field->type,
50842bdc 773 struct bt_field_type_enumeration, parent);
273b65be 774 enumeration->payload =
50842bdc 775 bt_field_create(enumeration_type->container);
273b65be
JG
776 }
777
778 container = enumeration->payload;
f6ccaed9 779 return bt_get(container);
273b65be
JG
780}
781
50842bdc
PP
782struct bt_field_type_enumeration_mapping_iterator *
783bt_field_enumeration_get_mappings(struct bt_field *field)
cd95e351
JG
784{
785 int ret;
50842bdc 786 struct bt_field *container = NULL;
50842bdc
PP
787 struct bt_field_type_integer *integer_type = NULL;
788 struct bt_field_type_enumeration_mapping_iterator *iter = NULL;
cd95e351 789
f6ccaed9
PP
790 BT_ASSERT_PRE_NON_NULL(field, "Enumeration field");
791 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_ENUM, "Field");
50842bdc 792 container = bt_field_enumeration_get_container(field);
f6ccaed9
PP
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,
50842bdc 797 struct bt_field_type_integer, parent);
f6ccaed9
PP
798 BT_ASSERT_PRE_FIELD_IS_SET(container,
799 "Enumeration field's payload field");
cd95e351 800
dc3fffef 801 if (!integer_type->is_signed) {
cd95e351 802 uint64_t value;
96e8f959 803
f6ccaed9
PP
804 ret = bt_field_unsigned_integer_get_value(container, &value);
805 BT_ASSERT(ret == 0);
50842bdc 806 iter = bt_field_type_enumeration_find_mappings_by_unsigned_value(
96e8f959 807 field->type, value);
cd95e351
JG
808 } else {
809 int64_t value;
96e8f959 810
f6ccaed9
PP
811 ret = bt_field_signed_integer_get_value(container, &value);
812 BT_ASSERT(ret == 0);
50842bdc 813 iter = bt_field_type_enumeration_find_mappings_by_signed_value(
96e8f959 814 field->type, value);
cd95e351
JG
815 }
816
83509119 817 bt_put(container);
e0f15669 818 return iter;
cd95e351
JG
819}
820
f6ccaed9 821int bt_field_signed_integer_get_value(struct bt_field *field, int64_t *value)
cd95e351 822{
50842bdc
PP
823 struct bt_field_integer *integer;
824 struct bt_field_type_integer *integer_type;
cd95e351 825
f6ccaed9
PP
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");
cd95e351 830 integer_type = container_of(field->type,
50842bdc 831 struct bt_field_type_integer, parent);
f6ccaed9
PP
832 BT_ASSERT_PRE(bt_field_type_integer_is_signed(field->type),
833 "Field's type is unsigned: %!+f", field);
cd95e351 834 integer = container_of(field,
50842bdc 835 struct bt_field_integer, parent);
dc3fffef 836 *value = integer->payload.signd;
f6ccaed9 837 return 0;
cd95e351
JG
838}
839
f6ccaed9
PP
840BT_ASSERT_PRE_FUNC
841static inline bool value_is_in_range_signed(unsigned int size, int64_t value)
273b65be 842{
f6ccaed9 843 bool ret = true;
273b65be
JG
844 int64_t min_value, max_value;
845
9dc0d640
JG
846 min_value = -(1ULL << (size - 1));
847 max_value = (1ULL << (size - 1)) - 1;
273b65be 848 if (value < min_value || value > max_value) {
f6ccaed9 849 BT_LOGF("Value is out of bounds: value=%" PRId64 ", "
fc25abce 850 "min-value=%" PRId64 ", max-value=%" PRId64,
f6ccaed9
PP
851 value, min_value, max_value);
852 ret = false;
273b65be
JG
853 }
854
273b65be
JG
855 return ret;
856}
857
f6ccaed9 858int bt_field_signed_integer_set_value(struct bt_field *field, int64_t value)
cd95e351
JG
859{
860 int ret = 0;
50842bdc
PP
861 struct bt_field_integer *integer;
862 struct bt_field_type_integer *integer_type;
cd95e351 863
f6ccaed9
PP
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);
cd95e351 868 integer_type = container_of(field->type,
50842bdc 869 struct bt_field_type_integer, parent);
f6ccaed9
PP
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",
874 value, field);
875 integer->payload.signd = value;
876 bt_field_set(field, true);
cd95e351
JG
877 return ret;
878}
879
f6ccaed9 880int bt_field_unsigned_integer_get_value(struct bt_field *field, uint64_t *value)
273b65be 881{
50842bdc
PP
882 struct bt_field_integer *integer;
883 struct bt_field_type_integer *integer_type;
fc25abce 884
f6ccaed9
PP
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");
273b65be 889 integer_type = container_of(field->type,
50842bdc 890 struct bt_field_type_integer, parent);
f6ccaed9
PP
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;
895 return 0;
896}
897
898BT_ASSERT_PRE_FUNC
899static inline bool value_is_in_range_unsigned(unsigned int size, uint64_t value)
900{
901 bool ret = true;
902 int64_t max_value;
273b65be 903
8684abc8 904 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
273b65be 905 if (value > max_value) {
f6ccaed9
PP
906 BT_LOGF("Value is out of bounds: value=%" PRIu64 ", "
907 "max-value=%" PRIu64,
908 value, max_value);
909 ret = false;
273b65be
JG
910 }
911
273b65be
JG
912 return ret;
913}
914
f6ccaed9 915int bt_field_unsigned_integer_set_value(struct bt_field *field, uint64_t value)
cd95e351 916{
f6ccaed9
PP
917 struct bt_field_integer *integer;
918 struct bt_field_type_integer *integer_type;
fc25abce 919
f6ccaed9
PP
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",
930 value, field);
931 integer->payload.unsignd = value;
932 bt_field_set(field, true);
933 return 0;
934}
fc25abce 935
f6ccaed9
PP
936int bt_field_floating_point_get_value(struct bt_field *field, double *value)
937{
938 struct bt_field_floating_point *floating_point;
cd95e351 939
f6ccaed9
PP
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");
cd95e351 944 floating_point = container_of(field,
50842bdc 945 struct bt_field_floating_point, parent);
dc3fffef 946 *value = floating_point->payload;
f6ccaed9 947 return 0;
cd95e351
JG
948}
949
f6ccaed9 950int bt_field_floating_point_set_value(struct bt_field *field, double value)
273b65be 951{
50842bdc 952 struct bt_field_floating_point *floating_point;
273b65be 953
f6ccaed9
PP
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");
50842bdc 957 floating_point = container_of(field, struct bt_field_floating_point,
273b65be 958 parent);
dc3fffef 959 floating_point->payload = value;
f6ccaed9
PP
960 bt_field_set(field, true);
961 return 0;
273b65be
JG
962}
963
50842bdc 964const char *bt_field_string_get_value(struct bt_field *field)
cd95e351 965{
50842bdc 966 struct bt_field_string *string;
cd95e351 967
f6ccaed9
PP
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;
cd95e351
JG
973}
974
f6ccaed9 975int bt_field_string_set_value(struct bt_field *field, const char *value)
273b65be 976{
50842bdc 977 struct bt_field_string *string;
273b65be 978
f6ccaed9
PP
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");
50842bdc 983 string = container_of(field, struct bt_field_string, parent);
273b65be 984 if (string->payload) {
97736814
JG
985 g_string_assign(string->payload, value);
986 } else {
987 string->payload = g_string_new(value);
273b65be
JG
988 }
989
f6ccaed9
PP
990 bt_field_set(field, true);
991 return 0;
273b65be
JG
992}
993
f6ccaed9 994int bt_field_string_append(struct bt_field *field, const char *value)
c6f9c5a3 995{
50842bdc 996 struct bt_field_string *string_field;
c6f9c5a3 997
f6ccaed9
PP
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");
50842bdc 1002 string_field = container_of(field, struct bt_field_string, parent);
c6f9c5a3
PP
1003 if (string_field->payload) {
1004 g_string_append(string_field->payload, value);
1005 } else {
1006 string_field->payload = g_string_new(value);
1007 }
1008
f6ccaed9
PP
1009 bt_field_set(field, true);
1010 return 0;
c6f9c5a3
PP
1011}
1012
f6ccaed9
PP
1013int bt_field_string_append_len(struct bt_field *field, const char *value,
1014 unsigned int length)
f98c6554 1015{
50842bdc 1016 struct bt_field_string *string_field;
f98c6554 1017
f6ccaed9
PP
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");
50842bdc 1022 string_field = container_of(field, struct bt_field_string, parent);
f98c6554
PP
1023
1024 /* make sure no null bytes are appended */
f6ccaed9
PP
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);
f98c6554
PP
1028
1029 if (string_field->payload) {
f6ccaed9 1030 g_string_append_len(string_field->payload, value, length);
f98c6554 1031 } else {
f6ccaed9 1032 string_field->payload = g_string_new_len(value, length);
f98c6554
PP
1033 }
1034
f6ccaed9
PP
1035 bt_field_set(field, true);
1036 return 0;
f98c6554
PP
1037}
1038
273b65be 1039BT_HIDDEN
f6ccaed9 1040int _bt_field_validate_recursive(struct bt_field *field)
273b65be
JG
1041{
1042 int ret = 0;
50842bdc 1043 enum bt_field_type_id type_id;
273b65be
JG
1044
1045 if (!field) {
f6ccaed9 1046 BT_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
273b65be
JG
1047 ret = -1;
1048 goto end;
1049 }
1050
f6ccaed9 1051 BT_ASSERT(field_type_has_known_id(field->type));
50842bdc 1052 type_id = bt_field_type_get_type_id(field->type);
273b65be 1053 ret = field_validate_funcs[type_id](field);
f6ccaed9 1054
273b65be
JG
1055end:
1056 return ret;
1057}
1058
f6ccaed9
PP
1059BT_HIDDEN
1060void _bt_field_reset_recursive(struct bt_field *field)
1061{ BT_ASSERT(field);
1062 field_reset_funcs[field->type->id](field);
1063}
12c8a1a3 1064
f6ccaed9
PP
1065BT_HIDDEN
1066void _bt_field_set(struct bt_field *field, bool value)
1067{
1068 BT_ASSERT(field);
1069 field->payload_set = value;
12c8a1a3
JG
1070}
1071
273b65be 1072BT_HIDDEN
f6ccaed9 1073int bt_field_serialize_recursive(struct bt_field *field, struct bt_stream_pos *pos,
50842bdc 1074 enum bt_byte_order native_byte_order)
273b65be 1075{
50842bdc 1076 enum bt_field_type_id type_id;
273b65be 1077
f6ccaed9
PP
1078 BT_ASSERT(pos);
1079 BT_ASSERT_PRE_NON_NULL(field, "Field");
1080 BT_ASSERT(field_type_has_known_id(field->type));
50842bdc 1081 type_id = bt_field_type_get_type_id(field->type);
f6ccaed9 1082 return field_serialize_funcs[type_id](field, pos, native_byte_order);
273b65be
JG
1083}
1084
f6ccaed9
PP
1085BT_HIDDEN
1086bt_bool _bt_field_is_set_recursive(struct bt_field *field)
76f869ab 1087{
d4bf905a 1088 bt_bool is_set = BT_FALSE;
50842bdc 1089 enum bt_field_type_id type_id;
76f869ab
JG
1090
1091 if (!field) {
1092 goto end;
1093 }
1094
f6ccaed9 1095 BT_ASSERT(field_type_has_known_id(field->type));
50842bdc 1096 type_id = bt_field_type_get_type_id(field->type);
d4bf905a 1097 is_set = field_is_set_funcs[type_id](field);
f6ccaed9 1098
76f869ab 1099end:
d4bf905a 1100 return is_set;
76f869ab
JG
1101}
1102
50842bdc 1103struct bt_field *bt_field_copy(struct bt_field *field)
87d43dc1
JG
1104{
1105 int ret;
50842bdc
PP
1106 struct bt_field *copy = NULL;
1107 enum bt_field_type_id type_id;
87d43dc1 1108
f6ccaed9
PP
1109 BT_ASSERT_PRE_NON_NULL(field, "Field");
1110 BT_ASSERT(field_type_has_known_id(field->type));
50842bdc 1111 copy = bt_field_create(field->type);
87d43dc1 1112 if (!copy) {
fc25abce 1113 BT_LOGW("Cannot create field: ft-addr=%p", field->type);
87d43dc1
JG
1114 goto end;
1115 }
1116
f6ccaed9
PP
1117 bt_field_set(copy, field->payload_set);
1118 type_id = bt_field_type_get_type_id(field->type);
87d43dc1
JG
1119 ret = field_copy_funcs[type_id](field, copy);
1120 if (ret) {
f6ccaed9 1121 BT_PUT(copy);
87d43dc1 1122 }
f6ccaed9 1123
87d43dc1
JG
1124end:
1125 return copy;
1126}
1127
273b65be 1128static
50842bdc 1129struct bt_field *bt_field_integer_create(struct bt_field_type *type)
273b65be 1130{
50842bdc
PP
1131 struct bt_field_integer *integer = g_new0(
1132 struct bt_field_integer, 1);
273b65be 1133
fc25abce
PP
1134 BT_LOGD("Creating integer field object: ft-addr=%p", type);
1135
1136 if (integer) {
1137 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
1138 &integer->parent, type);
1139 } else {
1140 BT_LOGE_STR("Failed to allocate one integer field.");
1141 }
1142
273b65be
JG
1143 return integer ? &integer->parent : NULL;
1144}
1145
1146static
50842bdc
PP
1147struct bt_field *bt_field_enumeration_create(
1148 struct bt_field_type *type)
273b65be 1149{
50842bdc
PP
1150 struct bt_field_enumeration *enumeration = g_new0(
1151 struct bt_field_enumeration, 1);
273b65be 1152
fc25abce
PP
1153 BT_LOGD("Creating enumeration field object: ft-addr=%p", type);
1154
1155 if (enumeration) {
1156 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
1157 &enumeration->parent, type);
1158 } else {
1159 BT_LOGE_STR("Failed to allocate one enumeration field.");
1160 }
1161
273b65be
JG
1162 return enumeration ? &enumeration->parent : NULL;
1163}
1164
1165static
50842bdc
PP
1166struct bt_field *bt_field_floating_point_create(
1167 struct bt_field_type *type)
273b65be 1168{
50842bdc 1169 struct bt_field_floating_point *floating_point;
273b65be 1170
fc25abce 1171 BT_LOGD("Creating floating point number field object: ft-addr=%p", type);
50842bdc 1172 floating_point = g_new0(struct bt_field_floating_point, 1);
fc25abce
PP
1173
1174 if (floating_point) {
1175 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
1176 &floating_point->parent, type);
1177 } else {
1178 BT_LOGE_STR("Failed to allocate one floating point number field.");
1179 }
1180
273b65be
JG
1181 return floating_point ? &floating_point->parent : NULL;
1182}
1183
1184static
50842bdc
PP
1185struct bt_field *bt_field_structure_create(
1186 struct bt_field_type *type)
273b65be 1187{
50842bdc
PP
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;
c58b9c62 1193 size_t i;
273b65be 1194
fc25abce
PP
1195 BT_LOGD("Creating structure field object: ft-addr=%p", type);
1196
8c1aa858 1197 if (!structure) {
fc25abce 1198 BT_LOGE_STR("Failed to allocate one structure field.");
273b65be
JG
1199 goto end;
1200 }
1201
273b65be 1202 structure->fields = g_ptr_array_new_with_free_func(
50842bdc 1203 (GDestroyNotify) bt_put);
273b65be 1204 g_ptr_array_set_size(structure->fields,
c58b9c62
JG
1205 structure_type->fields->len);
1206
1207 /* Create all fields contained by the structure field. */
1208 for (i = 0; i < structure_type->fields->len; i++) {
50842bdc 1209 struct bt_field *field;
c58b9c62
JG
1210 struct structure_field *field_type =
1211 g_ptr_array_index(structure_type->fields, i);
1212
50842bdc 1213 field = bt_field_create(field_type->type);
c58b9c62
JG
1214 if (!field) {
1215 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
1216 g_quark_to_string(field_type->name), i);
f6ccaed9 1217 bt_field_structure_destroy_recursive(&structure->parent);
c58b9c62
JG
1218 goto end;
1219 }
1220
1221 g_ptr_array_index(structure->fields, i) = field;
1222 }
1223
1224 ret = &structure->parent;
1225 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p", ret,
1226 type);
273b65be 1227end:
c58b9c62 1228 return ret;
273b65be
JG
1229}
1230
1231static
50842bdc 1232struct bt_field *bt_field_variant_create(struct bt_field_type *type)
273b65be 1233{
50842bdc
PP
1234 struct bt_field_variant *variant = g_new0(
1235 struct bt_field_variant, 1);
fc25abce
PP
1236
1237 BT_LOGD("Creating variant field object: ft-addr=%p", type);
1238
1239 if (variant) {
1240 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1241 &variant->parent, type);
1242 } else {
1243 BT_LOGE_STR("Failed to allocate one variant field.");
1244 }
1245
273b65be
JG
1246 return variant ? &variant->parent : NULL;
1247}
1248
1249static
50842bdc 1250struct bt_field *bt_field_array_create(struct bt_field_type *type)
273b65be 1251{
50842bdc
PP
1252 struct bt_field_array *array = g_new0(struct bt_field_array, 1);
1253 struct bt_field_type_array *array_type;
273b65be
JG
1254 unsigned int array_length;
1255
fc25abce 1256 BT_LOGD("Creating array field object: ft-addr=%p", type);
f6ccaed9 1257 BT_ASSERT(type);
fc25abce
PP
1258
1259 if (!array) {
1260 BT_LOGE_STR("Failed to allocate one array field.");
273b65be
JG
1261 goto error;
1262 }
1263
50842bdc 1264 array_type = container_of(type, struct bt_field_type_array, parent);
273b65be 1265 array_length = array_type->length;
fe0fe95c 1266 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1267 if (!array->elements) {
1268 goto error;
1269 }
1270
fe0fe95c 1271 g_ptr_array_set_free_func(array->elements,
50842bdc 1272 (GDestroyNotify) bt_put);
273b65be 1273 g_ptr_array_set_size(array->elements, array_length);
fc25abce
PP
1274 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1275 &array->parent, type);
273b65be
JG
1276 return &array->parent;
1277error:
1278 g_free(array);
1279 return NULL;
1280}
1281
1282static
50842bdc
PP
1283struct bt_field *bt_field_sequence_create(
1284 struct bt_field_type *type)
273b65be 1285{
50842bdc
PP
1286 struct bt_field_sequence *sequence = g_new0(
1287 struct bt_field_sequence, 1);
fc25abce
PP
1288
1289 BT_LOGD("Creating sequence field object: ft-addr=%p", type);
1290
1291 if (sequence) {
1292 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1293 &sequence->parent, type);
1294 } else {
1295 BT_LOGE_STR("Failed to allocate one sequence field.");
1296 }
1297
273b65be
JG
1298 return sequence ? &sequence->parent : NULL;
1299}
1300
1301static
50842bdc 1302struct bt_field *bt_field_string_create(struct bt_field_type *type)
273b65be 1303{
50842bdc
PP
1304 struct bt_field_string *string = g_new0(
1305 struct bt_field_string, 1);
fc25abce
PP
1306
1307 BT_LOGD("Creating string field object: ft-addr=%p", type);
1308
1309 if (string) {
1310 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1311 &string->parent, type);
1312 } else {
1313 BT_LOGE_STR("Failed to allocate one string field.");
1314 }
1315
273b65be
JG
1316 return string ? &string->parent : NULL;
1317}
1318
1319static
50842bdc 1320void bt_field_destroy(struct bt_object *obj)
273b65be 1321{
50842bdc
PP
1322 struct bt_field *field;
1323 struct bt_field_type *type;
1324 enum bt_field_type_id type_id;
273b65be 1325
f6ccaed9 1326 BT_ASSERT(obj);
50842bdc 1327 field = container_of(obj, struct bt_field, base);
273b65be 1328 type = field->type;
f6ccaed9 1329 BT_ASSERT(field_type_has_known_id(type));
50842bdc 1330 type_id = bt_field_type_get_type_id(type);
273b65be 1331 field_destroy_funcs[type_id](field);
fc25abce 1332 BT_LOGD_STR("Putting field's type.");
83509119 1333 bt_put(type);
273b65be
JG
1334}
1335
1336static
50842bdc 1337void bt_field_integer_destroy(struct bt_field *field)
273b65be 1338{
50842bdc 1339 struct bt_field_integer *integer;
273b65be 1340
f6ccaed9 1341 BT_ASSERT(field);
fc25abce 1342 BT_LOGD("Destroying integer field object: addr=%p", field);
50842bdc 1343 integer = container_of(field, struct bt_field_integer, parent);
273b65be
JG
1344 g_free(integer);
1345}
1346
1347static
f6ccaed9 1348void bt_field_enumeration_destroy_recursive(struct bt_field *field)
273b65be 1349{
50842bdc 1350 struct bt_field_enumeration *enumeration;
273b65be 1351
f6ccaed9 1352 BT_ASSERT(field);
fc25abce 1353 BT_LOGD("Destroying enumeration field object: addr=%p", field);
50842bdc 1354 enumeration = container_of(field, struct bt_field_enumeration,
273b65be 1355 parent);
fc25abce 1356 BT_LOGD_STR("Putting payload field.");
83509119 1357 bt_put(enumeration->payload);
273b65be
JG
1358 g_free(enumeration);
1359}
1360
1361static
50842bdc 1362void bt_field_floating_point_destroy(struct bt_field *field)
273b65be 1363{
50842bdc 1364 struct bt_field_floating_point *floating_point;
273b65be 1365
f6ccaed9 1366 BT_ASSERT(field);
fc25abce 1367 BT_LOGD("Destroying floating point number field object: addr=%p", field);
50842bdc 1368 floating_point = container_of(field, struct bt_field_floating_point,
273b65be
JG
1369 parent);
1370 g_free(floating_point);
1371}
1372
1373static
f6ccaed9 1374void bt_field_structure_destroy_recursive(struct bt_field *field)
273b65be 1375{
50842bdc 1376 struct bt_field_structure *structure;
273b65be 1377
f6ccaed9 1378 BT_ASSERT(field);
fc25abce 1379 BT_LOGD("Destroying structure field object: addr=%p", field);
50842bdc 1380 structure = container_of(field, struct bt_field_structure, parent);
273b65be
JG
1381 g_ptr_array_free(structure->fields, TRUE);
1382 g_free(structure);
1383}
1384
1385static
f6ccaed9 1386void bt_field_variant_destroy_recursive(struct bt_field *field)
273b65be 1387{
50842bdc 1388 struct bt_field_variant *variant;
273b65be 1389
f6ccaed9 1390 BT_ASSERT(field);
fc25abce 1391 BT_LOGD("Destroying variant field object: addr=%p", field);
50842bdc 1392 variant = container_of(field, struct bt_field_variant, parent);
fc25abce 1393 BT_LOGD_STR("Putting tag field.");
83509119 1394 bt_put(variant->tag);
fc25abce 1395 BT_LOGD_STR("Putting payload field.");
83509119 1396 bt_put(variant->payload);
273b65be
JG
1397 g_free(variant);
1398}
1399
1400static
f6ccaed9 1401void bt_field_array_destroy_recursive(struct bt_field *field)
273b65be 1402{
50842bdc 1403 struct bt_field_array *array;
273b65be 1404
f6ccaed9 1405 BT_ASSERT(field);
fc25abce 1406 BT_LOGD("Destroying array field object: addr=%p", field);
50842bdc 1407 array = container_of(field, struct bt_field_array, parent);
273b65be
JG
1408 g_ptr_array_free(array->elements, TRUE);
1409 g_free(array);
1410}
1411
1412static
f6ccaed9 1413void bt_field_sequence_destroy_recursive(struct bt_field *field)
273b65be 1414{
50842bdc 1415 struct bt_field_sequence *sequence;
273b65be 1416
f6ccaed9 1417 BT_ASSERT(field);
fc25abce 1418 BT_LOGD("Destroying sequence field object: addr=%p", field);
50842bdc 1419 sequence = container_of(field, struct bt_field_sequence, parent);
4fef87ab
JG
1420 if (sequence->elements) {
1421 g_ptr_array_free(sequence->elements, TRUE);
1422 }
fc25abce 1423 BT_LOGD_STR("Putting length field.");
83509119 1424 bt_put(sequence->length);
273b65be
JG
1425 g_free(sequence);
1426}
1427
1428static
50842bdc 1429void bt_field_string_destroy(struct bt_field *field)
273b65be 1430{
50842bdc 1431 struct bt_field_string *string;
fc25abce 1432
f6ccaed9 1433 BT_ASSERT(field);
fc25abce 1434 BT_LOGD("Destroying string field object: addr=%p", field);
50842bdc 1435 string = container_of(field, struct bt_field_string, parent);
9b2b7163
JG
1436 if (string->payload) {
1437 g_string_free(string->payload, TRUE);
1438 }
273b65be
JG
1439 g_free(string);
1440}
1441
1442static
50842bdc 1443int bt_field_generic_validate(struct bt_field *field)
273b65be 1444{
da2f6971 1445 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
1446}
1447
1448static
f6ccaed9 1449int bt_field_enumeration_validate_recursive(struct bt_field *field)
273b65be
JG
1450{
1451 int ret;
50842bdc 1452 struct bt_field_enumeration *enumeration;
273b65be 1453
f6ccaed9 1454 BT_ASSERT(field);
50842bdc 1455 enumeration = container_of(field, struct bt_field_enumeration,
273b65be
JG
1456 parent);
1457 if (!enumeration->payload) {
f6ccaed9
PP
1458 BT_ASSERT_PRE_MSG("Invalid enumeration field: payload is not set: "
1459 "%!+f", field);
273b65be
JG
1460 ret = -1;
1461 goto end;
1462 }
1463
f6ccaed9
PP
1464 ret = bt_field_validate_recursive(enumeration->payload);
1465
273b65be
JG
1466end:
1467 return ret;
1468}
1469
1470static
f6ccaed9 1471int bt_field_structure_validate_recursive(struct bt_field *field)
273b65be 1472{
fc25abce 1473 int64_t i;
273b65be 1474 int ret = 0;
50842bdc 1475 struct bt_field_structure *structure;
273b65be 1476
f6ccaed9 1477 BT_ASSERT(field);
50842bdc 1478 structure = container_of(field, struct bt_field_structure, parent);
f6ccaed9 1479
273b65be 1480 for (i = 0; i < structure->fields->len; i++) {
f6ccaed9
PP
1481 ret = bt_field_validate_recursive(
1482 (void *) structure->fields->pdata[i]);
fc25abce 1483
273b65be 1484 if (ret) {
fc25abce 1485 int this_ret;
6ce12048 1486 const char *name;
6ce12048 1487
50842bdc 1488 this_ret = bt_field_type_structure_get_field_by_index(
f6ccaed9
PP
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]);
273b65be
JG
1495 goto end;
1496 }
1497 }
f6ccaed9 1498
273b65be
JG
1499end:
1500 return ret;
1501}
1502
1503static
f6ccaed9 1504int bt_field_variant_validate_recursive(struct bt_field *field)
273b65be
JG
1505{
1506 int ret = 0;
50842bdc 1507 struct bt_field_variant *variant;
273b65be 1508
f6ccaed9 1509 BT_ASSERT(field);
50842bdc 1510 variant = container_of(field, struct bt_field_variant, parent);
f6ccaed9 1511 ret = bt_field_validate_recursive(variant->payload);
fc25abce 1512 if (ret) {
f6ccaed9
PP
1513 BT_ASSERT_PRE_MSG("Invalid variant field's payload field: "
1514 "%![variant-field-]+f, %![payload-field-]+f",
fc25abce
PP
1515 field, variant->payload);
1516 }
f6ccaed9 1517
273b65be
JG
1518 return ret;
1519}
1520
1521static
f6ccaed9 1522int bt_field_array_validate_recursive(struct bt_field *field)
273b65be 1523{
fc25abce 1524 int64_t i;
273b65be 1525 int ret = 0;
50842bdc 1526 struct bt_field_array *array;
273b65be 1527
f6ccaed9 1528 BT_ASSERT(field);
50842bdc 1529 array = container_of(field, struct bt_field_array, parent);
273b65be 1530 for (i = 0; i < array->elements->len; i++) {
f6ccaed9 1531 ret = bt_field_validate_recursive((void *) array->elements->pdata[i]);
273b65be 1532 if (ret) {
f6ccaed9
PP
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]);
273b65be
JG
1537 goto end;
1538 }
1539 }
f6ccaed9 1540
273b65be
JG
1541end:
1542 return ret;
1543}
1544
1545static
f6ccaed9 1546int bt_field_sequence_validate_recursive(struct bt_field *field)
273b65be
JG
1547{
1548 size_t i;
1549 int ret = 0;
50842bdc 1550 struct bt_field_sequence *sequence;
273b65be 1551
f6ccaed9 1552 BT_ASSERT(field);
50842bdc 1553 sequence = container_of(field, struct bt_field_sequence, parent);
273b65be 1554 for (i = 0; i < sequence->elements->len; i++) {
f6ccaed9
PP
1555 ret = bt_field_validate_recursive(
1556 (void *) sequence->elements->pdata[i]);
273b65be 1557 if (ret) {
f6ccaed9
PP
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]);
273b65be
JG
1562 goto end;
1563 }
1564 }
1565end:
1566 return ret;
1567}
1568
12c8a1a3 1569static
f6ccaed9 1570void bt_field_generic_reset(struct bt_field *field)
12c8a1a3 1571{
f6ccaed9 1572 BT_ASSERT(field);
d990a4fb 1573 field->payload_set = false;
12c8a1a3
JG
1574}
1575
1576static
f6ccaed9 1577void bt_field_enumeration_reset_recursive(struct bt_field *field)
12c8a1a3 1578{
50842bdc 1579 struct bt_field_enumeration *enumeration;
12c8a1a3 1580
f6ccaed9 1581 BT_ASSERT(field);
50842bdc 1582 enumeration = container_of(field, struct bt_field_enumeration,
12c8a1a3
JG
1583 parent);
1584 if (!enumeration->payload) {
f6ccaed9 1585 return;
12c8a1a3
JG
1586 }
1587
f6ccaed9 1588 bt_field_reset_recursive(enumeration->payload);
12c8a1a3
JG
1589}
1590
1591static
f6ccaed9 1592void bt_field_structure_reset_recursive(struct bt_field *field)
12c8a1a3 1593{
fc25abce 1594 int64_t i;
50842bdc 1595 struct bt_field_structure *structure;
12c8a1a3 1596
f6ccaed9 1597 BT_ASSERT(field);
50842bdc 1598 structure = container_of(field, struct bt_field_structure, parent);
f6ccaed9 1599
12c8a1a3 1600 for (i = 0; i < structure->fields->len; i++) {
50842bdc 1601 struct bt_field *member = structure->fields->pdata[i];
12c8a1a3
JG
1602
1603 if (!member) {
1604 /*
f6ccaed9
PP
1605 * Structure members are lazily initialized;
1606 * skip if this member has not been allocated
1607 * yet.
12c8a1a3
JG
1608 */
1609 continue;
1610 }
1611
f6ccaed9 1612 bt_field_reset_recursive(member);
12c8a1a3 1613 }
12c8a1a3
JG
1614}
1615
1616static
f6ccaed9 1617void bt_field_variant_reset_recursive(struct bt_field *field)
12c8a1a3 1618{
50842bdc 1619 struct bt_field_variant *variant;
12c8a1a3 1620
f6ccaed9 1621 BT_ASSERT(field);
50842bdc 1622 variant = container_of(field, struct bt_field_variant, parent);
6ead1648
JG
1623 BT_PUT(variant->tag);
1624 BT_PUT(variant->payload);
12c8a1a3
JG
1625}
1626
1627static
f6ccaed9 1628void bt_field_array_reset_recursive(struct bt_field *field)
12c8a1a3
JG
1629{
1630 size_t i;
50842bdc 1631 struct bt_field_array *array;
12c8a1a3 1632
f6ccaed9 1633 BT_ASSERT(field);
50842bdc 1634 array = container_of(field, struct bt_field_array, parent);
f6ccaed9 1635
12c8a1a3 1636 for (i = 0; i < array->elements->len; i++) {
50842bdc 1637 struct bt_field *member = array->elements->pdata[i];
12c8a1a3
JG
1638
1639 if (!member) {
1640 /*
f6ccaed9
PP
1641 * Array elements are lazily initialized; skip
1642 * if this member has not been allocated yet.
12c8a1a3
JG
1643 */
1644 continue;
1645 }
1646
f6ccaed9 1647 bt_field_reset_recursive(member);
12c8a1a3 1648 }
12c8a1a3
JG
1649}
1650
1651static
f6ccaed9 1652void bt_field_sequence_reset_recursive(struct bt_field *field)
12c8a1a3 1653{
50842bdc 1654 struct bt_field_sequence *sequence;
12c8a1a3 1655
f6ccaed9 1656 BT_ASSERT(field);
50842bdc 1657 sequence = container_of(field, struct bt_field_sequence, parent);
f6ccaed9 1658
6ead1648
JG
1659 if (sequence->elements) {
1660 g_ptr_array_free(sequence->elements, TRUE);
1661 sequence->elements = NULL;
12c8a1a3 1662 }
f6ccaed9 1663
6ead1648 1664 BT_PUT(sequence->length);
12c8a1a3
JG
1665}
1666
1667static
f6ccaed9 1668void bt_field_string_reset_recursive(struct bt_field *field)
12c8a1a3 1669{
50842bdc 1670 struct bt_field_string *string;
12c8a1a3 1671
f6ccaed9
PP
1672 BT_ASSERT(field);
1673 bt_field_generic_reset(field);
50842bdc 1674 string = container_of(field, struct bt_field_string, parent);
12c8a1a3
JG
1675 if (string->payload) {
1676 g_string_truncate(string->payload, 0);
1677 }
12c8a1a3
JG
1678}
1679
273b65be 1680static
50842bdc
PP
1681int bt_field_integer_serialize(struct bt_field *field,
1682 struct bt_stream_pos *pos,
1683 enum bt_byte_order native_byte_order)
273b65be
JG
1684{
1685 int ret = 0;
50842bdc
PP
1686 struct bt_field_integer *integer = container_of(field,
1687 struct bt_field_integer, parent);
273b65be 1688
f6ccaed9 1689 BT_ASSERT_PRE_FIELD_IS_SET(field, "Integer field");
fc25abce
PP
1690 BT_LOGV("Serializing integer field: addr=%p, pos-offset=%" PRId64 ", "
1691 "native-bo=%s", field, pos->offset,
50842bdc 1692 bt_byte_order_string(native_byte_order));
fc25abce 1693
273b65be 1694retry:
50842bdc 1695 ret = bt_field_integer_write(integer, pos, native_byte_order);
273b65be
JG
1696 if (ret == -EFAULT) {
1697 /*
1698 * The field is too large to fit in the current packet's
1699 * remaining space. Bump the packet size and retry.
1700 */
1701 ret = increase_packet_size(pos);
1702 if (ret) {
fc25abce 1703 BT_LOGE("Cannot increase packet size: ret=%d", ret);
273b65be
JG
1704 goto end;
1705 }
1706 goto retry;
1707 }
f6ccaed9 1708
273b65be
JG
1709end:
1710 return ret;
1711}
1712
1713static
f6ccaed9 1714int bt_field_enumeration_serialize_recursive(struct bt_field *field,
50842bdc
PP
1715 struct bt_stream_pos *pos,
1716 enum bt_byte_order native_byte_order)
273b65be 1717{
50842bdc
PP
1718 struct bt_field_enumeration *enumeration = container_of(
1719 field, struct bt_field_enumeration, parent);
273b65be 1720
fc25abce
PP
1721 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64 ", "
1722 "native-bo=%s", field, pos->offset,
50842bdc 1723 bt_byte_order_string(native_byte_order));
fc25abce 1724 BT_LOGV_STR("Serializing enumeration field's payload field.");
f6ccaed9 1725 return bt_field_serialize_recursive(enumeration->payload, pos,
dc3fffef 1726 native_byte_order);
273b65be
JG
1727}
1728
1729static
50842bdc
PP
1730int bt_field_floating_point_serialize(struct bt_field *field,
1731 struct bt_stream_pos *pos,
1732 enum bt_byte_order native_byte_order)
273b65be
JG
1733{
1734 int ret = 0;
50842bdc
PP
1735 struct bt_field_floating_point *floating_point = container_of(field,
1736 struct bt_field_floating_point, parent);
273b65be 1737
f6ccaed9 1738 BT_ASSERT_PRE_FIELD_IS_SET(field, "Floating point number field");
fc25abce
PP
1739 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64 ", "
1740 "native-bo=%s", field, pos->offset,
50842bdc 1741 bt_byte_order_string(native_byte_order));
fc25abce 1742
273b65be 1743retry:
50842bdc 1744 ret = bt_field_floating_point_write(floating_point, pos,
dc3fffef 1745 native_byte_order);
273b65be
JG
1746 if (ret == -EFAULT) {
1747 /*
1748 * The field is too large to fit in the current packet's
1749 * remaining space. Bump the packet size and retry.
1750 */
1751 ret = increase_packet_size(pos);
1752 if (ret) {
fc25abce 1753 BT_LOGE("Cannot increase packet size: ret=%d", ret);
273b65be
JG
1754 goto end;
1755 }
1756 goto retry;
1757 }
f6ccaed9 1758
273b65be
JG
1759end:
1760 return ret;
1761}
1762
1763static
f6ccaed9 1764int bt_field_structure_serialize_recursive(struct bt_field *field,
50842bdc
PP
1765 struct bt_stream_pos *pos,
1766 enum bt_byte_order native_byte_order)
273b65be 1767{
fc25abce 1768 int64_t i;
273b65be 1769 int ret = 0;
50842bdc
PP
1770 struct bt_field_structure *structure = container_of(
1771 field, struct bt_field_structure, parent);
273b65be 1772
fc25abce
PP
1773 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64 ", "
1774 "native-bo=%s", field, pos->offset,
50842bdc 1775 bt_byte_order_string(native_byte_order));
fc25abce 1776
50842bdc 1777 while (!bt_stream_pos_access_ok(pos,
dc3fffef 1778 offset_align(pos->offset, field->type->alignment))) {
9f56e450
JG
1779 ret = increase_packet_size(pos);
1780 if (ret) {
fc25abce 1781 BT_LOGE("Cannot increase packet size: ret=%d", ret);
9f56e450
JG
1782 goto end;
1783 }
273b65be
JG
1784 }
1785
50842bdc 1786 if (!bt_stream_pos_align(pos, field->type->alignment)) {
fc25abce
PP
1787 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64 ", "
1788 "align=%u", pos->offset, field->type->alignment);
70fd5a51
MD
1789 ret = -1;
1790 goto end;
1791 }
273b65be
JG
1792
1793 for (i = 0; i < structure->fields->len; i++) {
50842bdc 1794 struct bt_field *member = g_ptr_array_index(
273b65be 1795 structure->fields, i);
b3376dd9
PP
1796 const char *field_name = NULL;
1797
fc25abce
PP
1798 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64 ", "
1799 "field-addr=%p, index=%" PRId64,
1800 pos->offset, member, i);
b3376dd9
PP
1801
1802 if (!member) {
f6ccaed9
PP
1803 ret = bt_field_type_structure_get_field_by_index(
1804 field->type, &field_name, NULL, i);
1805 BT_ASSERT(ret == 0);
b3376dd9
PP
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);
1810 ret = -1;
1811 goto end;
1812 }
1813
f6ccaed9
PP
1814 ret = bt_field_serialize_recursive(member, pos,
1815 native_byte_order);
273b65be 1816 if (ret) {
f6ccaed9
PP
1817 ret = bt_field_type_structure_get_field_by_index(
1818 field->type, &field_name, NULL, i);
1819 BT_ASSERT(ret == 0);
fc25abce
PP
1820 BT_LOGW("Cannot serialize structure field's field: "
1821 "struct-field-addr=%p, field-addr=%p, "
1822 "field-name=\"%s\", index=%" PRId64,
b3376dd9 1823 field->type, member, field_name, i);
273b65be
JG
1824 break;
1825 }
1826 }
f6ccaed9 1827
9f56e450 1828end:
273b65be
JG
1829 return ret;
1830}
1831
1832static
f6ccaed9 1833int bt_field_variant_serialize_recursive(struct bt_field *field,
50842bdc
PP
1834 struct bt_stream_pos *pos,
1835 enum bt_byte_order native_byte_order)
273b65be 1836{
50842bdc
PP
1837 struct bt_field_variant *variant = container_of(
1838 field, struct bt_field_variant, parent);
273b65be 1839
fc25abce
PP
1840 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64 ", "
1841 "native-bo=%s", field, pos->offset,
50842bdc 1842 bt_byte_order_string(native_byte_order));
fc25abce 1843 BT_LOGV_STR("Serializing variant field's payload field.");
f6ccaed9 1844 return bt_field_serialize_recursive(variant->payload, pos,
dc3fffef 1845 native_byte_order);
273b65be
JG
1846}
1847
1848static
f6ccaed9 1849int bt_field_array_serialize_recursive(struct bt_field *field,
50842bdc
PP
1850 struct bt_stream_pos *pos,
1851 enum bt_byte_order native_byte_order)
273b65be 1852{
fc25abce 1853 int64_t i;
273b65be 1854 int ret = 0;
50842bdc
PP
1855 struct bt_field_array *array = container_of(
1856 field, struct bt_field_array, parent);
273b65be 1857
fc25abce
PP
1858 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64 ", "
1859 "native-bo=%s", field, pos->offset,
50842bdc 1860 bt_byte_order_string(native_byte_order));
fc25abce 1861
273b65be 1862 for (i = 0; i < array->elements->len; i++) {
50842bdc 1863 struct bt_field *elem_field =
fc25abce
PP
1864 g_ptr_array_index(array->elements, i);
1865
1866 BT_LOGV("Serializing array field's element field: "
1867 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
1868 pos->offset, elem_field, i);
f6ccaed9 1869 ret = bt_field_serialize_recursive(elem_field, pos,
dc3fffef 1870 native_byte_order);
273b65be 1871 if (ret) {
fc25abce
PP
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);
273b65be
JG
1875 goto end;
1876 }
1877 }
f6ccaed9 1878
273b65be
JG
1879end:
1880 return ret;
1881}
1882
1883static
f6ccaed9 1884int bt_field_sequence_serialize_recursive(struct bt_field *field,
50842bdc
PP
1885 struct bt_stream_pos *pos,
1886 enum bt_byte_order native_byte_order)
273b65be 1887{
fc25abce 1888 int64_t i;
273b65be 1889 int ret = 0;
50842bdc
PP
1890 struct bt_field_sequence *sequence = container_of(
1891 field, struct bt_field_sequence, parent);
273b65be 1892
fc25abce
PP
1893 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64 ", "
1894 "native-bo=%s", field, pos->offset,
50842bdc 1895 bt_byte_order_string(native_byte_order));
fc25abce 1896
273b65be 1897 for (i = 0; i < sequence->elements->len; i++) {
50842bdc 1898 struct bt_field *elem_field =
fc25abce
PP
1899 g_ptr_array_index(sequence->elements, i);
1900
1901 BT_LOGV("Serializing sequence field's element field: "
1902 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
1903 pos->offset, elem_field, i);
f6ccaed9 1904 ret = bt_field_serialize_recursive(elem_field, pos,
dc3fffef 1905 native_byte_order);
273b65be 1906 if (ret) {
fc25abce
PP
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);
273b65be
JG
1910 goto end;
1911 }
1912 }
f6ccaed9 1913
273b65be
JG
1914end:
1915 return ret;
1916}
1917
1918static
f6ccaed9 1919int bt_field_string_serialize(struct bt_field *field, struct bt_stream_pos *pos,
50842bdc 1920 enum bt_byte_order native_byte_order)
273b65be 1921{
fc25abce 1922 int64_t i;
273b65be 1923 int ret = 0;
50842bdc
PP
1924 struct bt_field_string *string = container_of(field,
1925 struct bt_field_string, parent);
1926 struct bt_field_type *character_type =
273b65be 1927 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
50842bdc 1928 struct bt_field *character;
fc25abce 1929
f6ccaed9 1930 BT_ASSERT_PRE_FIELD_IS_SET(field, "String field");
fc25abce
PP
1931 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64 ", "
1932 "native-bo=%s", field, pos->offset,
50842bdc 1933 bt_byte_order_string(native_byte_order));
fc25abce
PP
1934
1935 BT_LOGV_STR("Creating character field from string field's character field type.");
50842bdc 1936 character = bt_field_create(character_type);
273b65be
JG
1937
1938 for (i = 0; i < string->payload->len + 1; i++) {
fc25abce
PP
1939 const uint64_t chr = (uint64_t) string->payload->str[i];
1940
50842bdc 1941 ret = bt_field_unsigned_integer_set_value(character, chr);
f6ccaed9 1942 BT_ASSERT(ret == 0);
fc25abce
PP
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);
50842bdc 1947 ret = bt_field_integer_serialize(character, pos,
dc3fffef 1948 native_byte_order);
273b65be 1949 if (ret) {
b3376dd9 1950 BT_LOGW_STR("Cannot serialize character field.");
273b65be
JG
1951 goto end;
1952 }
1953 }
f6ccaed9 1954
273b65be 1955end:
83509119
JG
1956 bt_put(character);
1957 bt_put(character_type);
273b65be
JG
1958 return ret;
1959}
1960
87d43dc1 1961static
f6ccaed9 1962int bt_field_integer_copy(struct bt_field *src, struct bt_field *dst)
87d43dc1 1963{
50842bdc 1964 struct bt_field_integer *integer_src, *integer_dst;
87d43dc1 1965
fc25abce
PP
1966 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
1967 src, dst);
50842bdc
PP
1968 integer_src = container_of(src, struct bt_field_integer, parent);
1969 integer_dst = container_of(dst, struct bt_field_integer, parent);
dc3fffef 1970 integer_dst->payload = integer_src->payload;
fc25abce 1971 BT_LOGD_STR("Copied integer field.");
87d43dc1
JG
1972 return 0;
1973}
1974
1975static
f6ccaed9 1976int bt_field_enumeration_copy_recursive(struct bt_field *src,
50842bdc 1977 struct bt_field *dst)
87d43dc1
JG
1978{
1979 int ret = 0;
50842bdc 1980 struct bt_field_enumeration *enum_src, *enum_dst;
87d43dc1 1981
fc25abce
PP
1982 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
1983 src, dst);
50842bdc
PP
1984 enum_src = container_of(src, struct bt_field_enumeration, parent);
1985 enum_dst = container_of(dst, struct bt_field_enumeration, parent);
87d43dc1
JG
1986
1987 if (enum_src->payload) {
fc25abce 1988 BT_LOGD_STR("Copying enumeration field's payload field.");
50842bdc 1989 enum_dst->payload = bt_field_copy(enum_src->payload);
87d43dc1 1990 if (!enum_dst->payload) {
fc25abce 1991 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
87d43dc1
JG
1992 ret = -1;
1993 goto end;
1994 }
1995 }
fc25abce
PP
1996
1997 BT_LOGD_STR("Copied enumeration field.");
87d43dc1
JG
1998end:
1999 return ret;
2000}
2001
2002static
f6ccaed9 2003int bt_field_floating_point_copy(struct bt_field *src, struct bt_field *dst)
87d43dc1 2004{
50842bdc 2005 struct bt_field_floating_point *float_src, *float_dst;
87d43dc1 2006
fc25abce
PP
2007 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2008 src, dst);
50842bdc 2009 float_src = container_of(src, struct bt_field_floating_point,
87d43dc1 2010 parent);
50842bdc 2011 float_dst = container_of(dst, struct bt_field_floating_point,
87d43dc1 2012 parent);
dc3fffef 2013 float_dst->payload = float_src->payload;
fc25abce 2014 BT_LOGD_STR("Copied floating point number field.");
87d43dc1
JG
2015 return 0;
2016}
2017
2018static
f6ccaed9 2019int bt_field_structure_copy_recursive(struct bt_field *src,
50842bdc 2020 struct bt_field *dst)
87d43dc1 2021{
fc25abce
PP
2022 int ret = 0;
2023 int64_t i;
50842bdc 2024 struct bt_field_structure *struct_src, *struct_dst;
87d43dc1 2025
fc25abce
PP
2026 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2027 src, dst);
50842bdc
PP
2028 struct_src = container_of(src, struct bt_field_structure, parent);
2029 struct_dst = container_of(dst, struct bt_field_structure, parent);
87d43dc1 2030
8bfa3f9c 2031 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
2032
2033 for (i = 0; i < struct_src->fields->len; i++) {
50842bdc 2034 struct bt_field *field =
50fd95bf 2035 g_ptr_array_index(struct_src->fields, i);
50842bdc 2036 struct bt_field *field_copy = NULL;
87d43dc1 2037
50fd95bf 2038 if (field) {
32e87ceb 2039 BT_LOGD("Copying structure field's field: src-field-addr=%p"
fc25abce 2040 "index=%" PRId64, field, i);
50842bdc 2041 field_copy = bt_field_copy(field);
50fd95bf 2042 if (!field_copy) {
fc25abce
PP
2043 BT_LOGE("Cannot copy structure field's field: "
2044 "src-field-addr=%p, index=%" PRId64,
2045 field, i);
50fd95bf
PP
2046 ret = -1;
2047 goto end;
2048 }
87d43dc1 2049 }
50fd95bf 2050
c58b9c62 2051 BT_MOVE(g_ptr_array_index(struct_dst->fields, i), field_copy);
87d43dc1 2052 }
fc25abce
PP
2053
2054 BT_LOGD_STR("Copied structure field.");
2055
87d43dc1
JG
2056end:
2057 return ret;
2058}
2059
2060static
f6ccaed9 2061int bt_field_variant_copy_recursive(struct bt_field *src,
50842bdc 2062 struct bt_field *dst)
87d43dc1
JG
2063{
2064 int ret = 0;
50842bdc 2065 struct bt_field_variant *variant_src, *variant_dst;
87d43dc1 2066
fc25abce
PP
2067 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2068 src, dst);
50842bdc
PP
2069 variant_src = container_of(src, struct bt_field_variant, parent);
2070 variant_dst = container_of(dst, struct bt_field_variant, parent);
87d43dc1
JG
2071
2072 if (variant_src->tag) {
fc25abce 2073 BT_LOGD_STR("Copying variant field's tag field.");
50842bdc 2074 variant_dst->tag = bt_field_copy(variant_src->tag);
87d43dc1 2075 if (!variant_dst->tag) {
fc25abce 2076 BT_LOGE_STR("Cannot copy variant field's tag field.");
87d43dc1
JG
2077 ret = -1;
2078 goto end;
2079 }
2080 }
2081 if (variant_src->payload) {
fc25abce 2082 BT_LOGD_STR("Copying variant field's payload field.");
50842bdc 2083 variant_dst->payload = bt_field_copy(variant_src->payload);
87d43dc1 2084 if (!variant_dst->payload) {
fc25abce 2085 BT_LOGE_STR("Cannot copy variant field's payload field.");
87d43dc1
JG
2086 ret = -1;
2087 goto end;
2088 }
2089 }
fc25abce
PP
2090
2091 BT_LOGD_STR("Copied variant field.");
2092
87d43dc1
JG
2093end:
2094 return ret;
2095}
2096
2097static
f6ccaed9 2098int bt_field_array_copy_recursive(struct bt_field *src,
50842bdc 2099 struct bt_field *dst)
87d43dc1 2100{
fc25abce
PP
2101 int ret = 0;
2102 int64_t i;
50842bdc 2103 struct bt_field_array *array_src, *array_dst;
87d43dc1 2104
fc25abce
PP
2105 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2106 src, dst);
50842bdc
PP
2107 array_src = container_of(src, struct bt_field_array, parent);
2108 array_dst = container_of(dst, struct bt_field_array, parent);
87d43dc1 2109
8bfa3f9c 2110 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1 2111 for (i = 0; i < array_src->elements->len; i++) {
50842bdc 2112 struct bt_field *field =
50fd95bf 2113 g_ptr_array_index(array_src->elements, i);
50842bdc 2114 struct bt_field *field_copy = NULL;
87d43dc1 2115
50fd95bf 2116 if (field) {
fc25abce
PP
2117 BT_LOGD("Copying array field's element field: field-addr=%p, "
2118 "index=%" PRId64, field, i);
50842bdc 2119 field_copy = bt_field_copy(field);
50fd95bf 2120 if (!field_copy) {
fc25abce
PP
2121 BT_LOGE("Cannot copy array field's element field: "
2122 "src-field-addr=%p, index=%" PRId64,
2123 field, i);
50fd95bf
PP
2124 ret = -1;
2125 goto end;
2126 }
87d43dc1 2127 }
50fd95bf 2128
8bfa3f9c 2129 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1 2130 }
fc25abce
PP
2131
2132 BT_LOGD_STR("Copied array field.");
2133
87d43dc1
JG
2134end:
2135 return ret;
2136}
2137
2138static
f6ccaed9 2139int bt_field_sequence_copy_recursive(struct bt_field *src,
50842bdc 2140 struct bt_field *dst)
87d43dc1 2141{
fc25abce
PP
2142 int ret = 0;
2143 int64_t i;
50842bdc
PP
2144 struct bt_field_sequence *sequence_src, *sequence_dst;
2145 struct bt_field *src_length;
2146 struct bt_field *dst_length;
87d43dc1 2147
fc25abce
PP
2148 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2149 src, dst);
50842bdc
PP
2150 sequence_src = container_of(src, struct bt_field_sequence, parent);
2151 sequence_dst = container_of(dst, struct bt_field_sequence, parent);
87d43dc1 2152
50842bdc 2153 src_length = bt_field_sequence_get_length(src);
59ab494d
PP
2154 if (!src_length) {
2155 /* no length set yet: keep destination sequence empty */
2156 goto end;
2157 }
2158
2159 /* copy source length */
fc25abce 2160 BT_LOGD_STR("Copying sequence field's length field.");
50842bdc 2161 dst_length = bt_field_copy(src_length);
fc25abce 2162 BT_PUT(src_length);
59ab494d 2163 if (!dst_length) {
fc25abce 2164 BT_LOGE_STR("Cannot copy sequence field's length field.");
59ab494d
PP
2165 ret = -1;
2166 goto end;
2167 }
2168
2169 /* this will initialize the destination sequence's internal array */
50842bdc 2170 ret = bt_field_sequence_set_length(dst, dst_length);
83509119 2171 bt_put(dst_length);
59ab494d 2172 if (ret) {
fc25abce
PP
2173 BT_LOGE("Cannot set sequence field copy's length field: "
2174 "dst-length-field-addr=%p", dst_length);
2175 ret = -1;
59ab494d
PP
2176 goto end;
2177 }
2178
f6ccaed9 2179 BT_ASSERT(sequence_dst->elements->len == sequence_src->elements->len);
59ab494d 2180
87d43dc1 2181 for (i = 0; i < sequence_src->elements->len; i++) {
50842bdc 2182 struct bt_field *field =
50fd95bf 2183 g_ptr_array_index(sequence_src->elements, i);
50842bdc 2184 struct bt_field *field_copy = NULL;
87d43dc1 2185
50fd95bf 2186 if (field) {
fc25abce
PP
2187 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2188 "index=%" PRId64, field, i);
50842bdc 2189 field_copy = bt_field_copy(field);
50fd95bf 2190 if (!field_copy) {
fc25abce
PP
2191 BT_LOGE("Cannot copy sequence field's element field: "
2192 "src-field-addr=%p, index=%" PRId64,
2193 field, i);
50fd95bf
PP
2194 ret = -1;
2195 goto end;
2196 }
87d43dc1 2197 }
59ab494d 2198
8bfa3f9c 2199 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1 2200 }
fc25abce
PP
2201
2202 BT_LOGD_STR("Copied sequence field.");
2203
87d43dc1
JG
2204end:
2205 return ret;
2206}
2207
2208static
f6ccaed9 2209int bt_field_string_copy_recursive(struct bt_field *src,
50842bdc 2210 struct bt_field *dst)
87d43dc1
JG
2211{
2212 int ret = 0;
50842bdc 2213 struct bt_field_string *string_src, *string_dst;
87d43dc1 2214
fc25abce
PP
2215 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
2216 src, dst);
50842bdc
PP
2217 string_src = container_of(src, struct bt_field_string, parent);
2218 string_dst = container_of(dst, struct bt_field_string, parent);
87d43dc1
JG
2219
2220 if (string_src->payload) {
2221 string_dst->payload = g_string_new(string_src->payload->str);
2222 if (!string_dst->payload) {
fc25abce 2223 BT_LOGE_STR("Failed to allocate a GString.");
87d43dc1
JG
2224 ret = -1;
2225 goto end;
2226 }
2227 }
fc25abce
PP
2228
2229 BT_LOGD_STR("Copied string field.");
2230
87d43dc1
JG
2231end:
2232 return ret;
2233}
2234
273b65be 2235static
50842bdc 2236int increase_packet_size(struct bt_stream_pos *pos)
273b65be
JG
2237{
2238 int ret;
2239
f6ccaed9 2240 BT_ASSERT(pos);
fc25abce
PP
2241 BT_LOGV("Increasing packet size: pos-offset=%" PRId64 ", "
2242 "cur-packet-size=%" PRIu64,
2243 pos->offset, pos->packet_size);
273b65be
JG
2244 ret = munmap_align(pos->base_mma);
2245 if (ret) {
c606e638
PP
2246 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
2247 ": ret=%d", ret);
273b65be
JG
2248 goto end;
2249 }
2250
2251 pos->packet_size += PACKET_LEN_INCREMENT;
d9548894
MD
2252 do {
2253 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
2254 pos->packet_size / CHAR_BIT);
2255 } while (ret == EINTR);
273b65be 2256 if (ret) {
c606e638
PP
2257 BT_LOGE_ERRNO("Failed to preallocate memory space",
2258 ": ret=%d", ret);
d9548894
MD
2259 errno = EINTR;
2260 ret = -1;
273b65be
JG
2261 goto end;
2262 }
2263
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) {
c606e638
PP
2267 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
2268 ": ret=%d", ret);
273b65be
JG
2269 ret = -1;
2270 }
fc25abce
PP
2271
2272 BT_LOGV("Increased packet size: pos-offset=%" PRId64 ", "
2273 "new-packet-size=%" PRIu64,
2274 pos->offset, pos->packet_size);
f6ccaed9 2275 BT_ASSERT(pos->packet_size % 8 == 0);
b3376dd9 2276
273b65be
JG
2277end:
2278 return ret;
2279}
918be005
PP
2280
2281static
50842bdc 2282void generic_field_freeze(struct bt_field *field)
918be005 2283{
d990a4fb 2284 field->frozen = true;
918be005
PP
2285}
2286
2287static
f6ccaed9 2288void bt_field_enumeration_freeze_recursive(struct bt_field *field)
918be005 2289{
50842bdc
PP
2290 struct bt_field_enumeration *enum_field =
2291 container_of(field, struct bt_field_enumeration, parent);
918be005 2292
fc25abce
PP
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);
f6ccaed9 2295 bt_field_freeze_recursive(enum_field->payload);
918be005
PP
2296 generic_field_freeze(field);
2297}
2298
2299static
f6ccaed9 2300void bt_field_structure_freeze_recursive(struct bt_field *field)
918be005 2301{
fc25abce 2302 int64_t i;
50842bdc
PP
2303 struct bt_field_structure *structure_field =
2304 container_of(field, struct bt_field_structure, parent);
918be005 2305
fc25abce
PP
2306 BT_LOGD("Freezing structure field object: addr=%p", field);
2307
918be005 2308 for (i = 0; i < structure_field->fields->len; i++) {
50842bdc 2309 struct bt_field *field =
918be005
PP
2310 g_ptr_array_index(structure_field->fields, i);
2311
fc25abce
PP
2312 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
2313 field, i);
f6ccaed9 2314 bt_field_freeze_recursive(field);
918be005
PP
2315 }
2316
2317 generic_field_freeze(field);
2318}
2319
2320static
f6ccaed9 2321void bt_field_variant_freeze_recursive(struct bt_field *field)
918be005 2322{
50842bdc
PP
2323 struct bt_field_variant *variant_field =
2324 container_of(field, struct bt_field_variant, parent);
918be005 2325
fc25abce
PP
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);
f6ccaed9 2328 bt_field_freeze_recursive(variant_field->tag);
fc25abce 2329 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field->payload);
f6ccaed9 2330 bt_field_freeze_recursive(variant_field->payload);
918be005
PP
2331 generic_field_freeze(field);
2332}
2333
2334static
f6ccaed9 2335void bt_field_array_freeze_recursive(struct bt_field *field)
918be005 2336{
fc25abce 2337 int64_t i;
50842bdc
PP
2338 struct bt_field_array *array_field =
2339 container_of(field, struct bt_field_array, parent);
918be005 2340
fc25abce
PP
2341 BT_LOGD("Freezing array field object: addr=%p", field);
2342
918be005 2343 for (i = 0; i < array_field->elements->len; i++) {
50842bdc 2344 struct bt_field *elem_field =
918be005
PP
2345 g_ptr_array_index(array_field->elements, i);
2346
fc25abce
PP
2347 BT_LOGD("Freezing array field object's element field: "
2348 "element-field-addr=%p, index=%" PRId64,
2349 elem_field, i);
f6ccaed9 2350 bt_field_freeze_recursive(elem_field);
918be005
PP
2351 }
2352
2353 generic_field_freeze(field);
2354}
2355
2356static
f6ccaed9 2357void bt_field_sequence_freeze_recursive(struct bt_field *field)
918be005 2358{
fc25abce 2359 int64_t i;
50842bdc
PP
2360 struct bt_field_sequence *sequence_field =
2361 container_of(field, struct bt_field_sequence, parent);
918be005 2362
fc25abce
PP
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);
f6ccaed9 2366 bt_field_freeze_recursive(sequence_field->length);
918be005
PP
2367
2368 for (i = 0; i < sequence_field->elements->len; i++) {
50842bdc 2369 struct bt_field *elem_field =
918be005
PP
2370 g_ptr_array_index(sequence_field->elements, i);
2371
fc25abce
PP
2372 BT_LOGD("Freezing sequence field object's element field: "
2373 "element-field-addr=%p, index=%" PRId64,
2374 elem_field, i);
f6ccaed9 2375 bt_field_freeze_recursive(elem_field);
918be005
PP
2376 }
2377
2378 generic_field_freeze(field);
2379}
2380
2381BT_HIDDEN
f6ccaed9 2382void _bt_field_freeze_recursive(struct bt_field *field)
918be005 2383{
50842bdc 2384 enum bt_field_type_id type_id;
35f77de4 2385
918be005
PP
2386 if (!field) {
2387 goto end;
2388 }
2389
fc25abce 2390 if (field->frozen) {
35f77de4
JG
2391 goto end;
2392 }
918be005 2393
fc25abce 2394 BT_LOGD("Freezing field object: addr=%p", field);
f6ccaed9 2395 BT_ASSERT(field_type_has_known_id(field->type));
50842bdc 2396 type_id = bt_field_get_type_id(field);
35f77de4 2397 field_freeze_funcs[type_id](field);
918be005
PP
2398end:
2399 return;
2400}
76f869ab
JG
2401
2402static
50842bdc 2403bt_bool bt_field_generic_is_set(struct bt_field *field)
76f869ab
JG
2404{
2405 return field && field->payload_set;
2406}
2407
2408static
f6ccaed9 2409bt_bool bt_field_enumeration_is_set_recursive(struct bt_field *field)
76f869ab 2410{
d4bf905a 2411 bt_bool is_set = BT_FALSE;
50842bdc 2412 struct bt_field_enumeration *enumeration;
76f869ab 2413
f6ccaed9 2414 BT_ASSERT(field);
50842bdc 2415 enumeration = container_of(field, struct bt_field_enumeration,
76f869ab
JG
2416 parent);
2417 if (!enumeration->payload) {
2418 goto end;
2419 }
2420
f6ccaed9 2421 is_set = bt_field_is_set_recursive(enumeration->payload);
76f869ab 2422end:
d4bf905a 2423 return is_set;
76f869ab
JG
2424}
2425
2426static
f6ccaed9 2427bt_bool bt_field_structure_is_set_recursive(struct bt_field *field)
76f869ab 2428{
d4bf905a 2429 bt_bool is_set = BT_FALSE;
76f869ab 2430 size_t i;
50842bdc 2431 struct bt_field_structure *structure;
76f869ab 2432
f6ccaed9 2433 BT_ASSERT(field);
50842bdc 2434 structure = container_of(field, struct bt_field_structure, parent);
76f869ab 2435 for (i = 0; i < structure->fields->len; i++) {
f6ccaed9 2436 is_set = bt_field_is_set_recursive(
f1367c62 2437 structure->fields->pdata[i]);
d4bf905a 2438 if (!is_set) {
76f869ab
JG
2439 goto end;
2440 }
2441 }
2442end:
d4bf905a 2443 return is_set;
76f869ab
JG
2444}
2445
2446static
f6ccaed9 2447bt_bool bt_field_variant_is_set_recursive(struct bt_field *field)
76f869ab 2448{
50842bdc 2449 struct bt_field_variant *variant;
76f869ab 2450
f6ccaed9 2451 BT_ASSERT(field);
50842bdc 2452 variant = container_of(field, struct bt_field_variant, parent);
f6ccaed9 2453 return bt_field_is_set_recursive(variant->payload);
76f869ab
JG
2454}
2455
2456static
f6ccaed9 2457bt_bool bt_field_array_is_set_recursive(struct bt_field *field)
76f869ab
JG
2458{
2459 size_t i;
d4bf905a 2460 bt_bool is_set = BT_FALSE;
50842bdc 2461 struct bt_field_array *array;
76f869ab 2462
f6ccaed9 2463 BT_ASSERT(field);
50842bdc 2464 array = container_of(field, struct bt_field_array, parent);
76f869ab 2465 for (i = 0; i < array->elements->len; i++) {
f6ccaed9 2466 is_set = bt_field_is_set_recursive(array->elements->pdata[i]);
d4bf905a 2467 if (!is_set) {
76f869ab
JG
2468 goto end;
2469 }
2470 }
2471end:
d4bf905a 2472 return is_set;
76f869ab
JG
2473}
2474
2475static
f6ccaed9 2476bt_bool bt_field_sequence_is_set_recursive(struct bt_field *field)
76f869ab
JG
2477{
2478 size_t i;
d4bf905a 2479 bt_bool is_set = BT_FALSE;
50842bdc 2480 struct bt_field_sequence *sequence;
76f869ab 2481
f6ccaed9 2482 BT_ASSERT(field);
50842bdc 2483 sequence = container_of(field, struct bt_field_sequence, parent);
6ead1648
JG
2484 if (!sequence->elements) {
2485 goto end;
2486 }
2487
76f869ab 2488 for (i = 0; i < sequence->elements->len; i++) {
f6ccaed9 2489 is_set = bt_field_is_set_recursive(sequence->elements->pdata[i]);
d4bf905a 2490 if (!is_set) {
76f869ab
JG
2491 goto end;
2492 }
2493 }
2494end:
d4bf905a 2495 return is_set;
76f869ab 2496}
This page took 0.269618 seconds and 4 git commands to generate.