Implement bt_ctf_clock_value interface
[babeltrace.git] / formats / 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
2e33ac5a
PP
29#include <babeltrace/ctf-ir/fields-internal.h>
30#include <babeltrace/ctf-ir/field-types-internal.h>
83509119
JG
31#include <babeltrace/object-internal.h>
32#include <babeltrace/ref.h>
273b65be 33#include <babeltrace/compiler.h>
a323afb2 34#include <babeltrace/compat/fcntl.h>
273b65be
JG
35
36#define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
37
38static
39struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
40static
41struct bt_ctf_field *bt_ctf_field_enumeration_create(
42 struct bt_ctf_field_type *);
43static
44struct bt_ctf_field *bt_ctf_field_floating_point_create(
45 struct bt_ctf_field_type *);
46static
47struct bt_ctf_field *bt_ctf_field_structure_create(
48 struct bt_ctf_field_type *);
49static
50struct bt_ctf_field *bt_ctf_field_variant_create(
51 struct bt_ctf_field_type *);
52static
53struct bt_ctf_field *bt_ctf_field_array_create(
54 struct bt_ctf_field_type *);
55static
56struct bt_ctf_field *bt_ctf_field_sequence_create(
57 struct bt_ctf_field_type *);
58static
59struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
60
61static
83509119 62void bt_ctf_field_destroy(struct bt_object *);
273b65be
JG
63static
64void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
65static
66void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
67static
68void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
69static
70void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
71static
72void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
73static
74void bt_ctf_field_array_destroy(struct bt_ctf_field *);
75static
76void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
77static
78void bt_ctf_field_string_destroy(struct bt_ctf_field *);
79
80static
ca116246 81int bt_ctf_field_generic_validate(struct bt_ctf_field *);
273b65be 82static
ca116246 83int bt_ctf_field_structure_validate(struct bt_ctf_field *);
273b65be 84static
ca116246 85int bt_ctf_field_variant_validate(struct bt_ctf_field *);
273b65be 86static
ca116246 87int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
273b65be 88static
ca116246 89int bt_ctf_field_array_validate(struct bt_ctf_field *);
273b65be 90static
ca116246 91int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
273b65be 92
12c8a1a3 93static
ca116246 94int bt_ctf_field_generic_reset(struct bt_ctf_field *);
12c8a1a3 95static
ca116246 96int bt_ctf_field_structure_reset(struct bt_ctf_field *);
12c8a1a3 97static
ca116246 98int bt_ctf_field_variant_reset(struct bt_ctf_field *);
12c8a1a3 99static
ca116246 100int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
12c8a1a3 101static
ca116246 102int bt_ctf_field_array_reset(struct bt_ctf_field *);
12c8a1a3 103static
ca116246 104int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
12c8a1a3 105static
ca116246 106int bt_ctf_field_string_reset(struct bt_ctf_field *);
12c8a1a3 107
273b65be
JG
108static
109int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
110 struct ctf_stream_pos *);
111static
112int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
113 struct ctf_stream_pos *);
114static
115int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
116 struct ctf_stream_pos *);
117static
118int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
119 struct ctf_stream_pos *);
120static
121int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
122 struct ctf_stream_pos *);
123static
124int bt_ctf_field_array_serialize(struct bt_ctf_field *,
125 struct ctf_stream_pos *);
126static
127int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
128 struct ctf_stream_pos *);
129static
130int bt_ctf_field_string_serialize(struct bt_ctf_field *,
131 struct ctf_stream_pos *);
132
87d43dc1
JG
133static
134int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
135static
136int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
137static
138int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
139 struct bt_ctf_field *);
140static
141int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
142static
143int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
144static
145int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
146static
147int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
148static
149int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
150
918be005
PP
151static
152void generic_field_freeze(struct bt_ctf_field *);
153static
154void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
155static
156void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
157static
158void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
159static
160void bt_ctf_field_array_freeze(struct bt_ctf_field *);
161static
162void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
163
273b65be
JG
164static
165int increase_packet_size(struct ctf_stream_pos *pos);
166
167static
ce6da4fd 168struct bt_ctf_field *(* const field_create_funcs[])(
273b65be 169 struct bt_ctf_field_type *) = {
9a19a512
PP
170 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
171 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
172 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 173 bt_ctf_field_floating_point_create,
9a19a512
PP
174 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
175 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
176 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
177 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
178 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_create,
273b65be
JG
179};
180
181static
ce6da4fd 182void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
9a19a512
PP
183 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_destroy,
184 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_destroy,
185 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 186 bt_ctf_field_floating_point_destroy,
9a19a512
PP
187 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_destroy,
188 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_destroy,
189 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_destroy,
190 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_destroy,
191 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_destroy,
273b65be
JG
192};
193
194static
ce6da4fd 195int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
9a19a512
PP
196 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_validate,
197 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_validate,
198 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_validate,
199 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_validate,
200 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_validate,
201 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_validate,
202 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_validate,
203 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_validate,
273b65be
JG
204};
205
12c8a1a3 206static
ce6da4fd 207int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
9a19a512
PP
208 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_reset,
209 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_reset,
210 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_reset,
211 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_reset,
212 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_reset,
213 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_reset,
214 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_reset,
215 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_reset,
12c8a1a3
JG
216};
217
273b65be 218static
ce6da4fd 219int (* const field_serialize_funcs[])(struct bt_ctf_field *,
273b65be 220 struct ctf_stream_pos *) = {
9a19a512
PP
221 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_serialize,
222 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_serialize,
223 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 224 bt_ctf_field_floating_point_serialize,
9a19a512
PP
225 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_serialize,
226 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_serialize,
227 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_serialize,
228 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_serialize,
229 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_serialize,
273b65be
JG
230};
231
87d43dc1 232static
ce6da4fd
JG
233int (* const field_copy_funcs[])(struct bt_ctf_field *,
234 struct bt_ctf_field *) = {
9a19a512
PP
235 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_copy,
236 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_copy,
237 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_copy,
238 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_copy,
239 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_copy,
240 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_copy,
241 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_copy,
242 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_copy,
87d43dc1
JG
243};
244
918be005
PP
245static
246void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
247 [BT_CTF_TYPE_ID_INTEGER] = generic_field_freeze,
248 [BT_CTF_TYPE_ID_FLOAT] = generic_field_freeze,
249 [BT_CTF_TYPE_ID_STRING] = generic_field_freeze,
250 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
251 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
252 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
253 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
254 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
255};
256
273b65be
JG
257struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
258{
259 struct bt_ctf_field *field = NULL;
9a19a512 260 enum bt_ctf_type_id type_id;
81e36fac 261 int ret;
273b65be
JG
262
263 if (!type) {
264 goto error;
265 }
266
267 type_id = bt_ctf_field_type_get_type_id(type);
9a19a512
PP
268 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
269 type_id >= BT_CTF_NR_TYPE_IDS) {
81e36fac
PP
270 goto error;
271 }
272
273 /* Field class MUST be valid */
274 ret = bt_ctf_field_type_validate(type);
275
276 if (ret) {
277 /* Invalid */
273b65be
JG
278 goto error;
279 }
280
281 field = field_create_funcs[type_id](type);
282 if (!field) {
283 goto error;
284 }
285
286 /* The type's declaration can't change after this point */
287 bt_ctf_field_type_freeze(type);
83509119
JG
288 bt_get(type);
289 bt_object_init(field, bt_ctf_field_destroy);
273b65be
JG
290 field->type = type;
291error:
292 return field;
293}
294
295void bt_ctf_field_get(struct bt_ctf_field *field)
296{
83509119 297 bt_get(field);
273b65be
JG
298}
299
300void bt_ctf_field_put(struct bt_ctf_field *field)
301{
83509119 302 bt_put(field);
273b65be
JG
303}
304
cd95e351
JG
305struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
306{
307 struct bt_ctf_field_type *ret = NULL;
308
309 if (!field) {
310 goto end;
311 }
312
313 ret = field->type;
83509119 314 bt_get(ret);
cd95e351
JG
315end:
316 return ret;
317}
318
9a19a512 319enum bt_ctf_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
4ebcc695 320{
9a19a512 321 enum bt_ctf_type_id ret = BT_CTF_TYPE_ID_UNKNOWN;
4ebcc695
PP
322
323 if (!field) {
324 goto end;
325 }
326
327 ret = bt_ctf_field_type_get_type_id(field->type);
328end:
329 return ret;
330}
331
8f3553be
PP
332int bt_ctf_field_is_integer(struct bt_ctf_field *field)
333{
9a19a512 334 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_INTEGER;
8f3553be
PP
335}
336
337int bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
338{
9a19a512 339 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_FLOAT;
8f3553be
PP
340}
341
342int bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
343{
9a19a512 344 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ENUM;
8f3553be
PP
345}
346
347int bt_ctf_field_is_string(struct bt_ctf_field *field)
348{
9a19a512 349 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRING;
8f3553be
PP
350}
351
352int bt_ctf_field_is_structure(struct bt_ctf_field *field)
353{
9a19a512 354 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRUCT;
8f3553be
PP
355}
356
357int bt_ctf_field_is_array(struct bt_ctf_field *field)
358{
9a19a512 359 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ARRAY;
8f3553be
PP
360}
361
362int bt_ctf_field_is_sequence(struct bt_ctf_field *field)
363{
9a19a512 364 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_SEQUENCE;
8f3553be
PP
365}
366
367int bt_ctf_field_is_variant(struct bt_ctf_field *field)
368{
9a19a512 369 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_VARIANT;
8f3553be
PP
370}
371
cd95e351
JG
372struct bt_ctf_field *bt_ctf_field_sequence_get_length(
373 struct bt_ctf_field *field)
374{
375 struct bt_ctf_field *ret = NULL;
376 struct bt_ctf_field_sequence *sequence;
377
378 if (!field) {
379 goto end;
380 }
381
382 if (bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 383 BT_CTF_TYPE_ID_SEQUENCE) {
cd95e351
JG
384 goto end;
385 }
386
387 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
388 ret = sequence->length;
83509119 389 bt_get(ret);
cd95e351
JG
390end:
391 return ret;
392}
393
273b65be
JG
394int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
395 struct bt_ctf_field *length_field)
396{
397 int ret = 0;
398 struct bt_ctf_field_type_integer *length_type;
399 struct bt_ctf_field_integer *length;
400 struct bt_ctf_field_sequence *sequence;
401 uint64_t sequence_length;
402
918be005 403 if (!field || !length_field || field->frozen) {
273b65be
JG
404 ret = -1;
405 goto end;
406 }
407 if (bt_ctf_field_type_get_type_id(length_field->type) !=
9a19a512 408 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
409 ret = -1;
410 goto end;
411 }
412
413 length_type = container_of(length_field->type,
414 struct bt_ctf_field_type_integer, parent);
152e7331 415 /* The length field must be unsigned */
273b65be
JG
416 if (length_type->declaration.signedness) {
417 ret = -1;
418 goto end;
419 }
420
421 length = container_of(length_field, struct bt_ctf_field_integer,
422 parent);
423 sequence_length = length->definition.value._unsigned;
424 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
425 if (sequence->elements) {
426 g_ptr_array_free(sequence->elements, TRUE);
83509119 427 bt_put(sequence->length);
273b65be
JG
428 }
429
fe0fe95c 430 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
273b65be
JG
431 if (!sequence->elements) {
432 ret = -1;
433 goto end;
434 }
435
fe0fe95c 436 g_ptr_array_set_free_func(sequence->elements,
83509119
JG
437 (GDestroyNotify) bt_put);
438 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
439 bt_get(length_field);
273b65be
JG
440 sequence->length = length_field;
441end:
442 return ret;
443}
444
445struct bt_ctf_field *bt_ctf_field_structure_get_field(
446 struct bt_ctf_field *field, const char *name)
447{
448 struct bt_ctf_field *new_field = NULL;
449 GQuark field_quark;
450 struct bt_ctf_field_structure *structure;
b92ddaaa 451 struct bt_ctf_field_type *field_type = NULL;
273b65be
JG
452 size_t index;
453
454 if (!field || !name ||
455 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 456 BT_CTF_TYPE_ID_STRUCT) {
273b65be
JG
457 goto error;
458 }
459
460 field_quark = g_quark_from_string(name);
461 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
462 field_type =
463 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
464 name);
273b65be
JG
465 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
466 GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
467 goto error;
468 }
469
470 if (structure->fields->pdata[index]) {
471 new_field = structure->fields->pdata[index];
472 goto end;
473 }
474
918be005
PP
475 /* We don't want to modify this field if it's frozen */
476 if (field->frozen) {
477 goto end;
478 }
479
273b65be
JG
480 new_field = bt_ctf_field_create(field_type);
481 if (!new_field) {
482 goto error;
483 }
484
485 structure->fields->pdata[index] = new_field;
486end:
83509119 487 bt_get(new_field);
273b65be 488error:
b92ddaaa 489 if (field_type) {
83509119 490 bt_put(field_type);
b92ddaaa 491 }
273b65be
JG
492 return new_field;
493}
494
cd95e351 495struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
074ee56d 496 struct bt_ctf_field *field, int index)
cd95e351
JG
497{
498 int ret;
499 const char *field_name;
500 struct bt_ctf_field_structure *structure;
501 struct bt_ctf_field_type *structure_type;
502 struct bt_ctf_field_type *field_type = NULL;
503 struct bt_ctf_field *ret_field = NULL;
504
505 if (!field ||
9a19a512
PP
506 bt_ctf_field_type_get_type_id(field->type) !=
507 BT_CTF_TYPE_ID_STRUCT) {
cd95e351
JG
508 goto end;
509 }
510
511 structure = container_of(field, struct bt_ctf_field_structure, parent);
512 if (index >= structure->fields->len) {
513 goto error;
514 }
515
516 ret_field = structure->fields->pdata[index];
517 if (ret_field) {
518 goto end;
519 }
520
918be005
PP
521 /* We don't want to modify this field if it's frozen */
522 if (field->frozen) {
523 goto end;
524 }
525
cd95e351
JG
526 /* Field has not been instanciated yet, create it */
527 structure_type = bt_ctf_field_get_type(field);
528 if (!structure_type) {
529 goto error;
530 }
531
532 ret = bt_ctf_field_type_structure_get_field(structure_type,
533 &field_name, &field_type, index);
83509119 534 bt_put(structure_type);
cd95e351
JG
535 if (ret) {
536 goto error;
537 }
538
539 ret_field = bt_ctf_field_create(field_type);
540 if (!ret_field) {
541 goto error;
542 }
543
544 structure->fields->pdata[index] = ret_field;
545end:
83509119 546 bt_get(ret_field);
cd95e351 547error:
83509119 548 bt_put(field_type);
cd95e351
JG
549 return ret_field;
550}
551
273b65be
JG
552BT_HIDDEN
553int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
554 const char *name, struct bt_ctf_field *value)
555{
556 int ret = 0;
557 GQuark field_quark;
558 struct bt_ctf_field_structure *structure;
b92ddaaa 559 struct bt_ctf_field_type *expected_field_type = NULL;
273b65be
JG
560 size_t index;
561
918be005 562 if (!field || !name || !value || field->frozen ||
273b65be 563 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 564 BT_CTF_TYPE_ID_STRUCT) {
273b65be
JG
565 ret = -1;
566 goto end;
567 }
568
569 field_quark = g_quark_from_string(name);
570 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
571 expected_field_type =
572 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
573 name);
09840de5
PP
574
575 if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
273b65be
JG
576 ret = -1;
577 goto end;
578 }
579
580 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
581 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
582 goto end;
583 }
584
585 if (structure->fields->pdata[index]) {
83509119 586 bt_put(structure->fields->pdata[index]);
273b65be
JG
587 }
588
589 structure->fields->pdata[index] = value;
83509119 590 bt_get(value);
273b65be 591end:
b92ddaaa 592 if (expected_field_type) {
83509119 593 bt_put(expected_field_type);
b92ddaaa 594 }
273b65be
JG
595 return ret;
596}
597
598struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
599 uint64_t index)
600{
601 struct bt_ctf_field *new_field = NULL;
b92ddaaa 602 struct bt_ctf_field_type *field_type = NULL;
273b65be 603 struct bt_ctf_field_array *array;
273b65be
JG
604
605 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 606 BT_CTF_TYPE_ID_ARRAY) {
273b65be
JG
607 goto end;
608 }
609
610 array = container_of(field, struct bt_ctf_field_array, parent);
611 if (index >= array->elements->len) {
612 goto end;
613 }
614
b92ddaaa 615 field_type = bt_ctf_field_type_array_get_element_type(field->type);
273b65be
JG
616 if (array->elements->pdata[(size_t)index]) {
617 new_field = array->elements->pdata[(size_t)index];
618 goto end;
619 }
620
918be005
PP
621 /* We don't want to modify this field if it's frozen */
622 if (field->frozen) {
623 goto end;
624 }
625
273b65be 626 new_field = bt_ctf_field_create(field_type);
273b65be
JG
627 array->elements->pdata[(size_t)index] = new_field;
628end:
b92ddaaa 629 if (field_type) {
83509119 630 bt_put(field_type);
b92ddaaa 631 }
92c8b4f9 632 if (new_field) {
83509119 633 bt_get(new_field);
92c8b4f9 634 }
273b65be
JG
635 return new_field;
636}
637
638struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
639 uint64_t index)
640{
641 struct bt_ctf_field *new_field = NULL;
b92ddaaa 642 struct bt_ctf_field_type *field_type = NULL;
273b65be 643 struct bt_ctf_field_sequence *sequence;
273b65be
JG
644
645 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 646 BT_CTF_TYPE_ID_SEQUENCE) {
273b65be
JG
647 goto end;
648 }
649
650 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
651 if (!sequence->elements || sequence->elements->len <= index) {
652 goto end;
653 }
654
b92ddaaa 655 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
83509119
JG
656 if (sequence->elements->pdata[(size_t) index]) {
657 new_field = sequence->elements->pdata[(size_t) index];
273b65be
JG
658 goto end;
659 }
660
918be005
PP
661 /* We don't want to modify this field if it's frozen */
662 if (field->frozen) {
663 goto end;
664 }
665
273b65be 666 new_field = bt_ctf_field_create(field_type);
83509119 667 sequence->elements->pdata[(size_t) index] = new_field;
273b65be 668end:
b92ddaaa 669 if (field_type) {
83509119 670 bt_put(field_type);
b92ddaaa 671 }
92c8b4f9 672 if (new_field) {
83509119 673 bt_get(new_field);
92c8b4f9 674 }
273b65be
JG
675 return new_field;
676}
677
678struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
679 struct bt_ctf_field *tag_field)
680{
681 struct bt_ctf_field *new_field = NULL;
682 struct bt_ctf_field_variant *variant;
683 struct bt_ctf_field_type_variant *variant_type;
684 struct bt_ctf_field_type *field_type;
685 struct bt_ctf_field *tag_enum = NULL;
686 struct bt_ctf_field_integer *tag_enum_integer;
687 int64_t tag_enum_value;
688
689 if (!field || !tag_field ||
690 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 691 BT_CTF_TYPE_ID_VARIANT ||
273b65be 692 bt_ctf_field_type_get_type_id(tag_field->type) !=
9a19a512 693 BT_CTF_TYPE_ID_ENUM) {
273b65be
JG
694 goto end;
695 }
696
697 variant = container_of(field, struct bt_ctf_field_variant, parent);
698 variant_type = container_of(field->type,
699 struct bt_ctf_field_type_variant, parent);
700 tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
701 if (!tag_enum) {
702 goto end;
703 }
704
705 tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
706 parent);
707
2c661a4d 708 if (bt_ctf_field_validate(tag_field) < 0) {
273b65be
JG
709 goto end;
710 }
711
712 tag_enum_value = tag_enum_integer->definition.value._signed;
2829190c
PP
713
714 /*
715 * If the variant currently has a tag and a payload, and if the
716 * requested tag value is the same as the current one, return
717 * the current payload instead of creating a fresh one.
718 */
719 if (variant->tag && variant->payload) {
720 struct bt_ctf_field *cur_tag_container = NULL;
721 struct bt_ctf_field_integer *cur_tag_enum_integer;
722 int64_t cur_tag_value;
723
724 cur_tag_container =
725 bt_ctf_field_enumeration_get_container(variant->tag);
9a5df386 726 assert(cur_tag_container);
2829190c
PP
727 cur_tag_enum_integer = container_of(cur_tag_container,
728 struct bt_ctf_field_integer, parent);
83509119 729 bt_put(cur_tag_container);
2829190c
PP
730 cur_tag_value = cur_tag_enum_integer->definition.value._signed;
731
732 if (cur_tag_value == tag_enum_value) {
733 new_field = variant->payload;
83509119 734 bt_get(new_field);
2829190c
PP
735 goto end;
736 }
737 }
738
918be005
PP
739 /* We don't want to modify this field if it's frozen */
740 if (field->frozen) {
741 goto end;
742 }
743
b92ddaaa
JG
744 field_type = bt_ctf_field_type_variant_get_field_type_signed(
745 variant_type, tag_enum_value);
273b65be
JG
746 if (!field_type) {
747 goto end;
748 }
749
750 new_field = bt_ctf_field_create(field_type);
751 if (!new_field) {
752 goto end;
753 }
754
83509119
JG
755 bt_put(variant->tag);
756 bt_put(variant->payload);
757 bt_get(new_field);
758 bt_get(tag_field);
273b65be
JG
759 variant->tag = tag_field;
760 variant->payload = new_field;
761end:
83509119 762 bt_put(tag_enum);
273b65be
JG
763 return new_field;
764}
765
3f4a108d
PP
766struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
767 struct bt_ctf_field *variant_field)
768{
769 struct bt_ctf_field *current_field = NULL;
770 struct bt_ctf_field_variant *variant;
771
772 if (!variant_field ||
773 bt_ctf_field_type_get_type_id(variant_field->type) !=
9a19a512 774 BT_CTF_TYPE_ID_VARIANT) {
3f4a108d
PP
775 goto end;
776 }
777
778 variant = container_of(variant_field, struct bt_ctf_field_variant,
779 parent);
780
781 if (variant->payload) {
782 current_field = variant->payload;
83509119 783 bt_get(current_field);
3f4a108d
PP
784 goto end;
785 }
786
787end:
788 return current_field;
789}
790
f78d67fb
JG
791struct bt_ctf_field *bt_ctf_field_variant_get_tag(
792 struct bt_ctf_field *variant_field)
793{
794 struct bt_ctf_field *tag = NULL;
795 struct bt_ctf_field_variant *variant;
796
797 if (!variant_field ||
798 bt_ctf_field_type_get_type_id(variant_field->type) !=
799 BT_CTF_TYPE_ID_VARIANT) {
800 goto end;
801 }
802
803 variant = container_of(variant_field, struct bt_ctf_field_variant,
804 parent);
805 if (variant->tag) {
806 tag = bt_get(variant->tag);
807 }
808end:
809 return tag;
810}
811
273b65be
JG
812struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
813 struct bt_ctf_field *field)
814{
815 struct bt_ctf_field *container = NULL;
816 struct bt_ctf_field_enumeration *enumeration;
817
b92ddaaa 818 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 819 BT_CTF_TYPE_ID_ENUM) {
273b65be
JG
820 goto end;
821 }
822
823 enumeration = container_of(field, struct bt_ctf_field_enumeration,
824 parent);
825 if (!enumeration->payload) {
918be005
PP
826 /* We don't want to modify this field if it's frozen */
827 if (field->frozen) {
828 goto end;
829 }
830
273b65be
JG
831 struct bt_ctf_field_type_enumeration *enumeration_type =
832 container_of(field->type,
833 struct bt_ctf_field_type_enumeration, parent);
834 enumeration->payload =
835 bt_ctf_field_create(enumeration_type->container);
836 }
837
838 container = enumeration->payload;
83509119 839 bt_get(container);
273b65be
JG
840end:
841 return container;
842}
843
cd95e351
JG
844const char *bt_ctf_field_enumeration_get_mapping_name(
845 struct bt_ctf_field *field)
846{
847 int ret;
848 const char *name = NULL;
849 struct bt_ctf_field *container = NULL;
850 struct bt_ctf_field_type *container_type = NULL;
851 struct bt_ctf_field_type_integer *integer_type = NULL;
852 struct bt_ctf_field_type_enumeration *enumeration_type = NULL;
853
854 container = bt_ctf_field_enumeration_get_container(field);
855 if (!container) {
856 goto end;
857 }
858
859 container_type = bt_ctf_field_get_type(container);
860 if (!container_type) {
861 goto error_put_container;
862 }
863
864 integer_type = container_of(container_type,
865 struct bt_ctf_field_type_integer, parent);
866 enumeration_type = container_of(field->type,
867 struct bt_ctf_field_type_enumeration, parent);
868
10817e06 869 if (!integer_type->declaration.signedness) {
cd95e351
JG
870 uint64_t value;
871 ret = bt_ctf_field_unsigned_integer_get_value(container,
872 &value);
873 if (ret) {
874 goto error_put_container_type;
875 }
876
877 name = bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
878 enumeration_type, value);
879 } else {
880 int64_t value;
881 ret = bt_ctf_field_signed_integer_get_value(container,
882 &value);
883 if (ret) {
884 goto error_put_container_type;
885 }
886
887 name = bt_ctf_field_type_enumeration_get_mapping_name_signed(
888 enumeration_type, value);
889 }
890
891error_put_container_type:
83509119 892 bt_put(container_type);
cd95e351 893error_put_container:
83509119 894 bt_put(container);
cd95e351
JG
895end:
896 return name;
897}
898
899int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
900 int64_t *value)
901{
902 int ret = 0;
903 struct bt_ctf_field_integer *integer;
904 struct bt_ctf_field_type_integer *integer_type;
905
906 if (!field || !value || !field->payload_set ||
907 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 908 BT_CTF_TYPE_ID_INTEGER) {
cd95e351
JG
909 ret = -1;
910 goto end;
911 }
912
913 integer_type = container_of(field->type,
914 struct bt_ctf_field_type_integer, parent);
915 if (!integer_type->declaration.signedness) {
916 ret = -1;
917 goto end;
918 }
919
920 integer = container_of(field,
921 struct bt_ctf_field_integer, parent);
922 *value = integer->definition.value._signed;
923end:
924 return ret;
925}
926
273b65be
JG
927int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
928 int64_t value)
929{
930 int ret = 0;
931 struct bt_ctf_field_integer *integer;
932 struct bt_ctf_field_type_integer *integer_type;
933 unsigned int size;
934 int64_t min_value, max_value;
935
918be005 936 if (!field || field->frozen ||
273b65be 937 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 938 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
939 ret = -1;
940 goto end;
941 }
942
943 integer = container_of(field, struct bt_ctf_field_integer, parent);
944 integer_type = container_of(field->type,
945 struct bt_ctf_field_type_integer, parent);
946 if (!integer_type->declaration.signedness) {
947 ret = -1;
948 goto end;
949 }
950
951 size = integer_type->declaration.len;
9dc0d640
JG
952 min_value = -(1ULL << (size - 1));
953 max_value = (1ULL << (size - 1)) - 1;
273b65be
JG
954 if (value < min_value || value > max_value) {
955 ret = -1;
956 goto end;
957 }
958
959 integer->definition.value._signed = value;
960 integer->parent.payload_set = 1;
961end:
962 return ret;
963}
964
cd95e351
JG
965int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
966 uint64_t *value)
967{
968 int ret = 0;
969 struct bt_ctf_field_integer *integer;
970 struct bt_ctf_field_type_integer *integer_type;
971
972 if (!field || !value || !field->payload_set ||
973 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 974 BT_CTF_TYPE_ID_INTEGER) {
cd95e351
JG
975 ret = -1;
976 goto end;
977 }
978
979 integer_type = container_of(field->type,
980 struct bt_ctf_field_type_integer, parent);
981 if (integer_type->declaration.signedness) {
982 ret = -1;
983 goto end;
984 }
985
986 integer = container_of(field,
987 struct bt_ctf_field_integer, parent);
988 *value = integer->definition.value._unsigned;
989end:
990 return ret;
991}
992
273b65be
JG
993int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
994 uint64_t value)
995{
996 int ret = 0;
997 struct bt_ctf_field_integer *integer;
998 struct bt_ctf_field_type_integer *integer_type;
999 unsigned int size;
1000 uint64_t max_value;
1001
918be005 1002 if (!field || field->frozen ||
273b65be 1003 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1004 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
1005 ret = -1;
1006 goto end;
1007 }
1008
1009 integer = container_of(field, struct bt_ctf_field_integer, parent);
1010 integer_type = container_of(field->type,
1011 struct bt_ctf_field_type_integer, parent);
1012 if (integer_type->declaration.signedness) {
1013 ret = -1;
1014 goto end;
1015 }
1016
1017 size = integer_type->declaration.len;
8684abc8 1018 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
273b65be
JG
1019 if (value > max_value) {
1020 ret = -1;
1021 goto end;
1022 }
1023
1024 integer->definition.value._unsigned = value;
1025 integer->parent.payload_set = 1;
1026end:
1027 return ret;
1028}
1029
cd95e351
JG
1030int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1031 double *value)
1032{
1033 int ret = 0;
1034 struct bt_ctf_field_floating_point *floating_point;
1035
1036 if (!field || !value || !field->payload_set ||
1037 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1038 BT_CTF_TYPE_ID_FLOAT) {
cd95e351
JG
1039 ret = -1;
1040 goto end;
1041 }
1042
1043 floating_point = container_of(field,
1044 struct bt_ctf_field_floating_point, parent);
1045 *value = floating_point->definition.value;
1046end:
1047 return ret;
1048}
1049
273b65be
JG
1050int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1051 double value)
1052{
1053 int ret = 0;
1054 struct bt_ctf_field_floating_point *floating_point;
1055
918be005 1056 if (!field || field->frozen ||
273b65be 1057 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1058 BT_CTF_TYPE_ID_FLOAT) {
273b65be
JG
1059 ret = -1;
1060 goto end;
1061 }
1062 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1063 parent);
1064 floating_point->definition.value = value;
1065 floating_point->parent.payload_set = 1;
1066end:
1067 return ret;
1068}
1069
cd95e351
JG
1070const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1071{
1072 const char *ret = NULL;
1073 struct bt_ctf_field_string *string;
1074
1075 if (!field || !field->payload_set ||
1076 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1077 BT_CTF_TYPE_ID_STRING) {
cd95e351
JG
1078 goto end;
1079 }
1080
1081 string = container_of(field,
1082 struct bt_ctf_field_string, parent);
1083 ret = string->payload->str;
1084end:
1085 return ret;
1086}
1087
273b65be
JG
1088int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
1089 const char *value)
1090{
1091 int ret = 0;
1092 struct bt_ctf_field_string *string;
1093
918be005 1094 if (!field || !value || field->frozen ||
273b65be 1095 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1096 BT_CTF_TYPE_ID_STRING) {
273b65be
JG
1097 ret = -1;
1098 goto end;
1099 }
1100
1101 string = container_of(field, struct bt_ctf_field_string, parent);
1102 if (string->payload) {
97736814
JG
1103 g_string_assign(string->payload, value);
1104 } else {
1105 string->payload = g_string_new(value);
273b65be
JG
1106 }
1107
273b65be
JG
1108 string->parent.payload_set = 1;
1109end:
1110 return ret;
1111}
1112
c6f9c5a3
PP
1113int bt_ctf_field_string_append(struct bt_ctf_field *field,
1114 const char *value)
1115{
1116 int ret = 0;
1117 struct bt_ctf_field_string *string_field;
1118
918be005 1119 if (!field || !value || field->frozen ||
c6f9c5a3 1120 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1121 BT_CTF_TYPE_ID_STRING) {
c6f9c5a3
PP
1122 ret = -1;
1123 goto end;
1124 }
1125
1126 string_field = container_of(field, struct bt_ctf_field_string, parent);
1127
1128 if (string_field->payload) {
1129 g_string_append(string_field->payload, value);
1130 } else {
1131 string_field->payload = g_string_new(value);
1132 }
1133
1134 string_field->parent.payload_set = 1;
1135
1136end:
1137 return ret;
1138}
1139
f98c6554
PP
1140int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1141 const char *value, unsigned int length)
1142{
1143 int i;
1144 int ret = 0;
1145 unsigned int effective_length = length;
1146 struct bt_ctf_field_string *string_field;
1147
918be005 1148 if (!field || !value || field->frozen ||
f98c6554 1149 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1150 BT_CTF_TYPE_ID_STRING) {
f98c6554
PP
1151 ret = -1;
1152 goto end;
1153 }
1154
1155 string_field = container_of(field, struct bt_ctf_field_string, parent);
1156
1157 /* make sure no null bytes are appended */
1158 for (i = 0; i < length; ++i) {
1159 if (value[i] == '\0') {
1160 effective_length = i;
1161 break;
1162 }
1163 }
1164
1165 if (string_field->payload) {
ce6d5230 1166 g_string_append_len(string_field->payload, value,
f98c6554
PP
1167 effective_length);
1168 } else {
1169 string_field->payload = g_string_new_len(value,
1170 effective_length);
1171 }
1172
1173 string_field->parent.payload_set = 1;
1174
1175end:
1176 return ret;
1177}
1178
273b65be
JG
1179BT_HIDDEN
1180int bt_ctf_field_validate(struct bt_ctf_field *field)
1181{
1182 int ret = 0;
9a19a512 1183 enum bt_ctf_type_id type_id;
273b65be
JG
1184
1185 if (!field) {
1186 ret = -1;
1187 goto end;
1188 }
1189
1190 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1191 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1192 ret = -1;
1193 goto end;
1194 }
1195
1196 ret = field_validate_funcs[type_id](field);
1197end:
1198 return ret;
1199}
1200
12c8a1a3
JG
1201BT_HIDDEN
1202int bt_ctf_field_reset(struct bt_ctf_field *field)
1203{
1204 int ret = 0;
9a19a512 1205 enum bt_ctf_type_id type_id;
12c8a1a3
JG
1206
1207 if (!field) {
1208 ret = -1;
1209 goto end;
1210 }
1211
1212 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1213 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
12c8a1a3
JG
1214 ret = -1;
1215 goto end;
1216 }
1217
1218 ret = field_reset_funcs[type_id](field);
1219end:
1220 return ret;
1221}
1222
273b65be
JG
1223BT_HIDDEN
1224int bt_ctf_field_serialize(struct bt_ctf_field *field,
1225 struct ctf_stream_pos *pos)
1226{
1227 int ret = 0;
9a19a512 1228 enum bt_ctf_type_id type_id;
273b65be
JG
1229
1230 if (!field || !pos) {
1231 ret = -1;
1232 goto end;
1233 }
1234
1235 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1236 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1237 ret = -1;
1238 goto end;
1239 }
1240
1241 ret = field_serialize_funcs[type_id](field, pos);
1242end:
1243 return ret;
1244}
1245
87d43dc1
JG
1246struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1247{
1248 int ret;
1249 struct bt_ctf_field *copy = NULL;
9a19a512 1250 enum bt_ctf_type_id type_id;
87d43dc1
JG
1251
1252 if (!field) {
87d43dc1
JG
1253 goto end;
1254 }
1255
1256 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1257 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
87d43dc1
JG
1258 goto end;
1259 }
1260
1261 copy = bt_ctf_field_create(field->type);
1262 if (!copy) {
1263 goto end;
1264 }
1265
70996764 1266 copy->payload_set = field->payload_set;
87d43dc1
JG
1267 ret = field_copy_funcs[type_id](field, copy);
1268 if (ret) {
83509119 1269 bt_put(copy);
87d43dc1
JG
1270 copy = NULL;
1271 }
1272end:
1273 return copy;
1274}
1275
273b65be
JG
1276static
1277struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1278{
1279 struct bt_ctf_field_type_integer *integer_type = container_of(type,
1280 struct bt_ctf_field_type_integer, parent);
1281 struct bt_ctf_field_integer *integer = g_new0(
1282 struct bt_ctf_field_integer, 1);
1283
1284 if (integer) {
1285 integer->definition.declaration = &integer_type->declaration;
1286 }
1287
1288 return integer ? &integer->parent : NULL;
1289}
1290
1291static
1292struct bt_ctf_field *bt_ctf_field_enumeration_create(
1293 struct bt_ctf_field_type *type)
1294{
1295 struct bt_ctf_field_enumeration *enumeration = g_new0(
1296 struct bt_ctf_field_enumeration, 1);
1297
1298 return enumeration ? &enumeration->parent : NULL;
1299}
1300
1301static
1302struct bt_ctf_field *bt_ctf_field_floating_point_create(
1303 struct bt_ctf_field_type *type)
1304{
1305 struct bt_ctf_field_floating_point *floating_point;
1306 struct bt_ctf_field_type_floating_point *floating_point_type;
1307
1308 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
1309 if (!floating_point) {
1310 goto end;
1311 }
1312
1313 floating_point_type = container_of(type,
1314 struct bt_ctf_field_type_floating_point, parent);
1315 floating_point->definition.declaration = container_of(
1316 type->declaration, struct declaration_float, p);
1317
1318
1319 floating_point->definition.sign = &floating_point->sign;
1320 floating_point->sign.declaration = &floating_point_type->sign;
1321 floating_point->definition.sign->p.declaration =
1322 &floating_point_type->sign.p;
1323
1324 floating_point->definition.mantissa = &floating_point->mantissa;
1325 floating_point->mantissa.declaration = &floating_point_type->mantissa;
1326 floating_point->definition.mantissa->p.declaration =
1327 &floating_point_type->mantissa.p;
1328
1329 floating_point->definition.exp = &floating_point->exp;
1330 floating_point->exp.declaration = &floating_point_type->exp;
1331 floating_point->definition.exp->p.declaration =
1332 &floating_point_type->exp.p;
1333
1334end:
1335 return floating_point ? &floating_point->parent : NULL;
1336}
1337
1338static
1339struct bt_ctf_field *bt_ctf_field_structure_create(
1340 struct bt_ctf_field_type *type)
1341{
1342 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1343 struct bt_ctf_field_type_structure, parent);
1344 struct bt_ctf_field_structure *structure = g_new0(
1345 struct bt_ctf_field_structure, 1);
1346 struct bt_ctf_field *field = NULL;
1347
8c1aa858 1348 if (!structure) {
273b65be
JG
1349 goto end;
1350 }
1351
1352 structure->field_name_to_index = structure_type->field_name_to_index;
1353 structure->fields = g_ptr_array_new_with_free_func(
1354 (GDestroyNotify)bt_ctf_field_put);
1355 g_ptr_array_set_size(structure->fields,
1356 g_hash_table_size(structure->field_name_to_index));
1357 field = &structure->parent;
1358end:
1359 return field;
1360}
1361
1362static
1363struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1364{
1365 struct bt_ctf_field_variant *variant = g_new0(
1366 struct bt_ctf_field_variant, 1);
1367 return variant ? &variant->parent : NULL;
1368}
1369
1370static
1371struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1372{
1373 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1374 struct bt_ctf_field_type_array *array_type;
1375 unsigned int array_length;
1376
1377 if (!array || !type) {
1378 goto error;
1379 }
1380
1381 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1382 array_length = array_type->length;
fe0fe95c 1383 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1384 if (!array->elements) {
1385 goto error;
1386 }
1387
fe0fe95c
JG
1388 g_ptr_array_set_free_func(array->elements,
1389 (GDestroyNotify)bt_ctf_field_put);
273b65be
JG
1390 g_ptr_array_set_size(array->elements, array_length);
1391 return &array->parent;
1392error:
1393 g_free(array);
1394 return NULL;
1395}
1396
1397static
1398struct bt_ctf_field *bt_ctf_field_sequence_create(
1399 struct bt_ctf_field_type *type)
1400{
1401 struct bt_ctf_field_sequence *sequence = g_new0(
1402 struct bt_ctf_field_sequence, 1);
1403 return sequence ? &sequence->parent : NULL;
1404}
1405
1406static
1407struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1408{
1409 struct bt_ctf_field_string *string = g_new0(
1410 struct bt_ctf_field_string, 1);
1411 return string ? &string->parent : NULL;
1412}
1413
1414static
83509119 1415void bt_ctf_field_destroy(struct bt_object *obj)
273b65be
JG
1416{
1417 struct bt_ctf_field *field;
1418 struct bt_ctf_field_type *type;
9a19a512 1419 enum bt_ctf_type_id type_id;
273b65be 1420
83509119 1421 field = container_of(obj, struct bt_ctf_field, base);
273b65be
JG
1422 type = field->type;
1423 type_id = bt_ctf_field_type_get_type_id(type);
9a19a512
PP
1424 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
1425 type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1426 return;
1427 }
1428
1429 field_destroy_funcs[type_id](field);
83509119 1430 bt_put(type);
273b65be
JG
1431}
1432
1433static
1434void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1435{
1436 struct bt_ctf_field_integer *integer;
1437
1438 if (!field) {
1439 return;
1440 }
1441
1442 integer = container_of(field, struct bt_ctf_field_integer, parent);
1443 g_free(integer);
1444}
1445
1446static
1447void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1448{
1449 struct bt_ctf_field_enumeration *enumeration;
1450
1451 if (!field) {
1452 return;
1453 }
1454
1455 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1456 parent);
83509119 1457 bt_put(enumeration->payload);
273b65be
JG
1458 g_free(enumeration);
1459}
1460
1461static
1462void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
1463{
1464 struct bt_ctf_field_floating_point *floating_point;
1465
1466 if (!field) {
1467 return;
1468 }
1469
1470 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1471 parent);
1472 g_free(floating_point);
1473}
1474
1475static
1476void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
1477{
1478 struct bt_ctf_field_structure *structure;
1479
1480 if (!field) {
1481 return;
1482 }
1483
1484 structure = container_of(field, struct bt_ctf_field_structure, parent);
1485 g_ptr_array_free(structure->fields, TRUE);
1486 g_free(structure);
1487}
1488
1489static
1490void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
1491{
1492 struct bt_ctf_field_variant *variant;
1493
1494 if (!field) {
1495 return;
1496 }
1497
1498 variant = container_of(field, struct bt_ctf_field_variant, parent);
83509119
JG
1499 bt_put(variant->tag);
1500 bt_put(variant->payload);
273b65be
JG
1501 g_free(variant);
1502}
1503
1504static
1505void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
1506{
1507 struct bt_ctf_field_array *array;
1508
1509 if (!field) {
1510 return;
1511 }
1512
1513 array = container_of(field, struct bt_ctf_field_array, parent);
1514 g_ptr_array_free(array->elements, TRUE);
1515 g_free(array);
1516}
1517
1518static
1519void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
1520{
1521 struct bt_ctf_field_sequence *sequence;
1522
1523 if (!field) {
1524 return;
1525 }
1526
1527 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
4fef87ab
JG
1528 if (sequence->elements) {
1529 g_ptr_array_free(sequence->elements, TRUE);
1530 }
83509119 1531 bt_put(sequence->length);
273b65be
JG
1532 g_free(sequence);
1533}
1534
1535static
1536void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
1537{
1538 struct bt_ctf_field_string *string;
1539 if (!field) {
1540 return;
1541 }
1542
1543 string = container_of(field, struct bt_ctf_field_string, parent);
9b2b7163
JG
1544 if (string->payload) {
1545 g_string_free(string->payload, TRUE);
1546 }
273b65be
JG
1547 g_free(string);
1548}
1549
1550static
1551int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1552{
da2f6971 1553 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
1554}
1555
1556static
1557int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
1558{
1559 int ret;
1560 struct bt_ctf_field_enumeration *enumeration;
1561
1562 if (!field) {
1563 ret = -1;
1564 goto end;
1565 }
1566
1567 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1568 parent);
1569 if (!enumeration->payload) {
1570 ret = -1;
1571 goto end;
1572 }
1573
1574 ret = bt_ctf_field_validate(enumeration->payload);
1575end:
1576 return ret;
1577}
1578
1579static
1580int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
1581{
1582 size_t i;
1583 int ret = 0;
1584 struct bt_ctf_field_structure *structure;
1585
1586 if (!field) {
1587 ret = -1;
1588 goto end;
1589 }
1590
1591 structure = container_of(field, struct bt_ctf_field_structure, parent);
1592 for (i = 0; i < structure->fields->len; i++) {
1593 ret = bt_ctf_field_validate(structure->fields->pdata[i]);
1594 if (ret) {
6ce12048
JG
1595 const char *name;
1596 struct bt_ctf_field_type *field_type =
1597 bt_ctf_field_get_type(field);
1598
1599 (void) bt_ctf_field_type_structure_get_field(field_type,
1600 &name, NULL, i);
1601 fprintf(stderr, "Field %s failed validation\n",
1602 name ? name : "NULL");
e5ed1ccf 1603 bt_put(field_type);
273b65be
JG
1604 goto end;
1605 }
1606 }
1607end:
1608 return ret;
1609}
1610
1611static
1612int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1613{
1614 int ret = 0;
1615 struct bt_ctf_field_variant *variant;
1616
1617 if (!field) {
1618 ret = -1;
1619 goto end;
1620 }
1621
1622 variant = container_of(field, struct bt_ctf_field_variant, parent);
1623 ret = bt_ctf_field_validate(variant->payload);
1624end:
1625 return ret;
1626}
1627
1628static
1629int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1630{
1631 size_t i;
1632 int ret = 0;
1633 struct bt_ctf_field_array *array;
1634
1635 if (!field) {
1636 ret = -1;
1637 goto end;
1638 }
1639
1640 array = container_of(field, struct bt_ctf_field_array, parent);
1641 for (i = 0; i < array->elements->len; i++) {
1642 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1643 if (ret) {
bcfb49d4 1644 fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
273b65be
JG
1645 goto end;
1646 }
1647 }
1648end:
1649 return ret;
1650}
1651
1652static
1653int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1654{
1655 size_t i;
1656 int ret = 0;
1657 struct bt_ctf_field_sequence *sequence;
1658
1659 if (!field) {
1660 ret = -1;
1661 goto end;
1662 }
1663
1664 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1665 for (i = 0; i < sequence->elements->len; i++) {
1666 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1667 if (ret) {
bcfb49d4 1668 fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
273b65be
JG
1669 goto end;
1670 }
1671 }
1672end:
1673 return ret;
1674}
1675
12c8a1a3
JG
1676static
1677int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1678{
1679 int ret = 0;
1680
1681 if (!field) {
1682 ret = -1;
1683 goto end;
1684 }
1685
1686 field->payload_set = 0;
1687end:
1688 return ret;
1689}
1690
1691static
1692int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1693{
1694 int ret = 0;
1695 struct bt_ctf_field_enumeration *enumeration;
1696
1697 if (!field) {
1698 ret = -1;
1699 goto end;
1700 }
1701
1702 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1703 parent);
1704 if (!enumeration->payload) {
1705 goto end;
1706 }
1707
1708 ret = bt_ctf_field_reset(enumeration->payload);
1709end:
1710 return ret;
1711}
1712
1713static
1714int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1715{
1716 size_t i;
1717 int ret = 0;
1718 struct bt_ctf_field_structure *structure;
1719
1720 if (!field) {
1721 ret = -1;
1722 goto end;
1723 }
1724
1725 structure = container_of(field, struct bt_ctf_field_structure, parent);
1726 for (i = 0; i < structure->fields->len; i++) {
1727 struct bt_ctf_field *member = structure->fields->pdata[i];
1728
1729 if (!member) {
1730 /*
1731 * Structure members are lazily initialized; skip if
1732 * this member has not been allocated yet.
1733 */
1734 continue;
1735 }
1736
1737 ret = bt_ctf_field_reset(member);
1738 if (ret) {
1739 goto end;
1740 }
1741 }
1742end:
1743 return ret;
1744}
1745
1746static
1747int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1748{
1749 int ret = 0;
1750 struct bt_ctf_field_variant *variant;
1751
1752 if (!field) {
1753 ret = -1;
1754 goto end;
1755 }
1756
1757 variant = container_of(field, struct bt_ctf_field_variant, parent);
1758 if (variant->payload) {
1759 ret = bt_ctf_field_reset(variant->payload);
1760 }
1761end:
1762 return ret;
1763}
1764
1765static
1766int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1767{
1768 size_t i;
1769 int ret = 0;
1770 struct bt_ctf_field_array *array;
1771
1772 if (!field) {
1773 ret = -1;
1774 goto end;
1775 }
1776
1777 array = container_of(field, struct bt_ctf_field_array, parent);
1778 for (i = 0; i < array->elements->len; i++) {
1779 struct bt_ctf_field *member = array->elements->pdata[i];
1780
1781 if (!member) {
1782 /*
1783 * Array elements are lazily initialized; skip if
1784 * this member has not been allocated yet.
1785 */
1786 continue;
1787 }
1788
1789 ret = bt_ctf_field_reset(member);
1790 if (ret) {
1791 goto end;
1792 }
1793 }
1794end:
1795 return ret;
1796}
1797
1798static
1799int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1800{
1801 size_t i;
1802 int ret = 0;
1803 struct bt_ctf_field_sequence *sequence;
1804
1805 if (!field) {
1806 ret = -1;
1807 goto end;
1808 }
1809
1810 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1811 for (i = 0; i < sequence->elements->len; i++) {
1812 struct bt_ctf_field *member = sequence->elements->pdata[i];
1813
1814 if (!member) {
1815 /*
1816 * Sequence elements are lazily initialized; skip if
1817 * this member has not been allocated yet.
1818 */
1819 continue;
1820 }
1821
1822 ret = bt_ctf_field_reset(member);
1823 if (ret) {
1824 goto end;
1825 }
1826 }
1827end:
1828 return ret;
1829}
1830
1831static
1832int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1833{
1834 int ret = 0;
1835 struct bt_ctf_field_string *string;
1836
1837 if (!field) {
1838 ret = -1;
1839 goto end;
1840 }
1841
1842 ret = bt_ctf_field_generic_reset(field);
1843 if (ret) {
1844 goto end;
1845 }
1846
1847 string = container_of(field, struct bt_ctf_field_string, parent);
1848 if (string->payload) {
1849 g_string_truncate(string->payload, 0);
1850 }
1851end:
1852 return ret;
1853}
1854
273b65be
JG
1855static
1856int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1857 struct ctf_stream_pos *pos)
1858{
1859 int ret = 0;
1860 struct bt_ctf_field_integer *integer = container_of(field,
1861 struct bt_ctf_field_integer, parent);
1862
1863retry:
1864 ret = ctf_integer_write(&pos->parent, &integer->definition.p);
1865 if (ret == -EFAULT) {
1866 /*
1867 * The field is too large to fit in the current packet's
1868 * remaining space. Bump the packet size and retry.
1869 */
1870 ret = increase_packet_size(pos);
1871 if (ret) {
1872 goto end;
1873 }
1874 goto retry;
1875 }
1876end:
1877 return ret;
1878}
1879
1880static
1881int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1882 struct ctf_stream_pos *pos)
1883{
1884 struct bt_ctf_field_enumeration *enumeration = container_of(
1885 field, struct bt_ctf_field_enumeration, parent);
1886
1887 return bt_ctf_field_serialize(enumeration->payload, pos);
1888}
1889
1890static
1891int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1892 struct ctf_stream_pos *pos)
1893{
1894 int ret = 0;
1895 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1896 struct bt_ctf_field_floating_point, parent);
1897
1898retry:
1899 ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
1900 if (ret == -EFAULT) {
1901 /*
1902 * The field is too large to fit in the current packet's
1903 * remaining space. Bump the packet size and retry.
1904 */
1905 ret = increase_packet_size(pos);
1906 if (ret) {
1907 goto end;
1908 }
1909 goto retry;
1910 }
1911end:
1912 return ret;
1913}
1914
1915static
1916int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1917 struct ctf_stream_pos *pos)
1918{
1919 size_t i;
1920 int ret = 0;
1921 struct bt_ctf_field_structure *structure = container_of(
1922 field, struct bt_ctf_field_structure, parent);
1923
1924 while (!ctf_pos_access_ok(pos,
1925 offset_align(pos->offset,
1926 field->type->declaration->alignment))) {
9f56e450
JG
1927 ret = increase_packet_size(pos);
1928 if (ret) {
1929 goto end;
1930 }
273b65be
JG
1931 }
1932
70fd5a51
MD
1933 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1934 ret = -1;
1935 goto end;
1936 }
273b65be
JG
1937
1938 for (i = 0; i < structure->fields->len; i++) {
1939 struct bt_ctf_field *field = g_ptr_array_index(
1940 structure->fields, i);
1941
1942 ret = bt_ctf_field_serialize(field, pos);
1943 if (ret) {
bcfb49d4
JG
1944 const char *name;
1945 struct bt_ctf_field_type *field_type =
1946 bt_ctf_field_get_type(field);
1947
1948 (void) bt_ctf_field_type_structure_get_field(field_type,
1949 &name, NULL, i);
1950 fprintf(stderr, "Field %s failed to serialize\n",
1951 name ? name : "NULL");
1952 bt_put(field_type);
273b65be
JG
1953 break;
1954 }
1955 }
9f56e450 1956end:
273b65be
JG
1957 return ret;
1958}
1959
1960static
1961int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
1962 struct ctf_stream_pos *pos)
1963{
1964 struct bt_ctf_field_variant *variant = container_of(
1965 field, struct bt_ctf_field_variant, parent);
1966
1967 return bt_ctf_field_serialize(variant->payload, pos);
1968}
1969
1970static
1971int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
1972 struct ctf_stream_pos *pos)
1973{
1974 size_t i;
1975 int ret = 0;
1976 struct bt_ctf_field_array *array = container_of(
1977 field, struct bt_ctf_field_array, parent);
1978
1979 for (i = 0; i < array->elements->len; i++) {
1980 ret = bt_ctf_field_serialize(
1981 g_ptr_array_index(array->elements, i), pos);
1982 if (ret) {
bcfb49d4 1983 fprintf(stderr, "Failed to serialize array element #%zu\n", i);
273b65be
JG
1984 goto end;
1985 }
1986 }
1987end:
1988 return ret;
1989}
1990
1991static
1992int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
1993 struct ctf_stream_pos *pos)
1994{
1995 size_t i;
1996 int ret = 0;
1997 struct bt_ctf_field_sequence *sequence = container_of(
1998 field, struct bt_ctf_field_sequence, parent);
1999
2000 for (i = 0; i < sequence->elements->len; i++) {
2001 ret = bt_ctf_field_serialize(
2002 g_ptr_array_index(sequence->elements, i), pos);
2003 if (ret) {
bcfb49d4 2004 fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
273b65be
JG
2005 goto end;
2006 }
2007 }
2008end:
2009 return ret;
2010}
2011
2012static
2013int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
2014 struct ctf_stream_pos *pos)
2015{
2016 size_t i;
2017 int ret = 0;
2018 struct bt_ctf_field_string *string = container_of(field,
2019 struct bt_ctf_field_string, parent);
2020 struct bt_ctf_field_type *character_type =
2021 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
2022 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
2023
2024 for (i = 0; i < string->payload->len + 1; i++) {
2025 ret = bt_ctf_field_unsigned_integer_set_value(character,
2026 (uint64_t) string->payload->str[i]);
2027 if (ret) {
2028 goto end;
2029 }
2030
2031 ret = bt_ctf_field_integer_serialize(character, pos);
2032 if (ret) {
2033 goto end;
2034 }
2035 }
2036end:
83509119
JG
2037 bt_put(character);
2038 bt_put(character_type);
273b65be
JG
2039 return ret;
2040}
2041
87d43dc1
JG
2042static
2043int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2044 struct bt_ctf_field *dst)
2045{
2046 struct bt_ctf_field_integer *integer_src, *integer_dst;
2047
2048 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
8bfa3f9c 2049 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
87d43dc1
JG
2050
2051 memcpy(&integer_dst->definition, &integer_src->definition,
2052 sizeof(struct definition_integer));
2053 return 0;
2054}
2055
2056static
2057int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2058 struct bt_ctf_field *dst)
2059{
2060 int ret = 0;
2061 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2062
2063 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2064 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2065
2066 if (enum_src->payload) {
2067 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2068 if (!enum_dst->payload) {
2069 ret = -1;
2070 goto end;
2071 }
2072 }
2073end:
2074 return ret;
2075}
2076
2077static
2078int bt_ctf_field_floating_point_copy(
2079 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2080{
2081 struct bt_ctf_field_floating_point *float_src, *float_dst;
2082
2083 float_src = container_of(src, struct bt_ctf_field_floating_point,
2084 parent);
2085 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2086 parent);
2087
2088 memcpy(&float_dst->definition, &float_src->definition,
2089 sizeof(struct definition_float));
2090 memcpy(&float_dst->sign, &float_src->sign,
2091 sizeof(struct definition_integer));
2092 memcpy(&float_dst->mantissa, &float_src->mantissa,
2093 sizeof(struct definition_integer));
2094 memcpy(&float_dst->exp, &float_src->exp,
2095 sizeof(struct definition_integer));
2096 return 0;
2097}
2098
2099static
2100int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2101 struct bt_ctf_field *dst)
2102{
8bfa3f9c 2103 int ret = 0, i;
87d43dc1
JG
2104 struct bt_ctf_field_structure *struct_src, *struct_dst;
2105
2106 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2107 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2108
8bfa3f9c 2109 /* This field_name_to_index HT is owned by the structure field type */
87d43dc1 2110 struct_dst->field_name_to_index = struct_src->field_name_to_index;
8bfa3f9c 2111 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
2112
2113 for (i = 0; i < struct_src->fields->len; i++) {
50fd95bf
PP
2114 struct bt_ctf_field *field =
2115 g_ptr_array_index(struct_src->fields, i);
2116 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2117
50fd95bf
PP
2118 if (field) {
2119 field_copy = bt_ctf_field_copy(field);
2120
2121 if (!field_copy) {
2122 ret = -1;
2123 goto end;
2124 }
87d43dc1 2125 }
50fd95bf 2126
8bfa3f9c 2127 g_ptr_array_index(struct_dst->fields, i) = field_copy;
87d43dc1
JG
2128 }
2129end:
2130 return ret;
2131}
2132
2133static
2134int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2135 struct bt_ctf_field *dst)
2136{
2137 int ret = 0;
2138 struct bt_ctf_field_variant *variant_src, *variant_dst;
2139
2140 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2141 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2142
2143 if (variant_src->tag) {
2144 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2145 if (!variant_dst->tag) {
2146 ret = -1;
2147 goto end;
2148 }
2149 }
2150 if (variant_src->payload) {
2151 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2152 if (!variant_dst->payload) {
2153 ret = -1;
2154 goto end;
2155 }
2156 }
2157end:
2158 return ret;
2159}
2160
2161static
2162int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2163 struct bt_ctf_field *dst)
2164{
2165 int ret = 0, i;
2166 struct bt_ctf_field_array *array_src, *array_dst;
2167
2168 array_src = container_of(src, struct bt_ctf_field_array, parent);
2169 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2170
8bfa3f9c 2171 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1 2172 for (i = 0; i < array_src->elements->len; i++) {
50fd95bf
PP
2173 struct bt_ctf_field *field =
2174 g_ptr_array_index(array_src->elements, i);
2175 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2176
50fd95bf
PP
2177 if (field) {
2178 field_copy = bt_ctf_field_copy(field);
2179
2180 if (!field_copy) {
2181 ret = -1;
2182 goto end;
2183 }
87d43dc1 2184 }
50fd95bf 2185
8bfa3f9c 2186 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1
JG
2187 }
2188end:
2189 return ret;
2190}
2191
2192static
2193int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2194 struct bt_ctf_field *dst)
2195{
2196 int ret = 0, i;
2197 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
59ab494d
PP
2198 struct bt_ctf_field *src_length;
2199 struct bt_ctf_field *dst_length;
87d43dc1
JG
2200
2201 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2202 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2203
59ab494d
PP
2204 src_length = bt_ctf_field_sequence_get_length(src);
2205
2206 if (!src_length) {
2207 /* no length set yet: keep destination sequence empty */
2208 goto end;
2209 }
2210
2211 /* copy source length */
2212 dst_length = bt_ctf_field_copy(src_length);
83509119 2213 bt_put(src_length);
59ab494d
PP
2214
2215 if (!dst_length) {
2216 ret = -1;
2217 goto end;
2218 }
2219
2220 /* this will initialize the destination sequence's internal array */
2221 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
83509119 2222 bt_put(dst_length);
59ab494d
PP
2223
2224 if (ret) {
2225 goto end;
2226 }
2227
2228 assert(sequence_dst->elements->len == sequence_src->elements->len);
2229
87d43dc1 2230 for (i = 0; i < sequence_src->elements->len; i++) {
50fd95bf
PP
2231 struct bt_ctf_field *field =
2232 g_ptr_array_index(sequence_src->elements, i);
2233 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2234
50fd95bf
PP
2235 if (field) {
2236 field_copy = bt_ctf_field_copy(field);
2237
2238 if (!field_copy) {
2239 ret = -1;
2240 goto end;
2241 }
87d43dc1 2242 }
59ab494d 2243
8bfa3f9c 2244 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1
JG
2245 }
2246end:
2247 return ret;
2248}
2249
2250static
2251int bt_ctf_field_string_copy(struct bt_ctf_field *src,
2252 struct bt_ctf_field *dst)
2253{
2254 int ret = 0;
2255 struct bt_ctf_field_string *string_src, *string_dst;
2256
2257 string_src = container_of(src, struct bt_ctf_field_string, parent);
2258 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
2259
2260 if (string_src->payload) {
2261 string_dst->payload = g_string_new(string_src->payload->str);
2262 if (!string_dst->payload) {
2263 ret = -1;
2264 goto end;
2265 }
2266 }
2267end:
2268 return ret;
2269}
2270
273b65be
JG
2271static
2272int increase_packet_size(struct ctf_stream_pos *pos)
2273{
2274 int ret;
2275
2276 assert(pos);
2277 ret = munmap_align(pos->base_mma);
2278 if (ret) {
2279 goto end;
2280 }
2281
2282 pos->packet_size += PACKET_LEN_INCREMENT;
d9548894
MD
2283 do {
2284 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
2285 pos->packet_size / CHAR_BIT);
2286 } while (ret == EINTR);
273b65be 2287 if (ret) {
d9548894
MD
2288 errno = EINTR;
2289 ret = -1;
273b65be
JG
2290 goto end;
2291 }
2292
2293 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
2294 pos->flags, pos->fd, pos->mmap_offset);
2295 if (pos->base_mma == MAP_FAILED) {
2296 ret = -1;
2297 }
2298end:
2299 return ret;
2300}
918be005
PP
2301
2302static
2303void generic_field_freeze(struct bt_ctf_field *field)
2304{
2305 field->frozen = 1;
2306}
2307
2308static
2309void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
2310{
2311 struct bt_ctf_field_enumeration *enum_field =
2312 container_of(field, struct bt_ctf_field_enumeration, parent);
2313
2314 bt_ctf_field_freeze(enum_field->payload);
2315 generic_field_freeze(field);
2316}
2317
2318static
2319void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
2320{
2321 int i;
2322 struct bt_ctf_field_structure *structure_field =
2323 container_of(field, struct bt_ctf_field_structure, parent);
2324
2325 for (i = 0; i < structure_field->fields->len; i++) {
2326 struct bt_ctf_field *field =
2327 g_ptr_array_index(structure_field->fields, i);
2328
2329 bt_ctf_field_freeze(field);
2330 }
2331
2332 generic_field_freeze(field);
2333}
2334
2335static
2336void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
2337{
2338 struct bt_ctf_field_variant *variant_field =
2339 container_of(field, struct bt_ctf_field_variant, parent);
2340
2341 bt_ctf_field_freeze(variant_field->tag);
2342 bt_ctf_field_freeze(variant_field->payload);
2343 generic_field_freeze(field);
2344}
2345
2346static
2347void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
2348{
2349 int i;
2350 struct bt_ctf_field_array *array_field =
2351 container_of(field, struct bt_ctf_field_array, parent);
2352
2353 for (i = 0; i < array_field->elements->len; i++) {
2354 struct bt_ctf_field *field =
2355 g_ptr_array_index(array_field->elements, i);
2356
2357 bt_ctf_field_freeze(field);
2358 }
2359
2360 generic_field_freeze(field);
2361}
2362
2363static
2364void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
2365{
2366 int i;
2367 struct bt_ctf_field_sequence *sequence_field =
2368 container_of(field, struct bt_ctf_field_sequence, parent);
2369
2370 bt_ctf_field_freeze(sequence_field->length);
2371
2372 for (i = 0; i < sequence_field->elements->len; i++) {
2373 struct bt_ctf_field *field =
2374 g_ptr_array_index(sequence_field->elements, i);
2375
2376 bt_ctf_field_freeze(field);
2377 }
2378
2379 generic_field_freeze(field);
2380}
2381
2382BT_HIDDEN
2383void bt_ctf_field_freeze(struct bt_ctf_field *field)
2384{
35f77de4
JG
2385 enum bt_ctf_type_id type_id;
2386
918be005
PP
2387 if (!field) {
2388 goto end;
2389 }
2390
35f77de4
JG
2391 type_id = bt_ctf_field_get_type_id(field);
2392 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
2393 type_id >= BT_CTF_NR_TYPE_IDS) {
2394 goto end;
2395 }
918be005 2396
35f77de4 2397 field_freeze_funcs[type_id](field);
918be005
PP
2398end:
2399 return;
2400}
This page took 0.136224 seconds and 4 git commands to generate.