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