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