cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / lib / trace-ir / field-class.c
CommitLineData
5cd6d0e5 1/*
0235b0db
MJ
2 * SPDX-License-Identifier: MIT
3 *
e2f7325d 4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
5cd6d0e5 5 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5cd6d0e5
PP
6 */
7
350ad6c1 8#define BT_LOG_TAG "LIB/FIELD-CLASS"
c2d9d9cf 9#include "lib/logging.h"
5cd6d0e5 10
d98421f2 11#include "lib/assert-cond.h"
3fadfbc0 12#include <babeltrace2/trace-ir/field-class.h>
3fadfbc0 13#include <babeltrace2/trace-ir/field.h>
3fadfbc0 14#include <babeltrace2/trace-ir/clock-class.h>
578e048b
MJ
15#include "lib/object.h"
16#include "compat/compiler.h"
17#include "compat/endian.h"
18#include "common/assert.h"
5a3fec55 19#include "common/common.h"
578e048b 20#include "compat/glib.h"
5cd6d0e5 21#include <inttypes.h>
c4f23e30 22#include <stdbool.h>
5cd6d0e5
PP
23#include <stdlib.h>
24
578e048b 25#include "field-class.h"
578e048b 26#include "field-path.h"
d24d5663 27#include "lib/func-status.h"
45c51519 28#include "lib/integer-range-set.h"
c6962c96 29#include "lib/value.h"
578e048b 30
1353b066 31BT_EXPORT
40f4ba76
PP
32enum bt_field_class_type bt_field_class_get_type(
33 const struct bt_field_class *fc)
5cd6d0e5 34{
d5b13b9b 35 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
864cad70 36 return fc->type;
5cd6d0e5
PP
37}
38
39static
c6962c96 40int init_field_class(struct bt_field_class *fc, enum bt_field_class_type type,
5cd6d0e5
PP
41 bt_object_release_func release_func)
42{
c6962c96
PP
43 int ret = 0;
44
5cd6d0e5 45 BT_ASSERT(fc);
5cd6d0e5
PP
46 BT_ASSERT(release_func);
47 bt_object_init_shared(&fc->base, release_func);
864cad70 48 fc->type = type;
c6962c96
PP
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);
5cd6d0e5
PP
65}
66
1094efa4
PP
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);
c6962c96 72 finalize_field_class((void *) obj);
1094efa4
PP
73 g_free(obj);
74}
75
1353b066 76BT_EXPORT
1094efa4
PP
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
17f3083a 82 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 83 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1778c2a4 84 BT_ASSERT_PRE("valid-length", length > 0 && length <= 64,
1094efa4
PP
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
c6962c96
PP
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
1094efa4
PP
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
1353b066 111BT_EXPORT
1094efa4
PP
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
d5b13b9b 116 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4
PP
117 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
118 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
1094efa4
PP
119 return ba_fc->length;
120}
121
5cebbe7f
PP
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);
c6962c96 127 finalize_field_class((void *) obj);
5cebbe7f
PP
128 g_free(obj);
129}
130
1353b066 131BT_EXPORT
5cebbe7f
PP
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
17f3083a 137 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 138 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
5cebbe7f
PP
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
c6962c96
PP
147 if (init_field_class((void *) bool_fc, BT_FIELD_CLASS_TYPE_BOOL,
148 destroy_bool_field_class)) {
149 goto error;
150 }
151
5cebbe7f
PP
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
5cd6d0e5 162static
c6962c96 163int init_integer_field_class(struct bt_field_class_integer *fc,
864cad70 164 enum bt_field_class_type type,
5cd6d0e5
PP
165 bt_object_release_func release_func)
166{
c6962c96
PP
167 int ret;
168
169 ret = init_field_class((void *) fc, type, release_func);
170 if (ret) {
171 goto end;
172 }
173
5cd6d0e5
PP
174 fc->range = 64;
175 fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
c6962c96
PP
176
177end:
178 return ret;
5cd6d0e5
PP
179}
180
181static
182void destroy_integer_field_class(struct bt_object *obj)
183{
184 BT_ASSERT(obj);
e5be10ef 185 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj);
c6962c96 186 finalize_field_class((void *) obj);
5cd6d0e5
PP
187 g_free(obj);
188}
189
190static inline
1122a43a
PP
191struct bt_field_class *create_integer_field_class(bt_trace_class *trace_class,
192 enum bt_field_class_type type)
5cd6d0e5
PP
193{
194 struct bt_field_class_integer *int_fc = NULL;
195
d5b13b9b 196 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
e5be10ef 197 BT_LOGD("Creating default integer field class object: type=%s",
864cad70 198 bt_common_field_class_type_string(type));
5cd6d0e5
PP
199 int_fc = g_new0(struct bt_field_class_integer, 1);
200 if (!int_fc) {
870631a2
PP
201 BT_LIB_LOGE_APPEND_CAUSE(
202 "Failed to allocate one integer field class.");
5cd6d0e5
PP
203 goto error;
204 }
205
c6962c96
PP
206 if (init_integer_field_class(int_fc, type,
207 destroy_integer_field_class)) {
208 goto error;
209 }
210
e5be10ef 211 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc);
5cd6d0e5
PP
212 goto end;
213
214error:
65300d60 215 BT_OBJECT_PUT_REF_AND_RESET(int_fc);
5cd6d0e5
PP
216
217end:
218 return (void *) int_fc;
219}
220
1353b066 221BT_EXPORT
9c08c816 222struct bt_field_class *bt_field_class_integer_unsigned_create(
1122a43a 223 bt_trace_class *trace_class)
5cd6d0e5 224{
17f3083a
SM
225 BT_ASSERT_PRE_NO_ERROR();
226
1122a43a 227 return create_integer_field_class(trace_class,
e5be10ef 228 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER);
5cd6d0e5
PP
229}
230
1353b066 231BT_EXPORT
9c08c816 232struct bt_field_class *bt_field_class_integer_signed_create(
1122a43a 233 bt_trace_class *trace_class)
5cd6d0e5 234{
17f3083a
SM
235 BT_ASSERT_PRE_NO_ERROR();
236
1122a43a 237 return create_integer_field_class(trace_class,
e5be10ef 238 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER);
5cd6d0e5
PP
239}
240
1353b066 241BT_EXPORT
5cd6d0e5 242uint64_t bt_field_class_integer_get_field_value_range(
40f4ba76 243 const struct bt_field_class *fc)
5cd6d0e5 244{
40f4ba76 245 const struct bt_field_class_integer *int_fc = (const void *) fc;
5cd6d0e5 246
d5b13b9b 247 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 248 BT_ASSERT_PRE_DEV_FC_IS_INT("field-class", fc, "Field class");
5cd6d0e5
PP
249 return int_fc->range;
250}
251
5cd6d0e5 252static
ecd7492f
MJ
253bool size_is_valid_for_enumeration_field_class(
254 struct bt_field_class *fc __attribute__((unused)),
255 uint64_t size __attribute__((unused)))
5cd6d0e5
PP
256{
257 // TODO
258 return true;
259}
260
1353b066 261BT_EXPORT
40f4ba76
PP
262void bt_field_class_integer_set_field_value_range(
263 struct bt_field_class *fc, uint64_t size)
5cd6d0e5
PP
264{
265 struct bt_field_class_integer *int_fc = (void *) fc;
266
d5b13b9b 267 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
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,
e5be10ef 272 "Unsupported size for integer field class's field value range "
b19bbc8a 273 "(minimum is 1, maximum is 64): size=%" PRIu64, size);
1778c2a4 274 BT_ASSERT_PRE("valid-n-for-enumeration-field-class",
864cad70
PP
275 int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
276 int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
5cd6d0e5 277 size_is_valid_for_enumeration_field_class(fc, size),
e5be10ef 278 "Invalid field value range for enumeration field class: "
5cd6d0e5
PP
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;
3f7d4d90 282 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc);
5cd6d0e5
PP
283}
284
1353b066 285BT_EXPORT
5cd6d0e5 286enum bt_field_class_integer_preferred_display_base
40f4ba76 287bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc)
5cd6d0e5 288{
40f4ba76 289 const struct bt_field_class_integer *int_fc = (const void *) fc;
5cd6d0e5 290
d5b13b9b 291 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 292 BT_ASSERT_PRE_DEV_FC_IS_INT("field-class", fc, "Field class");
5cd6d0e5
PP
293 return int_fc->base;
294}
295
1353b066 296BT_EXPORT
40f4ba76
PP
297void bt_field_class_integer_set_preferred_display_base(
298 struct bt_field_class *fc,
5cd6d0e5
PP
299 enum bt_field_class_integer_preferred_display_base base)
300{
301 struct bt_field_class_integer *int_fc = (void *) fc;
302
d5b13b9b 303 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
304 BT_ASSERT_PRE_FC_IS_INT("field-class", fc, "Field class");
305 BT_ASSERT_PRE_DEV_FC_HOT(fc);
5cd6d0e5 306 int_fc->base = base;
3f7d4d90 307 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc);
5cd6d0e5
PP
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);
45c51519 318 mapping->label = NULL;
5cd6d0e5
PP
319 }
320
45c51519 321 BT_OBJECT_PUT_REF_AND_RESET(mapping->range_set);
5cd6d0e5
PP
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);
e5be10ef 330 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc);
c6962c96 331 finalize_field_class((void *) obj);
5cd6d0e5
PP
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);
238b7404 342 fc->mappings = NULL;
5cd6d0e5
PP
343 }
344
345 if (fc->label_buf) {
346 g_ptr_array_free(fc->label_buf, TRUE);
238b7404 347 fc->label_buf = NULL;
5cd6d0e5
PP
348 }
349
350 g_free(fc);
351}
352
353static
40f4ba76 354struct bt_field_class *create_enumeration_field_class(
1122a43a 355 bt_trace_class *trace_class, enum bt_field_class_type type)
5cd6d0e5
PP
356{
357 struct bt_field_class_enumeration *enum_fc = NULL;
358
d5b13b9b 359 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
e5be10ef 360 BT_LOGD("Creating default enumeration field class object: type=%s",
864cad70 361 bt_common_field_class_type_string(type));
5cd6d0e5
PP
362 enum_fc = g_new0(struct bt_field_class_enumeration, 1);
363 if (!enum_fc) {
870631a2
PP
364 BT_LIB_LOGE_APPEND_CAUSE(
365 "Failed to allocate one enumeration field class.");
5cd6d0e5
PP
366 goto error;
367 }
368
c6962c96
PP
369 if (init_integer_field_class((void *) enum_fc, type,
370 destroy_enumeration_field_class)) {
371 goto error;
372 }
373
5cd6d0e5
PP
374 enum_fc->mappings = g_array_new(FALSE, TRUE,
375 sizeof(struct bt_field_class_enumeration_mapping));
376 if (!enum_fc->mappings) {
870631a2 377 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
5cd6d0e5
PP
378 goto error;
379 }
380
381 enum_fc->label_buf = g_ptr_array_new();
382 if (!enum_fc->label_buf) {
870631a2 383 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
5cd6d0e5
PP
384 goto error;
385 }
386
e5be10ef 387 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc);
5cd6d0e5
PP
388 goto end;
389
390error:
65300d60 391 BT_OBJECT_PUT_REF_AND_RESET(enum_fc);
5cd6d0e5
PP
392
393end:
394 return (void *) enum_fc;
395}
396
1353b066 397BT_EXPORT
9c08c816 398struct bt_field_class *bt_field_class_enumeration_unsigned_create(
1122a43a 399 bt_trace_class *trace_class)
5cd6d0e5 400{
17f3083a
SM
401 BT_ASSERT_PRE_NO_ERROR();
402
1122a43a 403 return create_enumeration_field_class(trace_class,
864cad70 404 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION);
5cd6d0e5
PP
405}
406
1353b066 407BT_EXPORT
9c08c816 408struct bt_field_class *bt_field_class_enumeration_signed_create(
1122a43a 409 bt_trace_class *trace_class)
5cd6d0e5 410{
17f3083a
SM
411 BT_ASSERT_PRE_NO_ERROR();
412
1122a43a 413 return create_enumeration_field_class(trace_class,
864cad70 414 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
5cd6d0e5
PP
415}
416
1353b066 417BT_EXPORT
40f4ba76
PP
418uint64_t bt_field_class_enumeration_get_mapping_count(
419 const struct bt_field_class *fc)
5cd6d0e5 420{
40f4ba76 421 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5 422
d5b13b9b 423 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 424 BT_ASSERT_PRE_DEV_FC_IS_ENUM("field-class", fc, "Field class");
5cd6d0e5
PP
425 return (uint64_t) enum_fc->mappings->len;
426}
427
1353b066 428BT_EXPORT
9c08c816
PP
429const struct bt_field_class_enumeration_unsigned_mapping *
430bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
8f3ccfbc 431 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 432{
40f4ba76 433 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5 434
d5b13b9b 435 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
bdb288b3 436 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
1778c2a4
PP
437 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
438 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
8f3ccfbc 439 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
5cd6d0e5
PP
440}
441
1353b066 442BT_EXPORT
9c08c816
PP
443const struct bt_field_class_enumeration_signed_mapping *
444bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
8f3ccfbc 445 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 446{
40f4ba76 447 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5 448
d5b13b9b 449 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
bdb288b3 450 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
1778c2a4
PP
451 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
452 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
8f3ccfbc 453 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
5cd6d0e5
PP
454}
455
45c51519
PP
456static
457const struct bt_field_class_enumeration_mapping *
458borrow_enumeration_field_class_mapping_by_label(
1778c2a4
PP
459 const struct bt_field_class_enumeration *fc, const char *label,
460 const char *api_func)
5cd6d0e5 461{
45c51519
PP
462 struct bt_field_class_enumeration_mapping *mapping = NULL;
463 uint64_t i;
464
98b15851 465 BT_ASSERT_DBG(fc);
1778c2a4
PP
466 BT_ASSERT_PRE_DEV_NON_NULL_FROM_FUNC(api_func, "label", label,
467 "Label");
45c51519
PP
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;
5cd6d0e5
PP
481}
482
1353b066 483BT_EXPORT
9c08c816
PP
484const struct bt_field_class_enumeration_signed_mapping *
485bt_field_class_enumeration_signed_borrow_mapping_by_label_const(
45c51519 486 const struct bt_field_class *fc, const char *label)
5cd6d0e5 487{
d5b13b9b 488 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4
PP
489 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
490 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
45c51519 491 return (const void *) borrow_enumeration_field_class_mapping_by_label(
1778c2a4 492 (const void *) fc, label, __func__);
5cd6d0e5
PP
493}
494
1353b066 495BT_EXPORT
9c08c816
PP
496const struct bt_field_class_enumeration_unsigned_mapping *
497bt_field_class_enumeration_unsigned_borrow_mapping_by_label_const(
45c51519 498 const struct bt_field_class *fc, const char *label)
5cd6d0e5 499{
d5b13b9b 500 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 501 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
45c51519
PP
502 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
503 return (const void *) borrow_enumeration_field_class_mapping_by_label(
1778c2a4 504 (const void *) fc, label, __func__);
45c51519 505}
5cd6d0e5 506
1353b066 507BT_EXPORT
45c51519
PP
508const char *bt_field_class_enumeration_mapping_get_label(
509 const struct bt_field_class_enumeration_mapping *mapping)
510{
1778c2a4
PP
511 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
512 mapping, "Enumeration field class mapping");
45c51519 513 return mapping->label->str;
5cd6d0e5
PP
514}
515
1353b066 516BT_EXPORT
45c51519 517const struct bt_integer_range_set_unsigned *
9c08c816
PP
518bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
519 const struct bt_field_class_enumeration_unsigned_mapping *u_mapping)
5cd6d0e5 520{
45c51519
PP
521 const struct bt_field_class_enumeration_mapping *mapping =
522 (const void *) u_mapping;
523
1778c2a4
PP
524 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
525 mapping, "Enumeration field class mapping");
45c51519 526 return (const void *) mapping->range_set;
5cd6d0e5
PP
527}
528
1353b066 529BT_EXPORT
45c51519 530const struct bt_integer_range_set_signed *
9c08c816
PP
531bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
532 const struct bt_field_class_enumeration_signed_mapping *s_mapping)
5cd6d0e5 533{
45c51519
PP
534 const struct bt_field_class_enumeration_mapping *mapping =
535 (const void *) s_mapping;
536
1778c2a4
PP
537 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
538 mapping, "Enumeration field class mapping");
45c51519 539 return (const void *) mapping->range_set;
5cd6d0e5
PP
540}
541
1353b066 542BT_EXPORT
185ecf64 543enum bt_field_class_enumeration_get_mapping_labels_for_value_status
9c08c816 544bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
40f4ba76 545 const struct bt_field_class *fc, uint64_t value,
5cd6d0e5
PP
546 bt_field_class_enumeration_mapping_label_array *label_array,
547 uint64_t *count)
548{
40f4ba76 549 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
550 uint64_t i;
551
17f3083a 552 BT_ASSERT_PRE_DEV_NO_ERROR();
d5b13b9b 553 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4
PP
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");
5cd6d0e5
PP
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;
40f4ba76 563 const struct bt_field_class_enumeration_mapping *mapping =
5cd6d0e5
PP
564 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
565
45c51519
PP
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);
5cd6d0e5
PP
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;
d24d5663 582 return BT_FUNC_STATUS_OK;
5cd6d0e5
PP
583}
584
1353b066 585BT_EXPORT
185ecf64 586enum bt_field_class_enumeration_get_mapping_labels_for_value_status
9c08c816 587bt_field_class_enumeration_signed_get_mapping_labels_for_value(
40f4ba76 588 const struct bt_field_class *fc, int64_t value,
5cd6d0e5
PP
589 bt_field_class_enumeration_mapping_label_array *label_array,
590 uint64_t *count)
591{
40f4ba76 592 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
593 uint64_t i;
594
17f3083a 595 BT_ASSERT_PRE_DEV_NO_ERROR();
d5b13b9b 596 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4
PP
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");
5cd6d0e5
PP
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;
40f4ba76 606 const struct bt_field_class_enumeration_mapping *mapping =
5cd6d0e5
PP
607 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
608
45c51519
PP
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);
5cd6d0e5
PP
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;
d24d5663 625 return BT_FUNC_STATUS_OK;
5cd6d0e5
PP
626}
627
45c51519
PP
628static
629bool enumeration_field_class_has_mapping_with_label(
630 const struct bt_field_class_enumeration *enum_fc,
631 const char *label)
5cd6d0e5 632{
5cd6d0e5 633 uint64_t i;
45c51519 634 bool exists = false;
5cd6d0e5 635
45c51519
PP
636 BT_ASSERT(enum_fc);
637 BT_ASSERT(label);
5cd6d0e5 638
5cd6d0e5
PP
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) {
45c51519
PP
644 exists = true;
645 goto end;
5cd6d0e5
PP
646 }
647 }
648
45c51519
PP
649end:
650 return exists;
651}
5cd6d0e5 652
45c51519
PP
653static inline
654enum bt_field_class_enumeration_add_mapping_status
655add_mapping_to_enumeration_field_class(struct bt_field_class *fc,
1778c2a4
PP
656 const char *label, const struct bt_integer_range_set *range_set,
657 const char *api_func)
45c51519
PP
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
1778c2a4 664 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
45c51519 665 BT_ASSERT(fc);
1778c2a4
PP
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),
45c51519
PP
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;
5cd6d0e5
PP
681 }
682
45c51519 683 g_array_append_val(enum_fc->mappings, mapping);
3f7d4d90 684 BT_LIB_LOGD("Added mapping to enumeration field class: "
45c51519 685 "%![fc-]+F, label=\"%s\"", fc, label);
5cd6d0e5
PP
686
687end:
45c51519 688 return status;
5cd6d0e5
PP
689}
690
1353b066 691BT_EXPORT
45c51519 692enum bt_field_class_enumeration_add_mapping_status
9c08c816 693bt_field_class_enumeration_unsigned_add_mapping(
40f4ba76 694 struct bt_field_class *fc, const char *label,
45c51519 695 const struct bt_integer_range_set_unsigned *range_set)
5cd6d0e5 696{
17f3083a 697 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 698 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
699 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
700 "unsigned-enumeration-field-class",
701 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
45c51519 702 return add_mapping_to_enumeration_field_class(fc, label,
1778c2a4 703 (const void *) range_set, __func__);
45c51519
PP
704}
705
1353b066 706BT_EXPORT
45c51519 707enum bt_field_class_enumeration_add_mapping_status
9c08c816 708bt_field_class_enumeration_signed_add_mapping(
40f4ba76 709 struct bt_field_class *fc, const char *label,
45c51519 710 const struct bt_integer_range_set_signed *range_set)
5cd6d0e5 711{
17f3083a 712 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 713 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
714 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
715 "signed-enumeration-field-class",
716 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
45c51519 717 return add_mapping_to_enumeration_field_class(fc, label,
1778c2a4 718 (const void *) range_set, __func__);
5cd6d0e5
PP
719}
720
721static
722void destroy_real_field_class(struct bt_object *obj)
723{
724 BT_ASSERT(obj);
e5be10ef 725 BT_LIB_LOGD("Destroying real field class object: %!+F", obj);
c6962c96 726 finalize_field_class((void *) obj);
5cd6d0e5
PP
727 g_free(obj);
728}
729
fe4df857
FD
730static
731struct bt_field_class *create_real_field_class(bt_trace_class *trace_class,
732 enum bt_field_class_type type)
5cd6d0e5
PP
733{
734 struct bt_field_class_real *real_fc = NULL;
735
d5b13b9b 736 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
fe4df857
FD
737 BT_LOGD("Creating default real field class object: type=%s",
738 bt_common_field_class_type_string(type));
5cd6d0e5
PP
739 real_fc = g_new0(struct bt_field_class_real, 1);
740 if (!real_fc) {
870631a2 741 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
5cd6d0e5
PP
742 goto error;
743 }
744
fe4df857 745 if (init_field_class((void *) real_fc, type, destroy_real_field_class)) {
c6962c96
PP
746 goto error;
747 }
748
e5be10ef 749 BT_LIB_LOGD("Created real field class object: %!+F", real_fc);
5cd6d0e5
PP
750 goto end;
751
752error:
65300d60 753 BT_OBJECT_PUT_REF_AND_RESET(real_fc);
5cd6d0e5
PP
754
755end:
756 return (void *) real_fc;
757}
758
1353b066 759BT_EXPORT
fe4df857
FD
760struct bt_field_class *bt_field_class_real_single_precision_create(
761 bt_trace_class *trace_class)
5cd6d0e5 762{
17f3083a
SM
763 BT_ASSERT_PRE_NO_ERROR();
764
fe4df857
FD
765 return create_real_field_class(trace_class,
766 BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL);
5cd6d0e5
PP
767}
768
1353b066 769BT_EXPORT
fe4df857
FD
770struct bt_field_class *bt_field_class_real_double_precision_create(
771 bt_trace_class *trace_class)
5cd6d0e5 772{
17f3083a
SM
773 BT_ASSERT_PRE_NO_ERROR();
774
fe4df857
FD
775 return create_real_field_class(trace_class,
776 BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL);
5cd6d0e5
PP
777}
778
779static
780int init_named_field_classes_container(
781 struct bt_field_class_named_field_class_container *fc,
40f4ba76 782 enum bt_field_class_type type,
45c51519
PP
783 bt_object_release_func fc_release_func,
784 GDestroyNotify named_fc_destroy_func)
5cd6d0e5
PP
785{
786 int ret = 0;
787
c6962c96
PP
788 ret = init_field_class((void *) fc, type, fc_release_func);
789 if (ret) {
790 goto end;
791 }
792
45c51519 793 fc->named_fcs = g_ptr_array_new_with_free_func(named_fc_destroy_func);
5cd6d0e5 794 if (!fc->named_fcs) {
45c51519 795 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
5cd6d0e5
PP
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) {
870631a2 802 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
5cd6d0e5
PP
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);
e5be10ef 815 BT_LIB_LOGD("Finalizing named field class: "
5cd6d0e5
PP
816 "addr=%p, name=\"%s\", %![fc-]+F",
817 named_fc, named_fc->name ? named_fc->name->str : NULL,
818 named_fc->fc);
c6962c96 819 BT_OBJECT_PUT_REF_AND_RESET(named_fc->user_attributes);
5cd6d0e5
PP
820
821 if (named_fc->name) {
822 g_string_free(named_fc->name, TRUE);
45c51519 823 named_fc->name = NULL;
5cd6d0e5
PP
824 }
825
e5be10ef 826 BT_LOGD_STR("Putting named field class's field class.");
238b7404 827 BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc);
5cd6d0e5
PP
828}
829
45c51519
PP
830static
831void destroy_named_field_class(gpointer ptr)
832{
c6962c96
PP
833 struct bt_named_field_class *named_fc = ptr;
834
45c51519 835 if (ptr) {
c7d2f7b6 836 BT_OBJECT_PUT_REF_AND_RESET(named_fc->user_attributes);
45c51519
PP
837 finalize_named_field_class(ptr);
838 g_free(ptr);
839 }
840}
841
842static
de821fe5 843void destroy_variant_with_selector_field_option(gpointer ptr)
45c51519 844{
de821fe5 845 struct bt_field_class_variant_with_selector_field_option *opt = ptr;
45c51519
PP
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
5cd6d0e5
PP
854static
855void finalize_named_field_classes_container(
856 struct bt_field_class_named_field_class_container *fc)
857{
5cd6d0e5
PP
858 BT_ASSERT(fc);
859
860 if (fc->named_fcs) {
45c51519
PP
861 g_ptr_array_free(fc->named_fcs, TRUE);
862 fc->named_fcs = NULL;
5cd6d0e5 863
5cd6d0e5
PP
864 }
865
866 if (fc->name_to_index) {
867 g_hash_table_destroy(fc->name_to_index);
45c51519 868 fc->name_to_index = NULL;
5cd6d0e5
PP
869 }
870}
871
872static
873void destroy_structure_field_class(struct bt_object *obj)
874{
875 BT_ASSERT(obj);
1998d1ab 876 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj);
c6962c96 877 finalize_field_class((void *) obj);
5cd6d0e5
PP
878 finalize_named_field_classes_container((void *) obj);
879 g_free(obj);
880}
881
1353b066 882BT_EXPORT
1122a43a
PP
883struct bt_field_class *bt_field_class_structure_create(
884 bt_trace_class *trace_class)
5cd6d0e5
PP
885{
886 int ret;
887 struct bt_field_class_structure *struct_fc = NULL;
888
17f3083a 889 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 890 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
e5be10ef 891 BT_LOGD_STR("Creating default structure field class object.");
5cd6d0e5
PP
892 struct_fc = g_new0(struct bt_field_class_structure, 1);
893 if (!struct_fc) {
870631a2
PP
894 BT_LIB_LOGE_APPEND_CAUSE(
895 "Failed to allocate one structure field class.");
5cd6d0e5
PP
896 goto error;
897 }
898
899 ret = init_named_field_classes_container((void *) struct_fc,
45c51519
PP
900 BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class,
901 destroy_named_field_class);
5cd6d0e5 902 if (ret) {
45c51519 903 /* init_named_field_classes_container() logs errors */
5cd6d0e5
PP
904 goto error;
905 }
906
e5be10ef 907 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc);
5cd6d0e5
PP
908 goto end;
909
910error:
65300d60 911 BT_OBJECT_PUT_REF_AND_RESET(struct_fc);
5cd6d0e5
PP
912
913end:
914 return (void *) struct_fc;
915}
916
917static
45c51519 918int init_named_field_class(struct bt_named_field_class *named_fc,
5cd6d0e5
PP
919 const char *name, struct bt_field_class *fc)
920{
45c51519 921 int status = BT_FUNC_STATUS_OK;
5cd6d0e5 922
45c51519
PP
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) {
870631a2 928 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
45c51519 929 status = BT_FUNC_STATUS_MEMORY_ERROR;
5cd6d0e5
PP
930 goto end;
931 }
932
c6962c96
PP
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
398454ed 941 named_fc->fc = fc;
6871026b 942 bt_object_get_ref_no_null_check(named_fc->fc);
1e6fd1d7 943
45c51519
PP
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;
5cd6d0e5
PP
971
972end:
45c51519
PP
973 return named_fc;
974}
975
976static
de821fe5
PP
977struct bt_field_class_variant_with_selector_field_option *
978create_variant_with_selector_field_option(
45c51519
PP
979 const char *name, struct bt_field_class *fc,
980 const struct bt_integer_range_set *range_set)
981{
de821fe5
PP
982 struct bt_field_class_variant_with_selector_field_option *opt = g_new0(
983 struct bt_field_class_variant_with_selector_field_option, 1);
45c51519
PP
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;
6871026b 998 bt_object_get_ref_no_null_check(opt->range_set);
45c51519
PP
999 bt_integer_range_set_freeze(range_set);
1000 goto end;
1001
1002error:
de821fe5 1003 destroy_variant_with_selector_field_option(opt);
45c51519
PP
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,
1778c2a4
PP
1013 struct bt_named_field_class *named_fc, const char *api_func,
1014 const char *unique_entry_precond_id)
45c51519
PP
1015{
1016 BT_ASSERT(container_fc);
1017 BT_ASSERT(named_fc);
1778c2a4
PP
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),
45c51519
PP
1022 "Duplicate member/option name in structure/variant field class: "
1023 "%![container-fc-]+F, name=\"%s\"", container_fc,
1024 named_fc->name->str);
c6962c96
PP
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);
45c51519
PP
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;
5cd6d0e5
PP
1036}
1037
1353b066 1038BT_EXPORT
d24d5663
PP
1039enum bt_field_class_structure_append_member_status
1040bt_field_class_structure_append_member(
4295b9e0
PP
1041 struct bt_field_class *fc, const char *name,
1042 struct bt_field_class *member_fc)
5cd6d0e5 1043{
45c51519
PP
1044 enum bt_field_class_structure_append_member_status status;
1045 struct bt_named_field_class *named_fc = NULL;
e5be10ef 1046
17f3083a 1047 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 1048 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4 1049 BT_ASSERT_PRE_FC_IS_STRUCT("field-class", fc, "Field class");
45c51519
PP
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,
1778c2a4
PP
1058 named_fc, __func__,
1059 "structure-field-class-member-name-is-unique");
45c51519
PP
1060 if (status == BT_FUNC_STATUS_OK) {
1061 /* Moved to the container */
1062 named_fc = NULL;
1063 }
1064
1065end:
1066 return status;
5cd6d0e5
PP
1067}
1068
1353b066 1069BT_EXPORT
40f4ba76
PP
1070uint64_t bt_field_class_structure_get_member_count(
1071 const struct bt_field_class *fc)
5cd6d0e5
PP
1072{
1073 struct bt_field_class_structure *struct_fc = (void *) fc;
1074
d5b13b9b 1075 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1076 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
5cd6d0e5
PP
1077 return (uint64_t) struct_fc->common.named_fcs->len;
1078}
1079
1080static
1e6fd1d7
PP
1081struct bt_named_field_class *
1082borrow_named_field_class_from_container_field_class_at_index(
740faaf4 1083 struct bt_field_class_named_field_class_container *fc,
1778c2a4 1084 uint64_t index, const char *api_func)
5cd6d0e5 1085{
98b15851 1086 BT_ASSERT_DBG(fc);
1778c2a4
PP
1087 BT_ASSERT_PRE_DEV_VALID_INDEX_FROM_FUNC(api_func, index,
1088 fc->named_fcs->len);
45c51519 1089 return fc->named_fcs->pdata[index];
5cd6d0e5
PP
1090}
1091
1353b066 1092BT_EXPORT
1e6fd1d7
PP
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)
5cd6d0e5 1096{
d5b13b9b 1097 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1098 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1e6fd1d7
PP
1099 return (const void *)
1100 borrow_named_field_class_from_container_field_class_at_index(
1778c2a4 1101 (void *) fc, index, __func__);
740faaf4
PP
1102}
1103
1353b066 1104BT_EXPORT
1e6fd1d7
PP
1105struct bt_field_class_structure_member *
1106bt_field_class_structure_borrow_member_by_index(
1107 struct bt_field_class *fc, uint64_t index)
740faaf4 1108{
d5b13b9b 1109 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1110 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1e6fd1d7
PP
1111 return (void *)
1112 borrow_named_field_class_from_container_field_class_at_index(
1778c2a4 1113 (void *) fc, index, __func__);
e5be10ef
PP
1114}
1115
5cd6d0e5 1116static
1e6fd1d7
PP
1117struct bt_named_field_class *
1118borrow_named_field_class_from_container_field_class_by_name(
740faaf4 1119 struct bt_field_class_named_field_class_container *fc,
1778c2a4 1120 const char *name, const char *api_func)
5cd6d0e5 1121{
1e6fd1d7 1122 struct bt_named_field_class *named_fc = NULL;
5cd6d0e5
PP
1123 gpointer orig_key;
1124 gpointer value;
1125
98b15851 1126 BT_ASSERT_DBG(fc);
1778c2a4 1127 BT_ASSERT_PRE_DEV_NAME_NON_NULL_FROM_FUNC(api_func, name);
5cd6d0e5
PP
1128 if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key,
1129 &value)) {
1130 goto end;
1131 }
1132
45c51519 1133 named_fc = fc->named_fcs->pdata[GPOINTER_TO_UINT(value)];
5cd6d0e5
PP
1134
1135end:
1e6fd1d7 1136 return named_fc;
5cd6d0e5
PP
1137}
1138
1353b066 1139BT_EXPORT
1e6fd1d7 1140const struct bt_field_class_structure_member *
7c06e353 1141bt_field_class_structure_borrow_member_by_name_const(
40f4ba76 1142 const struct bt_field_class *fc, const char *name)
5cd6d0e5 1143{
d5b13b9b 1144 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1145 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1e6fd1d7
PP
1146 return (const void *)
1147 borrow_named_field_class_from_container_field_class_by_name(
1778c2a4 1148 (void *) fc, name, __func__);
740faaf4
PP
1149}
1150
1353b066 1151BT_EXPORT
1e6fd1d7 1152struct bt_field_class_structure_member *
fffedc87 1153bt_field_class_structure_borrow_member_by_name(
740faaf4
PP
1154 struct bt_field_class *fc, const char *name)
1155{
d5b13b9b 1156 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1157 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1e6fd1d7
PP
1158 return (void *)
1159 borrow_named_field_class_from_container_field_class_by_name(
1778c2a4 1160 (void *) fc, name, __func__);
e5be10ef
PP
1161}
1162
1353b066 1163BT_EXPORT
1e6fd1d7
PP
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
d5b13b9b 1169 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1e6fd1d7
PP
1170 return named_fc->name->str;
1171}
1172
1353b066 1173BT_EXPORT
1e6fd1d7
PP
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
d5b13b9b 1180 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1e6fd1d7
PP
1181 return named_fc->fc;
1182}
1183
1353b066 1184BT_EXPORT
bcd7ef6f
FD
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
d5b13b9b 1191 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
bcd7ef6f
FD
1192 return named_fc->fc;
1193}
1194
b38aea74
PP
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);
c6962c96 1202 finalize_field_class((void *) obj);
b38aea74
PP
1203 BT_LOGD_STR("Putting content field class.");
1204 BT_OBJECT_PUT_REF_AND_RESET(fc->content_fc);
0aa006b7 1205
de821fe5
PP
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 =
0aa006b7
PP
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
de821fe5
PP
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 =
0aa006b7
PP
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
b38aea74
PP
1224 g_free(fc);
1225}
1226
0aa006b7
PP
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,
1778c2a4
PP
1232 struct bt_field_class *selector_fc,
1233 const char *api_func)
b38aea74
PP
1234{
1235 struct bt_field_class_option *opt_fc = NULL;
1236
1778c2a4
PP
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");
b38aea74 1241 BT_LIB_LOGD("Creating option field class: "
0aa006b7
PP
1242 "type=%s, %![content-fc-]+F, %![sel-fc-]+F",
1243 bt_common_field_class_type_string(fc_type),
1244 content_fc, selector_fc);
1245
de821fe5
PP
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;
0aa006b7 1248
1778c2a4
PP
1249 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func,
1250 "selector-field-class", selector_fc,
1251 "Selector field class");
0aa006b7 1252
de821fe5 1253 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
1778c2a4
PP
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,
0aa006b7
PP
1257 "Selector field class");
1258 opt_with_sel_fc = (void *) g_new0(
de821fe5 1259 struct bt_field_class_option_with_selector_field_bool, 1);
0aa006b7 1260 } else {
1778c2a4
PP
1261 BT_ASSERT_PRE_FC_IS_INT_FROM_FUNC(api_func,
1262 "selector-field-class",
1263 selector_fc, "Selector field class");
0aa006b7 1264 opt_with_sel_fc = (void *) g_new0(
de821fe5 1265 struct bt_field_class_option_with_selector_field_integer, 1);
0aa006b7
PP
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;
6871026b 1275 bt_object_get_ref_no_null_check(opt_with_sel_fc->selector_fc);
0aa006b7
PP
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 }
b38aea74
PP
1284 }
1285
0aa006b7
PP
1286 BT_ASSERT(opt_fc);
1287
1288 if (init_field_class((void *) opt_fc, fc_type,
c6962c96
PP
1289 destroy_option_field_class)) {
1290 goto error;
1291 }
1292
b38aea74 1293 opt_fc->content_fc = content_fc;
6871026b 1294 bt_object_get_ref_no_null_check(opt_fc->content_fc);
b38aea74
PP
1295 bt_field_class_freeze(opt_fc->content_fc);
1296
1297 if (selector_fc) {
b38aea74
PP
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
1353b066 1312BT_EXPORT
0aa006b7
PP
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,
de821fe5 1318 BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD,
1778c2a4 1319 content_fc, NULL, __func__);
0aa006b7
PP
1320}
1321
1353b066 1322BT_EXPORT
de821fe5 1323struct bt_field_class *bt_field_class_option_with_selector_field_bool_create(
0aa006b7
PP
1324 struct bt_trace_class *trace_class,
1325 struct bt_field_class *content_fc,
1326 struct bt_field_class *selector_fc)
1327{
17f3083a 1328 BT_ASSERT_PRE_NO_ERROR();
0aa006b7 1329
17f3083a
SM
1330 return create_option_field_class(trace_class,
1331 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1778c2a4 1332 content_fc, selector_fc, __func__);
0aa006b7
PP
1333}
1334
1353b066 1335BT_EXPORT
0aa006b7 1336struct bt_field_class *
de821fe5 1337bt_field_class_option_with_selector_field_integer_unsigned_create(
0aa006b7
PP
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{
de821fe5 1343 struct bt_field_class_option_with_selector_field_integer *fc;
0aa006b7
PP
1344 const struct bt_integer_range_set *range_set =
1345 (const void *) u_range_set;
1346
17f3083a 1347 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 1348 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1778c2a4 1349 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
0aa006b7 1350 fc = (void *) create_option_field_class(trace_class,
de821fe5 1351 BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1778c2a4 1352 content_fc, selector_fc, __func__);
0aa006b7
PP
1353
1354 if (!fc) {
1355 goto end;
1356 }
1357
1358 fc->range_set = range_set;
6871026b 1359 bt_object_get_ref_no_null_check(fc->range_set);
0aa006b7
PP
1360 bt_integer_range_set_freeze(range_set);
1361
1362end:
1363 return (void *) fc;
1364}
1365
1353b066 1366BT_EXPORT
0aa006b7 1367struct bt_field_class *
de821fe5 1368bt_field_class_option_with_selector_field_integer_signed_create(
0aa006b7
PP
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{
de821fe5 1374 struct bt_field_class_option_with_selector_field_integer *fc;
0aa006b7
PP
1375 const struct bt_integer_range_set *range_set =
1376 (const void *) i_range_set;
1377
17f3083a 1378 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 1379 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1778c2a4 1380 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
0aa006b7 1381 fc = (void *) create_option_field_class(trace_class,
de821fe5 1382 BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1778c2a4 1383 content_fc, selector_fc, __func__);
0aa006b7
PP
1384
1385 if (!fc) {
1386 goto end;
1387 }
1388
1389 fc->range_set = range_set;
6871026b 1390 bt_object_get_ref_no_null_check(fc->range_set);
0aa006b7
PP
1391 bt_integer_range_set_freeze(range_set);
1392
1393end:
1394 return (void *) fc;
1395}
1396
1353b066 1397BT_EXPORT
b38aea74
PP
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
d5b13b9b 1403 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4 1404 BT_ASSERT_PRE_FC_IS_OPTION("field-class", fc, "Field class");
b38aea74
PP
1405 return opt_fc->content_fc;
1406}
1407
1353b066 1408BT_EXPORT
bcd7ef6f
FD
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
d5b13b9b 1414 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4 1415 BT_ASSERT_PRE_FC_IS_OPTION("field-class", fc, "Field class");
bcd7ef6f
FD
1416 return opt_fc->content_fc;
1417}
1418
1353b066 1419BT_EXPORT
b38aea74 1420const struct bt_field_path *
de821fe5 1421bt_field_class_option_with_selector_field_borrow_selector_field_path_const(
b38aea74
PP
1422 const struct bt_field_class *fc)
1423{
de821fe5 1424 const struct bt_field_class_option_with_selector_field *opt_fc =
0aa006b7 1425 (const void *) fc;
b38aea74 1426
d5b13b9b 1427 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4 1428 BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL("field-class", fc, "Field class");
b38aea74
PP
1429 return opt_fc->selector_field_path;
1430}
1431
1353b066 1432BT_EXPORT
de821fe5 1433void bt_field_class_option_with_selector_field_bool_set_selector_is_reversed(
0aa006b7
PP
1434 struct bt_field_class *fc, bt_bool sel_is_reversed)
1435{
de821fe5 1436 struct bt_field_class_option_with_selector_field_bool *opt_fc = (void *) fc;
0aa006b7 1437
d5b13b9b 1438 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
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);
0aa006b7
PP
1444 opt_fc->sel_is_reversed = sel_is_reversed;
1445}
1446
1353b066 1447BT_EXPORT
de821fe5 1448bt_bool bt_field_class_option_with_selector_field_bool_selector_is_reversed(
0aa006b7
PP
1449 const struct bt_field_class *fc)
1450{
de821fe5 1451 struct bt_field_class_option_with_selector_field_bool *opt_fc = (void *) fc;
0aa006b7 1452
d5b13b9b 1453 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
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");
0aa006b7
PP
1458 return opt_fc->sel_is_reversed;
1459}
1460
1353b066 1461BT_EXPORT
0aa006b7 1462const struct bt_integer_range_set_unsigned *
de821fe5 1463bt_field_class_option_with_selector_field_integer_unsigned_borrow_selector_ranges_const(
0aa006b7
PP
1464 const struct bt_field_class *fc)
1465{
de821fe5 1466 struct bt_field_class_option_with_selector_field_integer *opt_fc =
0aa006b7
PP
1467 (void *) fc;
1468
d5b13b9b 1469 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
1470 BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL("field-class", fc,
1471 "Field class");
0aa006b7
PP
1472 return (const void *) opt_fc->range_set;
1473}
1474
1353b066 1475BT_EXPORT
0aa006b7 1476const struct bt_integer_range_set_signed *
de821fe5 1477bt_field_class_option_with_selector_field_integer_signed_borrow_selector_ranges_const(
0aa006b7
PP
1478 const struct bt_field_class *fc)
1479{
de821fe5 1480 struct bt_field_class_option_with_selector_field_integer *opt_fc =
0aa006b7
PP
1481 (void *) fc;
1482
d5b13b9b 1483 BT_ASSERT_PRE_FC_NON_NULL(fc);
1778c2a4
PP
1484 BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL("field-class", fc,
1485 "Field class");
0aa006b7
PP
1486 return (const void *) opt_fc->range_set;
1487}
1488
45c51519
PP
1489static
1490void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
1e6fd1d7 1491{
45c51519
PP
1492 BT_ASSERT(var_fc);
1493 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc);
c6962c96 1494 finalize_field_class((void *) var_fc);
45c51519 1495 finalize_named_field_classes_container((void *) var_fc);
1e6fd1d7
PP
1496}
1497
5cd6d0e5
PP
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);
45c51519
PP
1504 finalize_variant_field_class(fc);
1505 g_free(fc);
1506}
1507
1508static
de821fe5 1509void destroy_variant_with_selector_field_field_class(struct bt_object *obj)
45c51519 1510{
de821fe5 1511 struct bt_field_class_variant_with_selector_field *fc = (void *) obj;
45c51519
PP
1512
1513 BT_ASSERT(fc);
1514 finalize_variant_field_class(&fc->common);
5cd6d0e5 1515 BT_LOGD_STR("Putting selector field path.");
238b7404
PP
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);
5cd6d0e5
PP
1519 g_free(fc);
1520}
1521
1353b066 1522BT_EXPORT
1122a43a 1523struct bt_field_class *bt_field_class_variant_create(
45c51519 1524 bt_trace_class *trace_class, bt_field_class *selector_fc)
5cd6d0e5
PP
1525{
1526 int ret;
1527 struct bt_field_class_variant *var_fc = NULL;
de821fe5 1528 struct bt_field_class_variant_with_selector_field *var_with_sel_fc = NULL;
45c51519 1529 enum bt_field_class_type fc_type;
5cd6d0e5 1530
17f3083a 1531 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 1532 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
45c51519
PP
1533
1534 if (selector_fc) {
1778c2a4
PP
1535 BT_ASSERT_PRE_FC_IS_INT("selector-field-class", selector_fc,
1536 "Selector field class");
5cd6d0e5
PP
1537 }
1538
45c51519
PP
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(
de821fe5 1544 struct bt_field_class_variant_with_selector_field, 1);
45c51519
PP
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
ebdb6693
PP
1551 if (bt_field_class_type_is(selector_fc->type,
1552 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)) {
de821fe5 1553 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD;
45c51519 1554 } else {
de821fe5 1555 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD;
45c51519
PP
1556 }
1557
1558 ret = init_named_field_classes_container(
1559 (void *) var_with_sel_fc, fc_type,
de821fe5
PP
1560 destroy_variant_with_selector_field_field_class,
1561 destroy_variant_with_selector_field_option);
45c51519
PP
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;
6871026b 1568 bt_object_get_ref_no_null_check(var_with_sel_fc->selector_fc);
45c51519
PP
1569 bt_field_class_freeze(selector_fc);
1570 var_fc = (void *) var_with_sel_fc;
d166032f
FD
1571 BT_LIB_LOGD("Created default variant field class with selector object: "
1572 "%![var-fc-]+F, %![sel-fc-]+F", var_fc, selector_fc);
45c51519
PP
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,
de821fe5 1582 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD,
45c51519
PP
1583 destroy_variant_field_class, destroy_named_field_class);
1584 if (ret) {
1585 /* init_named_field_classes_container() logs errors */
1586 goto error;
1587 }
d166032f
FD
1588 BT_LIB_LOGD("Created default variant field class without selector object: "
1589 "%![var-fc-]+F", var_fc);
5cd6d0e5
PP
1590 }
1591
45c51519 1592 BT_ASSERT(var_fc);
5cd6d0e5
PP
1593 goto end;
1594
1595error:
65300d60 1596 BT_OBJECT_PUT_REF_AND_RESET(var_fc);
9fdff45c 1597 BT_OBJECT_PUT_REF_AND_RESET(var_with_sel_fc);
5cd6d0e5
PP
1598
1599end:
1600 return (void *) var_fc;
1601}
1602
1778c2a4
PP
1603#define VAR_FC_OPT_NAME_IS_UNIQUE_ID \
1604 "variant-field-class-option-name-is-unique"
1605
1353b066 1606BT_EXPORT
45c51519
PP
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
17f3083a 1614 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b
PP
1615 BT_ASSERT_PRE_FC_NON_NULL(fc);
1616 BT_ASSERT_PRE_NAME_NON_NULL(name);
1778c2a4
PP
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");
45c51519
PP
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,
1778c2a4 1631 named_fc, __func__, VAR_FC_OPT_NAME_IS_UNIQUE_ID);
45c51519
PP
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;
5cd6d0e5
PP
1643}
1644
45c51519
PP
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++) {
de821fe5 1673 struct bt_field_class_variant_with_selector_field_option *opt =
45c51519
PP
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
de821fe5 1731int append_option_to_variant_with_selector_field_field_class(
45c51519
PP
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,
1778c2a4
PP
1735 enum bt_field_class_type expected_type,
1736 const char *api_func)
5cd6d0e5 1737{
45c51519 1738 int status;
de821fe5
PP
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;
45c51519 1741 bool has_overlap;
e5be10ef 1742
1778c2a4
PP
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);
45c51519 1749 status = ranges_overlap(var_fc->common.common.named_fcs, range_set,
de821fe5 1750 expected_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
45c51519
PP
1751 &has_overlap);
1752 if (status) {
1753 /* ranges_overlap() logs errors */
1754 goto end;
1755 }
1756
1778c2a4
PP
1757 BT_ASSERT_PRE_FROM_FUNC(api_func, "ranges-do-not-overlap",
1758 !has_overlap,
6769570a
PP
1759 "Integer range set's ranges and existing ranges have an overlap: "
1760 "%!+R", range_set);
de821fe5 1761 opt = create_variant_with_selector_field_option(name, option_fc, range_set);
45c51519 1762 if (!opt) {
de821fe5 1763 /* create_variant_with_selector_field_option() logs errors */
45c51519
PP
1764 status = BT_FUNC_STATUS_MEMORY_ERROR;
1765 goto end;
1766 }
1767
1768 status = append_named_field_class_to_container_field_class((void *) fc,
1778c2a4 1769 &opt->common, __func__, VAR_FC_OPT_NAME_IS_UNIQUE_ID);
45c51519
PP
1770 if (status == BT_FUNC_STATUS_OK) {
1771 /* Moved to the container */
1772 opt = NULL;
1773 }
1774
1775end:
1776 if (opt) {
de821fe5 1777 destroy_variant_with_selector_field_option(opt);
45c51519
PP
1778 }
1779
1780 return status;
1781}
1782
1353b066 1783BT_EXPORT
de821fe5
PP
1784enum bt_field_class_variant_with_selector_field_integer_append_option_status
1785bt_field_class_variant_with_selector_field_integer_unsigned_append_option(
45c51519
PP
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{
17f3083a 1790 BT_ASSERT_PRE_NO_ERROR();
1778c2a4
PP
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");
de821fe5 1796 return append_option_to_variant_with_selector_field_field_class(fc,
45c51519 1797 name, option_fc, (const void *) range_set,
1778c2a4
PP
1798 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1799 __func__);
45c51519
PP
1800}
1801
1353b066 1802BT_EXPORT
de821fe5
PP
1803enum bt_field_class_variant_with_selector_field_integer_append_option_status
1804bt_field_class_variant_with_selector_field_integer_signed_append_option(
45c51519
PP
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{
17f3083a 1809 BT_ASSERT_PRE_NO_ERROR();
1778c2a4
PP
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");
de821fe5 1815 return append_option_to_variant_with_selector_field_field_class(fc,
45c51519 1816 name, option_fc, (const void *) range_set,
1778c2a4
PP
1817 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1818 __func__);
45c51519
PP
1819}
1820
1353b066 1821BT_EXPORT
45c51519
PP
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
d5b13b9b 1826 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 1827 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
45c51519 1828 return (uint64_t) var_fc->common.named_fcs->len;
5cd6d0e5
PP
1829}
1830
1353b066 1831BT_EXPORT
1e6fd1d7 1832const struct bt_field_class_variant_option *
7c06e353 1833bt_field_class_variant_borrow_option_by_name_const(
40f4ba76 1834 const struct bt_field_class *fc, const char *name)
5cd6d0e5 1835{
d5b13b9b 1836 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 1837 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
1e6fd1d7
PP
1838 return (const void *)
1839 borrow_named_field_class_from_container_field_class_by_name(
1778c2a4 1840 (void *) fc, name, __func__);
740faaf4
PP
1841}
1842
1353b066 1843BT_EXPORT
45c51519
PP
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)
740faaf4 1847{
d5b13b9b 1848 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 1849 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
45c51519
PP
1850 return (const void *)
1851 borrow_named_field_class_from_container_field_class_at_index(
1778c2a4 1852 (void *) fc, index, __func__);
c6fe8c40
PP
1853}
1854
1353b066 1855BT_EXPORT
c6fe8c40
PP
1856struct bt_field_class_variant_option *
1857bt_field_class_variant_borrow_option_by_name(
1858 struct bt_field_class *fc, const char *name)
1859{
d5b13b9b 1860 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 1861 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
c6fe8c40
PP
1862 return (void *)
1863 borrow_named_field_class_from_container_field_class_by_name(
1778c2a4 1864 (void *) fc, name, __func__);
c6fe8c40
PP
1865}
1866
1353b066 1867BT_EXPORT
c6fe8c40
PP
1868struct bt_field_class_variant_option *
1869bt_field_class_variant_borrow_option_by_index(
1870 struct bt_field_class *fc, uint64_t index)
1871{
d5b13b9b 1872 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 1873 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
c6fe8c40
PP
1874 return (void *)
1875 borrow_named_field_class_from_container_field_class_at_index(
1778c2a4 1876 (void *) fc, index, __func__);
e5be10ef
PP
1877}
1878
1353b066 1879BT_EXPORT
de821fe5
PP
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(
45c51519 1882 const struct bt_field_class *fc, const char *name)
5cd6d0e5 1883{
d5b13b9b 1884 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1885 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1778c2a4 1886 "variant-field-class-with-unsigned-integer-selector-field",
de821fe5 1887 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
45c51519
PP
1888 "Field class");
1889 return (const void *)
1890 borrow_named_field_class_from_container_field_class_by_name(
1778c2a4 1891 (void *) fc, name, __func__);
5cd6d0e5
PP
1892}
1893
1353b066 1894BT_EXPORT
de821fe5
PP
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(
1e6fd1d7 1897 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 1898{
d5b13b9b 1899 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1900 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1778c2a4 1901 "variant-field-class-with-unsigned-integer-selector-field",
de821fe5 1902 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
45c51519 1903 "Field class");
1e6fd1d7
PP
1904 return (const void *)
1905 borrow_named_field_class_from_container_field_class_at_index(
1778c2a4 1906 (void *) fc, index, __func__);
740faaf4
PP
1907}
1908
1353b066 1909BT_EXPORT
de821fe5
PP
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(
45c51519 1912 const struct bt_field_class *fc, const char *name)
740faaf4 1913{
d5b13b9b 1914 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1915 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1778c2a4 1916 "variant-field-class-with-signed-integer-selector-field",
de821fe5 1917 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
45c51519
PP
1918 "Field class");
1919 return (const void *)
1920 borrow_named_field_class_from_container_field_class_by_name(
1778c2a4 1921 (void *) fc, name, __func__);
45c51519
PP
1922}
1923
1353b066 1924BT_EXPORT
de821fe5
PP
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(
45c51519
PP
1927 const struct bt_field_class *fc, uint64_t index)
1928{
d5b13b9b 1929 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 1930 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1778c2a4 1931 "variant-field-class-with-signed-integer-selector-field",
de821fe5 1932 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
45c51519
PP
1933 "Field class");
1934 return (const void *)
1e6fd1d7 1935 borrow_named_field_class_from_container_field_class_at_index(
1778c2a4 1936 (void *) fc, index, __func__);
1e6fd1d7
PP
1937}
1938
1353b066 1939BT_EXPORT
1e6fd1d7
PP
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
d5b13b9b 1945 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1e6fd1d7
PP
1946 return named_fc->name->str;
1947}
1948
1353b066 1949BT_EXPORT
1e6fd1d7
PP
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
d5b13b9b 1956 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
1e6fd1d7
PP
1957 return named_fc->fc;
1958}
1959
1353b066 1960BT_EXPORT
bcd7ef6f
FD
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
d5b13b9b 1967 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
bcd7ef6f
FD
1968 return named_fc->fc;
1969}
1970
1353b066 1971BT_EXPORT
45c51519 1972const struct bt_integer_range_set_unsigned *
de821fe5
PP
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)
1e6fd1d7 1975{
de821fe5 1976 const struct bt_field_class_variant_with_selector_field_option *opt =
45c51519 1977 (const void *) option;
1e6fd1d7 1978
d5b13b9b 1979 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
45c51519
PP
1980 return (const void *) opt->range_set;
1981}
1982
1353b066 1983BT_EXPORT
45c51519 1984const struct bt_integer_range_set_signed *
de821fe5
PP
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)
45c51519 1987{
de821fe5 1988 const struct bt_field_class_variant_with_selector_field_option *opt =
45c51519
PP
1989 (const void *) option;
1990
d5b13b9b 1991 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
45c51519 1992 return (const void *) opt->range_set;
5cd6d0e5
PP
1993}
1994
1353b066 1995BT_EXPORT
40f4ba76 1996const struct bt_field_path *
de821fe5 1997bt_field_class_variant_with_selector_field_borrow_selector_field_path_const(
40f4ba76 1998 const struct bt_field_class *fc)
e5be10ef 1999{
de821fe5 2000 const struct bt_field_class_variant_with_selector_field *var_fc =
45c51519 2001 (const void *) fc;
5cd6d0e5 2002
d5b13b9b 2003 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4
PP
2004 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL("field-class", fc,
2005 "Field class");
5cd6d0e5
PP
2006 return var_fc->selector_field_path;
2007}
2008
2009static
c6962c96 2010int init_array_field_class(struct bt_field_class_array *fc,
864cad70 2011 enum bt_field_class_type type, bt_object_release_func release_func,
5cd6d0e5
PP
2012 struct bt_field_class *element_fc)
2013{
c6962c96
PP
2014 int ret;
2015
5cd6d0e5 2016 BT_ASSERT(element_fc);
c6962c96
PP
2017 ret = init_field_class((void *) fc, type, release_func);
2018 if (ret) {
2019 goto end;
2020 }
2021
398454ed 2022 fc->element_fc = element_fc;
6871026b 2023 bt_object_get_ref_no_null_check(fc->element_fc);
5cd6d0e5 2024 bt_field_class_freeze(element_fc);
c6962c96
PP
2025
2026end:
2027 return ret;
5cd6d0e5
PP
2028}
2029
2030static
2031void finalize_array_field_class(struct bt_field_class_array *array_fc)
2032{
2033 BT_ASSERT(array_fc);
e5be10ef 2034 BT_LOGD_STR("Putting element field class.");
c6962c96 2035 finalize_field_class((void *) array_fc);
238b7404 2036 BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc);
5cd6d0e5
PP
2037}
2038
2039static
2040void destroy_static_array_field_class(struct bt_object *obj)
2041{
2042 BT_ASSERT(obj);
e5be10ef 2043 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj);
5cd6d0e5
PP
2044 finalize_array_field_class((void *) obj);
2045 g_free(obj);
2046}
2047
1353b066 2048BT_EXPORT
40f4ba76 2049struct bt_field_class *
9c08c816 2050bt_field_class_array_static_create(bt_trace_class *trace_class,
1122a43a 2051 struct bt_field_class *element_fc, uint64_t length)
5cd6d0e5 2052{
9c08c816 2053 struct bt_field_class_array_static *array_fc = NULL;
5cd6d0e5 2054
17f3083a 2055 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 2056 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1778c2a4
PP
2057 BT_ASSERT_PRE_NON_NULL("element-field-class", element_fc,
2058 "Element field class");
e5be10ef 2059 BT_LOGD_STR("Creating default static array field class object.");
9c08c816 2060 array_fc = g_new0(struct bt_field_class_array_static, 1);
5cd6d0e5 2061 if (!array_fc) {
870631a2
PP
2062 BT_LIB_LOGE_APPEND_CAUSE(
2063 "Failed to allocate one static array field class.");
5cd6d0e5
PP
2064 goto error;
2065 }
2066
c6962c96
PP
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
5cd6d0e5 2073 array_fc->length = length;
e5be10ef 2074 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc);
5cd6d0e5
PP
2075 goto end;
2076
2077error:
65300d60 2078 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
5cd6d0e5
PP
2079
2080end:
2081 return (void *) array_fc;
2082}
2083
1353b066 2084BT_EXPORT
40f4ba76
PP
2085const struct bt_field_class *
2086bt_field_class_array_borrow_element_field_class_const(
2087 const struct bt_field_class *fc)
5cd6d0e5 2088{
40f4ba76 2089 const struct bt_field_class_array *array_fc = (const void *) fc;
5cd6d0e5 2090
d5b13b9b 2091 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 2092 BT_ASSERT_PRE_DEV_FC_IS_ARRAY("field-class", fc, "Field class");
5cd6d0e5
PP
2093 return array_fc->element_fc;
2094}
2095
1353b066 2096BT_EXPORT
740faaf4
PP
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
d5b13b9b 2102 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4 2103 BT_ASSERT_PRE_DEV_FC_IS_ARRAY("field-class", fc, "Field class");
740faaf4
PP
2104 return array_fc->element_fc;
2105}
2106
1353b066 2107BT_EXPORT
9c08c816 2108uint64_t bt_field_class_array_static_get_length(const struct bt_field_class *fc)
e5be10ef 2109{
9c08c816 2110 const struct bt_field_class_array_static *array_fc = (const void *) fc;
5cd6d0e5 2111
d5b13b9b 2112 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
b9ebcd13 2113 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
1778c2a4 2114 "static-array-field-class", BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
5cd6d0e5
PP
2115 "Field class");
2116 return (uint64_t) array_fc->length;
2117}
2118
2119static
2120void destroy_dynamic_array_field_class(struct bt_object *obj)
2121{
9c08c816 2122 struct bt_field_class_array_dynamic *fc = (void *) obj;
5cd6d0e5
PP
2123
2124 BT_ASSERT(fc);
e5be10ef 2125 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc);
5cd6d0e5
PP
2126 finalize_array_field_class((void *) fc);
2127 BT_LOGD_STR("Putting length field path.");
238b7404
PP
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);
5cd6d0e5
PP
2131 g_free(fc);
2132}
2133
1353b066 2134BT_EXPORT
9c08c816 2135struct bt_field_class *bt_field_class_array_dynamic_create(
1367bc7c
PP
2136 struct bt_trace_class *trace_class,
2137 struct bt_field_class *element_fc,
2138 struct bt_field_class *length_fc)
5cd6d0e5 2139{
9c08c816 2140 struct bt_field_class_array_dynamic *array_fc = NULL;
5cd6d0e5 2141
17f3083a 2142 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 2143 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1778c2a4
PP
2144 BT_ASSERT_PRE_NON_NULL("element-field-class", element_fc,
2145 "Element field class");
e5be10ef 2146 BT_LOGD_STR("Creating default dynamic array field class object.");
9c08c816 2147 array_fc = g_new0(struct bt_field_class_array_dynamic, 1);
5cd6d0e5 2148 if (!array_fc) {
870631a2
PP
2149 BT_LIB_LOGE_APPEND_CAUSE(
2150 "Failed to allocate one dynamic array field class.");
5cd6d0e5
PP
2151 goto error;
2152 }
2153
c6962c96 2154 if (init_array_field_class((void *) array_fc,
81b8fa44
PP
2155 length_fc ?
2156 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD :
2157 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD,
c6962c96
PP
2158 destroy_dynamic_array_field_class, element_fc)) {
2159 goto error;
2160 }
1367bc7c
PP
2161
2162 if (length_fc) {
1778c2a4
PP
2163 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT("length-field-class",
2164 length_fc, "Length field class");
1367bc7c 2165 array_fc->length_fc = length_fc;
6871026b 2166 bt_object_get_ref_no_null_check(array_fc->length_fc);
1367bc7c
PP
2167 bt_field_class_freeze(length_fc);
2168 }
2169
e5be10ef 2170 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc);
5cd6d0e5
PP
2171 goto end;
2172
2173error:
65300d60 2174 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
5cd6d0e5
PP
2175
2176end:
2177 return (void *) array_fc;
2178}
2179
1353b066 2180BT_EXPORT
40f4ba76 2181const struct bt_field_path *
81b8fa44 2182bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const(
40f4ba76 2183 const struct bt_field_class *fc)
5cd6d0e5 2184{
9c08c816 2185 const struct bt_field_class_array_dynamic *seq_fc = (const void *) fc;
5cd6d0e5 2186
17f3083a 2187 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 2188 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1778c2a4
PP
2189 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2190 "dynamic-array-field-class-with-length-field",
81b8fa44 2191 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD,
5cd6d0e5
PP
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);
e5be10ef 2200 BT_LIB_LOGD("Destroying string field class object: %!+F", obj);
c6962c96 2201 finalize_field_class((void *) obj);
5cd6d0e5
PP
2202 g_free(obj);
2203}
2204
1353b066 2205BT_EXPORT
1122a43a 2206struct bt_field_class *bt_field_class_string_create(bt_trace_class *trace_class)
5cd6d0e5
PP
2207{
2208 struct bt_field_class_string *string_fc = NULL;
2209
17f3083a 2210 BT_ASSERT_PRE_NO_ERROR();
d5b13b9b 2211 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
e5be10ef 2212 BT_LOGD_STR("Creating default string field class object.");
5cd6d0e5
PP
2213 string_fc = g_new0(struct bt_field_class_string, 1);
2214 if (!string_fc) {
870631a2
PP
2215 BT_LIB_LOGE_APPEND_CAUSE(
2216 "Failed to allocate one string field class.");
5cd6d0e5
PP
2217 goto error;
2218 }
2219
c6962c96
PP
2220 if (init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING,
2221 destroy_string_field_class)) {
2222 goto error;
2223 }
2224
e5be10ef 2225 BT_LIB_LOGD("Created string field class object: %!+F", string_fc);
5cd6d0e5
PP
2226 goto end;
2227
2228error:
65300d60 2229 BT_OBJECT_PUT_REF_AND_RESET(string_fc);
5cd6d0e5
PP
2230
2231end:
2232 return (void *) string_fc;
2233}
2234
1e6fd1d7 2235void _bt_field_class_freeze(const struct bt_field_class *c_fc)
5cd6d0e5 2236{
1e6fd1d7
PP
2237 struct bt_field_class *fc = (void *) c_fc;
2238
5cd6d0e5
PP
2239 /*
2240 * Element/member/option field classes are frozen when added to
2241 * their owner.
2242 */
2243 BT_ASSERT(fc);
c6962c96 2244 bt_value_freeze(fc->user_attributes);
1e6fd1d7
PP
2245 fc->frozen = true;
2246
ebdb6693
PP
2247 if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
2248 bt_field_class_type_is(fc->type,
2249 BT_FIELD_CLASS_TYPE_VARIANT)) {
1e6fd1d7
PP
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++) {
45c51519
PP
2255 bt_named_field_class_freeze(
2256 container_fc->named_fcs->pdata[i]);
1e6fd1d7 2257 }
1e6fd1d7
PP
2258 }
2259}
2260
1e6fd1d7
PP
2261void _bt_named_field_class_freeze(const struct bt_named_field_class *named_fc)
2262{
2263 BT_ASSERT(named_fc);
c6962c96
PP
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);
1e6fd1d7 2268 ((struct bt_named_field_class *) named_fc)->frozen = true;
5cd6d0e5
PP
2269}
2270
bdb288b3 2271void bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc)
5cd6d0e5 2272{
40f4ba76
PP
2273 struct bt_field_class *fc = (void *) c_fc;
2274
5cd6d0e5 2275 BT_ASSERT(fc);
1778c2a4
PP
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);
862ca4ed 2279 fc->part_of_trace_class = true;
5cd6d0e5 2280
ebdb6693
PP
2281 if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
2282 bt_field_class_type_is(fc->type,
2283 BT_FIELD_CLASS_TYPE_VARIANT)) {
5cd6d0e5
PP
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 =
45c51519 2290 container_fc->named_fcs->pdata[i];
5cd6d0e5 2291
862ca4ed 2292 bt_field_class_make_part_of_trace_class(named_fc->fc);
5cd6d0e5 2293 }
ebdb6693
PP
2294 } else if (bt_field_class_type_is(fc->type,
2295 BT_FIELD_CLASS_TYPE_ARRAY)) {
5cd6d0e5
PP
2296 struct bt_field_class_array *array_fc = (void *) fc;
2297
862ca4ed 2298 bt_field_class_make_part_of_trace_class(array_fc->element_fc);
5cd6d0e5
PP
2299 }
2300}
c5b9b441 2301
1353b066 2302BT_EXPORT
c6962c96
PP
2303const struct bt_value *bt_field_class_borrow_user_attributes_const(
2304 const struct bt_field_class *fc)
2305{
d5b13b9b 2306 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
c6962c96
PP
2307 return fc->user_attributes;
2308}
2309
1353b066 2310BT_EXPORT
c6962c96
PP
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
1353b066 2319BT_EXPORT
c6962c96
PP
2320void bt_field_class_set_user_attributes(
2321 struct bt_field_class *fc,
2322 const struct bt_value *user_attributes)
2323{
d5b13b9b
PP
2324 BT_ASSERT_PRE_FC_NON_NULL(fc);
2325 BT_ASSERT_PRE_USER_ATTRS_NON_NULL(user_attributes);
1778c2a4
PP
2326 BT_ASSERT_PRE_USER_ATTRS_IS_MAP(user_attributes);
2327 BT_ASSERT_PRE_DEV_FC_HOT(fc);
6871026b 2328 bt_object_put_ref_no_null_check(fc->user_attributes);
c6962c96 2329 fc->user_attributes = (void *) user_attributes;
6871026b 2330 bt_object_get_ref_no_null_check(fc->user_attributes);
c6962c96
PP
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
1778c2a4 2341void set_named_field_class_user_attributes(
c6962c96 2342 struct bt_named_field_class *named_fc,
1778c2a4 2343 const struct bt_value *user_attributes, const char *api_func)
c6962c96 2344{
1778c2a4
PP
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);
6871026b 2347 bt_object_put_ref_no_null_check(named_fc->user_attributes);
c6962c96 2348 named_fc->user_attributes = (void *) user_attributes;
6871026b 2349 bt_object_get_ref_no_null_check(named_fc->user_attributes);
c6962c96
PP
2350}
2351
1353b066 2352BT_EXPORT
c6962c96
PP
2353const struct bt_value *
2354bt_field_class_structure_member_borrow_user_attributes_const(
2355 const struct bt_field_class_structure_member *member)
2356{
d5b13b9b 2357 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
c6962c96
PP
2358 return bt_named_field_class_borrow_user_attributes_const(
2359 (const void *) member);
2360}
2361
1353b066 2362BT_EXPORT
c6962c96
PP
2363struct bt_value *
2364bt_field_class_structure_member_borrow_user_attributes(
2365 struct bt_field_class_structure_member *member)
2366{
d5b13b9b 2367 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
c6962c96
PP
2368 return (void *) bt_named_field_class_borrow_user_attributes_const(
2369 (void *) member);
2370}
2371
1353b066 2372BT_EXPORT
c6962c96
PP
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{
d5b13b9b 2377 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
1778c2a4
PP
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__);
c6962c96
PP
2383}
2384
1353b066 2385BT_EXPORT
c6962c96
PP
2386const struct bt_value *bt_field_class_variant_option_borrow_user_attributes_const(
2387 const struct bt_field_class_variant_option *option)
2388{
d5b13b9b 2389 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
c6962c96
PP
2390 return bt_named_field_class_borrow_user_attributes_const(
2391 (const void *) option);
2392}
2393
1353b066 2394BT_EXPORT
c6962c96
PP
2395struct bt_value *bt_field_class_variant_option_borrow_user_attributes(
2396 struct bt_field_class_variant_option *option)
2397{
d5b13b9b 2398 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
c6962c96
PP
2399 return (void *) bt_named_field_class_borrow_user_attributes_const(
2400 (void *) option);
2401}
2402
1353b066 2403BT_EXPORT
c6962c96
PP
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{
d5b13b9b 2408 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
1778c2a4
PP
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__);
c6962c96
PP
2414}
2415
1353b066 2416BT_EXPORT
c5b9b441
PP
2417void bt_field_class_get_ref(const struct bt_field_class *field_class)
2418{
2419 bt_object_get_ref(field_class);
2420}
2421
1353b066 2422BT_EXPORT
c5b9b441
PP
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.207392 seconds and 4 git commands to generate.