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