lib: move plugin set API declarations to `babeltrace/plugin/plugin-set.h`
[babeltrace.git] / lib / ctf-writer / fields.c
CommitLineData
3dca2276
PP
1/*
2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#define BT_LOG_TAG "CTF-WRITER-FIELDS"
26#include <babeltrace/lib-logging-internal.h>
27
16ca5ff0
PP
28#include <babeltrace/assert-pre-internal.h>
29#include <babeltrace/align-internal.h>
30#include <babeltrace/assert-internal.h>
3dca2276 31#include <babeltrace/compat/fcntl-internal.h>
16ca5ff0 32#include <babeltrace/compiler-internal.h>
3dca2276 33#include <babeltrace/ctf-writer/field-types-internal.h>
16ca5ff0 34#include <babeltrace/ctf-writer/fields-internal.h>
3dca2276 35#include <babeltrace/ctf-writer/serialize-internal.h>
16ca5ff0 36#include <babeltrace/endian-internal.h>
3dca2276 37#include <babeltrace/object-internal.h>
65300d60 38#include <babeltrace/object.h>
3dca2276
PP
39#include <float.h>
40#include <inttypes.h>
16ca5ff0 41#include <inttypes.h>
3dca2276
PP
42#include <stdlib.h>
43
16ca5ff0
PP
44#define BT_ASSERT_PRE_CTF_FIELD_IS_INT_OR_ENUM(_field, _name) \
45 BT_ASSERT_PRE((_field)->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || \
46 (_field)->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, \
47 _name " is not an integer or an enumeration field: " \
48 "field-addr=%p", (_field))
49
50BT_HIDDEN
51struct bt_ctf_field_common *bt_ctf_field_common_copy(struct bt_ctf_field_common *field)
52{
53 struct bt_ctf_field_common *copy = NULL;
54
55 BT_ASSERT_PRE_NON_NULL(field, "Field");
56 BT_ASSERT(field_type_common_has_known_id(field->type));
57 BT_ASSERT(field->methods->copy);
58 copy = field->methods->copy(field);
59 if (!copy) {
60 BT_LOGW("Cannot create field: ft-addr=%p", field->type);
61 goto end;
62 }
63
64 bt_ctf_field_common_set(copy, field->payload_set);
65
66end:
67 return copy;
68}
69
70BT_HIDDEN
71int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common *field,
72 struct bt_ctf_field_type_common *type,
73 bool is_shared, bt_object_release_func release_func,
74 struct bt_ctf_field_common_methods *methods,
75 bt_ctf_field_common_create_func field_create_func,
76 GDestroyNotify field_release_func)
77{
78 int ret = 0;
79 struct bt_ctf_field_type_common_structure *structure_type =
80 BT_CTF_FROM_COMMON(type);
81 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
82 size_t i;
83
84 BT_LOGD("Initializing common structure field object: ft-addr=%p", type);
85 bt_ctf_field_common_initialize(field, type, is_shared,
86 release_func, methods);
87 structure->fields = g_ptr_array_new_with_free_func(field_release_func);
88 g_ptr_array_set_size(structure->fields, structure_type->fields->len);
89
90 /* Create all fields contained in the structure field. */
91 for (i = 0; i < structure_type->fields->len; i++) {
92 struct bt_ctf_field_common *field;
93 struct bt_ctf_field_type_common_structure_field *struct_field =
94 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
95 structure_type, i);
96 field = field_create_func(struct_field->type);
97 if (!field) {
98 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
99 g_quark_to_string(struct_field->name), i);
100 ret = -1;
101 goto end;
102 }
103
104 g_ptr_array_index(structure->fields, i) = field;
105 }
106
107 BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
108 field, type);
109
110end:
111 return ret;
112}
113
114BT_HIDDEN
115int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common *field,
116 struct bt_ctf_field_type_common *type,
117 bool is_shared, bt_object_release_func release_func,
118 struct bt_ctf_field_common_methods *methods,
119 bt_ctf_field_common_create_func field_create_func,
120 GDestroyNotify field_release_func)
121{
122 int ret = 0;
123 struct bt_ctf_field_type_common_variant *variant_type =
124 BT_CTF_FROM_COMMON(type);
125 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
126 size_t i;
127
128 BT_LOGD("Initializing common variant field object: ft-addr=%p", type);
129 bt_ctf_field_common_initialize(field, type, is_shared,
130 release_func, methods);
131 ret = bt_ctf_field_type_common_variant_update_choices(type);
132 if (ret) {
133 BT_LOGE("Cannot update common variant field type choices: "
134 "ret=%d", ret);
135 goto end;
136 }
137
138 variant->fields = g_ptr_array_new_with_free_func(field_release_func);
139 g_ptr_array_set_size(variant->fields, variant_type->choices->len);
140
141 /* Create all fields contained in the variant field. */
142 for (i = 0; i < variant_type->choices->len; i++) {
143 struct bt_ctf_field_common *field;
144 struct bt_ctf_field_type_common_variant_choice *var_choice =
145 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
146 variant_type, i);
147
148 field = field_create_func(var_choice->type);
149 if (!field) {
150 BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
151 g_quark_to_string(var_choice->name), i);
152 ret = -1;
153 goto end;
154 }
155
156 g_ptr_array_index(variant->fields, i) = field;
157 }
158
159 BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
160 field, type);
161
162end:
163 return ret;
164}
165
166BT_HIDDEN
167int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common *field,
168 struct bt_ctf_field_type_common *type,
169 bool is_shared, bt_object_release_func release_func,
170 struct bt_ctf_field_common_methods *methods)
171{
172 int ret = 0;
173 struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
174
175 BT_LOGD("Initializing common string field object: ft-addr=%p", type);
176 bt_ctf_field_common_initialize(field, type, is_shared,
177 release_func, methods);
178 string->buf = g_array_sized_new(FALSE, FALSE, sizeof(char), 1);
179 if (!string->buf) {
180 ret = -1;
181 goto end;
182 }
183
184 g_array_index(string->buf, char, 0) = '\0';
185 BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
186 field, type);
187
188end:
189 return ret;
190}
191
192BT_HIDDEN
193int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common *field,
194 struct bt_ctf_field_type_common *type,
195 bool is_shared, bt_object_release_func release_func,
196 struct bt_ctf_field_common_methods *methods,
197 bt_ctf_field_common_create_func field_create_func,
198 GDestroyNotify field_destroy_func)
199{
200 struct bt_ctf_field_type_common_array *array_type = BT_CTF_FROM_COMMON(type);
201 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
202 unsigned int array_length;
203 int ret = 0;
204 uint64_t i;
205
206 BT_LOGD("Initializing common array field object: ft-addr=%p", type);
207 BT_ASSERT(type);
208 bt_ctf_field_common_initialize(field, type, is_shared,
209 release_func, methods);
210 array_length = array_type->length;
211 array->elements = g_ptr_array_sized_new(array_length);
212 if (!array->elements) {
213 ret = -1;
214 goto end;
215 }
216
217 g_ptr_array_set_free_func(array->elements, field_destroy_func);
218 g_ptr_array_set_size(array->elements, array_length);
219
220 for (i = 0; i < array_length; i++) {
221 array->elements->pdata[i] = field_create_func(
222 array_type->element_ft);
223 if (!array->elements->pdata[i]) {
224 ret = -1;
225 goto end;
226 }
227 }
228
229 BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
230 field, type);
231
232end:
233 return ret;
234}
235
236BT_HIDDEN
237int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common *field,
238 struct bt_ctf_field_type_common *type,
239 bool is_shared, bt_object_release_func release_func,
240 struct bt_ctf_field_common_methods *methods,
241 GDestroyNotify field_destroy_func)
242{
243 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
244 int ret = 0;
245
246 BT_LOGD("Initializing common sequence field object: ft-addr=%p", type);
247 BT_ASSERT(type);
248 bt_ctf_field_common_initialize(field, type, is_shared,
249 release_func, methods);
250 sequence->elements = g_ptr_array_new();
251 if (!sequence->elements) {
252 ret = -1;
253 goto end;
254 }
255
256 g_ptr_array_set_free_func(sequence->elements, field_destroy_func);
257 BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
258 field, type);
259
260end:
261 return ret;
262}
263
264BT_HIDDEN
265int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common *field)
266{
267 return (field && field->payload_set) ? 0 : -1;
268}
269
270BT_HIDDEN
271int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common *field)
272{
273 int64_t i;
274 int ret = 0;
275 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
276
277 BT_ASSERT(field);
278
279 for (i = 0; i < structure->fields->len; i++) {
280 ret = bt_ctf_field_common_validate_recursive(
281 (void *) structure->fields->pdata[i]);
282
283 if (ret) {
284 int this_ret;
285 const char *name;
286
287 this_ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
288 field->type, &name, NULL, i);
289 BT_ASSERT(this_ret == 0);
290 BT_ASSERT_PRE_MSG("Invalid structure field's field: "
291 "struct-field-addr=%p, field-name=\"%s\", "
292 "index=%" PRId64 ", field-addr=%p",
293 field, name, i, structure->fields->pdata[i]);
294 goto end;
295 }
296 }
297
298end:
299 return ret;
300}
301
302BT_HIDDEN
303int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common *field)
304{
305 int ret = 0;
306 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
307
308 BT_ASSERT(field);
309
310 if (!variant->current_field) {
311 ret = -1;
312 goto end;
313 }
314
315 ret = bt_ctf_field_common_validate_recursive(variant->current_field);
316
317end:
318 return ret;
319}
320
321BT_HIDDEN
322int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common *field)
323{
324 int64_t i;
325 int ret = 0;
326 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
327
328 BT_ASSERT(field);
329
330 for (i = 0; i < array->elements->len; i++) {
331 ret = bt_ctf_field_common_validate_recursive((void *) array->elements->pdata[i]);
332 if (ret) {
333 BT_ASSERT_PRE_MSG("Invalid array field's element field: "
334 "array-field-addr=%p, " PRId64 ", "
335 "elem-field-addr=%p",
336 field, i, array->elements->pdata[i]);
337 goto end;
338 }
339 }
340
341end:
342 return ret;
343}
344
345BT_HIDDEN
346int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common *field)
347{
348 size_t i;
349 int ret = 0;
350 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
351
352 BT_ASSERT(field);
353
354 for (i = 0; i < sequence->elements->len; i++) {
355 ret = bt_ctf_field_common_validate_recursive(
356 (void *) sequence->elements->pdata[i]);
357 if (ret) {
358 BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
359 "seq-field-addr=%p, " PRId64 ", "
360 "elem-field-addr=%p",
361 field, i, sequence->elements->pdata[i]);
362 goto end;
363 }
364 }
365end:
366 return ret;
367}
368
369BT_HIDDEN
370void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common *field)
371{
372 BT_ASSERT(field);
373 field->payload_set = false;
374}
375
376BT_HIDDEN
377void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common *field)
378{
379 int64_t i;
380 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
381
382 BT_ASSERT(field);
383
384 for (i = 0; i < structure->fields->len; i++) {
385 struct bt_ctf_field_common *member = structure->fields->pdata[i];
386
387 if (!member) {
388 /*
389 * Structure members are lazily initialized;
390 * skip if this member has not been allocated
391 * yet.
392 */
393 continue;
394 }
395
396 bt_ctf_field_common_reset_recursive(member);
397 }
398}
399
400BT_HIDDEN
401void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common *field)
402{
403 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
404
405 BT_ASSERT(field);
406 variant->current_field = NULL;
407}
408
409BT_HIDDEN
410void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common *field)
411{
412 size_t i;
413 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
414
415 BT_ASSERT(field);
416
417 for (i = 0; i < array->elements->len; i++) {
418 struct bt_ctf_field_common *member = array->elements->pdata[i];
419
420 if (!member) {
421 /*
422 * Array elements are lazily initialized; skip
423 * if this member has not been allocated yet.
424 */
425 continue;
426 }
427
428 bt_ctf_field_common_reset_recursive(member);
429 }
430}
431
432BT_HIDDEN
433void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common *field)
434{
435 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
436 uint64_t i;
437
438 BT_ASSERT(field);
439
440 for (i = 0; i < sequence->elements->len; i++) {
441 if (sequence->elements->pdata[i]) {
442 bt_ctf_field_common_reset_recursive(
443 sequence->elements->pdata[i]);
444 }
445 }
446
447 sequence->length = 0;
448}
449
450BT_HIDDEN
451void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common *field,
452 bool is_frozen)
453{
454 field->frozen = is_frozen;
455}
456
457BT_HIDDEN
458void bt_ctf_field_common_structure_set_is_frozen_recursive(
459 struct bt_ctf_field_common *field, bool is_frozen)
460{
461 uint64_t i;
462 struct bt_ctf_field_common_structure *structure_field =
463 BT_CTF_FROM_COMMON(field);
464
465 BT_LOGD("Freezing structure field object: addr=%p", field);
466
467 for (i = 0; i < structure_field->fields->len; i++) {
468 struct bt_ctf_field_common *struct_field =
469 g_ptr_array_index(structure_field->fields, i);
470
471 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
472 struct_field, i);
473 bt_ctf_field_common_set_is_frozen_recursive(struct_field,
474 is_frozen);
475 }
476
477 bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
478}
479
480BT_HIDDEN
481void bt_ctf_field_common_variant_set_is_frozen_recursive(
482 struct bt_ctf_field_common *field, bool is_frozen)
483{
484 uint64_t i;
485 struct bt_ctf_field_common_variant *variant_field = BT_CTF_FROM_COMMON(field);
486
487 BT_LOGD("Freezing variant field object: addr=%p", field);
488
489 for (i = 0; i < variant_field->fields->len; i++) {
490 struct bt_ctf_field_common *var_field =
491 g_ptr_array_index(variant_field->fields, i);
492
493 BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64,
494 var_field, i);
495 bt_ctf_field_common_set_is_frozen_recursive(var_field, is_frozen);
496 }
497
498 bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
499}
500
501BT_HIDDEN
502void bt_ctf_field_common_array_set_is_frozen_recursive(
503 struct bt_ctf_field_common *field, bool is_frozen)
504{
505 int64_t i;
506 struct bt_ctf_field_common_array *array_field = BT_CTF_FROM_COMMON(field);
507
508 BT_LOGD("Freezing array field object: addr=%p", field);
509
510 for (i = 0; i < array_field->elements->len; i++) {
511 struct bt_ctf_field_common *elem_field =
512 g_ptr_array_index(array_field->elements, i);
513
514 BT_LOGD("Freezing array field object's element field: "
515 "element-field-addr=%p, index=%" PRId64,
516 elem_field, i);
517 bt_ctf_field_common_set_is_frozen_recursive(elem_field, is_frozen);
518 }
519
520 bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
521}
522
523BT_HIDDEN
524void bt_ctf_field_common_sequence_set_is_frozen_recursive(
525 struct bt_ctf_field_common *field, bool is_frozen)
526{
527 int64_t i;
528 struct bt_ctf_field_common_sequence *sequence_field =
529 BT_CTF_FROM_COMMON(field);
530
531 BT_LOGD("Freezing sequence field object: addr=%p", field);
532
533 for (i = 0; i < sequence_field->length; i++) {
534 struct bt_ctf_field_common *elem_field =
535 g_ptr_array_index(sequence_field->elements, i);
536
537 BT_LOGD("Freezing sequence field object's element field: "
538 "element-field-addr=%p, index=%" PRId64,
539 elem_field, i);
540 bt_ctf_field_common_set_is_frozen_recursive(elem_field, is_frozen);
541 }
542
543 bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
544}
545
546BT_HIDDEN
547void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common *field,
548 bool is_frozen)
549{
550 if (!field) {
551 goto end;
552 }
553
554 BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
555 field, is_frozen);
556 BT_ASSERT(field_type_common_has_known_id(field->type));
557 BT_ASSERT(field->methods->set_is_frozen);
558 field->methods->set_is_frozen(field, is_frozen);
559
560end:
561 return;
562}
563
564BT_HIDDEN
565bt_bool bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common *field)
566{
567 return field && field->payload_set;
568}
569
570BT_HIDDEN
571bt_bool bt_ctf_field_common_structure_is_set_recursive(
572 struct bt_ctf_field_common *field)
573{
574 bt_bool is_set = BT_FALSE;
575 size_t i;
576 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
577
578 BT_ASSERT(field);
579
580 for (i = 0; i < structure->fields->len; i++) {
581 is_set = bt_ctf_field_common_is_set_recursive(
582 structure->fields->pdata[i]);
583 if (!is_set) {
584 goto end;
585 }
586 }
587
588end:
589 return is_set;
590}
591
592BT_HIDDEN
593bt_bool bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common *field)
594{
595 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
596 bt_bool is_set = BT_FALSE;
597
598 BT_ASSERT(field);
599
600 if (variant->current_field) {
601 is_set = bt_ctf_field_common_is_set_recursive(
602 variant->current_field);
603 }
604
605 return is_set;
606}
607
608BT_HIDDEN
609bt_bool bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common *field)
610{
611 size_t i;
612 bt_bool is_set = BT_FALSE;
613 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
614
615 BT_ASSERT(field);
616
617 for (i = 0; i < array->elements->len; i++) {
618 is_set = bt_ctf_field_common_is_set_recursive(array->elements->pdata[i]);
619 if (!is_set) {
620 goto end;
621 }
622 }
623
624end:
625 return is_set;
626}
627
628BT_HIDDEN
629bt_bool bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common *field)
630{
631 size_t i;
632 bt_bool is_set = BT_FALSE;
633 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
634
635 BT_ASSERT(field);
636
637 if (!sequence->elements) {
638 goto end;
639 }
640
641 for (i = 0; i < sequence->elements->len; i++) {
642 is_set = bt_ctf_field_common_is_set_recursive(
643 sequence->elements->pdata[i]);
644 if (!is_set) {
645 goto end;
646 }
647 }
648
649end:
650 return is_set;
651}
652
653static struct bt_ctf_field_common_methods bt_ctf_field_integer_methods = {
654 .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
655 .validate = bt_ctf_field_common_generic_validate,
3dca2276 656 .copy = NULL,
16ca5ff0
PP
657 .is_set = bt_ctf_field_common_generic_is_set,
658 .reset = bt_ctf_field_common_generic_reset,
3dca2276
PP
659};
660
16ca5ff0
PP
661static struct bt_ctf_field_common_methods bt_ctf_field_floating_point_methods = {
662 .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
663 .validate = bt_ctf_field_common_generic_validate,
3dca2276 664 .copy = NULL,
16ca5ff0
PP
665 .is_set = bt_ctf_field_common_generic_is_set,
666 .reset = bt_ctf_field_common_generic_reset,
3dca2276
PP
667};
668
312c056a
PP
669static
670void bt_ctf_field_enumeration_set_is_frozen_recursive(
16ca5ff0 671 struct bt_ctf_field_common *field, bool is_frozen);
312c056a
PP
672
673static
16ca5ff0 674int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common *field);
312c056a
PP
675
676static
677bt_bool bt_ctf_field_enumeration_is_set_recursive(
16ca5ff0 678 struct bt_ctf_field_common *field);
312c056a
PP
679
680static
16ca5ff0 681void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common *field);
312c056a 682
16ca5ff0 683static struct bt_ctf_field_common_methods bt_ctf_field_enumeration_methods = {
312c056a
PP
684 .set_is_frozen = bt_ctf_field_enumeration_set_is_frozen_recursive,
685 .validate = bt_ctf_field_enumeration_validate_recursive,
3dca2276 686 .copy = NULL,
312c056a
PP
687 .is_set = bt_ctf_field_enumeration_is_set_recursive,
688 .reset = bt_ctf_field_enumeration_reset_recursive,
3dca2276
PP
689};
690
16ca5ff0
PP
691static struct bt_ctf_field_common_methods bt_ctf_field_string_methods = {
692 .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
693 .validate = bt_ctf_field_common_generic_validate,
3dca2276 694 .copy = NULL,
16ca5ff0
PP
695 .is_set = bt_ctf_field_common_generic_is_set,
696 .reset = bt_ctf_field_common_generic_reset,
3dca2276
PP
697};
698
16ca5ff0
PP
699static struct bt_ctf_field_common_methods bt_ctf_field_structure_methods = {
700 .set_is_frozen = bt_ctf_field_common_structure_set_is_frozen_recursive,
701 .validate = bt_ctf_field_common_structure_validate_recursive,
3dca2276 702 .copy = NULL,
16ca5ff0
PP
703 .is_set = bt_ctf_field_common_structure_is_set_recursive,
704 .reset = bt_ctf_field_common_structure_reset_recursive,
3dca2276
PP
705};
706
16ca5ff0
PP
707static struct bt_ctf_field_common_methods bt_ctf_field_sequence_methods = {
708 .set_is_frozen = bt_ctf_field_common_sequence_set_is_frozen_recursive,
709 .validate = bt_ctf_field_common_sequence_validate_recursive,
3dca2276 710 .copy = NULL,
16ca5ff0
PP
711 .is_set = bt_ctf_field_common_sequence_is_set_recursive,
712 .reset = bt_ctf_field_common_sequence_reset_recursive,
3dca2276
PP
713};
714
16ca5ff0
PP
715static struct bt_ctf_field_common_methods bt_ctf_field_array_methods = {
716 .set_is_frozen = bt_ctf_field_common_array_set_is_frozen_recursive,
717 .validate = bt_ctf_field_common_array_validate_recursive,
3dca2276 718 .copy = NULL,
16ca5ff0
PP
719 .is_set = bt_ctf_field_common_array_is_set_recursive,
720 .reset = bt_ctf_field_common_array_reset_recursive,
3dca2276
PP
721};
722
312c056a 723static
16ca5ff0 724void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_ctf_field_common *field,
312c056a
PP
725 bool is_frozen);
726
727static
16ca5ff0 728int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common *field);
312c056a
PP
729
730static
16ca5ff0 731bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common *field);
312c056a
PP
732
733static
16ca5ff0 734void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common *field);
312c056a 735
16ca5ff0 736static struct bt_ctf_field_common_methods bt_ctf_field_variant_methods = {
312c056a
PP
737 .set_is_frozen = bt_ctf_field_variant_set_is_frozen_recursive,
738 .validate = bt_ctf_field_variant_validate_recursive,
3dca2276 739 .copy = NULL,
312c056a
PP
740 .is_set = bt_ctf_field_variant_is_set_recursive,
741 .reset = bt_ctf_field_variant_reset_recursive,
3dca2276
PP
742};
743
744static
745struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
746
747static
748struct bt_ctf_field *bt_ctf_field_enumeration_create(struct bt_ctf_field_type *);
749
750static
751struct bt_ctf_field *bt_ctf_field_floating_point_create(struct bt_ctf_field_type *);
752
753static
754struct bt_ctf_field *bt_ctf_field_structure_create(struct bt_ctf_field_type *);
755
756static
757struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *);
758
759static
760struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *);
761
762static
763struct bt_ctf_field *bt_ctf_field_sequence_create(struct bt_ctf_field_type *);
764
765static
766struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
767
768static
769struct bt_ctf_field *(* const field_create_funcs[])(struct bt_ctf_field_type *) = {
16ca5ff0
PP
770 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
771 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
772 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_create,
773 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
774 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
775 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
776 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
777 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_create,
3dca2276
PP
778};
779
780typedef int (*bt_ctf_field_serialize_recursive_func)(
16ca5ff0 781 struct bt_ctf_field_common *, struct bt_ctf_stream_pos *,
3dca2276
PP
782 enum bt_ctf_byte_order);
783
312c056a
PP
784static
785void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
786{
787 BT_LOGD("Destroying CTF writer integer field object: addr=%p", field);
16ca5ff0 788 bt_ctf_field_common_integer_finalize((void *) field);
312c056a
PP
789 g_free(field);
790}
791
792static
793void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
794{
795 BT_LOGD("Destroying CTF writer floating point field object: addr=%p",
796 field);
16ca5ff0 797 bt_ctf_field_common_floating_point_finalize((void *) field);
312c056a
PP
798 g_free(field);
799}
800
801static
802void bt_ctf_field_enumeration_destroy_recursive(struct bt_ctf_field *field)
803{
16ca5ff0 804 struct bt_ctf_field_enumeration *enumeration = BT_CTF_FROM_COMMON(field);
312c056a
PP
805
806 BT_LOGD("Destroying CTF writer enumeration field object: addr=%p",
807 field);
808 BT_LOGD_STR("Putting container field.");
65300d60 809 bt_object_put_ref(enumeration->container);
16ca5ff0 810 bt_ctf_field_common_finalize((void *) field);
312c056a
PP
811 g_free(field);
812}
813
814static
815void bt_ctf_field_structure_destroy_recursive(struct bt_ctf_field *field)
816{
817 BT_LOGD("Destroying CTF writer structure field object: addr=%p", field);
16ca5ff0 818 bt_ctf_field_common_structure_finalize_recursive((void *) field);
312c056a
PP
819 g_free(field);
820}
821
822static
823void bt_ctf_field_variant_destroy_recursive(struct bt_ctf_field *field)
824{
16ca5ff0 825 struct bt_ctf_field_variant *variant = BT_CTF_FROM_COMMON(field);
312c056a
PP
826
827 BT_LOGD("Destroying CTF writer variant field object: addr=%p", field);
828 BT_LOGD_STR("Putting tag field.");
65300d60 829 bt_object_put_ref(variant->tag);
16ca5ff0 830 bt_ctf_field_common_variant_finalize_recursive((void *) field);
312c056a
PP
831 g_free(field);
832}
833
834static
835void bt_ctf_field_array_destroy_recursive(struct bt_ctf_field *field)
836{
837 BT_LOGD("Destroying CTF writer array field object: addr=%p", field);
16ca5ff0 838 bt_ctf_field_common_array_finalize_recursive((void *) field);
312c056a
PP
839 g_free(field);
840}
841
842static
843void bt_ctf_field_sequence_destroy_recursive(struct bt_ctf_field *field)
844{
845 BT_LOGD("Destroying CTF writer sequence field object: addr=%p", field);
16ca5ff0 846 bt_ctf_field_common_sequence_finalize_recursive((void *) field);
312c056a
PP
847 g_free(field);
848}
849
850static
851void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
852{
853 BT_LOGD("Destroying CTF writer string field object: addr=%p", field);
16ca5ff0 854 bt_ctf_field_common_string_finalize((void *) field);
312c056a
PP
855 g_free(field);
856}
857
3dca2276
PP
858BT_HIDDEN
859int bt_ctf_field_serialize_recursive(struct bt_ctf_field *field,
860 struct bt_ctf_stream_pos *pos,
861 enum bt_ctf_byte_order native_byte_order)
862{
16ca5ff0 863 struct bt_ctf_field_common *field_common = (void *) field;
3dca2276
PP
864 bt_ctf_field_serialize_recursive_func serialize_func;
865
866 BT_ASSERT(pos);
867 BT_ASSERT_PRE_NON_NULL(field, "Field");
868 BT_ASSERT(field_common->spec.writer.serialize_func);
869 serialize_func = field_common->spec.writer.serialize_func;
870 return serialize_func(field_common, pos,
871 native_byte_order);
872}
873
874static
875int increase_packet_size(struct bt_ctf_stream_pos *pos)
876{
877 int ret;
878
879 BT_ASSERT(pos);
880 BT_LOGV("Increasing packet size: pos-offset=%" PRId64 ", "
881 "cur-packet-size=%" PRIu64,
882 pos->offset, pos->packet_size);
883 ret = munmap_align(pos->base_mma);
884 if (ret) {
885 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
886 ": ret=%d", ret);
887 goto end;
888 }
889
890 pos->packet_size += PACKET_LEN_INCREMENT;
891 do {
892 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
893 pos->packet_size / CHAR_BIT);
894 } while (ret == EINTR);
895 if (ret) {
896 BT_LOGE_ERRNO("Failed to preallocate memory space",
897 ": ret=%d", ret);
898 errno = EINTR;
899 ret = -1;
900 goto end;
901 }
902
903 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
904 pos->flags, pos->fd, pos->mmap_offset);
905 if (pos->base_mma == MAP_FAILED) {
906 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
907 ": ret=%d", ret);
908 ret = -1;
909 }
910
911 BT_LOGV("Increased packet size: pos-offset=%" PRId64 ", "
912 "new-packet-size=%" PRIu64,
913 pos->offset, pos->packet_size);
914 BT_ASSERT(pos->packet_size % 8 == 0);
915
916end:
917 return ret;
918}
919
920static
16ca5ff0 921int bt_ctf_field_integer_serialize(struct bt_ctf_field_common *field,
3dca2276
PP
922 struct bt_ctf_stream_pos *pos,
923 enum bt_ctf_byte_order native_byte_order)
924{
925 int ret = 0;
926
16ca5ff0 927 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "Integer field");
3dca2276
PP
928 BT_LOGV("Serializing CTF writer integer field: addr=%p, pos-offset=%" PRId64 ", "
929 "native-bo=%s", field, pos->offset,
16ca5ff0 930 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
931
932retry:
933 ret = bt_ctf_field_integer_write(field, pos, native_byte_order);
934 if (ret == -EFAULT) {
935 /*
936 * The field is too large to fit in the current packet's
937 * remaining space. Bump the packet size and retry.
938 */
939 ret = increase_packet_size(pos);
940 if (ret) {
941 BT_LOGE("Cannot increase packet size: ret=%d", ret);
942 goto end;
943 }
944 goto retry;
945 }
946
947end:
948 return ret;
949}
950
951static
16ca5ff0 952int bt_ctf_field_enumeration_serialize_recursive(struct bt_ctf_field_common *field,
3dca2276
PP
953 struct bt_ctf_stream_pos *pos,
954 enum bt_ctf_byte_order native_byte_order)
955{
312c056a 956 struct bt_ctf_field_enumeration *enumeration = (void *) field;
3dca2276
PP
957
958 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64 ", "
959 "native-bo=%s", field, pos->offset,
16ca5ff0 960 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276 961 BT_LOGV_STR("Serializing enumeration field's payload field.");
312c056a
PP
962 return bt_ctf_field_serialize_recursive(
963 (void *) enumeration->container, pos, native_byte_order);
3dca2276
PP
964}
965
966static
16ca5ff0 967int bt_ctf_field_floating_point_serialize(struct bt_ctf_field_common *field,
3dca2276
PP
968 struct bt_ctf_stream_pos *pos,
969 enum bt_ctf_byte_order native_byte_order)
970{
971 int ret = 0;
972
16ca5ff0 973 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "Floating point number field");
3dca2276
PP
974 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64 ", "
975 "native-bo=%s", field, pos->offset,
16ca5ff0 976 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
977
978retry:
979 ret = bt_ctf_field_floating_point_write(field, pos,
980 native_byte_order);
981 if (ret == -EFAULT) {
982 /*
983 * The field is too large to fit in the current packet's
984 * remaining space. Bump the packet size and retry.
985 */
986 ret = increase_packet_size(pos);
987 if (ret) {
988 BT_LOGE("Cannot increase packet size: ret=%d", ret);
989 goto end;
990 }
991 goto retry;
992 }
993
994end:
995 return ret;
996}
997
998static
16ca5ff0 999int bt_ctf_field_structure_serialize_recursive(struct bt_ctf_field_common *field,
3dca2276
PP
1000 struct bt_ctf_stream_pos *pos,
1001 enum bt_ctf_byte_order native_byte_order)
1002{
1003 int64_t i;
1004 int ret = 0;
16ca5ff0 1005 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
3dca2276
PP
1006
1007 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64 ", "
1008 "native-bo=%s", field, pos->offset,
16ca5ff0 1009 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
1010
1011 while (!bt_ctf_stream_pos_access_ok(pos,
1012 offset_align(pos->offset, field->type->alignment))) {
1013 ret = increase_packet_size(pos);
1014 if (ret) {
1015 BT_LOGE("Cannot increase packet size: ret=%d", ret);
1016 goto end;
1017 }
1018 }
1019
1020 if (!bt_ctf_stream_pos_align(pos, field->type->alignment)) {
1021 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64 ", "
1022 "align=%u", pos->offset, field->type->alignment);
1023 ret = -1;
1024 goto end;
1025 }
1026
1027 for (i = 0; i < structure->fields->len; i++) {
16ca5ff0 1028 struct bt_ctf_field_common *member = g_ptr_array_index(
3dca2276
PP
1029 structure->fields, i);
1030 const char *field_name = NULL;
1031
1032 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64 ", "
1033 "field-addr=%p, index=%" PRId64,
1034 pos->offset, member, i);
1035
1036 if (!member) {
16ca5ff0 1037 ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
3dca2276
PP
1038 field->type, &field_name, NULL, i);
1039 BT_ASSERT(ret == 0);
1040 BT_LOGW("Cannot serialize structure field's field: field is not set: "
1041 "struct-field-addr=%p, "
1042 "field-name=\"%s\", index=%" PRId64,
1043 field, field_name, i);
1044 ret = -1;
1045 goto end;
1046 }
1047
1048 ret = bt_ctf_field_serialize_recursive((void *) member, pos,
1049 native_byte_order);
1050 if (ret) {
16ca5ff0 1051 ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
3dca2276
PP
1052 field->type, &field_name, NULL, i);
1053 BT_ASSERT(ret == 0);
1054 BT_LOGW("Cannot serialize structure field's field: "
1055 "struct-field-addr=%p, field-addr=%p, "
1056 "field-name=\"%s\", index=%" PRId64,
1057 field->type, member, field_name, i);
1058 break;
1059 }
1060 }
1061
1062end:
1063 return ret;
1064}
1065
1066static
16ca5ff0 1067int bt_ctf_field_variant_serialize_recursive(struct bt_ctf_field_common *field,
3dca2276
PP
1068 struct bt_ctf_stream_pos *pos,
1069 enum bt_ctf_byte_order native_byte_order)
1070{
16ca5ff0 1071 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
3dca2276
PP
1072
1073 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64 ", "
1074 "native-bo=%s", field, pos->offset,
16ca5ff0 1075 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
1076 BT_LOGV_STR("Serializing variant field's payload field.");
1077 return bt_ctf_field_serialize_recursive(
312c056a 1078 (void *) variant->current_field, pos, native_byte_order);
3dca2276
PP
1079}
1080
1081static
16ca5ff0 1082int bt_ctf_field_array_serialize_recursive(struct bt_ctf_field_common *field,
3dca2276
PP
1083 struct bt_ctf_stream_pos *pos,
1084 enum bt_ctf_byte_order native_byte_order)
1085{
1086 int64_t i;
1087 int ret = 0;
16ca5ff0 1088 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
3dca2276
PP
1089
1090 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64 ", "
1091 "native-bo=%s", field, pos->offset,
16ca5ff0 1092 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
1093
1094 for (i = 0; i < array->elements->len; i++) {
16ca5ff0 1095 struct bt_ctf_field_common *elem_field =
3dca2276
PP
1096 g_ptr_array_index(array->elements, i);
1097
1098 BT_LOGV("Serializing array field's element field: "
1099 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
1100 pos->offset, elem_field, i);
1101 ret = bt_ctf_field_serialize_recursive(
1102 (void *) elem_field, pos, native_byte_order);
1103 if (ret) {
1104 BT_LOGW("Cannot serialize array field's element field: "
1105 "array-field-addr=%p, field-addr=%p, "
1106 "index=%" PRId64, field, elem_field, i);
1107 goto end;
1108 }
1109 }
1110
1111end:
1112 return ret;
1113}
1114
1115static
16ca5ff0 1116int bt_ctf_field_sequence_serialize_recursive(struct bt_ctf_field_common *field,
3dca2276
PP
1117 struct bt_ctf_stream_pos *pos,
1118 enum bt_ctf_byte_order native_byte_order)
1119{
1120 int64_t i;
1121 int ret = 0;
16ca5ff0 1122 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
3dca2276
PP
1123
1124 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64 ", "
1125 "native-bo=%s", field, pos->offset,
16ca5ff0 1126 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
1127
1128 for (i = 0; i < sequence->elements->len; i++) {
16ca5ff0 1129 struct bt_ctf_field_common *elem_field =
3dca2276
PP
1130 g_ptr_array_index(sequence->elements, i);
1131
1132 BT_LOGV("Serializing sequence field's element field: "
1133 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
1134 pos->offset, elem_field, i);
1135 ret = bt_ctf_field_serialize_recursive(
1136 (void *) elem_field, pos, native_byte_order);
1137 if (ret) {
1138 BT_LOGW("Cannot serialize sequence field's element field: "
1139 "sequence-field-addr=%p, field-addr=%p, "
1140 "index=%" PRId64, field, elem_field, i);
1141 goto end;
1142 }
1143 }
1144
1145end:
1146 return ret;
1147}
1148
1149static
16ca5ff0 1150int bt_ctf_field_string_serialize(struct bt_ctf_field_common *field,
3dca2276
PP
1151 struct bt_ctf_stream_pos *pos,
1152 enum bt_ctf_byte_order native_byte_order)
1153{
1154 int64_t i;
1155 int ret = 0;
16ca5ff0 1156 struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
3dca2276
PP
1157 struct bt_ctf_field_type *character_type =
1158 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
1159 struct bt_ctf_field *character;
1160
16ca5ff0 1161 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "String field");
3dca2276
PP
1162 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64 ", "
1163 "native-bo=%s", field, pos->offset,
16ca5ff0 1164 bt_ctf_byte_order_string((int) native_byte_order));
3dca2276
PP
1165
1166 BT_LOGV_STR("Creating character field from string field's character field type.");
1167 character = bt_ctf_field_create(character_type);
1168
4d4b475d
PP
1169 for (i = 0; i < string->size + 1; i++) {
1170 const uint64_t chr = (uint64_t) ((char *) string->buf->data)[i];
3dca2276
PP
1171
1172 ret = bt_ctf_field_integer_unsigned_set_value(character, chr);
1173 BT_ASSERT(ret == 0);
1174 BT_LOGV("Serializing string field's character field: "
1175 "pos-offset=%" PRId64 ", field-addr=%p, "
1176 "index=%" PRId64 ", char-int=%" PRIu64,
1177 pos->offset, character, i, chr);
1178 ret = bt_ctf_field_integer_serialize(
1179 (void *) character, pos, native_byte_order);
1180 if (ret) {
1181 BT_LOGW_STR("Cannot serialize character field.");
1182 goto end;
1183 }
1184 }
1185
1186end:
65300d60
PP
1187 bt_object_put_ref(character);
1188 bt_object_put_ref(character_type);
3dca2276
PP
1189 return ret;
1190}
1191
1192struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
1193{
1194 struct bt_ctf_field *field = NULL;
1195 enum bt_ctf_field_type_id type_id;
1196
1197 BT_ASSERT_PRE_NON_NULL(type, "Field type");
1198 BT_ASSERT(field_type_common_has_known_id((void *) type));
16ca5ff0
PP
1199 BT_ASSERT_PRE(bt_ctf_field_type_common_validate((void *) type) == 0,
1200 "Field type is invalid: ft-addr=%p", type);
3dca2276
PP
1201 type_id = bt_ctf_field_type_get_type_id(type);
1202 field = field_create_funcs[type_id](type);
1203 if (!field) {
1204 goto end;
1205 }
1206
16ca5ff0 1207 bt_ctf_field_type_common_freeze((void *) type);
3dca2276
PP
1208
1209end:
1210 return field;
1211}
1212
1213struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
1214{
65300d60 1215 return bt_object_get_ref(bt_ctf_field_common_borrow_type((void *) field));
3dca2276
PP
1216}
1217
1218enum bt_ctf_field_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
1219{
16ca5ff0 1220 struct bt_ctf_field_common *field_common = (void *) field;
3dca2276
PP
1221
1222 BT_ASSERT_PRE_NON_NULL(field, "Field");
1223 return (int) field_common->type->id;
1224}
1225
3dca2276
PP
1226int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
1227 struct bt_ctf_field *length_field)
1228{
312c056a 1229 int ret;
16ca5ff0 1230 struct bt_ctf_field_common *common_length_field = (void *) length_field;
312c056a
PP
1231 uint64_t length;
1232
1233 BT_ASSERT_PRE_NON_NULL(length_field, "Length field");
16ca5ff0
PP
1234 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) length_field, "Length field");
1235 BT_ASSERT_PRE(common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER ||
1236 common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_ENUM,
1237 "Length field must be an integer or enumeration field: field-addr=%p",
312c056a
PP
1238 length_field);
1239
16ca5ff0 1240 if (common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_ENUM) {
312c056a
PP
1241 struct bt_ctf_field_enumeration *enumeration = (void *)
1242 length_field;
1243
1244 length_field = (void *) enumeration->container;
1245 }
1246
1247 ret = bt_ctf_field_integer_unsigned_get_value(length_field, &length);
1248 BT_ASSERT(ret == 0);
16ca5ff0
PP
1249 return bt_ctf_field_common_sequence_set_length((void *) field,
1250 length, (bt_ctf_field_common_create_func) bt_ctf_field_create);
3dca2276
PP
1251}
1252
1253struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
1254 struct bt_ctf_field *field, uint64_t index)
1255{
65300d60 1256 return bt_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_index(
094ff7c0 1257 (void *) field, index));
3dca2276
PP
1258}
1259
1260struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
1261 struct bt_ctf_field *field, const char *name)
1262{
65300d60 1263 return bt_object_get_ref(bt_ctf_field_common_structure_borrow_field_by_name(
094ff7c0 1264 (void *) field, name));
3dca2276
PP
1265}
1266
3dca2276
PP
1267struct bt_ctf_field *bt_ctf_field_array_get_field(
1268 struct bt_ctf_field *field, uint64_t index)
1269{
65300d60 1270 return bt_object_get_ref(
16ca5ff0 1271 bt_ctf_field_common_array_borrow_field((void *) field, index));
3dca2276
PP
1272}
1273
1274struct bt_ctf_field *bt_ctf_field_sequence_get_field(
1275 struct bt_ctf_field *field, uint64_t index)
1276{
65300d60 1277 return bt_object_get_ref(
16ca5ff0 1278 bt_ctf_field_common_sequence_borrow_field((void *) field, index));
3dca2276
PP
1279}
1280
1281struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
1282 struct bt_ctf_field *tag_field)
1283{
312c056a
PP
1284 struct bt_ctf_field_variant *variant_field = (void *) field;
1285 struct bt_ctf_field_enumeration *enum_field = (void *) tag_field;
16ca5ff0
PP
1286 struct bt_ctf_field_type_common_variant *variant_ft;
1287 struct bt_ctf_field_type_common_enumeration *tag_ft;
312c056a
PP
1288 struct bt_ctf_field *current_field = NULL;
1289 bt_bool is_signed;
1290 uint64_t tag_uval;
1291 int ret;
1292
1293 BT_ASSERT_PRE_NON_NULL(field, "Variant field");
1294 BT_ASSERT_PRE_NON_NULL(tag_field, "Tag field");
16ca5ff0
PP
1295 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) tag_field, "Tag field");
1296 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1297 (struct bt_ctf_field_common *) tag_field,
1298 BT_CTF_FIELD_TYPE_ID_ENUM, "Tag field");
1299 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
1300 (struct bt_ctf_field_common *) field,
1301 BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
312c056a 1302 BT_ASSERT_PRE(
16ca5ff0
PP
1303 bt_ctf_field_common_validate_recursive((void *) tag_field) == 0,
1304 "Tag field is invalid: field-addr=%p", tag_field);
1305 variant_ft = BT_CTF_FROM_COMMON(variant_field->common.common.type);
1306 BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
1307 BT_CTF_TO_COMMON(variant_ft->tag_ft), enum_field->common.type) == 0,
1308 "Unexpected tag field's type: expected-ft-addr=%p, "
1309 "tag-ft-addr=%p", variant_ft->tag_ft,
312c056a 1310 enum_field->common.type);
16ca5ff0 1311 tag_ft = BT_CTF_FROM_COMMON(enum_field->common.type);
312c056a
PP
1312 is_signed = tag_ft->container_ft->is_signed;
1313
1314 if (is_signed) {
1315 int64_t tag_ival;
1316
1317 ret = bt_ctf_field_integer_signed_get_value(
1318 (void *) enum_field->container, &tag_ival);
1319 tag_uval = (uint64_t) tag_ival;
1320 } else {
1321 ret = bt_ctf_field_integer_unsigned_get_value(
1322 (void *) enum_field->container, &tag_uval);
1323 }
1324
1325 BT_ASSERT(ret == 0);
16ca5ff0 1326 ret = bt_ctf_field_common_variant_set_tag((void *) field, tag_uval,
312c056a
PP
1327 is_signed);
1328 if (ret) {
1329 goto end;
1330 }
1331
65300d60
PP
1332 bt_object_put_ref(variant_field->tag);
1333 variant_field->tag = bt_object_get_ref(tag_field);
312c056a
PP
1334 current_field = bt_ctf_field_variant_get_current_field(field);
1335 BT_ASSERT(current_field);
1336
1337end:
1338 return current_field;
3dca2276
PP
1339}
1340
1341struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
1342 struct bt_ctf_field *variant_field)
1343{
65300d60 1344 return bt_object_get_ref(bt_ctf_field_common_variant_borrow_current_field(
094ff7c0 1345 (void *) variant_field));
3dca2276
PP
1346}
1347
312c056a
PP
1348BT_HIDDEN
1349struct bt_ctf_field *bt_ctf_field_enumeration_borrow_container(
1350 struct bt_ctf_field *field)
3dca2276 1351{
312c056a
PP
1352 struct bt_ctf_field_enumeration *enumeration = (void *) field;
1353
1354 BT_ASSERT_PRE_NON_NULL(field, "Enumeration field");
16ca5ff0 1355 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID((struct bt_ctf_field_common *) field,
312c056a
PP
1356 BT_CTF_FIELD_TYPE_ID_ENUM, "Field");
1357 BT_ASSERT(enumeration->container);
1358 return (void *) enumeration->container;
3dca2276
PP
1359}
1360
312c056a
PP
1361struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
1362 struct bt_ctf_field *field)
3dca2276 1363{
65300d60 1364 return bt_object_get_ref(bt_ctf_field_enumeration_borrow_container(field));
3dca2276
PP
1365}
1366
312c056a
PP
1367int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field *field,
1368 int64_t *value)
3dca2276 1369{
16ca5ff0 1370 struct bt_ctf_field_common_integer *integer = (void *) field;
312c056a
PP
1371
1372 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
1373 BT_ASSERT_PRE_NON_NULL(value, "Value");
16ca5ff0
PP
1374 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer), "Integer field");
1375 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
1376 BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
1377 BT_ASSERT_PRE(bt_ctf_field_type_common_integer_is_signed(
312c056a 1378 integer->common.type),
16ca5ff0 1379 "Field's type is unsigned: field-addr=%p", field);
312c056a
PP
1380 *value = integer->payload.signd;
1381 return 0;
3dca2276
PP
1382}
1383
1384int bt_ctf_field_integer_signed_set_value(struct bt_ctf_field *field,
1385 int64_t value)
1386{
312c056a 1387 int ret = 0;
16ca5ff0
PP
1388 struct bt_ctf_field_common_integer *integer = (void *) field;
1389 struct bt_ctf_field_type_common_integer *integer_type;
312c056a
PP
1390
1391 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
16ca5ff0
PP
1392 BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer), "Integer field");
1393 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
1394 BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
1395 integer_type = BT_CTF_FROM_COMMON(integer->common.type);
312c056a 1396 BT_ASSERT_PRE(
16ca5ff0
PP
1397 bt_ctf_field_type_common_integer_is_signed(integer->common.type),
1398 "Field's type is unsigned: field-addr=%p", field);
312c056a 1399 BT_ASSERT_PRE(value_is_in_range_signed(integer_type->size, value),
16ca5ff0 1400 "Value is out of bounds: value=%" PRId64 ", field-addr=%p",
312c056a
PP
1401 value, field);
1402 integer->payload.signd = value;
16ca5ff0 1403 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer), true);
312c056a 1404 return ret;
3dca2276
PP
1405}
1406
1407int bt_ctf_field_integer_unsigned_get_value(struct bt_ctf_field *field,
1408 uint64_t *value)
1409{
16ca5ff0 1410 struct bt_ctf_field_common_integer *integer = (void *) field;
312c056a
PP
1411
1412 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
1413 BT_ASSERT_PRE_NON_NULL(value, "Value");
16ca5ff0
PP
1414 BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer), "Integer field");
1415 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
1416 BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
312c056a 1417 BT_ASSERT_PRE(
16ca5ff0
PP
1418 !bt_ctf_field_type_common_integer_is_signed(integer->common.type),
1419 "Field's type is signed: field-addr=%p", field);
312c056a
PP
1420 *value = integer->payload.unsignd;
1421 return 0;
3dca2276
PP
1422}
1423
312c056a
PP
1424int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field *field,
1425 uint64_t value)
3dca2276 1426{
16ca5ff0
PP
1427 struct bt_ctf_field_common_integer *integer = (void *) field;
1428 struct bt_ctf_field_type_common_integer *integer_type;
312c056a
PP
1429
1430 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
16ca5ff0
PP
1431 BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer), "Integer field");
1432 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
1433 BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
1434 integer_type = BT_CTF_FROM_COMMON(integer->common.type);
312c056a 1435 BT_ASSERT_PRE(
16ca5ff0
PP
1436 !bt_ctf_field_type_common_integer_is_signed(integer->common.type),
1437 "Field's type is signed: field-addr=%p", field);
312c056a 1438 BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type->size, value),
16ca5ff0 1439 "Value is out of bounds: value=%" PRIu64 ", field-addr=%p",
312c056a
PP
1440 value, field);
1441 integer->payload.unsignd = value;
16ca5ff0 1442 bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer), true);
312c056a 1443 return 0;
3dca2276
PP
1444}
1445
1446int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1447 double *value)
1448{
16ca5ff0 1449 return bt_ctf_field_common_floating_point_get_value((void *) field, value);
3dca2276
PP
1450}
1451
1452int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1453 double value)
1454{
16ca5ff0 1455 return bt_ctf_field_common_floating_point_set_value((void *) field, value);
3dca2276
PP
1456}
1457
1458const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1459{
16ca5ff0 1460 return bt_ctf_field_common_string_get_value((void *) field);
3dca2276
PP
1461}
1462
1463int bt_ctf_field_string_set_value(struct bt_ctf_field *field, const char *value)
1464{
16ca5ff0 1465 return bt_ctf_field_common_string_set_value((void *) field, value);
3dca2276
PP
1466}
1467
1468int bt_ctf_field_string_append(struct bt_ctf_field *field, const char *value)
1469{
16ca5ff0 1470 return bt_ctf_field_common_string_append((void *) field, value);
3dca2276
PP
1471}
1472
1473int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1474 const char *value, unsigned int length)
1475{
16ca5ff0 1476 return bt_ctf_field_common_string_append_len((void *) field, value, length);
3dca2276
PP
1477}
1478
1479struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1480{
16ca5ff0 1481 return (void *) bt_ctf_field_common_copy((void *) field);
3dca2276
PP
1482}
1483
1484static
1485struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1486{
16ca5ff0
PP
1487 struct bt_ctf_field_common_integer *integer =
1488 g_new0(struct bt_ctf_field_common_integer, 1);
3dca2276
PP
1489
1490 BT_LOGD("Creating CTF writer integer field object: ft-addr=%p", type);
1491
1492 if (integer) {
16ca5ff0 1493 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(integer), (void *) type,
3fea54f6 1494 true,
312c056a 1495 (bt_object_release_func) bt_ctf_field_integer_destroy,
3dca2276
PP
1496 &bt_ctf_field_integer_methods);
1497 integer->common.spec.writer.serialize_func =
1498 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_integer_serialize;
1499 BT_LOGD("Created CTF writer integer field object: addr=%p, ft-addr=%p",
1500 integer, type);
1501 } else {
1502 BT_LOGE_STR("Failed to allocate one integer field.");
1503 }
1504
1505 return (void *) integer;
1506}
1507
1508static
1509struct bt_ctf_field *bt_ctf_field_enumeration_create(
1510 struct bt_ctf_field_type *type)
1511{
16ca5ff0 1512 struct bt_ctf_field_type_common_enumeration *enum_ft = (void *) type;
312c056a
PP
1513 struct bt_ctf_field_enumeration *enumeration = g_new0(
1514 struct bt_ctf_field_enumeration, 1);
3dca2276
PP
1515
1516 BT_LOGD("Creating CTF writer enumeration field object: ft-addr=%p", type);
1517
312c056a 1518 if (!enumeration) {
3dca2276 1519 BT_LOGE_STR("Failed to allocate one enumeration field.");
312c056a 1520 goto end;
3dca2276
PP
1521 }
1522
16ca5ff0 1523 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(enumeration),
312c056a 1524 (void *) type,
3fea54f6 1525 true, (bt_object_release_func)
312c056a
PP
1526 bt_ctf_field_enumeration_destroy_recursive,
1527 &bt_ctf_field_enumeration_methods);
1528 enumeration->container = (void *) bt_ctf_field_create(
16ca5ff0 1529 BT_CTF_FROM_COMMON(enum_ft->container_ft));
312c056a 1530 if (!enumeration->container) {
65300d60 1531 BT_OBJECT_PUT_REF_AND_RESET(enumeration);
312c056a
PP
1532 goto end;
1533 }
1534
1535 enumeration->common.spec.writer.serialize_func =
1536 (bt_ctf_field_serialize_recursive_func)
1537 bt_ctf_field_enumeration_serialize_recursive;
1538 BT_LOGD("Created CTF writer enumeration field object: addr=%p, ft-addr=%p",
1539 enumeration, type);
1540
1541end:
3dca2276
PP
1542 return (void *) enumeration;
1543}
1544
1545static
1546struct bt_ctf_field *bt_ctf_field_floating_point_create(
1547 struct bt_ctf_field_type *type)
1548{
16ca5ff0 1549 struct bt_ctf_field_common_floating_point *floating_point;
3dca2276
PP
1550
1551 BT_LOGD("Creating CTF writer floating point number field object: ft-addr=%p", type);
16ca5ff0 1552 floating_point = g_new0(struct bt_ctf_field_common_floating_point, 1);
3dca2276
PP
1553
1554 if (floating_point) {
16ca5ff0 1555 bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(floating_point),
3dca2276 1556 (void *) type,
3fea54f6 1557 true, (bt_object_release_func)
312c056a 1558 bt_ctf_field_floating_point_destroy,
3dca2276
PP
1559 &bt_ctf_field_floating_point_methods);
1560 floating_point->common.spec.writer.serialize_func =
1561 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_floating_point_serialize;
1562 BT_LOGD("Created CTF writer floating point number field object: addr=%p, ft-addr=%p",
1563 floating_point, type);
1564 } else {
1565 BT_LOGE_STR("Failed to allocate one floating point number field.");
1566 }
1567
1568 return (void *) floating_point;
1569}
1570
1571static
1572struct bt_ctf_field *bt_ctf_field_structure_create(
1573 struct bt_ctf_field_type *type)
1574{
16ca5ff0
PP
1575 struct bt_ctf_field_common_structure *structure = g_new0(
1576 struct bt_ctf_field_common_structure, 1);
3dca2276
PP
1577 int iret;
1578
1579 BT_LOGD("Creating CTF writer structure field object: ft-addr=%p", type);
1580
1581 if (!structure) {
1582 BT_LOGE_STR("Failed to allocate one structure field.");
1583 goto end;
1584 }
1585
16ca5ff0 1586 iret = bt_ctf_field_common_structure_initialize(BT_CTF_TO_COMMON(structure),
312c056a 1587 (void *) type,
3fea54f6 1588 true, (bt_object_release_func)
312c056a 1589 bt_ctf_field_structure_destroy_recursive,
3dca2276 1590 &bt_ctf_field_structure_methods,
16ca5ff0 1591 (bt_ctf_field_common_create_func) bt_ctf_field_create,
65300d60 1592 (GDestroyNotify) bt_object_put_ref);
3dca2276
PP
1593 structure->common.spec.writer.serialize_func =
1594 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_structure_serialize_recursive;
1595 if (iret) {
65300d60 1596 BT_OBJECT_PUT_REF_AND_RESET(structure);
3dca2276
PP
1597 goto end;
1598 }
1599
1600 BT_LOGD("Created CTF writer structure field object: addr=%p, ft-addr=%p",
1601 structure, type);
1602
1603end:
1604 return (void *) structure;
1605}
1606
1607static
1608struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1609{
16ca5ff0 1610 struct bt_ctf_field_type_common_variant *var_ft = (void *) type;
312c056a
PP
1611 struct bt_ctf_field_variant *variant = g_new0(
1612 struct bt_ctf_field_variant, 1);
3dca2276
PP
1613
1614 BT_LOGD("Creating CTF writer variant field object: ft-addr=%p", type);
1615
312c056a 1616 if (!variant) {
3dca2276 1617 BT_LOGE_STR("Failed to allocate one variant field.");
312c056a 1618 goto end;
3dca2276
PP
1619 }
1620
16ca5ff0 1621 bt_ctf_field_common_variant_initialize(BT_CTF_TO_COMMON(BT_CTF_TO_COMMON(variant)),
312c056a 1622 (void *) type,
3fea54f6 1623 true, (bt_object_release_func)
312c056a
PP
1624 bt_ctf_field_variant_destroy_recursive,
1625 &bt_ctf_field_variant_methods,
16ca5ff0 1626 (bt_ctf_field_common_create_func) bt_ctf_field_create,
65300d60 1627 (GDestroyNotify) bt_object_put_ref);
312c056a 1628 variant->tag = (void *) bt_ctf_field_create(
16ca5ff0 1629 BT_CTF_FROM_COMMON(var_ft->tag_ft));
312c056a
PP
1630 variant->common.common.spec.writer.serialize_func =
1631 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_variant_serialize_recursive;
1632 BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p",
1633 variant, type);
1634
1635end:
3dca2276
PP
1636 return (void *) variant;
1637}
1638
1639static
1640struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1641{
16ca5ff0
PP
1642 struct bt_ctf_field_common_array *array =
1643 g_new0(struct bt_ctf_field_common_array, 1);
3dca2276
PP
1644 int ret;
1645
1646 BT_LOGD("Creating CTF writer array field object: ft-addr=%p", type);
1647 BT_ASSERT(type);
1648
1649 if (!array) {
1650 BT_LOGE_STR("Failed to allocate one array field.");
1651 goto end;
1652 }
1653
16ca5ff0 1654 ret = bt_ctf_field_common_array_initialize(BT_CTF_TO_COMMON(array),
3dca2276 1655 (void *) type,
3fea54f6 1656 true, (bt_object_release_func)
312c056a
PP
1657 bt_ctf_field_array_destroy_recursive,
1658 &bt_ctf_field_array_methods,
16ca5ff0 1659 (bt_ctf_field_common_create_func) bt_ctf_field_create,
65300d60 1660 (GDestroyNotify) bt_object_put_ref);
3dca2276
PP
1661 array->common.spec.writer.serialize_func =
1662 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_array_serialize_recursive;
1663 if (ret) {
65300d60 1664 BT_OBJECT_PUT_REF_AND_RESET(array);
3dca2276
PP
1665 goto end;
1666 }
1667
1668 BT_LOGD("Created CTF writer array field object: addr=%p, ft-addr=%p",
1669 array, type);
1670
1671end:
1672 return (void *) array;
1673}
1674
1675static
1676struct bt_ctf_field *bt_ctf_field_sequence_create(struct bt_ctf_field_type *type)
1677{
16ca5ff0
PP
1678 struct bt_ctf_field_common_sequence *sequence = g_new0(
1679 struct bt_ctf_field_common_sequence, 1);
3dca2276
PP
1680
1681 BT_LOGD("Creating CTF writer sequence field object: ft-addr=%p", type);
1682
1683 if (sequence) {
16ca5ff0 1684 bt_ctf_field_common_sequence_initialize(BT_CTF_TO_COMMON(sequence),
3dca2276 1685 (void *) type,
3fea54f6 1686 true, (bt_object_release_func)
312c056a
PP
1687 bt_ctf_field_sequence_destroy_recursive,
1688 &bt_ctf_field_sequence_methods,
65300d60 1689 (GDestroyNotify) bt_object_put_ref);
3dca2276
PP
1690 sequence->common.spec.writer.serialize_func =
1691 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_sequence_serialize_recursive;
1692 BT_LOGD("Created CTF writer sequence field object: addr=%p, ft-addr=%p",
1693 sequence, type);
1694 } else {
1695 BT_LOGE_STR("Failed to allocate one sequence field.");
1696 }
1697
1698 return (void *) sequence;
1699}
1700
1701static
1702struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1703{
16ca5ff0
PP
1704 struct bt_ctf_field_common_string *string = g_new0(
1705 struct bt_ctf_field_common_string, 1);
3dca2276
PP
1706
1707 BT_LOGD("Creating CTF writer string field object: ft-addr=%p", type);
1708
1709 if (string) {
16ca5ff0 1710 bt_ctf_field_common_string_initialize(BT_CTF_TO_COMMON(string),
3dca2276 1711 (void *) type,
3fea54f6 1712 true, (bt_object_release_func)
312c056a 1713 bt_ctf_field_string_destroy,
3dca2276
PP
1714 &bt_ctf_field_string_methods);
1715 string->common.spec.writer.serialize_func =
1716 (bt_ctf_field_serialize_recursive_func) bt_ctf_field_string_serialize;
1717 BT_LOGD("Created CTF writer string field object: addr=%p, ft-addr=%p",
1718 string, type);
1719 } else {
1720 BT_LOGE_STR("Failed to allocate one string field.");
1721 }
1722
1723 return (void *) string;
1724}
312c056a
PP
1725
1726static
1727void bt_ctf_field_enumeration_set_is_frozen_recursive(
16ca5ff0 1728 struct bt_ctf_field_common *field, bool is_frozen)
312c056a
PP
1729{
1730 struct bt_ctf_field_enumeration *enumeration = (void *) field;
1731
1732 if (enumeration->container) {
16ca5ff0 1733 bt_ctf_field_common_set_is_frozen_recursive(
312c056a
PP
1734 (void *) enumeration->container, is_frozen);
1735 }
1736
16ca5ff0 1737 bt_ctf_field_common_generic_set_is_frozen((void *) field, is_frozen);
312c056a
PP
1738}
1739
1740static
16ca5ff0 1741int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common *field)
312c056a
PP
1742{
1743 int ret = -1;
1744 struct bt_ctf_field_enumeration *enumeration = (void *) field;
1745
1746 if (enumeration->container) {
16ca5ff0 1747 ret = bt_ctf_field_common_validate_recursive(
312c056a
PP
1748 (void *) enumeration->container);
1749 }
1750
1751 return ret;
1752}
1753
1754static
16ca5ff0 1755bt_bool bt_ctf_field_enumeration_is_set_recursive(struct bt_ctf_field_common *field)
312c056a
PP
1756{
1757 bt_bool is_set = BT_FALSE;
1758 struct bt_ctf_field_enumeration *enumeration = (void *) field;
1759
1760 if (enumeration->container) {
16ca5ff0 1761 is_set = bt_ctf_field_common_is_set_recursive(
312c056a
PP
1762 (void *) enumeration->container);
1763 }
1764
1765 return is_set;
1766}
1767
1768static
16ca5ff0 1769void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common *field)
312c056a
PP
1770{
1771 struct bt_ctf_field_enumeration *enumeration = (void *) field;
1772
1773 if (enumeration->container) {
16ca5ff0 1774 bt_ctf_field_common_reset_recursive(
312c056a
PP
1775 (void *) enumeration->container);
1776 }
1777
16ca5ff0 1778 bt_ctf_field_common_generic_reset((void *) field);
312c056a
PP
1779}
1780
1781static
1782void bt_ctf_field_variant_set_is_frozen_recursive(
16ca5ff0 1783 struct bt_ctf_field_common *field, bool is_frozen)
312c056a
PP
1784{
1785 struct bt_ctf_field_variant *variant = (void *) field;
1786
1787 if (variant->tag) {
16ca5ff0 1788 bt_ctf_field_common_set_is_frozen_recursive(
312c056a
PP
1789 (void *) variant->tag, is_frozen);
1790 }
1791
16ca5ff0 1792 bt_ctf_field_common_variant_set_is_frozen_recursive((void *) field,
312c056a
PP
1793 is_frozen);
1794}
1795
1796static
16ca5ff0 1797int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common *field)
312c056a
PP
1798{
1799 int ret;
1800 struct bt_ctf_field_variant *variant = (void *) field;
1801
1802 if (variant->tag) {
16ca5ff0 1803 ret = bt_ctf_field_common_validate_recursive(
312c056a
PP
1804 (void *) variant->tag);
1805 if (ret) {
1806 goto end;
1807 }
1808 }
1809
16ca5ff0 1810 ret = bt_ctf_field_common_variant_validate_recursive((void *) field);
312c056a
PP
1811
1812end:
1813 return ret;
1814}
1815
1816static
16ca5ff0 1817bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common *field)
312c056a
PP
1818{
1819 bt_bool is_set;
1820 struct bt_ctf_field_variant *variant = (void *) field;
1821
1822 if (variant->tag) {
16ca5ff0 1823 is_set = bt_ctf_field_common_is_set_recursive(
312c056a
PP
1824 (void *) variant->tag);
1825 if (is_set) {
1826 goto end;
1827 }
1828 }
1829
16ca5ff0 1830 is_set = bt_ctf_field_common_variant_is_set_recursive((void *) field);
312c056a
PP
1831
1832end:
1833 return is_set;
1834}
1835
1836static
16ca5ff0 1837void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common *field)
312c056a
PP
1838{
1839 struct bt_ctf_field_variant *variant = (void *) field;
1840
1841 if (variant->tag) {
16ca5ff0 1842 bt_ctf_field_common_reset_recursive(
312c056a
PP
1843 (void *) variant->tag);
1844 }
1845
16ca5ff0 1846 bt_ctf_field_common_variant_reset_recursive((void *) field);
312c056a
PP
1847}
1848
1849BT_ASSERT_PRE_FUNC
1850static inline bool field_to_set_has_expected_type(
16ca5ff0
PP
1851 struct bt_ctf_field_common *struct_field,
1852 const char *name, struct bt_ctf_field_common *value)
312c056a
PP
1853{
1854 bool ret = true;
16ca5ff0 1855 struct bt_ctf_field_type_common *expected_field_type = NULL;
312c056a
PP
1856
1857 expected_field_type =
16ca5ff0 1858 bt_ctf_field_type_common_structure_borrow_field_type_by_name(
312c056a
PP
1859 struct_field->type, name);
1860
16ca5ff0 1861 if (bt_ctf_field_type_common_compare(expected_field_type, value->type)) {
312c056a 1862 BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
16ca5ff0 1863 "value-ft-addr=%p, expected-ft-addr=%p", value->type,
312c056a
PP
1864 expected_field_type);
1865 ret = false;
1866 goto end;
1867 }
1868
1869end:
1870 return ret;
1871}
1872
1873BT_HIDDEN
1874int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *field,
1875 const char *name, struct bt_ctf_field *value)
1876{
1877 int ret = 0;
1878 GQuark field_quark;
16ca5ff0
PP
1879 struct bt_ctf_field_common *common_field = (void *) field;
1880 struct bt_ctf_field_common_structure *structure =
1881 BT_CTF_FROM_COMMON(common_field);
1882 struct bt_ctf_field_common *common_value = (void *) value;
312c056a
PP
1883 size_t index;
1884 GHashTable *field_name_to_index;
16ca5ff0 1885 struct bt_ctf_field_type_common_structure *structure_ft;
312c056a
PP
1886
1887 BT_ASSERT_PRE_NON_NULL(field, "Parent field");
1888 BT_ASSERT_PRE_NON_NULL(name, "Field name");
1889 BT_ASSERT_PRE_NON_NULL(value, "Value field");
16ca5ff0
PP
1890 BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(common_field,
1891 BT_CTF_FIELD_TYPE_ID_STRUCT, "Parent field");
312c056a
PP
1892 BT_ASSERT_PRE(field_to_set_has_expected_type(common_field,
1893 name, common_value),
1894 "Value field's type is different from the expected field type.");
1895 field_quark = g_quark_from_string(name);
16ca5ff0 1896 structure_ft = BT_CTF_FROM_COMMON(common_field->type);
312c056a
PP
1897 field_name_to_index = structure_ft->field_name_to_index;
1898 if (!g_hash_table_lookup_extended(field_name_to_index,
1899 GUINT_TO_POINTER(field_quark), NULL,
1900 (gpointer *) &index)) {
1901 BT_LOGV("Invalid parameter: no such field in structure field's type: "
1902 "struct-field-addr=%p, struct-ft-addr=%p, "
1903 "field-ft-addr=%p, name=\"%s\"",
1904 field, common_field->type, common_value->type, name);
1905 ret = -1;
1906 goto end;
1907 }
65300d60
PP
1908 bt_object_get_ref(value);
1909 BT_OBJECT_MOVE_REF(structure->fields->pdata[index], value);
312c056a
PP
1910
1911end:
1912 return ret;
1913}
This page took 0.10819 seconds and 4 git commands to generate.