.gitignore: add some more IDE / tools related file
[babeltrace.git] / src / lib / trace-ir / field-class.c
... / ...
CommitLineData
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-CLASS"
9#include "lib/logging.h"
10
11#include "lib/assert-cond.h"
12#include <babeltrace2/trace-ir/field-class.h>
13#include <babeltrace2/trace-ir/field.h>
14#include <babeltrace2/trace-ir/clock-class.h>
15#include "lib/object.h"
16#include "compat/compiler.h"
17#include "compat/endian.h"
18#include "common/assert.h"
19#include "common/common.h"
20#include "compat/glib.h"
21#include <inttypes.h>
22#include <stdbool.h>
23#include <stdlib.h>
24
25#include "field-class.h"
26#include "field-path.h"
27#include "lib/func-status.h"
28#include "lib/integer-range-set.h"
29#include "lib/value.h"
30
31BT_EXPORT
32enum bt_field_class_type bt_field_class_get_type(
33 const struct bt_field_class *fc)
34{
35 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
36 return fc->type;
37}
38
39static
40int init_field_class(struct bt_field_class *fc, enum bt_field_class_type type,
41 bt_object_release_func release_func)
42{
43 int ret = 0;
44
45 BT_ASSERT(fc);
46 BT_ASSERT(release_func);
47 bt_object_init_shared(&fc->base, release_func);
48 fc->type = type;
49 fc->user_attributes = bt_value_map_create();
50 if (!fc->user_attributes) {
51 BT_LIB_LOGE_APPEND_CAUSE(
52 "Failed to create a map value object.");
53 ret = -1;
54 goto end;
55 }
56
57end:
58 return ret;
59}
60
61static
62void finalize_field_class(struct bt_field_class *fc)
63{
64 BT_OBJECT_PUT_REF_AND_RESET(fc->user_attributes);
65}
66
67static
68void destroy_bit_array_field_class(struct bt_object *obj)
69{
70 BT_ASSERT(obj);
71 BT_LIB_LOGD("Destroying bit array field class object: %!+F", obj);
72 finalize_field_class((void *) obj);
73 g_free(obj);
74}
75
76BT_EXPORT
77struct bt_field_class *bt_field_class_bit_array_create(
78 struct bt_trace_class *trace_class, uint64_t length)
79{
80 struct bt_field_class_bit_array *ba_fc = NULL;
81
82 BT_ASSERT_PRE_NO_ERROR();
83 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
84 BT_ASSERT_PRE("valid-length", length > 0 && length <= 64,
85 "Unsupported length for bit array field class "
86 "(minimum is 1, maximum is 64): length=%" PRIu64, length);
87 BT_LOGD("Creating default bit array field class object.");
88 ba_fc = g_new0(struct bt_field_class_bit_array, 1);
89 if (!ba_fc) {
90 BT_LIB_LOGE_APPEND_CAUSE(
91 "Failed to allocate one bit array field class.");
92 goto error;
93 }
94
95 if (init_field_class((void *) ba_fc, BT_FIELD_CLASS_TYPE_BIT_ARRAY,
96 destroy_bit_array_field_class)) {
97 goto error;
98 }
99
100 ba_fc->length = length;
101 BT_LIB_LOGD("Created bit array field class object: %!+F", ba_fc);
102 goto end;
103
104error:
105 BT_OBJECT_PUT_REF_AND_RESET(ba_fc);
106
107end:
108 return (void *) ba_fc;
109}
110
111BT_EXPORT
112uint64_t bt_field_class_bit_array_get_length(const struct bt_field_class *fc)
113{
114 const struct bt_field_class_bit_array *ba_fc = (const void *) fc;
115
116 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
117 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
118 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
119 return ba_fc->length;
120}
121
122static
123void destroy_bool_field_class(struct bt_object *obj)
124{
125 BT_ASSERT(obj);
126 BT_LIB_LOGD("Destroying boolean field class object: %!+F", obj);
127 finalize_field_class((void *) obj);
128 g_free(obj);
129}
130
131BT_EXPORT
132struct bt_field_class *bt_field_class_bool_create(
133 bt_trace_class *trace_class)
134{
135 struct bt_field_class_bool *bool_fc = NULL;
136
137 BT_ASSERT_PRE_NO_ERROR();
138 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
139 BT_LOGD("Creating default boolean field class object.");
140 bool_fc = g_new0(struct bt_field_class_bool, 1);
141 if (!bool_fc) {
142 BT_LIB_LOGE_APPEND_CAUSE(
143 "Failed to allocate one boolean field class.");
144 goto error;
145 }
146
147 if (init_field_class((void *) bool_fc, BT_FIELD_CLASS_TYPE_BOOL,
148 destroy_bool_field_class)) {
149 goto error;
150 }
151
152 BT_LIB_LOGD("Created boolean field class object: %!+F", bool_fc);
153 goto end;
154
155error:
156 BT_OBJECT_PUT_REF_AND_RESET(bool_fc);
157
158end:
159 return (void *) bool_fc;
160}
161
162static
163int init_integer_field_class(struct bt_field_class_integer *fc,
164 enum bt_field_class_type type,
165 bt_object_release_func release_func)
166{
167 int ret;
168
169 ret = init_field_class((void *) fc, type, release_func);
170 if (ret) {
171 goto end;
172 }
173
174 fc->range = 64;
175 fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
176
177end:
178 return ret;
179}
180
181static
182void destroy_integer_field_class(struct bt_object *obj)
183{
184 BT_ASSERT(obj);
185 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj);
186 finalize_field_class((void *) obj);
187 g_free(obj);
188}
189
190static inline
191struct bt_field_class *create_integer_field_class(bt_trace_class *trace_class,
192 enum bt_field_class_type type)
193{
194 struct bt_field_class_integer *int_fc = NULL;
195
196 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
197 BT_LOGD("Creating default integer field class object: type=%s",
198 bt_common_field_class_type_string(type));
199 int_fc = g_new0(struct bt_field_class_integer, 1);
200 if (!int_fc) {
201 BT_LIB_LOGE_APPEND_CAUSE(
202 "Failed to allocate one integer field class.");
203 goto error;
204 }
205
206 if (init_integer_field_class(int_fc, type,
207 destroy_integer_field_class)) {
208 goto error;
209 }
210
211 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc);
212 goto end;
213
214error:
215 BT_OBJECT_PUT_REF_AND_RESET(int_fc);
216
217end:
218 return (void *) int_fc;
219}
220
221BT_EXPORT
222struct bt_field_class *bt_field_class_integer_unsigned_create(
223 bt_trace_class *trace_class)
224{
225 BT_ASSERT_PRE_NO_ERROR();
226
227 return create_integer_field_class(trace_class,
228 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER);
229}
230
231BT_EXPORT
232struct bt_field_class *bt_field_class_integer_signed_create(
233 bt_trace_class *trace_class)
234{
235 BT_ASSERT_PRE_NO_ERROR();
236
237 return create_integer_field_class(trace_class,
238 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER);
239}
240
241BT_EXPORT
242uint64_t bt_field_class_integer_get_field_value_range(
243 const struct bt_field_class *fc)
244{
245 const struct bt_field_class_integer *int_fc = (const void *) fc;
246
247 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
248 BT_ASSERT_PRE_DEV_FC_IS_INT("field-class", fc, "Field class");
249 return int_fc->range;
250}
251
252static
253bool size_is_valid_for_enumeration_field_class(
254 struct bt_field_class *fc __attribute__((unused)),
255 uint64_t size __attribute__((unused)))
256{
257 // TODO
258 return true;
259}
260
261BT_EXPORT
262void bt_field_class_integer_set_field_value_range(
263 struct bt_field_class *fc, uint64_t size)
264{
265 struct bt_field_class_integer *int_fc = (void *) fc;
266
267 BT_ASSERT_PRE_FC_NON_NULL(fc);
268 BT_ASSERT_PRE_FC_IS_INT("field-class", fc, "Field class");
269 BT_ASSERT_PRE_DEV_FC_HOT(fc);
270 BT_ASSERT_PRE("valid-n",
271 size >= 1 && size <= 64,
272 "Unsupported size for integer field class's field value range "
273 "(minimum is 1, maximum is 64): size=%" PRIu64, size);
274 BT_ASSERT_PRE("valid-n-for-enumeration-field-class",
275 int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
276 int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
277 size_is_valid_for_enumeration_field_class(fc, size),
278 "Invalid field value range for enumeration field class: "
279 "at least one of the current mapping ranges contains values "
280 "which are outside this range: %!+F, size=%" PRIu64, fc, size);
281 int_fc->range = size;
282 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc);
283}
284
285BT_EXPORT
286enum bt_field_class_integer_preferred_display_base
287bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc)
288{
289 const struct bt_field_class_integer *int_fc = (const void *) fc;
290
291 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
292 BT_ASSERT_PRE_DEV_FC_IS_INT("field-class", fc, "Field class");
293 return int_fc->base;
294}
295
296BT_EXPORT
297void bt_field_class_integer_set_preferred_display_base(
298 struct bt_field_class *fc,
299 enum bt_field_class_integer_preferred_display_base base)
300{
301 struct bt_field_class_integer *int_fc = (void *) fc;
302
303 BT_ASSERT_PRE_FC_NON_NULL(fc);
304 BT_ASSERT_PRE_FC_IS_INT("field-class", fc, "Field class");
305 BT_ASSERT_PRE_DEV_FC_HOT(fc);
306 int_fc->base = base;
307 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc);
308}
309
310static
311void finalize_enumeration_field_class_mapping(
312 struct bt_field_class_enumeration_mapping *mapping)
313{
314 BT_ASSERT(mapping);
315
316 if (mapping->label) {
317 g_string_free(mapping->label, TRUE);
318 mapping->label = NULL;
319 }
320
321 BT_OBJECT_PUT_REF_AND_RESET(mapping->range_set);
322}
323
324static
325void destroy_enumeration_field_class(struct bt_object *obj)
326{
327 struct bt_field_class_enumeration *fc = (void *) obj;
328
329 BT_ASSERT(fc);
330 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc);
331 finalize_field_class((void *) obj);
332
333 if (fc->mappings) {
334 uint64_t i;
335
336 for (i = 0; i < fc->mappings->len; i++) {
337 finalize_enumeration_field_class_mapping(
338 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i));
339 }
340
341 g_array_free(fc->mappings, TRUE);
342 fc->mappings = NULL;
343 }
344
345 if (fc->label_buf) {
346 g_ptr_array_free(fc->label_buf, TRUE);
347 fc->label_buf = NULL;
348 }
349
350 g_free(fc);
351}
352
353static
354struct bt_field_class *create_enumeration_field_class(
355 bt_trace_class *trace_class, enum bt_field_class_type type)
356{
357 struct bt_field_class_enumeration *enum_fc = NULL;
358
359 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
360 BT_LOGD("Creating default enumeration field class object: type=%s",
361 bt_common_field_class_type_string(type));
362 enum_fc = g_new0(struct bt_field_class_enumeration, 1);
363 if (!enum_fc) {
364 BT_LIB_LOGE_APPEND_CAUSE(
365 "Failed to allocate one enumeration field class.");
366 goto error;
367 }
368
369 if (init_integer_field_class((void *) enum_fc, type,
370 destroy_enumeration_field_class)) {
371 goto error;
372 }
373
374 enum_fc->mappings = g_array_new(FALSE, TRUE,
375 sizeof(struct bt_field_class_enumeration_mapping));
376 if (!enum_fc->mappings) {
377 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
378 goto error;
379 }
380
381 enum_fc->label_buf = g_ptr_array_new();
382 if (!enum_fc->label_buf) {
383 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
384 goto error;
385 }
386
387 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc);
388 goto end;
389
390error:
391 BT_OBJECT_PUT_REF_AND_RESET(enum_fc);
392
393end:
394 return (void *) enum_fc;
395}
396
397BT_EXPORT
398struct bt_field_class *bt_field_class_enumeration_unsigned_create(
399 bt_trace_class *trace_class)
400{
401 BT_ASSERT_PRE_NO_ERROR();
402
403 return create_enumeration_field_class(trace_class,
404 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION);
405}
406
407BT_EXPORT
408struct bt_field_class *bt_field_class_enumeration_signed_create(
409 bt_trace_class *trace_class)
410{
411 BT_ASSERT_PRE_NO_ERROR();
412
413 return create_enumeration_field_class(trace_class,
414 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
415}
416
417BT_EXPORT
418uint64_t bt_field_class_enumeration_get_mapping_count(
419 const struct bt_field_class *fc)
420{
421 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
422
423 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
424 BT_ASSERT_PRE_DEV_FC_IS_ENUM("field-class", fc, "Field class");
425 return (uint64_t) enum_fc->mappings->len;
426}
427
428BT_EXPORT
429const struct bt_field_class_enumeration_unsigned_mapping *
430bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
431 const struct bt_field_class *fc, uint64_t index)
432{
433 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
434
435 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
436 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
437 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
438 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
439 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
440}
441
442BT_EXPORT
443const struct bt_field_class_enumeration_signed_mapping *
444bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
445 const struct bt_field_class *fc, uint64_t index)
446{
447 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
448
449 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
450 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
451 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
452 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
453 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
454}
455
456static
457const struct bt_field_class_enumeration_mapping *
458borrow_enumeration_field_class_mapping_by_label(
459 const struct bt_field_class_enumeration *fc, const char *label,
460 const char *api_func)
461{
462 struct bt_field_class_enumeration_mapping *mapping = NULL;
463 uint64_t i;
464
465 BT_ASSERT_DBG(fc);
466 BT_ASSERT_PRE_DEV_NON_NULL_FROM_FUNC(api_func, "label", label,
467 "Label");
468
469 for (i = 0; i < fc->mappings->len; i++) {
470 struct bt_field_class_enumeration_mapping *this_mapping =
471 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i);
472
473 if (strcmp(this_mapping->label->str, label) == 0) {
474 mapping = this_mapping;
475 goto end;
476 }
477 }
478
479end:
480 return mapping;
481}
482
483BT_EXPORT
484const struct bt_field_class_enumeration_signed_mapping *
485bt_field_class_enumeration_signed_borrow_mapping_by_label_const(
486 const struct bt_field_class *fc, const char *label)
487{
488 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
489 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
490 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
491 return (const void *) borrow_enumeration_field_class_mapping_by_label(
492 (const void *) fc, label, __func__);
493}
494
495BT_EXPORT
496const struct bt_field_class_enumeration_unsigned_mapping *
497bt_field_class_enumeration_unsigned_borrow_mapping_by_label_const(
498 const struct bt_field_class *fc, const char *label)
499{
500 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
501 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
502 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
503 return (const void *) borrow_enumeration_field_class_mapping_by_label(
504 (const void *) fc, label, __func__);
505}
506
507BT_EXPORT
508const char *bt_field_class_enumeration_mapping_get_label(
509 const struct bt_field_class_enumeration_mapping *mapping)
510{
511 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
512 mapping, "Enumeration field class mapping");
513 return mapping->label->str;
514}
515
516BT_EXPORT
517const struct bt_integer_range_set_unsigned *
518bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
519 const struct bt_field_class_enumeration_unsigned_mapping *u_mapping)
520{
521 const struct bt_field_class_enumeration_mapping *mapping =
522 (const void *) u_mapping;
523
524 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
525 mapping, "Enumeration field class mapping");
526 return (const void *) mapping->range_set;
527}
528
529BT_EXPORT
530const struct bt_integer_range_set_signed *
531bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
532 const struct bt_field_class_enumeration_signed_mapping *s_mapping)
533{
534 const struct bt_field_class_enumeration_mapping *mapping =
535 (const void *) s_mapping;
536
537 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
538 mapping, "Enumeration field class mapping");
539 return (const void *) mapping->range_set;
540}
541
542BT_EXPORT
543enum bt_field_class_enumeration_get_mapping_labels_for_value_status
544bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
545 const struct bt_field_class *fc, uint64_t value,
546 bt_field_class_enumeration_mapping_label_array *label_array,
547 uint64_t *count)
548{
549 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
550 uint64_t i;
551
552 BT_ASSERT_PRE_DEV_NO_ERROR();
553 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
554 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
555 "Label array (output)");
556 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
557 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
558 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
559 g_ptr_array_set_size(enum_fc->label_buf, 0);
560
561 for (i = 0; i < enum_fc->mappings->len; i++) {
562 uint64_t j;
563 const struct bt_field_class_enumeration_mapping *mapping =
564 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
565
566 for (j = 0; j < mapping->range_set->ranges->len; j++) {
567 const struct bt_integer_range *range = (const void *)
568 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
569 mapping->range_set, j);
570
571 if (value >= range->lower.u &&
572 value <= range->upper.u) {
573 g_ptr_array_add(enum_fc->label_buf,
574 mapping->label->str);
575 break;
576 }
577 }
578 }
579
580 *label_array = (void *) enum_fc->label_buf->pdata;
581 *count = (uint64_t) enum_fc->label_buf->len;
582 return BT_FUNC_STATUS_OK;
583}
584
585BT_EXPORT
586enum bt_field_class_enumeration_get_mapping_labels_for_value_status
587bt_field_class_enumeration_signed_get_mapping_labels_for_value(
588 const struct bt_field_class *fc, int64_t value,
589 bt_field_class_enumeration_mapping_label_array *label_array,
590 uint64_t *count)
591{
592 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
593 uint64_t i;
594
595 BT_ASSERT_PRE_DEV_NO_ERROR();
596 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
597 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
598 "Label array (output)");
599 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
600 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
601 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
602 g_ptr_array_set_size(enum_fc->label_buf, 0);
603
604 for (i = 0; i < enum_fc->mappings->len; i++) {
605 uint64_t j;
606 const struct bt_field_class_enumeration_mapping *mapping =
607 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
608
609 for (j = 0; j < mapping->range_set->ranges->len; j++) {
610 const struct bt_integer_range *range = (const void *)
611 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
612 mapping->range_set, j);
613
614 if (value >= range->lower.i &&
615 value <= range->upper.i) {
616 g_ptr_array_add(enum_fc->label_buf,
617 mapping->label->str);
618 break;
619 }
620 }
621 }
622
623 *label_array = (void *) enum_fc->label_buf->pdata;
624 *count = (uint64_t) enum_fc->label_buf->len;
625 return BT_FUNC_STATUS_OK;
626}
627
628static
629bool enumeration_field_class_has_mapping_with_label(
630 const struct bt_field_class_enumeration *enum_fc,
631 const char *label)
632{
633 uint64_t i;
634 bool exists = false;
635
636 BT_ASSERT(enum_fc);
637 BT_ASSERT(label);
638
639 for (i = 0; i < enum_fc->mappings->len; i++) {
640 struct bt_field_class_enumeration_mapping *mapping_candidate =
641 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
642
643 if (strcmp(mapping_candidate->label->str, label) == 0) {
644 exists = true;
645 goto end;
646 }
647 }
648
649end:
650 return exists;
651}
652
653static inline
654enum bt_field_class_enumeration_add_mapping_status
655add_mapping_to_enumeration_field_class(struct bt_field_class *fc,
656 const char *label, const struct bt_integer_range_set *range_set,
657 const char *api_func)
658{
659 enum bt_field_class_enumeration_add_mapping_status status =
660 BT_FUNC_STATUS_OK;
661 struct bt_field_class_enumeration *enum_fc = (void *) fc;
662 struct bt_field_class_enumeration_mapping mapping = { 0 };
663
664 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
665 BT_ASSERT(fc);
666 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "label", label, "Label");
667 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL_FROM_FUNC(api_func, range_set);
668 BT_ASSERT_PRE_FROM_FUNC(api_func,
669 "enumeration-field-class-mapping-label-is-unique",
670 !enumeration_field_class_has_mapping_with_label(
671 enum_fc, label),
672 "Duplicate mapping name in enumeration field class: "
673 "%![enum-fc-]+F, label=\"%s\"", fc, label);
674 mapping.range_set = range_set;
675 bt_object_get_ref(mapping.range_set);
676 mapping.label = g_string_new(label);
677 if (!mapping.label) {
678 finalize_enumeration_field_class_mapping(&mapping);
679 status = BT_FUNC_STATUS_MEMORY_ERROR;
680 goto end;
681 }
682
683 g_array_append_val(enum_fc->mappings, mapping);
684 BT_LIB_LOGD("Added mapping to enumeration field class: "
685 "%![fc-]+F, label=\"%s\"", fc, label);
686
687end:
688 return status;
689}
690
691BT_EXPORT
692enum bt_field_class_enumeration_add_mapping_status
693bt_field_class_enumeration_unsigned_add_mapping(
694 struct bt_field_class *fc, const char *label,
695 const struct bt_integer_range_set_unsigned *range_set)
696{
697 BT_ASSERT_PRE_NO_ERROR();
698 BT_ASSERT_PRE_FC_NON_NULL(fc);
699 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
700 "unsigned-enumeration-field-class",
701 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
702 return add_mapping_to_enumeration_field_class(fc, label,
703 (const void *) range_set, __func__);
704}
705
706BT_EXPORT
707enum bt_field_class_enumeration_add_mapping_status
708bt_field_class_enumeration_signed_add_mapping(
709 struct bt_field_class *fc, const char *label,
710 const struct bt_integer_range_set_signed *range_set)
711{
712 BT_ASSERT_PRE_NO_ERROR();
713 BT_ASSERT_PRE_FC_NON_NULL(fc);
714 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
715 "signed-enumeration-field-class",
716 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
717 return add_mapping_to_enumeration_field_class(fc, label,
718 (const void *) range_set, __func__);
719}
720
721static
722void destroy_real_field_class(struct bt_object *obj)
723{
724 BT_ASSERT(obj);
725 BT_LIB_LOGD("Destroying real field class object: %!+F", obj);
726 finalize_field_class((void *) obj);
727 g_free(obj);
728}
729
730static
731struct bt_field_class *create_real_field_class(bt_trace_class *trace_class,
732 enum bt_field_class_type type)
733{
734 struct bt_field_class_real *real_fc = NULL;
735
736 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
737 BT_LOGD("Creating default real field class object: type=%s",
738 bt_common_field_class_type_string(type));
739 real_fc = g_new0(struct bt_field_class_real, 1);
740 if (!real_fc) {
741 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
742 goto error;
743 }
744
745 if (init_field_class((void *) real_fc, type, destroy_real_field_class)) {
746 goto error;
747 }
748
749 BT_LIB_LOGD("Created real field class object: %!+F", real_fc);
750 goto end;
751
752error:
753 BT_OBJECT_PUT_REF_AND_RESET(real_fc);
754
755end:
756 return (void *) real_fc;
757}
758
759BT_EXPORT
760struct bt_field_class *bt_field_class_real_single_precision_create(
761 bt_trace_class *trace_class)
762{
763 BT_ASSERT_PRE_NO_ERROR();
764
765 return create_real_field_class(trace_class,
766 BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL);
767}
768
769BT_EXPORT
770struct bt_field_class *bt_field_class_real_double_precision_create(
771 bt_trace_class *trace_class)
772{
773 BT_ASSERT_PRE_NO_ERROR();
774
775 return create_real_field_class(trace_class,
776 BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL);
777}
778
779static
780int init_named_field_classes_container(
781 struct bt_field_class_named_field_class_container *fc,
782 enum bt_field_class_type type,
783 bt_object_release_func fc_release_func,
784 GDestroyNotify named_fc_destroy_func)
785{
786 int ret = 0;
787
788 ret = init_field_class((void *) fc, type, fc_release_func);
789 if (ret) {
790 goto end;
791 }
792
793 fc->named_fcs = g_ptr_array_new_with_free_func(named_fc_destroy_func);
794 if (!fc->named_fcs) {
795 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
796 ret = -1;
797 goto end;
798 }
799
800 fc->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
801 if (!fc->name_to_index) {
802 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
803 ret = -1;
804 goto end;
805 }
806
807end:
808 return ret;
809}
810
811static
812void finalize_named_field_class(struct bt_named_field_class *named_fc)
813{
814 BT_ASSERT(named_fc);
815 BT_LIB_LOGD("Finalizing named field class: "
816 "addr=%p, name=\"%s\", %![fc-]+F",
817 named_fc, named_fc->name ? named_fc->name->str : NULL,
818 named_fc->fc);
819 BT_OBJECT_PUT_REF_AND_RESET(named_fc->user_attributes);
820
821 if (named_fc->name) {
822 g_string_free(named_fc->name, TRUE);
823 named_fc->name = NULL;
824 }
825
826 BT_LOGD_STR("Putting named field class's field class.");
827 BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc);
828}
829
830static
831void destroy_named_field_class(gpointer ptr)
832{
833 struct bt_named_field_class *named_fc = ptr;
834
835 if (ptr) {
836 BT_OBJECT_PUT_REF_AND_RESET(named_fc->user_attributes);
837 finalize_named_field_class(ptr);
838 g_free(ptr);
839 }
840}
841
842static
843void destroy_variant_with_selector_field_option(gpointer ptr)
844{
845 struct bt_field_class_variant_with_selector_field_option *opt = ptr;
846
847 if (ptr) {
848 finalize_named_field_class(&opt->common);
849 BT_OBJECT_PUT_REF_AND_RESET(opt->range_set);
850 g_free(ptr);
851 }
852}
853
854static
855void finalize_named_field_classes_container(
856 struct bt_field_class_named_field_class_container *fc)
857{
858 BT_ASSERT(fc);
859
860 if (fc->named_fcs) {
861 g_ptr_array_free(fc->named_fcs, TRUE);
862 fc->named_fcs = NULL;
863
864 }
865
866 if (fc->name_to_index) {
867 g_hash_table_destroy(fc->name_to_index);
868 fc->name_to_index = NULL;
869 }
870}
871
872static
873void destroy_structure_field_class(struct bt_object *obj)
874{
875 BT_ASSERT(obj);
876 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj);
877 finalize_field_class((void *) obj);
878 finalize_named_field_classes_container((void *) obj);
879 g_free(obj);
880}
881
882BT_EXPORT
883struct bt_field_class *bt_field_class_structure_create(
884 bt_trace_class *trace_class)
885{
886 int ret;
887 struct bt_field_class_structure *struct_fc = NULL;
888
889 BT_ASSERT_PRE_NO_ERROR();
890 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
891 BT_LOGD_STR("Creating default structure field class object.");
892 struct_fc = g_new0(struct bt_field_class_structure, 1);
893 if (!struct_fc) {
894 BT_LIB_LOGE_APPEND_CAUSE(
895 "Failed to allocate one structure field class.");
896 goto error;
897 }
898
899 ret = init_named_field_classes_container((void *) struct_fc,
900 BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class,
901 destroy_named_field_class);
902 if (ret) {
903 /* init_named_field_classes_container() logs errors */
904 goto error;
905 }
906
907 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc);
908 goto end;
909
910error:
911 BT_OBJECT_PUT_REF_AND_RESET(struct_fc);
912
913end:
914 return (void *) struct_fc;
915}
916
917static
918int init_named_field_class(struct bt_named_field_class *named_fc,
919 const char *name, struct bt_field_class *fc)
920{
921 int status = BT_FUNC_STATUS_OK;
922
923 BT_ASSERT(named_fc);
924 BT_ASSERT(name);
925 BT_ASSERT(fc);
926 named_fc->name = g_string_new(name);
927 if (!named_fc->name) {
928 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
929 status = BT_FUNC_STATUS_MEMORY_ERROR;
930 goto end;
931 }
932
933 named_fc->user_attributes = bt_value_map_create();
934 if (!named_fc->user_attributes) {
935 BT_LIB_LOGE_APPEND_CAUSE(
936 "Failed to create a map value object.");
937 status = BT_FUNC_STATUS_MEMORY_ERROR;
938 goto end;
939 }
940
941 named_fc->fc = fc;
942 bt_object_get_ref_no_null_check(named_fc->fc);
943
944end:
945 return status;
946}
947
948static
949struct bt_named_field_class *create_named_field_class(const char *name,
950 struct bt_field_class *fc)
951{
952 struct bt_named_field_class *named_fc = g_new0(
953 struct bt_named_field_class, 1);
954
955 if (!named_fc) {
956 BT_LIB_LOGE_APPEND_CAUSE(
957 "Failed to allocate a named field class.");
958 goto error;
959 }
960
961 if (init_named_field_class(named_fc, name, fc)) {
962 /* init_named_field_class() logs errors */
963 goto error;
964 }
965
966 goto end;
967
968error:
969 destroy_named_field_class(named_fc);
970 named_fc = NULL;
971
972end:
973 return named_fc;
974}
975
976static
977struct bt_field_class_variant_with_selector_field_option *
978create_variant_with_selector_field_option(
979 const char *name, struct bt_field_class *fc,
980 const struct bt_integer_range_set *range_set)
981{
982 struct bt_field_class_variant_with_selector_field_option *opt = g_new0(
983 struct bt_field_class_variant_with_selector_field_option, 1);
984
985 BT_ASSERT(range_set);
986
987 if (!opt) {
988 BT_LIB_LOGE_APPEND_CAUSE(
989 "Failed to allocate a named field class.");
990 goto error;
991 }
992
993 if (init_named_field_class(&opt->common, name, fc)) {
994 goto error;
995 }
996
997 opt->range_set = range_set;
998 bt_object_get_ref_no_null_check(opt->range_set);
999 bt_integer_range_set_freeze(range_set);
1000 goto end;
1001
1002error:
1003 destroy_variant_with_selector_field_option(opt);
1004 opt = NULL;
1005
1006end:
1007 return opt;
1008}
1009
1010static
1011int append_named_field_class_to_container_field_class(
1012 struct bt_field_class_named_field_class_container *container_fc,
1013 struct bt_named_field_class *named_fc, const char *api_func,
1014 const char *unique_entry_precond_id)
1015{
1016 BT_ASSERT(container_fc);
1017 BT_ASSERT(named_fc);
1018 BT_ASSERT_PRE_DEV_FC_HOT_FROM_FUNC(api_func, container_fc);
1019 BT_ASSERT_PRE_FROM_FUNC(api_func, unique_entry_precond_id,
1020 !bt_g_hash_table_contains(container_fc->name_to_index,
1021 named_fc->name->str),
1022 "Duplicate member/option name in structure/variant field class: "
1023 "%![container-fc-]+F, name=\"%s\"", container_fc,
1024 named_fc->name->str);
1025
1026 /*
1027 * Freeze the contained field class, but not the named field
1028 * class itself, as it's still possible afterwards to modify
1029 * properties of the member/option object.
1030 */
1031 bt_field_class_freeze(named_fc->fc);
1032 g_ptr_array_add(container_fc->named_fcs, named_fc);
1033 g_hash_table_insert(container_fc->name_to_index, named_fc->name->str,
1034 GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
1035 return BT_FUNC_STATUS_OK;
1036}
1037
1038BT_EXPORT
1039enum bt_field_class_structure_append_member_status
1040bt_field_class_structure_append_member(
1041 struct bt_field_class *fc, const char *name,
1042 struct bt_field_class *member_fc)
1043{
1044 enum bt_field_class_structure_append_member_status status;
1045 struct bt_named_field_class *named_fc = NULL;
1046
1047 BT_ASSERT_PRE_NO_ERROR();
1048 BT_ASSERT_PRE_FC_NON_NULL(fc);
1049 BT_ASSERT_PRE_FC_IS_STRUCT("field-class", fc, "Field class");
1050 named_fc = create_named_field_class(name, member_fc);
1051 if (!named_fc) {
1052 /* create_named_field_class() logs errors */
1053 status = BT_FUNC_STATUS_MEMORY_ERROR;
1054 goto end;
1055 }
1056
1057 status = append_named_field_class_to_container_field_class((void *) fc,
1058 named_fc, __func__,
1059 "structure-field-class-member-name-is-unique");
1060 if (status == BT_FUNC_STATUS_OK) {
1061 /* Moved to the container */
1062 named_fc = NULL;
1063 }
1064
1065end:
1066 return status;
1067}
1068
1069BT_EXPORT
1070uint64_t bt_field_class_structure_get_member_count(
1071 const struct bt_field_class *fc)
1072{
1073 struct bt_field_class_structure *struct_fc = (void *) fc;
1074
1075 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1076 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1077 return (uint64_t) struct_fc->common.named_fcs->len;
1078}
1079
1080static
1081struct bt_named_field_class *
1082borrow_named_field_class_from_container_field_class_at_index(
1083 struct bt_field_class_named_field_class_container *fc,
1084 uint64_t index, const char *api_func)
1085{
1086 BT_ASSERT_DBG(fc);
1087 BT_ASSERT_PRE_DEV_VALID_INDEX_FROM_FUNC(api_func, index,
1088 fc->named_fcs->len);
1089 return fc->named_fcs->pdata[index];
1090}
1091
1092BT_EXPORT
1093const struct bt_field_class_structure_member *
1094bt_field_class_structure_borrow_member_by_index_const(
1095 const struct bt_field_class *fc, uint64_t index)
1096{
1097 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1098 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1099 return (const void *)
1100 borrow_named_field_class_from_container_field_class_at_index(
1101 (void *) fc, index, __func__);
1102}
1103
1104BT_EXPORT
1105struct bt_field_class_structure_member *
1106bt_field_class_structure_borrow_member_by_index(
1107 struct bt_field_class *fc, uint64_t index)
1108{
1109 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1110 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1111 return (void *)
1112 borrow_named_field_class_from_container_field_class_at_index(
1113 (void *) fc, index, __func__);
1114}
1115
1116static
1117struct bt_named_field_class *
1118borrow_named_field_class_from_container_field_class_by_name(
1119 struct bt_field_class_named_field_class_container *fc,
1120 const char *name, const char *api_func)
1121{
1122 struct bt_named_field_class *named_fc = NULL;
1123 gpointer orig_key;
1124 gpointer value;
1125
1126 BT_ASSERT_DBG(fc);
1127 BT_ASSERT_PRE_DEV_NAME_NON_NULL_FROM_FUNC(api_func, name);
1128 if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key,
1129 &value)) {
1130 goto end;
1131 }
1132
1133 named_fc = fc->named_fcs->pdata[GPOINTER_TO_UINT(value)];
1134
1135end:
1136 return named_fc;
1137}
1138
1139BT_EXPORT
1140const struct bt_field_class_structure_member *
1141bt_field_class_structure_borrow_member_by_name_const(
1142 const struct bt_field_class *fc, const char *name)
1143{
1144 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1145 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1146 return (const void *)
1147 borrow_named_field_class_from_container_field_class_by_name(
1148 (void *) fc, name, __func__);
1149}
1150
1151BT_EXPORT
1152struct bt_field_class_structure_member *
1153bt_field_class_structure_borrow_member_by_name(
1154 struct bt_field_class *fc, const char *name)
1155{
1156 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1157 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1158 return (void *)
1159 borrow_named_field_class_from_container_field_class_by_name(
1160 (void *) fc, name, __func__);
1161}
1162
1163BT_EXPORT
1164const char *bt_field_class_structure_member_get_name(
1165 const struct bt_field_class_structure_member *member)
1166{
1167 const struct bt_named_field_class *named_fc = (const void *) member;
1168
1169 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1170 return named_fc->name->str;
1171}
1172
1173BT_EXPORT
1174const struct bt_field_class *
1175bt_field_class_structure_member_borrow_field_class_const(
1176 const struct bt_field_class_structure_member *member)
1177{
1178 const struct bt_named_field_class *named_fc = (const void *) member;
1179
1180 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1181 return named_fc->fc;
1182}
1183
1184BT_EXPORT
1185struct bt_field_class *
1186bt_field_class_structure_member_borrow_field_class(
1187 struct bt_field_class_structure_member *member)
1188{
1189 struct bt_named_field_class *named_fc = (void *) member;
1190
1191 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1192 return named_fc->fc;
1193}
1194
1195static
1196void destroy_option_field_class(struct bt_object *obj)
1197{
1198 struct bt_field_class_option *fc = (void *) obj;
1199
1200 BT_ASSERT(fc);
1201 BT_LIB_LOGD("Destroying option field class object: %!+F", fc);
1202 finalize_field_class((void *) obj);
1203 BT_LOGD_STR("Putting content field class.");
1204 BT_OBJECT_PUT_REF_AND_RESET(fc->content_fc);
1205
1206 if (fc->common.type != BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD) {
1207 struct bt_field_class_option_with_selector_field *with_sel_fc =
1208 (void *) obj;
1209
1210 BT_LOGD_STR("Putting selector field path.");
1211 BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_field_path);
1212 BT_LOGD_STR("Putting selector field class.");
1213 BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_fc);
1214
1215 if (fc->common.type != BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
1216 struct bt_field_class_option_with_selector_field_integer *with_int_sel_fc =
1217 (void *) obj;
1218
1219 BT_LOGD_STR("Putting integer range set.");
1220 BT_OBJECT_PUT_REF_AND_RESET(with_int_sel_fc->range_set);
1221 }
1222 }
1223
1224 g_free(fc);
1225}
1226
1227static
1228struct bt_field_class *create_option_field_class(
1229 struct bt_trace_class *trace_class,
1230 enum bt_field_class_type fc_type,
1231 struct bt_field_class *content_fc,
1232 struct bt_field_class *selector_fc,
1233 const char *api_func)
1234{
1235 struct bt_field_class_option *opt_fc = NULL;
1236
1237 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
1238 BT_ASSERT_PRE_TC_NON_NULL_FROM_FUNC(api_func, trace_class);
1239 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "content-field-class",
1240 content_fc, "Content field class");
1241 BT_LIB_LOGD("Creating option field class: "
1242 "type=%s, %![content-fc-]+F, %![sel-fc-]+F",
1243 bt_common_field_class_type_string(fc_type),
1244 content_fc, selector_fc);
1245
1246 if (fc_type != BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD) {
1247 struct bt_field_class_option_with_selector_field *opt_with_sel_fc = NULL;
1248
1249 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func,
1250 "selector-field-class", selector_fc,
1251 "Selector field class");
1252
1253 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
1254 BT_ASSERT_PRE_FC_HAS_TYPE_FROM_FUNC(api_func,
1255 "selector-field-class", selector_fc,
1256 "boolean-field-class", BT_FIELD_CLASS_TYPE_BOOL,
1257 "Selector field class");
1258 opt_with_sel_fc = (void *) g_new0(
1259 struct bt_field_class_option_with_selector_field_bool, 1);
1260 } else {
1261 BT_ASSERT_PRE_FC_IS_INT_FROM_FUNC(api_func,
1262 "selector-field-class",
1263 selector_fc, "Selector field class");
1264 opt_with_sel_fc = (void *) g_new0(
1265 struct bt_field_class_option_with_selector_field_integer, 1);
1266 }
1267
1268 if (!opt_with_sel_fc) {
1269 BT_LIB_LOGE_APPEND_CAUSE(
1270 "Failed to allocate one option with selector field class.");
1271 goto error;
1272 }
1273
1274 opt_with_sel_fc->selector_fc = selector_fc;
1275 bt_object_get_ref_no_null_check(opt_with_sel_fc->selector_fc);
1276 opt_fc = (void *) opt_with_sel_fc;
1277 } else {
1278 opt_fc = g_new0(struct bt_field_class_option, 1);
1279 if (!opt_fc) {
1280 BT_LIB_LOGE_APPEND_CAUSE(
1281 "Failed to allocate one option field class.");
1282 goto error;
1283 }
1284 }
1285
1286 BT_ASSERT(opt_fc);
1287
1288 if (init_field_class((void *) opt_fc, fc_type,
1289 destroy_option_field_class)) {
1290 goto error;
1291 }
1292
1293 opt_fc->content_fc = content_fc;
1294 bt_object_get_ref_no_null_check(opt_fc->content_fc);
1295 bt_field_class_freeze(opt_fc->content_fc);
1296
1297 if (selector_fc) {
1298 bt_field_class_freeze(selector_fc);
1299 }
1300
1301 BT_LIB_LOGD("Created option field class object: "
1302 "%![opt-fc-]+F, %![sel-fc-]+F", opt_fc, selector_fc);
1303 goto end;
1304
1305error:
1306 BT_OBJECT_PUT_REF_AND_RESET(opt_fc);
1307
1308end:
1309 return (void *) opt_fc;
1310}
1311
1312BT_EXPORT
1313struct bt_field_class *bt_field_class_option_without_selector_create(
1314 struct bt_trace_class *trace_class,
1315 struct bt_field_class *content_fc)
1316{
1317 return create_option_field_class(trace_class,
1318 BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD,
1319 content_fc, NULL, __func__);
1320}
1321
1322BT_EXPORT
1323struct bt_field_class *bt_field_class_option_with_selector_field_bool_create(
1324 struct bt_trace_class *trace_class,
1325 struct bt_field_class *content_fc,
1326 struct bt_field_class *selector_fc)
1327{
1328 BT_ASSERT_PRE_NO_ERROR();
1329
1330 return create_option_field_class(trace_class,
1331 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1332 content_fc, selector_fc, __func__);
1333}
1334
1335BT_EXPORT
1336struct bt_field_class *
1337bt_field_class_option_with_selector_field_integer_unsigned_create(
1338 struct bt_trace_class *trace_class,
1339 struct bt_field_class *content_fc,
1340 struct bt_field_class *selector_fc,
1341 const struct bt_integer_range_set_unsigned *u_range_set)
1342{
1343 struct bt_field_class_option_with_selector_field_integer *fc;
1344 const struct bt_integer_range_set *range_set =
1345 (const void *) u_range_set;
1346
1347 BT_ASSERT_PRE_NO_ERROR();
1348 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1349 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
1350 fc = (void *) create_option_field_class(trace_class,
1351 BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1352 content_fc, selector_fc, __func__);
1353
1354 if (!fc) {
1355 goto end;
1356 }
1357
1358 fc->range_set = range_set;
1359 bt_object_get_ref_no_null_check(fc->range_set);
1360 bt_integer_range_set_freeze(range_set);
1361
1362end:
1363 return (void *) fc;
1364}
1365
1366BT_EXPORT
1367struct bt_field_class *
1368bt_field_class_option_with_selector_field_integer_signed_create(
1369 struct bt_trace_class *trace_class,
1370 struct bt_field_class *content_fc,
1371 struct bt_field_class *selector_fc,
1372 const struct bt_integer_range_set_signed *i_range_set)
1373{
1374 struct bt_field_class_option_with_selector_field_integer *fc;
1375 const struct bt_integer_range_set *range_set =
1376 (const void *) i_range_set;
1377
1378 BT_ASSERT_PRE_NO_ERROR();
1379 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1380 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
1381 fc = (void *) create_option_field_class(trace_class,
1382 BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1383 content_fc, selector_fc, __func__);
1384
1385 if (!fc) {
1386 goto end;
1387 }
1388
1389 fc->range_set = range_set;
1390 bt_object_get_ref_no_null_check(fc->range_set);
1391 bt_integer_range_set_freeze(range_set);
1392
1393end:
1394 return (void *) fc;
1395}
1396
1397BT_EXPORT
1398const struct bt_field_class *bt_field_class_option_borrow_field_class_const(
1399 const struct bt_field_class *fc)
1400{
1401 struct bt_field_class_option *opt_fc = (void *) fc;
1402
1403 BT_ASSERT_PRE_FC_NON_NULL(fc);
1404 BT_ASSERT_PRE_FC_IS_OPTION("field-class", fc, "Field class");
1405 return opt_fc->content_fc;
1406}
1407
1408BT_EXPORT
1409struct bt_field_class *bt_field_class_option_borrow_field_class(
1410 struct bt_field_class *fc)
1411{
1412 struct bt_field_class_option *opt_fc = (void *) fc;
1413
1414 BT_ASSERT_PRE_FC_NON_NULL(fc);
1415 BT_ASSERT_PRE_FC_IS_OPTION("field-class", fc, "Field class");
1416 return opt_fc->content_fc;
1417}
1418
1419BT_EXPORT
1420const struct bt_field_path *
1421bt_field_class_option_with_selector_field_borrow_selector_field_path_const(
1422 const struct bt_field_class *fc)
1423{
1424 const struct bt_field_class_option_with_selector_field *opt_fc =
1425 (const void *) fc;
1426
1427 BT_ASSERT_PRE_FC_NON_NULL(fc);
1428 BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL("field-class", fc, "Field class");
1429 return opt_fc->selector_field_path;
1430}
1431
1432BT_EXPORT
1433void bt_field_class_option_with_selector_field_bool_set_selector_is_reversed(
1434 struct bt_field_class *fc, bt_bool sel_is_reversed)
1435{
1436 struct bt_field_class_option_with_selector_field_bool *opt_fc = (void *) fc;
1437
1438 BT_ASSERT_PRE_FC_NON_NULL(fc);
1439 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1440 "option-field-class-with-boolean-selector-field",
1441 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1442 "Field class");
1443 BT_ASSERT_PRE_DEV_FC_HOT(fc);
1444 opt_fc->sel_is_reversed = sel_is_reversed;
1445}
1446
1447BT_EXPORT
1448bt_bool bt_field_class_option_with_selector_field_bool_selector_is_reversed(
1449 const struct bt_field_class *fc)
1450{
1451 struct bt_field_class_option_with_selector_field_bool *opt_fc = (void *) fc;
1452
1453 BT_ASSERT_PRE_FC_NON_NULL(fc);
1454 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1455 "option-field-class-with-boolean-selector-field",
1456 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1457 "Field class");
1458 return opt_fc->sel_is_reversed;
1459}
1460
1461BT_EXPORT
1462const struct bt_integer_range_set_unsigned *
1463bt_field_class_option_with_selector_field_integer_unsigned_borrow_selector_ranges_const(
1464 const struct bt_field_class *fc)
1465{
1466 struct bt_field_class_option_with_selector_field_integer *opt_fc =
1467 (void *) fc;
1468
1469 BT_ASSERT_PRE_FC_NON_NULL(fc);
1470 BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL("field-class", fc,
1471 "Field class");
1472 return (const void *) opt_fc->range_set;
1473}
1474
1475BT_EXPORT
1476const struct bt_integer_range_set_signed *
1477bt_field_class_option_with_selector_field_integer_signed_borrow_selector_ranges_const(
1478 const struct bt_field_class *fc)
1479{
1480 struct bt_field_class_option_with_selector_field_integer *opt_fc =
1481 (void *) fc;
1482
1483 BT_ASSERT_PRE_FC_NON_NULL(fc);
1484 BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL("field-class", fc,
1485 "Field class");
1486 return (const void *) opt_fc->range_set;
1487}
1488
1489static
1490void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
1491{
1492 BT_ASSERT(var_fc);
1493 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc);
1494 finalize_field_class((void *) var_fc);
1495 finalize_named_field_classes_container((void *) var_fc);
1496}
1497
1498static
1499void destroy_variant_field_class(struct bt_object *obj)
1500{
1501 struct bt_field_class_variant *fc = (void *) obj;
1502
1503 BT_ASSERT(fc);
1504 finalize_variant_field_class(fc);
1505 g_free(fc);
1506}
1507
1508static
1509void destroy_variant_with_selector_field_field_class(struct bt_object *obj)
1510{
1511 struct bt_field_class_variant_with_selector_field *fc = (void *) obj;
1512
1513 BT_ASSERT(fc);
1514 finalize_variant_field_class(&fc->common);
1515 BT_LOGD_STR("Putting selector field path.");
1516 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path);
1517 BT_LOGD_STR("Putting selector field class.");
1518 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc);
1519 g_free(fc);
1520}
1521
1522BT_EXPORT
1523struct bt_field_class *bt_field_class_variant_create(
1524 bt_trace_class *trace_class, bt_field_class *selector_fc)
1525{
1526 int ret;
1527 struct bt_field_class_variant *var_fc = NULL;
1528 struct bt_field_class_variant_with_selector_field *var_with_sel_fc = NULL;
1529 enum bt_field_class_type fc_type;
1530
1531 BT_ASSERT_PRE_NO_ERROR();
1532 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1533
1534 if (selector_fc) {
1535 BT_ASSERT_PRE_FC_IS_INT("selector-field-class", selector_fc,
1536 "Selector field class");
1537 }
1538
1539 BT_LIB_LOGD("Creating default variant field class: %![sel-fc-]+F",
1540 selector_fc);
1541
1542 if (selector_fc) {
1543 var_with_sel_fc = g_new0(
1544 struct bt_field_class_variant_with_selector_field, 1);
1545 if (!var_with_sel_fc) {
1546 BT_LIB_LOGE_APPEND_CAUSE(
1547 "Failed to allocate one variant field class with selector.");
1548 goto error;
1549 }
1550
1551 if (bt_field_class_type_is(selector_fc->type,
1552 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)) {
1553 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD;
1554 } else {
1555 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD;
1556 }
1557
1558 ret = init_named_field_classes_container(
1559 (void *) var_with_sel_fc, fc_type,
1560 destroy_variant_with_selector_field_field_class,
1561 destroy_variant_with_selector_field_option);
1562 if (ret) {
1563 /* init_named_field_classes_container() logs errors */
1564 goto error;
1565 }
1566
1567 var_with_sel_fc->selector_fc = selector_fc;
1568 bt_object_get_ref_no_null_check(var_with_sel_fc->selector_fc);
1569 bt_field_class_freeze(selector_fc);
1570 var_fc = (void *) var_with_sel_fc;
1571 BT_LIB_LOGD("Created default variant field class with selector object: "
1572 "%![var-fc-]+F, %![sel-fc-]+F", var_fc, selector_fc);
1573 } else {
1574 var_fc = g_new0(struct bt_field_class_variant, 1);
1575 if (!var_fc) {
1576 BT_LIB_LOGE_APPEND_CAUSE(
1577 "Failed to allocate one variant field class without selector.");
1578 goto error;
1579 }
1580
1581 ret = init_named_field_classes_container((void *) var_fc,
1582 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD,
1583 destroy_variant_field_class, destroy_named_field_class);
1584 if (ret) {
1585 /* init_named_field_classes_container() logs errors */
1586 goto error;
1587 }
1588 BT_LIB_LOGD("Created default variant field class without selector object: "
1589 "%![var-fc-]+F", var_fc);
1590 }
1591
1592 BT_ASSERT(var_fc);
1593 goto end;
1594
1595error:
1596 BT_OBJECT_PUT_REF_AND_RESET(var_fc);
1597 BT_OBJECT_PUT_REF_AND_RESET(var_with_sel_fc);
1598
1599end:
1600 return (void *) var_fc;
1601}
1602
1603#define VAR_FC_OPT_NAME_IS_UNIQUE_ID \
1604 "variant-field-class-option-name-is-unique"
1605
1606BT_EXPORT
1607enum bt_field_class_variant_without_selector_append_option_status
1608bt_field_class_variant_without_selector_append_option(struct bt_field_class *fc,
1609 const char *name, struct bt_field_class *option_fc)
1610{
1611 enum bt_field_class_variant_without_selector_append_option_status status;
1612 struct bt_named_field_class *named_fc = NULL;
1613
1614 BT_ASSERT_PRE_NO_ERROR();
1615 BT_ASSERT_PRE_FC_NON_NULL(fc);
1616 BT_ASSERT_PRE_NAME_NON_NULL(name);
1617 BT_ASSERT_PRE_NON_NULL("option-field-class", option_fc,
1618 "Option field class");
1619 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1620 "variant-field-class-without-selector-field",
1621 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD,
1622 "Field class");
1623 named_fc = create_named_field_class(name, option_fc);
1624 if (!named_fc) {
1625 /* create_named_field_class() logs errors */
1626 status = BT_FUNC_STATUS_MEMORY_ERROR;
1627 goto end;
1628 }
1629
1630 status = append_named_field_class_to_container_field_class((void *) fc,
1631 named_fc, __func__, VAR_FC_OPT_NAME_IS_UNIQUE_ID);
1632 if (status == BT_FUNC_STATUS_OK) {
1633 /* Moved to the container */
1634 named_fc = NULL;
1635 }
1636
1637end:
1638 if (named_fc) {
1639 destroy_named_field_class(named_fc);
1640 }
1641
1642 return status;
1643}
1644
1645static
1646int ranges_overlap(GPtrArray *var_fc_opts, const struct bt_integer_range_set *range_set,
1647 bool is_signed, bool *has_overlap)
1648{
1649 int status = BT_FUNC_STATUS_OK;
1650 struct bt_integer_range_set *full_range_set;
1651 uint64_t i;
1652
1653 *has_overlap = false;
1654
1655 /*
1656 * Build a single range set with all the ranges and test for
1657 * overlaps.
1658 */
1659 if (is_signed) {
1660 full_range_set = (void *) bt_integer_range_set_signed_create();
1661 } else {
1662 full_range_set = (void *) bt_integer_range_set_unsigned_create();
1663 }
1664
1665 if (!full_range_set) {
1666 BT_LOGE_STR("Failed to create a range set.");
1667 status = BT_FUNC_STATUS_MEMORY_ERROR;
1668 goto end;
1669 }
1670
1671 /* Add existing option ranges */
1672 for (i = 0; i < var_fc_opts->len; i++) {
1673 struct bt_field_class_variant_with_selector_field_option *opt =
1674 var_fc_opts->pdata[i];
1675 uint64_t j;
1676
1677 for (j = 0; j < opt->range_set->ranges->len; j++) {
1678 struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1679 opt->range_set, j);
1680
1681 if (is_signed) {
1682 status = bt_integer_range_set_signed_add_range(
1683 (void *) full_range_set, range->lower.i,
1684 range->upper.i);
1685 } else {
1686 status = bt_integer_range_set_unsigned_add_range(
1687 (void *) full_range_set, range->lower.u,
1688 range->upper.u);
1689 }
1690
1691 if (status) {
1692 goto end;
1693 }
1694 }
1695 }
1696
1697 /* Add new ranges */
1698 for (i = 0; i < range_set->ranges->len; i++) {
1699 struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1700 range_set, i);
1701
1702 if (is_signed) {
1703 status = bt_integer_range_set_signed_add_range(
1704 (void *) full_range_set, range->lower.i,
1705 range->upper.i);
1706 } else {
1707 status = bt_integer_range_set_unsigned_add_range(
1708 (void *) full_range_set, range->lower.u,
1709 range->upper.u);
1710 }
1711
1712 if (status) {
1713 goto end;
1714 }
1715 }
1716
1717 /* Check overlaps */
1718 if (is_signed) {
1719 *has_overlap = bt_integer_range_set_signed_has_overlaps(full_range_set);
1720 } else {
1721 *has_overlap = bt_integer_range_set_unsigned_has_overlaps(
1722 full_range_set);
1723 }
1724
1725end:
1726 bt_object_put_ref(full_range_set);
1727 return status;
1728}
1729
1730static
1731int append_option_to_variant_with_selector_field_field_class(
1732 struct bt_field_class *fc, const char *name,
1733 struct bt_field_class *option_fc,
1734 const struct bt_integer_range_set *range_set,
1735 enum bt_field_class_type expected_type,
1736 const char *api_func)
1737{
1738 int status;
1739 struct bt_field_class_variant_with_selector_field *var_fc = (void *) fc;
1740 struct bt_field_class_variant_with_selector_field_option *opt = NULL;
1741 bool has_overlap;
1742
1743 BT_ASSERT(fc);
1744 BT_ASSERT_PRE_NAME_NON_NULL_FROM_FUNC(api_func, name);
1745 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "option-field-class",
1746 option_fc, "Option field class");
1747 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL_FROM_FUNC(api_func, range_set);
1748 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY_FROM_FUNC(api_func, range_set);
1749 status = ranges_overlap(var_fc->common.common.named_fcs, range_set,
1750 expected_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1751 &has_overlap);
1752 if (status) {
1753 /* ranges_overlap() logs errors */
1754 goto end;
1755 }
1756
1757 BT_ASSERT_PRE_FROM_FUNC(api_func, "ranges-do-not-overlap",
1758 !has_overlap,
1759 "Integer range set's ranges and existing ranges have an overlap: "
1760 "%!+R", range_set);
1761 opt = create_variant_with_selector_field_option(name, option_fc, range_set);
1762 if (!opt) {
1763 /* create_variant_with_selector_field_option() logs errors */
1764 status = BT_FUNC_STATUS_MEMORY_ERROR;
1765 goto end;
1766 }
1767
1768 status = append_named_field_class_to_container_field_class((void *) fc,
1769 &opt->common, __func__, VAR_FC_OPT_NAME_IS_UNIQUE_ID);
1770 if (status == BT_FUNC_STATUS_OK) {
1771 /* Moved to the container */
1772 opt = NULL;
1773 }
1774
1775end:
1776 if (opt) {
1777 destroy_variant_with_selector_field_option(opt);
1778 }
1779
1780 return status;
1781}
1782
1783BT_EXPORT
1784enum bt_field_class_variant_with_selector_field_integer_append_option_status
1785bt_field_class_variant_with_selector_field_integer_unsigned_append_option(
1786 struct bt_field_class *fc, const char *name,
1787 struct bt_field_class *option_fc,
1788 const struct bt_integer_range_set_unsigned *range_set)
1789{
1790 BT_ASSERT_PRE_NO_ERROR();
1791 BT_ASSERT_PRE_FC_NON_NULL(fc);
1792 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1793 "variant-field-class-with-unsigned-integer-selector-field",
1794 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1795 "Field class");
1796 return append_option_to_variant_with_selector_field_field_class(fc,
1797 name, option_fc, (const void *) range_set,
1798 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1799 __func__);
1800}
1801
1802BT_EXPORT
1803enum bt_field_class_variant_with_selector_field_integer_append_option_status
1804bt_field_class_variant_with_selector_field_integer_signed_append_option(
1805 struct bt_field_class *fc, const char *name,
1806 struct bt_field_class *option_fc,
1807 const struct bt_integer_range_set_signed *range_set)
1808{
1809 BT_ASSERT_PRE_NO_ERROR();
1810 BT_ASSERT_PRE_FC_NON_NULL(fc);
1811 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1812 "variant-field-class-with-signed-integer-selector-field",
1813 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1814 "Field class");
1815 return append_option_to_variant_with_selector_field_field_class(fc,
1816 name, option_fc, (const void *) range_set,
1817 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1818 __func__);
1819}
1820
1821BT_EXPORT
1822uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc)
1823{
1824 const struct bt_field_class_variant *var_fc = (const void *) fc;
1825
1826 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1827 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
1828 return (uint64_t) var_fc->common.named_fcs->len;
1829}
1830
1831BT_EXPORT
1832const struct bt_field_class_variant_option *
1833bt_field_class_variant_borrow_option_by_name_const(
1834 const struct bt_field_class *fc, const char *name)
1835{
1836 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1837 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
1838 return (const void *)
1839 borrow_named_field_class_from_container_field_class_by_name(
1840 (void *) fc, name, __func__);
1841}
1842
1843BT_EXPORT
1844const struct bt_field_class_variant_option *
1845bt_field_class_variant_borrow_option_by_index_const(
1846 const struct bt_field_class *fc, uint64_t index)
1847{
1848 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1849 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
1850 return (const void *)
1851 borrow_named_field_class_from_container_field_class_at_index(
1852 (void *) fc, index, __func__);
1853}
1854
1855BT_EXPORT
1856struct bt_field_class_variant_option *
1857bt_field_class_variant_borrow_option_by_name(
1858 struct bt_field_class *fc, const char *name)
1859{
1860 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1861 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
1862 return (void *)
1863 borrow_named_field_class_from_container_field_class_by_name(
1864 (void *) fc, name, __func__);
1865}
1866
1867BT_EXPORT
1868struct bt_field_class_variant_option *
1869bt_field_class_variant_borrow_option_by_index(
1870 struct bt_field_class *fc, uint64_t index)
1871{
1872 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1873 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
1874 return (void *)
1875 borrow_named_field_class_from_container_field_class_at_index(
1876 (void *) fc, index, __func__);
1877}
1878
1879BT_EXPORT
1880const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *
1881bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_name_const(
1882 const struct bt_field_class *fc, const char *name)
1883{
1884 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1885 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1886 "variant-field-class-with-unsigned-integer-selector-field",
1887 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1888 "Field class");
1889 return (const void *)
1890 borrow_named_field_class_from_container_field_class_by_name(
1891 (void *) fc, name, __func__);
1892}
1893
1894BT_EXPORT
1895const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *
1896bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_index_const(
1897 const struct bt_field_class *fc, uint64_t index)
1898{
1899 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1900 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1901 "variant-field-class-with-unsigned-integer-selector-field",
1902 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1903 "Field class");
1904 return (const void *)
1905 borrow_named_field_class_from_container_field_class_at_index(
1906 (void *) fc, index, __func__);
1907}
1908
1909BT_EXPORT
1910const struct bt_field_class_variant_with_selector_field_integer_signed_option *
1911bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_name_const(
1912 const struct bt_field_class *fc, const char *name)
1913{
1914 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1915 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1916 "variant-field-class-with-signed-integer-selector-field",
1917 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1918 "Field class");
1919 return (const void *)
1920 borrow_named_field_class_from_container_field_class_by_name(
1921 (void *) fc, name, __func__);
1922}
1923
1924BT_EXPORT
1925const struct bt_field_class_variant_with_selector_field_integer_signed_option *
1926bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_index_const(
1927 const struct bt_field_class *fc, uint64_t index)
1928{
1929 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1930 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1931 "variant-field-class-with-signed-integer-selector-field",
1932 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1933 "Field class");
1934 return (const void *)
1935 borrow_named_field_class_from_container_field_class_at_index(
1936 (void *) fc, index, __func__);
1937}
1938
1939BT_EXPORT
1940const char *bt_field_class_variant_option_get_name(
1941 const struct bt_field_class_variant_option *option)
1942{
1943 const struct bt_named_field_class *named_fc = (const void *) option;
1944
1945 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1946 return named_fc->name->str;
1947}
1948
1949BT_EXPORT
1950const struct bt_field_class *
1951bt_field_class_variant_option_borrow_field_class_const(
1952 const struct bt_field_class_variant_option *option)
1953{
1954 const struct bt_named_field_class *named_fc = (const void *) option;
1955
1956 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1957 return named_fc->fc;
1958}
1959
1960BT_EXPORT
1961struct bt_field_class *
1962bt_field_class_variant_option_borrow_field_class(
1963 struct bt_field_class_variant_option *option)
1964{
1965 struct bt_named_field_class *named_fc = (void *) option;
1966
1967 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1968 return named_fc->fc;
1969}
1970
1971BT_EXPORT
1972const struct bt_integer_range_set_unsigned *
1973bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const(
1974 const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *option)
1975{
1976 const struct bt_field_class_variant_with_selector_field_option *opt =
1977 (const void *) option;
1978
1979 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1980 return (const void *) opt->range_set;
1981}
1982
1983BT_EXPORT
1984const struct bt_integer_range_set_signed *
1985bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const(
1986 const struct bt_field_class_variant_with_selector_field_integer_signed_option *option)
1987{
1988 const struct bt_field_class_variant_with_selector_field_option *opt =
1989 (const void *) option;
1990
1991 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1992 return (const void *) opt->range_set;
1993}
1994
1995BT_EXPORT
1996const struct bt_field_path *
1997bt_field_class_variant_with_selector_field_borrow_selector_field_path_const(
1998 const struct bt_field_class *fc)
1999{
2000 const struct bt_field_class_variant_with_selector_field *var_fc =
2001 (const void *) fc;
2002
2003 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2004 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL("field-class", fc,
2005 "Field class");
2006 return var_fc->selector_field_path;
2007}
2008
2009static
2010int init_array_field_class(struct bt_field_class_array *fc,
2011 enum bt_field_class_type type, bt_object_release_func release_func,
2012 struct bt_field_class *element_fc)
2013{
2014 int ret;
2015
2016 BT_ASSERT(element_fc);
2017 ret = init_field_class((void *) fc, type, release_func);
2018 if (ret) {
2019 goto end;
2020 }
2021
2022 fc->element_fc = element_fc;
2023 bt_object_get_ref_no_null_check(fc->element_fc);
2024 bt_field_class_freeze(element_fc);
2025
2026end:
2027 return ret;
2028}
2029
2030static
2031void finalize_array_field_class(struct bt_field_class_array *array_fc)
2032{
2033 BT_ASSERT(array_fc);
2034 BT_LOGD_STR("Putting element field class.");
2035 finalize_field_class((void *) array_fc);
2036 BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc);
2037}
2038
2039static
2040void destroy_static_array_field_class(struct bt_object *obj)
2041{
2042 BT_ASSERT(obj);
2043 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj);
2044 finalize_array_field_class((void *) obj);
2045 g_free(obj);
2046}
2047
2048BT_EXPORT
2049struct bt_field_class *
2050bt_field_class_array_static_create(bt_trace_class *trace_class,
2051 struct bt_field_class *element_fc, uint64_t length)
2052{
2053 struct bt_field_class_array_static *array_fc = NULL;
2054
2055 BT_ASSERT_PRE_NO_ERROR();
2056 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2057 BT_ASSERT_PRE_NON_NULL("element-field-class", element_fc,
2058 "Element field class");
2059 BT_LOGD_STR("Creating default static array field class object.");
2060 array_fc = g_new0(struct bt_field_class_array_static, 1);
2061 if (!array_fc) {
2062 BT_LIB_LOGE_APPEND_CAUSE(
2063 "Failed to allocate one static array field class.");
2064 goto error;
2065 }
2066
2067 if (init_array_field_class((void *) array_fc,
2068 BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
2069 destroy_static_array_field_class, element_fc)) {
2070 goto error;
2071 }
2072
2073 array_fc->length = length;
2074 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc);
2075 goto end;
2076
2077error:
2078 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2079
2080end:
2081 return (void *) array_fc;
2082}
2083
2084BT_EXPORT
2085const struct bt_field_class *
2086bt_field_class_array_borrow_element_field_class_const(
2087 const struct bt_field_class *fc)
2088{
2089 const struct bt_field_class_array *array_fc = (const void *) fc;
2090
2091 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2092 BT_ASSERT_PRE_DEV_FC_IS_ARRAY("field-class", fc, "Field class");
2093 return array_fc->element_fc;
2094}
2095
2096BT_EXPORT
2097struct bt_field_class *
2098bt_field_class_array_borrow_element_field_class(struct bt_field_class *fc)
2099{
2100 struct bt_field_class_array *array_fc = (void *) fc;
2101
2102 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2103 BT_ASSERT_PRE_DEV_FC_IS_ARRAY("field-class", fc, "Field class");
2104 return array_fc->element_fc;
2105}
2106
2107BT_EXPORT
2108uint64_t bt_field_class_array_static_get_length(const struct bt_field_class *fc)
2109{
2110 const struct bt_field_class_array_static *array_fc = (const void *) fc;
2111
2112 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2113 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
2114 "static-array-field-class", BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
2115 "Field class");
2116 return (uint64_t) array_fc->length;
2117}
2118
2119static
2120void destroy_dynamic_array_field_class(struct bt_object *obj)
2121{
2122 struct bt_field_class_array_dynamic *fc = (void *) obj;
2123
2124 BT_ASSERT(fc);
2125 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc);
2126 finalize_array_field_class((void *) fc);
2127 BT_LOGD_STR("Putting length field path.");
2128 BT_OBJECT_PUT_REF_AND_RESET(fc->length_field_path);
2129 BT_LOGD_STR("Putting length field class.");
2130 BT_OBJECT_PUT_REF_AND_RESET(fc->length_fc);
2131 g_free(fc);
2132}
2133
2134BT_EXPORT
2135struct bt_field_class *bt_field_class_array_dynamic_create(
2136 struct bt_trace_class *trace_class,
2137 struct bt_field_class *element_fc,
2138 struct bt_field_class *length_fc)
2139{
2140 struct bt_field_class_array_dynamic *array_fc = NULL;
2141
2142 BT_ASSERT_PRE_NO_ERROR();
2143 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2144 BT_ASSERT_PRE_NON_NULL("element-field-class", element_fc,
2145 "Element field class");
2146 BT_LOGD_STR("Creating default dynamic array field class object.");
2147 array_fc = g_new0(struct bt_field_class_array_dynamic, 1);
2148 if (!array_fc) {
2149 BT_LIB_LOGE_APPEND_CAUSE(
2150 "Failed to allocate one dynamic array field class.");
2151 goto error;
2152 }
2153
2154 if (init_array_field_class((void *) array_fc,
2155 length_fc ?
2156 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD :
2157 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD,
2158 destroy_dynamic_array_field_class, element_fc)) {
2159 goto error;
2160 }
2161
2162 if (length_fc) {
2163 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT("length-field-class",
2164 length_fc, "Length field class");
2165 array_fc->length_fc = length_fc;
2166 bt_object_get_ref_no_null_check(array_fc->length_fc);
2167 bt_field_class_freeze(length_fc);
2168 }
2169
2170 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc);
2171 goto end;
2172
2173error:
2174 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2175
2176end:
2177 return (void *) array_fc;
2178}
2179
2180BT_EXPORT
2181const struct bt_field_path *
2182bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const(
2183 const struct bt_field_class *fc)
2184{
2185 const struct bt_field_class_array_dynamic *seq_fc = (const void *) fc;
2186
2187 BT_ASSERT_PRE_NO_ERROR();
2188 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2189 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2190 "dynamic-array-field-class-with-length-field",
2191 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD,
2192 "Field class");
2193 return seq_fc->length_field_path;
2194}
2195
2196static
2197void destroy_string_field_class(struct bt_object *obj)
2198{
2199 BT_ASSERT(obj);
2200 BT_LIB_LOGD("Destroying string field class object: %!+F", obj);
2201 finalize_field_class((void *) obj);
2202 g_free(obj);
2203}
2204
2205BT_EXPORT
2206struct bt_field_class *bt_field_class_string_create(bt_trace_class *trace_class)
2207{
2208 struct bt_field_class_string *string_fc = NULL;
2209
2210 BT_ASSERT_PRE_NO_ERROR();
2211 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2212 BT_LOGD_STR("Creating default string field class object.");
2213 string_fc = g_new0(struct bt_field_class_string, 1);
2214 if (!string_fc) {
2215 BT_LIB_LOGE_APPEND_CAUSE(
2216 "Failed to allocate one string field class.");
2217 goto error;
2218 }
2219
2220 if (init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING,
2221 destroy_string_field_class)) {
2222 goto error;
2223 }
2224
2225 BT_LIB_LOGD("Created string field class object: %!+F", string_fc);
2226 goto end;
2227
2228error:
2229 BT_OBJECT_PUT_REF_AND_RESET(string_fc);
2230
2231end:
2232 return (void *) string_fc;
2233}
2234
2235void _bt_field_class_freeze(const struct bt_field_class *c_fc)
2236{
2237 struct bt_field_class *fc = (void *) c_fc;
2238
2239 /*
2240 * Element/member/option field classes are frozen when added to
2241 * their owner.
2242 */
2243 BT_ASSERT(fc);
2244 bt_value_freeze(fc->user_attributes);
2245 fc->frozen = true;
2246
2247 if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
2248 bt_field_class_type_is(fc->type,
2249 BT_FIELD_CLASS_TYPE_VARIANT)) {
2250 struct bt_field_class_named_field_class_container *container_fc =
2251 (void *) fc;
2252 uint64_t i;
2253
2254 for (i = 0; i < container_fc->named_fcs->len; i++) {
2255 bt_named_field_class_freeze(
2256 container_fc->named_fcs->pdata[i]);
2257 }
2258 }
2259}
2260
2261void _bt_named_field_class_freeze(const struct bt_named_field_class *named_fc)
2262{
2263 BT_ASSERT(named_fc);
2264 BT_ASSERT(named_fc->fc->frozen);
2265 BT_LIB_LOGD("Freezing named field class's user attributes: %!+v",
2266 named_fc->user_attributes);
2267 bt_value_freeze(named_fc->user_attributes);
2268 ((struct bt_named_field_class *) named_fc)->frozen = true;
2269}
2270
2271void bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc)
2272{
2273 struct bt_field_class *fc = (void *) c_fc;
2274
2275 BT_ASSERT(fc);
2276 BT_ASSERT_PRE("field-class-is-not-part-of-trace-class",
2277 !fc->part_of_trace_class,
2278 "Field class is already part of a trace class: %!+F", fc);
2279 fc->part_of_trace_class = true;
2280
2281 if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
2282 bt_field_class_type_is(fc->type,
2283 BT_FIELD_CLASS_TYPE_VARIANT)) {
2284 struct bt_field_class_named_field_class_container *container_fc =
2285 (void *) fc;
2286 uint64_t i;
2287
2288 for (i = 0; i < container_fc->named_fcs->len; i++) {
2289 struct bt_named_field_class *named_fc =
2290 container_fc->named_fcs->pdata[i];
2291
2292 bt_field_class_make_part_of_trace_class(named_fc->fc);
2293 }
2294 } else if (bt_field_class_type_is(fc->type,
2295 BT_FIELD_CLASS_TYPE_ARRAY)) {
2296 struct bt_field_class_array *array_fc = (void *) fc;
2297
2298 bt_field_class_make_part_of_trace_class(array_fc->element_fc);
2299 }
2300}
2301
2302BT_EXPORT
2303const struct bt_value *bt_field_class_borrow_user_attributes_const(
2304 const struct bt_field_class *fc)
2305{
2306 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2307 return fc->user_attributes;
2308}
2309
2310BT_EXPORT
2311struct bt_value *bt_field_class_borrow_user_attributes(
2312 struct bt_field_class *field_class)
2313{
2314 return (void *) bt_field_class_borrow_user_attributes_const(
2315 (void *) field_class);
2316}
2317
2318
2319BT_EXPORT
2320void bt_field_class_set_user_attributes(
2321 struct bt_field_class *fc,
2322 const struct bt_value *user_attributes)
2323{
2324 BT_ASSERT_PRE_FC_NON_NULL(fc);
2325 BT_ASSERT_PRE_USER_ATTRS_NON_NULL(user_attributes);
2326 BT_ASSERT_PRE_USER_ATTRS_IS_MAP(user_attributes);
2327 BT_ASSERT_PRE_DEV_FC_HOT(fc);
2328 bt_object_put_ref_no_null_check(fc->user_attributes);
2329 fc->user_attributes = (void *) user_attributes;
2330 bt_object_get_ref_no_null_check(fc->user_attributes);
2331}
2332
2333static
2334const struct bt_value *bt_named_field_class_borrow_user_attributes_const(
2335 const struct bt_named_field_class *named_fc)
2336{
2337 return named_fc->user_attributes;
2338}
2339
2340static
2341void set_named_field_class_user_attributes(
2342 struct bt_named_field_class *named_fc,
2343 const struct bt_value *user_attributes, const char *api_func)
2344{
2345 BT_ASSERT_PRE_USER_ATTRS_NON_NULL_FROM_FUNC(api_func, user_attributes);
2346 BT_ASSERT_PRE_USER_ATTRS_NON_NULL_FROM_FUNC(api_func, user_attributes);
2347 bt_object_put_ref_no_null_check(named_fc->user_attributes);
2348 named_fc->user_attributes = (void *) user_attributes;
2349 bt_object_get_ref_no_null_check(named_fc->user_attributes);
2350}
2351
2352BT_EXPORT
2353const struct bt_value *
2354bt_field_class_structure_member_borrow_user_attributes_const(
2355 const struct bt_field_class_structure_member *member)
2356{
2357 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
2358 return bt_named_field_class_borrow_user_attributes_const(
2359 (const void *) member);
2360}
2361
2362BT_EXPORT
2363struct bt_value *
2364bt_field_class_structure_member_borrow_user_attributes(
2365 struct bt_field_class_structure_member *member)
2366{
2367 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
2368 return (void *) bt_named_field_class_borrow_user_attributes_const(
2369 (void *) member);
2370}
2371
2372BT_EXPORT
2373void bt_field_class_structure_member_set_user_attributes(
2374 struct bt_field_class_structure_member *member,
2375 const struct bt_value *user_attributes)
2376{
2377 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
2378 BT_ASSERT_PRE_DEV_HOT("structure-field-class-member",
2379 (struct bt_named_field_class *) member,
2380 "Structure field class member", ".");
2381 set_named_field_class_user_attributes((void *) member,
2382 user_attributes, __func__);
2383}
2384
2385BT_EXPORT
2386const struct bt_value *bt_field_class_variant_option_borrow_user_attributes_const(
2387 const struct bt_field_class_variant_option *option)
2388{
2389 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
2390 return bt_named_field_class_borrow_user_attributes_const(
2391 (const void *) option);
2392}
2393
2394BT_EXPORT
2395struct bt_value *bt_field_class_variant_option_borrow_user_attributes(
2396 struct bt_field_class_variant_option *option)
2397{
2398 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
2399 return (void *) bt_named_field_class_borrow_user_attributes_const(
2400 (void *) option);
2401}
2402
2403BT_EXPORT
2404void bt_field_class_variant_option_set_user_attributes(
2405 struct bt_field_class_variant_option *option,
2406 const struct bt_value *user_attributes)
2407{
2408 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
2409 BT_ASSERT_PRE_DEV_HOT("variant-field-class-option",
2410 (struct bt_named_field_class *) option,
2411 "Variant field class option", ".");
2412 set_named_field_class_user_attributes((void *) option,
2413 user_attributes, __func__);
2414}
2415
2416BT_EXPORT
2417void bt_field_class_get_ref(const struct bt_field_class *field_class)
2418{
2419 bt_object_get_ref(field_class);
2420}
2421
2422BT_EXPORT
2423void bt_field_class_put_ref(const struct bt_field_class *field_class)
2424{
2425 bt_object_put_ref(field_class);
2426}
This page took 0.05123 seconds and 5 git commands to generate.