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