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