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