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