Hide new bt_ctf_field_* symbols
[babeltrace.git] / formats / ctf / ir / fields.c
CommitLineData
1c822dfb
JG
1/*
2 * fields.c
3 *
4 * Babeltrace CTF IR - Event Fields
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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
29#include <babeltrace/ctf-ir/fields-internal.h>
30#include <babeltrace/ctf-ir/field-types-internal.h>
31#include <babeltrace/object-internal.h>
32#include <babeltrace/ref.h>
33#include <babeltrace/compiler.h>
34#include <babeltrace/compat/fcntl.h>
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
62void bt_ctf_field_destroy(struct bt_object *);
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
81int bt_ctf_field_generic_validate(struct bt_ctf_field *);
82static
83int bt_ctf_field_structure_validate(struct bt_ctf_field *);
84static
85int bt_ctf_field_variant_validate(struct bt_ctf_field *);
86static
87int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
88static
89int bt_ctf_field_array_validate(struct bt_ctf_field *);
90static
91int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
92
93static
94int bt_ctf_field_generic_reset(struct bt_ctf_field *);
95static
96int bt_ctf_field_structure_reset(struct bt_ctf_field *);
97static
98int bt_ctf_field_variant_reset(struct bt_ctf_field *);
99static
100int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
101static
102int bt_ctf_field_array_reset(struct bt_ctf_field *);
103static
104int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
105static
106int bt_ctf_field_string_reset(struct bt_ctf_field *);
107
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
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
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
164static
165int increase_packet_size(struct ctf_stream_pos *pos);
166
167static
168struct bt_ctf_field *(* const field_create_funcs[])(
169 struct bt_ctf_field_type *) = {
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] =
173 bt_ctf_field_floating_point_create,
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,
179};
180
181static
182void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
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] =
186 bt_ctf_field_floating_point_destroy,
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,
192};
193
194static
195int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
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,
204};
205
206static
207int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
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,
216};
217
218static
219int (* const field_serialize_funcs[])(struct bt_ctf_field *,
220 struct ctf_stream_pos *) = {
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] =
224 bt_ctf_field_floating_point_serialize,
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,
230};
231
232static
233int (* const field_copy_funcs[])(struct bt_ctf_field *,
234 struct bt_ctf_field *) = {
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,
243};
244
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
257struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
258{
259 struct bt_ctf_field *field = NULL;
260 enum bt_ctf_type_id type_id;
261 int ret;
262
263 if (!type) {
264 goto error;
265 }
266
267 type_id = bt_ctf_field_type_get_type_id(type);
268 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
269 type_id >= BT_CTF_NR_TYPE_IDS) {
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 */
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);
288 bt_get(type);
289 bt_object_init(field, bt_ctf_field_destroy);
290 field->type = type;
291error:
292 return field;
293}
294
295void bt_ctf_field_get(struct bt_ctf_field *field)
296{
297 bt_get(field);
298}
299
300void bt_ctf_field_put(struct bt_ctf_field *field)
301{
302 bt_put(field);
303}
304
ad72416e 305BT_HIDDEN
1c822dfb
JG
306struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
307{
308 struct bt_ctf_field_type *ret = NULL;
309
310 if (!field) {
311 goto end;
312 }
313
314 ret = field->type;
315 bt_get(ret);
316end:
317 return ret;
318}
319
ad72416e 320BT_HIDDEN
1c822dfb
JG
321enum bt_ctf_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
322{
323 enum bt_ctf_type_id ret = BT_CTF_TYPE_ID_UNKNOWN;
324
325 if (!field) {
326 goto end;
327 }
328
329 ret = bt_ctf_field_type_get_type_id(field->type);
330end:
331 return ret;
332}
333
ad72416e 334BT_HIDDEN
1c822dfb
JG
335int bt_ctf_field_is_integer(struct bt_ctf_field *field)
336{
337 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_INTEGER;
338}
339
ad72416e 340BT_HIDDEN
1c822dfb
JG
341int bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
342{
343 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_FLOAT;
344}
345
ad72416e 346BT_HIDDEN
1c822dfb
JG
347int bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
348{
349 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ENUM;
350}
351
ad72416e 352BT_HIDDEN
1c822dfb
JG
353int bt_ctf_field_is_string(struct bt_ctf_field *field)
354{
355 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRING;
356}
357
ad72416e 358BT_HIDDEN
1c822dfb
JG
359int bt_ctf_field_is_structure(struct bt_ctf_field *field)
360{
361 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRUCT;
362}
363
ad72416e 364BT_HIDDEN
1c822dfb
JG
365int bt_ctf_field_is_array(struct bt_ctf_field *field)
366{
367 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ARRAY;
368}
369
ad72416e 370BT_HIDDEN
1c822dfb
JG
371int bt_ctf_field_is_sequence(struct bt_ctf_field *field)
372{
373 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_SEQUENCE;
374}
375
ad72416e 376BT_HIDDEN
1c822dfb
JG
377int bt_ctf_field_is_variant(struct bt_ctf_field *field)
378{
379 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_VARIANT;
380}
381
ad72416e 382BT_HIDDEN
1c822dfb
JG
383struct bt_ctf_field *bt_ctf_field_sequence_get_length(
384 struct bt_ctf_field *field)
385{
386 struct bt_ctf_field *ret = NULL;
387 struct bt_ctf_field_sequence *sequence;
388
389 if (!field) {
390 goto end;
391 }
392
393 if (bt_ctf_field_type_get_type_id(field->type) !=
394 BT_CTF_TYPE_ID_SEQUENCE) {
395 goto end;
396 }
397
398 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
399 ret = sequence->length;
400 bt_get(ret);
401end:
402 return ret;
403}
404
405int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
406 struct bt_ctf_field *length_field)
407{
408 int ret = 0;
409 struct bt_ctf_field_type_integer *length_type;
410 struct bt_ctf_field_integer *length;
411 struct bt_ctf_field_sequence *sequence;
412 uint64_t sequence_length;
413
414 if (!field || !length_field || field->frozen) {
415 ret = -1;
416 goto end;
417 }
418 if (bt_ctf_field_type_get_type_id(length_field->type) !=
419 BT_CTF_TYPE_ID_INTEGER) {
420 ret = -1;
421 goto end;
422 }
423
424 length_type = container_of(length_field->type,
425 struct bt_ctf_field_type_integer, parent);
426 /* The length field must be unsigned */
427 if (length_type->declaration.signedness) {
428 ret = -1;
429 goto end;
430 }
431
432 length = container_of(length_field, struct bt_ctf_field_integer,
433 parent);
434 sequence_length = length->definition.value._unsigned;
435 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
436 if (sequence->elements) {
437 g_ptr_array_free(sequence->elements, TRUE);
438 bt_put(sequence->length);
439 }
440
441 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
442 if (!sequence->elements) {
443 ret = -1;
444 goto end;
445 }
446
447 g_ptr_array_set_free_func(sequence->elements,
448 (GDestroyNotify) bt_put);
449 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
450 bt_get(length_field);
451 sequence->length = length_field;
452end:
453 return ret;
454}
455
456struct bt_ctf_field *bt_ctf_field_structure_get_field(
457 struct bt_ctf_field *field, const char *name)
458{
459 struct bt_ctf_field *new_field = NULL;
460 GQuark field_quark;
461 struct bt_ctf_field_structure *structure;
462 struct bt_ctf_field_type *field_type = NULL;
463 size_t index;
464
465 if (!field || !name ||
466 bt_ctf_field_type_get_type_id(field->type) !=
467 BT_CTF_TYPE_ID_STRUCT) {
468 goto error;
469 }
470
471 field_quark = g_quark_from_string(name);
472 structure = container_of(field, struct bt_ctf_field_structure, parent);
473 field_type =
474 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
475 name);
476 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
477 GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
478 goto error;
479 }
480
481 if (structure->fields->pdata[index]) {
482 new_field = structure->fields->pdata[index];
483 goto end;
484 }
485
486 /* We don't want to modify this field if it's frozen */
487 if (field->frozen) {
488 goto end;
489 }
490
491 new_field = bt_ctf_field_create(field_type);
492 if (!new_field) {
493 goto error;
494 }
495
496 structure->fields->pdata[index] = new_field;
497end:
498 bt_get(new_field);
499error:
500 if (field_type) {
501 bt_put(field_type);
502 }
503 return new_field;
504}
505
ad72416e 506BT_HIDDEN
1c822dfb
JG
507struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
508 struct bt_ctf_field *field, int index)
509{
510 int ret;
511 const char *field_name;
512 struct bt_ctf_field_structure *structure;
513 struct bt_ctf_field_type *structure_type;
514 struct bt_ctf_field_type *field_type = NULL;
515 struct bt_ctf_field *ret_field = NULL;
516
517 if (!field ||
518 bt_ctf_field_type_get_type_id(field->type) !=
519 BT_CTF_TYPE_ID_STRUCT) {
520 goto end;
521 }
522
523 structure = container_of(field, struct bt_ctf_field_structure, parent);
524 if (index >= structure->fields->len) {
525 goto error;
526 }
527
528 ret_field = structure->fields->pdata[index];
529 if (ret_field) {
530 goto end;
531 }
532
533 /* We don't want to modify this field if it's frozen */
534 if (field->frozen) {
535 goto end;
536 }
537
538 /* Field has not been instanciated yet, create it */
539 structure_type = bt_ctf_field_get_type(field);
540 if (!structure_type) {
541 goto error;
542 }
543
544 ret = bt_ctf_field_type_structure_get_field(structure_type,
545 &field_name, &field_type, index);
546 bt_put(structure_type);
547 if (ret) {
548 goto error;
549 }
550
551 ret_field = bt_ctf_field_create(field_type);
552 if (!ret_field) {
553 goto error;
554 }
555
556 structure->fields->pdata[index] = ret_field;
557end:
558 bt_get(ret_field);
559error:
560 bt_put(field_type);
561 return ret_field;
562}
563
564BT_HIDDEN
565int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
566 const char *name, struct bt_ctf_field *value)
567{
568 int ret = 0;
569 GQuark field_quark;
570 struct bt_ctf_field_structure *structure;
571 struct bt_ctf_field_type *expected_field_type = NULL;
572 size_t index;
573
574 if (!field || !name || !value || field->frozen ||
575 bt_ctf_field_type_get_type_id(field->type) !=
576 BT_CTF_TYPE_ID_STRUCT) {
577 ret = -1;
578 goto end;
579 }
580
581 field_quark = g_quark_from_string(name);
582 structure = container_of(field, struct bt_ctf_field_structure, parent);
583 expected_field_type =
584 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
585 name);
586
587 if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
588 ret = -1;
589 goto end;
590 }
591
592 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
593 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
594 goto end;
595 }
596
597 if (structure->fields->pdata[index]) {
598 bt_put(structure->fields->pdata[index]);
599 }
600
601 structure->fields->pdata[index] = value;
602 bt_get(value);
603end:
604 if (expected_field_type) {
605 bt_put(expected_field_type);
606 }
607 return ret;
608}
609
610struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
611 uint64_t index)
612{
613 struct bt_ctf_field *new_field = NULL;
614 struct bt_ctf_field_type *field_type = NULL;
615 struct bt_ctf_field_array *array;
616
617 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
618 BT_CTF_TYPE_ID_ARRAY) {
619 goto end;
620 }
621
622 array = container_of(field, struct bt_ctf_field_array, parent);
623 if (index >= array->elements->len) {
624 goto end;
625 }
626
627 field_type = bt_ctf_field_type_array_get_element_type(field->type);
628 if (array->elements->pdata[(size_t)index]) {
629 new_field = array->elements->pdata[(size_t)index];
630 goto end;
631 }
632
633 /* We don't want to modify this field if it's frozen */
634 if (field->frozen) {
635 goto end;
636 }
637
638 new_field = bt_ctf_field_create(field_type);
639 array->elements->pdata[(size_t)index] = new_field;
640end:
641 if (field_type) {
642 bt_put(field_type);
643 }
644 if (new_field) {
645 bt_get(new_field);
646 }
647 return new_field;
648}
649
650struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
651 uint64_t index)
652{
653 struct bt_ctf_field *new_field = NULL;
654 struct bt_ctf_field_type *field_type = NULL;
655 struct bt_ctf_field_sequence *sequence;
656
657 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
658 BT_CTF_TYPE_ID_SEQUENCE) {
659 goto end;
660 }
661
662 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
663 if (!sequence->elements || sequence->elements->len <= index) {
664 goto end;
665 }
666
667 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
668 if (sequence->elements->pdata[(size_t) index]) {
669 new_field = sequence->elements->pdata[(size_t) index];
670 goto end;
671 }
672
673 /* We don't want to modify this field if it's frozen */
674 if (field->frozen) {
675 goto end;
676 }
677
678 new_field = bt_ctf_field_create(field_type);
679 sequence->elements->pdata[(size_t) index] = new_field;
680end:
681 if (field_type) {
682 bt_put(field_type);
683 }
684 if (new_field) {
685 bt_get(new_field);
686 }
687 return new_field;
688}
689
690struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
691 struct bt_ctf_field *tag_field)
692{
693 struct bt_ctf_field *new_field = NULL;
694 struct bt_ctf_field_variant *variant;
695 struct bt_ctf_field_type_variant *variant_type;
696 struct bt_ctf_field_type *field_type;
697 struct bt_ctf_field *tag_enum = NULL;
698 struct bt_ctf_field_integer *tag_enum_integer;
699 int64_t tag_enum_value;
700
701 if (!field || !tag_field ||
702 bt_ctf_field_type_get_type_id(field->type) !=
703 BT_CTF_TYPE_ID_VARIANT ||
704 bt_ctf_field_type_get_type_id(tag_field->type) !=
705 BT_CTF_TYPE_ID_ENUM) {
706 goto end;
707 }
708
709 variant = container_of(field, struct bt_ctf_field_variant, parent);
710 variant_type = container_of(field->type,
711 struct bt_ctf_field_type_variant, parent);
712 tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
713 if (!tag_enum) {
714 goto end;
715 }
716
717 tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
718 parent);
719
720 if (bt_ctf_field_validate(tag_field) < 0) {
721 goto end;
722 }
723
724 tag_enum_value = tag_enum_integer->definition.value._signed;
725
726 /*
727 * If the variant currently has a tag and a payload, and if the
728 * requested tag value is the same as the current one, return
729 * the current payload instead of creating a fresh one.
730 */
731 if (variant->tag && variant->payload) {
732 struct bt_ctf_field *cur_tag_container = NULL;
733 struct bt_ctf_field_integer *cur_tag_enum_integer;
734 int64_t cur_tag_value;
735
736 cur_tag_container =
737 bt_ctf_field_enumeration_get_container(variant->tag);
738 assert(cur_tag_container);
739 cur_tag_enum_integer = container_of(cur_tag_container,
740 struct bt_ctf_field_integer, parent);
741 bt_put(cur_tag_container);
742 cur_tag_value = cur_tag_enum_integer->definition.value._signed;
743
744 if (cur_tag_value == tag_enum_value) {
745 new_field = variant->payload;
746 bt_get(new_field);
747 goto end;
748 }
749 }
750
751 /* We don't want to modify this field if it's frozen */
752 if (field->frozen) {
753 goto end;
754 }
755
756 field_type = bt_ctf_field_type_variant_get_field_type_signed(
757 variant_type, tag_enum_value);
758 if (!field_type) {
759 goto end;
760 }
761
762 new_field = bt_ctf_field_create(field_type);
763 if (!new_field) {
764 goto end;
765 }
766
767 bt_put(variant->tag);
768 bt_put(variant->payload);
769 bt_get(new_field);
770 bt_get(tag_field);
771 variant->tag = tag_field;
772 variant->payload = new_field;
773end:
774 bt_put(tag_enum);
775 return new_field;
776}
777
ad72416e 778BT_HIDDEN
1c822dfb
JG
779struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
780 struct bt_ctf_field *variant_field)
781{
782 struct bt_ctf_field *current_field = NULL;
783 struct bt_ctf_field_variant *variant;
784
785 if (!variant_field ||
786 bt_ctf_field_type_get_type_id(variant_field->type) !=
787 BT_CTF_TYPE_ID_VARIANT) {
788 goto end;
789 }
790
791 variant = container_of(variant_field, struct bt_ctf_field_variant,
792 parent);
793
794 if (variant->payload) {
795 current_field = variant->payload;
796 bt_get(current_field);
797 goto end;
798 }
799
800end:
801 return current_field;
802}
803
804struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
805 struct bt_ctf_field *field)
806{
807 struct bt_ctf_field *container = NULL;
808 struct bt_ctf_field_enumeration *enumeration;
809
810 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
811 BT_CTF_TYPE_ID_ENUM) {
812 goto end;
813 }
814
815 enumeration = container_of(field, struct bt_ctf_field_enumeration,
816 parent);
817 if (!enumeration->payload) {
818 /* We don't want to modify this field if it's frozen */
819 if (field->frozen) {
820 goto end;
821 }
822
823 struct bt_ctf_field_type_enumeration *enumeration_type =
824 container_of(field->type,
825 struct bt_ctf_field_type_enumeration, parent);
826 enumeration->payload =
827 bt_ctf_field_create(enumeration_type->container);
828 }
829
830 container = enumeration->payload;
831 bt_get(container);
832end:
833 return container;
834}
835
ad72416e 836BT_HIDDEN
1c822dfb
JG
837const char *bt_ctf_field_enumeration_get_mapping_name(
838 struct bt_ctf_field *field)
839{
840 int ret;
841 const char *name = NULL;
842 struct bt_ctf_field *container = NULL;
843 struct bt_ctf_field_type *container_type = NULL;
844 struct bt_ctf_field_type_integer *integer_type = NULL;
845 struct bt_ctf_field_type_enumeration *enumeration_type = NULL;
846
847 container = bt_ctf_field_enumeration_get_container(field);
848 if (!container) {
849 goto end;
850 }
851
852 container_type = bt_ctf_field_get_type(container);
853 if (!container_type) {
854 goto error_put_container;
855 }
856
857 integer_type = container_of(container_type,
858 struct bt_ctf_field_type_integer, parent);
859 enumeration_type = container_of(field->type,
860 struct bt_ctf_field_type_enumeration, parent);
861
862 if (!integer_type->declaration.signedness) {
863 uint64_t value;
864 ret = bt_ctf_field_unsigned_integer_get_value(container,
865 &value);
866 if (ret) {
867 goto error_put_container_type;
868 }
869
870 name = bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
871 enumeration_type, value);
872 } else {
873 int64_t value;
874 ret = bt_ctf_field_signed_integer_get_value(container,
875 &value);
876 if (ret) {
877 goto error_put_container_type;
878 }
879
880 name = bt_ctf_field_type_enumeration_get_mapping_name_signed(
881 enumeration_type, value);
882 }
883
884error_put_container_type:
885 bt_put(container_type);
886error_put_container:
887 bt_put(container);
888end:
889 return name;
890}
891
ad72416e 892BT_HIDDEN
1c822dfb
JG
893int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
894 int64_t *value)
895{
896 int ret = 0;
897 struct bt_ctf_field_integer *integer;
898 struct bt_ctf_field_type_integer *integer_type;
899
900 if (!field || !value || !field->payload_set ||
901 bt_ctf_field_type_get_type_id(field->type) !=
902 BT_CTF_TYPE_ID_INTEGER) {
903 ret = -1;
904 goto end;
905 }
906
907 integer_type = container_of(field->type,
908 struct bt_ctf_field_type_integer, parent);
909 if (!integer_type->declaration.signedness) {
910 ret = -1;
911 goto end;
912 }
913
914 integer = container_of(field,
915 struct bt_ctf_field_integer, parent);
916 *value = integer->definition.value._signed;
917end:
918 return ret;
919}
920
921int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
922 int64_t value)
923{
924 int ret = 0;
925 struct bt_ctf_field_integer *integer;
926 struct bt_ctf_field_type_integer *integer_type;
927 unsigned int size;
928 int64_t min_value, max_value;
929
930 if (!field || field->frozen ||
931 bt_ctf_field_type_get_type_id(field->type) !=
932 BT_CTF_TYPE_ID_INTEGER) {
933 ret = -1;
934 goto end;
935 }
936
937 integer = container_of(field, struct bt_ctf_field_integer, parent);
938 integer_type = container_of(field->type,
939 struct bt_ctf_field_type_integer, parent);
940 if (!integer_type->declaration.signedness) {
941 ret = -1;
942 goto end;
943 }
944
945 size = integer_type->declaration.len;
946 min_value = -(1ULL << (size - 1));
947 max_value = (1ULL << (size - 1)) - 1;
948 if (value < min_value || value > max_value) {
949 ret = -1;
950 goto end;
951 }
952
953 integer->definition.value._signed = value;
954 integer->parent.payload_set = 1;
955end:
956 return ret;
957}
958
ad72416e 959BT_HIDDEN
1c822dfb
JG
960int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
961 uint64_t *value)
962{
963 int ret = 0;
964 struct bt_ctf_field_integer *integer;
965 struct bt_ctf_field_type_integer *integer_type;
966
967 if (!field || !value || !field->payload_set ||
968 bt_ctf_field_type_get_type_id(field->type) !=
969 BT_CTF_TYPE_ID_INTEGER) {
970 ret = -1;
971 goto end;
972 }
973
974 integer_type = container_of(field->type,
975 struct bt_ctf_field_type_integer, parent);
976 if (integer_type->declaration.signedness) {
977 ret = -1;
978 goto end;
979 }
980
981 integer = container_of(field,
982 struct bt_ctf_field_integer, parent);
983 *value = integer->definition.value._unsigned;
984end:
985 return ret;
986}
987
988int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
989 uint64_t value)
990{
991 int ret = 0;
992 struct bt_ctf_field_integer *integer;
993 struct bt_ctf_field_type_integer *integer_type;
994 unsigned int size;
995 uint64_t max_value;
996
997 if (!field || field->frozen ||
998 bt_ctf_field_type_get_type_id(field->type) !=
999 BT_CTF_TYPE_ID_INTEGER) {
1000 ret = -1;
1001 goto end;
1002 }
1003
1004 integer = container_of(field, struct bt_ctf_field_integer, parent);
1005 integer_type = container_of(field->type,
1006 struct bt_ctf_field_type_integer, parent);
1007 if (integer_type->declaration.signedness) {
1008 ret = -1;
1009 goto end;
1010 }
1011
1012 size = integer_type->declaration.len;
1013 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
1014 if (value > max_value) {
1015 ret = -1;
1016 goto end;
1017 }
1018
1019 integer->definition.value._unsigned = value;
1020 integer->parent.payload_set = 1;
1021end:
1022 return ret;
1023}
1024
ad72416e 1025BT_HIDDEN
1c822dfb
JG
1026int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1027 double *value)
1028{
1029 int ret = 0;
1030 struct bt_ctf_field_floating_point *floating_point;
1031
1032 if (!field || !value || !field->payload_set ||
1033 bt_ctf_field_type_get_type_id(field->type) !=
1034 BT_CTF_TYPE_ID_FLOAT) {
1035 ret = -1;
1036 goto end;
1037 }
1038
1039 floating_point = container_of(field,
1040 struct bt_ctf_field_floating_point, parent);
1041 *value = floating_point->definition.value;
1042end:
1043 return ret;
1044}
1045
1046int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1047 double value)
1048{
1049 int ret = 0;
1050 struct bt_ctf_field_floating_point *floating_point;
1051
1052 if (!field || field->frozen ||
1053 bt_ctf_field_type_get_type_id(field->type) !=
1054 BT_CTF_TYPE_ID_FLOAT) {
1055 ret = -1;
1056 goto end;
1057 }
1058 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1059 parent);
1060 floating_point->definition.value = value;
1061 floating_point->parent.payload_set = 1;
1062end:
1063 return ret;
1064}
1065
ad72416e 1066BT_HIDDEN
1c822dfb
JG
1067const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1068{
1069 const char *ret = NULL;
1070 struct bt_ctf_field_string *string;
1071
1072 if (!field || !field->payload_set ||
1073 bt_ctf_field_type_get_type_id(field->type) !=
1074 BT_CTF_TYPE_ID_STRING) {
1075 goto end;
1076 }
1077
1078 string = container_of(field,
1079 struct bt_ctf_field_string, parent);
1080 ret = string->payload->str;
1081end:
1082 return ret;
1083}
1084
1085int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
1086 const char *value)
1087{
1088 int ret = 0;
1089 struct bt_ctf_field_string *string;
1090
1091 if (!field || !value || field->frozen ||
1092 bt_ctf_field_type_get_type_id(field->type) !=
1093 BT_CTF_TYPE_ID_STRING) {
1094 ret = -1;
1095 goto end;
1096 }
1097
1098 string = container_of(field, struct bt_ctf_field_string, parent);
1099 if (string->payload) {
1100 g_string_assign(string->payload, value);
1101 } else {
1102 string->payload = g_string_new(value);
1103 }
1104
1105 string->parent.payload_set = 1;
1106end:
1107 return ret;
1108}
1109
ad72416e 1110BT_HIDDEN
1c822dfb
JG
1111int bt_ctf_field_string_append(struct bt_ctf_field *field,
1112 const char *value)
1113{
1114 int ret = 0;
1115 struct bt_ctf_field_string *string_field;
1116
1117 if (!field || !value || field->frozen ||
1118 bt_ctf_field_type_get_type_id(field->type) !=
1119 BT_CTF_TYPE_ID_STRING) {
1120 ret = -1;
1121 goto end;
1122 }
1123
1124 string_field = container_of(field, struct bt_ctf_field_string, parent);
1125
1126 if (string_field->payload) {
1127 g_string_append(string_field->payload, value);
1128 } else {
1129 string_field->payload = g_string_new(value);
1130 }
1131
1132 string_field->parent.payload_set = 1;
1133
1134end:
1135 return ret;
1136}
1137
ad72416e 1138BT_HIDDEN
1c822dfb
JG
1139int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1140 const char *value, unsigned int length)
1141{
1142 int i;
1143 int ret = 0;
1144 unsigned int effective_length = length;
1145 struct bt_ctf_field_string *string_field;
1146
1147 if (!field || !value || field->frozen ||
1148 bt_ctf_field_type_get_type_id(field->type) !=
1149 BT_CTF_TYPE_ID_STRING) {
1150 ret = -1;
1151 goto end;
1152 }
1153
1154 string_field = container_of(field, struct bt_ctf_field_string, parent);
1155
1156 /* make sure no null bytes are appended */
1157 for (i = 0; i < length; ++i) {
1158 if (value[i] == '\0') {
1159 effective_length = i;
1160 break;
1161 }
1162 }
1163
1164 if (string_field->payload) {
1165 g_string_append_len(string_field->payload, value,
1166 effective_length);
1167 } else {
1168 string_field->payload = g_string_new_len(value,
1169 effective_length);
1170 }
1171
1172 string_field->parent.payload_set = 1;
1173
1174end:
1175 return ret;
1176}
1177
1178BT_HIDDEN
1179int bt_ctf_field_validate(struct bt_ctf_field *field)
1180{
1181 int ret = 0;
1182 enum bt_ctf_type_id type_id;
1183
1184 if (!field) {
1185 ret = -1;
1186 goto end;
1187 }
1188
1189 type_id = bt_ctf_field_type_get_type_id(field->type);
1190 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1191 ret = -1;
1192 goto end;
1193 }
1194
1195 ret = field_validate_funcs[type_id](field);
1196end:
1197 return ret;
1198}
1199
1200BT_HIDDEN
1201int bt_ctf_field_reset(struct bt_ctf_field *field)
1202{
1203 int ret = 0;
1204 enum bt_ctf_type_id type_id;
1205
1206 if (!field) {
1207 ret = -1;
1208 goto end;
1209 }
1210
1211 type_id = bt_ctf_field_type_get_type_id(field->type);
1212 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1213 ret = -1;
1214 goto end;
1215 }
1216
1217 ret = field_reset_funcs[type_id](field);
1218end:
1219 return ret;
1220}
1221
1222BT_HIDDEN
1223int bt_ctf_field_serialize(struct bt_ctf_field *field,
1224 struct ctf_stream_pos *pos)
1225{
1226 int ret = 0;
1227 enum bt_ctf_type_id type_id;
1228
1229 if (!field || !pos) {
1230 ret = -1;
1231 goto end;
1232 }
1233
1234 type_id = bt_ctf_field_type_get_type_id(field->type);
1235 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1236 ret = -1;
1237 goto end;
1238 }
1239
1240 ret = field_serialize_funcs[type_id](field, pos);
1241end:
1242 return ret;
1243}
1244
ad72416e 1245BT_HIDDEN
1c822dfb
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;
1250 enum bt_ctf_type_id type_id;
1251
1252 if (!field) {
1253 goto end;
1254 }
1255
1256 type_id = bt_ctf_field_type_get_type_id(field->type);
1257 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1258 goto end;
1259 }
1260
1261 copy = bt_ctf_field_create(field->type);
1262 if (!copy) {
1263 goto end;
1264 }
1265
1266 copy->payload_set = field->payload_set;
1267 ret = field_copy_funcs[type_id](field, copy);
1268 if (ret) {
1269 bt_put(copy);
1270 copy = NULL;
1271 }
1272end:
1273 return copy;
1274}
1275
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
1348 if (!structure) {
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;
1383 array->elements = g_ptr_array_sized_new(array_length);
1384 if (!array->elements) {
1385 goto error;
1386 }
1387
1388 g_ptr_array_set_free_func(array->elements,
1389 (GDestroyNotify)bt_ctf_field_put);
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
1415void bt_ctf_field_destroy(struct bt_object *obj)
1416{
1417 struct bt_ctf_field *field;
1418 struct bt_ctf_field_type *type;
1419 enum bt_ctf_type_id type_id;
1420
1421 field = container_of(obj, struct bt_ctf_field, base);
1422 type = field->type;
1423 type_id = bt_ctf_field_type_get_type_id(type);
1424 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
1425 type_id >= BT_CTF_NR_TYPE_IDS) {
1426 return;
1427 }
1428
1429 field_destroy_funcs[type_id](field);
1430 bt_put(type);
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);
1457 bt_put(enumeration->payload);
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);
1499 bt_put(variant->tag);
1500 bt_put(variant->payload);
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);
1528 if (sequence->elements) {
1529 g_ptr_array_free(sequence->elements, TRUE);
1530 }
1531 bt_put(sequence->length);
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);
1544 if (string->payload) {
1545 g_string_free(string->payload, TRUE);
1546 }
1547 g_free(string);
1548}
1549
1550static
1551int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1552{
1553 return (field && field->payload_set) ? 0 : -1;
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) {
1595 goto end;
1596 }
1597 }
1598end:
1599 return ret;
1600}
1601
1602static
1603int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1604{
1605 int ret = 0;
1606 struct bt_ctf_field_variant *variant;
1607
1608 if (!field) {
1609 ret = -1;
1610 goto end;
1611 }
1612
1613 variant = container_of(field, struct bt_ctf_field_variant, parent);
1614 ret = bt_ctf_field_validate(variant->payload);
1615end:
1616 return ret;
1617}
1618
1619static
1620int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1621{
1622 size_t i;
1623 int ret = 0;
1624 struct bt_ctf_field_array *array;
1625
1626 if (!field) {
1627 ret = -1;
1628 goto end;
1629 }
1630
1631 array = container_of(field, struct bt_ctf_field_array, parent);
1632 for (i = 0; i < array->elements->len; i++) {
1633 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1634 if (ret) {
1635 goto end;
1636 }
1637 }
1638end:
1639 return ret;
1640}
1641
1642static
1643int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1644{
1645 size_t i;
1646 int ret = 0;
1647 struct bt_ctf_field_sequence *sequence;
1648
1649 if (!field) {
1650 ret = -1;
1651 goto end;
1652 }
1653
1654 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1655 for (i = 0; i < sequence->elements->len; i++) {
1656 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1657 if (ret) {
1658 goto end;
1659 }
1660 }
1661end:
1662 return ret;
1663}
1664
1665static
1666int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1667{
1668 int ret = 0;
1669
1670 if (!field) {
1671 ret = -1;
1672 goto end;
1673 }
1674
1675 field->payload_set = 0;
1676end:
1677 return ret;
1678}
1679
1680static
1681int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1682{
1683 int ret = 0;
1684 struct bt_ctf_field_enumeration *enumeration;
1685
1686 if (!field) {
1687 ret = -1;
1688 goto end;
1689 }
1690
1691 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1692 parent);
1693 if (!enumeration->payload) {
1694 goto end;
1695 }
1696
1697 ret = bt_ctf_field_reset(enumeration->payload);
1698end:
1699 return ret;
1700}
1701
1702static
1703int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1704{
1705 size_t i;
1706 int ret = 0;
1707 struct bt_ctf_field_structure *structure;
1708
1709 if (!field) {
1710 ret = -1;
1711 goto end;
1712 }
1713
1714 structure = container_of(field, struct bt_ctf_field_structure, parent);
1715 for (i = 0; i < structure->fields->len; i++) {
1716 struct bt_ctf_field *member = structure->fields->pdata[i];
1717
1718 if (!member) {
1719 /*
1720 * Structure members are lazily initialized; skip if
1721 * this member has not been allocated yet.
1722 */
1723 continue;
1724 }
1725
1726 ret = bt_ctf_field_reset(member);
1727 if (ret) {
1728 goto end;
1729 }
1730 }
1731end:
1732 return ret;
1733}
1734
1735static
1736int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1737{
1738 int ret = 0;
1739 struct bt_ctf_field_variant *variant;
1740
1741 if (!field) {
1742 ret = -1;
1743 goto end;
1744 }
1745
1746 variant = container_of(field, struct bt_ctf_field_variant, parent);
1747 if (variant->payload) {
1748 ret = bt_ctf_field_reset(variant->payload);
1749 }
1750end:
1751 return ret;
1752}
1753
1754static
1755int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1756{
1757 size_t i;
1758 int ret = 0;
1759 struct bt_ctf_field_array *array;
1760
1761 if (!field) {
1762 ret = -1;
1763 goto end;
1764 }
1765
1766 array = container_of(field, struct bt_ctf_field_array, parent);
1767 for (i = 0; i < array->elements->len; i++) {
1768 struct bt_ctf_field *member = array->elements->pdata[i];
1769
1770 if (!member) {
1771 /*
1772 * Array elements are lazily initialized; skip if
1773 * this member has not been allocated yet.
1774 */
1775 continue;
1776 }
1777
1778 ret = bt_ctf_field_reset(member);
1779 if (ret) {
1780 goto end;
1781 }
1782 }
1783end:
1784 return ret;
1785}
1786
1787static
1788int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1789{
1790 size_t i;
1791 int ret = 0;
1792 struct bt_ctf_field_sequence *sequence;
1793
1794 if (!field) {
1795 ret = -1;
1796 goto end;
1797 }
1798
1799 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1800 for (i = 0; i < sequence->elements->len; i++) {
1801 struct bt_ctf_field *member = sequence->elements->pdata[i];
1802
1803 if (!member) {
1804 /*
1805 * Sequence elements are lazily initialized; skip if
1806 * this member has not been allocated yet.
1807 */
1808 continue;
1809 }
1810
1811 ret = bt_ctf_field_reset(member);
1812 if (ret) {
1813 goto end;
1814 }
1815 }
1816end:
1817 return ret;
1818}
1819
1820static
1821int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1822{
1823 int ret = 0;
1824 struct bt_ctf_field_string *string;
1825
1826 if (!field) {
1827 ret = -1;
1828 goto end;
1829 }
1830
1831 ret = bt_ctf_field_generic_reset(field);
1832 if (ret) {
1833 goto end;
1834 }
1835
1836 string = container_of(field, struct bt_ctf_field_string, parent);
1837 if (string->payload) {
1838 g_string_truncate(string->payload, 0);
1839 }
1840end:
1841 return ret;
1842}
1843
1844static
1845int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1846 struct ctf_stream_pos *pos)
1847{
1848 int ret = 0;
1849 struct bt_ctf_field_integer *integer = container_of(field,
1850 struct bt_ctf_field_integer, parent);
1851
1852retry:
1853 ret = ctf_integer_write(&pos->parent, &integer->definition.p);
1854 if (ret == -EFAULT) {
1855 /*
1856 * The field is too large to fit in the current packet's
1857 * remaining space. Bump the packet size and retry.
1858 */
1859 ret = increase_packet_size(pos);
1860 if (ret) {
1861 goto end;
1862 }
1863 goto retry;
1864 }
1865end:
1866 return ret;
1867}
1868
1869static
1870int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1871 struct ctf_stream_pos *pos)
1872{
1873 struct bt_ctf_field_enumeration *enumeration = container_of(
1874 field, struct bt_ctf_field_enumeration, parent);
1875
1876 return bt_ctf_field_serialize(enumeration->payload, pos);
1877}
1878
1879static
1880int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1881 struct ctf_stream_pos *pos)
1882{
1883 int ret = 0;
1884 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1885 struct bt_ctf_field_floating_point, parent);
1886
1887retry:
1888 ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
1889 if (ret == -EFAULT) {
1890 /*
1891 * The field is too large to fit in the current packet's
1892 * remaining space. Bump the packet size and retry.
1893 */
1894 ret = increase_packet_size(pos);
1895 if (ret) {
1896 goto end;
1897 }
1898 goto retry;
1899 }
1900end:
1901 return ret;
1902}
1903
1904static
1905int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1906 struct ctf_stream_pos *pos)
1907{
1908 size_t i;
1909 int ret = 0;
1910 struct bt_ctf_field_structure *structure = container_of(
1911 field, struct bt_ctf_field_structure, parent);
1912
1913 while (!ctf_pos_access_ok(pos,
1914 offset_align(pos->offset,
1915 field->type->declaration->alignment))) {
1916 ret = increase_packet_size(pos);
1917 if (ret) {
1918 goto end;
1919 }
1920 }
1921
1922 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1923 ret = -1;
1924 goto end;
1925 }
1926
1927 for (i = 0; i < structure->fields->len; i++) {
1928 struct bt_ctf_field *field = g_ptr_array_index(
1929 structure->fields, i);
1930
1931 ret = bt_ctf_field_serialize(field, pos);
1932 if (ret) {
1933 break;
1934 }
1935 }
1936end:
1937 return ret;
1938}
1939
1940static
1941int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
1942 struct ctf_stream_pos *pos)
1943{
1944 struct bt_ctf_field_variant *variant = container_of(
1945 field, struct bt_ctf_field_variant, parent);
1946
1947 return bt_ctf_field_serialize(variant->payload, pos);
1948}
1949
1950static
1951int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
1952 struct ctf_stream_pos *pos)
1953{
1954 size_t i;
1955 int ret = 0;
1956 struct bt_ctf_field_array *array = container_of(
1957 field, struct bt_ctf_field_array, parent);
1958
1959 for (i = 0; i < array->elements->len; i++) {
1960 ret = bt_ctf_field_serialize(
1961 g_ptr_array_index(array->elements, i), pos);
1962 if (ret) {
1963 goto end;
1964 }
1965 }
1966end:
1967 return ret;
1968}
1969
1970static
1971int bt_ctf_field_sequence_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_sequence *sequence = container_of(
1977 field, struct bt_ctf_field_sequence, parent);
1978
1979 for (i = 0; i < sequence->elements->len; i++) {
1980 ret = bt_ctf_field_serialize(
1981 g_ptr_array_index(sequence->elements, i), pos);
1982 if (ret) {
1983 goto end;
1984 }
1985 }
1986end:
1987 return ret;
1988}
1989
1990static
1991int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
1992 struct ctf_stream_pos *pos)
1993{
1994 size_t i;
1995 int ret = 0;
1996 struct bt_ctf_field_string *string = container_of(field,
1997 struct bt_ctf_field_string, parent);
1998 struct bt_ctf_field_type *character_type =
1999 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
2000 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
2001
2002 for (i = 0; i < string->payload->len + 1; i++) {
2003 ret = bt_ctf_field_unsigned_integer_set_value(character,
2004 (uint64_t) string->payload->str[i]);
2005 if (ret) {
2006 goto end;
2007 }
2008
2009 ret = bt_ctf_field_integer_serialize(character, pos);
2010 if (ret) {
2011 goto end;
2012 }
2013 }
2014end:
2015 bt_put(character);
2016 bt_put(character_type);
2017 return ret;
2018}
2019
2020static
2021int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2022 struct bt_ctf_field *dst)
2023{
2024 struct bt_ctf_field_integer *integer_src, *integer_dst;
2025
2026 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
2027 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
2028
2029 memcpy(&integer_dst->definition, &integer_src->definition,
2030 sizeof(struct definition_integer));
2031 return 0;
2032}
2033
2034static
2035int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2036 struct bt_ctf_field *dst)
2037{
2038 int ret = 0;
2039 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2040
2041 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2042 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2043
2044 if (enum_src->payload) {
2045 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2046 if (!enum_dst->payload) {
2047 ret = -1;
2048 goto end;
2049 }
2050 }
2051end:
2052 return ret;
2053}
2054
2055static
2056int bt_ctf_field_floating_point_copy(
2057 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2058{
2059 struct bt_ctf_field_floating_point *float_src, *float_dst;
2060
2061 float_src = container_of(src, struct bt_ctf_field_floating_point,
2062 parent);
2063 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2064 parent);
2065
2066 memcpy(&float_dst->definition, &float_src->definition,
2067 sizeof(struct definition_float));
2068 memcpy(&float_dst->sign, &float_src->sign,
2069 sizeof(struct definition_integer));
2070 memcpy(&float_dst->mantissa, &float_src->mantissa,
2071 sizeof(struct definition_integer));
2072 memcpy(&float_dst->exp, &float_src->exp,
2073 sizeof(struct definition_integer));
2074 return 0;
2075}
2076
2077static
2078int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2079 struct bt_ctf_field *dst)
2080{
2081 int ret = 0, i;
2082 struct bt_ctf_field_structure *struct_src, *struct_dst;
2083
2084 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2085 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2086
2087 /* This field_name_to_index HT is owned by the structure field type */
2088 struct_dst->field_name_to_index = struct_src->field_name_to_index;
2089 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
2090
2091 for (i = 0; i < struct_src->fields->len; i++) {
2092 struct bt_ctf_field *field =
2093 g_ptr_array_index(struct_src->fields, i);
2094 struct bt_ctf_field *field_copy = NULL;
2095
2096 if (field) {
2097 field_copy = bt_ctf_field_copy(field);
2098
2099 if (!field_copy) {
2100 ret = -1;
2101 goto end;
2102 }
2103 }
2104
2105 g_ptr_array_index(struct_dst->fields, i) = field_copy;
2106 }
2107end:
2108 return ret;
2109}
2110
2111static
2112int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2113 struct bt_ctf_field *dst)
2114{
2115 int ret = 0;
2116 struct bt_ctf_field_variant *variant_src, *variant_dst;
2117
2118 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2119 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2120
2121 if (variant_src->tag) {
2122 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2123 if (!variant_dst->tag) {
2124 ret = -1;
2125 goto end;
2126 }
2127 }
2128 if (variant_src->payload) {
2129 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2130 if (!variant_dst->payload) {
2131 ret = -1;
2132 goto end;
2133 }
2134 }
2135end:
2136 return ret;
2137}
2138
2139static
2140int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2141 struct bt_ctf_field *dst)
2142{
2143 int ret = 0, i;
2144 struct bt_ctf_field_array *array_src, *array_dst;
2145
2146 array_src = container_of(src, struct bt_ctf_field_array, parent);
2147 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2148
2149 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
2150 for (i = 0; i < array_src->elements->len; i++) {
2151 struct bt_ctf_field *field =
2152 g_ptr_array_index(array_src->elements, i);
2153 struct bt_ctf_field *field_copy = NULL;
2154
2155 if (field) {
2156 field_copy = bt_ctf_field_copy(field);
2157
2158 if (!field_copy) {
2159 ret = -1;
2160 goto end;
2161 }
2162 }
2163
2164 g_ptr_array_index(array_dst->elements, i) = field_copy;
2165 }
2166end:
2167 return ret;
2168}
2169
2170static
2171int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2172 struct bt_ctf_field *dst)
2173{
2174 int ret = 0, i;
2175 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
2176 struct bt_ctf_field *src_length;
2177 struct bt_ctf_field *dst_length;
2178
2179 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2180 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2181
2182 src_length = bt_ctf_field_sequence_get_length(src);
2183
2184 if (!src_length) {
2185 /* no length set yet: keep destination sequence empty */
2186 goto end;
2187 }
2188
2189 /* copy source length */
2190 dst_length = bt_ctf_field_copy(src_length);
2191 bt_put(src_length);
2192
2193 if (!dst_length) {
2194 ret = -1;
2195 goto end;
2196 }
2197
2198 /* this will initialize the destination sequence's internal array */
2199 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
2200 bt_put(dst_length);
2201
2202 if (ret) {
2203 goto end;
2204 }
2205
2206 assert(sequence_dst->elements->len == sequence_src->elements->len);
2207
2208 for (i = 0; i < sequence_src->elements->len; i++) {
2209 struct bt_ctf_field *field =
2210 g_ptr_array_index(sequence_src->elements, i);
2211 struct bt_ctf_field *field_copy = NULL;
2212
2213 if (field) {
2214 field_copy = bt_ctf_field_copy(field);
2215
2216 if (!field_copy) {
2217 ret = -1;
2218 goto end;
2219 }
2220 }
2221
2222 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
2223 }
2224end:
2225 return ret;
2226}
2227
2228static
2229int bt_ctf_field_string_copy(struct bt_ctf_field *src,
2230 struct bt_ctf_field *dst)
2231{
2232 int ret = 0;
2233 struct bt_ctf_field_string *string_src, *string_dst;
2234
2235 string_src = container_of(src, struct bt_ctf_field_string, parent);
2236 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
2237
2238 if (string_src->payload) {
2239 string_dst->payload = g_string_new(string_src->payload->str);
2240 if (!string_dst->payload) {
2241 ret = -1;
2242 goto end;
2243 }
2244 }
2245end:
2246 return ret;
2247}
2248
2249static
2250int increase_packet_size(struct ctf_stream_pos *pos)
2251{
2252 int ret;
2253
2254 assert(pos);
2255 ret = munmap_align(pos->base_mma);
2256 if (ret) {
2257 goto end;
2258 }
2259
2260 pos->packet_size += PACKET_LEN_INCREMENT;
2261 do {
2262 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
2263 pos->packet_size / CHAR_BIT);
2264 } while (ret == EINTR);
2265 if (ret) {
2266 errno = EINTR;
2267 ret = -1;
2268 goto end;
2269 }
2270
2271 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
2272 pos->flags, pos->fd, pos->mmap_offset);
2273 if (pos->base_mma == MAP_FAILED) {
2274 ret = -1;
2275 }
2276end:
2277 return ret;
2278}
2279
2280static
2281void generic_field_freeze(struct bt_ctf_field *field)
2282{
2283 field->frozen = 1;
2284}
2285
2286static
2287void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
2288{
2289 struct bt_ctf_field_enumeration *enum_field =
2290 container_of(field, struct bt_ctf_field_enumeration, parent);
2291
2292 bt_ctf_field_freeze(enum_field->payload);
2293 generic_field_freeze(field);
2294}
2295
2296static
2297void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
2298{
2299 int i;
2300 struct bt_ctf_field_structure *structure_field =
2301 container_of(field, struct bt_ctf_field_structure, parent);
2302
2303 for (i = 0; i < structure_field->fields->len; i++) {
2304 struct bt_ctf_field *field =
2305 g_ptr_array_index(structure_field->fields, i);
2306
2307 bt_ctf_field_freeze(field);
2308 }
2309
2310 generic_field_freeze(field);
2311}
2312
2313static
2314void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
2315{
2316 struct bt_ctf_field_variant *variant_field =
2317 container_of(field, struct bt_ctf_field_variant, parent);
2318
2319 bt_ctf_field_freeze(variant_field->tag);
2320 bt_ctf_field_freeze(variant_field->payload);
2321 generic_field_freeze(field);
2322}
2323
2324static
2325void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
2326{
2327 int i;
2328 struct bt_ctf_field_array *array_field =
2329 container_of(field, struct bt_ctf_field_array, parent);
2330
2331 for (i = 0; i < array_field->elements->len; i++) {
2332 struct bt_ctf_field *field =
2333 g_ptr_array_index(array_field->elements, i);
2334
2335 bt_ctf_field_freeze(field);
2336 }
2337
2338 generic_field_freeze(field);
2339}
2340
2341static
2342void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
2343{
2344 int i;
2345 struct bt_ctf_field_sequence *sequence_field =
2346 container_of(field, struct bt_ctf_field_sequence, parent);
2347
2348 bt_ctf_field_freeze(sequence_field->length);
2349
2350 for (i = 0; i < sequence_field->elements->len; i++) {
2351 struct bt_ctf_field *field =
2352 g_ptr_array_index(sequence_field->elements, i);
2353
2354 bt_ctf_field_freeze(field);
2355 }
2356
2357 generic_field_freeze(field);
2358}
2359
2360BT_HIDDEN
2361void bt_ctf_field_freeze(struct bt_ctf_field *field)
2362{
2363 enum bt_ctf_type_id type_id;
2364
2365 if (!field) {
2366 goto end;
2367 }
2368
2369 type_id = bt_ctf_field_get_type_id(field);
2370 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
2371 type_id >= BT_CTF_NR_TYPE_IDS) {
2372 goto end;
2373 }
2374
2375 field_freeze_funcs[type_id](field);
2376end:
2377 return;
2378}
This page took 0.1056 seconds and 4 git commands to generate.