bt2: cleanup: Remove unused `_StreamClass` id setter
[babeltrace.git] / src / lib / trace-ir / field.c
... / ...
CommitLineData
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
41static
42void reset_single_field(struct bt_field *field);
43
44static
45void reset_array_field(struct bt_field *field);
46
47static
48void reset_structure_field(struct bt_field *field);
49
50static
51void reset_variant_field(struct bt_field *field);
52
53static
54void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
55
56static
57void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
58
59static
60void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
61
62static
63void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
64
65static
66bool single_field_is_set(const struct bt_field *field);
67
68static
69bool array_field_is_set(const struct bt_field *field);
70
71static
72bool structure_field_is_set(const struct bt_field *field);
73
74static
75bool variant_field_is_set(const struct bt_field *field);
76
77static
78struct bt_field_methods integer_field_methods = {
79 .set_is_frozen = set_single_field_is_frozen,
80 .is_set = single_field_is_set,
81 .reset = reset_single_field,
82};
83
84static
85struct bt_field_methods real_field_methods = {
86 .set_is_frozen = set_single_field_is_frozen,
87 .is_set = single_field_is_set,
88 .reset = reset_single_field,
89};
90
91static
92struct bt_field_methods string_field_methods = {
93 .set_is_frozen = set_single_field_is_frozen,
94 .is_set = single_field_is_set,
95 .reset = reset_single_field,
96};
97
98static
99struct bt_field_methods structure_field_methods = {
100 .set_is_frozen = set_structure_field_is_frozen,
101 .is_set = structure_field_is_set,
102 .reset = reset_structure_field,
103};
104
105static
106struct bt_field_methods array_field_methods = {
107 .set_is_frozen = set_array_field_is_frozen,
108 .is_set = array_field_is_set,
109 .reset = reset_array_field,
110};
111
112static
113struct bt_field_methods variant_field_methods = {
114 .set_is_frozen = set_variant_field_is_frozen,
115 .is_set = variant_field_is_set,
116 .reset = reset_variant_field,
117};
118
119static
120struct bt_field *create_integer_field(struct bt_field_class *);
121
122static
123struct bt_field *create_real_field(struct bt_field_class *);
124
125static
126struct bt_field *create_string_field(struct bt_field_class *);
127
128static
129struct bt_field *create_structure_field(struct bt_field_class *);
130
131static
132struct bt_field *create_static_array_field(struct bt_field_class *);
133
134static
135struct bt_field *create_dynamic_array_field(struct bt_field_class *);
136
137static
138struct bt_field *create_variant_field(struct bt_field_class *);
139
140static
141struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = {
142 [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = create_integer_field,
143 [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = create_integer_field,
144 [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = create_integer_field,
145 [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = create_integer_field,
146 [BT_FIELD_CLASS_TYPE_REAL] = create_real_field,
147 [BT_FIELD_CLASS_TYPE_STRING] = create_string_field,
148 [BT_FIELD_CLASS_TYPE_STRUCTURE] = create_structure_field,
149 [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = create_static_array_field,
150 [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = create_dynamic_array_field,
151 [BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR] = create_variant_field,
152 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR] = create_variant_field,
153 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR] = create_variant_field,
154};
155
156static
157void destroy_integer_field(struct bt_field *field);
158
159static
160void destroy_real_field(struct bt_field *field);
161
162static
163void destroy_string_field(struct bt_field *field);
164
165static
166void destroy_structure_field(struct bt_field *field);
167
168static
169void destroy_array_field(struct bt_field *field);
170
171static
172void destroy_variant_field(struct bt_field *field);
173
174static
175void (* const field_destroy_funcs[])(struct bt_field *) = {
176 [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = destroy_integer_field,
177 [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = destroy_integer_field,
178 [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = destroy_integer_field,
179 [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = destroy_integer_field,
180 [BT_FIELD_CLASS_TYPE_REAL] = destroy_real_field,
181 [BT_FIELD_CLASS_TYPE_STRING] = destroy_string_field,
182 [BT_FIELD_CLASS_TYPE_STRUCTURE] = destroy_structure_field,
183 [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = destroy_array_field,
184 [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = destroy_array_field,
185 [BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR] = destroy_variant_field,
186 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR] = destroy_variant_field,
187 [BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR] = destroy_variant_field,
188};
189
190struct bt_field_class *bt_field_borrow_class(const struct bt_field *field)
191{
192 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
193 return field->class;
194}
195
196const struct bt_field_class *bt_field_borrow_class_const(
197 const struct bt_field *field)
198{
199 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
200 return field->class;
201}
202
203enum bt_field_class_type bt_field_get_class_type(const struct bt_field *field)
204{
205 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
206 return field->class->type;
207}
208
209BT_HIDDEN
210struct bt_field *bt_field_create(struct bt_field_class *fc)
211{
212 struct bt_field *field = NULL;
213
214 BT_ASSERT(fc);
215 field = field_create_funcs[fc->type](fc);
216 if (!field) {
217 BT_LIB_LOGE_APPEND_CAUSE("Cannot create field object from field class: "
218 "%![fc-]+F", fc);
219 goto end;
220 }
221
222end:
223 return field;
224}
225
226static inline
227void init_field(struct bt_field *field, struct bt_field_class *fc,
228 struct bt_field_methods *methods)
229{
230 BT_ASSERT(field);
231 BT_ASSERT(fc);
232 bt_object_init_unique(&field->base);
233 field->methods = methods;
234 field->class = fc;
235 bt_object_get_no_null_check(fc);
236}
237
238static
239struct bt_field *create_integer_field(struct bt_field_class *fc)
240{
241 struct bt_field_integer *int_field;
242
243 BT_LIB_LOGD("Creating integer field object: %![fc-]+F", fc);
244 int_field = g_new0(struct bt_field_integer, 1);
245 if (!int_field) {
246 BT_LIB_LOGE_APPEND_CAUSE(
247 "Failed to allocate one integer field.");
248 goto end;
249 }
250
251 init_field((void *) int_field, fc, &integer_field_methods);
252 BT_LIB_LOGD("Created integer field object: %!+f", int_field);
253
254end:
255 return (void *) int_field;
256}
257
258static
259struct bt_field *create_real_field(struct bt_field_class *fc)
260{
261 struct bt_field_real *real_field;
262
263 BT_LIB_LOGD("Creating real field object: %![fc-]+F", fc);
264 real_field = g_new0(struct bt_field_real, 1);
265 if (!real_field) {
266 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field.");
267 goto end;
268 }
269
270 init_field((void *) real_field, fc, &real_field_methods);
271 BT_LIB_LOGD("Created real field object: %!+f", real_field);
272
273end:
274 return (void *) real_field;
275}
276
277static
278struct bt_field *create_string_field(struct bt_field_class *fc)
279{
280 struct bt_field_string *string_field;
281
282 BT_LIB_LOGD("Creating string field object: %![fc-]+F", fc);
283 string_field = g_new0(struct bt_field_string, 1);
284 if (!string_field) {
285 BT_LIB_LOGE_APPEND_CAUSE(
286 "Failed to allocate one string field.");
287 goto end;
288 }
289
290 init_field((void *) string_field, fc, &string_field_methods);
291 string_field->buf = g_array_sized_new(FALSE, FALSE,
292 sizeof(char), 1);
293 if (!string_field->buf) {
294 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
295 BT_OBJECT_PUT_REF_AND_RESET(string_field);
296 goto end;
297 }
298
299 g_array_index(string_field->buf, char, 0) = '\0';
300 BT_LIB_LOGD("Created string field object: %!+f", string_field);
301
302end:
303 return (void *) string_field;
304}
305
306static inline
307int create_fields_from_named_field_classes(
308 struct bt_field_class_named_field_class_container *fc,
309 GPtrArray **fields)
310{
311 int ret = 0;
312 uint64_t i;
313
314 *fields = g_ptr_array_new_with_free_func(
315 (GDestroyNotify) bt_field_destroy);
316 if (!*fields) {
317 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
318 ret = -1;
319 goto end;
320 }
321
322 g_ptr_array_set_size(*fields, fc->named_fcs->len);
323
324 for (i = 0; i < fc->named_fcs->len; i++) {
325 struct bt_field *field;
326 struct bt_named_field_class *named_fc = fc->named_fcs->pdata[i];
327
328 field = bt_field_create(named_fc->fc);
329 if (!field) {
330 BT_LIB_LOGE_APPEND_CAUSE(
331 "Failed to create structure member or variant option field: "
332 "name=\"%s\", %![fc-]+F",
333 named_fc->name->str, named_fc->fc);
334 ret = -1;
335 goto end;
336 }
337
338 g_ptr_array_index(*fields, i) = field;
339 }
340
341end:
342 return ret;
343}
344
345static
346struct bt_field *create_structure_field(struct bt_field_class *fc)
347{
348 struct bt_field_structure *struct_field;
349
350 BT_LIB_LOGD("Creating structure field object: %![fc-]+F", fc);
351 struct_field = g_new0(struct bt_field_structure, 1);
352 if (!struct_field) {
353 BT_LIB_LOGE_APPEND_CAUSE(
354 "Failed to allocate one structure field.");
355 goto end;
356 }
357
358 init_field((void *) struct_field, fc, &structure_field_methods);
359
360 if (create_fields_from_named_field_classes((void *) fc,
361 &struct_field->fields)) {
362 BT_LIB_LOGE_APPEND_CAUSE(
363 "Cannot create structure member fields: %![fc-]+F", fc);
364 BT_OBJECT_PUT_REF_AND_RESET(struct_field);
365 goto end;
366 }
367
368 BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
369
370end:
371 return (void *) struct_field;
372}
373
374static
375struct bt_field *create_variant_field(struct bt_field_class *fc)
376{
377 struct bt_field_variant *var_field;
378
379 BT_LIB_LOGD("Creating variant field object: %![fc-]+F", fc);
380 var_field = g_new0(struct bt_field_variant, 1);
381 if (!var_field) {
382 BT_LIB_LOGE_APPEND_CAUSE(
383 "Failed to allocate one variant field.");
384 goto end;
385 }
386
387 init_field((void *) var_field, fc, &variant_field_methods);
388
389 if (create_fields_from_named_field_classes((void *) fc,
390 &var_field->fields)) {
391 BT_LIB_LOGE_APPEND_CAUSE("Cannot create variant member fields: "
392 "%![fc-]+F", fc);
393 BT_OBJECT_PUT_REF_AND_RESET(var_field);
394 goto end;
395 }
396
397 BT_LIB_LOGD("Created variant field object: %!+f", var_field);
398
399end:
400 return (void *) var_field;
401}
402
403static inline
404int init_array_field_fields(struct bt_field_array *array_field)
405{
406 int ret = 0;
407 uint64_t i;
408 struct bt_field_class_array *array_fc;
409
410 BT_ASSERT(array_field);
411 array_fc = (void *) array_field->common.class;
412 array_field->fields = g_ptr_array_sized_new(array_field->length);
413 if (!array_field->fields) {
414 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
415 ret = -1;
416 goto end;
417 }
418
419 g_ptr_array_set_free_func(array_field->fields,
420 (GDestroyNotify) bt_field_destroy);
421 g_ptr_array_set_size(array_field->fields, array_field->length);
422
423 for (i = 0; i < array_field->length; i++) {
424 array_field->fields->pdata[i] = bt_field_create(
425 array_fc->element_fc);
426 if (!array_field->fields->pdata[i]) {
427 BT_LIB_LOGE_APPEND_CAUSE(
428 "Cannot create array field's element field: "
429 "index=%" PRIu64 ", %![fc-]+F", i, array_fc);
430 ret = -1;
431 goto end;
432 }
433 }
434
435end:
436 return ret;
437}
438
439static
440struct bt_field *create_static_array_field(struct bt_field_class *fc)
441{
442 struct bt_field_class_array_static *array_fc = (void *) fc;
443 struct bt_field_array *array_field;
444
445 BT_LIB_LOGD("Creating static array field object: %![fc-]+F", fc);
446 array_field = g_new0(struct bt_field_array, 1);
447 if (!array_field) {
448 BT_LIB_LOGE_APPEND_CAUSE(
449 "Failed to allocate one static array field.");
450 goto end;
451 }
452
453 init_field((void *) array_field, fc, &array_field_methods);
454 array_field->length = array_fc->length;
455
456 if (init_array_field_fields(array_field)) {
457 BT_LIB_LOGE_APPEND_CAUSE("Cannot create static array fields: "
458 "%![fc-]+F", fc);
459 BT_OBJECT_PUT_REF_AND_RESET(array_field);
460 goto end;
461 }
462
463 BT_LIB_LOGD("Created static array field object: %!+f", array_field);
464
465end:
466 return (void *) array_field;
467}
468
469static
470struct bt_field *create_dynamic_array_field(struct bt_field_class *fc)
471{
472 struct bt_field_array *array_field;
473
474 BT_LIB_LOGD("Creating dynamic array field object: %![fc-]+F", fc);
475 array_field = g_new0(struct bt_field_array, 1);
476 if (!array_field) {
477 BT_LIB_LOGE_APPEND_CAUSE(
478 "Failed to allocate one dynamic array field.");
479 goto end;
480 }
481
482 init_field((void *) array_field, fc, &array_field_methods);
483
484 if (init_array_field_fields(array_field)) {
485 BT_LIB_LOGE_APPEND_CAUSE("Cannot create dynamic array fields: "
486 "%![fc-]+F", fc);
487 BT_OBJECT_PUT_REF_AND_RESET(array_field);
488 goto end;
489 }
490
491 BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
492
493end:
494 return (void *) array_field;
495}
496
497int64_t bt_field_integer_signed_get_value(const struct bt_field *field)
498{
499 const struct bt_field_integer *int_field = (const void *) field;
500
501 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
502 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
503 BT_ASSERT_PRE_DEV_FIELD_IS_SIGNED_INT(field, "Field");
504 return int_field->value.i;
505}
506
507void bt_field_integer_signed_set_value(struct bt_field *field, int64_t value)
508{
509 struct bt_field_integer *int_field = (void *) field;
510
511 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
512 BT_ASSERT_PRE_DEV_FIELD_IS_SIGNED_INT(field, "Field");
513 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
514 BT_ASSERT_PRE_DEV(bt_util_value_is_in_range_signed(
515 ((struct bt_field_class_integer *) field->class)->range, value),
516 "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
517 "%![fc-]+F", value, field, field->class);
518 int_field->value.i = value;
519 bt_field_set_single(field, true);
520}
521
522uint64_t bt_field_integer_unsigned_get_value(const struct bt_field *field)
523{
524 const struct bt_field_integer *int_field = (const void *) field;
525
526 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
527 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
528 BT_ASSERT_PRE_DEV_FIELD_IS_UNSIGNED_INT(field, "Field");
529 return int_field->value.u;
530}
531
532void bt_field_integer_unsigned_set_value(struct bt_field *field, uint64_t value)
533{
534 struct bt_field_integer *int_field = (void *) field;
535
536 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
537 BT_ASSERT_PRE_DEV_FIELD_IS_UNSIGNED_INT(field, "Field");
538 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
539 BT_ASSERT_PRE_DEV(bt_util_value_is_in_range_unsigned(
540 ((struct bt_field_class_integer *) field->class)->range, value),
541 "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
542 "%![fc-]+F", value, field, field->class);
543 int_field->value.u = value;
544 bt_field_set_single(field, true);
545}
546
547double bt_field_real_get_value(const struct bt_field *field)
548{
549 const struct bt_field_real *real_field = (const void *) field;
550
551 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
552 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
553 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field");
554 return real_field->value;
555}
556
557void bt_field_real_set_value(struct bt_field *field, double value)
558{
559 struct bt_field_real *real_field = (void *) field;
560
561 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
562 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field");
563 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
564 BT_ASSERT_PRE_DEV(
565 !((struct bt_field_class_real *) field->class)->is_single_precision ||
566 (double) (float) value == value,
567 "Invalid value for a single-precision real number: value=%f, "
568 "%![fc-]+F", value, field->class);
569 real_field->value = value;
570 bt_field_set_single(field, true);
571}
572
573enum bt_field_enumeration_get_mapping_labels_status
574bt_field_enumeration_unsigned_get_mapping_labels(
575 const struct bt_field *field,
576 bt_field_class_enumeration_mapping_label_array *label_array,
577 uint64_t *count)
578{
579 const struct bt_field_integer *int_field = (const void *) field;
580
581 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
582 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Label array (output)");
583 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Count (output)");
584 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
585 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
586 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field");
587 return (int)
588 bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
589 field->class, int_field->value.u, label_array, count);
590}
591
592enum bt_field_enumeration_get_mapping_labels_status
593bt_field_enumeration_signed_get_mapping_labels(
594 const struct bt_field *field,
595 bt_field_class_enumeration_mapping_label_array *label_array,
596 uint64_t *count)
597{
598 const struct bt_field_integer *int_field = (const void *) field;
599
600 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
601 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Label array (output)");
602 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Count (output)");
603 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
604 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
605 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field");
606 return (int)
607 bt_field_class_enumeration_signed_get_mapping_labels_for_value(
608 field->class, int_field->value.i, label_array, count);
609}
610
611const char *bt_field_string_get_value(const struct bt_field *field)
612{
613 const struct bt_field_string *string_field = (const void *) field;
614
615 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
616 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
617 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING,
618 "Field");
619 return (const char *) string_field->buf->data;
620}
621
622uint64_t bt_field_string_get_length(const struct bt_field *field)
623{
624 const struct bt_field_string *string_field = (const void *) field;
625
626 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
627 BT_ASSERT_PRE_DEV_FIELD_IS_SET(field, "Field");
628 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING,
629 "Field");
630 return string_field->length;
631}
632
633static inline
634void clear_string_field(struct bt_field *field)
635{
636 struct bt_field_string *string_field = (void *) field;
637
638 BT_ASSERT(field);
639 string_field->length = 0;
640 bt_field_set_single(field, true);
641}
642
643enum bt_field_string_set_value_status bt_field_string_set_value(
644 struct bt_field *field, const char *value)
645{
646 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
647 BT_ASSERT_PRE_DEV_NON_NULL(value, "Value");
648 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
649 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING,
650 "Field");
651 clear_string_field(field);
652 return (int) bt_field_string_append_with_length(field, value,
653 (uint64_t) strlen(value));
654}
655
656enum bt_field_string_append_status bt_field_string_append(
657 struct bt_field *field, const char *value)
658{
659 return bt_field_string_append_with_length(field,
660 value, (uint64_t) strlen(value));
661}
662
663enum bt_field_string_append_status bt_field_string_append_with_length(
664 struct bt_field *field, const char *value, uint64_t length)
665{
666 struct bt_field_string *string_field = (void *) field;
667 char *data;
668 uint64_t new_length;
669
670 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
671 BT_ASSERT_PRE_DEV_NON_NULL(value, "Value");
672 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
673 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
674 BT_FIELD_CLASS_TYPE_STRING, "Field");
675
676 /* Make sure no null bytes are appended */
677 BT_ASSERT_PRE_DEV(!memchr(value, '\0', length),
678 "String value to append contains a null character: "
679 "partial-value=\"%.32s\", length=%" PRIu64, value, length);
680
681 new_length = length + string_field->length;
682
683 if (G_UNLIKELY(new_length + 1 > string_field->buf->len)) {
684 g_array_set_size(string_field->buf, new_length + 1);
685 }
686
687 data = string_field->buf->data;
688 memcpy(data + string_field->length, value, length);
689 ((char *) string_field->buf->data)[new_length] = '\0';
690 string_field->length = new_length;
691 bt_field_set_single(field, true);
692 return BT_FUNC_STATUS_OK;
693}
694
695void bt_field_string_clear(struct bt_field *field)
696{
697 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
698 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
699 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
700 BT_FIELD_CLASS_TYPE_STRING, "Field");
701 clear_string_field(field);
702}
703
704uint64_t bt_field_array_get_length(const struct bt_field *field)
705{
706 const struct bt_field_array *array_field = (const void *) field;
707
708 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
709 BT_ASSERT_PRE_DEV_FIELD_IS_ARRAY(field, "Field");
710 return array_field->length;
711}
712
713enum bt_field_array_dynamic_set_length_status bt_field_array_dynamic_set_length(
714 struct bt_field *field, uint64_t length)
715{
716 int ret = BT_FUNC_STATUS_OK;
717 struct bt_field_array *array_field = (void *) field;
718
719 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
720 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
721 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, "Field");
722 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
723
724 if (G_UNLIKELY(length > array_field->fields->len)) {
725 /* Make more room */
726 struct bt_field_class_array *array_fc;
727 uint64_t cur_len = array_field->fields->len;
728 uint64_t i;
729
730 g_ptr_array_set_size(array_field->fields, length);
731 array_fc = (void *) field->class;
732
733 for (i = cur_len; i < array_field->fields->len; i++) {
734 struct bt_field *elem_field = bt_field_create(
735 array_fc->element_fc);
736
737 if (!elem_field) {
738 BT_LIB_LOGE_APPEND_CAUSE(
739 "Cannot create element field for "
740 "dynamic array field: "
741 "index=%" PRIu64 ", "
742 "%![array-field-]+f", i, field);
743 ret = BT_FUNC_STATUS_MEMORY_ERROR;
744 goto end;
745 }
746
747 BT_ASSERT(!array_field->fields->pdata[i]);
748 array_field->fields->pdata[i] = elem_field;
749 }
750 }
751
752 array_field->length = length;
753
754end:
755 return ret;
756}
757
758static inline
759struct bt_field *borrow_array_field_element_field_by_index(
760 struct bt_field *field, uint64_t index)
761{
762 struct bt_field_array *array_field = (void *) field;
763
764 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
765 BT_ASSERT_PRE_DEV_FIELD_IS_ARRAY(field, "Field");
766 BT_ASSERT_PRE_DEV_VALID_INDEX(index, array_field->length);
767 return array_field->fields->pdata[index];
768}
769
770struct bt_field *bt_field_array_borrow_element_field_by_index(
771 struct bt_field *field, uint64_t index)
772{
773 return borrow_array_field_element_field_by_index(field, index);
774}
775
776const struct bt_field *
777bt_field_array_borrow_element_field_by_index_const(
778 const struct bt_field *field, uint64_t index)
779{
780 return borrow_array_field_element_field_by_index((void *) field, index);
781}
782
783static inline
784struct bt_field *borrow_structure_field_member_field_by_index(
785 struct bt_field *field, uint64_t index)
786{
787 struct bt_field_structure *struct_field = (void *) field;
788
789 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
790 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
791 BT_FIELD_CLASS_TYPE_STRUCTURE, "Field");
792 BT_ASSERT_PRE_DEV_VALID_INDEX(index, struct_field->fields->len);
793 return struct_field->fields->pdata[index];
794}
795
796struct bt_field *bt_field_structure_borrow_member_field_by_index(
797 struct bt_field *field, uint64_t index)
798{
799 return borrow_structure_field_member_field_by_index(field,
800 index);
801}
802
803const struct bt_field *
804bt_field_structure_borrow_member_field_by_index_const(
805 const struct bt_field *field, uint64_t index)
806{
807 return borrow_structure_field_member_field_by_index(
808 (void *) field, index);
809}
810
811static inline
812struct bt_field *borrow_structure_field_member_field_by_name(
813 struct bt_field *field, const char *name)
814{
815 struct bt_field *ret_field = NULL;
816 struct bt_field_class_structure *struct_fc;
817 struct bt_field_structure *struct_field = (void *) field;
818 gpointer orig_key;
819 gpointer index;
820
821 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
822 BT_ASSERT_PRE_DEV_NON_NULL(name, "Field name");
823 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
824 BT_FIELD_CLASS_TYPE_STRUCTURE, "Field");
825 struct_fc = (void *) field->class;
826
827 if (!g_hash_table_lookup_extended(struct_fc->common.name_to_index, name,
828 &orig_key, &index)) {
829 goto end;
830 }
831
832 ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
833 BT_ASSERT(ret_field);
834
835end:
836 return ret_field;
837}
838
839struct bt_field *bt_field_structure_borrow_member_field_by_name(
840 struct bt_field *field, const char *name)
841{
842 return borrow_structure_field_member_field_by_name(field, name);
843}
844
845const struct bt_field *bt_field_structure_borrow_member_field_by_name_const(
846 const struct bt_field *field, const char *name)
847{
848 return borrow_structure_field_member_field_by_name(
849 (void *) field, name);
850}
851
852static inline
853struct bt_field *borrow_variant_field_selected_option_field(
854 struct bt_field *field)
855{
856 struct bt_field_variant *var_field = (void *) field;
857
858 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
859 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
860 BT_ASSERT_PRE_DEV(var_field->selected_field,
861 "Variant field has no selected field: %!+f", field);
862 return var_field->selected_field;
863}
864
865struct bt_field *bt_field_variant_borrow_selected_option_field(
866 struct bt_field *field)
867{
868 return borrow_variant_field_selected_option_field(field);
869}
870
871const struct bt_field *bt_field_variant_borrow_selected_option_field_const(
872 const struct bt_field *field)
873{
874 return borrow_variant_field_selected_option_field((void *) field);
875}
876
877static
878const struct bt_field_class_variant_option *
879borrow_variant_field_selected_class_option(const struct bt_field *field)
880{
881 const struct bt_field_class_named_field_class_container *container_fc;
882 const struct bt_field_variant *var_field = (const void *) field;
883
884 BT_ASSERT(field);
885 BT_ASSERT_PRE_DEV(var_field->selected_field,
886 "Variant field has no selected field: %!+f", field);
887 container_fc = (const void *) field->class;
888 return container_fc->named_fcs->pdata[var_field->selected_index];
889}
890
891const struct bt_field_class_variant_option *
892bt_field_variant_borrow_selected_class_option_const(
893 const struct bt_field *field)
894{
895 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
896 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
897 return borrow_variant_field_selected_class_option(field);
898}
899
900const struct bt_field_class_variant_with_selector_unsigned_option *
901bt_field_variant_with_unsigned_selector_borrow_selected_class_option_const(
902 const struct bt_field *field)
903{
904 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
905 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
906 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR, "Field");
907 return (const void *) borrow_variant_field_selected_class_option(field);
908}
909
910const struct bt_field_class_variant_with_selector_signed_option *
911bt_field_variant_with_signed_selector_borrow_selected_class_option_const(
912 const struct bt_field *field)
913{
914 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
915 BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
916 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR, "Field");
917 return (const void *) borrow_variant_field_selected_class_option(field);
918}
919
920enum bt_field_variant_select_option_field_by_index_status
921bt_field_variant_select_option_field_by_index(
922 struct bt_field *field, uint64_t index)
923{
924 struct bt_field_variant *var_field = (void *) field;
925
926 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
927 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
928 BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
929 BT_ASSERT_PRE_DEV_VALID_INDEX(index, var_field->fields->len);
930 var_field->selected_field = var_field->fields->pdata[index];
931 var_field->selected_index = index;
932 return BT_FUNC_STATUS_OK;
933}
934
935uint64_t bt_field_variant_get_selected_option_field_index(
936 const struct bt_field *field)
937{
938 const struct bt_field_variant *var_field = (const void *) field;
939
940 BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
941 BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
942 BT_ASSERT_PRE_DEV(var_field->selected_field,
943 "Variant field has no selected field: %!+f", field);
944 return var_field->selected_index;
945}
946
947static inline
948void bt_field_finalize(struct bt_field *field)
949{
950 BT_ASSERT(field);
951 BT_LOGD_STR("Putting field's class.");
952 BT_OBJECT_PUT_REF_AND_RESET(field->class);
953}
954
955static
956void destroy_integer_field(struct bt_field *field)
957{
958 BT_ASSERT(field);
959 BT_LIB_LOGD("Destroying integer field object: %!+f", field);
960 bt_field_finalize(field);
961 g_free(field);
962}
963
964static
965void destroy_real_field(struct bt_field *field)
966{
967 BT_ASSERT(field);
968 BT_LIB_LOGD("Destroying real field object: %!+f", field);
969 bt_field_finalize(field);
970 g_free(field);
971}
972
973static
974void destroy_structure_field(struct bt_field *field)
975{
976 struct bt_field_structure *struct_field = (void *) field;
977
978 BT_ASSERT(field);
979 BT_LIB_LOGD("Destroying structure field object: %!+f", field);
980 bt_field_finalize(field);
981
982 if (struct_field->fields) {
983 g_ptr_array_free(struct_field->fields, TRUE);
984 struct_field->fields = NULL;
985 }
986
987 g_free(field);
988}
989
990static
991void destroy_variant_field(struct bt_field *field)
992{
993 struct bt_field_variant *var_field = (void *) field;
994
995 BT_ASSERT(field);
996 BT_LIB_LOGD("Destroying variant field object: %!+f", field);
997 bt_field_finalize(field);
998
999 if (var_field->fields) {
1000 g_ptr_array_free(var_field->fields, TRUE);
1001 var_field->fields = NULL;
1002 }
1003
1004 g_free(field);
1005}
1006
1007static
1008void destroy_array_field(struct bt_field *field)
1009{
1010 struct bt_field_array *array_field = (void *) field;
1011
1012 BT_ASSERT(field);
1013 BT_LIB_LOGD("Destroying array field object: %!+f", field);
1014 bt_field_finalize(field);
1015
1016 if (array_field->fields) {
1017 g_ptr_array_free(array_field->fields, TRUE);
1018 array_field->fields = NULL;
1019 }
1020
1021 g_free(field);
1022}
1023
1024static
1025void destroy_string_field(struct bt_field *field)
1026{
1027 struct bt_field_string *string_field = (void *) field;
1028
1029 BT_ASSERT(field);
1030 BT_LIB_LOGD("Destroying string field object: %!+f", field);
1031 bt_field_finalize(field);
1032
1033 if (string_field->buf) {
1034 g_array_free(string_field->buf, TRUE);
1035 string_field->buf = NULL;
1036 }
1037
1038 g_free(field);
1039}
1040
1041BT_HIDDEN
1042void bt_field_destroy(struct bt_field *field)
1043{
1044 BT_ASSERT(field);
1045 field_destroy_funcs[field->class->type](field);
1046}
1047
1048static
1049void reset_single_field(struct bt_field *field)
1050{
1051 BT_ASSERT(field);
1052 field->is_set = false;
1053}
1054
1055static
1056void reset_structure_field(struct bt_field *field)
1057{
1058 uint64_t i;
1059 struct bt_field_structure *struct_field = (void *) field;
1060
1061 BT_ASSERT(field);
1062
1063 for (i = 0; i < struct_field->fields->len; i++) {
1064 bt_field_reset(struct_field->fields->pdata[i]);
1065 }
1066}
1067
1068static
1069void reset_variant_field(struct bt_field *field)
1070{
1071 uint64_t i;
1072 struct bt_field_variant *var_field = (void *) field;
1073
1074 BT_ASSERT(field);
1075
1076 for (i = 0; i < var_field->fields->len; i++) {
1077 bt_field_reset(var_field->fields->pdata[i]);
1078 }
1079}
1080
1081static
1082void reset_array_field(struct bt_field *field)
1083{
1084 uint64_t i;
1085 struct bt_field_array *array_field = (void *) field;
1086
1087 BT_ASSERT(field);
1088
1089 for (i = 0; i < array_field->fields->len; i++) {
1090 bt_field_reset(array_field->fields->pdata[i]);
1091 }
1092}
1093
1094static
1095void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
1096{
1097 field->frozen = is_frozen;
1098}
1099
1100static
1101void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
1102{
1103 uint64_t i;
1104 struct bt_field_structure *struct_field = (void *) field;
1105
1106 BT_LIB_LOGD("Setting structure field's frozen state: "
1107 "%![field-]+f, is-frozen=%d", field, is_frozen);
1108
1109 for (i = 0; i < struct_field->fields->len; i++) {
1110 struct bt_field *member_field = struct_field->fields->pdata[i];
1111
1112 BT_LIB_LOGD("Setting structure field's member field's "
1113 "frozen state: %![field-]+f, index=%" PRIu64,
1114 member_field, i);
1115 bt_field_set_is_frozen(member_field, is_frozen);
1116 }
1117
1118 set_single_field_is_frozen(field, is_frozen);
1119}
1120
1121static
1122void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
1123{
1124 uint64_t i;
1125 struct bt_field_variant *var_field = (void *) field;
1126
1127 BT_LIB_LOGD("Setting variant field's frozen state: "
1128 "%![field-]+f, is-frozen=%d", field, is_frozen);
1129
1130 for (i = 0; i < var_field->fields->len; i++) {
1131 struct bt_field *option_field = var_field->fields->pdata[i];
1132
1133 BT_LIB_LOGD("Setting variant field's option field's "
1134 "frozen state: %![field-]+f, index=%" PRIu64,
1135 option_field, i);
1136 bt_field_set_is_frozen(option_field, is_frozen);
1137 }
1138
1139 set_single_field_is_frozen(field, is_frozen);
1140}
1141
1142static
1143void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
1144{
1145 uint64_t i;
1146 struct bt_field_array *array_field = (void *) field;
1147
1148 BT_LIB_LOGD("Setting array field's frozen state: "
1149 "%![field-]+f, is-frozen=%d", field, is_frozen);
1150
1151 for (i = 0; i < array_field->fields->len; i++) {
1152 struct bt_field *elem_field = array_field->fields->pdata[i];
1153
1154 BT_LIB_LOGD("Setting array field's element field's "
1155 "frozen state: %![field-]+f, index=%" PRIu64,
1156 elem_field, i);
1157 bt_field_set_is_frozen(elem_field, is_frozen);
1158 }
1159
1160 set_single_field_is_frozen(field, is_frozen);
1161}
1162
1163BT_HIDDEN
1164void _bt_field_set_is_frozen(const struct bt_field *field,
1165 bool is_frozen)
1166{
1167 BT_ASSERT(field);
1168 BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
1169 field, is_frozen);
1170 BT_ASSERT(field->methods->set_is_frozen);
1171 field->methods->set_is_frozen((void *) field, is_frozen);
1172}
1173
1174static
1175bool single_field_is_set(const struct bt_field *field)
1176{
1177 BT_ASSERT(field);
1178 return field->is_set;
1179}
1180
1181static
1182bool structure_field_is_set(const struct bt_field *field)
1183{
1184 bool is_set = true;
1185 uint64_t i;
1186 const struct bt_field_structure *struct_field = (const void *) field;
1187
1188 BT_ASSERT(field);
1189
1190 for (i = 0; i < struct_field->fields->len; i++) {
1191 is_set = bt_field_is_set(struct_field->fields->pdata[i]);
1192 if (!is_set) {
1193 goto end;
1194 }
1195 }
1196
1197end:
1198 return is_set;
1199}
1200
1201static
1202bool variant_field_is_set(const struct bt_field *field)
1203{
1204 const struct bt_field_variant *var_field = (const void *) field;
1205 bool is_set = false;
1206
1207 BT_ASSERT(field);
1208
1209 if (var_field->selected_field) {
1210 is_set = bt_field_is_set(var_field->selected_field);
1211 }
1212
1213 return is_set;
1214}
1215
1216static
1217bool array_field_is_set(const struct bt_field *field)
1218{
1219 bool is_set = true;
1220 uint64_t i;
1221 const struct bt_field_array *array_field = (const void *) field;
1222
1223 BT_ASSERT(field);
1224
1225 for (i = 0; i < array_field->length; i++) {
1226 is_set = bt_field_is_set(array_field->fields->pdata[i]);
1227 if (!is_set) {
1228 goto end;
1229 }
1230 }
1231
1232end:
1233 return is_set;
1234}
This page took 0.026237 seconds and 4 git commands to generate.