Visibility hidden by default
[babeltrace.git] / src / lib / trace-ir / field.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
5 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 */
7
8 #define BT_LOG_TAG "LIB/FIELD"
9 #include "lib/logging.h"
10
11 #include "lib/assert-cond.h"
12 #include <babeltrace2/trace-ir/field.h>
13 #include "lib/object.h"
14 #include "compat/compiler.h"
15 #include "compat/fcntl.h"
16 #include "common/align.h"
17 #include "common/assert.h"
18 #include <inttypes.h>
19 #include <stdbool.h>
20
21 #include "field.h"
22 #include "field-class.h"
23 #include "lib/func-status.h"
24
25 #define BT_ASSERT_PRE_DEV_FIELD_HOT(_field) \
26 BT_ASSERT_PRE_DEV_HOT("field", \
27 (const struct bt_field *) (_field), "Field", ": %!+f", (_field))
28
29 static
30 void reset_single_field(struct bt_field *field);
31
32 static
33 void reset_array_field(struct bt_field *field);
34
35 static
36 void reset_structure_field(struct bt_field *field);
37
38 static
39 void reset_option_field(struct bt_field *field);
40
41 static
42 void reset_variant_field(struct bt_field *field);
43
44 static
45 void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
46
47 static
48 void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
49
50 static
51 void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
52
53 static
54 void set_option_field_is_frozen(struct bt_field *field, bool is_frozen);
55
56 static
57 void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
58
59 static
60 bool single_field_is_set(const struct bt_field *field);
61
62 static
63 bool array_field_is_set(const struct bt_field *field);
64
65 static
66 bool structure_field_is_set(const struct bt_field *field);
67
68 static
69 bool option_field_is_set(const struct bt_field *field);
70
71 static
72 bool variant_field_is_set(const struct bt_field *field);
73
74 static
75 struct bt_field_methods bool_field_methods = {
76 .set_is_frozen = set_single_field_is_frozen,
77 .is_set = single_field_is_set,
78 .reset = reset_single_field,
79 };
80
81 static
82 struct bt_field_methods bit_array_field_methods = {
83 .set_is_frozen = set_single_field_is_frozen,
84 .is_set = single_field_is_set,
85 .reset = reset_single_field,
86 };
87
88 static
89 struct bt_field_methods integer_field_methods = {
90 .set_is_frozen = set_single_field_is_frozen,
91 .is_set = single_field_is_set,
92 .reset = reset_single_field,
93 };
94
95 static
96 struct bt_field_methods real_field_methods = {
97 .set_is_frozen = set_single_field_is_frozen,
98 .is_set = single_field_is_set,
99 .reset = reset_single_field,
100 };
101
102 static
103 struct bt_field_methods string_field_methods = {
104 .set_is_frozen = set_single_field_is_frozen,
105 .is_set = single_field_is_set,
106 .reset = reset_single_field,
107 };
108
109 static
110 struct bt_field_methods structure_field_methods = {
111 .set_is_frozen = set_structure_field_is_frozen,
112 .is_set = structure_field_is_set,
113 .reset = reset_structure_field,
114 };
115
116 static
117 struct bt_field_methods array_field_methods = {
118 .set_is_frozen = set_array_field_is_frozen,
119 .is_set = array_field_is_set,
120 .reset = reset_array_field,
121 };
122
123 static
124 struct bt_field_methods option_field_methods = {
125 .set_is_frozen = set_option_field_is_frozen,
126 .is_set = option_field_is_set,
127 .reset = reset_option_field,
128 };
129
130 static
131 struct bt_field_methods variant_field_methods = {
132 .set_is_frozen = set_variant_field_is_frozen,
133 .is_set = variant_field_is_set,
134 .reset = reset_variant_field,
135 };
136
137 static
138 struct bt_field *create_bool_field(struct bt_field_class *);
139
140 static
141 struct bt_field *create_bit_array_field(struct bt_field_class *);
142
143 static
144 struct bt_field *create_integer_field(struct bt_field_class *);
145
146 static
147 struct bt_field *create_real_field(struct bt_field_class *);
148
149 static
150 struct bt_field *create_string_field(struct bt_field_class *);
151
152 static
153 struct bt_field *create_structure_field(struct bt_field_class *);
154
155 static
156 struct bt_field *create_static_array_field(struct bt_field_class *);
157
158 static
159 struct bt_field *create_dynamic_array_field(struct bt_field_class *);
160
161 static
162 struct bt_field *create_option_field(struct bt_field_class *);
163
164 static
165 struct bt_field *create_variant_field(struct bt_field_class *);
166
167 static
168 void destroy_bool_field(struct bt_field *field);
169
170 static
171 void destroy_bit_array_field(struct bt_field *field);
172
173 static
174 void destroy_integer_field(struct bt_field *field);
175
176 static
177 void destroy_real_field(struct bt_field *field);
178
179 static
180 void destroy_string_field(struct bt_field *field);
181
182 static
183 void destroy_structure_field(struct bt_field *field);
184
185 static
186 void destroy_array_field(struct bt_field *field);
187
188 static
189 void destroy_option_field(struct bt_field *field);
190
191 static
192 void destroy_variant_field(struct bt_field *field);
193
194 BT_EXPORT
195 struct bt_field_class *bt_field_borrow_class(struct bt_field *field)
196 {
197 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
198 return field->class;
199 }
200
201 BT_EXPORT
202 const struct bt_field_class *bt_field_borrow_class_const(
203 const struct bt_field *field)
204 {
205 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
206 return field->class;
207 }
208
209 BT_EXPORT
210 enum bt_field_class_type bt_field_get_class_type(const struct bt_field *field)
211 {
212 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
213 return field->class->type;
214 }
215
216 struct bt_field *bt_field_create(struct bt_field_class *fc)
217 {
218 struct bt_field *field = NULL;
219
220 BT_ASSERT(fc);
221
222 switch (fc->type) {
223 case BT_FIELD_CLASS_TYPE_BOOL:
224 field = create_bool_field(fc);
225 break;
226 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
227 field = create_bit_array_field(fc);
228 break;
229 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
230 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
231 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
232 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
233 field = create_integer_field(fc);
234 break;
235 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
236 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
237 field = create_real_field(fc);
238 break;
239 case BT_FIELD_CLASS_TYPE_STRING:
240 field = create_string_field(fc);
241 break;
242 case BT_FIELD_CLASS_TYPE_STRUCTURE:
243 field = create_structure_field(fc);
244 break;
245 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
246 field = create_static_array_field(fc);
247 break;
248 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD:
249 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD:
250 field = create_dynamic_array_field(fc);
251 break;
252 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD:
253 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD:
254 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD:
255 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
256 field = create_option_field(fc);
257 break;
258 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD:
259 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD:
260 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
261 field = create_variant_field(fc);
262 break;
263 default:
264 bt_common_abort();
265 }
266
267 if (!field) {
268 BT_LIB_LOGE_APPEND_CAUSE("Cannot create field object from field class: "
269 "%![fc-]+F", fc);
270 goto end;
271 }
272
273 end:
274 return field;
275 }
276
277 static inline
278 void init_field(struct bt_field *field, struct bt_field_class *fc,
279 struct bt_field_methods *methods)
280 {
281 BT_ASSERT(field);
282 BT_ASSERT(fc);
283 bt_object_init_unique(&field->base);
284 field->methods = methods;
285 field->class = fc;
286 bt_object_get_ref_no_null_check(fc);
287 }
288
289 static
290 struct bt_field *create_bool_field(struct bt_field_class *fc)
291 {
292 struct bt_field_bool *bool_field;
293
294 BT_LIB_LOGD("Creating boolean field object: %![fc-]+F", fc);
295 bool_field = g_new0(struct bt_field_bool, 1);
296 if (!bool_field) {
297 BT_LIB_LOGE_APPEND_CAUSE(
298 "Failed to allocate one boolean field.");
299 goto end;
300 }
301
302 init_field((void *) bool_field, fc, &bool_field_methods);
303 BT_LIB_LOGD("Created boolean field object: %!+f", bool_field);
304
305 end:
306 return (void *) bool_field;
307 }
308
309 static
310 struct bt_field *create_bit_array_field(struct bt_field_class *fc)
311 {
312 struct bt_field_bit_array *ba_field;
313
314 BT_LIB_LOGD("Creating bit array field object: %![fc-]+F", fc);
315 ba_field = g_new0(struct bt_field_bit_array, 1);
316 if (!ba_field) {
317 BT_LIB_LOGE_APPEND_CAUSE(
318 "Failed to allocate one bit array field.");
319 goto end;
320 }
321
322 init_field((void *) ba_field, fc, &bit_array_field_methods);
323 BT_LIB_LOGD("Created bit array field object: %!+f", ba_field);
324
325 end:
326 return (void *) ba_field;
327 }
328
329 static
330 struct bt_field *create_integer_field(struct bt_field_class *fc)
331 {
332 struct bt_field_integer *int_field;
333
334 BT_LIB_LOGD("Creating integer field object: %![fc-]+F", fc);
335 int_field = g_new0(struct bt_field_integer, 1);
336 if (!int_field) {
337 BT_LIB_LOGE_APPEND_CAUSE(
338 "Failed to allocate one integer field.");
339 goto end;
340 }
341
342 init_field((void *) int_field, fc, &integer_field_methods);
343 BT_LIB_LOGD("Created integer field object: %!+f", int_field);
344
345 end:
346 return (void *) int_field;
347 }
348
349 static
350 struct bt_field *create_real_field(struct bt_field_class *fc)
351 {
352 struct bt_field_real *real_field;
353
354 BT_LIB_LOGD("Creating real field object: %![fc-]+F", fc);
355 real_field = g_new0(struct bt_field_real, 1);
356 if (!real_field) {
357 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field.");
358 goto end;
359 }
360
361 init_field((void *) real_field, fc, &real_field_methods);
362 BT_LIB_LOGD("Created real field object: %!+f", real_field);
363
364 end:
365 return (void *) real_field;
366 }
367
368 static
369 struct bt_field *create_string_field(struct bt_field_class *fc)
370 {
371 struct bt_field_string *string_field;
372
373 BT_LIB_LOGD("Creating string field object: %![fc-]+F", fc);
374 string_field = g_new0(struct bt_field_string, 1);
375 if (!string_field) {
376 BT_LIB_LOGE_APPEND_CAUSE(
377 "Failed to allocate one string field.");
378 goto end;
379 }
380
381 init_field((void *) string_field, fc, &string_field_methods);
382 string_field->buf = g_array_sized_new(FALSE, FALSE,
383 sizeof(char), 1);
384 if (!string_field->buf) {
385 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
386 bt_field_destroy((void *) string_field);
387 string_field = NULL;
388 goto end;
389 }
390
391 g_array_index(string_field->buf, char, 0) = '\0';
392 BT_LIB_LOGD("Created string field object: %!+f", string_field);
393
394 end:
395 return (void *) string_field;
396 }
397
398 static inline
399 int create_fields_from_named_field_classes(
400 struct bt_field_class_named_field_class_container *fc,
401 GPtrArray **fields)
402 {
403 int ret = 0;
404 uint64_t i;
405
406 *fields = g_ptr_array_new_with_free_func(
407 (GDestroyNotify) bt_field_destroy);
408 if (!*fields) {
409 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
410 ret = -1;
411 goto end;
412 }
413
414 g_ptr_array_set_size(*fields, fc->named_fcs->len);
415
416 for (i = 0; i < fc->named_fcs->len; i++) {
417 struct bt_field *field;
418 struct bt_named_field_class *named_fc = fc->named_fcs->pdata[i];
419
420 field = bt_field_create(named_fc->fc);
421 if (!field) {
422 BT_LIB_LOGE_APPEND_CAUSE(
423 "Failed to create structure member or variant option field: "
424 "name=\"%s\", %![fc-]+F",
425 named_fc->name->str, named_fc->fc);
426 ret = -1;
427 goto end;
428 }
429
430 g_ptr_array_index(*fields, i) = field;
431 }
432
433 end:
434 return ret;
435 }
436
437 static
438 struct bt_field *create_structure_field(struct bt_field_class *fc)
439 {
440 struct bt_field_structure *struct_field;
441
442 BT_LIB_LOGD("Creating structure field object: %![fc-]+F", fc);
443 struct_field = g_new0(struct bt_field_structure, 1);
444 if (!struct_field) {
445 BT_LIB_LOGE_APPEND_CAUSE(
446 "Failed to allocate one structure field.");
447 goto end;
448 }
449
450 init_field((void *) struct_field, fc, &structure_field_methods);
451
452 if (create_fields_from_named_field_classes((void *) fc,
453 &struct_field->fields)) {
454 BT_LIB_LOGE_APPEND_CAUSE(
455 "Cannot create structure member fields: %![fc-]+F", fc);
456 bt_field_destroy((void *) struct_field);
457 struct_field = NULL;
458 goto end;
459 }
460
461 BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
462
463 end:
464 return (void *) struct_field;
465 }
466
467 static
468 struct bt_field *create_option_field(struct bt_field_class *fc)
469 {
470 struct bt_field_option *opt_field;
471 struct bt_field_class_option *opt_fc = (void *) fc;
472
473 BT_LIB_LOGD("Creating option field object: %![fc-]+F", fc);
474 opt_field = g_new0(struct bt_field_option, 1);
475 if (!opt_field) {
476 BT_LIB_LOGE_APPEND_CAUSE(
477 "Failed to allocate one option field.");
478 goto end;
479 }
480
481 init_field((void *) opt_field, fc, &option_field_methods);
482 opt_field->content_field = bt_field_create(opt_fc->content_fc);
483 if (!opt_field->content_field) {
484 BT_LIB_LOGE_APPEND_CAUSE(
485 "Failed to create option field's content field: "
486 "%![opt-fc-]+F, %![content-fc-]+F",
487 opt_fc, opt_fc->content_fc);
488 bt_field_destroy((void *) opt_field);
489 opt_field = NULL;
490 goto end;
491 }
492
493 BT_LIB_LOGD("Created option field object: %!+f", opt_field);
494
495 end:
496 return (void *) opt_field;
497 }
498
499 static
500 struct bt_field *create_variant_field(struct bt_field_class *fc)
501 {
502 struct bt_field_variant *var_field;
503
504 BT_LIB_LOGD("Creating variant field object: %![fc-]+F", fc);
505 var_field = g_new0(struct bt_field_variant, 1);
506 if (!var_field) {
507 BT_LIB_LOGE_APPEND_CAUSE(
508 "Failed to allocate one variant field.");
509 goto end;
510 }
511
512 init_field((void *) var_field, fc, &variant_field_methods);
513
514 if (create_fields_from_named_field_classes((void *) fc,
515 &var_field->fields)) {
516 BT_LIB_LOGE_APPEND_CAUSE("Cannot create variant member fields: "
517 "%![fc-]+F", fc);
518 bt_field_destroy((void *) var_field);
519 var_field = NULL;
520 goto end;
521 }
522
523 BT_LIB_LOGD("Created variant field object: %!+f", var_field);
524
525 end:
526 return (void *) var_field;
527 }
528
529 static inline
530 int init_array_field_fields(struct bt_field_array *array_field)
531 {
532 int ret = 0;
533 uint64_t i;
534 struct bt_field_class_array *array_fc;
535
536 BT_ASSERT(array_field);
537 array_fc = (void *) array_field->common.class;
538 array_field->fields = g_ptr_array_sized_new(array_field->length);
539 if (!array_field->fields) {
540 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
541 ret = -1;
542 goto end;
543 }
544
545 g_ptr_array_set_free_func(array_field->fields,
546 (GDestroyNotify) bt_field_destroy);
547 g_ptr_array_set_size(array_field->fields, array_field->length);
548
549 for (i = 0; i < array_field->length; i++) {
550 array_field->fields->pdata[i] = bt_field_create(
551 array_fc->element_fc);
552 if (!array_field->fields->pdata[i]) {
553 BT_LIB_LOGE_APPEND_CAUSE(
554 "Cannot create array field's element field: "
555 "index=%" PRIu64 ", %![fc-]+F", i, array_fc);
556 ret = -1;
557 goto end;
558 }
559 }
560
561 end:
562 return ret;
563 }
564
565 static
566 struct bt_field *create_static_array_field(struct bt_field_class *fc)
567 {
568 struct bt_field_class_array_static *array_fc = (void *) fc;
569 struct bt_field_array *array_field;
570
571 BT_LIB_LOGD("Creating static array field object: %![fc-]+F", fc);
572 array_field = g_new0(struct bt_field_array, 1);
573 if (!array_field) {
574 BT_LIB_LOGE_APPEND_CAUSE(
575 "Failed to allocate one static array field.");
576 goto end;
577 }
578
579 init_field((void *) array_field, fc, &array_field_methods);
580 array_field->length = array_fc->length;
581
582 if (init_array_field_fields(array_field)) {
583 BT_LIB_LOGE_APPEND_CAUSE("Cannot create static array fields: "
584 "%![fc-]+F", fc);
585 bt_field_destroy((void *) array_field);
586 array_field = NULL;
587 goto end;
588 }
589
590 BT_LIB_LOGD("Created static array field object: %!+f", array_field);
591
592 end:
593 return (void *) array_field;
594 }
595
596 static
597 struct bt_field *create_dynamic_array_field(struct bt_field_class *fc)
598 {
599 struct bt_field_array *array_field;
600
601 BT_LIB_LOGD("Creating dynamic array field object: %![fc-]+F", fc);
602 array_field = g_new0(struct bt_field_array, 1);
603 if (!array_field) {
604 BT_LIB_LOGE_APPEND_CAUSE(
605 "Failed to allocate one dynamic array field.");
606 goto end;
607 }
608
609 init_field((void *) array_field, fc, &array_field_methods);
610
611 if (init_array_field_fields(array_field)) {
612 BT_LIB_LOGE_APPEND_CAUSE("Cannot create dynamic array fields: "
613 "%![fc-]+F", fc);
614 bt_field_destroy((void *) array_field);
615 array_field = NULL;
616 goto end;
617 }
618
619 BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
620
621 end:
622 return (void *) array_field;
623 }
624
625 BT_EXPORT
626 bt_bool bt_field_bool_get_value(const struct bt_field *field)
627 {
628 const struct bt_field_bool *bool_field = (const void *) field;
629
630 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
631 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
632 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
633 "boolean-field", BT_FIELD_CLASS_TYPE_BOOL, "Field");
634 return (bt_bool) bool_field->value;
635 }
636
637 BT_EXPORT
638 void bt_field_bool_set_value(struct bt_field *field, bt_bool value)
639 {
640 struct bt_field_bool *bool_field = (void *) field;
641
642 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
643 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
644 "boolean-field", BT_FIELD_CLASS_TYPE_BOOL, "Field");
645 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
646 bool_field->value = (bool) value;
647 bt_field_set_single(field, true);
648 }
649
650 BT_EXPORT
651 uint64_t bt_field_bit_array_get_value_as_integer(const struct bt_field *field)
652 {
653 const struct bt_field_bit_array *ba_field = (const void *) field;
654
655 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
656 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
657 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
658 "bit-array-field", BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field");
659 return ba_field->value_as_int;
660 }
661
662 BT_EXPORT
663 void bt_field_bit_array_set_value_as_integer(struct bt_field *field,
664 uint64_t value)
665 {
666 struct bt_field_bit_array *ba_field = (void *) field;
667 struct bt_field_class_bit_array *ba_fc;
668
669 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
670 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
671 "bit-array-field", BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field");
672 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
673 ba_fc = (void *) field->class;
674 ba_field->value_as_int = value;
675
676 if (ba_fc->length < 64) {
677 /* Apply mask */
678 ba_field->value_as_int &= ((UINT64_C(1) << ba_fc->length) - 1);
679 }
680
681 bt_field_set_single(field, true);
682 }
683
684 BT_EXPORT
685 int64_t bt_field_integer_signed_get_value(const struct bt_field *field)
686 {
687 const struct bt_field_integer *int_field = (const void *) field;
688
689 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
690 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
691 BT_ASSERT_PRE_DEV_FIELD_IS_SIGNED_INT("field", field, "Field");
692 return int_field->value.i;
693 }
694
695 BT_EXPORT
696 void bt_field_integer_signed_set_value(struct bt_field *field, int64_t value)
697 {
698 struct bt_field_integer *int_field = (void *) field;
699
700 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
701 BT_ASSERT_PRE_DEV_FIELD_IS_SIGNED_INT("field", field, "Field");
702 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
703 BT_ASSERT_PRE_DEV("valid-value-for-field-class-field-value-range",
704 bt_util_value_is_in_range_signed(
705 ((struct bt_field_class_integer *) field->class)->range,
706 value),
707 "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
708 "%![fc-]+F", value, field, field->class);
709 int_field->value.i = value;
710 bt_field_set_single(field, true);
711 }
712
713 BT_EXPORT
714 uint64_t bt_field_integer_unsigned_get_value(const struct bt_field *field)
715 {
716 const struct bt_field_integer *int_field = (const void *) field;
717
718 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
719 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
720 BT_ASSERT_PRE_DEV_FIELD_IS_UNSIGNED_INT("field", field, "Field");
721 return int_field->value.u;
722 }
723
724 BT_EXPORT
725 void bt_field_integer_unsigned_set_value(struct bt_field *field, uint64_t value)
726 {
727 struct bt_field_integer *int_field = (void *) field;
728
729 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
730 BT_ASSERT_PRE_DEV_FIELD_IS_UNSIGNED_INT("field", field, "Field");
731 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
732 BT_ASSERT_PRE_DEV("valid-value-for-field-class-field-value-range",
733 bt_util_value_is_in_range_unsigned(
734 ((struct bt_field_class_integer *) field->class)->range,
735 value),
736 "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
737 "%![fc-]+F", value, field, field->class);
738 int_field->value.u = value;
739 bt_field_set_single(field, true);
740 }
741
742 BT_EXPORT
743 float bt_field_real_single_precision_get_value(const struct bt_field *field)
744 {
745 const struct bt_field_real *real_field = (const void *) field;
746
747 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
748 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
749 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
750 "single-precision-real-field",
751 BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL, "Field");
752 return (float) real_field->value;
753 }
754
755 BT_EXPORT
756 double bt_field_real_double_precision_get_value(const struct bt_field *field)
757 {
758 const struct bt_field_real *real_field = (const void *) field;
759
760 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
761 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
762 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
763 "double-precision-real-field",
764 BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL, "Field");
765 return real_field->value;
766 }
767
768 BT_EXPORT
769 void bt_field_real_single_precision_set_value(struct bt_field *field,
770 float value)
771 {
772 struct bt_field_real *real_field = (void *) field;
773
774 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
775 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
776 "single-precision-real-field",
777 BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL, "Field");
778 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
779
780 real_field->value = (double) value;
781 bt_field_set_single(field, true);
782 }
783
784 BT_EXPORT
785 void bt_field_real_double_precision_set_value(struct bt_field *field,
786 double value)
787 {
788 struct bt_field_real *real_field = (void *) field;
789
790 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
791 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
792 "double-precision-real-field",
793 BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL, "Field");
794 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
795
796 real_field->value = value;
797 bt_field_set_single(field, true);
798 }
799
800 BT_EXPORT
801 enum bt_field_enumeration_get_mapping_labels_status
802 bt_field_enumeration_unsigned_get_mapping_labels(
803 const struct bt_field *field,
804 bt_field_class_enumeration_mapping_label_array *label_array,
805 uint64_t *count)
806 {
807 const struct bt_field_integer *int_field = (const void *) field;
808
809 BT_ASSERT_PRE_DEV_NO_ERROR();
810 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
811 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
812 "Label array (output)");
813 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
814 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
815 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
816 "unsigned-enumeration-field",
817 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field");
818 return (int)
819 bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
820 field->class, int_field->value.u, label_array, count);
821 }
822
823 BT_EXPORT
824 enum bt_field_enumeration_get_mapping_labels_status
825 bt_field_enumeration_signed_get_mapping_labels(
826 const struct bt_field *field,
827 bt_field_class_enumeration_mapping_label_array *label_array,
828 uint64_t *count)
829 {
830 const struct bt_field_integer *int_field = (const void *) field;
831
832 BT_ASSERT_PRE_DEV_NO_ERROR();
833 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
834 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
835 "Label array (output)");
836 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
837 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
838 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
839 "signed-enumeration-field",
840 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field");
841 return (int)
842 bt_field_class_enumeration_signed_get_mapping_labels_for_value(
843 field->class, int_field->value.i, label_array, count);
844 }
845
846 BT_EXPORT
847 const char *bt_field_string_get_value(const struct bt_field *field)
848 {
849 const struct bt_field_string *string_field = (const void *) field;
850
851 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
852 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
853 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field, "string-field",
854 BT_FIELD_CLASS_TYPE_STRING, "Field");
855 return (const char *) string_field->buf->data;
856 }
857
858 BT_EXPORT
859 uint64_t bt_field_string_get_length(const struct bt_field *field)
860 {
861 const struct bt_field_string *string_field = (const void *) field;
862
863 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
864 BT_ASSERT_PRE_DEV_FIELD_IS_SET("field", field);
865 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field, "string-field",
866 BT_FIELD_CLASS_TYPE_STRING, "Field");
867 return string_field->length;
868 }
869
870 static inline
871 void clear_string_field(struct bt_field *field)
872 {
873 struct bt_field_string *string_field = (void *) field;
874
875 BT_ASSERT_DBG(field);
876 string_field->length = 0;
877 g_array_index(string_field->buf, char, 0) = '\0';
878 bt_field_set_single(field, true);
879 }
880
881 BT_EXPORT
882 enum bt_field_string_set_value_status bt_field_string_set_value(
883 struct bt_field *field, const char *value)
884 {
885 BT_ASSERT_PRE_DEV_NO_ERROR();
886 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
887 BT_ASSERT_PRE_DEV_NON_NULL("value", value, "Value");
888 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
889 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field, "string-field",
890 BT_FIELD_CLASS_TYPE_STRING, "Field");
891 clear_string_field(field);
892 return (int) bt_field_string_append_with_length(field, value,
893 (uint64_t) strlen(value));
894 }
895
896 #define BT_ASSERT_PRE_DEV_FOR_APPEND_TO_STRING_FIELD_WITH_LENGTH(_field, _value, _length) \
897 do { \
898 BT_ASSERT_PRE_DEV_NO_ERROR(); \
899 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(_field); \
900 BT_ASSERT_PRE_DEV_NON_NULL("value", (_value), "Value"); \
901 BT_ASSERT_PRE_DEV_FIELD_HOT(_field); \
902 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", \
903 (_field), "string-field", \
904 BT_FIELD_CLASS_TYPE_STRING, "Field"); \
905 BT_ASSERT_PRE_DEV("value-has-no-null-byte", \
906 !memchr((_value), '\0', (_length)), \
907 "String value to append contains a null character: " \
908 "partial-value=\"%.32s\", length=%" PRIu64, \
909 (_value), (_length)); \
910 } while (0)
911
912 static
913 enum bt_field_string_append_status append_to_string_field_with_length(
914 struct bt_field *field, const char *value, uint64_t length)
915 {
916 struct bt_field_string *string_field = (void *) field;
917 char *data;
918 uint64_t new_length;
919
920 BT_ASSERT_DBG(field);
921 BT_ASSERT_DBG(value);
922 new_length = length + string_field->length;
923
924 if (G_UNLIKELY(new_length + 1 > string_field->buf->len)) {
925 g_array_set_size(string_field->buf, new_length + 1);
926 }
927
928 data = string_field->buf->data;
929 memcpy(data + string_field->length, value, length);
930 ((char *) string_field->buf->data)[new_length] = '\0';
931 string_field->length = new_length;
932 bt_field_set_single(field, true);
933 return BT_FUNC_STATUS_OK;
934 }
935
936 BT_EXPORT
937 enum bt_field_string_append_status bt_field_string_append_with_length(
938 struct bt_field *field, const char *value, uint64_t length)
939 {
940 BT_ASSERT_PRE_DEV_FOR_APPEND_TO_STRING_FIELD_WITH_LENGTH(field, value,
941 length);
942 return append_to_string_field_with_length(field, value, length);
943 }
944
945 BT_EXPORT
946 enum bt_field_string_append_status bt_field_string_append(
947 struct bt_field *field, const char *value)
948 {
949 uint64_t length = (uint64_t) strlen(value);
950
951 BT_ASSERT_PRE_DEV_FOR_APPEND_TO_STRING_FIELD_WITH_LENGTH(field, value,
952 length);
953 return append_to_string_field_with_length(field, value, length);
954 }
955
956 BT_EXPORT
957 void bt_field_string_clear(struct bt_field *field)
958 {
959 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
960 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
961 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field, "string-field",
962 BT_FIELD_CLASS_TYPE_STRING, "Field");
963 clear_string_field(field);
964 }
965
966 BT_EXPORT
967 uint64_t bt_field_array_get_length(const struct bt_field *field)
968 {
969 const struct bt_field_array *array_field = (const void *) field;
970
971 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
972 BT_ASSERT_PRE_DEV_FIELD_IS_ARRAY("field", field, "Field");
973 return array_field->length;
974 }
975
976 BT_EXPORT
977 enum bt_field_array_dynamic_set_length_status bt_field_array_dynamic_set_length(
978 struct bt_field *field, uint64_t length)
979 {
980 int ret = BT_FUNC_STATUS_OK;
981 struct bt_field_array *array_field = (void *) field;
982
983 BT_ASSERT_PRE_DEV_NO_ERROR();
984 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
985 BT_ASSERT_PRE_DEV_FIELD_IS_DYNAMIC_ARRAY("field", field, "Field");
986 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
987
988 if (G_UNLIKELY(length > array_field->fields->len)) {
989 /* Make more room */
990 struct bt_field_class_array *array_fc;
991 uint64_t cur_len = array_field->fields->len;
992 uint64_t i;
993
994 g_ptr_array_set_size(array_field->fields, length);
995 array_fc = (void *) field->class;
996
997 for (i = cur_len; i < array_field->fields->len; i++) {
998 struct bt_field *elem_field = bt_field_create(
999 array_fc->element_fc);
1000
1001 if (!elem_field) {
1002 BT_LIB_LOGE_APPEND_CAUSE(
1003 "Cannot create element field for "
1004 "dynamic array field: "
1005 "index=%" PRIu64 ", "
1006 "%![array-field-]+f", i, field);
1007 ret = BT_FUNC_STATUS_MEMORY_ERROR;
1008 goto end;
1009 }
1010
1011 BT_ASSERT_DBG(!array_field->fields->pdata[i]);
1012 array_field->fields->pdata[i] = elem_field;
1013 }
1014 }
1015
1016 array_field->length = length;
1017
1018 end:
1019 return ret;
1020 }
1021
1022 static inline
1023 struct bt_field *borrow_array_field_element_field_by_index(
1024 struct bt_field *field, uint64_t index, const char *api_func)
1025 {
1026 struct bt_field_array *array_field = (void *) field;
1027
1028 BT_ASSERT_PRE_DEV_FIELD_NON_NULL_FROM_FUNC(api_func, field);
1029 BT_ASSERT_PRE_DEV_FIELD_IS_ARRAY_FROM_FUNC(api_func, "field", field,
1030 "Field");
1031 BT_ASSERT_PRE_DEV_VALID_INDEX_FROM_FUNC(api_func, index,
1032 array_field->length);
1033 return array_field->fields->pdata[index];
1034 }
1035
1036 BT_EXPORT
1037 struct bt_field *bt_field_array_borrow_element_field_by_index(
1038 struct bt_field *field, uint64_t index)
1039 {
1040 return borrow_array_field_element_field_by_index(field, index,
1041 __func__);
1042 }
1043
1044 BT_EXPORT
1045 const struct bt_field *
1046 bt_field_array_borrow_element_field_by_index_const(
1047 const struct bt_field *field, uint64_t index)
1048 {
1049 return borrow_array_field_element_field_by_index((void *) field, index,
1050 __func__);
1051 }
1052
1053 static inline
1054 struct bt_field *borrow_structure_field_member_field_by_index(
1055 struct bt_field *field, uint64_t index, const char *api_func)
1056 {
1057 struct bt_field_structure *struct_field = (void *) field;
1058
1059 BT_ASSERT_PRE_DEV_FIELD_NON_NULL_FROM_FUNC(api_func, field);
1060 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE_FROM_FUNC(api_func, "field",
1061 field, "structure-field", BT_FIELD_CLASS_TYPE_STRUCTURE,
1062 "Field");
1063 BT_ASSERT_PRE_DEV_VALID_INDEX_FROM_FUNC(api_func, index,
1064 struct_field->fields->len);
1065 return struct_field->fields->pdata[index];
1066 }
1067
1068 BT_EXPORT
1069 struct bt_field *bt_field_structure_borrow_member_field_by_index(
1070 struct bt_field *field, uint64_t index)
1071 {
1072 return borrow_structure_field_member_field_by_index(field,
1073 index, __func__);
1074 }
1075
1076 BT_EXPORT
1077 const struct bt_field *
1078 bt_field_structure_borrow_member_field_by_index_const(
1079 const struct bt_field *field, uint64_t index)
1080 {
1081 return borrow_structure_field_member_field_by_index(
1082 (void *) field, index, __func__);
1083 }
1084
1085 static inline
1086 struct bt_field *borrow_structure_field_member_field_by_name(
1087 struct bt_field *field, const char *name, const char *api_func)
1088 {
1089 struct bt_field *ret_field = NULL;
1090 struct bt_field_class_structure *struct_fc;
1091 struct bt_field_structure *struct_field = (void *) field;
1092 gpointer orig_key;
1093 gpointer index;
1094
1095 BT_ASSERT_PRE_DEV_FIELD_NON_NULL_FROM_FUNC(api_func, field);
1096 BT_ASSERT_PRE_DEV_NON_NULL_FROM_FUNC(api_func, "member-name", name,
1097 "Member name");
1098 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE_FROM_FUNC(api_func, "field",
1099 field, "structure-field", BT_FIELD_CLASS_TYPE_STRUCTURE,
1100 "Field");
1101 struct_fc = (void *) field->class;
1102
1103 if (!g_hash_table_lookup_extended(struct_fc->common.name_to_index, name,
1104 &orig_key, &index)) {
1105 goto end;
1106 }
1107
1108 ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
1109 BT_ASSERT_DBG(ret_field);
1110
1111 end:
1112 return ret_field;
1113 }
1114
1115 BT_EXPORT
1116 struct bt_field *bt_field_structure_borrow_member_field_by_name(
1117 struct bt_field *field, const char *name)
1118 {
1119 return borrow_structure_field_member_field_by_name(field, name,
1120 __func__);
1121 }
1122
1123 BT_EXPORT
1124 const struct bt_field *bt_field_structure_borrow_member_field_by_name_const(
1125 const struct bt_field *field, const char *name)
1126 {
1127 return borrow_structure_field_member_field_by_name(
1128 (void *) field, name, __func__);
1129 }
1130
1131 BT_EXPORT
1132 void bt_field_option_set_has_field(struct bt_field *field, bt_bool has_field)
1133 {
1134 struct bt_field_option *opt_field = (void *) field;
1135
1136 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1137 BT_ASSERT_PRE_DEV_FIELD_IS_OPTION("field", field, "Field");
1138 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
1139
1140 if (has_field) {
1141 opt_field->selected_field = opt_field->content_field;
1142 } else {
1143 opt_field->selected_field = NULL;
1144 }
1145 }
1146
1147 BT_EXPORT
1148 struct bt_field *bt_field_option_borrow_field(struct bt_field *field)
1149 {
1150 struct bt_field_option *opt_field = (void *) field;
1151
1152 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1153 BT_ASSERT_PRE_DEV_FIELD_IS_OPTION("field", field, "Field");
1154 return opt_field->selected_field;
1155 }
1156
1157 BT_EXPORT
1158 const struct bt_field *bt_field_option_borrow_field_const(
1159 const struct bt_field *field)
1160 {
1161 return (const void *) bt_field_option_borrow_field((void *) field);
1162 }
1163
1164 #define BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_OPT_FIELD(_field) \
1165 do { \
1166 struct bt_field_variant *_var_field = (void *) field; \
1167 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(_field); \
1168 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT("field", (_field), \
1169 "Field"); \
1170 BT_ASSERT_PRE_DEV("has-selected-field", \
1171 _var_field->selected_field, \
1172 "Variant field has no selected field: %!+f", \
1173 field); \
1174 } while (0)
1175
1176 static inline
1177 struct bt_field *borrow_variant_field_selected_option_field(
1178 struct bt_field *field)
1179 {
1180 struct bt_field_variant *var_field = (void *) field;
1181
1182 BT_ASSERT_DBG(field);
1183 return var_field->selected_field;
1184 }
1185
1186 BT_EXPORT
1187 struct bt_field *bt_field_variant_borrow_selected_option_field(
1188 struct bt_field *field)
1189 {
1190 BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_OPT_FIELD(field);
1191 return borrow_variant_field_selected_option_field(field);
1192 }
1193
1194 BT_EXPORT
1195 const struct bt_field *bt_field_variant_borrow_selected_option_field_const(
1196 const struct bt_field *field)
1197 {
1198 BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_OPT_FIELD(field);
1199 return borrow_variant_field_selected_option_field((void *) field);
1200 }
1201
1202 #define BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_CLASS_OPT(_field) \
1203 do { \
1204 struct bt_field_variant *_var_field = (void *) field; \
1205 BT_ASSERT_PRE_DEV("has-selected-field", \
1206 _var_field->selected_field, \
1207 "Variant field has no selected field: %!+f", \
1208 (_field)); \
1209 } while (0)
1210
1211 static
1212 const struct bt_field_class_variant_option *
1213 borrow_variant_field_selected_class_option(const struct bt_field *field)
1214 {
1215 const struct bt_field_class_named_field_class_container *container_fc;
1216 const struct bt_field_variant *var_field = (const void *) field;
1217
1218 BT_ASSERT_DBG(field);
1219 container_fc = (const void *) field->class;
1220 return container_fc->named_fcs->pdata[var_field->selected_index];
1221 }
1222
1223 BT_EXPORT
1224 const struct bt_field_class_variant_option *
1225 bt_field_variant_borrow_selected_option_class_const(
1226 const struct bt_field *field)
1227 {
1228 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1229 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT("field", field, "Field");
1230 BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_CLASS_OPT(field);
1231 return borrow_variant_field_selected_class_option(field);
1232 }
1233
1234 BT_EXPORT
1235 const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *
1236 bt_field_variant_with_selector_field_integer_unsigned_borrow_selected_option_class_const(
1237 const struct bt_field *field)
1238 {
1239 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1240 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
1241 "variant-field-with-unsigned-selector-field",
1242 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1243 "Field");
1244 BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_CLASS_OPT(field);
1245 return (const void *) borrow_variant_field_selected_class_option(field);
1246 }
1247
1248 BT_EXPORT
1249 const struct bt_field_class_variant_with_selector_field_integer_signed_option *
1250 bt_field_variant_with_selector_field_integer_signed_borrow_selected_option_class_const(
1251 const struct bt_field *field)
1252 {
1253 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1254 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE("field", field,
1255 "variant-field-with-signed-selector-field",
1256 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1257 "Field");
1258 BT_ASSERT_PRE_DEV_FOR_BORROW_VAR_FIELD_SEL_CLASS_OPT(field);
1259 return (const void *) borrow_variant_field_selected_class_option(field);
1260 }
1261
1262 BT_EXPORT
1263 enum bt_field_variant_select_option_by_index_status
1264 bt_field_variant_select_option_by_index(
1265 struct bt_field *field, uint64_t index)
1266 {
1267 struct bt_field_variant *var_field = (void *) field;
1268
1269 BT_ASSERT_PRE_DEV_NO_ERROR();
1270 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1271 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT("field", field, "Field");
1272 BT_ASSERT_PRE_DEV_FIELD_HOT(field);
1273 BT_ASSERT_PRE_DEV_VALID_INDEX(index, var_field->fields->len);
1274 var_field->selected_field = var_field->fields->pdata[index];
1275 var_field->selected_index = index;
1276 return BT_FUNC_STATUS_OK;
1277 }
1278
1279 BT_EXPORT
1280 uint64_t bt_field_variant_get_selected_option_index(
1281 const struct bt_field *field)
1282 {
1283 const struct bt_field_variant *var_field = (const void *) field;
1284
1285 BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
1286 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT("field", field, "Field");
1287 BT_ASSERT_PRE_DEV("has-selected-field", var_field->selected_field,
1288 "Variant field has no selected field: %!+f", field);
1289 return var_field->selected_index;
1290 }
1291
1292 static inline
1293 void bt_field_finalize(struct bt_field *field)
1294 {
1295 BT_ASSERT(field);
1296 BT_LOGD_STR("Putting field's class.");
1297 BT_OBJECT_PUT_REF_AND_RESET(field->class);
1298 }
1299
1300 static
1301 void destroy_bool_field(struct bt_field *field)
1302 {
1303 BT_ASSERT(field);
1304 BT_LIB_LOGD("Destroying boolean field object: %!+f", field);
1305 bt_field_finalize(field);
1306 g_free(field);
1307 }
1308
1309 static
1310 void destroy_bit_array_field(struct bt_field *field)
1311 {
1312 BT_ASSERT(field);
1313 BT_LIB_LOGD("Destroying bit array field object: %!+f", field);
1314 bt_field_finalize(field);
1315 g_free(field);
1316 }
1317
1318 static
1319 void destroy_integer_field(struct bt_field *field)
1320 {
1321 BT_ASSERT(field);
1322 BT_LIB_LOGD("Destroying integer field object: %!+f", field);
1323 bt_field_finalize(field);
1324 g_free(field);
1325 }
1326
1327 static
1328 void destroy_real_field(struct bt_field *field)
1329 {
1330 BT_ASSERT(field);
1331 BT_LIB_LOGD("Destroying real field object: %!+f", field);
1332 bt_field_finalize(field);
1333 g_free(field);
1334 }
1335
1336 static
1337 void destroy_structure_field(struct bt_field *field)
1338 {
1339 struct bt_field_structure *struct_field = (void *) field;
1340
1341 BT_ASSERT(field);
1342 BT_LIB_LOGD("Destroying structure field object: %!+f", field);
1343 bt_field_finalize(field);
1344
1345 if (struct_field->fields) {
1346 g_ptr_array_free(struct_field->fields, TRUE);
1347 struct_field->fields = NULL;
1348 }
1349
1350 g_free(field);
1351 }
1352
1353 static
1354 void destroy_option_field(struct bt_field *field)
1355 {
1356 struct bt_field_option *opt_field = (void *) field;
1357
1358 BT_ASSERT(field);
1359 BT_LIB_LOGD("Destroying option field object: %!+f", field);
1360 bt_field_finalize(field);
1361
1362 if (opt_field->content_field) {
1363 bt_field_destroy(opt_field->content_field);
1364 }
1365
1366 g_free(field);
1367 }
1368
1369 static
1370 void destroy_variant_field(struct bt_field *field)
1371 {
1372 struct bt_field_variant *var_field = (void *) field;
1373
1374 BT_ASSERT(field);
1375 BT_LIB_LOGD("Destroying variant field object: %!+f", field);
1376 bt_field_finalize(field);
1377
1378 if (var_field->fields) {
1379 g_ptr_array_free(var_field->fields, TRUE);
1380 var_field->fields = NULL;
1381 }
1382
1383 g_free(field);
1384 }
1385
1386 static
1387 void destroy_array_field(struct bt_field *field)
1388 {
1389 struct bt_field_array *array_field = (void *) field;
1390
1391 BT_ASSERT(field);
1392 BT_LIB_LOGD("Destroying array field object: %!+f", field);
1393 bt_field_finalize(field);
1394
1395 if (array_field->fields) {
1396 g_ptr_array_free(array_field->fields, TRUE);
1397 array_field->fields = NULL;
1398 }
1399
1400 g_free(field);
1401 }
1402
1403 static
1404 void destroy_string_field(struct bt_field *field)
1405 {
1406 struct bt_field_string *string_field = (void *) field;
1407
1408 BT_ASSERT(field);
1409 BT_LIB_LOGD("Destroying string field object: %!+f", field);
1410 bt_field_finalize(field);
1411
1412 if (string_field->buf) {
1413 g_array_free(string_field->buf, TRUE);
1414 string_field->buf = NULL;
1415 }
1416
1417 g_free(field);
1418 }
1419
1420 void bt_field_destroy(struct bt_field *field)
1421 {
1422 BT_ASSERT(field);
1423
1424 switch (field->class->type) {
1425 case BT_FIELD_CLASS_TYPE_BOOL:
1426 destroy_bool_field(field);
1427 break;
1428 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
1429 destroy_bit_array_field(field);
1430 break;
1431 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
1432 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
1433 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
1434 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
1435 destroy_integer_field(field);
1436 break;
1437 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
1438 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
1439 destroy_real_field(field);
1440 break;
1441 case BT_FIELD_CLASS_TYPE_STRING:
1442 destroy_string_field(field);
1443 break;
1444 case BT_FIELD_CLASS_TYPE_STRUCTURE:
1445 destroy_structure_field(field);
1446 break;
1447 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
1448 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD:
1449 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD:
1450 destroy_array_field(field);
1451 break;
1452 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD:
1453 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD:
1454 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD:
1455 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
1456 destroy_option_field(field);
1457 break;
1458 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD:
1459 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD:
1460 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
1461 destroy_variant_field(field);
1462 break;
1463 default:
1464 bt_common_abort();
1465 }
1466 }
1467
1468 static
1469 void reset_single_field(struct bt_field *field)
1470 {
1471 BT_ASSERT_DBG(field);
1472 field->is_set = false;
1473 }
1474
1475 static
1476 void reset_structure_field(struct bt_field *field)
1477 {
1478 uint64_t i;
1479 struct bt_field_structure *struct_field = (void *) field;
1480
1481 BT_ASSERT_DBG(field);
1482
1483 for (i = 0; i < struct_field->fields->len; i++) {
1484 bt_field_reset(struct_field->fields->pdata[i]);
1485 }
1486 }
1487
1488 static
1489 void reset_option_field(struct bt_field *field)
1490 {
1491 struct bt_field_option *opt_field = (void *) field;
1492
1493 BT_ASSERT_DBG(opt_field);
1494 bt_field_reset(opt_field->content_field);
1495 opt_field->selected_field = NULL;
1496 }
1497
1498 static
1499 void reset_variant_field(struct bt_field *field)
1500 {
1501 uint64_t i;
1502 struct bt_field_variant *var_field = (void *) field;
1503
1504 BT_ASSERT_DBG(field);
1505
1506 for (i = 0; i < var_field->fields->len; i++) {
1507 bt_field_reset(var_field->fields->pdata[i]);
1508 }
1509 }
1510
1511 static
1512 void reset_array_field(struct bt_field *field)
1513 {
1514 uint64_t i;
1515 struct bt_field_array *array_field = (void *) field;
1516
1517 BT_ASSERT_DBG(field);
1518
1519 for (i = 0; i < array_field->fields->len; i++) {
1520 bt_field_reset(array_field->fields->pdata[i]);
1521 }
1522 }
1523
1524 static
1525 void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
1526 {
1527 field->frozen = is_frozen;
1528 }
1529
1530 static
1531 void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
1532 {
1533 uint64_t i;
1534 struct bt_field_structure *struct_field = (void *) field;
1535
1536 BT_LIB_LOGD("Setting structure field's frozen state: "
1537 "%![field-]+f, is-frozen=%d", field, is_frozen);
1538
1539 for (i = 0; i < struct_field->fields->len; i++) {
1540 struct bt_field *member_field = struct_field->fields->pdata[i];
1541
1542 BT_LIB_LOGD("Setting structure field's member field's "
1543 "frozen state: %![field-]+f, index=%" PRIu64,
1544 member_field, i);
1545 _bt_field_set_is_frozen(member_field, is_frozen);
1546 }
1547
1548 set_single_field_is_frozen(field, is_frozen);
1549 }
1550
1551 static
1552 void set_option_field_is_frozen(struct bt_field *field, bool is_frozen)
1553 {
1554 struct bt_field_option *opt_field = (void *) field;
1555
1556 BT_LIB_LOGD("Setting option field's frozen state: "
1557 "%![field-]+f, is-frozen=%d", field, is_frozen);
1558 _bt_field_set_is_frozen(opt_field->content_field, is_frozen);
1559 set_single_field_is_frozen(field, is_frozen);
1560 }
1561
1562 static
1563 void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
1564 {
1565 uint64_t i;
1566 struct bt_field_variant *var_field = (void *) field;
1567
1568 BT_LIB_LOGD("Setting variant field's frozen state: "
1569 "%![field-]+f, is-frozen=%d", field, is_frozen);
1570
1571 for (i = 0; i < var_field->fields->len; i++) {
1572 struct bt_field *option_field = var_field->fields->pdata[i];
1573
1574 BT_LIB_LOGD("Setting variant field's option field's "
1575 "frozen state: %![field-]+f, index=%" PRIu64,
1576 option_field, i);
1577 _bt_field_set_is_frozen(option_field, is_frozen);
1578 }
1579
1580 set_single_field_is_frozen(field, is_frozen);
1581 }
1582
1583 static
1584 void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
1585 {
1586 uint64_t i;
1587 struct bt_field_array *array_field = (void *) field;
1588
1589 BT_LIB_LOGD("Setting array field's frozen state: "
1590 "%![field-]+f, is-frozen=%d", field, is_frozen);
1591
1592 for (i = 0; i < array_field->fields->len; i++) {
1593 struct bt_field *elem_field = array_field->fields->pdata[i];
1594
1595 BT_LIB_LOGD("Setting array field's element field's "
1596 "frozen state: %![field-]+f, index=%" PRIu64,
1597 elem_field, i);
1598 _bt_field_set_is_frozen(elem_field, is_frozen);
1599 }
1600
1601 set_single_field_is_frozen(field, is_frozen);
1602 }
1603
1604 void _bt_field_set_is_frozen(const struct bt_field *field,
1605 bool is_frozen)
1606 {
1607 BT_ASSERT_DBG(field);
1608 BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
1609 field, is_frozen);
1610 BT_ASSERT_DBG(field->methods->set_is_frozen);
1611 field->methods->set_is_frozen((void *) field, is_frozen);
1612 }
1613
1614 static
1615 bool single_field_is_set(const struct bt_field *field)
1616 {
1617 BT_ASSERT_DBG(field);
1618 return field->is_set;
1619 }
1620
1621 static
1622 bool structure_field_is_set(const struct bt_field *field)
1623 {
1624 bool is_set = true;
1625 uint64_t i;
1626 const struct bt_field_structure *struct_field = (const void *) field;
1627
1628 BT_ASSERT_DBG(field);
1629
1630 for (i = 0; i < struct_field->fields->len; i++) {
1631 is_set = bt_field_is_set(struct_field->fields->pdata[i]);
1632 if (!is_set) {
1633 goto end;
1634 }
1635 }
1636
1637 end:
1638 return is_set;
1639 }
1640
1641 static
1642 bool option_field_is_set(const struct bt_field *field)
1643 {
1644 const struct bt_field_option *opt_field = (const void *) field;
1645 bool is_set = false;
1646
1647 BT_ASSERT_DBG(field);
1648
1649 if (opt_field->selected_field) {
1650 is_set = bt_field_is_set(opt_field->selected_field);
1651 }
1652
1653 return is_set;
1654 }
1655
1656 static
1657 bool variant_field_is_set(const struct bt_field *field)
1658 {
1659 const struct bt_field_variant *var_field = (const void *) field;
1660 bool is_set = false;
1661
1662 BT_ASSERT_DBG(field);
1663
1664 if (var_field->selected_field) {
1665 is_set = bt_field_is_set(var_field->selected_field);
1666 }
1667
1668 return is_set;
1669 }
1670
1671 static
1672 bool array_field_is_set(const struct bt_field *field)
1673 {
1674 bool is_set = true;
1675 uint64_t i;
1676 const struct bt_field_array *array_field = (const void *) field;
1677
1678 BT_ASSERT_DBG(field);
1679
1680 for (i = 0; i < array_field->length; i++) {
1681 is_set = bt_field_is_set(array_field->fields->pdata[i]);
1682 if (!is_set) {
1683 goto end;
1684 }
1685 }
1686
1687 end:
1688 return is_set;
1689 }
This page took 0.106053 seconds and 4 git commands to generate.