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