Add internal BT_ASSERT() and BT_ASSERT_PRE() helpers
[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>
fc25abce 40#include <inttypes.h>
273b65be 41
273b65be 42static
50842bdc 43struct bt_field *bt_field_integer_create(struct bt_field_type *);
273b65be 44static
50842bdc
PP
45struct bt_field *bt_field_enumeration_create(
46 struct bt_field_type *);
273b65be 47static
50842bdc
PP
48struct bt_field *bt_field_floating_point_create(
49 struct bt_field_type *);
273b65be 50static
50842bdc
PP
51struct bt_field *bt_field_structure_create(
52 struct bt_field_type *);
273b65be 53static
50842bdc
PP
54struct bt_field *bt_field_variant_create(
55 struct bt_field_type *);
273b65be 56static
50842bdc
PP
57struct bt_field *bt_field_array_create(
58 struct bt_field_type *);
273b65be 59static
50842bdc
PP
60struct bt_field *bt_field_sequence_create(
61 struct bt_field_type *);
273b65be 62static
50842bdc 63struct bt_field *bt_field_string_create(struct bt_field_type *);
273b65be
JG
64
65static
50842bdc 66void bt_field_destroy(struct bt_object *);
273b65be 67static
50842bdc 68void bt_field_integer_destroy(struct bt_field *);
273b65be 69static
50842bdc 70void bt_field_enumeration_destroy(struct bt_field *);
273b65be 71static
50842bdc 72void bt_field_floating_point_destroy(struct bt_field *);
273b65be 73static
50842bdc 74void bt_field_structure_destroy(struct bt_field *);
273b65be 75static
50842bdc 76void bt_field_variant_destroy(struct bt_field *);
273b65be 77static
50842bdc 78void bt_field_array_destroy(struct bt_field *);
273b65be 79static
50842bdc 80void bt_field_sequence_destroy(struct bt_field *);
273b65be 81static
50842bdc 82void bt_field_string_destroy(struct bt_field *);
273b65be
JG
83
84static
50842bdc 85int bt_field_generic_validate(struct bt_field *);
273b65be 86static
50842bdc 87int bt_field_structure_validate(struct bt_field *);
273b65be 88static
50842bdc 89int bt_field_variant_validate(struct bt_field *);
273b65be 90static
50842bdc 91int bt_field_enumeration_validate(struct bt_field *);
273b65be 92static
50842bdc 93int bt_field_array_validate(struct bt_field *);
273b65be 94static
50842bdc 95int bt_field_sequence_validate(struct bt_field *);
273b65be 96
12c8a1a3 97static
50842bdc 98int bt_field_generic_reset(struct bt_field *);
12c8a1a3 99static
50842bdc 100int bt_field_structure_reset(struct bt_field *);
12c8a1a3 101static
50842bdc 102int bt_field_variant_reset(struct bt_field *);
12c8a1a3 103static
50842bdc 104int bt_field_enumeration_reset(struct bt_field *);
12c8a1a3 105static
50842bdc 106int bt_field_array_reset(struct bt_field *);
12c8a1a3 107static
50842bdc 108int bt_field_sequence_reset(struct bt_field *);
12c8a1a3 109static
50842bdc 110int bt_field_string_reset(struct bt_field *);
12c8a1a3 111
273b65be 112static
50842bdc
PP
113int bt_field_integer_serialize(struct bt_field *,
114 struct bt_stream_pos *, enum bt_byte_order);
273b65be 115static
50842bdc
PP
116int bt_field_enumeration_serialize(struct bt_field *,
117 struct bt_stream_pos *, enum bt_byte_order);
273b65be 118static
50842bdc
PP
119int bt_field_floating_point_serialize(struct bt_field *,
120 struct bt_stream_pos *, enum bt_byte_order);
273b65be 121static
50842bdc
PP
122int bt_field_structure_serialize(struct bt_field *,
123 struct bt_stream_pos *, enum bt_byte_order);
273b65be 124static
50842bdc
PP
125int bt_field_variant_serialize(struct bt_field *,
126 struct bt_stream_pos *, enum bt_byte_order);
273b65be 127static
50842bdc
PP
128int bt_field_array_serialize(struct bt_field *,
129 struct bt_stream_pos *, enum bt_byte_order);
273b65be 130static
50842bdc
PP
131int bt_field_sequence_serialize(struct bt_field *,
132 struct bt_stream_pos *, enum bt_byte_order);
273b65be 133static
50842bdc
PP
134int bt_field_string_serialize(struct bt_field *,
135 struct bt_stream_pos *, enum bt_byte_order);
273b65be 136
87d43dc1 137static
50842bdc 138int bt_field_integer_copy(struct bt_field *, struct bt_field *);
87d43dc1 139static
50842bdc 140int bt_field_enumeration_copy(struct bt_field *, struct bt_field *);
87d43dc1 141static
50842bdc
PP
142int bt_field_floating_point_copy(struct bt_field *,
143 struct bt_field *);
87d43dc1 144static
50842bdc 145int bt_field_structure_copy(struct bt_field *, struct bt_field *);
87d43dc1 146static
50842bdc 147int bt_field_variant_copy(struct bt_field *, struct bt_field *);
87d43dc1 148static
50842bdc 149int bt_field_array_copy(struct bt_field *, struct bt_field *);
87d43dc1 150static
50842bdc 151int bt_field_sequence_copy(struct bt_field *, struct bt_field *);
87d43dc1 152static
50842bdc 153int bt_field_string_copy(struct bt_field *, struct bt_field *);
87d43dc1 154
918be005 155static
50842bdc 156void generic_field_freeze(struct bt_field *);
918be005 157static
50842bdc 158void bt_field_enumeration_freeze(struct bt_field *);
918be005 159static
50842bdc 160void bt_field_structure_freeze(struct bt_field *);
918be005 161static
50842bdc 162void bt_field_variant_freeze(struct bt_field *);
918be005 163static
50842bdc 164void bt_field_array_freeze(struct bt_field *);
918be005 165static
50842bdc 166void bt_field_sequence_freeze(struct bt_field *);
918be005 167
76f869ab 168static
50842bdc 169bt_bool bt_field_generic_is_set(struct bt_field *);
76f869ab 170static
50842bdc 171bt_bool bt_field_structure_is_set(struct bt_field *);
76f869ab 172static
50842bdc 173bt_bool bt_field_variant_is_set(struct bt_field *);
76f869ab 174static
50842bdc 175bt_bool bt_field_enumeration_is_set(struct bt_field *);
76f869ab 176static
50842bdc 177bt_bool bt_field_array_is_set(struct bt_field *);
76f869ab 178static
50842bdc 179bt_bool bt_field_sequence_is_set(struct bt_field *);
76f869ab 180
273b65be 181static
50842bdc 182int increase_packet_size(struct bt_stream_pos *pos);
273b65be
JG
183
184static
50842bdc
PP
185struct bt_field *(* const field_create_funcs[])(
186 struct bt_field_type *) = {
187 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_create,
188 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_create,
189 [BT_FIELD_TYPE_ID_FLOAT] =
190 bt_field_floating_point_create,
191 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_create,
192 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_create,
193 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_create,
194 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_create,
195 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_create,
273b65be
JG
196};
197
198static
50842bdc
PP
199void (* const field_destroy_funcs[])(struct bt_field *) = {
200 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_destroy,
201 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_destroy,
202 [BT_FIELD_TYPE_ID_FLOAT] =
203 bt_field_floating_point_destroy,
204 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_destroy,
205 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_destroy,
206 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_destroy,
207 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_destroy,
208 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_destroy,
273b65be
JG
209};
210
211static
50842bdc
PP
212int (* const field_validate_funcs[])(struct bt_field *) = {
213 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_generic_validate,
214 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_validate,
215 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_generic_validate,
216 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_validate,
217 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_validate,
218 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_validate,
219 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_validate,
220 [BT_FIELD_TYPE_ID_STRING] = bt_field_generic_validate,
273b65be
JG
221};
222
12c8a1a3 223static
50842bdc
PP
224int (* const field_reset_funcs[])(struct bt_field *) = {
225 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_generic_reset,
226 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_reset,
227 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_generic_reset,
228 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_reset,
229 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_reset,
230 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_reset,
231 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_reset,
232 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_reset,
12c8a1a3
JG
233};
234
273b65be 235static
50842bdc
PP
236int (* const field_serialize_funcs[])(struct bt_field *,
237 struct bt_stream_pos *, enum bt_byte_order) = {
238 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_serialize,
239 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_serialize,
240 [BT_FIELD_TYPE_ID_FLOAT] =
241 bt_field_floating_point_serialize,
242 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_serialize,
243 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_serialize,
244 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_serialize,
245 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_serialize,
246 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_serialize,
273b65be
JG
247};
248
87d43dc1 249static
50842bdc
PP
250int (* const field_copy_funcs[])(struct bt_field *,
251 struct bt_field *) = {
252 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_copy,
253 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_copy,
254 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_copy,
255 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_copy,
256 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_copy,
257 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_copy,
258 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_copy,
259 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_copy,
87d43dc1
JG
260};
261
918be005 262static
50842bdc
PP
263void (* const field_freeze_funcs[])(struct bt_field *) = {
264 [BT_FIELD_TYPE_ID_INTEGER] = generic_field_freeze,
265 [BT_FIELD_TYPE_ID_FLOAT] = generic_field_freeze,
266 [BT_FIELD_TYPE_ID_STRING] = generic_field_freeze,
267 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_freeze,
268 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_freeze,
269 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_freeze,
270 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_freeze,
271 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_freeze,
918be005
PP
272};
273
76f869ab 274static
50842bdc
PP
275bt_bool (* const field_is_set_funcs[])(struct bt_field *) = {
276 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_generic_is_set,
277 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_is_set,
278 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_generic_is_set,
279 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_is_set,
280 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_is_set,
281 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_is_set,
282 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_is_set,
283 [BT_FIELD_TYPE_ID_STRING] = bt_field_generic_is_set,
76f869ab
JG
284};
285
50842bdc 286struct bt_field *bt_field_create(struct bt_field_type *type)
273b65be 287{
50842bdc
PP
288 struct bt_field *field = NULL;
289 enum bt_field_type_id type_id;
81e36fac 290 int ret;
273b65be
JG
291
292 if (!type) {
fc25abce 293 BT_LOGW_STR("Invalid parameter: field type is NULL.");
273b65be
JG
294 goto error;
295 }
296
50842bdc
PP
297 type_id = bt_field_type_get_type_id(type);
298 if (type_id <= BT_FIELD_TYPE_ID_UNKNOWN ||
299 type_id >= BT_FIELD_TYPE_ID_NR) {
fc25abce
PP
300 BT_LOGW("Invalid parameter: unknown field type ID: "
301 "ft-addr=%p, ft-id=%d", type, type_id);
81e36fac
PP
302 goto error;
303 }
304
305 /* Field class MUST be valid */
50842bdc 306 ret = bt_field_type_validate(type);
81e36fac
PP
307 if (ret) {
308 /* Invalid */
fc25abce
PP
309 BT_LOGW("Invalid parameter: field type is invalid: "
310 "ft-addr=%p", type);
273b65be
JG
311 goto error;
312 }
313
314 field = field_create_funcs[type_id](type);
315 if (!field) {
316 goto error;
317 }
318
319 /* The type's declaration can't change after this point */
50842bdc 320 bt_field_type_freeze(type);
83509119 321 bt_get(type);
50842bdc 322 bt_object_init(field, bt_field_destroy);
273b65be
JG
323 field->type = type;
324error:
325 return field;
326}
327
fc25abce 328/* Pre-2.0 CTF writer backward compatibility */
50842bdc 329void bt_ctf_field_get(struct bt_field *field)
273b65be 330{
83509119 331 bt_get(field);
273b65be
JG
332}
333
fc25abce 334/* Pre-2.0 CTF writer backward compatibility */
50842bdc 335void bt_ctf_field_put(struct bt_field *field)
273b65be 336{
83509119 337 bt_put(field);
273b65be
JG
338}
339
50842bdc 340struct bt_field_type *bt_field_get_type(struct bt_field *field)
cd95e351 341{
50842bdc 342 struct bt_field_type *ret = NULL;
cd95e351
JG
343
344 if (!field) {
fc25abce 345 BT_LOGW_STR("Invalid parameter: field is NULL.");
cd95e351
JG
346 goto end;
347 }
348
349 ret = field->type;
83509119 350 bt_get(ret);
cd95e351
JG
351end:
352 return ret;
353}
354
50842bdc 355enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
4ebcc695 356{
50842bdc 357 enum bt_field_type_id ret = BT_FIELD_TYPE_ID_UNKNOWN;
4ebcc695
PP
358
359 if (!field) {
fc25abce 360 BT_LOGW_STR("Invalid parameter: field is NULL.");
4ebcc695
PP
361 goto end;
362 }
363
50842bdc 364 ret = bt_field_type_get_type_id(field->type);
4ebcc695
PP
365end:
366 return ret;
367}
368
50842bdc 369bt_bool bt_field_is_integer(struct bt_field *field)
8f3553be 370{
50842bdc 371 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_INTEGER;
8f3553be
PP
372}
373
50842bdc 374bt_bool bt_field_is_floating_point(struct bt_field *field)
8f3553be 375{
50842bdc 376 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_FLOAT;
8f3553be
PP
377}
378
50842bdc 379bt_bool bt_field_is_enumeration(struct bt_field *field)
8f3553be 380{
50842bdc 381 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ENUM;
8f3553be
PP
382}
383
50842bdc 384bt_bool bt_field_is_string(struct bt_field *field)
8f3553be 385{
50842bdc 386 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRING;
8f3553be
PP
387}
388
50842bdc 389bt_bool bt_field_is_structure(struct bt_field *field)
8f3553be 390{
50842bdc 391 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRUCT;
8f3553be
PP
392}
393
50842bdc 394bt_bool bt_field_is_array(struct bt_field *field)
8f3553be 395{
50842bdc 396 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ARRAY;
8f3553be
PP
397}
398
50842bdc 399bt_bool bt_field_is_sequence(struct bt_field *field)
8f3553be 400{
50842bdc 401 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_SEQUENCE;
8f3553be
PP
402}
403
50842bdc 404bt_bool bt_field_is_variant(struct bt_field *field)
8f3553be 405{
50842bdc 406 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_VARIANT;
8f3553be
PP
407}
408
2e8876d3
PP
409BT_HIDDEN
410int64_t bt_field_sequence_get_int_length(struct bt_field *field)
411{
412 struct bt_field_sequence *sequence;
413 int64_t ret;
414
415 assert(field);
416 assert(bt_field_type_get_type_id(field->type) ==
417 BT_FIELD_TYPE_ID_SEQUENCE);
418 sequence = container_of(field, struct bt_field_sequence, parent);
419 if (!sequence->length) {
420 ret = -1;
421 goto end;
422 }
423
424 ret = (int64_t) sequence->elements->len;
425
426end:
427 return ret;
428}
429
50842bdc
PP
430struct bt_field *bt_field_sequence_get_length(
431 struct bt_field *field)
cd95e351 432{
50842bdc
PP
433 struct bt_field *ret = NULL;
434 struct bt_field_sequence *sequence;
cd95e351
JG
435
436 if (!field) {
fc25abce 437 BT_LOGW_STR("Invalid parameter: field is NULL.");
cd95e351
JG
438 goto end;
439 }
440
50842bdc
PP
441 if (bt_field_type_get_type_id(field->type) !=
442 BT_FIELD_TYPE_ID_SEQUENCE) {
fc25abce
PP
443 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
444 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
445 field->type,
50842bdc 446 bt_field_type_id_string(field->type->id));
cd95e351
JG
447 goto end;
448 }
449
50842bdc 450 sequence = container_of(field, struct bt_field_sequence, parent);
cd95e351 451 ret = sequence->length;
83509119 452 bt_get(ret);
cd95e351
JG
453end:
454 return ret;
455}
456
50842bdc
PP
457int bt_field_sequence_set_length(struct bt_field *field,
458 struct bt_field *length_field)
273b65be
JG
459{
460 int ret = 0;
50842bdc
PP
461 struct bt_field_type_integer *length_type;
462 struct bt_field_integer *length;
463 struct bt_field_sequence *sequence;
273b65be
JG
464 uint64_t sequence_length;
465
fc25abce
PP
466 if (!field) {
467 BT_LOGW_STR("Invalid parameter: field is NULL.");
468 ret = -1;
469 goto end;
470 }
471
472 if (!length_field) {
473 BT_LOGW_STR("Invalid parameter: length field is NULL.");
474 ret = -1;
475 goto end;
476 }
477
478 if (field->frozen) {
479 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
480 field);
273b65be
JG
481 ret = -1;
482 goto end;
483 }
fc25abce 484
50842bdc
PP
485 if (bt_field_type_get_type_id(length_field->type) !=
486 BT_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
487 BT_LOGW("Invalid parameter: length field's type is not an integer field type: "
488 "field-addr=%p, length-field-addr=%p, length-ft-addr=%p, length-ft-id=%s",
489 field, length_field, length_field->type,
50842bdc 490 bt_field_type_id_string(length_field->type->id));
273b65be
JG
491 ret = -1;
492 goto end;
493 }
494
495 length_type = container_of(length_field->type,
50842bdc 496 struct bt_field_type_integer, parent);
152e7331 497 /* The length field must be unsigned */
dc3fffef 498 if (length_type->is_signed) {
fc25abce
PP
499 BT_LOGW("Invalid parameter: length field's type is signed: "
500 "field-addr=%p, length-field-addr=%p, "
501 "length-field-ft-addr=%p", field, length_field,
502 length_field->type);
273b65be
JG
503 ret = -1;
504 goto end;
505 }
506
50842bdc 507 if (!bt_field_is_set(length_field)) {
a54f72f0
JG
508 BT_LOGW("Invalid parameter: length field's value is not set: "
509 "field-addr=%p, length-field-addr=%p, "
510 "length-field-ft-addr=%p", field, length_field,
511 length_field->type);
512 ret = -1;
513 goto end;
514 }
515
50842bdc 516 length = container_of(length_field, struct bt_field_integer,
273b65be 517 parent);
dc3fffef 518 sequence_length = length->payload.unsignd;
50842bdc 519 sequence = container_of(field, struct bt_field_sequence, parent);
273b65be
JG
520 if (sequence->elements) {
521 g_ptr_array_free(sequence->elements, TRUE);
83509119 522 bt_put(sequence->length);
273b65be
JG
523 }
524
f6fcfe74 525 sequence->elements = g_ptr_array_sized_new((size_t) sequence_length);
273b65be 526 if (!sequence->elements) {
fc25abce 527 BT_LOGE_STR("Failed to allocate a GPtrArray.");
273b65be
JG
528 ret = -1;
529 goto end;
530 }
531
fe0fe95c 532 g_ptr_array_set_free_func(sequence->elements,
83509119
JG
533 (GDestroyNotify) bt_put);
534 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
535 bt_get(length_field);
273b65be 536 sequence->length = length_field;
50842bdc 537 bt_field_freeze(length_field);
273b65be
JG
538end:
539 return ret;
540}
541
50842bdc
PP
542struct bt_field *bt_field_structure_get_field_by_name(
543 struct bt_field *field, const char *name)
273b65be 544{
50842bdc 545 struct bt_field *ret = NULL;
273b65be 546 GQuark field_quark;
50842bdc 547 struct bt_field_structure *structure;
273b65be 548 size_t index;
c58b9c62 549 GHashTable *field_name_to_index;
273b65be 550
fc25abce
PP
551 if (!field) {
552 BT_LOGW_STR("Invalid parameter: field is NULL.");
553 goto error;
554 }
555
556 if (!name) {
557 BT_LOGW_STR("Invalid parameter: field name is NULL.");
558 goto error;
559 }
560
50842bdc
PP
561 if (bt_field_type_get_type_id(field->type) !=
562 BT_FIELD_TYPE_ID_STRUCT) {
fc25abce
PP
563 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
564 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
565 field->type,
50842bdc 566 bt_field_type_id_string(field->type->id));
273b65be
JG
567 goto error;
568 }
569
c58b9c62 570 field_name_to_index =
50842bdc 571 container_of(field->type, struct bt_field_type_structure,
c58b9c62 572 parent)->field_name_to_index;
273b65be 573 field_quark = g_quark_from_string(name);
50842bdc 574 structure = container_of(field, struct bt_field_structure, parent);
c58b9c62 575 if (!g_hash_table_lookup_extended(field_name_to_index,
fc25abce
PP
576 GUINT_TO_POINTER(field_quark),
577 NULL, (gpointer *)&index)) {
6fa8d37b 578 BT_LOGV("Invalid parameter: no such field in structure field's type: "
c58b9c62
JG
579 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
580 field, field->type, name);
273b65be
JG
581 goto error;
582 }
583
c58b9c62
JG
584 ret = bt_get(structure->fields->pdata[index]);
585 assert(ret);
273b65be 586error:
c58b9c62 587 return ret;
273b65be
JG
588}
589
50842bdc
PP
590struct bt_field *bt_field_structure_get_field_by_index(
591 struct bt_field *field, uint64_t index)
cd95e351 592{
50842bdc
PP
593 struct bt_field_structure *structure;
594 struct bt_field *ret = NULL;
cd95e351 595
fc25abce
PP
596 if (!field) {
597 BT_LOGW_STR("Invalid parameter: field is NULL.");
598 goto end;
599 }
600
50842bdc
PP
601 if (bt_field_type_get_type_id(field->type) !=
602 BT_FIELD_TYPE_ID_STRUCT) {
fc25abce
PP
603 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
604 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
605 field->type,
50842bdc 606 bt_field_type_id_string(field->type->id));
cd95e351
JG
607 goto end;
608 }
609
50842bdc 610 structure = container_of(field, struct bt_field_structure, parent);
cd95e351 611 if (index >= structure->fields->len) {
fc25abce
PP
612 BT_LOGW("Invalid parameter: index is out of bounds: "
613 "addr=%p, index=%" PRIu64 ", count=%u",
614 field, index, structure->fields->len);
918be005
PP
615 goto end;
616 }
617
c58b9c62 618 ret = bt_get(structure->fields->pdata[index]);
cd95e351 619end:
c58b9c62 620 return ret;
cd95e351
JG
621}
622
50842bdc
PP
623int bt_field_structure_set_field_by_name(struct bt_field *field,
624 const char *name, struct bt_field *value)
273b65be
JG
625{
626 int ret = 0;
627 GQuark field_quark;
50842bdc
PP
628 struct bt_field_structure *structure;
629 struct bt_field_type *expected_field_type = NULL;
273b65be 630 size_t index;
c58b9c62 631 GHashTable *field_name_to_index;
273b65be 632
fc25abce
PP
633 if (!field) {
634 BT_LOGW_STR("Invalid parameter: structure field is NULL.");
635 ret = -1;
636 goto end;
637 }
638
639 if (!name) {
640 BT_LOGW_STR("Invalid parameter: field name is NULL.");
641 ret = -1;
642 goto end;
643 }
644
645 if (!value) {
646 BT_LOGW_STR("Invalid parameter: field is NULL.");
647 ret = -1;
648 goto end;
649 }
650
50842bdc
PP
651 if (bt_field_type_get_type_id(field->type) !=
652 BT_FIELD_TYPE_ID_STRUCT) {
fc25abce
PP
653 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
654 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
655 field->type,
50842bdc 656 bt_field_type_id_string(field->type->id));
273b65be
JG
657 ret = -1;
658 goto end;
659 }
660
661 field_quark = g_quark_from_string(name);
50842bdc 662 structure = container_of(field, struct bt_field_structure, parent);
b92ddaaa 663 expected_field_type =
50842bdc 664 bt_field_type_structure_get_field_type_by_name(field->type,
b92ddaaa 665 name);
09840de5 666
50842bdc 667 if (bt_field_type_compare(expected_field_type, value->type)) {
fc25abce
PP
668 BT_LOGW("Invalid parameter: field type of field to set is different from the expected field type: "
669 "struct-field-addr=%p, field-addr=%p, "
670 "field-ft-addr=%p, expected-ft-addr=%p",
671 field, value, value->type, expected_field_type);
273b65be
JG
672 ret = -1;
673 goto end;
674 }
675
c58b9c62 676 field_name_to_index =
50842bdc 677 container_of(field->type, struct bt_field_type_structure,
c58b9c62
JG
678 parent)->field_name_to_index;
679 if (!g_hash_table_lookup_extended(field_name_to_index,
680 GUINT_TO_POINTER(field_quark), NULL,
681 (gpointer *) &index)) {
6fa8d37b 682 BT_LOGV("Invalid parameter: no such field in structure field's type: "
fc25abce
PP
683 "struct-field-addr=%p, struct-ft-addr=%p, "
684 "field-ft-addr=%p, name=\"%s\"",
685 field, field->type, value->type, name);
686 ret = -1;
273b65be
JG
687 goto end;
688 }
83509119 689 bt_get(value);
c58b9c62 690 BT_MOVE(structure->fields->pdata[index], value);
273b65be 691end:
b92ddaaa 692 if (expected_field_type) {
83509119 693 bt_put(expected_field_type);
b92ddaaa 694 }
273b65be
JG
695 return ret;
696}
697
50842bdc 698struct bt_field *bt_field_array_get_field(struct bt_field *field,
273b65be
JG
699 uint64_t index)
700{
50842bdc
PP
701 struct bt_field *new_field = NULL;
702 struct bt_field_type *field_type = NULL;
703 struct bt_field_array *array;
273b65be 704
fc25abce
PP
705 if (!field) {
706 BT_LOGW_STR("Invalid parameter: field is NULL.");
707 goto end;
708 }
709
50842bdc
PP
710 if (bt_field_type_get_type_id(field->type) !=
711 BT_FIELD_TYPE_ID_ARRAY) {
fc25abce
PP
712 BT_LOGW("Invalid parameter: field's type is not an array field type: "
713 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
714 field->type,
50842bdc 715 bt_field_type_id_string(field->type->id));
273b65be
JG
716 goto end;
717 }
718
50842bdc 719 array = container_of(field, struct bt_field_array, parent);
273b65be 720 if (index >= array->elements->len) {
fc25abce
PP
721 BT_LOGW("Invalid parameter: index is out of bounds: "
722 "addr=%p, index=%" PRIu64 ", count=%u",
723 field, index, array->elements->len);
273b65be
JG
724 goto end;
725 }
726
50842bdc 727 field_type = bt_field_type_array_get_element_type(field->type);
273b65be
JG
728 if (array->elements->pdata[(size_t)index]) {
729 new_field = array->elements->pdata[(size_t)index];
730 goto end;
731 }
732
918be005
PP
733 /* We don't want to modify this field if it's frozen */
734 if (field->frozen) {
e67720a9
PP
735 /*
736 * Not logging a warning here because the user could
737 * legitimately check if a array field is set with
738 * this function: if the preconditions are satisfied,
739 * a NULL return value means this.
740 */
741 BT_LOGV("Not creating a field because array field is frozen: "
742 "array-field-addr=%p, index=%" PRIu64, field, index);
918be005
PP
743 goto end;
744 }
745
50842bdc 746 new_field = bt_field_create(field_type);
273b65be
JG
747 array->elements->pdata[(size_t)index] = new_field;
748end:
b92ddaaa 749 if (field_type) {
83509119 750 bt_put(field_type);
b92ddaaa 751 }
92c8b4f9 752 if (new_field) {
83509119 753 bt_get(new_field);
92c8b4f9 754 }
273b65be
JG
755 return new_field;
756}
757
50842bdc 758struct bt_field *bt_field_sequence_get_field(struct bt_field *field,
273b65be
JG
759 uint64_t index)
760{
50842bdc
PP
761 struct bt_field *new_field = NULL;
762 struct bt_field_type *field_type = NULL;
763 struct bt_field_sequence *sequence;
273b65be 764
fc25abce
PP
765 if (!field) {
766 BT_LOGW_STR("Invalid parameter: field is NULL.");
767 goto end;
768 }
769
50842bdc
PP
770 if (bt_field_type_get_type_id(field->type) !=
771 BT_FIELD_TYPE_ID_SEQUENCE) {
fc25abce
PP
772 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
773 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
774 field->type,
50842bdc 775 bt_field_type_id_string(field->type->id));
273b65be
JG
776 goto end;
777 }
778
50842bdc 779 sequence = container_of(field, struct bt_field_sequence, parent);
fc25abce 780 if (!sequence->elements) {
6fa8d37b 781 BT_LOGV("Sequence field's elements do not exist: addr=%p",
fc25abce
PP
782 field);
783 goto end;
784 }
785
786 if (index >= sequence->elements->len) {
787 BT_LOGW("Invalid parameter: index is out of bounds: "
788 "addr=%p, index=%" PRIu64 ", count=%u",
789 field, index, sequence->elements->len);
273b65be
JG
790 goto end;
791 }
792
50842bdc 793 field_type = bt_field_type_sequence_get_element_type(field->type);
83509119
JG
794 if (sequence->elements->pdata[(size_t) index]) {
795 new_field = sequence->elements->pdata[(size_t) index];
273b65be
JG
796 goto end;
797 }
798
918be005
PP
799 /* We don't want to modify this field if it's frozen */
800 if (field->frozen) {
e67720a9
PP
801 /*
802 * Not logging a warning here because the user could
803 * legitimately check if a sequence field is set with
804 * this function: if the preconditions are satisfied,
805 * a NULL return value means this.
806 */
807 BT_LOGV("Not creating a field because sequence field is frozen: "
808 "sequence-field-addr=%p, index=%" PRIu64, field, index);
918be005
PP
809 goto end;
810 }
811
50842bdc 812 new_field = bt_field_create(field_type);
83509119 813 sequence->elements->pdata[(size_t) index] = new_field;
273b65be 814end:
b92ddaaa 815 if (field_type) {
83509119 816 bt_put(field_type);
b92ddaaa 817 }
92c8b4f9 818 if (new_field) {
83509119 819 bt_get(new_field);
92c8b4f9 820 }
273b65be
JG
821 return new_field;
822}
823
50842bdc
PP
824struct bt_field *bt_field_variant_get_field(struct bt_field *field,
825 struct bt_field *tag_field)
273b65be 826{
50842bdc
PP
827 struct bt_field *new_field = NULL;
828 struct bt_field_variant *variant;
829 struct bt_field_type_variant *variant_type;
830 struct bt_field_type *field_type;
831 struct bt_field *tag_enum = NULL;
832 struct bt_field_integer *tag_enum_integer;
273b65be
JG
833 int64_t tag_enum_value;
834
fc25abce
PP
835 if (!field) {
836 BT_LOGW_STR("Invalid parameter: field is NULL.");
837 goto end;
838 }
839
840 if (!tag_field) {
841 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
842 goto end;
843 }
844
50842bdc
PP
845 if (bt_field_type_get_type_id(field->type) !=
846 BT_FIELD_TYPE_ID_VARIANT) {
fc25abce
PP
847 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
848 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
849 field->type,
50842bdc 850 bt_field_type_id_string(field->type->id));
fc25abce
PP
851 goto end;
852 }
853
50842bdc
PP
854 if (bt_field_type_get_type_id(tag_field->type) !=
855 BT_FIELD_TYPE_ID_ENUM) {
fc25abce
PP
856 BT_LOGW("Invalid parameter: tag field's type is not an enumeration field type: "
857 "field-addr=%p, ft-addr=%p, ft-id=%s", tag_field,
858 tag_field->type,
50842bdc 859 bt_field_type_id_string(tag_field->type->id));
273b65be
JG
860 goto end;
861 }
862
50842bdc 863 variant = container_of(field, struct bt_field_variant, parent);
273b65be 864 variant_type = container_of(field->type,
50842bdc
PP
865 struct bt_field_type_variant, parent);
866 tag_enum = bt_field_enumeration_get_container(tag_field);
273b65be
JG
867 if (!tag_enum) {
868 goto end;
869 }
870
50842bdc 871 tag_enum_integer = container_of(tag_enum, struct bt_field_integer,
273b65be
JG
872 parent);
873
50842bdc 874 if (bt_field_validate(tag_field) < 0) {
fc25abce
PP
875 BT_LOGW("Invalid parameter: tag field is invalid: "
876 "variant-field-addr=%p, tag-field-addr=%p",
877 field, tag_field);
273b65be
JG
878 goto end;
879 }
880
dc3fffef 881 tag_enum_value = tag_enum_integer->payload.signd;
2829190c
PP
882
883 /*
884 * If the variant currently has a tag and a payload, and if the
885 * requested tag value is the same as the current one, return
886 * the current payload instead of creating a fresh one.
887 */
888 if (variant->tag && variant->payload) {
50842bdc
PP
889 struct bt_field *cur_tag_container = NULL;
890 struct bt_field_integer *cur_tag_enum_integer;
2829190c
PP
891 int64_t cur_tag_value;
892
893 cur_tag_container =
50842bdc 894 bt_field_enumeration_get_container(variant->tag);
9a5df386 895 assert(cur_tag_container);
2829190c 896 cur_tag_enum_integer = container_of(cur_tag_container,
50842bdc 897 struct bt_field_integer, parent);
83509119 898 bt_put(cur_tag_container);
dc3fffef 899 cur_tag_value = cur_tag_enum_integer->payload.signd;
2829190c
PP
900
901 if (cur_tag_value == tag_enum_value) {
902 new_field = variant->payload;
83509119 903 bt_get(new_field);
2829190c
PP
904 goto end;
905 }
906 }
907
918be005
PP
908 /* We don't want to modify this field if it's frozen */
909 if (field->frozen) {
e67720a9
PP
910 /*
911 * Not logging a warning here because the user could
912 * legitimately check if a variant field is set with
913 * this function: if the preconditions are satisfied,
914 * a NULL return value means this.
915 */
916 BT_LOGV("Not creating a field because variant field is frozen: "
917 "variant-field-addr=%p, tag-field-addr=%p",
918 field, tag_field);
918be005
PP
919 goto end;
920 }
921
50842bdc 922 field_type = bt_field_type_variant_get_field_type_signed(
b92ddaaa 923 variant_type, tag_enum_value);
273b65be 924 if (!field_type) {
fc25abce
PP
925 BT_LOGW("Cannot get variant field type's field: "
926 "variant-field-addr=%p, variant-ft-addr=%p, "
927 "tag-value-signed=%" PRId64,
928 field, variant_type, tag_enum_value);
273b65be
JG
929 goto end;
930 }
931
50842bdc 932 new_field = bt_field_create(field_type);
273b65be 933 if (!new_field) {
fc25abce
PP
934 BT_LOGW("Cannot create field: "
935 "variant-field-addr=%p, variant-ft-addr=%p, "
936 "field-ft-addr=%p", field, field->type, field_type);
273b65be
JG
937 goto end;
938 }
939
83509119
JG
940 bt_put(variant->tag);
941 bt_put(variant->payload);
942 bt_get(new_field);
943 bt_get(tag_field);
273b65be
JG
944 variant->tag = tag_field;
945 variant->payload = new_field;
946end:
83509119 947 bt_put(tag_enum);
273b65be
JG
948 return new_field;
949}
950
50842bdc
PP
951struct bt_field *bt_field_variant_get_current_field(
952 struct bt_field *variant_field)
3f4a108d 953{
50842bdc
PP
954 struct bt_field *current_field = NULL;
955 struct bt_field_variant *variant;
3f4a108d 956
fc25abce
PP
957 if (!variant_field) {
958 BT_LOGW_STR("Invalid parameter: field is NULL.");
959 goto end;
960 }
961
50842bdc
PP
962 if (bt_field_type_get_type_id(variant_field->type) !=
963 BT_FIELD_TYPE_ID_VARIANT) {
fc25abce
PP
964 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
965 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field,
966 variant_field->type,
50842bdc 967 bt_field_type_id_string(variant_field->type->id));
3f4a108d
PP
968 goto end;
969 }
970
50842bdc 971 variant = container_of(variant_field, struct bt_field_variant,
3f4a108d
PP
972 parent);
973
974 if (variant->payload) {
975 current_field = variant->payload;
83509119 976 bt_get(current_field);
3f4a108d
PP
977 goto end;
978 }
979
980end:
981 return current_field;
982}
983
50842bdc
PP
984struct bt_field *bt_field_variant_get_tag(
985 struct bt_field *variant_field)
f78d67fb 986{
50842bdc
PP
987 struct bt_field *tag = NULL;
988 struct bt_field_variant *variant;
f78d67fb 989
fc25abce
PP
990 if (!variant_field) {
991 BT_LOGW_STR("Invalid parameter: field is NULL.");
992 goto end;
993 }
994
50842bdc
PP
995 if (bt_field_type_get_type_id(variant_field->type) !=
996 BT_FIELD_TYPE_ID_VARIANT) {
fc25abce
PP
997 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
998 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field,
999 variant_field->type,
50842bdc 1000 bt_field_type_id_string(variant_field->type->id));
f78d67fb
JG
1001 goto end;
1002 }
1003
50842bdc 1004 variant = container_of(variant_field, struct bt_field_variant,
f78d67fb
JG
1005 parent);
1006 if (variant->tag) {
1007 tag = bt_get(variant->tag);
1008 }
1009end:
1010 return tag;
1011}
1012
50842bdc
PP
1013struct bt_field *bt_field_enumeration_get_container(
1014 struct bt_field *field)
273b65be 1015{
50842bdc
PP
1016 struct bt_field *container = NULL;
1017 struct bt_field_enumeration *enumeration;
273b65be 1018
fc25abce
PP
1019 if (!field) {
1020 BT_LOGW_STR("Invalid parameter: field is NULL.");
1021 goto end;
1022 }
1023
50842bdc
PP
1024 if (bt_field_type_get_type_id(field->type) !=
1025 BT_FIELD_TYPE_ID_ENUM) {
fc25abce
PP
1026 BT_LOGW("Invalid parameter: field's type is not an enumeration field type: "
1027 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1028 field->type,
50842bdc 1029 bt_field_type_id_string(field->type->id));
273b65be
JG
1030 goto end;
1031 }
1032
50842bdc 1033 enumeration = container_of(field, struct bt_field_enumeration,
273b65be
JG
1034 parent);
1035 if (!enumeration->payload) {
918be005
PP
1036 /* We don't want to modify this field if it's frozen */
1037 if (field->frozen) {
e67720a9
PP
1038 /*
1039 * Not logging a warning here because the user
1040 * could legitimately check if an enumeration's
1041 * container field is set with this function: if
1042 * the preconditions are satisfied, a NULL
1043 * return value means this.
1044 */
1045 BT_LOGV("Not creating a field because enumeration field is frozen: "
1046 "enum-field-addr=%p", field);
918be005
PP
1047 goto end;
1048 }
1049
50842bdc 1050 struct bt_field_type_enumeration *enumeration_type =
273b65be 1051 container_of(field->type,
50842bdc 1052 struct bt_field_type_enumeration, parent);
273b65be 1053 enumeration->payload =
50842bdc 1054 bt_field_create(enumeration_type->container);
273b65be
JG
1055 }
1056
1057 container = enumeration->payload;
83509119 1058 bt_get(container);
273b65be
JG
1059end:
1060 return container;
1061}
1062
50842bdc
PP
1063struct bt_field_type_enumeration_mapping_iterator *
1064bt_field_enumeration_get_mappings(struct bt_field *field)
cd95e351
JG
1065{
1066 int ret;
50842bdc
PP
1067 struct bt_field *container = NULL;
1068 struct bt_field_type *container_type = NULL;
1069 struct bt_field_type_integer *integer_type = NULL;
1070 struct bt_field_type_enumeration_mapping_iterator *iter = NULL;
cd95e351 1071
50842bdc 1072 container = bt_field_enumeration_get_container(field);
cd95e351 1073 if (!container) {
fc25abce
PP
1074 BT_LOGW("Invalid parameter: enumeration field has no container field: "
1075 "addr=%p", field);
cd95e351
JG
1076 goto end;
1077 }
1078
50842bdc 1079 container_type = bt_field_get_type(container);
fc25abce 1080 assert(container_type);
cd95e351 1081 integer_type = container_of(container_type,
50842bdc 1082 struct bt_field_type_integer, parent);
cd95e351 1083
dc3fffef 1084 if (!integer_type->is_signed) {
cd95e351 1085 uint64_t value;
96e8f959 1086
50842bdc 1087 ret = bt_field_unsigned_integer_get_value(container,
cd95e351
JG
1088 &value);
1089 if (ret) {
fc25abce
PP
1090 BT_LOGW("Cannot get value from signed enumeration field's payload field: "
1091 "enum-field-addr=%p, payload-field-addr=%p",
1092 field, container);
cd95e351
JG
1093 goto error_put_container_type;
1094 }
50842bdc 1095 iter = bt_field_type_enumeration_find_mappings_by_unsigned_value(
96e8f959 1096 field->type, value);
cd95e351
JG
1097 } else {
1098 int64_t value;
96e8f959 1099
50842bdc 1100 ret = bt_field_signed_integer_get_value(container,
cd95e351
JG
1101 &value);
1102 if (ret) {
fc25abce
PP
1103 BT_LOGW("Cannot get value from unsigned enumeration field's payload field: "
1104 "enum-field-addr=%p, payload-field-addr=%p",
1105 field, container);
cd95e351
JG
1106 goto error_put_container_type;
1107 }
50842bdc 1108 iter = bt_field_type_enumeration_find_mappings_by_signed_value(
96e8f959 1109 field->type, value);
cd95e351
JG
1110 }
1111
1112error_put_container_type:
83509119 1113 bt_put(container_type);
83509119 1114 bt_put(container);
cd95e351 1115end:
e0f15669 1116 return iter;
cd95e351
JG
1117}
1118
50842bdc 1119int bt_field_signed_integer_get_value(struct bt_field *field,
cd95e351
JG
1120 int64_t *value)
1121{
1122 int ret = 0;
50842bdc
PP
1123 struct bt_field_integer *integer;
1124 struct bt_field_type_integer *integer_type;
cd95e351 1125
fc25abce
PP
1126 if (!field) {
1127 BT_LOGW_STR("Invalid parameter: field is NULL.");
1128 ret = -1;
1129 goto end;
1130 }
1131
1132 if (!value) {
1133 BT_LOGW_STR("Invalid parameter: value is NULL.");
1134 ret = -1;
1135 goto end;
1136 }
1137
1138 if (!field->payload_set) {
1139 BT_LOGV("Field's payload is not set: addr=%p", field);
1140 ret = -1;
1141 goto end;
1142 }
1143
50842bdc
PP
1144 if (bt_field_type_get_type_id(field->type) !=
1145 BT_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1146 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1147 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1148 field->type,
50842bdc 1149 bt_field_type_id_string(field->type->id));
cd95e351
JG
1150 ret = -1;
1151 goto end;
1152 }
1153
1154 integer_type = container_of(field->type,
50842bdc 1155 struct bt_field_type_integer, parent);
dc3fffef 1156 if (!integer_type->is_signed) {
fc25abce
PP
1157 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1158 "field-addr=%p, ft-addr=%p", field, field->type);
cd95e351
JG
1159 ret = -1;
1160 goto end;
1161 }
1162
1163 integer = container_of(field,
50842bdc 1164 struct bt_field_integer, parent);
dc3fffef 1165 *value = integer->payload.signd;
cd95e351
JG
1166end:
1167 return ret;
1168}
1169
50842bdc 1170int bt_field_signed_integer_set_value(struct bt_field *field,
273b65be
JG
1171 int64_t value)
1172{
1173 int ret = 0;
50842bdc
PP
1174 struct bt_field_integer *integer;
1175 struct bt_field_type_integer *integer_type;
273b65be
JG
1176 unsigned int size;
1177 int64_t min_value, max_value;
1178
fc25abce
PP
1179 if (!field) {
1180 BT_LOGW_STR("Invalid parameter: field is NULL.");
1181 ret = -1;
1182 goto end;
1183 }
1184
1185 if (field->frozen) {
1186 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1187 field);
1188 ret = -1;
1189 goto end;
1190 }
1191
50842bdc
PP
1192 if (bt_field_type_get_type_id(field->type) !=
1193 BT_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1194 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1195 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1196 field->type,
50842bdc 1197 bt_field_type_id_string(field->type->id));
273b65be
JG
1198 ret = -1;
1199 goto end;
1200 }
1201
50842bdc 1202 integer = container_of(field, struct bt_field_integer, parent);
273b65be 1203 integer_type = container_of(field->type,
50842bdc 1204 struct bt_field_type_integer, parent);
dc3fffef 1205 if (!integer_type->is_signed) {
fc25abce
PP
1206 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1207 "field-addr=%p, ft-addr=%p", field, field->type);
273b65be
JG
1208 ret = -1;
1209 goto end;
1210 }
1211
dc3fffef 1212 size = integer_type->size;
9dc0d640
JG
1213 min_value = -(1ULL << (size - 1));
1214 max_value = (1ULL << (size - 1)) - 1;
273b65be 1215 if (value < min_value || value > max_value) {
fc25abce
PP
1216 BT_LOGW("Invalid parameter: value is out of bounds: "
1217 "addr=%p, value=%" PRId64 ", "
1218 "min-value=%" PRId64 ", max-value=%" PRId64,
1219 field, value, min_value, max_value);
273b65be
JG
1220 ret = -1;
1221 goto end;
1222 }
1223
dc3fffef 1224 integer->payload.signd = value;
d990a4fb 1225 integer->parent.payload_set = true;
273b65be
JG
1226end:
1227 return ret;
1228}
1229
50842bdc 1230int bt_field_unsigned_integer_get_value(struct bt_field *field,
cd95e351
JG
1231 uint64_t *value)
1232{
1233 int ret = 0;
50842bdc
PP
1234 struct bt_field_integer *integer;
1235 struct bt_field_type_integer *integer_type;
cd95e351 1236
fc25abce
PP
1237 if (!field) {
1238 BT_LOGW_STR("Invalid parameter: field is NULL.");
1239 ret = -1;
1240 goto end;
1241 }
1242
1243 if (!value) {
1244 BT_LOGW_STR("Invalid parameter: value is NULL.");
1245 ret = -1;
1246 goto end;
1247 }
1248
1249 if (!field->payload_set) {
1250 BT_LOGV("Field's payload is not set: addr=%p", field);
1251 ret = -1;
1252 goto end;
1253 }
1254
50842bdc
PP
1255 if (bt_field_type_get_type_id(field->type) !=
1256 BT_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1257 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1258 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1259 field->type,
50842bdc 1260 bt_field_type_id_string(field->type->id));
cd95e351
JG
1261 ret = -1;
1262 goto end;
1263 }
1264
1265 integer_type = container_of(field->type,
50842bdc 1266 struct bt_field_type_integer, parent);
dc3fffef 1267 if (integer_type->is_signed) {
fc25abce
PP
1268 BT_LOGW("Invalid parameter: integer field's type is signed: "
1269 "field-addr=%p, ft-addr=%p", field, field->type);
cd95e351
JG
1270 ret = -1;
1271 goto end;
1272 }
1273
1274 integer = container_of(field,
50842bdc 1275 struct bt_field_integer, parent);
dc3fffef 1276 *value = integer->payload.unsignd;
cd95e351
JG
1277end:
1278 return ret;
1279}
1280
50842bdc 1281int bt_field_unsigned_integer_set_value(struct bt_field *field,
273b65be
JG
1282 uint64_t value)
1283{
1284 int ret = 0;
50842bdc
PP
1285 struct bt_field_integer *integer;
1286 struct bt_field_type_integer *integer_type;
273b65be
JG
1287 unsigned int size;
1288 uint64_t max_value;
1289
fc25abce
PP
1290 if (!field) {
1291 BT_LOGW_STR("Invalid parameter: field is NULL.");
1292 ret = -1;
1293 goto end;
1294 }
1295
1296 if (field->frozen) {
1297 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1298 field);
1299 ret = -1;
1300 goto end;
1301 }
1302
50842bdc
PP
1303 if (bt_field_type_get_type_id(field->type) !=
1304 BT_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1305 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1306 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1307 field->type,
50842bdc 1308 bt_field_type_id_string(field->type->id));
273b65be
JG
1309 ret = -1;
1310 goto end;
1311 }
1312
50842bdc 1313 integer = container_of(field, struct bt_field_integer, parent);
273b65be 1314 integer_type = container_of(field->type,
50842bdc 1315 struct bt_field_type_integer, parent);
dc3fffef 1316 if (integer_type->is_signed) {
fc25abce
PP
1317 BT_LOGW("Invalid parameter: integer field's type is signed: "
1318 "field-addr=%p, ft-addr=%p", field, field->type);
273b65be
JG
1319 ret = -1;
1320 goto end;
1321 }
1322
dc3fffef 1323 size = integer_type->size;
8684abc8 1324 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
273b65be 1325 if (value > max_value) {
fc25abce
PP
1326 BT_LOGW("Invalid parameter: value is out of bounds: "
1327 "addr=%p, value=%" PRIu64 ", "
1328 "min-value=%" PRIu64 ", max-value=%" PRIu64,
1329 field, value, (uint64_t) 0, max_value);
273b65be
JG
1330 ret = -1;
1331 goto end;
1332 }
1333
dc3fffef 1334 integer->payload.unsignd = value;
d990a4fb 1335 integer->parent.payload_set = true;
273b65be
JG
1336end:
1337 return ret;
1338}
1339
50842bdc 1340int bt_field_floating_point_get_value(struct bt_field *field,
cd95e351
JG
1341 double *value)
1342{
1343 int ret = 0;
50842bdc 1344 struct bt_field_floating_point *floating_point;
cd95e351 1345
fc25abce
PP
1346 if (!field) {
1347 BT_LOGW_STR("Invalid parameter: field is NULL.");
1348 ret = -1;
1349 goto end;
1350 }
1351
1352 if (!value) {
1353 BT_LOGW_STR("Invalid parameter: value is NULL.");
1354 ret = -1;
1355 goto end;
1356 }
1357
1358 if (!field->payload_set) {
1359 BT_LOGV("Field's payload is not set: addr=%p", field);
1360 ret = -1;
1361 goto end;
1362 }
1363
50842bdc
PP
1364 if (bt_field_type_get_type_id(field->type) !=
1365 BT_FIELD_TYPE_ID_FLOAT) {
fc25abce
PP
1366 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1367 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1368 field->type,
50842bdc 1369 bt_field_type_id_string(field->type->id));
cd95e351
JG
1370 ret = -1;
1371 goto end;
1372 }
1373
1374 floating_point = container_of(field,
50842bdc 1375 struct bt_field_floating_point, parent);
dc3fffef 1376 *value = floating_point->payload;
cd95e351
JG
1377end:
1378 return ret;
1379}
1380
50842bdc 1381int bt_field_floating_point_set_value(struct bt_field *field,
273b65be
JG
1382 double value)
1383{
1384 int ret = 0;
50842bdc 1385 struct bt_field_floating_point *floating_point;
273b65be 1386
fc25abce
PP
1387 if (!field) {
1388 BT_LOGW_STR("Invalid parameter: field is NULL.");
1389 ret = -1;
1390 goto end;
1391 }
1392
1393 if (field->frozen) {
1394 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1395 field);
1396 ret = -1;
1397 goto end;
1398 }
1399
50842bdc
PP
1400 if (bt_field_type_get_type_id(field->type) !=
1401 BT_FIELD_TYPE_ID_FLOAT) {
fc25abce
PP
1402 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1403 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1404 field->type,
50842bdc 1405 bt_field_type_id_string(field->type->id));
273b65be
JG
1406 ret = -1;
1407 goto end;
1408 }
fc25abce 1409
50842bdc 1410 floating_point = container_of(field, struct bt_field_floating_point,
273b65be 1411 parent);
dc3fffef 1412 floating_point->payload = value;
d990a4fb 1413 floating_point->parent.payload_set = true;
273b65be
JG
1414end:
1415 return ret;
1416}
1417
50842bdc 1418const char *bt_field_string_get_value(struct bt_field *field)
cd95e351
JG
1419{
1420 const char *ret = NULL;
50842bdc 1421 struct bt_field_string *string;
cd95e351 1422
fc25abce
PP
1423 if (!field) {
1424 BT_LOGW_STR("Invalid parameter: field is NULL.");
1425 goto end;
1426 }
1427
1428 if (!field->payload_set) {
1429 BT_LOGV("Field's payload is not set: addr=%p", field);
1430 goto end;
1431 }
1432
50842bdc
PP
1433 if (bt_field_type_get_type_id(field->type) !=
1434 BT_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1435 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1436 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1437 field->type,
50842bdc 1438 bt_field_type_id_string(field->type->id));
cd95e351
JG
1439 goto end;
1440 }
1441
1442 string = container_of(field,
50842bdc 1443 struct bt_field_string, parent);
cd95e351
JG
1444 ret = string->payload->str;
1445end:
1446 return ret;
1447}
1448
50842bdc 1449int bt_field_string_set_value(struct bt_field *field,
273b65be
JG
1450 const char *value)
1451{
1452 int ret = 0;
50842bdc 1453 struct bt_field_string *string;
273b65be 1454
fc25abce
PP
1455 if (!field) {
1456 BT_LOGW_STR("Invalid parameter: field is NULL.");
1457 ret = -1;
1458 goto end;
1459 }
1460
1461 if (!value) {
1462 BT_LOGW_STR("Invalid parameter: value is NULL.");
1463 ret = -1;
1464 goto end;
1465 }
1466
1467 if (field->frozen) {
1468 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1469 field);
1470 ret = -1;
1471 goto end;
1472 }
1473
50842bdc
PP
1474 if (bt_field_type_get_type_id(field->type) !=
1475 BT_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1476 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1477 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1478 field->type,
50842bdc 1479 bt_field_type_id_string(field->type->id));
273b65be
JG
1480 ret = -1;
1481 goto end;
1482 }
1483
50842bdc 1484 string = container_of(field, struct bt_field_string, parent);
273b65be 1485 if (string->payload) {
97736814
JG
1486 g_string_assign(string->payload, value);
1487 } else {
1488 string->payload = g_string_new(value);
273b65be
JG
1489 }
1490
d990a4fb 1491 string->parent.payload_set = true;
273b65be
JG
1492end:
1493 return ret;
1494}
1495
50842bdc 1496int bt_field_string_append(struct bt_field *field,
c6f9c5a3
PP
1497 const char *value)
1498{
1499 int ret = 0;
50842bdc 1500 struct bt_field_string *string_field;
c6f9c5a3 1501
fc25abce
PP
1502 if (!field) {
1503 BT_LOGW_STR("Invalid parameter: field is NULL.");
1504 ret = -1;
1505 goto end;
1506 }
1507
1508 if (!value) {
1509 BT_LOGW_STR("Invalid parameter: value is NULL.");
1510 ret = -1;
1511 goto end;
1512 }
1513
1514 if (field->frozen) {
1515 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1516 field);
1517 ret = -1;
1518 goto end;
1519 }
1520
50842bdc
PP
1521 if (bt_field_type_get_type_id(field->type) !=
1522 BT_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1523 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1524 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1525 field->type,
50842bdc 1526 bt_field_type_id_string(field->type->id));
c6f9c5a3
PP
1527 ret = -1;
1528 goto end;
1529 }
1530
50842bdc 1531 string_field = container_of(field, struct bt_field_string, parent);
c6f9c5a3
PP
1532
1533 if (string_field->payload) {
1534 g_string_append(string_field->payload, value);
1535 } else {
1536 string_field->payload = g_string_new(value);
1537 }
1538
d990a4fb 1539 string_field->parent.payload_set = true;
c6f9c5a3
PP
1540
1541end:
1542 return ret;
1543}
1544
50842bdc 1545int bt_field_string_append_len(struct bt_field *field,
f98c6554
PP
1546 const char *value, unsigned int length)
1547{
1548 int i;
1549 int ret = 0;
1550 unsigned int effective_length = length;
50842bdc 1551 struct bt_field_string *string_field;
f98c6554 1552
fc25abce
PP
1553 if (!field) {
1554 BT_LOGW_STR("Invalid parameter: field is NULL.");
1555 ret = -1;
1556 goto end;
1557 }
1558
1559 if (!value) {
1560 BT_LOGW_STR("Invalid parameter: value is NULL.");
1561 ret = -1;
1562 goto end;
1563 }
1564
1565 if (field->frozen) {
1566 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1567 field);
1568 ret = -1;
1569 goto end;
1570 }
1571
50842bdc
PP
1572 if (bt_field_type_get_type_id(field->type) !=
1573 BT_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1574 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1575 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1576 field->type,
50842bdc 1577 bt_field_type_id_string(field->type->id));
f98c6554
PP
1578 ret = -1;
1579 goto end;
1580 }
1581
50842bdc 1582 string_field = container_of(field, struct bt_field_string, parent);
f98c6554
PP
1583
1584 /* make sure no null bytes are appended */
1585 for (i = 0; i < length; ++i) {
1586 if (value[i] == '\0') {
1587 effective_length = i;
1588 break;
1589 }
1590 }
1591
1592 if (string_field->payload) {
ce6d5230 1593 g_string_append_len(string_field->payload, value,
f98c6554
PP
1594 effective_length);
1595 } else {
1596 string_field->payload = g_string_new_len(value,
1597 effective_length);
1598 }
1599
d990a4fb 1600 string_field->parent.payload_set = true;
f98c6554
PP
1601
1602end:
1603 return ret;
1604}
1605
273b65be 1606BT_HIDDEN
50842bdc 1607int bt_field_validate(struct bt_field *field)
273b65be
JG
1608{
1609 int ret = 0;
50842bdc 1610 enum bt_field_type_id type_id;
273b65be
JG
1611
1612 if (!field) {
fc25abce 1613 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
1614 ret = -1;
1615 goto end;
1616 }
1617
50842bdc
PP
1618 type_id = bt_field_type_get_type_id(field->type);
1619 if (type_id <= BT_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_FIELD_TYPE_ID_NR) {
fc25abce
PP
1620 BT_LOGW("Invalid parameter: unknown field type ID: "
1621 "addr=%p, ft-addr=%p, ft-id=%d",
1622 field, field->type, type_id);
273b65be
JG
1623 ret = -1;
1624 goto end;
1625 }
1626
1627 ret = field_validate_funcs[type_id](field);
1628end:
1629 return ret;
1630}
1631
50842bdc 1632int bt_field_reset(struct bt_field *field)
12c8a1a3
JG
1633{
1634 int ret = 0;
50842bdc 1635 enum bt_field_type_id type_id;
12c8a1a3
JG
1636
1637 if (!field) {
fc25abce 1638 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
1639 ret = -1;
1640 goto end;
1641 }
1642
6ead1648
JG
1643 if (field->frozen) {
1644 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1645 field);
1646 ret = -1;
1647 goto end;
1648 }
1649
50842bdc
PP
1650 type_id = bt_field_type_get_type_id(field->type);
1651 if (type_id <= BT_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_FIELD_TYPE_ID_NR) {
fc25abce
PP
1652 BT_LOGW("Invalid parameter: unknown field type ID: "
1653 "addr=%p, ft-addr=%p, ft-id=%d",
1654 field, field->type, type_id);
12c8a1a3
JG
1655 ret = -1;
1656 goto end;
1657 }
1658
d4bf905a 1659 ret = field_reset_funcs[type_id](field);
12c8a1a3
JG
1660end:
1661 return ret;
1662}
1663
273b65be 1664BT_HIDDEN
50842bdc
PP
1665int bt_field_serialize(struct bt_field *field,
1666 struct bt_stream_pos *pos,
1667 enum bt_byte_order native_byte_order)
273b65be
JG
1668{
1669 int ret = 0;
50842bdc 1670 enum bt_field_type_id type_id;
273b65be 1671
fc25abce
PP
1672 assert(pos);
1673
1674 if (!field) {
1675 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
1676 ret = -1;
1677 goto end;
1678 }
1679
50842bdc
PP
1680 type_id = bt_field_type_get_type_id(field->type);
1681 if (type_id <= BT_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_FIELD_TYPE_ID_NR) {
fc25abce
PP
1682 BT_LOGW("Invalid parameter: unknown field type ID: "
1683 "addr=%p, ft-addr=%p, ft-id=%d",
1684 field, field->type, type_id);
273b65be
JG
1685 ret = -1;
1686 goto end;
1687 }
1688
dc3fffef 1689 ret = field_serialize_funcs[type_id](field, pos, native_byte_order);
273b65be
JG
1690end:
1691 return ret;
1692}
1693
50842bdc 1694bt_bool bt_field_is_set(struct bt_field *field)
76f869ab 1695{
d4bf905a 1696 bt_bool is_set = BT_FALSE;
50842bdc 1697 enum bt_field_type_id type_id;
76f869ab
JG
1698
1699 if (!field) {
1700 goto end;
1701 }
1702
50842bdc
PP
1703 type_id = bt_field_type_get_type_id(field->type);
1704 if (type_id <= BT_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_FIELD_TYPE_ID_NR) {
fc25abce
PP
1705 BT_LOGW("Invalid parameter: unknown field type ID: "
1706 "field-addr=%p, ft-addr=%p, ft-id=%d",
1707 field, field->type, type_id);
76f869ab
JG
1708 goto end;
1709 }
1710
d4bf905a 1711 is_set = field_is_set_funcs[type_id](field);
76f869ab 1712end:
d4bf905a 1713 return is_set;
76f869ab
JG
1714}
1715
50842bdc 1716struct bt_field *bt_field_copy(struct bt_field *field)
87d43dc1
JG
1717{
1718 int ret;
50842bdc
PP
1719 struct bt_field *copy = NULL;
1720 enum bt_field_type_id type_id;
87d43dc1
JG
1721
1722 if (!field) {
fc25abce 1723 BT_LOGW_STR("Invalid parameter: field is NULL.");
87d43dc1
JG
1724 goto end;
1725 }
1726
50842bdc
PP
1727 type_id = bt_field_type_get_type_id(field->type);
1728 if (type_id <= BT_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_FIELD_TYPE_ID_NR) {
fc25abce
PP
1729 BT_LOGW("Invalid parameter: unknown field type ID: "
1730 "field-addr=%p, ft-addr=%p, ft-id=%d",
1731 field, field->type, type_id);
87d43dc1
JG
1732 goto end;
1733 }
1734
50842bdc 1735 copy = bt_field_create(field->type);
87d43dc1 1736 if (!copy) {
fc25abce 1737 BT_LOGW("Cannot create field: ft-addr=%p", field->type);
87d43dc1
JG
1738 goto end;
1739 }
1740
70996764 1741 copy->payload_set = field->payload_set;
87d43dc1
JG
1742 ret = field_copy_funcs[type_id](field, copy);
1743 if (ret) {
83509119 1744 bt_put(copy);
87d43dc1
JG
1745 copy = NULL;
1746 }
1747end:
1748 return copy;
1749}
1750
273b65be 1751static
50842bdc 1752struct bt_field *bt_field_integer_create(struct bt_field_type *type)
273b65be 1753{
50842bdc
PP
1754 struct bt_field_integer *integer = g_new0(
1755 struct bt_field_integer, 1);
273b65be 1756
fc25abce
PP
1757 BT_LOGD("Creating integer field object: ft-addr=%p", type);
1758
1759 if (integer) {
1760 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
1761 &integer->parent, type);
1762 } else {
1763 BT_LOGE_STR("Failed to allocate one integer field.");
1764 }
1765
273b65be
JG
1766 return integer ? &integer->parent : NULL;
1767}
1768
1769static
50842bdc
PP
1770struct bt_field *bt_field_enumeration_create(
1771 struct bt_field_type *type)
273b65be 1772{
50842bdc
PP
1773 struct bt_field_enumeration *enumeration = g_new0(
1774 struct bt_field_enumeration, 1);
273b65be 1775
fc25abce
PP
1776 BT_LOGD("Creating enumeration field object: ft-addr=%p", type);
1777
1778 if (enumeration) {
1779 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
1780 &enumeration->parent, type);
1781 } else {
1782 BT_LOGE_STR("Failed to allocate one enumeration field.");
1783 }
1784
273b65be
JG
1785 return enumeration ? &enumeration->parent : NULL;
1786}
1787
1788static
50842bdc
PP
1789struct bt_field *bt_field_floating_point_create(
1790 struct bt_field_type *type)
273b65be 1791{
50842bdc 1792 struct bt_field_floating_point *floating_point;
273b65be 1793
fc25abce 1794 BT_LOGD("Creating floating point number field object: ft-addr=%p", type);
50842bdc 1795 floating_point = g_new0(struct bt_field_floating_point, 1);
fc25abce
PP
1796
1797 if (floating_point) {
1798 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
1799 &floating_point->parent, type);
1800 } else {
1801 BT_LOGE_STR("Failed to allocate one floating point number field.");
1802 }
1803
273b65be
JG
1804 return floating_point ? &floating_point->parent : NULL;
1805}
1806
1807static
50842bdc
PP
1808struct bt_field *bt_field_structure_create(
1809 struct bt_field_type *type)
273b65be 1810{
50842bdc
PP
1811 struct bt_field_type_structure *structure_type = container_of(type,
1812 struct bt_field_type_structure, parent);
1813 struct bt_field_structure *structure = g_new0(
1814 struct bt_field_structure, 1);
1815 struct bt_field *ret = NULL;
c58b9c62 1816 size_t i;
273b65be 1817
fc25abce
PP
1818 BT_LOGD("Creating structure field object: ft-addr=%p", type);
1819
8c1aa858 1820 if (!structure) {
fc25abce 1821 BT_LOGE_STR("Failed to allocate one structure field.");
273b65be
JG
1822 goto end;
1823 }
1824
273b65be 1825 structure->fields = g_ptr_array_new_with_free_func(
50842bdc 1826 (GDestroyNotify) bt_put);
273b65be 1827 g_ptr_array_set_size(structure->fields,
c58b9c62
JG
1828 structure_type->fields->len);
1829
1830 /* Create all fields contained by the structure field. */
1831 for (i = 0; i < structure_type->fields->len; i++) {
50842bdc 1832 struct bt_field *field;
c58b9c62
JG
1833 struct structure_field *field_type =
1834 g_ptr_array_index(structure_type->fields, i);
1835
50842bdc 1836 field = bt_field_create(field_type->type);
c58b9c62
JG
1837 if (!field) {
1838 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
1839 g_quark_to_string(field_type->name), i);
50842bdc 1840 bt_field_structure_destroy(&structure->parent);
c58b9c62
JG
1841 goto end;
1842 }
1843
1844 g_ptr_array_index(structure->fields, i) = field;
1845 }
1846
1847 ret = &structure->parent;
1848 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p", ret,
1849 type);
273b65be 1850end:
c58b9c62 1851 return ret;
273b65be
JG
1852}
1853
1854static
50842bdc 1855struct bt_field *bt_field_variant_create(struct bt_field_type *type)
273b65be 1856{
50842bdc
PP
1857 struct bt_field_variant *variant = g_new0(
1858 struct bt_field_variant, 1);
fc25abce
PP
1859
1860 BT_LOGD("Creating variant field object: ft-addr=%p", type);
1861
1862 if (variant) {
1863 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1864 &variant->parent, type);
1865 } else {
1866 BT_LOGE_STR("Failed to allocate one variant field.");
1867 }
1868
273b65be
JG
1869 return variant ? &variant->parent : NULL;
1870}
1871
1872static
50842bdc 1873struct bt_field *bt_field_array_create(struct bt_field_type *type)
273b65be 1874{
50842bdc
PP
1875 struct bt_field_array *array = g_new0(struct bt_field_array, 1);
1876 struct bt_field_type_array *array_type;
273b65be
JG
1877 unsigned int array_length;
1878
fc25abce
PP
1879 BT_LOGD("Creating array field object: ft-addr=%p", type);
1880 assert(type);
1881
1882 if (!array) {
1883 BT_LOGE_STR("Failed to allocate one array field.");
273b65be
JG
1884 goto error;
1885 }
1886
50842bdc 1887 array_type = container_of(type, struct bt_field_type_array, parent);
273b65be 1888 array_length = array_type->length;
fe0fe95c 1889 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1890 if (!array->elements) {
1891 goto error;
1892 }
1893
fe0fe95c 1894 g_ptr_array_set_free_func(array->elements,
50842bdc 1895 (GDestroyNotify) bt_put);
273b65be 1896 g_ptr_array_set_size(array->elements, array_length);
fc25abce
PP
1897 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1898 &array->parent, type);
273b65be
JG
1899 return &array->parent;
1900error:
1901 g_free(array);
1902 return NULL;
1903}
1904
1905static
50842bdc
PP
1906struct bt_field *bt_field_sequence_create(
1907 struct bt_field_type *type)
273b65be 1908{
50842bdc
PP
1909 struct bt_field_sequence *sequence = g_new0(
1910 struct bt_field_sequence, 1);
fc25abce
PP
1911
1912 BT_LOGD("Creating sequence field object: ft-addr=%p", type);
1913
1914 if (sequence) {
1915 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1916 &sequence->parent, type);
1917 } else {
1918 BT_LOGE_STR("Failed to allocate one sequence field.");
1919 }
1920
273b65be
JG
1921 return sequence ? &sequence->parent : NULL;
1922}
1923
1924static
50842bdc 1925struct bt_field *bt_field_string_create(struct bt_field_type *type)
273b65be 1926{
50842bdc
PP
1927 struct bt_field_string *string = g_new0(
1928 struct bt_field_string, 1);
fc25abce
PP
1929
1930 BT_LOGD("Creating string field object: ft-addr=%p", type);
1931
1932 if (string) {
1933 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1934 &string->parent, type);
1935 } else {
1936 BT_LOGE_STR("Failed to allocate one string field.");
1937 }
1938
273b65be
JG
1939 return string ? &string->parent : NULL;
1940}
1941
1942static
50842bdc 1943void bt_field_destroy(struct bt_object *obj)
273b65be 1944{
50842bdc
PP
1945 struct bt_field *field;
1946 struct bt_field_type *type;
1947 enum bt_field_type_id type_id;
273b65be 1948
50842bdc 1949 field = container_of(obj, struct bt_field, base);
273b65be 1950 type = field->type;
50842bdc
PP
1951 type_id = bt_field_type_get_type_id(type);
1952 assert(type_id > BT_FIELD_TYPE_ID_UNKNOWN &&
1953 type_id < BT_FIELD_TYPE_ID_NR);
273b65be 1954 field_destroy_funcs[type_id](field);
fc25abce 1955 BT_LOGD_STR("Putting field's type.");
83509119 1956 bt_put(type);
273b65be
JG
1957}
1958
1959static
50842bdc 1960void bt_field_integer_destroy(struct bt_field *field)
273b65be 1961{
50842bdc 1962 struct bt_field_integer *integer;
273b65be
JG
1963
1964 if (!field) {
1965 return;
1966 }
1967
fc25abce 1968 BT_LOGD("Destroying integer field object: addr=%p", field);
50842bdc 1969 integer = container_of(field, struct bt_field_integer, parent);
273b65be
JG
1970 g_free(integer);
1971}
1972
1973static
50842bdc 1974void bt_field_enumeration_destroy(struct bt_field *field)
273b65be 1975{
50842bdc 1976 struct bt_field_enumeration *enumeration;
273b65be
JG
1977
1978 if (!field) {
1979 return;
1980 }
1981
fc25abce 1982 BT_LOGD("Destroying enumeration field object: addr=%p", field);
50842bdc 1983 enumeration = container_of(field, struct bt_field_enumeration,
273b65be 1984 parent);
fc25abce 1985 BT_LOGD_STR("Putting payload field.");
83509119 1986 bt_put(enumeration->payload);
273b65be
JG
1987 g_free(enumeration);
1988}
1989
1990static
50842bdc 1991void bt_field_floating_point_destroy(struct bt_field *field)
273b65be 1992{
50842bdc 1993 struct bt_field_floating_point *floating_point;
273b65be
JG
1994
1995 if (!field) {
1996 return;
1997 }
1998
fc25abce 1999 BT_LOGD("Destroying floating point number field object: addr=%p", field);
50842bdc 2000 floating_point = container_of(field, struct bt_field_floating_point,
273b65be
JG
2001 parent);
2002 g_free(floating_point);
2003}
2004
2005static
50842bdc 2006void bt_field_structure_destroy(struct bt_field *field)
273b65be 2007{
50842bdc 2008 struct bt_field_structure *structure;
273b65be
JG
2009
2010 if (!field) {
2011 return;
2012 }
2013
fc25abce 2014 BT_LOGD("Destroying structure field object: addr=%p", field);
50842bdc 2015 structure = container_of(field, struct bt_field_structure, parent);
273b65be
JG
2016 g_ptr_array_free(structure->fields, TRUE);
2017 g_free(structure);
2018}
2019
2020static
50842bdc 2021void bt_field_variant_destroy(struct bt_field *field)
273b65be 2022{
50842bdc 2023 struct bt_field_variant *variant;
273b65be
JG
2024
2025 if (!field) {
2026 return;
2027 }
2028
fc25abce 2029 BT_LOGD("Destroying variant field object: addr=%p", field);
50842bdc 2030 variant = container_of(field, struct bt_field_variant, parent);
fc25abce 2031 BT_LOGD_STR("Putting tag field.");
83509119 2032 bt_put(variant->tag);
fc25abce 2033 BT_LOGD_STR("Putting payload field.");
83509119 2034 bt_put(variant->payload);
273b65be
JG
2035 g_free(variant);
2036}
2037
2038static
50842bdc 2039void bt_field_array_destroy(struct bt_field *field)
273b65be 2040{
50842bdc 2041 struct bt_field_array *array;
273b65be
JG
2042
2043 if (!field) {
2044 return;
2045 }
2046
fc25abce 2047 BT_LOGD("Destroying array field object: addr=%p", field);
50842bdc 2048 array = container_of(field, struct bt_field_array, parent);
273b65be
JG
2049 g_ptr_array_free(array->elements, TRUE);
2050 g_free(array);
2051}
2052
2053static
50842bdc 2054void bt_field_sequence_destroy(struct bt_field *field)
273b65be 2055{
50842bdc 2056 struct bt_field_sequence *sequence;
273b65be
JG
2057
2058 if (!field) {
2059 return;
2060 }
2061
fc25abce 2062 BT_LOGD("Destroying sequence field object: addr=%p", field);
50842bdc 2063 sequence = container_of(field, struct bt_field_sequence, parent);
4fef87ab
JG
2064 if (sequence->elements) {
2065 g_ptr_array_free(sequence->elements, TRUE);
2066 }
fc25abce 2067 BT_LOGD_STR("Putting length field.");
83509119 2068 bt_put(sequence->length);
273b65be
JG
2069 g_free(sequence);
2070}
2071
2072static
50842bdc 2073void bt_field_string_destroy(struct bt_field *field)
273b65be 2074{
50842bdc 2075 struct bt_field_string *string;
fc25abce 2076
273b65be
JG
2077 if (!field) {
2078 return;
2079 }
2080
fc25abce 2081 BT_LOGD("Destroying string field object: addr=%p", field);
50842bdc 2082 string = container_of(field, struct bt_field_string, parent);
9b2b7163
JG
2083 if (string->payload) {
2084 g_string_free(string->payload, TRUE);
2085 }
273b65be
JG
2086 g_free(string);
2087}
2088
2089static
50842bdc 2090int bt_field_generic_validate(struct bt_field *field)
273b65be 2091{
da2f6971 2092 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
2093}
2094
2095static
50842bdc 2096int bt_field_enumeration_validate(struct bt_field *field)
273b65be
JG
2097{
2098 int ret;
50842bdc 2099 struct bt_field_enumeration *enumeration;
273b65be
JG
2100
2101 if (!field) {
fc25abce 2102 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2103 ret = -1;
2104 goto end;
2105 }
2106
50842bdc 2107 enumeration = container_of(field, struct bt_field_enumeration,
273b65be
JG
2108 parent);
2109 if (!enumeration->payload) {
fc25abce
PP
2110 BT_LOGW("Invalid enumeration field: payload is not set: "
2111 "addr=%p", field);
273b65be
JG
2112 ret = -1;
2113 goto end;
2114 }
2115
50842bdc 2116 ret = bt_field_validate(enumeration->payload);
273b65be
JG
2117end:
2118 return ret;
2119}
2120
2121static
50842bdc 2122int bt_field_structure_validate(struct bt_field *field)
273b65be 2123{
fc25abce 2124 int64_t i;
273b65be 2125 int ret = 0;
50842bdc 2126 struct bt_field_structure *structure;
273b65be
JG
2127
2128 if (!field) {
fc25abce 2129 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2130 ret = -1;
2131 goto end;
2132 }
2133
50842bdc 2134 structure = container_of(field, struct bt_field_structure, parent);
273b65be 2135 for (i = 0; i < structure->fields->len; i++) {
50842bdc
PP
2136 struct bt_field *entry_field = structure->fields->pdata[i];
2137 ret = bt_field_validate(entry_field);
fc25abce 2138
273b65be 2139 if (ret) {
fc25abce 2140 int this_ret;
6ce12048 2141 const char *name;
50842bdc
PP
2142 struct bt_field_type *field_type =
2143 bt_field_get_type(field);
6ce12048 2144
50842bdc 2145 this_ret = bt_field_type_structure_get_field_by_index(
fc25abce
PP
2146 field_type, &name, NULL, i);
2147 assert(this_ret == 0);
2148 BT_LOGW("Invalid structure field's field: "
2149 "struct-field-addr=%p, field-addr=%p, "
2150 "field-name=\"%s\", index=%" PRId64,
2151 field, entry_field, name, i);
e5ed1ccf 2152 bt_put(field_type);
273b65be
JG
2153 goto end;
2154 }
2155 }
2156end:
2157 return ret;
2158}
2159
2160static
50842bdc 2161int bt_field_variant_validate(struct bt_field *field)
273b65be
JG
2162{
2163 int ret = 0;
50842bdc 2164 struct bt_field_variant *variant;
273b65be
JG
2165
2166 if (!field) {
fc25abce 2167 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2168 ret = -1;
2169 goto end;
2170 }
2171
50842bdc
PP
2172 variant = container_of(field, struct bt_field_variant, parent);
2173 ret = bt_field_validate(variant->payload);
fc25abce
PP
2174 if (ret) {
2175 BT_LOGW("Invalid variant field's payload field: "
2176 "variant-field-addr=%p, variant-payload-field-addr=%p",
2177 field, variant->payload);
2178 }
273b65be
JG
2179end:
2180 return ret;
2181}
2182
2183static
50842bdc 2184int bt_field_array_validate(struct bt_field *field)
273b65be 2185{
fc25abce 2186 int64_t i;
273b65be 2187 int ret = 0;
50842bdc 2188 struct bt_field_array *array;
273b65be
JG
2189
2190 if (!field) {
fc25abce 2191 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2192 ret = -1;
2193 goto end;
2194 }
2195
50842bdc 2196 array = container_of(field, struct bt_field_array, parent);
273b65be 2197 for (i = 0; i < array->elements->len; i++) {
50842bdc 2198 struct bt_field *elem_field = array->elements->pdata[i];
fc25abce 2199
50842bdc 2200 ret = bt_field_validate(elem_field);
273b65be 2201 if (ret) {
fc25abce
PP
2202 BT_LOGW("Invalid array field's element field: "
2203 "array-field-addr=%p, field-addr=%p, "
2204 "index=%" PRId64, field, elem_field, i);
273b65be
JG
2205 goto end;
2206 }
2207 }
2208end:
2209 return ret;
2210}
2211
2212static
50842bdc 2213int bt_field_sequence_validate(struct bt_field *field)
273b65be
JG
2214{
2215 size_t i;
2216 int ret = 0;
50842bdc 2217 struct bt_field_sequence *sequence;
273b65be
JG
2218
2219 if (!field) {
fc25abce 2220 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2221 ret = -1;
2222 goto end;
2223 }
2224
50842bdc 2225 sequence = container_of(field, struct bt_field_sequence, parent);
273b65be 2226 for (i = 0; i < sequence->elements->len; i++) {
50842bdc 2227 struct bt_field *elem_field = sequence->elements->pdata[i];
fc25abce 2228
50842bdc 2229 ret = bt_field_validate(elem_field);
273b65be 2230 if (ret) {
fc25abce
PP
2231 BT_LOGW("Invalid sequence field's element field: "
2232 "sequence-field-addr=%p, field-addr=%p, "
1974687e 2233 "index=%zu", field, elem_field, i);
273b65be
JG
2234 goto end;
2235 }
2236 }
2237end:
2238 return ret;
2239}
2240
12c8a1a3 2241static
50842bdc 2242int bt_field_generic_reset(struct bt_field *field)
12c8a1a3
JG
2243{
2244 int ret = 0;
2245
2246 if (!field) {
fc25abce 2247 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2248 ret = -1;
2249 goto end;
2250 }
2251
d990a4fb 2252 field->payload_set = false;
12c8a1a3
JG
2253end:
2254 return ret;
2255}
2256
2257static
50842bdc 2258int bt_field_enumeration_reset(struct bt_field *field)
12c8a1a3
JG
2259{
2260 int ret = 0;
50842bdc 2261 struct bt_field_enumeration *enumeration;
12c8a1a3
JG
2262
2263 if (!field) {
fc25abce 2264 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2265 ret = -1;
2266 goto end;
2267 }
2268
50842bdc 2269 enumeration = container_of(field, struct bt_field_enumeration,
12c8a1a3
JG
2270 parent);
2271 if (!enumeration->payload) {
2272 goto end;
2273 }
2274
50842bdc 2275 ret = bt_field_reset(enumeration->payload);
12c8a1a3
JG
2276end:
2277 return ret;
2278}
2279
2280static
50842bdc 2281int bt_field_structure_reset(struct bt_field *field)
12c8a1a3 2282{
fc25abce 2283 int64_t i;
12c8a1a3 2284 int ret = 0;
50842bdc 2285 struct bt_field_structure *structure;
12c8a1a3
JG
2286
2287 if (!field) {
fc25abce 2288 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2289 ret = -1;
2290 goto end;
2291 }
2292
50842bdc 2293 structure = container_of(field, struct bt_field_structure, parent);
12c8a1a3 2294 for (i = 0; i < structure->fields->len; i++) {
50842bdc 2295 struct bt_field *member = structure->fields->pdata[i];
12c8a1a3
JG
2296
2297 if (!member) {
2298 /*
2299 * Structure members are lazily initialized; skip if
2300 * this member has not been allocated yet.
2301 */
2302 continue;
2303 }
2304
50842bdc 2305 ret = bt_field_reset(member);
12c8a1a3 2306 if (ret) {
fc25abce
PP
2307 BT_LOGE("Failed to reset structure field's field: "
2308 "struct-field-addr=%p, field-addr=%p, "
2309 "index=%" PRId64, field, member, i);
12c8a1a3
JG
2310 goto end;
2311 }
2312 }
2313end:
2314 return ret;
2315}
2316
2317static
50842bdc 2318int bt_field_variant_reset(struct bt_field *field)
12c8a1a3
JG
2319{
2320 int ret = 0;
50842bdc 2321 struct bt_field_variant *variant;
12c8a1a3
JG
2322
2323 if (!field) {
fc25abce 2324 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2325 ret = -1;
2326 goto end;
2327 }
2328
50842bdc 2329 variant = container_of(field, struct bt_field_variant, parent);
6ead1648
JG
2330 BT_PUT(variant->tag);
2331 BT_PUT(variant->payload);
12c8a1a3
JG
2332end:
2333 return ret;
2334}
2335
2336static
50842bdc 2337int bt_field_array_reset(struct bt_field *field)
12c8a1a3
JG
2338{
2339 size_t i;
2340 int ret = 0;
50842bdc 2341 struct bt_field_array *array;
12c8a1a3
JG
2342
2343 if (!field) {
fc25abce 2344 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2345 ret = -1;
2346 goto end;
2347 }
2348
50842bdc 2349 array = container_of(field, struct bt_field_array, parent);
12c8a1a3 2350 for (i = 0; i < array->elements->len; i++) {
50842bdc 2351 struct bt_field *member = array->elements->pdata[i];
12c8a1a3
JG
2352
2353 if (!member) {
2354 /*
2355 * Array elements are lazily initialized; skip if
2356 * this member has not been allocated yet.
2357 */
2358 continue;
2359 }
2360
50842bdc 2361 ret = bt_field_reset(member);
12c8a1a3 2362 if (ret) {
fc25abce
PP
2363 BT_LOGE("Failed to reset array field's field: "
2364 "array-field-addr=%p, field-addr=%p, "
1974687e 2365 "index=%zu", field, member, i);
12c8a1a3
JG
2366 goto end;
2367 }
2368 }
2369end:
2370 return ret;
2371}
2372
2373static
50842bdc 2374int bt_field_sequence_reset(struct bt_field *field)
12c8a1a3 2375{
12c8a1a3 2376 int ret = 0;
50842bdc 2377 struct bt_field_sequence *sequence;
12c8a1a3
JG
2378
2379 if (!field) {
fc25abce 2380 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2381 ret = -1;
2382 goto end;
2383 }
2384
50842bdc 2385 sequence = container_of(field, struct bt_field_sequence, parent);
6ead1648
JG
2386 if (sequence->elements) {
2387 g_ptr_array_free(sequence->elements, TRUE);
2388 sequence->elements = NULL;
12c8a1a3 2389 }
6ead1648 2390 BT_PUT(sequence->length);
12c8a1a3
JG
2391end:
2392 return ret;
2393}
2394
2395static
50842bdc 2396int bt_field_string_reset(struct bt_field *field)
12c8a1a3
JG
2397{
2398 int ret = 0;
50842bdc 2399 struct bt_field_string *string;
12c8a1a3
JG
2400
2401 if (!field) {
fc25abce 2402 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2403 ret = -1;
2404 goto end;
2405 }
2406
50842bdc 2407 ret = bt_field_generic_reset(field);
12c8a1a3
JG
2408 if (ret) {
2409 goto end;
2410 }
2411
50842bdc 2412 string = container_of(field, struct bt_field_string, parent);
12c8a1a3
JG
2413 if (string->payload) {
2414 g_string_truncate(string->payload, 0);
2415 }
2416end:
2417 return ret;
2418}
2419
273b65be 2420static
50842bdc
PP
2421int bt_field_integer_serialize(struct bt_field *field,
2422 struct bt_stream_pos *pos,
2423 enum bt_byte_order native_byte_order)
273b65be
JG
2424{
2425 int ret = 0;
50842bdc
PP
2426 struct bt_field_integer *integer = container_of(field,
2427 struct bt_field_integer, parent);
273b65be 2428
fc25abce
PP
2429 BT_LOGV("Serializing integer field: addr=%p, pos-offset=%" PRId64 ", "
2430 "native-bo=%s", field, pos->offset,
50842bdc 2431 bt_byte_order_string(native_byte_order));
fc25abce 2432
50842bdc 2433 if (!bt_field_generic_is_set(field)) {
fc25abce 2434 BT_LOGW_STR("Field's payload is not set.");
fa21dcb1
JG
2435 ret = -1;
2436 goto end;
2437 }
273b65be 2438retry:
50842bdc 2439 ret = bt_field_integer_write(integer, pos, native_byte_order);
273b65be
JG
2440 if (ret == -EFAULT) {
2441 /*
2442 * The field is too large to fit in the current packet's
2443 * remaining space. Bump the packet size and retry.
2444 */
2445 ret = increase_packet_size(pos);
2446 if (ret) {
fc25abce 2447 BT_LOGE("Cannot increase packet size: ret=%d", ret);
273b65be
JG
2448 goto end;
2449 }
2450 goto retry;
2451 }
2452end:
2453 return ret;
2454}
2455
2456static
50842bdc
PP
2457int bt_field_enumeration_serialize(struct bt_field *field,
2458 struct bt_stream_pos *pos,
2459 enum bt_byte_order native_byte_order)
273b65be 2460{
50842bdc
PP
2461 struct bt_field_enumeration *enumeration = container_of(
2462 field, struct bt_field_enumeration, parent);
273b65be 2463
fc25abce
PP
2464 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64 ", "
2465 "native-bo=%s", field, pos->offset,
50842bdc 2466 bt_byte_order_string(native_byte_order));
fc25abce 2467 BT_LOGV_STR("Serializing enumeration field's payload field.");
50842bdc 2468 return bt_field_serialize(enumeration->payload, pos,
dc3fffef 2469 native_byte_order);
273b65be
JG
2470}
2471
2472static
50842bdc
PP
2473int bt_field_floating_point_serialize(struct bt_field *field,
2474 struct bt_stream_pos *pos,
2475 enum bt_byte_order native_byte_order)
273b65be
JG
2476{
2477 int ret = 0;
50842bdc
PP
2478 struct bt_field_floating_point *floating_point = container_of(field,
2479 struct bt_field_floating_point, parent);
273b65be 2480
fc25abce
PP
2481 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64 ", "
2482 "native-bo=%s", field, pos->offset,
50842bdc 2483 bt_byte_order_string(native_byte_order));
fc25abce 2484
50842bdc 2485 if (!bt_field_generic_is_set(field)) {
fc25abce 2486 BT_LOGW_STR("Field's payload is not set.");
fa21dcb1
JG
2487 ret = -1;
2488 goto end;
2489 }
273b65be 2490retry:
50842bdc 2491 ret = bt_field_floating_point_write(floating_point, pos,
dc3fffef 2492 native_byte_order);
273b65be
JG
2493 if (ret == -EFAULT) {
2494 /*
2495 * The field is too large to fit in the current packet's
2496 * remaining space. Bump the packet size and retry.
2497 */
2498 ret = increase_packet_size(pos);
2499 if (ret) {
fc25abce 2500 BT_LOGE("Cannot increase packet size: ret=%d", ret);
273b65be
JG
2501 goto end;
2502 }
2503 goto retry;
2504 }
2505end:
2506 return ret;
2507}
2508
2509static
50842bdc
PP
2510int bt_field_structure_serialize(struct bt_field *field,
2511 struct bt_stream_pos *pos,
2512 enum bt_byte_order native_byte_order)
273b65be 2513{
fc25abce 2514 int64_t i;
273b65be 2515 int ret = 0;
50842bdc
PP
2516 struct bt_field_structure *structure = container_of(
2517 field, struct bt_field_structure, parent);
273b65be 2518
fc25abce
PP
2519 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64 ", "
2520 "native-bo=%s", field, pos->offset,
50842bdc 2521 bt_byte_order_string(native_byte_order));
fc25abce 2522
50842bdc 2523 while (!bt_stream_pos_access_ok(pos,
dc3fffef 2524 offset_align(pos->offset, field->type->alignment))) {
9f56e450
JG
2525 ret = increase_packet_size(pos);
2526 if (ret) {
fc25abce 2527 BT_LOGE("Cannot increase packet size: ret=%d", ret);
9f56e450
JG
2528 goto end;
2529 }
273b65be
JG
2530 }
2531
50842bdc 2532 if (!bt_stream_pos_align(pos, field->type->alignment)) {
fc25abce
PP
2533 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64 ", "
2534 "align=%u", pos->offset, field->type->alignment);
70fd5a51
MD
2535 ret = -1;
2536 goto end;
2537 }
273b65be
JG
2538
2539 for (i = 0; i < structure->fields->len; i++) {
50842bdc 2540 struct bt_field *member = g_ptr_array_index(
273b65be 2541 structure->fields, i);
b3376dd9
PP
2542 const char *field_name = NULL;
2543
2544 if (BT_LOG_ON_WARN) {
50842bdc 2545 ret = bt_field_type_structure_get_field_by_index(
b3376dd9
PP
2546 field->type, &field_name, NULL, i);
2547 assert(ret == 0);
2548 }
273b65be 2549
fc25abce
PP
2550 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64 ", "
2551 "field-addr=%p, index=%" PRId64,
2552 pos->offset, member, i);
b3376dd9
PP
2553
2554 if (!member) {
2555 BT_LOGW("Cannot serialize structure field's field: field is not set: "
2556 "struct-field-addr=%p, "
2557 "field-name=\"%s\", index=%" PRId64,
2558 field, field_name, i);
2559 ret = -1;
2560 goto end;
2561 }
2562
50842bdc 2563 ret = bt_field_serialize(member, pos, native_byte_order);
273b65be 2564 if (ret) {
fc25abce
PP
2565 BT_LOGW("Cannot serialize structure field's field: "
2566 "struct-field-addr=%p, field-addr=%p, "
2567 "field-name=\"%s\", index=%" PRId64,
b3376dd9 2568 field->type, member, field_name, i);
273b65be
JG
2569 break;
2570 }
2571 }
9f56e450 2572end:
273b65be
JG
2573 return ret;
2574}
2575
2576static
50842bdc
PP
2577int bt_field_variant_serialize(struct bt_field *field,
2578 struct bt_stream_pos *pos,
2579 enum bt_byte_order native_byte_order)
273b65be 2580{
50842bdc
PP
2581 struct bt_field_variant *variant = container_of(
2582 field, struct bt_field_variant, parent);
273b65be 2583
fc25abce
PP
2584 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64 ", "
2585 "native-bo=%s", field, pos->offset,
50842bdc 2586 bt_byte_order_string(native_byte_order));
fc25abce 2587 BT_LOGV_STR("Serializing variant field's payload field.");
50842bdc 2588 return bt_field_serialize(variant->payload, pos,
dc3fffef 2589 native_byte_order);
273b65be
JG
2590}
2591
2592static
50842bdc
PP
2593int bt_field_array_serialize(struct bt_field *field,
2594 struct bt_stream_pos *pos,
2595 enum bt_byte_order native_byte_order)
273b65be 2596{
fc25abce 2597 int64_t i;
273b65be 2598 int ret = 0;
50842bdc
PP
2599 struct bt_field_array *array = container_of(
2600 field, struct bt_field_array, parent);
273b65be 2601
fc25abce
PP
2602 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64 ", "
2603 "native-bo=%s", field, pos->offset,
50842bdc 2604 bt_byte_order_string(native_byte_order));
fc25abce 2605
273b65be 2606 for (i = 0; i < array->elements->len; i++) {
50842bdc 2607 struct bt_field *elem_field =
fc25abce
PP
2608 g_ptr_array_index(array->elements, i);
2609
2610 BT_LOGV("Serializing array field's element field: "
2611 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
2612 pos->offset, elem_field, i);
50842bdc 2613 ret = bt_field_serialize(elem_field, pos,
dc3fffef 2614 native_byte_order);
273b65be 2615 if (ret) {
fc25abce
PP
2616 BT_LOGW("Cannot serialize array field's element field: "
2617 "array-field-addr=%p, field-addr=%p, "
2618 "index=%" PRId64, field, elem_field, i);
273b65be
JG
2619 goto end;
2620 }
2621 }
2622end:
2623 return ret;
2624}
2625
2626static
50842bdc
PP
2627int bt_field_sequence_serialize(struct bt_field *field,
2628 struct bt_stream_pos *pos,
2629 enum bt_byte_order native_byte_order)
273b65be 2630{
fc25abce 2631 int64_t i;
273b65be 2632 int ret = 0;
50842bdc
PP
2633 struct bt_field_sequence *sequence = container_of(
2634 field, struct bt_field_sequence, parent);
273b65be 2635
fc25abce
PP
2636 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64 ", "
2637 "native-bo=%s", field, pos->offset,
50842bdc 2638 bt_byte_order_string(native_byte_order));
fc25abce 2639
273b65be 2640 for (i = 0; i < sequence->elements->len; i++) {
50842bdc 2641 struct bt_field *elem_field =
fc25abce
PP
2642 g_ptr_array_index(sequence->elements, i);
2643
2644 BT_LOGV("Serializing sequence field's element field: "
2645 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
2646 pos->offset, elem_field, i);
50842bdc 2647 ret = bt_field_serialize(elem_field, pos,
dc3fffef 2648 native_byte_order);
273b65be 2649 if (ret) {
fc25abce
PP
2650 BT_LOGW("Cannot serialize sequence field's element field: "
2651 "sequence-field-addr=%p, field-addr=%p, "
2652 "index=%" PRId64, field, elem_field, i);
273b65be
JG
2653 goto end;
2654 }
2655 }
2656end:
2657 return ret;
2658}
2659
2660static
50842bdc
PP
2661int bt_field_string_serialize(struct bt_field *field,
2662 struct bt_stream_pos *pos,
2663 enum bt_byte_order native_byte_order)
273b65be 2664{
fc25abce 2665 int64_t i;
273b65be 2666 int ret = 0;
50842bdc
PP
2667 struct bt_field_string *string = container_of(field,
2668 struct bt_field_string, parent);
2669 struct bt_field_type *character_type =
273b65be 2670 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
50842bdc 2671 struct bt_field *character;
fc25abce
PP
2672
2673 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64 ", "
2674 "native-bo=%s", field, pos->offset,
50842bdc 2675 bt_byte_order_string(native_byte_order));
fc25abce
PP
2676
2677 BT_LOGV_STR("Creating character field from string field's character field type.");
50842bdc 2678 character = bt_field_create(character_type);
273b65be
JG
2679
2680 for (i = 0; i < string->payload->len + 1; i++) {
fc25abce
PP
2681 const uint64_t chr = (uint64_t) string->payload->str[i];
2682
50842bdc 2683 ret = bt_field_unsigned_integer_set_value(character, chr);
273b65be 2684 if (ret) {
b3376dd9 2685 BT_LOGW("Cannot set character field's value: "
fc25abce
PP
2686 "pos-offset=%" PRId64 ", field-addr=%p, "
2687 "index=%" PRId64 ", char-int=%" PRIu64,
2688 pos->offset, character, i, chr);
273b65be
JG
2689 goto end;
2690 }
2691
fc25abce
PP
2692 BT_LOGV("Serializing string field's character field: "
2693 "pos-offset=%" PRId64 ", field-addr=%p, "
2694 "index=%" PRId64 ", char-int=%" PRIu64,
2695 pos->offset, character, i, chr);
50842bdc 2696 ret = bt_field_integer_serialize(character, pos,
dc3fffef 2697 native_byte_order);
273b65be 2698 if (ret) {
b3376dd9 2699 BT_LOGW_STR("Cannot serialize character field.");
273b65be
JG
2700 goto end;
2701 }
2702 }
2703end:
83509119
JG
2704 bt_put(character);
2705 bt_put(character_type);
273b65be
JG
2706 return ret;
2707}
2708
87d43dc1 2709static
50842bdc
PP
2710int bt_field_integer_copy(struct bt_field *src,
2711 struct bt_field *dst)
87d43dc1 2712{
50842bdc 2713 struct bt_field_integer *integer_src, *integer_dst;
87d43dc1 2714
fc25abce
PP
2715 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
2716 src, dst);
50842bdc
PP
2717 integer_src = container_of(src, struct bt_field_integer, parent);
2718 integer_dst = container_of(dst, struct bt_field_integer, parent);
dc3fffef 2719 integer_dst->payload = integer_src->payload;
fc25abce 2720 BT_LOGD_STR("Copied integer field.");
87d43dc1
JG
2721 return 0;
2722}
2723
2724static
50842bdc
PP
2725int bt_field_enumeration_copy(struct bt_field *src,
2726 struct bt_field *dst)
87d43dc1
JG
2727{
2728 int ret = 0;
50842bdc 2729 struct bt_field_enumeration *enum_src, *enum_dst;
87d43dc1 2730
fc25abce
PP
2731 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
2732 src, dst);
50842bdc
PP
2733 enum_src = container_of(src, struct bt_field_enumeration, parent);
2734 enum_dst = container_of(dst, struct bt_field_enumeration, parent);
87d43dc1
JG
2735
2736 if (enum_src->payload) {
fc25abce 2737 BT_LOGD_STR("Copying enumeration field's payload field.");
50842bdc 2738 enum_dst->payload = bt_field_copy(enum_src->payload);
87d43dc1 2739 if (!enum_dst->payload) {
fc25abce 2740 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
87d43dc1
JG
2741 ret = -1;
2742 goto end;
2743 }
2744 }
fc25abce
PP
2745
2746 BT_LOGD_STR("Copied enumeration field.");
87d43dc1
JG
2747end:
2748 return ret;
2749}
2750
2751static
50842bdc
PP
2752int bt_field_floating_point_copy(
2753 struct bt_field *src, struct bt_field *dst)
87d43dc1 2754{
50842bdc 2755 struct bt_field_floating_point *float_src, *float_dst;
87d43dc1 2756
fc25abce
PP
2757 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2758 src, dst);
50842bdc 2759 float_src = container_of(src, struct bt_field_floating_point,
87d43dc1 2760 parent);
50842bdc 2761 float_dst = container_of(dst, struct bt_field_floating_point,
87d43dc1 2762 parent);
dc3fffef 2763 float_dst->payload = float_src->payload;
fc25abce 2764 BT_LOGD_STR("Copied floating point number field.");
87d43dc1
JG
2765 return 0;
2766}
2767
2768static
50842bdc
PP
2769int bt_field_structure_copy(struct bt_field *src,
2770 struct bt_field *dst)
87d43dc1 2771{
fc25abce
PP
2772 int ret = 0;
2773 int64_t i;
50842bdc 2774 struct bt_field_structure *struct_src, *struct_dst;
87d43dc1 2775
fc25abce
PP
2776 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2777 src, dst);
50842bdc
PP
2778 struct_src = container_of(src, struct bt_field_structure, parent);
2779 struct_dst = container_of(dst, struct bt_field_structure, parent);
87d43dc1 2780
8bfa3f9c 2781 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
2782
2783 for (i = 0; i < struct_src->fields->len; i++) {
50842bdc 2784 struct bt_field *field =
50fd95bf 2785 g_ptr_array_index(struct_src->fields, i);
50842bdc 2786 struct bt_field *field_copy = NULL;
87d43dc1 2787
50fd95bf 2788 if (field) {
32e87ceb 2789 BT_LOGD("Copying structure field's field: src-field-addr=%p"
fc25abce 2790 "index=%" PRId64, field, i);
50842bdc 2791 field_copy = bt_field_copy(field);
50fd95bf 2792 if (!field_copy) {
fc25abce
PP
2793 BT_LOGE("Cannot copy structure field's field: "
2794 "src-field-addr=%p, index=%" PRId64,
2795 field, i);
50fd95bf
PP
2796 ret = -1;
2797 goto end;
2798 }
87d43dc1 2799 }
50fd95bf 2800
c58b9c62 2801 BT_MOVE(g_ptr_array_index(struct_dst->fields, i), field_copy);
87d43dc1 2802 }
fc25abce
PP
2803
2804 BT_LOGD_STR("Copied structure field.");
2805
87d43dc1
JG
2806end:
2807 return ret;
2808}
2809
2810static
50842bdc
PP
2811int bt_field_variant_copy(struct bt_field *src,
2812 struct bt_field *dst)
87d43dc1
JG
2813{
2814 int ret = 0;
50842bdc 2815 struct bt_field_variant *variant_src, *variant_dst;
87d43dc1 2816
fc25abce
PP
2817 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2818 src, dst);
50842bdc
PP
2819 variant_src = container_of(src, struct bt_field_variant, parent);
2820 variant_dst = container_of(dst, struct bt_field_variant, parent);
87d43dc1
JG
2821
2822 if (variant_src->tag) {
fc25abce 2823 BT_LOGD_STR("Copying variant field's tag field.");
50842bdc 2824 variant_dst->tag = bt_field_copy(variant_src->tag);
87d43dc1 2825 if (!variant_dst->tag) {
fc25abce 2826 BT_LOGE_STR("Cannot copy variant field's tag field.");
87d43dc1
JG
2827 ret = -1;
2828 goto end;
2829 }
2830 }
2831 if (variant_src->payload) {
fc25abce 2832 BT_LOGD_STR("Copying variant field's payload field.");
50842bdc 2833 variant_dst->payload = bt_field_copy(variant_src->payload);
87d43dc1 2834 if (!variant_dst->payload) {
fc25abce 2835 BT_LOGE_STR("Cannot copy variant field's payload field.");
87d43dc1
JG
2836 ret = -1;
2837 goto end;
2838 }
2839 }
fc25abce
PP
2840
2841 BT_LOGD_STR("Copied variant field.");
2842
87d43dc1
JG
2843end:
2844 return ret;
2845}
2846
2847static
50842bdc
PP
2848int bt_field_array_copy(struct bt_field *src,
2849 struct bt_field *dst)
87d43dc1 2850{
fc25abce
PP
2851 int ret = 0;
2852 int64_t i;
50842bdc 2853 struct bt_field_array *array_src, *array_dst;
87d43dc1 2854
fc25abce
PP
2855 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2856 src, dst);
50842bdc
PP
2857 array_src = container_of(src, struct bt_field_array, parent);
2858 array_dst = container_of(dst, struct bt_field_array, parent);
87d43dc1 2859
8bfa3f9c 2860 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1 2861 for (i = 0; i < array_src->elements->len; i++) {
50842bdc 2862 struct bt_field *field =
50fd95bf 2863 g_ptr_array_index(array_src->elements, i);
50842bdc 2864 struct bt_field *field_copy = NULL;
87d43dc1 2865
50fd95bf 2866 if (field) {
fc25abce
PP
2867 BT_LOGD("Copying array field's element field: field-addr=%p, "
2868 "index=%" PRId64, field, i);
50842bdc 2869 field_copy = bt_field_copy(field);
50fd95bf 2870 if (!field_copy) {
fc25abce
PP
2871 BT_LOGE("Cannot copy array field's element field: "
2872 "src-field-addr=%p, index=%" PRId64,
2873 field, i);
50fd95bf
PP
2874 ret = -1;
2875 goto end;
2876 }
87d43dc1 2877 }
50fd95bf 2878
8bfa3f9c 2879 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1 2880 }
fc25abce
PP
2881
2882 BT_LOGD_STR("Copied array field.");
2883
87d43dc1
JG
2884end:
2885 return ret;
2886}
2887
2888static
50842bdc
PP
2889int bt_field_sequence_copy(struct bt_field *src,
2890 struct bt_field *dst)
87d43dc1 2891{
fc25abce
PP
2892 int ret = 0;
2893 int64_t i;
50842bdc
PP
2894 struct bt_field_sequence *sequence_src, *sequence_dst;
2895 struct bt_field *src_length;
2896 struct bt_field *dst_length;
87d43dc1 2897
fc25abce
PP
2898 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2899 src, dst);
50842bdc
PP
2900 sequence_src = container_of(src, struct bt_field_sequence, parent);
2901 sequence_dst = container_of(dst, struct bt_field_sequence, parent);
87d43dc1 2902
50842bdc 2903 src_length = bt_field_sequence_get_length(src);
59ab494d
PP
2904 if (!src_length) {
2905 /* no length set yet: keep destination sequence empty */
2906 goto end;
2907 }
2908
2909 /* copy source length */
fc25abce 2910 BT_LOGD_STR("Copying sequence field's length field.");
50842bdc 2911 dst_length = bt_field_copy(src_length);
fc25abce 2912 BT_PUT(src_length);
59ab494d 2913 if (!dst_length) {
fc25abce 2914 BT_LOGE_STR("Cannot copy sequence field's length field.");
59ab494d
PP
2915 ret = -1;
2916 goto end;
2917 }
2918
2919 /* this will initialize the destination sequence's internal array */
50842bdc 2920 ret = bt_field_sequence_set_length(dst, dst_length);
83509119 2921 bt_put(dst_length);
59ab494d 2922 if (ret) {
fc25abce
PP
2923 BT_LOGE("Cannot set sequence field copy's length field: "
2924 "dst-length-field-addr=%p", dst_length);
2925 ret = -1;
59ab494d
PP
2926 goto end;
2927 }
2928
2929 assert(sequence_dst->elements->len == sequence_src->elements->len);
2930
87d43dc1 2931 for (i = 0; i < sequence_src->elements->len; i++) {
50842bdc 2932 struct bt_field *field =
50fd95bf 2933 g_ptr_array_index(sequence_src->elements, i);
50842bdc 2934 struct bt_field *field_copy = NULL;
87d43dc1 2935
50fd95bf 2936 if (field) {
fc25abce
PP
2937 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2938 "index=%" PRId64, field, i);
50842bdc 2939 field_copy = bt_field_copy(field);
50fd95bf 2940 if (!field_copy) {
fc25abce
PP
2941 BT_LOGE("Cannot copy sequence field's element field: "
2942 "src-field-addr=%p, index=%" PRId64,
2943 field, i);
50fd95bf
PP
2944 ret = -1;
2945 goto end;
2946 }
87d43dc1 2947 }
59ab494d 2948
8bfa3f9c 2949 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1 2950 }
fc25abce
PP
2951
2952 BT_LOGD_STR("Copied sequence field.");
2953
87d43dc1
JG
2954end:
2955 return ret;
2956}
2957
2958static
50842bdc
PP
2959int bt_field_string_copy(struct bt_field *src,
2960 struct bt_field *dst)
87d43dc1
JG
2961{
2962 int ret = 0;
50842bdc 2963 struct bt_field_string *string_src, *string_dst;
87d43dc1 2964
fc25abce
PP
2965 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
2966 src, dst);
50842bdc
PP
2967 string_src = container_of(src, struct bt_field_string, parent);
2968 string_dst = container_of(dst, struct bt_field_string, parent);
87d43dc1
JG
2969
2970 if (string_src->payload) {
2971 string_dst->payload = g_string_new(string_src->payload->str);
2972 if (!string_dst->payload) {
fc25abce 2973 BT_LOGE_STR("Failed to allocate a GString.");
87d43dc1
JG
2974 ret = -1;
2975 goto end;
2976 }
2977 }
fc25abce
PP
2978
2979 BT_LOGD_STR("Copied string field.");
2980
87d43dc1
JG
2981end:
2982 return ret;
2983}
2984
273b65be 2985static
50842bdc 2986int increase_packet_size(struct bt_stream_pos *pos)
273b65be
JG
2987{
2988 int ret;
2989
2990 assert(pos);
fc25abce
PP
2991 BT_LOGV("Increasing packet size: pos-offset=%" PRId64 ", "
2992 "cur-packet-size=%" PRIu64,
2993 pos->offset, pos->packet_size);
273b65be
JG
2994 ret = munmap_align(pos->base_mma);
2995 if (ret) {
c606e638
PP
2996 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
2997 ": ret=%d", ret);
273b65be
JG
2998 goto end;
2999 }
3000
3001 pos->packet_size += PACKET_LEN_INCREMENT;
d9548894
MD
3002 do {
3003 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
3004 pos->packet_size / CHAR_BIT);
3005 } while (ret == EINTR);
273b65be 3006 if (ret) {
c606e638
PP
3007 BT_LOGE_ERRNO("Failed to preallocate memory space",
3008 ": ret=%d", ret);
d9548894
MD
3009 errno = EINTR;
3010 ret = -1;
273b65be
JG
3011 goto end;
3012 }
3013
3014 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
3015 pos->flags, pos->fd, pos->mmap_offset);
3016 if (pos->base_mma == MAP_FAILED) {
c606e638
PP
3017 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
3018 ": ret=%d", ret);
273b65be
JG
3019 ret = -1;
3020 }
fc25abce
PP
3021
3022 BT_LOGV("Increased packet size: pos-offset=%" PRId64 ", "
3023 "new-packet-size=%" PRIu64,
3024 pos->offset, pos->packet_size);
b3376dd9
PP
3025 assert(pos->packet_size % 8 == 0);
3026
273b65be
JG
3027end:
3028 return ret;
3029}
918be005
PP
3030
3031static
50842bdc 3032void generic_field_freeze(struct bt_field *field)
918be005 3033{
d990a4fb 3034 field->frozen = true;
918be005
PP
3035}
3036
3037static
50842bdc 3038void bt_field_enumeration_freeze(struct bt_field *field)
918be005 3039{
50842bdc
PP
3040 struct bt_field_enumeration *enum_field =
3041 container_of(field, struct bt_field_enumeration, parent);
918be005 3042
fc25abce
PP
3043 BT_LOGD("Freezing enumeration field object: addr=%p", field);
3044 BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field->payload);
50842bdc 3045 bt_field_freeze(enum_field->payload);
918be005
PP
3046 generic_field_freeze(field);
3047}
3048
3049static
50842bdc 3050void bt_field_structure_freeze(struct bt_field *field)
918be005 3051{
fc25abce 3052 int64_t i;
50842bdc
PP
3053 struct bt_field_structure *structure_field =
3054 container_of(field, struct bt_field_structure, parent);
918be005 3055
fc25abce
PP
3056 BT_LOGD("Freezing structure field object: addr=%p", field);
3057
918be005 3058 for (i = 0; i < structure_field->fields->len; i++) {
50842bdc 3059 struct bt_field *field =
918be005
PP
3060 g_ptr_array_index(structure_field->fields, i);
3061
fc25abce
PP
3062 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
3063 field, i);
50842bdc 3064 bt_field_freeze(field);
918be005
PP
3065 }
3066
3067 generic_field_freeze(field);
3068}
3069
3070static
50842bdc 3071void bt_field_variant_freeze(struct bt_field *field)
918be005 3072{
50842bdc
PP
3073 struct bt_field_variant *variant_field =
3074 container_of(field, struct bt_field_variant, parent);
918be005 3075
fc25abce
PP
3076 BT_LOGD("Freezing variant field object: addr=%p", field);
3077 BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field->tag);
50842bdc 3078 bt_field_freeze(variant_field->tag);
fc25abce 3079 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field->payload);
50842bdc 3080 bt_field_freeze(variant_field->payload);
918be005
PP
3081 generic_field_freeze(field);
3082}
3083
3084static
50842bdc 3085void bt_field_array_freeze(struct bt_field *field)
918be005 3086{
fc25abce 3087 int64_t i;
50842bdc
PP
3088 struct bt_field_array *array_field =
3089 container_of(field, struct bt_field_array, parent);
918be005 3090
fc25abce
PP
3091 BT_LOGD("Freezing array field object: addr=%p", field);
3092
918be005 3093 for (i = 0; i < array_field->elements->len; i++) {
50842bdc 3094 struct bt_field *elem_field =
918be005
PP
3095 g_ptr_array_index(array_field->elements, i);
3096
fc25abce
PP
3097 BT_LOGD("Freezing array field object's element field: "
3098 "element-field-addr=%p, index=%" PRId64,
3099 elem_field, i);
50842bdc 3100 bt_field_freeze(elem_field);
918be005
PP
3101 }
3102
3103 generic_field_freeze(field);
3104}
3105
3106static
50842bdc 3107void bt_field_sequence_freeze(struct bt_field *field)
918be005 3108{
fc25abce 3109 int64_t i;
50842bdc
PP
3110 struct bt_field_sequence *sequence_field =
3111 container_of(field, struct bt_field_sequence, parent);
918be005 3112
fc25abce
PP
3113 BT_LOGD("Freezing sequence field object: addr=%p", field);
3114 BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p",
3115 sequence_field->length);
50842bdc 3116 bt_field_freeze(sequence_field->length);
918be005
PP
3117
3118 for (i = 0; i < sequence_field->elements->len; i++) {
50842bdc 3119 struct bt_field *elem_field =
918be005
PP
3120 g_ptr_array_index(sequence_field->elements, i);
3121
fc25abce
PP
3122 BT_LOGD("Freezing sequence field object's element field: "
3123 "element-field-addr=%p, index=%" PRId64,
3124 elem_field, i);
50842bdc 3125 bt_field_freeze(elem_field);
918be005
PP
3126 }
3127
3128 generic_field_freeze(field);
3129}
3130
3131BT_HIDDEN
50842bdc 3132void bt_field_freeze(struct bt_field *field)
918be005 3133{
50842bdc 3134 enum bt_field_type_id type_id;
35f77de4 3135
918be005
PP
3136 if (!field) {
3137 goto end;
3138 }
3139
fc25abce 3140 if (field->frozen) {
35f77de4
JG
3141 goto end;
3142 }
918be005 3143
fc25abce 3144 BT_LOGD("Freezing field object: addr=%p", field);
50842bdc
PP
3145 type_id = bt_field_get_type_id(field);
3146 assert(type_id > BT_FIELD_TYPE_ID_UNKNOWN &&
3147 type_id < BT_FIELD_TYPE_ID_NR);
35f77de4 3148 field_freeze_funcs[type_id](field);
918be005
PP
3149end:
3150 return;
3151}
76f869ab
JG
3152
3153static
50842bdc 3154bt_bool bt_field_generic_is_set(struct bt_field *field)
76f869ab
JG
3155{
3156 return field && field->payload_set;
3157}
3158
3159static
50842bdc 3160bt_bool bt_field_enumeration_is_set(struct bt_field *field)
76f869ab 3161{
d4bf905a 3162 bt_bool is_set = BT_FALSE;
50842bdc 3163 struct bt_field_enumeration *enumeration;
76f869ab
JG
3164
3165 if (!field) {
3166 goto end;
3167 }
3168
50842bdc 3169 enumeration = container_of(field, struct bt_field_enumeration,
76f869ab
JG
3170 parent);
3171 if (!enumeration->payload) {
3172 goto end;
3173 }
3174
50842bdc 3175 is_set = bt_field_is_set(enumeration->payload);
76f869ab 3176end:
d4bf905a 3177 return is_set;
76f869ab
JG
3178}
3179
3180static
50842bdc 3181bt_bool bt_field_structure_is_set(struct bt_field *field)
76f869ab 3182{
d4bf905a 3183 bt_bool is_set = BT_FALSE;
76f869ab 3184 size_t i;
50842bdc 3185 struct bt_field_structure *structure;
76f869ab
JG
3186
3187 if (!field) {
3188 goto end;
3189 }
3190
50842bdc 3191 structure = container_of(field, struct bt_field_structure, parent);
76f869ab 3192 for (i = 0; i < structure->fields->len; i++) {
50842bdc 3193 is_set = bt_field_is_set(
f1367c62 3194 structure->fields->pdata[i]);
d4bf905a 3195 if (!is_set) {
76f869ab
JG
3196 goto end;
3197 }
3198 }
3199end:
d4bf905a 3200 return is_set;
76f869ab
JG
3201}
3202
3203static
50842bdc 3204bt_bool bt_field_variant_is_set(struct bt_field *field)
76f869ab 3205{
d4bf905a 3206 bt_bool is_set = BT_FALSE;
50842bdc 3207 struct bt_field_variant *variant;
76f869ab
JG
3208
3209 if (!field) {
3210 goto end;
3211 }
3212
50842bdc
PP
3213 variant = container_of(field, struct bt_field_variant, parent);
3214 is_set = bt_field_is_set(variant->payload);
76f869ab 3215end:
d4bf905a 3216 return is_set;
76f869ab
JG
3217}
3218
3219static
50842bdc 3220bt_bool bt_field_array_is_set(struct bt_field *field)
76f869ab
JG
3221{
3222 size_t i;
d4bf905a 3223 bt_bool is_set = BT_FALSE;
50842bdc 3224 struct bt_field_array *array;
76f869ab
JG
3225
3226 if (!field) {
3227 goto end;
3228 }
3229
50842bdc 3230 array = container_of(field, struct bt_field_array, parent);
76f869ab 3231 for (i = 0; i < array->elements->len; i++) {
50842bdc 3232 is_set = bt_field_is_set(array->elements->pdata[i]);
d4bf905a 3233 if (!is_set) {
76f869ab
JG
3234 goto end;
3235 }
3236 }
3237end:
d4bf905a 3238 return is_set;
76f869ab
JG
3239}
3240
3241static
50842bdc 3242bt_bool bt_field_sequence_is_set(struct bt_field *field)
76f869ab
JG
3243{
3244 size_t i;
d4bf905a 3245 bt_bool is_set = BT_FALSE;
50842bdc 3246 struct bt_field_sequence *sequence;
76f869ab
JG
3247
3248 if (!field) {
3249 goto end;
3250 }
3251
50842bdc 3252 sequence = container_of(field, struct bt_field_sequence, parent);
6ead1648
JG
3253 if (!sequence->elements) {
3254 goto end;
3255 }
3256
76f869ab 3257 for (i = 0; i < sequence->elements->len; i++) {
50842bdc 3258 is_set = bt_field_is_set(sequence->elements->pdata[i]);
d4bf905a 3259 if (!is_set) {
76f869ab
JG
3260 goto end;
3261 }
3262 }
3263end:
d4bf905a 3264 return is_set;
76f869ab 3265}
This page took 0.216365 seconds and 4 git commands to generate.