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