lib: add bt_field_class_variant_borrow_option_by_{index,name}()
[babeltrace.git] / src / lib / trace-ir / field-class.c
CommitLineData
5cd6d0e5 1/*
e2f7325d 2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
5cd6d0e5
PP
3 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5cd6d0e5
PP
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
350ad6c1 24#define BT_LOG_TAG "LIB/FIELD-CLASS"
c2d9d9cf 25#include "lib/logging.h"
5cd6d0e5 26
578e048b 27#include "lib/assert-pre.h"
3fadfbc0
MJ
28#include <babeltrace2/trace-ir/field-class.h>
29#include <babeltrace2/trace-ir/field-class-const.h>
3fadfbc0
MJ
30#include <babeltrace2/trace-ir/field-const.h>
31#include <babeltrace2/trace-ir/field.h>
3fadfbc0 32#include <babeltrace2/trace-ir/clock-class.h>
578e048b
MJ
33#include "lib/object.h"
34#include "compat/compiler.h"
35#include "compat/endian.h"
36#include "common/assert.h"
37#include "compat/glib.h"
5cd6d0e5
PP
38#include <float.h>
39#include <inttypes.h>
40#include <stdlib.h>
41
578e048b
MJ
42#include "clock-class.h"
43#include "field-class.h"
44#include "field.h"
45#include "field-path.h"
46#include "utils.h"
d24d5663 47#include "lib/func-status.h"
45c51519 48#include "lib/integer-range-set.h"
578e048b 49
40f4ba76
PP
50enum bt_field_class_type bt_field_class_get_type(
51 const struct bt_field_class *fc)
5cd6d0e5 52{
bdb288b3 53 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
864cad70 54 return fc->type;
5cd6d0e5
PP
55}
56
57static
864cad70 58void init_field_class(struct bt_field_class *fc, enum bt_field_class_type type,
5cd6d0e5
PP
59 bt_object_release_func release_func)
60{
61 BT_ASSERT(fc);
5cd6d0e5
PP
62 BT_ASSERT(release_func);
63 bt_object_init_shared(&fc->base, release_func);
864cad70 64 fc->type = type;
5cd6d0e5
PP
65}
66
1094efa4
PP
67static
68void destroy_bit_array_field_class(struct bt_object *obj)
69{
70 BT_ASSERT(obj);
71 BT_LIB_LOGD("Destroying bit array field class object: %!+F", obj);
72 g_free(obj);
73}
74
75struct bt_field_class *bt_field_class_bit_array_create(
76 struct bt_trace_class *trace_class, uint64_t length)
77{
78 struct bt_field_class_bit_array *ba_fc = NULL;
79
80 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
81 BT_ASSERT_PRE(length > 0 && length <= 64,
82 "Unsupported length for bit array field class "
83 "(minimum is 1, maximum is 64): length=%" PRIu64, length);
84 BT_LOGD("Creating default bit array field class object.");
85 ba_fc = g_new0(struct bt_field_class_bit_array, 1);
86 if (!ba_fc) {
87 BT_LIB_LOGE_APPEND_CAUSE(
88 "Failed to allocate one bit array field class.");
89 goto error;
90 }
91
92 init_field_class((void *) ba_fc, BT_FIELD_CLASS_TYPE_BIT_ARRAY,
93 destroy_bit_array_field_class);
94 ba_fc->length = length;
95 BT_LIB_LOGD("Created bit array field class object: %!+F", ba_fc);
96 goto end;
97
98error:
99 BT_OBJECT_PUT_REF_AND_RESET(ba_fc);
100
101end:
102 return (void *) ba_fc;
103}
104
105uint64_t bt_field_class_bit_array_get_length(const struct bt_field_class *fc)
106{
107 const struct bt_field_class_bit_array *ba_fc = (const void *) fc;
108
109 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
110 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_BIT_ARRAY,
111 "Field class");
112 return ba_fc->length;
113}
114
5cebbe7f
PP
115static
116void destroy_bool_field_class(struct bt_object *obj)
117{
118 BT_ASSERT(obj);
119 BT_LIB_LOGD("Destroying boolean field class object: %!+F", obj);
120 g_free(obj);
121}
122
123struct bt_field_class *bt_field_class_bool_create(
124 bt_trace_class *trace_class)
125{
126 struct bt_field_class_bool *bool_fc = NULL;
127
128 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
129 BT_LOGD("Creating default boolean field class object.");
130 bool_fc = g_new0(struct bt_field_class_bool, 1);
131 if (!bool_fc) {
132 BT_LIB_LOGE_APPEND_CAUSE(
133 "Failed to allocate one boolean field class.");
134 goto error;
135 }
136
137 init_field_class((void *) bool_fc, BT_FIELD_CLASS_TYPE_BOOL,
138 destroy_bool_field_class);
139 BT_LIB_LOGD("Created boolean field class object: %!+F", bool_fc);
140 goto end;
141
142error:
143 BT_OBJECT_PUT_REF_AND_RESET(bool_fc);
144
145end:
146 return (void *) bool_fc;
147}
148
5cd6d0e5 149static
864cad70
PP
150void init_integer_field_class(struct bt_field_class_integer *fc,
151 enum bt_field_class_type type,
5cd6d0e5
PP
152 bt_object_release_func release_func)
153{
864cad70 154 init_field_class((void *) fc, type, release_func);
5cd6d0e5
PP
155 fc->range = 64;
156 fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
157}
158
159static
160void destroy_integer_field_class(struct bt_object *obj)
161{
162 BT_ASSERT(obj);
e5be10ef 163 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj);
5cd6d0e5
PP
164 g_free(obj);
165}
166
167static inline
1122a43a
PP
168struct bt_field_class *create_integer_field_class(bt_trace_class *trace_class,
169 enum bt_field_class_type type)
5cd6d0e5
PP
170{
171 struct bt_field_class_integer *int_fc = NULL;
172
1122a43a 173 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 174 BT_LOGD("Creating default integer field class object: type=%s",
864cad70 175 bt_common_field_class_type_string(type));
5cd6d0e5
PP
176 int_fc = g_new0(struct bt_field_class_integer, 1);
177 if (!int_fc) {
870631a2
PP
178 BT_LIB_LOGE_APPEND_CAUSE(
179 "Failed to allocate one integer field class.");
5cd6d0e5
PP
180 goto error;
181 }
182
864cad70 183 init_integer_field_class(int_fc, type, destroy_integer_field_class);
e5be10ef 184 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc);
5cd6d0e5
PP
185 goto end;
186
187error:
65300d60 188 BT_OBJECT_PUT_REF_AND_RESET(int_fc);
5cd6d0e5
PP
189
190end:
191 return (void *) int_fc;
192}
193
9c08c816 194struct bt_field_class *bt_field_class_integer_unsigned_create(
1122a43a 195 bt_trace_class *trace_class)
5cd6d0e5 196{
1122a43a 197 return create_integer_field_class(trace_class,
e5be10ef 198 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER);
5cd6d0e5
PP
199}
200
9c08c816 201struct bt_field_class *bt_field_class_integer_signed_create(
1122a43a 202 bt_trace_class *trace_class)
5cd6d0e5 203{
1122a43a 204 return create_integer_field_class(trace_class,
e5be10ef 205 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER);
5cd6d0e5
PP
206}
207
208uint64_t bt_field_class_integer_get_field_value_range(
40f4ba76 209 const struct bt_field_class *fc)
5cd6d0e5 210{
40f4ba76 211 const struct bt_field_class_integer *int_fc = (const void *) fc;
5cd6d0e5 212
bdb288b3
PP
213 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
214 BT_ASSERT_PRE_DEV_FC_IS_INT(fc, "Field class");
5cd6d0e5
PP
215 return int_fc->range;
216}
217
5cd6d0e5
PP
218static
219bool size_is_valid_for_enumeration_field_class(struct bt_field_class *fc,
220 uint64_t size)
221{
222 // TODO
223 return true;
224}
225
40f4ba76
PP
226void bt_field_class_integer_set_field_value_range(
227 struct bt_field_class *fc, uint64_t size)
5cd6d0e5
PP
228{
229 struct bt_field_class_integer *int_fc = (void *) fc;
230
231 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
232 BT_ASSERT_PRE_FC_IS_INT(fc, "Field class");
bdb288b3 233 BT_ASSERT_PRE_DEV_FC_HOT(fc, "Field class");
5cd6d0e5 234 BT_ASSERT_PRE(size <= 64,
e5be10ef 235 "Unsupported size for integer field class's field value range "
5cd6d0e5 236 "(maximum is 64): size=%" PRIu64, size);
864cad70
PP
237 BT_ASSERT_PRE(
238 int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
239 int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
5cd6d0e5 240 size_is_valid_for_enumeration_field_class(fc, size),
e5be10ef 241 "Invalid field value range for enumeration field class: "
5cd6d0e5
PP
242 "at least one of the current mapping ranges contains values "
243 "which are outside this range: %!+F, size=%" PRIu64, fc, size);
244 int_fc->range = size;
3f7d4d90 245 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc);
5cd6d0e5
PP
246}
247
248enum bt_field_class_integer_preferred_display_base
40f4ba76 249bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc)
5cd6d0e5 250{
40f4ba76 251 const struct bt_field_class_integer *int_fc = (const void *) fc;
5cd6d0e5 252
bdb288b3
PP
253 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
254 BT_ASSERT_PRE_DEV_FC_IS_INT(fc, "Field class");
5cd6d0e5
PP
255 return int_fc->base;
256}
257
40f4ba76
PP
258void bt_field_class_integer_set_preferred_display_base(
259 struct bt_field_class *fc,
5cd6d0e5
PP
260 enum bt_field_class_integer_preferred_display_base base)
261{
262 struct bt_field_class_integer *int_fc = (void *) fc;
263
264 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
265 BT_ASSERT_PRE_FC_IS_INT(fc, "Field class");
bdb288b3 266 BT_ASSERT_PRE_DEV_FC_HOT(fc, "Field class");
5cd6d0e5 267 int_fc->base = base;
3f7d4d90 268 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc);
5cd6d0e5
PP
269}
270
271static
272void finalize_enumeration_field_class_mapping(
273 struct bt_field_class_enumeration_mapping *mapping)
274{
275 BT_ASSERT(mapping);
276
277 if (mapping->label) {
278 g_string_free(mapping->label, TRUE);
45c51519 279 mapping->label = NULL;
5cd6d0e5
PP
280 }
281
45c51519 282 BT_OBJECT_PUT_REF_AND_RESET(mapping->range_set);
5cd6d0e5
PP
283}
284
285static
286void destroy_enumeration_field_class(struct bt_object *obj)
287{
288 struct bt_field_class_enumeration *fc = (void *) obj;
289
290 BT_ASSERT(fc);
e5be10ef 291 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc);
5cd6d0e5
PP
292
293 if (fc->mappings) {
294 uint64_t i;
295
296 for (i = 0; i < fc->mappings->len; i++) {
297 finalize_enumeration_field_class_mapping(
298 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i));
299 }
300
301 g_array_free(fc->mappings, TRUE);
238b7404 302 fc->mappings = NULL;
5cd6d0e5
PP
303 }
304
305 if (fc->label_buf) {
306 g_ptr_array_free(fc->label_buf, TRUE);
238b7404 307 fc->label_buf = NULL;
5cd6d0e5
PP
308 }
309
310 g_free(fc);
311}
312
313static
40f4ba76 314struct bt_field_class *create_enumeration_field_class(
1122a43a 315 bt_trace_class *trace_class, enum bt_field_class_type type)
5cd6d0e5
PP
316{
317 struct bt_field_class_enumeration *enum_fc = NULL;
318
1122a43a 319 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 320 BT_LOGD("Creating default enumeration field class object: type=%s",
864cad70 321 bt_common_field_class_type_string(type));
5cd6d0e5
PP
322 enum_fc = g_new0(struct bt_field_class_enumeration, 1);
323 if (!enum_fc) {
870631a2
PP
324 BT_LIB_LOGE_APPEND_CAUSE(
325 "Failed to allocate one enumeration field class.");
5cd6d0e5
PP
326 goto error;
327 }
328
864cad70 329 init_integer_field_class((void *) enum_fc, type,
5cd6d0e5
PP
330 destroy_enumeration_field_class);
331 enum_fc->mappings = g_array_new(FALSE, TRUE,
332 sizeof(struct bt_field_class_enumeration_mapping));
333 if (!enum_fc->mappings) {
870631a2 334 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
5cd6d0e5
PP
335 goto error;
336 }
337
338 enum_fc->label_buf = g_ptr_array_new();
339 if (!enum_fc->label_buf) {
870631a2 340 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
5cd6d0e5
PP
341 goto error;
342 }
343
e5be10ef 344 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc);
5cd6d0e5
PP
345 goto end;
346
347error:
65300d60 348 BT_OBJECT_PUT_REF_AND_RESET(enum_fc);
5cd6d0e5
PP
349
350end:
351 return (void *) enum_fc;
352}
353
9c08c816 354struct bt_field_class *bt_field_class_enumeration_unsigned_create(
1122a43a 355 bt_trace_class *trace_class)
5cd6d0e5 356{
1122a43a 357 return create_enumeration_field_class(trace_class,
864cad70 358 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION);
5cd6d0e5
PP
359}
360
9c08c816 361struct bt_field_class *bt_field_class_enumeration_signed_create(
1122a43a 362 bt_trace_class *trace_class)
5cd6d0e5 363{
1122a43a 364 return create_enumeration_field_class(trace_class,
864cad70 365 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
5cd6d0e5
PP
366}
367
40f4ba76
PP
368uint64_t bt_field_class_enumeration_get_mapping_count(
369 const struct bt_field_class *fc)
5cd6d0e5 370{
40f4ba76 371 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5 372
bdb288b3
PP
373 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
374 BT_ASSERT_PRE_DEV_FC_IS_ENUM(fc, "Field class");
5cd6d0e5
PP
375 return (uint64_t) enum_fc->mappings->len;
376}
377
9c08c816
PP
378const struct bt_field_class_enumeration_unsigned_mapping *
379bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
8f3ccfbc 380 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 381{
40f4ba76 382 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5 383
bdb288b3
PP
384 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
385 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
386 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
5cd6d0e5 387 "Field class");
8f3ccfbc 388 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
5cd6d0e5
PP
389}
390
9c08c816
PP
391const struct bt_field_class_enumeration_signed_mapping *
392bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
8f3ccfbc 393 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 394{
40f4ba76 395 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5 396
bdb288b3
PP
397 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
398 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
399 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
5cd6d0e5 400 "Field class");
8f3ccfbc 401 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
5cd6d0e5
PP
402}
403
45c51519
PP
404static
405const struct bt_field_class_enumeration_mapping *
406borrow_enumeration_field_class_mapping_by_label(
407 const struct bt_field_class_enumeration *fc, const char *label)
5cd6d0e5 408{
45c51519
PP
409 struct bt_field_class_enumeration_mapping *mapping = NULL;
410 uint64_t i;
411
412 BT_ASSERT(fc);
413 BT_ASSERT_PRE_DEV_NON_NULL(label, "Label");
414
415 for (i = 0; i < fc->mappings->len; i++) {
416 struct bt_field_class_enumeration_mapping *this_mapping =
417 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i);
418
419 if (strcmp(this_mapping->label->str, label) == 0) {
420 mapping = this_mapping;
421 goto end;
422 }
423 }
424
425end:
426 return mapping;
5cd6d0e5
PP
427}
428
9c08c816
PP
429const struct bt_field_class_enumeration_signed_mapping *
430bt_field_class_enumeration_signed_borrow_mapping_by_label_const(
45c51519 431 const struct bt_field_class *fc, const char *label)
5cd6d0e5 432{
45c51519
PP
433 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
434 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
435 "Field class");
436 return (const void *) borrow_enumeration_field_class_mapping_by_label(
437 (const void *) fc, label);
5cd6d0e5
PP
438}
439
9c08c816
PP
440const struct bt_field_class_enumeration_unsigned_mapping *
441bt_field_class_enumeration_unsigned_borrow_mapping_by_label_const(
45c51519 442 const struct bt_field_class *fc, const char *label)
5cd6d0e5 443{
45c51519
PP
444 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
445 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
446 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
447 return (const void *) borrow_enumeration_field_class_mapping_by_label(
448 (const void *) fc, label);
449}
5cd6d0e5 450
45c51519
PP
451const char *bt_field_class_enumeration_mapping_get_label(
452 const struct bt_field_class_enumeration_mapping *mapping)
453{
454 BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
455 return mapping->label->str;
5cd6d0e5
PP
456}
457
45c51519 458const struct bt_integer_range_set_unsigned *
9c08c816
PP
459bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
460 const struct bt_field_class_enumeration_unsigned_mapping *u_mapping)
5cd6d0e5 461{
45c51519
PP
462 const struct bt_field_class_enumeration_mapping *mapping =
463 (const void *) u_mapping;
464
465 BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
466 return (const void *) mapping->range_set;
5cd6d0e5
PP
467}
468
45c51519 469const struct bt_integer_range_set_signed *
9c08c816
PP
470bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
471 const struct bt_field_class_enumeration_signed_mapping *s_mapping)
5cd6d0e5 472{
45c51519
PP
473 const struct bt_field_class_enumeration_mapping *mapping =
474 (const void *) s_mapping;
475
476 BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
477 return (const void *) mapping->range_set;
5cd6d0e5
PP
478}
479
185ecf64 480enum bt_field_class_enumeration_get_mapping_labels_for_value_status
9c08c816 481bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
40f4ba76 482 const struct bt_field_class *fc, uint64_t value,
5cd6d0e5
PP
483 bt_field_class_enumeration_mapping_label_array *label_array,
484 uint64_t *count)
485{
40f4ba76 486 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
487 uint64_t i;
488
bdb288b3
PP
489 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
490 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Label array (output)");
491 BT_ASSERT_PRE_DEV_NON_NULL(count, "Count (output)");
492 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
5cd6d0e5
PP
493 "Field class");
494 g_ptr_array_set_size(enum_fc->label_buf, 0);
495
496 for (i = 0; i < enum_fc->mappings->len; i++) {
497 uint64_t j;
40f4ba76 498 const struct bt_field_class_enumeration_mapping *mapping =
5cd6d0e5
PP
499 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
500
45c51519
PP
501 for (j = 0; j < mapping->range_set->ranges->len; j++) {
502 const struct bt_integer_range *range = (const void *)
503 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
504 mapping->range_set, j);
5cd6d0e5
PP
505
506 if (value >= range->lower.u &&
507 value <= range->upper.u) {
508 g_ptr_array_add(enum_fc->label_buf,
509 mapping->label->str);
510 break;
511 }
512 }
513 }
514
515 *label_array = (void *) enum_fc->label_buf->pdata;
516 *count = (uint64_t) enum_fc->label_buf->len;
d24d5663 517 return BT_FUNC_STATUS_OK;
5cd6d0e5
PP
518}
519
185ecf64 520enum bt_field_class_enumeration_get_mapping_labels_for_value_status
9c08c816 521bt_field_class_enumeration_signed_get_mapping_labels_for_value(
40f4ba76 522 const struct bt_field_class *fc, int64_t value,
5cd6d0e5
PP
523 bt_field_class_enumeration_mapping_label_array *label_array,
524 uint64_t *count)
525{
40f4ba76 526 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
527 uint64_t i;
528
bdb288b3
PP
529 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
530 BT_ASSERT_PRE_DEV_NON_NULL(label_array, "Label array (output)");
531 BT_ASSERT_PRE_DEV_NON_NULL(count, "Count (output)");
532 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
5cd6d0e5
PP
533 "Field class");
534 g_ptr_array_set_size(enum_fc->label_buf, 0);
535
536 for (i = 0; i < enum_fc->mappings->len; i++) {
537 uint64_t j;
40f4ba76 538 const struct bt_field_class_enumeration_mapping *mapping =
5cd6d0e5
PP
539 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
540
45c51519
PP
541 for (j = 0; j < mapping->range_set->ranges->len; j++) {
542 const struct bt_integer_range *range = (const void *)
543 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
544 mapping->range_set, j);
5cd6d0e5
PP
545
546 if (value >= range->lower.i &&
547 value <= range->upper.i) {
548 g_ptr_array_add(enum_fc->label_buf,
549 mapping->label->str);
550 break;
551 }
552 }
553 }
554
555 *label_array = (void *) enum_fc->label_buf->pdata;
556 *count = (uint64_t) enum_fc->label_buf->len;
d24d5663 557 return BT_FUNC_STATUS_OK;
5cd6d0e5
PP
558}
559
45c51519
PP
560static
561bool enumeration_field_class_has_mapping_with_label(
562 const struct bt_field_class_enumeration *enum_fc,
563 const char *label)
5cd6d0e5 564{
5cd6d0e5 565 uint64_t i;
45c51519 566 bool exists = false;
5cd6d0e5 567
45c51519
PP
568 BT_ASSERT(enum_fc);
569 BT_ASSERT(label);
5cd6d0e5 570
5cd6d0e5
PP
571 for (i = 0; i < enum_fc->mappings->len; i++) {
572 struct bt_field_class_enumeration_mapping *mapping_candidate =
573 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
574
575 if (strcmp(mapping_candidate->label->str, label) == 0) {
45c51519
PP
576 exists = true;
577 goto end;
5cd6d0e5
PP
578 }
579 }
580
45c51519
PP
581end:
582 return exists;
583}
5cd6d0e5 584
45c51519
PP
585static inline
586enum bt_field_class_enumeration_add_mapping_status
587add_mapping_to_enumeration_field_class(struct bt_field_class *fc,
588 const char *label, const struct bt_integer_range_set *range_set)
589{
590 enum bt_field_class_enumeration_add_mapping_status status =
591 BT_FUNC_STATUS_OK;
592 struct bt_field_class_enumeration *enum_fc = (void *) fc;
593 struct bt_field_class_enumeration_mapping mapping = { 0 };
594
595 BT_ASSERT(fc);
596 BT_ASSERT_PRE_NON_NULL(label, "Label");
6769570a 597 BT_ASSERT_PRE_NON_NULL(range_set, "Integer range set");
45c51519
PP
598 BT_ASSERT_PRE(!enumeration_field_class_has_mapping_with_label(
599 enum_fc, label),
600 "Duplicate mapping name in enumeration field class: "
601 "%![enum-fc-]+F, label=\"%s\"", fc, label);
602 mapping.range_set = range_set;
603 bt_object_get_ref(mapping.range_set);
604 mapping.label = g_string_new(label);
605 if (!mapping.label) {
606 finalize_enumeration_field_class_mapping(&mapping);
607 status = BT_FUNC_STATUS_MEMORY_ERROR;
608 goto end;
5cd6d0e5
PP
609 }
610
45c51519 611 g_array_append_val(enum_fc->mappings, mapping);
3f7d4d90 612 BT_LIB_LOGD("Added mapping to enumeration field class: "
45c51519 613 "%![fc-]+F, label=\"%s\"", fc, label);
5cd6d0e5
PP
614
615end:
45c51519 616 return status;
5cd6d0e5
PP
617}
618
45c51519 619enum bt_field_class_enumeration_add_mapping_status
9c08c816 620bt_field_class_enumeration_unsigned_add_mapping(
40f4ba76 621 struct bt_field_class *fc, const char *label,
45c51519 622 const struct bt_integer_range_set_unsigned *range_set)
5cd6d0e5 623{
5cd6d0e5 624 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 625 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
5cd6d0e5 626 "Field class");
45c51519
PP
627 return add_mapping_to_enumeration_field_class(fc, label,
628 (const void *) range_set);
629}
630
631enum bt_field_class_enumeration_add_mapping_status
9c08c816 632bt_field_class_enumeration_signed_add_mapping(
40f4ba76 633 struct bt_field_class *fc, const char *label,
45c51519 634 const struct bt_integer_range_set_signed *range_set)
5cd6d0e5 635{
5cd6d0e5 636 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 637 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
5cd6d0e5 638 "Field class");
45c51519
PP
639 return add_mapping_to_enumeration_field_class(fc, label,
640 (const void *) range_set);
5cd6d0e5
PP
641}
642
643static
644void destroy_real_field_class(struct bt_object *obj)
645{
646 BT_ASSERT(obj);
e5be10ef 647 BT_LIB_LOGD("Destroying real field class object: %!+F", obj);
5cd6d0e5
PP
648 g_free(obj);
649}
650
1122a43a 651struct bt_field_class *bt_field_class_real_create(bt_trace_class *trace_class)
5cd6d0e5
PP
652{
653 struct bt_field_class_real *real_fc = NULL;
654
1122a43a 655 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 656 BT_LOGD_STR("Creating default real field class object.");
5cd6d0e5
PP
657 real_fc = g_new0(struct bt_field_class_real, 1);
658 if (!real_fc) {
870631a2 659 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
5cd6d0e5
PP
660 goto error;
661 }
662
864cad70 663 init_field_class((void *) real_fc, BT_FIELD_CLASS_TYPE_REAL,
5cd6d0e5 664 destroy_real_field_class);
e5be10ef 665 BT_LIB_LOGD("Created real field class object: %!+F", real_fc);
5cd6d0e5
PP
666 goto end;
667
668error:
65300d60 669 BT_OBJECT_PUT_REF_AND_RESET(real_fc);
5cd6d0e5
PP
670
671end:
672 return (void *) real_fc;
673}
674
40f4ba76 675bt_bool bt_field_class_real_is_single_precision(const struct bt_field_class *fc)
5cd6d0e5 676{
40f4ba76 677 const struct bt_field_class_real *real_fc = (const void *) fc;
5cd6d0e5 678
bdb288b3
PP
679 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
680 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class");
5cd6d0e5
PP
681 return real_fc->is_single_precision;
682}
683
40f4ba76 684void bt_field_class_real_set_is_single_precision(struct bt_field_class *fc,
5cd6d0e5
PP
685 bt_bool is_single_precision)
686{
687 struct bt_field_class_real *real_fc = (void *) fc;
688
689 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 690 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class");
bdb288b3 691 BT_ASSERT_PRE_DEV_FC_HOT(fc, "Field class");
5cd6d0e5 692 real_fc->is_single_precision = (bool) is_single_precision;
3f7d4d90 693 BT_LIB_LOGD("Set real field class's \"is single precision\" property: "
5cd6d0e5 694 "%!+F", fc);
5cd6d0e5
PP
695}
696
697static
698int init_named_field_classes_container(
699 struct bt_field_class_named_field_class_container *fc,
40f4ba76 700 enum bt_field_class_type type,
45c51519
PP
701 bt_object_release_func fc_release_func,
702 GDestroyNotify named_fc_destroy_func)
5cd6d0e5
PP
703{
704 int ret = 0;
705
45c51519
PP
706 init_field_class((void *) fc, type, fc_release_func);
707 fc->named_fcs = g_ptr_array_new_with_free_func(named_fc_destroy_func);
5cd6d0e5 708 if (!fc->named_fcs) {
45c51519 709 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
5cd6d0e5
PP
710 ret = -1;
711 goto end;
712 }
713
714 fc->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
715 if (!fc->name_to_index) {
870631a2 716 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
5cd6d0e5
PP
717 ret = -1;
718 goto end;
719 }
720
721end:
722 return ret;
723}
724
725static
726void finalize_named_field_class(struct bt_named_field_class *named_fc)
727{
728 BT_ASSERT(named_fc);
e5be10ef 729 BT_LIB_LOGD("Finalizing named field class: "
5cd6d0e5
PP
730 "addr=%p, name=\"%s\", %![fc-]+F",
731 named_fc, named_fc->name ? named_fc->name->str : NULL,
732 named_fc->fc);
733
734 if (named_fc->name) {
735 g_string_free(named_fc->name, TRUE);
45c51519 736 named_fc->name = NULL;
5cd6d0e5
PP
737 }
738
e5be10ef 739 BT_LOGD_STR("Putting named field class's field class.");
238b7404 740 BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc);
5cd6d0e5
PP
741}
742
45c51519
PP
743static
744void destroy_named_field_class(gpointer ptr)
745{
746 if (ptr) {
747 finalize_named_field_class(ptr);
748 g_free(ptr);
749 }
750}
751
752static
753void destroy_variant_with_selector_option(gpointer ptr)
754{
755 struct bt_field_class_variant_with_selector_option *opt = ptr;
756
757 if (ptr) {
758 finalize_named_field_class(&opt->common);
759 BT_OBJECT_PUT_REF_AND_RESET(opt->range_set);
760 g_free(ptr);
761 }
762}
763
5cd6d0e5
PP
764static
765void finalize_named_field_classes_container(
766 struct bt_field_class_named_field_class_container *fc)
767{
5cd6d0e5
PP
768 BT_ASSERT(fc);
769
770 if (fc->named_fcs) {
45c51519
PP
771 g_ptr_array_free(fc->named_fcs, TRUE);
772 fc->named_fcs = NULL;
5cd6d0e5 773
5cd6d0e5
PP
774 }
775
776 if (fc->name_to_index) {
777 g_hash_table_destroy(fc->name_to_index);
45c51519 778 fc->name_to_index = NULL;
5cd6d0e5
PP
779 }
780}
781
782static
783void destroy_structure_field_class(struct bt_object *obj)
784{
785 BT_ASSERT(obj);
1998d1ab 786 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj);
5cd6d0e5
PP
787 finalize_named_field_classes_container((void *) obj);
788 g_free(obj);
789}
790
1122a43a
PP
791struct bt_field_class *bt_field_class_structure_create(
792 bt_trace_class *trace_class)
5cd6d0e5
PP
793{
794 int ret;
795 struct bt_field_class_structure *struct_fc = NULL;
796
1122a43a 797 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 798 BT_LOGD_STR("Creating default structure field class object.");
5cd6d0e5
PP
799 struct_fc = g_new0(struct bt_field_class_structure, 1);
800 if (!struct_fc) {
870631a2
PP
801 BT_LIB_LOGE_APPEND_CAUSE(
802 "Failed to allocate one structure field class.");
5cd6d0e5
PP
803 goto error;
804 }
805
806 ret = init_named_field_classes_container((void *) struct_fc,
45c51519
PP
807 BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class,
808 destroy_named_field_class);
5cd6d0e5 809 if (ret) {
45c51519 810 /* init_named_field_classes_container() logs errors */
5cd6d0e5
PP
811 goto error;
812 }
813
e5be10ef 814 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc);
5cd6d0e5
PP
815 goto end;
816
817error:
65300d60 818 BT_OBJECT_PUT_REF_AND_RESET(struct_fc);
5cd6d0e5
PP
819
820end:
821 return (void *) struct_fc;
822}
823
824static
45c51519 825int init_named_field_class(struct bt_named_field_class *named_fc,
5cd6d0e5
PP
826 const char *name, struct bt_field_class *fc)
827{
45c51519 828 int status = BT_FUNC_STATUS_OK;
5cd6d0e5 829
45c51519
PP
830 BT_ASSERT(named_fc);
831 BT_ASSERT(name);
832 BT_ASSERT(fc);
833 named_fc->name = g_string_new(name);
834 if (!named_fc->name) {
870631a2 835 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
45c51519 836 status = BT_FUNC_STATUS_MEMORY_ERROR;
5cd6d0e5
PP
837 goto end;
838 }
839
398454ed 840 named_fc->fc = fc;
45c51519
PP
841 bt_object_get_no_null_check(named_fc->fc);
842 bt_named_field_class_freeze(named_fc);
1e6fd1d7 843
45c51519
PP
844end:
845 return status;
846}
847
848static
849struct bt_named_field_class *create_named_field_class(const char *name,
850 struct bt_field_class *fc)
851{
852 struct bt_named_field_class *named_fc = g_new0(
853 struct bt_named_field_class, 1);
854
855 if (!named_fc) {
856 BT_LIB_LOGE_APPEND_CAUSE(
857 "Failed to allocate a named field class.");
858 goto error;
859 }
860
861 if (init_named_field_class(named_fc, name, fc)) {
862 /* init_named_field_class() logs errors */
863 goto error;
864 }
865
866 goto end;
867
868error:
869 destroy_named_field_class(named_fc);
870 named_fc = NULL;
5cd6d0e5
PP
871
872end:
45c51519
PP
873 return named_fc;
874}
875
876static
877struct bt_field_class_variant_with_selector_option *
878create_variant_with_selector_option(
879 const char *name, struct bt_field_class *fc,
880 const struct bt_integer_range_set *range_set)
881{
882 struct bt_field_class_variant_with_selector_option *opt = g_new0(
883 struct bt_field_class_variant_with_selector_option, 1);
884
885 BT_ASSERT(range_set);
886
887 if (!opt) {
888 BT_LIB_LOGE_APPEND_CAUSE(
889 "Failed to allocate a named field class.");
890 goto error;
891 }
892
893 if (init_named_field_class(&opt->common, name, fc)) {
894 goto error;
895 }
896
897 opt->range_set = range_set;
898 bt_object_get_no_null_check(opt->range_set);
899 bt_integer_range_set_freeze(range_set);
900 goto end;
901
902error:
903 destroy_variant_with_selector_option(opt);
904 opt = NULL;
905
906end:
907 return opt;
908}
909
910static
911int append_named_field_class_to_container_field_class(
912 struct bt_field_class_named_field_class_container *container_fc,
913 struct bt_named_field_class *named_fc)
914{
915 BT_ASSERT(container_fc);
916 BT_ASSERT(named_fc);
917 BT_ASSERT_PRE_DEV_FC_HOT(container_fc, "Field class");
918 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc->name_to_index,
919 named_fc->name->str),
920 "Duplicate member/option name in structure/variant field class: "
921 "%![container-fc-]+F, name=\"%s\"", container_fc,
922 named_fc->name->str);
923 g_ptr_array_add(container_fc->named_fcs, named_fc);
924 g_hash_table_insert(container_fc->name_to_index, named_fc->name->str,
925 GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
926 return BT_FUNC_STATUS_OK;
5cd6d0e5
PP
927}
928
d24d5663
PP
929enum bt_field_class_structure_append_member_status
930bt_field_class_structure_append_member(
4295b9e0
PP
931 struct bt_field_class *fc, const char *name,
932 struct bt_field_class *member_fc)
5cd6d0e5 933{
45c51519
PP
934 enum bt_field_class_structure_append_member_status status;
935 struct bt_named_field_class *named_fc = NULL;
e5be10ef 936
5cd6d0e5 937 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
740faaf4
PP
938 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
939 "Field class");
45c51519
PP
940 named_fc = create_named_field_class(name, member_fc);
941 if (!named_fc) {
942 /* create_named_field_class() logs errors */
943 status = BT_FUNC_STATUS_MEMORY_ERROR;
944 goto end;
945 }
946
947 status = append_named_field_class_to_container_field_class((void *) fc,
948 named_fc);
949 if (status == BT_FUNC_STATUS_OK) {
950 /* Moved to the container */
951 named_fc = NULL;
952 }
953
954end:
955 return status;
5cd6d0e5
PP
956}
957
40f4ba76
PP
958uint64_t bt_field_class_structure_get_member_count(
959 const struct bt_field_class *fc)
5cd6d0e5
PP
960{
961 struct bt_field_class_structure *struct_fc = (void *) fc;
962
bdb288b3
PP
963 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
964 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
740faaf4 965 "Field class");
5cd6d0e5
PP
966 return (uint64_t) struct_fc->common.named_fcs->len;
967}
968
969static
1e6fd1d7
PP
970struct bt_named_field_class *
971borrow_named_field_class_from_container_field_class_at_index(
740faaf4 972 struct bt_field_class_named_field_class_container *fc,
1e6fd1d7 973 uint64_t index)
5cd6d0e5 974{
5cd6d0e5 975 BT_ASSERT(fc);
bdb288b3 976 BT_ASSERT_PRE_DEV_VALID_INDEX(index, fc->named_fcs->len);
45c51519 977 return fc->named_fcs->pdata[index];
5cd6d0e5
PP
978}
979
1e6fd1d7
PP
980const struct bt_field_class_structure_member *
981bt_field_class_structure_borrow_member_by_index_const(
982 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 983{
bdb288b3
PP
984 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
985 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
740faaf4 986 "Field class");
1e6fd1d7
PP
987 return (const void *)
988 borrow_named_field_class_from_container_field_class_at_index(
989 (void *) fc, index);
740faaf4
PP
990}
991
1e6fd1d7
PP
992struct bt_field_class_structure_member *
993bt_field_class_structure_borrow_member_by_index(
994 struct bt_field_class *fc, uint64_t index)
740faaf4 995{
bdb288b3
PP
996 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
997 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
740faaf4 998 "Field class");
1e6fd1d7
PP
999 return (void *)
1000 borrow_named_field_class_from_container_field_class_at_index(
1001 (void *) fc, index);
e5be10ef
PP
1002}
1003
5cd6d0e5 1004static
1e6fd1d7
PP
1005struct bt_named_field_class *
1006borrow_named_field_class_from_container_field_class_by_name(
740faaf4 1007 struct bt_field_class_named_field_class_container *fc,
5cd6d0e5
PP
1008 const char *name)
1009{
1e6fd1d7 1010 struct bt_named_field_class *named_fc = NULL;
5cd6d0e5
PP
1011 gpointer orig_key;
1012 gpointer value;
1013
1014 BT_ASSERT(fc);
bdb288b3 1015 BT_ASSERT_PRE_DEV_NON_NULL(name, "Name");
5cd6d0e5
PP
1016 if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key,
1017 &value)) {
1018 goto end;
1019 }
1020
45c51519 1021 named_fc = fc->named_fcs->pdata[GPOINTER_TO_UINT(value)];
5cd6d0e5
PP
1022
1023end:
1e6fd1d7 1024 return named_fc;
5cd6d0e5
PP
1025}
1026
1e6fd1d7 1027const struct bt_field_class_structure_member *
7c06e353 1028bt_field_class_structure_borrow_member_by_name_const(
40f4ba76 1029 const struct bt_field_class *fc, const char *name)
5cd6d0e5 1030{
bdb288b3
PP
1031 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1032 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
740faaf4 1033 "Field class");
1e6fd1d7
PP
1034 return (const void *)
1035 borrow_named_field_class_from_container_field_class_by_name(
740faaf4
PP
1036 (void *) fc, name);
1037}
1038
1e6fd1d7 1039struct bt_field_class_structure_member *
fffedc87 1040bt_field_class_structure_borrow_member_by_name(
740faaf4
PP
1041 struct bt_field_class *fc, const char *name)
1042{
bdb288b3
PP
1043 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1044 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
740faaf4 1045 "Field class");
1e6fd1d7
PP
1046 return (void *)
1047 borrow_named_field_class_from_container_field_class_by_name(
40f4ba76 1048 (void *) fc, name);
e5be10ef
PP
1049}
1050
1e6fd1d7
PP
1051const char *bt_field_class_structure_member_get_name(
1052 const struct bt_field_class_structure_member *member)
1053{
1054 const struct bt_named_field_class *named_fc = (const void *) member;
1055
bdb288b3 1056 BT_ASSERT_PRE_DEV_NON_NULL(member, "Structure field class member");
1e6fd1d7
PP
1057 return named_fc->name->str;
1058}
1059
1060const struct bt_field_class *
1061bt_field_class_structure_member_borrow_field_class_const(
1062 const struct bt_field_class_structure_member *member)
1063{
1064 const struct bt_named_field_class *named_fc = (const void *) member;
1065
bdb288b3 1066 BT_ASSERT_PRE_DEV_NON_NULL(member, "Structure field class member");
1e6fd1d7
PP
1067 return named_fc->fc;
1068}
1069
b38aea74
PP
1070static
1071void destroy_option_field_class(struct bt_object *obj)
1072{
1073 struct bt_field_class_option *fc = (void *) obj;
1074
1075 BT_ASSERT(fc);
1076 BT_LIB_LOGD("Destroying option field class object: %!+F", fc);
1077 BT_LOGD_STR("Putting content field class.");
1078 BT_OBJECT_PUT_REF_AND_RESET(fc->content_fc);
1079 BT_LOGD_STR("Putting selector field path.");
1080 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path);
1081 BT_LOGD_STR("Putting selector field class.");
1082 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc);
1083 g_free(fc);
1084}
1085
1086struct bt_field_class *bt_field_class_option_create(bt_trace_class *trace_class,
1087 bt_field_class *content_fc, bt_field_class *selector_fc)
1088{
1089 struct bt_field_class_option *opt_fc = NULL;
1090
1091 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
1092 BT_ASSERT_PRE_NON_NULL(content_fc, "Content field class");
1093 BT_LIB_LOGD("Creating option field class: "
1094 "%![content-fc-]+F, %![sel-fc-]+F", content_fc, selector_fc);
1095 opt_fc = g_new0(struct bt_field_class_option, 1);
1096 if (!opt_fc) {
1097 BT_LIB_LOGE_APPEND_CAUSE(
1098 "Failed to allocate one option field class.");
1099 goto error;
1100 }
1101
1102 init_field_class((void *) opt_fc, BT_FIELD_CLASS_TYPE_OPTION,
1103 destroy_option_field_class);
1104 opt_fc->content_fc = content_fc;
1105 bt_object_get_no_null_check(opt_fc->content_fc);
1106 bt_field_class_freeze(opt_fc->content_fc);
1107
1108 if (selector_fc) {
1109 BT_ASSERT_PRE_FC_HAS_ID(selector_fc, BT_FIELD_CLASS_TYPE_BOOL,
1110 "Selector field class");
1111 opt_fc->selector_fc = selector_fc;
1112 bt_object_get_no_null_check(opt_fc->selector_fc);
1113 bt_field_class_freeze(selector_fc);
1114 }
1115
1116 BT_LIB_LOGD("Created option field class object: "
1117 "%![opt-fc-]+F, %![sel-fc-]+F", opt_fc, selector_fc);
1118 goto end;
1119
1120error:
1121 BT_OBJECT_PUT_REF_AND_RESET(opt_fc);
1122
1123end:
1124 return (void *) opt_fc;
1125}
1126
1127const struct bt_field_class *bt_field_class_option_borrow_field_class_const(
1128 const struct bt_field_class *fc)
1129{
1130 struct bt_field_class_option *opt_fc = (void *) fc;
1131
1132 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
1133 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_OPTION,
1134 "Field class");
1135 return opt_fc->content_fc;
1136}
1137
1138const struct bt_field_path *
1139bt_field_class_option_borrow_selector_field_path_const(
1140 const struct bt_field_class *fc)
1141{
1142 struct bt_field_class_option *opt_fc = (void *) fc;
1143
1144 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
1145 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_OPTION,
1146 "Field class");
1147 return opt_fc->selector_field_path;
1148}
1149
45c51519
PP
1150static
1151void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
1e6fd1d7 1152{
45c51519
PP
1153 BT_ASSERT(var_fc);
1154 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc);
1155 finalize_named_field_classes_container((void *) var_fc);
1e6fd1d7
PP
1156}
1157
5cd6d0e5
PP
1158static
1159void destroy_variant_field_class(struct bt_object *obj)
1160{
1161 struct bt_field_class_variant *fc = (void *) obj;
1162
1163 BT_ASSERT(fc);
45c51519
PP
1164 finalize_variant_field_class(fc);
1165 g_free(fc);
1166}
1167
1168static
1169void destroy_variant_with_selector_field_class(struct bt_object *obj)
1170{
1171 struct bt_field_class_variant_with_selector *fc = (void *) obj;
1172
1173 BT_ASSERT(fc);
1174 finalize_variant_field_class(&fc->common);
5cd6d0e5 1175 BT_LOGD_STR("Putting selector field path.");
238b7404
PP
1176 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path);
1177 BT_LOGD_STR("Putting selector field class.");
1178 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc);
5cd6d0e5
PP
1179 g_free(fc);
1180}
1181
1122a43a 1182struct bt_field_class *bt_field_class_variant_create(
45c51519 1183 bt_trace_class *trace_class, bt_field_class *selector_fc)
5cd6d0e5
PP
1184{
1185 int ret;
1186 struct bt_field_class_variant *var_fc = NULL;
45c51519
PP
1187 struct bt_field_class_variant_with_selector *var_with_sel_fc = NULL;
1188 enum bt_field_class_type fc_type;
5cd6d0e5 1189
1122a43a 1190 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
45c51519
PP
1191
1192 if (selector_fc) {
1193 BT_ASSERT_PRE_FC_IS_INT(selector_fc, "Selector field class");
5cd6d0e5
PP
1194 }
1195
45c51519
PP
1196 BT_LIB_LOGD("Creating default variant field class: %![sel-fc-]+F",
1197 selector_fc);
1198
1199 if (selector_fc) {
1200 var_with_sel_fc = g_new0(
1201 struct bt_field_class_variant_with_selector, 1);
1202 if (!var_with_sel_fc) {
1203 BT_LIB_LOGE_APPEND_CAUSE(
1204 "Failed to allocate one variant field class with selector.");
1205 goto error;
1206 }
1207
1208 if (selector_fc->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
1209 selector_fc->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
1210 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR;
1211 } else {
1212 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR;
1213 }
1214
1215 ret = init_named_field_classes_container(
1216 (void *) var_with_sel_fc, fc_type,
1217 destroy_variant_with_selector_field_class,
1218 destroy_variant_with_selector_option);
1219 if (ret) {
1220 /* init_named_field_classes_container() logs errors */
1221 goto error;
1222 }
1223
1224 var_with_sel_fc->selector_fc = selector_fc;
1225 bt_object_get_no_null_check(var_with_sel_fc->selector_fc);
1226 bt_field_class_freeze(selector_fc);
1227 var_fc = (void *) var_with_sel_fc;
1228 } else {
1229 var_fc = g_new0(struct bt_field_class_variant, 1);
1230 if (!var_fc) {
1231 BT_LIB_LOGE_APPEND_CAUSE(
1232 "Failed to allocate one variant field class without selector.");
1233 goto error;
1234 }
1235
1236 ret = init_named_field_classes_container((void *) var_fc,
1237 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR,
1238 destroy_variant_field_class, destroy_named_field_class);
1239 if (ret) {
1240 /* init_named_field_classes_container() logs errors */
1241 goto error;
1242 }
5cd6d0e5
PP
1243 }
1244
45c51519
PP
1245 BT_ASSERT(var_fc);
1246 BT_LIB_LOGD("Created default variant field class with selector object: "
1247 "%![var-fc-]+F, %![sel-fc-]+F", var_fc, selector_fc);
5cd6d0e5
PP
1248 goto end;
1249
1250error:
65300d60 1251 BT_OBJECT_PUT_REF_AND_RESET(var_fc);
5cd6d0e5
PP
1252
1253end:
1254 return (void *) var_fc;
1255}
1256
45c51519
PP
1257enum bt_field_class_variant_without_selector_append_option_status
1258bt_field_class_variant_without_selector_append_option(struct bt_field_class *fc,
1259 const char *name, struct bt_field_class *option_fc)
1260{
1261 enum bt_field_class_variant_without_selector_append_option_status status;
1262 struct bt_named_field_class *named_fc = NULL;
1263
1264 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
1265 BT_ASSERT_PRE_NON_NULL(name, "Name");
1266 BT_ASSERT_PRE_NON_NULL(option_fc, "Option field class");
1267 BT_ASSERT_PRE_FC_HAS_ID(fc,
1268 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR, "Field class");
1269 named_fc = create_named_field_class(name, option_fc);
1270 if (!named_fc) {
1271 /* create_named_field_class() logs errors */
1272 status = BT_FUNC_STATUS_MEMORY_ERROR;
1273 goto end;
1274 }
1275
1276 status = append_named_field_class_to_container_field_class((void *) fc,
1277 named_fc);
1278 if (status == BT_FUNC_STATUS_OK) {
1279 /* Moved to the container */
1280 named_fc = NULL;
1281 }
1282
1283end:
1284 if (named_fc) {
1285 destroy_named_field_class(named_fc);
1286 }
1287
1288 return status;
5cd6d0e5
PP
1289}
1290
45c51519
PP
1291static
1292int ranges_overlap(GPtrArray *var_fc_opts, const struct bt_integer_range_set *range_set,
1293 bool is_signed, bool *has_overlap)
1294{
1295 int status = BT_FUNC_STATUS_OK;
1296 struct bt_integer_range_set *full_range_set;
1297 uint64_t i;
1298
1299 *has_overlap = false;
1300
1301 /*
1302 * Build a single range set with all the ranges and test for
1303 * overlaps.
1304 */
1305 if (is_signed) {
1306 full_range_set = (void *) bt_integer_range_set_signed_create();
1307 } else {
1308 full_range_set = (void *) bt_integer_range_set_unsigned_create();
1309 }
1310
1311 if (!full_range_set) {
1312 BT_LOGE_STR("Failed to create a range set.");
1313 status = BT_FUNC_STATUS_MEMORY_ERROR;
1314 goto end;
1315 }
1316
1317 /* Add existing option ranges */
1318 for (i = 0; i < var_fc_opts->len; i++) {
1319 struct bt_field_class_variant_with_selector_option *opt =
1320 var_fc_opts->pdata[i];
1321 uint64_t j;
1322
1323 for (j = 0; j < opt->range_set->ranges->len; j++) {
1324 struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1325 opt->range_set, j);
1326
1327 if (is_signed) {
1328 status = bt_integer_range_set_signed_add_range(
1329 (void *) full_range_set, range->lower.i,
1330 range->upper.i);
1331 } else {
1332 status = bt_integer_range_set_unsigned_add_range(
1333 (void *) full_range_set, range->lower.u,
1334 range->upper.u);
1335 }
1336
1337 if (status) {
1338 goto end;
1339 }
1340 }
1341 }
1342
1343 /* Add new ranges */
1344 for (i = 0; i < range_set->ranges->len; i++) {
1345 struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
1346 range_set, i);
1347
1348 if (is_signed) {
1349 status = bt_integer_range_set_signed_add_range(
1350 (void *) full_range_set, range->lower.i,
1351 range->upper.i);
1352 } else {
1353 status = bt_integer_range_set_unsigned_add_range(
1354 (void *) full_range_set, range->lower.u,
1355 range->upper.u);
1356 }
1357
1358 if (status) {
1359 goto end;
1360 }
1361 }
1362
1363 /* Check overlaps */
1364 if (is_signed) {
1365 *has_overlap = bt_integer_range_set_signed_has_overlaps(full_range_set);
1366 } else {
1367 *has_overlap = bt_integer_range_set_unsigned_has_overlaps(
1368 full_range_set);
1369 }
1370
1371end:
1372 bt_object_put_ref(full_range_set);
1373 return status;
1374}
1375
1376static
1377int append_option_to_variant_with_selector_field_class(
1378 struct bt_field_class *fc, const char *name,
1379 struct bt_field_class *option_fc,
1380 const struct bt_integer_range_set *range_set,
1381 enum bt_field_class_type expected_type)
5cd6d0e5 1382{
45c51519
PP
1383 int status;
1384 struct bt_field_class_variant_with_selector *var_fc = (void *) fc;
1385 struct bt_field_class_variant_with_selector_option *opt = NULL;
1386 bool has_overlap;
e5be10ef 1387
5cd6d0e5 1388 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
45c51519
PP
1389 BT_ASSERT_PRE_NON_NULL(name, "Name");
1390 BT_ASSERT_PRE_NON_NULL(option_fc, "Option field class");
6769570a 1391 BT_ASSERT_PRE_NON_NULL(range_set, "Integer range set");
45c51519
PP
1392 BT_ASSERT_PRE_FC_HAS_ID(fc, expected_type, "Field class");
1393 BT_ASSERT_PRE(range_set->ranges->len > 0,
6769570a 1394 "Integer range set is empty: %!+R", range_set);
45c51519
PP
1395 status = ranges_overlap(var_fc->common.common.named_fcs, range_set,
1396 expected_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
1397 &has_overlap);
1398 if (status) {
1399 /* ranges_overlap() logs errors */
1400 goto end;
1401 }
1402
1403 BT_ASSERT_PRE(!has_overlap,
6769570a
PP
1404 "Integer range set's ranges and existing ranges have an overlap: "
1405 "%!+R", range_set);
45c51519
PP
1406 opt = create_variant_with_selector_option(name, option_fc, range_set);
1407 if (!opt) {
1408 /* create_variant_with_selector_option() logs errors */
1409 status = BT_FUNC_STATUS_MEMORY_ERROR;
1410 goto end;
1411 }
1412
1413 status = append_named_field_class_to_container_field_class((void *) fc,
1414 &opt->common);
1415 if (status == BT_FUNC_STATUS_OK) {
1416 /* Moved to the container */
1417 opt = NULL;
1418 }
1419
1420end:
1421 if (opt) {
1422 destroy_variant_with_selector_option(opt);
1423 }
1424
1425 return status;
1426}
1427
1428enum bt_field_class_variant_with_selector_append_option_status
9c08c816 1429bt_field_class_variant_with_selector_unsigned_append_option(
45c51519
PP
1430 struct bt_field_class *fc, const char *name,
1431 struct bt_field_class *option_fc,
1432 const struct bt_integer_range_set_unsigned *range_set)
1433{
1434 return append_option_to_variant_with_selector_field_class(fc,
1435 name, option_fc, (const void *) range_set,
1436 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR);
1437}
1438
1439enum bt_field_class_variant_with_selector_append_option_status
9c08c816 1440bt_field_class_variant_with_selector_signed_append_option(
45c51519
PP
1441 struct bt_field_class *fc, const char *name,
1442 struct bt_field_class *option_fc,
1443 const struct bt_integer_range_set_signed *range_set)
1444{
1445 return append_option_to_variant_with_selector_field_class(fc,
1446 name, option_fc, (const void *) range_set,
1447 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR);
1448}
1449
1450uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc)
1451{
1452 const struct bt_field_class_variant *var_fc = (const void *) fc;
1453
1454 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1455 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
1456 return (uint64_t) var_fc->common.named_fcs->len;
5cd6d0e5
PP
1457}
1458
1e6fd1d7 1459const struct bt_field_class_variant_option *
7c06e353 1460bt_field_class_variant_borrow_option_by_name_const(
40f4ba76 1461 const struct bt_field_class *fc, const char *name)
5cd6d0e5 1462{
bdb288b3 1463 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
45c51519 1464 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
1e6fd1d7
PP
1465 return (const void *)
1466 borrow_named_field_class_from_container_field_class_by_name(
1467 (void *) fc, name);
740faaf4
PP
1468}
1469
45c51519
PP
1470const struct bt_field_class_variant_option *
1471bt_field_class_variant_borrow_option_by_index_const(
1472 const struct bt_field_class *fc, uint64_t index)
740faaf4 1473{
bdb288b3 1474 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
45c51519
PP
1475 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
1476 return (const void *)
1477 borrow_named_field_class_from_container_field_class_at_index(
c6fe8c40
PP
1478 (void *) fc, index);
1479}
1480
1481struct bt_field_class_variant_option *
1482bt_field_class_variant_borrow_option_by_name(
1483 struct bt_field_class *fc, const char *name)
1484{
1485 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1486 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
1487 return (void *)
1488 borrow_named_field_class_from_container_field_class_by_name(
1489 (void *) fc, name);
1490}
1491
1492struct bt_field_class_variant_option *
1493bt_field_class_variant_borrow_option_by_index(
1494 struct bt_field_class *fc, uint64_t index)
1495{
1496 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1497 BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
1498 return (void *)
1499 borrow_named_field_class_from_container_field_class_at_index(
45c51519 1500 (void *) fc, index);
e5be10ef
PP
1501}
1502
9c08c816
PP
1503const struct bt_field_class_variant_with_selector_unsigned_option *
1504bt_field_class_variant_with_selector_unsigned_borrow_option_by_name_const(
45c51519 1505 const struct bt_field_class *fc, const char *name)
5cd6d0e5 1506{
bdb288b3 1507 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
45c51519
PP
1508 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
1509 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
1510 "Field class");
1511 return (const void *)
1512 borrow_named_field_class_from_container_field_class_by_name(
1513 (void *) fc, name);
5cd6d0e5
PP
1514}
1515
9c08c816
PP
1516const struct bt_field_class_variant_with_selector_unsigned_option *
1517bt_field_class_variant_with_selector_unsigned_borrow_option_by_index_const(
1e6fd1d7 1518 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 1519{
bdb288b3 1520 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
45c51519
PP
1521 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
1522 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
1523 "Field class");
1e6fd1d7
PP
1524 return (const void *)
1525 borrow_named_field_class_from_container_field_class_at_index(
1526 (void *) fc, index);
740faaf4
PP
1527}
1528
9c08c816
PP
1529const struct bt_field_class_variant_with_selector_signed_option *
1530bt_field_class_variant_with_selector_signed_borrow_option_by_name_const(
45c51519 1531 const struct bt_field_class *fc, const char *name)
740faaf4 1532{
bdb288b3 1533 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
45c51519
PP
1534 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
1535 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
1536 "Field class");
1537 return (const void *)
1538 borrow_named_field_class_from_container_field_class_by_name(
1539 (void *) fc, name);
1540}
1541
9c08c816
PP
1542const struct bt_field_class_variant_with_selector_signed_option *
1543bt_field_class_variant_with_selector_signed_borrow_option_by_index_const(
45c51519
PP
1544 const struct bt_field_class *fc, uint64_t index)
1545{
1546 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1547 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
1548 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
1549 "Field class");
1550 return (const void *)
1e6fd1d7
PP
1551 borrow_named_field_class_from_container_field_class_at_index(
1552 (void *) fc, index);
1553}
1554
1555const char *bt_field_class_variant_option_get_name(
1556 const struct bt_field_class_variant_option *option)
1557{
1558 const struct bt_named_field_class *named_fc = (const void *) option;
1559
bdb288b3 1560 BT_ASSERT_PRE_DEV_NON_NULL(option, "Variant field class option");
1e6fd1d7
PP
1561 return named_fc->name->str;
1562}
1563
1564const struct bt_field_class *
1565bt_field_class_variant_option_borrow_field_class_const(
1566 const struct bt_field_class_variant_option *option)
1567{
1568 const struct bt_named_field_class *named_fc = (const void *) option;
1569
bdb288b3 1570 BT_ASSERT_PRE_DEV_NON_NULL(option, "Variant field class option");
1e6fd1d7
PP
1571 return named_fc->fc;
1572}
1573
45c51519 1574const struct bt_integer_range_set_unsigned *
9c08c816
PP
1575bt_field_class_variant_with_selector_unsigned_option_borrow_ranges_const(
1576 const struct bt_field_class_variant_with_selector_unsigned_option *option)
1e6fd1d7 1577{
45c51519
PP
1578 const struct bt_field_class_variant_with_selector_option *opt =
1579 (const void *) option;
1e6fd1d7 1580
bdb288b3 1581 BT_ASSERT_PRE_DEV_NON_NULL(option, "Variant field class option");
45c51519
PP
1582 return (const void *) opt->range_set;
1583}
1584
1585const struct bt_integer_range_set_signed *
9c08c816
PP
1586bt_field_class_variant_with_selector_signed_option_borrow_ranges_const(
1587 const struct bt_field_class_variant_with_selector_signed_option *option)
45c51519
PP
1588{
1589 const struct bt_field_class_variant_with_selector_option *opt =
1590 (const void *) option;
1591
1592 BT_ASSERT_PRE_DEV_NON_NULL(option, "Variant field class option");
1593 return (const void *) opt->range_set;
5cd6d0e5
PP
1594}
1595
40f4ba76 1596const struct bt_field_path *
45c51519 1597bt_field_class_variant_with_selector_borrow_selector_field_path_const(
40f4ba76 1598 const struct bt_field_class *fc)
e5be10ef 1599{
45c51519
PP
1600 const struct bt_field_class_variant_with_selector *var_fc =
1601 (const void *) fc;
5cd6d0e5 1602
bdb288b3 1603 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
45c51519 1604 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL(fc, "Field class");
5cd6d0e5
PP
1605 return var_fc->selector_field_path;
1606}
1607
1608static
1609void init_array_field_class(struct bt_field_class_array *fc,
864cad70 1610 enum bt_field_class_type type, bt_object_release_func release_func,
5cd6d0e5
PP
1611 struct bt_field_class *element_fc)
1612{
1613 BT_ASSERT(element_fc);
864cad70 1614 init_field_class((void *) fc, type, release_func);
398454ed 1615 fc->element_fc = element_fc;
45c51519 1616 bt_object_get_no_null_check(fc->element_fc);
5cd6d0e5
PP
1617 bt_field_class_freeze(element_fc);
1618}
1619
1620static
1621void finalize_array_field_class(struct bt_field_class_array *array_fc)
1622{
1623 BT_ASSERT(array_fc);
e5be10ef 1624 BT_LOGD_STR("Putting element field class.");
238b7404 1625 BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc);
5cd6d0e5
PP
1626}
1627
1628static
1629void destroy_static_array_field_class(struct bt_object *obj)
1630{
1631 BT_ASSERT(obj);
e5be10ef 1632 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj);
5cd6d0e5
PP
1633 finalize_array_field_class((void *) obj);
1634 g_free(obj);
1635}
1636
40f4ba76 1637struct bt_field_class *
9c08c816 1638bt_field_class_array_static_create(bt_trace_class *trace_class,
1122a43a 1639 struct bt_field_class *element_fc, uint64_t length)
5cd6d0e5 1640{
9c08c816 1641 struct bt_field_class_array_static *array_fc = NULL;
5cd6d0e5 1642
1122a43a 1643 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef
PP
1644 BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class");
1645 BT_LOGD_STR("Creating default static array field class object.");
9c08c816 1646 array_fc = g_new0(struct bt_field_class_array_static, 1);
5cd6d0e5 1647 if (!array_fc) {
870631a2
PP
1648 BT_LIB_LOGE_APPEND_CAUSE(
1649 "Failed to allocate one static array field class.");
5cd6d0e5
PP
1650 goto error;
1651 }
1652
864cad70 1653 init_array_field_class((void *) array_fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
5cd6d0e5
PP
1654 destroy_static_array_field_class, element_fc);
1655 array_fc->length = length;
e5be10ef 1656 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc);
5cd6d0e5
PP
1657 goto end;
1658
1659error:
65300d60 1660 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
5cd6d0e5
PP
1661
1662end:
1663 return (void *) array_fc;
1664}
1665
40f4ba76
PP
1666const struct bt_field_class *
1667bt_field_class_array_borrow_element_field_class_const(
1668 const struct bt_field_class *fc)
5cd6d0e5 1669{
40f4ba76 1670 const struct bt_field_class_array *array_fc = (const void *) fc;
5cd6d0e5 1671
bdb288b3
PP
1672 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1673 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc, "Field class");
5cd6d0e5
PP
1674 return array_fc->element_fc;
1675}
1676
740faaf4
PP
1677struct bt_field_class *
1678bt_field_class_array_borrow_element_field_class(struct bt_field_class *fc)
1679{
1680 struct bt_field_class_array *array_fc = (void *) fc;
1681
bdb288b3
PP
1682 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1683 BT_ASSERT_PRE_DEV_FC_IS_ARRAY(fc, "Field class");
740faaf4
PP
1684 return array_fc->element_fc;
1685}
1686
9c08c816 1687uint64_t bt_field_class_array_static_get_length(const struct bt_field_class *fc)
e5be10ef 1688{
9c08c816 1689 const struct bt_field_class_array_static *array_fc = (const void *) fc;
5cd6d0e5 1690
bdb288b3
PP
1691 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1692 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
5cd6d0e5
PP
1693 "Field class");
1694 return (uint64_t) array_fc->length;
1695}
1696
1697static
1698void destroy_dynamic_array_field_class(struct bt_object *obj)
1699{
9c08c816 1700 struct bt_field_class_array_dynamic *fc = (void *) obj;
5cd6d0e5
PP
1701
1702 BT_ASSERT(fc);
e5be10ef 1703 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc);
5cd6d0e5
PP
1704 finalize_array_field_class((void *) fc);
1705 BT_LOGD_STR("Putting length field path.");
238b7404
PP
1706 BT_OBJECT_PUT_REF_AND_RESET(fc->length_field_path);
1707 BT_LOGD_STR("Putting length field class.");
1708 BT_OBJECT_PUT_REF_AND_RESET(fc->length_fc);
5cd6d0e5
PP
1709 g_free(fc);
1710}
1711
9c08c816 1712struct bt_field_class *bt_field_class_array_dynamic_create(
1367bc7c
PP
1713 struct bt_trace_class *trace_class,
1714 struct bt_field_class *element_fc,
1715 struct bt_field_class *length_fc)
5cd6d0e5 1716{
9c08c816 1717 struct bt_field_class_array_dynamic *array_fc = NULL;
5cd6d0e5 1718
1122a43a 1719 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef
PP
1720 BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class");
1721 BT_LOGD_STR("Creating default dynamic array field class object.");
9c08c816 1722 array_fc = g_new0(struct bt_field_class_array_dynamic, 1);
5cd6d0e5 1723 if (!array_fc) {
870631a2
PP
1724 BT_LIB_LOGE_APPEND_CAUSE(
1725 "Failed to allocate one dynamic array field class.");
5cd6d0e5
PP
1726 goto error;
1727 }
1728
40f4ba76
PP
1729 init_array_field_class((void *) array_fc,
1730 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
5cd6d0e5 1731 destroy_dynamic_array_field_class, element_fc);
1367bc7c
PP
1732
1733 if (length_fc) {
1734 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc,
1735 "Length field class");
1736 array_fc->length_fc = length_fc;
1737 bt_object_get_no_null_check(array_fc->length_fc);
1738 bt_field_class_freeze(length_fc);
1739 }
1740
e5be10ef 1741 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc);
5cd6d0e5
PP
1742 goto end;
1743
1744error:
65300d60 1745 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
5cd6d0e5
PP
1746
1747end:
1748 return (void *) array_fc;
1749}
1750
40f4ba76 1751const struct bt_field_path *
9c08c816 1752bt_field_class_array_dynamic_borrow_length_field_path_const(
40f4ba76 1753 const struct bt_field_class *fc)
5cd6d0e5 1754{
9c08c816 1755 const struct bt_field_class_array_dynamic *seq_fc = (const void *) fc;
5cd6d0e5 1756
bdb288b3
PP
1757 BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
1758 BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
5cd6d0e5
PP
1759 "Field class");
1760 return seq_fc->length_field_path;
1761}
1762
1763static
1764void destroy_string_field_class(struct bt_object *obj)
1765{
1766 BT_ASSERT(obj);
e5be10ef 1767 BT_LIB_LOGD("Destroying string field class object: %!+F", obj);
5cd6d0e5
PP
1768 g_free(obj);
1769}
1770
1122a43a 1771struct bt_field_class *bt_field_class_string_create(bt_trace_class *trace_class)
5cd6d0e5
PP
1772{
1773 struct bt_field_class_string *string_fc = NULL;
1774
1122a43a 1775 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 1776 BT_LOGD_STR("Creating default string field class object.");
5cd6d0e5
PP
1777 string_fc = g_new0(struct bt_field_class_string, 1);
1778 if (!string_fc) {
870631a2
PP
1779 BT_LIB_LOGE_APPEND_CAUSE(
1780 "Failed to allocate one string field class.");
5cd6d0e5
PP
1781 goto error;
1782 }
1783
864cad70 1784 init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING,
5cd6d0e5 1785 destroy_string_field_class);
e5be10ef 1786 BT_LIB_LOGD("Created string field class object: %!+F", string_fc);
5cd6d0e5
PP
1787 goto end;
1788
1789error:
65300d60 1790 BT_OBJECT_PUT_REF_AND_RESET(string_fc);
5cd6d0e5
PP
1791
1792end:
1793 return (void *) string_fc;
1794}
1795
1796BT_HIDDEN
1e6fd1d7 1797void _bt_field_class_freeze(const struct bt_field_class *c_fc)
5cd6d0e5 1798{
1e6fd1d7
PP
1799 struct bt_field_class *fc = (void *) c_fc;
1800
5cd6d0e5
PP
1801 /*
1802 * Element/member/option field classes are frozen when added to
1803 * their owner.
1804 */
1805 BT_ASSERT(fc);
1e6fd1d7
PP
1806 fc->frozen = true;
1807
1808 switch (fc->type) {
1809 case BT_FIELD_CLASS_TYPE_STRUCTURE:
45c51519
PP
1810 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
1811 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
1812 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
1e6fd1d7
PP
1813 {
1814 struct bt_field_class_named_field_class_container *container_fc =
1815 (void *) fc;
1816 uint64_t i;
1817
1818 for (i = 0; i < container_fc->named_fcs->len; i++) {
45c51519
PP
1819 bt_named_field_class_freeze(
1820 container_fc->named_fcs->pdata[i]);
1e6fd1d7
PP
1821 }
1822
1823 break;
1824 }
1825 default:
1826 break;
1827 }
1828}
1829
1830BT_HIDDEN
1831void _bt_named_field_class_freeze(const struct bt_named_field_class *named_fc)
1832{
1833 BT_ASSERT(named_fc);
1834 ((struct bt_named_field_class *) named_fc)->frozen = true;
1835 bt_field_class_freeze(named_fc->fc);
5cd6d0e5
PP
1836}
1837
1838BT_HIDDEN
bdb288b3 1839void bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc)
5cd6d0e5 1840{
40f4ba76
PP
1841 struct bt_field_class *fc = (void *) c_fc;
1842
5cd6d0e5 1843 BT_ASSERT(fc);
862ca4ed 1844 BT_ASSERT_PRE(!fc->part_of_trace_class,
5cd6d0e5 1845 "Field class is already part of a trace: %!+F", fc);
862ca4ed 1846 fc->part_of_trace_class = true;
5cd6d0e5 1847
864cad70
PP
1848 switch (fc->type) {
1849 case BT_FIELD_CLASS_TYPE_STRUCTURE:
45c51519
PP
1850 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
1851 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
1852 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
5cd6d0e5
PP
1853 {
1854 struct bt_field_class_named_field_class_container *container_fc =
1855 (void *) fc;
1856 uint64_t i;
1857
1858 for (i = 0; i < container_fc->named_fcs->len; i++) {
1859 struct bt_named_field_class *named_fc =
45c51519 1860 container_fc->named_fcs->pdata[i];
5cd6d0e5 1861
862ca4ed 1862 bt_field_class_make_part_of_trace_class(named_fc->fc);
5cd6d0e5
PP
1863 }
1864
1865 break;
1866 }
864cad70
PP
1867 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
1868 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
5cd6d0e5
PP
1869 {
1870 struct bt_field_class_array *array_fc = (void *) fc;
1871
862ca4ed 1872 bt_field_class_make_part_of_trace_class(array_fc->element_fc);
5cd6d0e5
PP
1873 break;
1874 }
1875 default:
1876 break;
1877 }
1878}
c5b9b441
PP
1879
1880void bt_field_class_get_ref(const struct bt_field_class *field_class)
1881{
1882 bt_object_get_ref(field_class);
1883}
1884
1885void bt_field_class_put_ref(const struct bt_field_class *field_class)
1886{
1887 bt_object_put_ref(field_class);
1888}
This page took 0.131473 seconds and 4 git commands to generate.