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