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