bt2: add option field class and field support
[babeltrace.git] / src / lib / trace-ir / field.c
1 /*
2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
3 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #define BT_LOG_TAG "LIB/FIELD"
25 #include "lib/logging.h"
26
27 #include "lib/assert-pre.h"
28 #include <babeltrace2/trace-ir/field.h>
29 #include <babeltrace2/trace-ir/field-const.h>
30 #include "lib/object.h"
31 #include "compat/compiler.h"
32 #include "compat/fcntl.h"
33 #include "common/align.h"
34 #include "common/assert.h"
35 #include <inttypes.h>
36
37 #include "field.h"
38 #include "field-class.h"
39 #include "lib/func-status.h"
40
41 static
42 void reset_single_field(struct bt_field *field);
43
44 static
45 void reset_array_field(struct bt_field *field);
46
47 static
48 void reset_structure_field(struct bt_field *field);
49
50 static
51 void reset_option_field(struct bt_field *field);
52
53 static
54 void reset_variant_field(struct bt_field *field);
55
56 static
57 void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
58
59 static
60 void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
61
62 static
63 void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
64
65 static
66 void set_option_field_is_frozen(struct bt_field *field, bool is_frozen);
67
68 static
69 void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
70
71 static
72 bool single_field_is_set(const struct bt_field *field);
73
74 static
75 bool array_field_is_set(const struct bt_field *field);
76
77 static
78 bool structure_field_is_set(const struct bt_field *field);
79
80 static
81 bool option_field_is_set(const struct bt_field *field);
82
83 static
84 bool variant_field_is_set(const struct bt_field *field);
85
86 static
87 struct bt_field_methods bool_field_methods = {
88 .set_is_frozen = set_single_field_is_frozen,
89 .is_set = single_field_is_set,
90 .reset = reset_single_field,
91 };
92
93 static
94 struct bt_field_methods integer_field_methods = {
95 .set_is_frozen = set_single_field_is_frozen,
96 .is_set = single_field_is_set,
97 .reset = reset_single_field,
98 };
99
100 static
101 struct bt_field_methods real_field_methods = {
102 .set_is_frozen = set_single_field_is_frozen,
103 .is_set = single_field_is_set,
104 .reset = reset_single_field,
105 };
106
107 static
108 struct bt_field_methods string_field_methods = {
109 .set_is_frozen = set_single_field_is_frozen,
110 .is_set = single_field_is_set,
111 .reset = reset_single_field,
112 };
113
114 static
115 struct bt_field_methods structure_field_methods = {
116 .set_is_frozen = set_structure_field_is_frozen,
117 .is_set = structure_field_is_set,
118 .reset = reset_structure_field,
119 };
120
121 static
122 struct bt_field_methods array_field_methods = {
123 .set_is_frozen = set_array_field_is_frozen,
124 .is_set = array_field_is_set,
125 .reset = reset_array_field,
126 };
127
128 static
129 struct bt_field_methods option_field_methods = {
130 .set_is_frozen = set_option_field_is_frozen,
131 .is_set = option_field_is_set,
132 .reset = reset_option_field,
133 };
134
135 static
136 struct bt_field_methods variant_field_methods = {
137 .set_is_frozen = set_variant_field_is_frozen,
138 .is_set = variant_field_is_set,
139 .reset = reset_variant_field,
140 };
141
142 static
143 struct bt_field *create_bool_field(struct bt_field_class *);
144
145 static
146 struct bt_field *create_integer_field(struct bt_field_class *);
147
148 static
149 struct bt_field *create_real_field(struct bt_field_class *);
150
151 static
152 struct bt_field *create_string_field(struct bt_field_class *);
153
154 static
155 struct bt_field *create_structure_field(struct bt_field_class *);
156
157 static
158 struct bt_field *create_static_array_field(struct bt_field_class *);
159
160 static
161 struct bt_field *create_dynamic_array_field(struct bt_field_class *);
162
163 static
164 struct bt_field *create_option_field(struct bt_field_class *);
165
166 static
167 struct bt_field *create_variant_field(struct bt_field_class *);
168
169 static
170 struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = {
171 [BT_FIELD_CLASS_TYPE_BOOL] = create_bool_field,
172 [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = create_integer_field,
173 [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = create_integer_field,
174 [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = create_integer_field,
175 [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = create_integer_field,
176 [BT_FIELD_CLASS_TYPE_REAL] = create_real_field,
177 [BT_FIELD_CLASS_TYPE_STRING] = create_string_field,
178 [BT_FIELD_CLASS_TYPE_STRUCTURE] = create_structure_field,
179 [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = create_static_array_field,
180 [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = create_dynamic_array_field,
181 [BT_FIELD_CLASS_TYPE_OPTION] = create_option_field,
182 [BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR] = create_variant_field,
183 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR] = create_variant_field,
184 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR] = create_variant_field,
185 };
186
187 static
188 void destroy_bool_field(struct bt_field *field);
189
190 static
191 void destroy_integer_field(struct bt_field *field);
192
193 static
194 void destroy_real_field(struct bt_field *field);
195
196 static
197 void destroy_string_field(struct bt_field *field);
198
199 static
200 void destroy_structure_field(struct bt_field *field);
201
202 static
203 void destroy_array_field(struct bt_field *field);
204
205 static
206 void destroy_option_field(struct bt_field *field);
207
208 static
209 void destroy_variant_field(struct bt_field *field);
210
211 static
212 void (* const field_destroy_funcs[])(struct bt_field *) = {
213 [BT_FIELD_CLASS_TYPE_BOOL] = destroy_bool_field,
214 [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = destroy_integer_field,
215 [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = destroy_integer_field,
216 [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = destroy_integer_field,
217 [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = destroy_integer_field,
218 [BT_FIELD_CLASS_TYPE_REAL] = destroy_real_field,
219 [BT_FIELD_CLASS_TYPE_STRING] = destroy_string_field,
220 [BT_FIELD_CLASS_TYPE_STRUCTURE] = destroy_structure_field,
221 [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = destroy_array_field,
222 [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = destroy_array_field,
223 [BT_FIELD_CLASS_TYPE_OPTION] = destroy_option_field,
224 [BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR] = destroy_variant_field,
225 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR] = destroy_variant_field,
226 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR] = destroy_variant_field,
227 };
228
229 struct bt_field_class *bt_field_borrow_class(const struct bt_field *field)
230 {
231 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
232 return field->class;
233 }
234
235 const struct bt_field_class *bt_field_borrow_class_const(
236 const struct bt_field *field)
237 {
238 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
239 return field->class;
240 }
241
242 enum bt_field_class_type bt_field_get_class_type(const struct bt_field *field)
243 {
244 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
245 return field->class->type;
246 }
247
248 BT_HIDDEN
249 struct bt_field *bt_field_create(struct bt_field_class *fc)
250 {
251 struct bt_field *field = NULL;
252
253 BT_ASSERT(fc);
254 field = field_create_funcs[fc->type](fc);
255 if (!field) {
256 BT_LIB_LOGE_APPEND_CAUSE("Cannot create field object from field class: "
257 "%![fc-]+F", fc);
258 goto end;
259 }
260
261 end:
262 return field;
263 }
264
265 static inline
266 void init_field(struct bt_field *field, struct bt_field_class *fc,
267 struct bt_field_methods *methods)
268 {
269 BT_ASSERT(field);
270 BT_ASSERT(fc);
271 bt_object_init_unique(&field->base);
272 field->methods = methods;
273 field->class = fc;
274 bt_object_get_no_null_check(fc);
275 }
276
277 static
278 struct bt_field *create_bool_field(struct bt_field_class *fc)
279 {
280 struct bt_field_bool *bool_field;
281
282 BT_LIB_LOGD("Creating boolean field object: %![fc-]+F", fc);
283 bool_field = g_new0(struct bt_field_bool, 1);
284 if (!bool_field) {
285 BT_LIB_LOGE_APPEND_CAUSE(
286 "Failed to allocate one boolean field.");
287 goto end;
288 }
289
290 init_field((void *) bool_field, fc, &bool_field_methods);
291 BT_LIB_LOGD("Created boolean field object: %!+f", bool_field);
292
293 end:
294 return (void *) bool_field;
295 }
296
297 static
298 struct bt_field *create_integer_field(struct bt_field_class *fc)
299 {
300 struct bt_field_integer *int_field;
301
302 BT_LIB_LOGD("Creating integer field object: %![fc-]+F", fc);
303 int_field = g_new0(struct bt_field_integer, 1);
304 if (!int_field) {
305 BT_LIB_LOGE_APPEND_CAUSE(
306 "Failed to allocate one integer field.");
307 goto end;
308 }
309
310 init_field((void *) int_field, fc, &integer_field_methods);
311 BT_LIB_LOGD("Created integer field object: %!+f", int_field);
312
313 end:
314 return (void *) int_field;
315 }
316
317 static
318 struct bt_field *create_real_field(struct bt_field_class *fc)
319 {
320 struct bt_field_real *real_field;
321
322 BT_LIB_LOGD("Creating real field object: %![fc-]+F", fc);
323 real_field = g_new0(struct bt_field_real, 1);
324 if (!real_field) {
325 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field.");
326 goto end;
327 }
328
329 init_field((void *) real_field, fc, &real_field_methods);
330 BT_LIB_LOGD("Created real field object: %!+f", real_field);
331
332 end:
333 return (void *) real_field;
334 }
335
336 static
337 struct bt_field *create_string_field(struct bt_field_class *fc)
338 {
339 struct bt_field_string *string_field;
340
341 BT_LIB_LOGD("Creating string field object: %![fc-]+F", fc);
342 string_field = g_new0(struct bt_field_string, 1);
343 if (!string_field) {
344 BT_LIB_LOGE_APPEND_CAUSE(
345 "Failed to allocate one string field.");
346 goto end;
347 }
348
349 init_field((void *) string_field, fc, &string_field_methods);
350 string_field->buf = g_array_sized_new(FALSE, FALSE,
351 sizeof(char), 1);
352 if (!string_field->buf) {
353 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
354 BT_OBJECT_PUT_REF_AND_RESET(string_field);
355 goto end;
356 }
357
358 g_array_index(string_field->buf, char, 0) = '\0';
359 BT_LIB_LOGD("Created string field object: %!+f", string_field);
360
361 end:
362 return (void *) string_field;
363 }
364
365 static inline
366 int create_fields_from_named_field_classes(
367 struct bt_field_class_named_field_class_container *fc,
368 GPtrArray **fields)
369 {
370 int ret = 0;
371 uint64_t i;
372
373 *fields = g_ptr_array_new_with_free_func(
374 (GDestroyNotify) bt_field_destroy);
375 if (!*fields) {
376 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
377 ret = -1;
378 goto end;
379 }
380
381 g_ptr_array_set_size(*fields, fc->named_fcs->len);
382
383 for (i = 0; i < fc->named_fcs->len; i++) {
384 struct bt_field *field;
385 struct bt_named_field_class *named_fc = fc->named_fcs->pdata[i];
386
387 field = bt_field_create(named_fc->fc);
388 if (!field) {
389 BT_LIB_LOGE_APPEND_CAUSE(
390 "Failed to create structure member or variant option field: "
391 "name=\"%s\", %![fc-]+F",
392 named_fc->name->str, named_fc->fc);
393 ret = -1;
394 goto end;
395 }
396
397 g_ptr_array_index(*fields, i) = field;
398 }
399
400 end:
401 return ret;
402 }
403
404 static
405 struct bt_field *create_structure_field(struct bt_field_class *fc)
406 {
407 struct bt_field_structure *struct_field;
408
409 BT_LIB_LOGD("Creating structure field object: %![fc-]+F", fc);
410 struct_field = g_new0(struct bt_field_structure, 1);
411 if (!struct_field) {
412 BT_LIB_LOGE_APPEND_CAUSE(
413 "Failed to allocate one structure field.");
414 goto end;
415 }
416
417 init_field((void *) struct_field, fc, &structure_field_methods);
418
419 if (create_fields_from_named_field_classes((void *) fc,
420 &struct_field->fields)) {
421 BT_LIB_LOGE_APPEND_CAUSE(
422 "Cannot create structure member fields: %![fc-]+F", fc);
423 BT_OBJECT_PUT_REF_AND_RESET(struct_field);
424 goto end;
425 }
426
427 BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
428
429 end:
430 return (void *) struct_field;
431 }
432
433 static
434 struct bt_field *create_option_field(struct bt_field_class *fc)
435 {
436 struct bt_field_option *opt_field;
437 struct bt_field_class_option *opt_fc = (void *) fc;
438
439 BT_LIB_LOGD("Creating option field object: %![fc-]+F", fc);
440 opt_field = g_new0(struct bt_field_option, 1);
441 if (!opt_field) {
442 BT_LIB_LOGE_APPEND_CAUSE(
443 "Failed to allocate one option field.");
444 goto end;
445 }
446
447 init_field((void *) opt_field, fc, &option_field_methods);
448 opt_field->content_field = bt_field_create(opt_fc->content_fc);
449 if (!opt_field->content_field) {
450 BT_LIB_LOGE_APPEND_CAUSE(
451 "Failed to create option field's content field: "
452 "%![opt-fc-]+F, %![content-fc-]+F",
453 opt_fc, opt_fc->content_fc);
454 BT_OBJECT_PUT_REF_AND_RESET(opt_field);
455 goto end;
456 }
457
458 BT_LIB_LOGD("Created option field object: %!+f", opt_field);
459
460 end:
461 return (void *) opt_field;
462 }
463
464 static
465 struct bt_field *create_variant_field(struct bt_field_class *fc)
466 {
467 struct bt_field_variant *var_field;
468
469 BT_LIB_LOGD("Creating variant field object: %![fc-]+F", fc);
470 var_field = g_new0(struct bt_field_variant, 1);
471 if (!var_field) {
472 BT_LIB_LOGE_APPEND_CAUSE(
473 "Failed to allocate one variant field.");
474 goto end;
475 }
476
477 init_field((void *) var_field, fc, &variant_field_methods);
478
479 if (create_fields_from_named_field_classes((void *) fc,
480 &var_field->fields)) {
481 BT_LIB_LOGE_APPEND_CAUSE("Cannot create variant member fields: "
482 "%![fc-]+F", fc);
483 BT_OBJECT_PUT_REF_AND_RESET(var_field);
484 goto end;
485 }
486
487 BT_LIB_LOGD("Created variant field object: %!+f", var_field);
488
489 end:
490 return (void *) var_field;
491 }
492
493 static inline
494 int init_array_field_fields(struct bt_field_array *array_field)
495 {
496 int ret = 0;
497 uint64_t i;
498 struct bt_field_class_array *array_fc;
499
500 BT_ASSERT(array_field);
501 array_fc = (void *) array_field->common.class;
502 array_field->fields = g_ptr_array_sized_new(array_field->length);
503 if (!array_field->fields) {
504 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
505 ret = -1;
506 goto end;
507 }
508
509 g_ptr_array_set_free_func(array_field->fields,
510 (GDestroyNotify) bt_field_destroy);
511 g_ptr_array_set_size(array_field->fields, array_field->length);
512
513 for (i = 0; i < array_field->length; i++) {
514 array_field->fields->pdata[i] = bt_field_create(
515 array_fc->element_fc);
516 if (!array_field->fields->pdata[i]) {
517 BT_LIB_LOGE_APPEND_CAUSE(
518 "Cannot create array field's element field: "
519 "index=%" PRIu64 ", %![fc-]+F", i, array_fc);
520 ret = -1;
521 goto end;
522 }
523 }
524
525 end:
526 return ret;
527 }
528
529 static
530 struct bt_field *create_static_array_field(struct bt_field_class *fc)
531 {
532 struct bt_field_class_array_static *array_fc = (void *) fc;
533 struct bt_field_array *array_field;
534
535 BT_LIB_LOGD("Creating static array field object: %![fc-]+F", fc);
536 array_field = g_new0(struct bt_field_array, 1);
537 if (!array_field) {
538 BT_LIB_LOGE_APPEND_CAUSE(
539 "Failed to allocate one static array field.");
540 goto end;
541 }
542
543 init_field((void *) array_field, fc, &array_field_methods);
544 array_field->length = array_fc->length;
545
546 if (init_array_field_fields(array_field)) {
547 BT_LIB_LOGE_APPEND_CAUSE("Cannot create static array fields: "
548 "%![fc-]+F", fc);
549 BT_OBJECT_PUT_REF_AND_RESET(array_field);
550 goto end;
551 }
552
553 BT_LIB_LOGD("Created static array field object: %!+f", array_field);
554
555 end:
556 return (void *) array_field;
557 }
558
559 static
560 struct bt_field *create_dynamic_array_field(struct bt_field_class *fc)
561 {
562 struct bt_field_array *array_field;
563
564 BT_LIB_LOGD("Creating dynamic array field object: %![fc-]+F", fc);
565 array_field = g_new0(struct bt_field_array, 1);
566 if (!array_field) {
567 BT_LIB_LOGE_APPEND_CAUSE(
568 "Failed to allocate one dynamic array field.");
569 goto end;
570 }
571
572 init_field((void *) array_field, fc, &array_field_methods);
573
574 if (init_array_field_fields(array_field)) {
575 BT_LIB_LOGE_APPEND_CAUSE("Cannot create dynamic array fields: "
576 "%![fc-]+F", fc);
577 BT_OBJECT_PUT_REF_AND_RESET(array_field);
578 goto end;
579 }
580
581 BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
582
583 end:
584 return (void *) array_field;
585 }
586
587 bt_bool bt_field_bool_get_value(const struct bt_field *field)
588 {
589 const struct bt_field_bool *bool_field = (const void *) field;
590
591 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
592 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
593 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_BOOL,
594 "Field");
595 return (bt_bool) bool_field->value;
596 }
597
598 void bt_field_bool_set_value(struct bt_field *field, bt_bool value)
599 {
600 struct bt_field_bool *bool_field = (void *) field;
601
602 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
603 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_BOOL,
604 "Field");
605 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
606 bool_field->value = (bool) value;
607 bt_field_set_single(field, true);
608 }
609
610 int64_t bt_field_integer_signed_get_value(const struct bt_field *field)
611 {
612 const struct bt_field_integer *int_field = (const void *) field;
613
614 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
615 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
616 BT_ASSERT_PRE_DEV_FIELD_IS_SIGNED_INT(field, "Field");
617 return int_field->value.i;
618 }
619
620 void bt_field_integer_signed_set_value(struct bt_field *field, int64_t value)
621 {
622 struct bt_field_integer *int_field = (void *) field;
623
624 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
625 BT_ASSERT_PRE_DEV_FIELD_IS_SIGNED_INT(field, "Field");
626 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
627 BT_ASSERT_PRE_DEV(bt_util_value_is_in_range_signed(
628 ((struct bt_field_class_integer *) field->class)->range, value),
629 "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
630 "%![fc-]+F", value, field, field->class);
631 int_field->value.i = value;
632 bt_field_set_single(field, true);
633 }
634
635 uint64_t bt_field_integer_unsigned_get_value(const struct bt_field *field)
636 {
637 const struct bt_field_integer *int_field = (const void *) field;
638
639 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
640 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
641 BT_ASSERT_PRE_DEV_FIELD_IS_UNSIGNED_INT(field, "Field");
642 return int_field->value.u;
643 }
644
645 void bt_field_integer_unsigned_set_value(struct bt_field *field, uint64_t value)
646 {
647 struct bt_field_integer *int_field = (void *) field;
648
649 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
650 BT_ASSERT_PRE_DEV_FIELD_IS_UNSIGNED_INT(field, "Field");
651 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
652 BT_ASSERT_PRE_DEV(bt_util_value_is_in_range_unsigned(
653 ((struct bt_field_class_integer *) field->class)->range, value),
654 "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
655 "%![fc-]+F", value, field, field->class);
656 int_field->value.u = value;
657 bt_field_set_single(field, true);
658 }
659
660 double bt_field_real_get_value(const struct bt_field *field)
661 {
662 const struct bt_field_real *real_field = (const void *) field;
663
664 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
665 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
666 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field");
667 return real_field->value;
668 }
669
670 void bt_field_real_set_value(struct bt_field *field, double value)
671 {
672 struct bt_field_real *real_field = (void *) field;
673
674 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
675 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field");
676 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
677 BT_ASSERT_PRE_DEV(
678 !((struct bt_field_class_real *) field->class)->is_single_precision ||
679 (double) (float) value == value,
680 "Invalid value for a single-precision real number: value=%f, "
681 "%![fc-]+F", value, field->class);
682 real_field->value = value;
683 bt_field_set_single(field, true);
684 }
685
686 enum bt_field_enumeration_get_mapping_labels_status
687 bt_field_enumeration_unsigned_get_mapping_labels(
688 const struct bt_field *field,
689 bt_field_class_enumeration_mapping_label_array *label_array,
690 uint64_t *count)
691 {
692 const struct bt_field_integer *int_field = (const void *) field;
693
694 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
695 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Label array (output)");
696 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Count (output)");
697 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
698 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
699 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field");
700 return (int)
701 bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
702 field->class, int_field->value.u, label_array, count);
703 }
704
705 enum bt_field_enumeration_get_mapping_labels_status
706 bt_field_enumeration_signed_get_mapping_labels(
707 const struct bt_field *field,
708 bt_field_class_enumeration_mapping_label_array *label_array,
709 uint64_t *count)
710 {
711 const struct bt_field_integer *int_field = (const void *) field;
712
713 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
714 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Label array (output)");
715 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Count (output)");
716 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
717 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
718 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field");
719 return (int)
720 bt_field_class_enumeration_signed_get_mapping_labels_for_value(
721 field->class, int_field->value.i, label_array, count);
722 }
723
724 const char *bt_field_string_get_value(const struct bt_field *field)
725 {
726 const struct bt_field_string *string_field = (const void *) field;
727
728 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
729 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
730 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING,
731 "Field");
732 return (const char *) string_field->buf->data;
733 }
734
735 uint64_t bt_field_string_get_length(const struct bt_field *field)
736 {
737 const struct bt_field_string *string_field = (const void *) field;
738
739 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
740 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
741 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING,
742 "Field");
743 return string_field->length;
744 }
745
746 static inline
747 void clear_string_field(struct bt_field *field)
748 {
749 struct bt_field_string *string_field = (void *) field;
750
751 BT_ASSERT(field);
752 string_field->length = 0;
753 bt_field_set_single(field, true);
754 }
755
756 enum bt_field_string_set_value_status bt_field_string_set_value(
757 struct bt_field *field, const char *value)
758 {
759 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
760 BT_ASSERT_PRE_DEV_NON_NULL(value, "Value");
761 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
762 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING,
763 "Field");
764 clear_string_field(field);
765 return (int) bt_field_string_append_with_length(field, value,
766 (uint64_t) strlen(value));
767 }
768
769 enum bt_field_string_append_status bt_field_string_append(
770 struct bt_field *field, const char *value)
771 {
772 return bt_field_string_append_with_length(field,
773 value, (uint64_t) strlen(value));
774 }
775
776 enum bt_field_string_append_status bt_field_string_append_with_length(
777 struct bt_field *field, const char *value, uint64_t length)
778 {
779 struct bt_field_string *string_field = (void *) field;
780 char *data;
781 uint64_t new_length;
782
783 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
784 BT_ASSERT_PRE_DEV_NON_NULL(value, "Value");
785 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
786 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
787 BT_FIELD_CLASS_TYPE_STRING, "Field");
788
789 /* Make sure no null bytes are appended */
790 BT_ASSERT_PRE_DEV(!memchr(value, '\0', length),
791 "String value to append contains a null character: "
792 "partial-value=\"%.32s\", length=%" PRIu64, value, length);
793
794 new_length = length + string_field->length;
795
796 if (G_UNLIKELY(new_length + 1 > string_field->buf->len)) {
797 g_array_set_size(string_field->buf, new_length + 1);
798 }
799
800 data = string_field->buf->data;
801 memcpy(data + string_field->length, value, length);
802 ((char *) string_field->buf->data)[new_length] = '\0';
803 string_field->length = new_length;
804 bt_field_set_single(field, true);
805 return BT_FUNC_STATUS_OK;
806 }
807
808 void bt_field_string_clear(struct bt_field *field)
809 {
810 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
811 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
812 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
813 BT_FIELD_CLASS_TYPE_STRING, "Field");
814 clear_string_field(field);
815 }
816
817 uint64_t bt_field_array_get_length(const struct bt_field *field)
818 {
819 const struct bt_field_array *array_field = (const void *) field;
820
821 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
822 BT_ASSERT_PRE_DEV_FIELD_IS_ARRAY(field, "Field");
823 return array_field->length;
824 }
825
826 enum bt_field_array_dynamic_set_length_status bt_field_array_dynamic_set_length(
827 struct bt_field *field, uint64_t length)
828 {
829 int ret = BT_FUNC_STATUS_OK;
830 struct bt_field_array *array_field = (void *) field;
831
832 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
833 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
834 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, "Field");
835 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
836
837 if (G_UNLIKELY(length > array_field->fields->len)) {
838 /* Make more room */
839 struct bt_field_class_array *array_fc;
840 uint64_t cur_len = array_field->fields->len;
841 uint64_t i;
842
843 g_ptr_array_set_size(array_field->fields, length);
844 array_fc = (void *) field->class;
845
846 for (i = cur_len; i < array_field->fields->len; i++) {
847 struct bt_field *elem_field = bt_field_create(
848 array_fc->element_fc);
849
850 if (!elem_field) {
851 BT_LIB_LOGE_APPEND_CAUSE(
852 "Cannot create element field for "
853 "dynamic array field: "
854 "index=%" PRIu64 ", "
855 "%![array-field-]+f", i, field);
856 ret = BT_FUNC_STATUS_MEMORY_ERROR;
857 goto end;
858 }
859
860 BT_ASSERT(!array_field->fields->pdata[i]);
861 array_field->fields->pdata[i] = elem_field;
862 }
863 }
864
865 array_field->length = length;
866
867 end:
868 return ret;
869 }
870
871 static inline
872 struct bt_field *borrow_array_field_element_field_by_index(
873 struct bt_field *field, uint64_t index)
874 {
875 struct bt_field_array *array_field = (void *) field;
876
877 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
878 BT_ASSERT_PRE_DEV_FIELD_IS_ARRAY(field, "Field");
879 BT_ASSERT_PRE_DEV_VALID_INDEX(index, array_field->length);
880 return array_field->fields->pdata[index];
881 }
882
883 struct bt_field *bt_field_array_borrow_element_field_by_index(
884 struct bt_field *field, uint64_t index)
885 {
886 return borrow_array_field_element_field_by_index(field, index);
887 }
888
889 const struct bt_field *
890 bt_field_array_borrow_element_field_by_index_const(
891 const struct bt_field *field, uint64_t index)
892 {
893 return borrow_array_field_element_field_by_index((void *) field, index);
894 }
895
896 static inline
897 struct bt_field *borrow_structure_field_member_field_by_index(
898 struct bt_field *field, uint64_t index)
899 {
900 struct bt_field_structure *struct_field = (void *) field;
901
902 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
903 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
904 BT_FIELD_CLASS_TYPE_STRUCTURE, "Field");
905 BT_ASSERT_PRE_DEV_VALID_INDEX(index, struct_field->fields->len);
906 return struct_field->fields->pdata[index];
907 }
908
909 struct bt_field *bt_field_structure_borrow_member_field_by_index(
910 struct bt_field *field, uint64_t index)
911 {
912 return borrow_structure_field_member_field_by_index(field,
913 index);
914 }
915
916 const struct bt_field *
917 bt_field_structure_borrow_member_field_by_index_const(
918 const struct bt_field *field, uint64_t index)
919 {
920 return borrow_structure_field_member_field_by_index(
921 (void *) field, index);
922 }
923
924 static inline
925 struct bt_field *borrow_structure_field_member_field_by_name(
926 struct bt_field *field, const char *name)
927 {
928 struct bt_field *ret_field = NULL;
929 struct bt_field_class_structure *struct_fc;
930 struct bt_field_structure *struct_field = (void *) field;
931 gpointer orig_key;
932 gpointer index;
933
934 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
935 BT_ASSERT_PRE_DEV_NON_NULL(name, "Field name");
936 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
937 BT_FIELD_CLASS_TYPE_STRUCTURE, "Field");
938 struct_fc = (void *) field->class;
939
940 if (!g_hash_table_lookup_extended(struct_fc->common.name_to_index, name,
941 &orig_key, &index)) {
942 goto end;
943 }
944
945 ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
946 BT_ASSERT(ret_field);
947
948 end:
949 return ret_field;
950 }
951
952 struct bt_field *bt_field_structure_borrow_member_field_by_name(
953 struct bt_field *field, const char *name)
954 {
955 return borrow_structure_field_member_field_by_name(field, name);
956 }
957
958 const struct bt_field *bt_field_structure_borrow_member_field_by_name_const(
959 const struct bt_field *field, const char *name)
960 {
961 return borrow_structure_field_member_field_by_name(
962 (void *) field, name);
963 }
964
965 void bt_field_option_set_has_field(struct bt_field *field, bt_bool has_field)
966 {
967 struct bt_field_option *opt_field = (void *) field;
968
969 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
970 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
971 BT_FIELD_CLASS_TYPE_OPTION, "Field");
972 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
973
974 if (has_field) {
975 opt_field->selected_field = opt_field->content_field;
976 } else {
977 opt_field->selected_field = NULL;
978 }
979 }
980
981 struct bt_field *bt_field_option_borrow_field(struct bt_field *field)
982 {
983 struct bt_field_option *opt_field = (void *) field;
984
985 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
986 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
987 BT_FIELD_CLASS_TYPE_OPTION, "Field");
988 return opt_field->selected_field;
989 }
990
991 const struct bt_field *bt_field_option_borrow_field_const(
992 const struct bt_field *field)
993 {
994 return (const void *) bt_field_option_borrow_field((void *) field);
995 }
996
997 static inline
998 struct bt_field *borrow_variant_field_selected_option_field(
999 struct bt_field *field)
1000 {
1001 struct bt_field_variant *var_field = (void *) field;
1002
1003 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
1004 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
1005 BT_ASSERT_PRE_DEV(var_field->selected_field,
1006 "Variant field has no selected field: %!+f", field);
1007 return var_field->selected_field;
1008 }
1009
1010 struct bt_field *bt_field_variant_borrow_selected_option_field(
1011 struct bt_field *field)
1012 {
1013 return borrow_variant_field_selected_option_field(field);
1014 }
1015
1016 const struct bt_field *bt_field_variant_borrow_selected_option_field_const(
1017 const struct bt_field *field)
1018 {
1019 return borrow_variant_field_selected_option_field((void *) field);
1020 }
1021
1022 static
1023 const struct bt_field_class_variant_option *
1024 borrow_variant_field_selected_class_option(const struct bt_field *field)
1025 {
1026 const struct bt_field_class_named_field_class_container *container_fc;
1027 const struct bt_field_variant *var_field = (const void *) field;
1028
1029 BT_ASSERT(field);
1030 BT_ASSERT_PRE_DEV(var_field->selected_field,
1031 "Variant field has no selected field: %!+f", field);
1032 container_fc = (const void *) field->class;
1033 return container_fc->named_fcs->pdata[var_field->selected_index];
1034 }
1035
1036 const struct bt_field_class_variant_option *
1037 bt_field_variant_borrow_selected_class_option_const(
1038 const struct bt_field *field)
1039 {
1040 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
1041 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
1042 return borrow_variant_field_selected_class_option(field);
1043 }
1044
1045 const struct bt_field_class_variant_with_selector_unsigned_option *
1046 bt_field_variant_with_unsigned_selector_borrow_selected_class_option_const(
1047 const struct bt_field *field)
1048 {
1049 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
1050 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
1051 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR, "Field");
1052 return (const void *) borrow_variant_field_selected_class_option(field);
1053 }
1054
1055 const struct bt_field_class_variant_with_selector_signed_option *
1056 bt_field_variant_with_signed_selector_borrow_selected_class_option_const(
1057 const struct bt_field *field)
1058 {
1059 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
1060 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
1061 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR, "Field");
1062 return (const void *) borrow_variant_field_selected_class_option(field);
1063 }
1064
1065 enum bt_field_variant_select_option_field_by_index_status
1066 bt_field_variant_select_option_field_by_index(
1067 struct bt_field *field, uint64_t index)
1068 {
1069 struct bt_field_variant *var_field = (void *) field;
1070
1071 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
1072 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
1073 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
1074 BT_ASSERT_PRE_DEV_VALID_INDEX(index, var_field->fields->len);
1075 var_field->selected_field = var_field->fields->pdata[index];
1076 var_field->selected_index = index;
1077 return BT_FUNC_STATUS_OK;
1078 }
1079
1080 uint64_t bt_field_variant_get_selected_option_field_index(
1081 const struct bt_field *field)
1082 {
1083 const struct bt_field_variant *var_field = (const void *) field;
1084
1085 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
1086 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
1087 BT_ASSERT_PRE_DEV(var_field->selected_field,
1088 "Variant field has no selected field: %!+f", field);
1089 return var_field->selected_index;
1090 }
1091
1092 static inline
1093 void bt_field_finalize(struct bt_field *field)
1094 {
1095 BT_ASSERT(field);
1096 BT_LOGD_STR("Putting field's class.");
1097 BT_OBJECT_PUT_REF_AND_RESET(field->class);
1098 }
1099
1100 static
1101 void destroy_bool_field(struct bt_field *field)
1102 {
1103 BT_ASSERT(field);
1104 BT_LIB_LOGD("Destroying boolean field object: %!+f", field);
1105 bt_field_finalize(field);
1106 g_free(field);
1107 }
1108
1109 static
1110 void destroy_integer_field(struct bt_field *field)
1111 {
1112 BT_ASSERT(field);
1113 BT_LIB_LOGD("Destroying integer field object: %!+f", field);
1114 bt_field_finalize(field);
1115 g_free(field);
1116 }
1117
1118 static
1119 void destroy_real_field(struct bt_field *field)
1120 {
1121 BT_ASSERT(field);
1122 BT_LIB_LOGD("Destroying real field object: %!+f", field);
1123 bt_field_finalize(field);
1124 g_free(field);
1125 }
1126
1127 static
1128 void destroy_structure_field(struct bt_field *field)
1129 {
1130 struct bt_field_structure *struct_field = (void *) field;
1131
1132 BT_ASSERT(field);
1133 BT_LIB_LOGD("Destroying structure field object: %!+f", field);
1134 bt_field_finalize(field);
1135
1136 if (struct_field->fields) {
1137 g_ptr_array_free(struct_field->fields, TRUE);
1138 struct_field->fields = NULL;
1139 }
1140
1141 g_free(field);
1142 }
1143
1144 static
1145 void destroy_option_field(struct bt_field *field)
1146 {
1147 struct bt_field_option *opt_field = (void *) field;
1148
1149 BT_ASSERT(field);
1150 BT_LIB_LOGD("Destroying option field object: %!+f", field);
1151 bt_field_finalize(field);
1152
1153 if (opt_field->content_field) {
1154 bt_field_destroy(opt_field->content_field);
1155 }
1156
1157 g_free(field);
1158 }
1159
1160 static
1161 void destroy_variant_field(struct bt_field *field)
1162 {
1163 struct bt_field_variant *var_field = (void *) field;
1164
1165 BT_ASSERT(field);
1166 BT_LIB_LOGD("Destroying variant field object: %!+f", field);
1167 bt_field_finalize(field);
1168
1169 if (var_field->fields) {
1170 g_ptr_array_free(var_field->fields, TRUE);
1171 var_field->fields = NULL;
1172 }
1173
1174 g_free(field);
1175 }
1176
1177 static
1178 void destroy_array_field(struct bt_field *field)
1179 {
1180 struct bt_field_array *array_field = (void *) field;
1181
1182 BT_ASSERT(field);
1183 BT_LIB_LOGD("Destroying array field object: %!+f", field);
1184 bt_field_finalize(field);
1185
1186 if (array_field->fields) {
1187 g_ptr_array_free(array_field->fields, TRUE);
1188 array_field->fields = NULL;
1189 }
1190
1191 g_free(field);
1192 }
1193
1194 static
1195 void destroy_string_field(struct bt_field *field)
1196 {
1197 struct bt_field_string *string_field = (void *) field;
1198
1199 BT_ASSERT(field);
1200 BT_LIB_LOGD("Destroying string field object: %!+f", field);
1201 bt_field_finalize(field);
1202
1203 if (string_field->buf) {
1204 g_array_free(string_field->buf, TRUE);
1205 string_field->buf = NULL;
1206 }
1207
1208 g_free(field);
1209 }
1210
1211 BT_HIDDEN
1212 void bt_field_destroy(struct bt_field *field)
1213 {
1214 BT_ASSERT(field);
1215 field_destroy_funcs[field->class->type](field);
1216 }
1217
1218 static
1219 void reset_single_field(struct bt_field *field)
1220 {
1221 BT_ASSERT(field);
1222 field->is_set = false;
1223 }
1224
1225 static
1226 void reset_structure_field(struct bt_field *field)
1227 {
1228 uint64_t i;
1229 struct bt_field_structure *struct_field = (void *) field;
1230
1231 BT_ASSERT(field);
1232
1233 for (i = 0; i < struct_field->fields->len; i++) {
1234 bt_field_reset(struct_field->fields->pdata[i]);
1235 }
1236 }
1237
1238 static
1239 void reset_option_field(struct bt_field *field)
1240 {
1241 struct bt_field_option *opt_field = (void *) field;
1242
1243 BT_ASSERT(opt_field);
1244 bt_field_reset(opt_field->content_field);
1245 opt_field->selected_field = NULL;
1246 }
1247
1248 static
1249 void reset_variant_field(struct bt_field *field)
1250 {
1251 uint64_t i;
1252 struct bt_field_variant *var_field = (void *) field;
1253
1254 BT_ASSERT(field);
1255
1256 for (i = 0; i < var_field->fields->len; i++) {
1257 bt_field_reset(var_field->fields->pdata[i]);
1258 }
1259 }
1260
1261 static
1262 void reset_array_field(struct bt_field *field)
1263 {
1264 uint64_t i;
1265 struct bt_field_array *array_field = (void *) field;
1266
1267 BT_ASSERT(field);
1268
1269 for (i = 0; i < array_field->fields->len; i++) {
1270 bt_field_reset(array_field->fields->pdata[i]);
1271 }
1272 }
1273
1274 static
1275 void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
1276 {
1277 field->frozen = is_frozen;
1278 }
1279
1280 static
1281 void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
1282 {
1283 uint64_t i;
1284 struct bt_field_structure *struct_field = (void *) field;
1285
1286 BT_LIB_LOGD("Setting structure field's frozen state: "
1287 "%![field-]+f, is-frozen=%d", field, is_frozen);
1288
1289 for (i = 0; i < struct_field->fields->len; i++) {
1290 struct bt_field *member_field = struct_field->fields->pdata[i];
1291
1292 BT_LIB_LOGD("Setting structure field's member field's "
1293 "frozen state: %![field-]+f, index=%" PRIu64,
1294 member_field, i);
1295 _bt_field_set_is_frozen(member_field, is_frozen);
1296 }
1297
1298 set_single_field_is_frozen(field, is_frozen);
1299 }
1300
1301 static
1302 void set_option_field_is_frozen(struct bt_field *field, bool is_frozen)
1303 {
1304 struct bt_field_option *opt_field = (void *) field;
1305
1306 BT_LIB_LOGD("Setting option field's frozen state: "
1307 "%![field-]+f, is-frozen=%d", field, is_frozen);
1308 _bt_field_set_is_frozen(opt_field->content_field, is_frozen);
1309 set_single_field_is_frozen(field, is_frozen);
1310 }
1311
1312 static
1313 void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
1314 {
1315 uint64_t i;
1316 struct bt_field_variant *var_field = (void *) field;
1317
1318 BT_LIB_LOGD("Setting variant field's frozen state: "
1319 "%![field-]+f, is-frozen=%d", field, is_frozen);
1320
1321 for (i = 0; i < var_field->fields->len; i++) {
1322 struct bt_field *option_field = var_field->fields->pdata[i];
1323
1324 BT_LIB_LOGD("Setting variant field's option field's "
1325 "frozen state: %![field-]+f, index=%" PRIu64,
1326 option_field, i);
1327 _bt_field_set_is_frozen(option_field, is_frozen);
1328 }
1329
1330 set_single_field_is_frozen(field, is_frozen);
1331 }
1332
1333 static
1334 void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
1335 {
1336 uint64_t i;
1337 struct bt_field_array *array_field = (void *) field;
1338
1339 BT_LIB_LOGD("Setting array field's frozen state: "
1340 "%![field-]+f, is-frozen=%d", field, is_frozen);
1341
1342 for (i = 0; i < array_field->fields->len; i++) {
1343 struct bt_field *elem_field = array_field->fields->pdata[i];
1344
1345 BT_LIB_LOGD("Setting array field's element field's "
1346 "frozen state: %![field-]+f, index=%" PRIu64,
1347 elem_field, i);
1348 _bt_field_set_is_frozen(elem_field, is_frozen);
1349 }
1350
1351 set_single_field_is_frozen(field, is_frozen);
1352 }
1353
1354 BT_HIDDEN
1355 void _bt_field_set_is_frozen(const struct bt_field *field,
1356 bool is_frozen)
1357 {
1358 BT_ASSERT(field);
1359 BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
1360 field, is_frozen);
1361 BT_ASSERT(field->methods->set_is_frozen);
1362 field->methods->set_is_frozen((void *) field, is_frozen);
1363 }
1364
1365 static
1366 bool single_field_is_set(const struct bt_field *field)
1367 {
1368 BT_ASSERT(field);
1369 return field->is_set;
1370 }
1371
1372 static
1373 bool structure_field_is_set(const struct bt_field *field)
1374 {
1375 bool is_set = true;
1376 uint64_t i;
1377 const struct bt_field_structure *struct_field = (const void *) field;
1378
1379 BT_ASSERT(field);
1380
1381 for (i = 0; i < struct_field->fields->len; i++) {
1382 is_set = bt_field_is_set(struct_field->fields->pdata[i]);
1383 if (!is_set) {
1384 goto end;
1385 }
1386 }
1387
1388 end:
1389 return is_set;
1390 }
1391
1392 static
1393 bool option_field_is_set(const struct bt_field *field)
1394 {
1395 const struct bt_field_option *opt_field = (const void *) field;
1396 bool is_set = false;
1397
1398 BT_ASSERT(field);
1399
1400 if (opt_field->selected_field) {
1401 is_set = bt_field_is_set(opt_field->selected_field);
1402 }
1403
1404 return is_set;
1405 }
1406
1407 static
1408 bool variant_field_is_set(const struct bt_field *field)
1409 {
1410 const struct bt_field_variant *var_field = (const void *) field;
1411 bool is_set = false;
1412
1413 BT_ASSERT(field);
1414
1415 if (var_field->selected_field) {
1416 is_set = bt_field_is_set(var_field->selected_field);
1417 }
1418
1419 return is_set;
1420 }
1421
1422 static
1423 bool array_field_is_set(const struct bt_field *field)
1424 {
1425 bool is_set = true;
1426 uint64_t i;
1427 const struct bt_field_array *array_field = (const void *) field;
1428
1429 BT_ASSERT(field);
1430
1431 for (i = 0; i < array_field->length; i++) {
1432 is_set = bt_field_is_set(array_field->fields->pdata[i]);
1433 if (!is_set) {
1434 goto end;
1435 }
1436 }
1437
1438 end:
1439 return is_set;
1440 }
This page took 0.061193 seconds and 5 git commands to generate.