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