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