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