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