.gitignore: add some missing files
[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 "common/common.h"
20 #include "compat/glib.h"
21 #include <inttypes.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24
25 #include "field-class.h"
26 #include "field-path.h"
27 #include "lib/func-status.h"
28 #include "lib/integer-range-set.h"
29 #include "lib/value.h"
30 #include "lib/trace-ir/trace-class.h"
31
32 BT_EXPORT
33 enum bt_field_class_type bt_field_class_get_type(
34 const struct bt_field_class *fc)
35 {
36 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
37 return fc->type;
38 }
39
40 static
41 int init_field_class(struct bt_field_class *fc, enum bt_field_class_type type,
42 bt_object_release_func release_func,
43 const struct bt_trace_class *trace_class)
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 fc->mip_version = trace_class->mip_version;
60
61 end:
62 return ret;
63 }
64
65 static
66 void finalize_field_class(struct bt_field_class *fc)
67 {
68 BT_OBJECT_PUT_REF_AND_RESET(fc->user_attributes);
69 }
70
71 #define _BT_ASSERT_PRE_BIT_ARRAY_FC_FLAG_NAME "Bit array field class flag"
72 #define _BT_ASSERT_PRE_BIT_ARRAY_FC_FLAG_ID "bit-array-field-class-flag"
73
74 #define BT_ASSERT_PRE_DEV_BIT_ARRAY_FC_FLAG_NON_NULL(_flag) \
75 BT_ASSERT_PRE_DEV_NON_NULL( \
76 _BT_ASSERT_PRE_BIT_ARRAY_FC_FLAG_ID, (_flag), \
77 _BT_ASSERT_PRE_BIT_ARRAY_FC_FLAG_NAME)
78
79 static
80 void destroy_bit_array_field_class(struct bt_object *obj)
81 {
82 const struct bt_field_class_bit_array *ba_fc;
83
84 BT_ASSERT(obj);
85 BT_LIB_LOGD("Destroying bit array field class object: %!+F", obj);
86
87 ba_fc = (const void *) obj;
88
89 if (ba_fc->flags) {
90 g_ptr_array_free(ba_fc->flags, TRUE);
91 }
92
93 finalize_field_class((void *) obj);
94 g_free(obj);
95 }
96
97 static
98 void destroy_bit_array_flag(struct bt_field_class_bit_array_flag *flag)
99 {
100 if (!flag) {
101 goto end;
102 }
103
104 g_free(flag->label);
105 bt_object_put_ref(flag->range_set);
106 g_free(flag);
107
108 end:
109 return;
110 }
111
112 static
113 void destroy_bit_array_flag_void(gpointer ptr)
114 {
115 destroy_bit_array_flag((struct bt_field_class_bit_array_flag *) ptr);
116 }
117
118 BT_EXPORT
119 struct bt_field_class *bt_field_class_bit_array_create(
120 struct bt_trace_class *trace_class, uint64_t length)
121 {
122 struct bt_field_class_bit_array *ba_fc = NULL;
123
124 BT_ASSERT_PRE_NO_ERROR();
125 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
126 BT_ASSERT_PRE("valid-length", length > 0 && length <= 64,
127 "Unsupported length for bit array field class "
128 "(minimum is 1, maximum is 64): length=%" PRIu64, length);
129 BT_LOGD("Creating default bit array field class object.");
130 ba_fc = g_new0(struct bt_field_class_bit_array, 1);
131 if (!ba_fc) {
132 BT_LIB_LOGE_APPEND_CAUSE(
133 "Failed to allocate one bit array field class.");
134 goto error;
135 }
136
137 if (init_field_class((void *) ba_fc, BT_FIELD_CLASS_TYPE_BIT_ARRAY,
138 destroy_bit_array_field_class, trace_class)) {
139 goto error;
140 }
141
142 ba_fc->length = length;
143 ba_fc->flags = g_ptr_array_new_with_free_func(
144 destroy_bit_array_flag_void);
145 if (!ba_fc->flags) {
146 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
147 goto error;
148 }
149
150 BT_LIB_LOGD("Created bit array field class object: %!+F", ba_fc);
151 goto end;
152
153 error:
154 BT_OBJECT_PUT_REF_AND_RESET(ba_fc);
155
156 end:
157 return (void *) ba_fc;
158 }
159
160 BT_EXPORT
161 uint64_t bt_field_class_bit_array_get_length(const struct bt_field_class *fc)
162 {
163 const struct bt_field_class_bit_array *ba_fc = (const void *) fc;
164
165 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
166 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
167 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
168 return ba_fc->length;
169 }
170
171 BT_EXPORT
172 uint64_t bt_field_class_bit_array_get_flag_count(const bt_field_class *fc)
173 {
174 const struct bt_field_class_bit_array *ba_fc = (const void *) fc;
175
176 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
177 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
178 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
179 return ba_fc->flags->len;
180 }
181
182 BT_EXPORT
183 bt_field_class_bit_array_add_flag_status bt_field_class_bit_array_add_flag(
184 struct bt_field_class *fc, const char *label,
185 const bt_integer_range_set_unsigned *index_ranges)
186 {
187 struct bt_field_class_bit_array *ba_fc = (void *) fc;
188 struct bt_field_class_bit_array_flag *flag = NULL;
189 bt_field_class_bit_array_add_flag_status status;
190 struct bt_integer_range_set *index_ranges_internal =
191 (bt_integer_range_set *) index_ranges;
192 guint range_i;
193
194 BT_ASSERT_PRE_NO_ERROR();
195 BT_ASSERT_PRE_FC_NON_NULL(fc);
196 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc, "bit-array",
197 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
198 BT_ASSERT_PRE_NON_NULL("label", label, "Label");
199 BT_ASSERT_PRE("bit-array-field-class-flag-label-is-unique",
200 !bt_field_class_bit_array_borrow_flag_by_label_const(fc, label),
201 "Duplicate flag name in bit array field class: "
202 "%![bit-array-fc-]+F, label=\"%s\"", fc, label);
203 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(index_ranges);
204
205 for (range_i = 0; range_i < index_ranges_internal->ranges->len; ++range_i) {
206 struct bt_integer_range *range
207 = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(index_ranges_internal,
208 range_i);
209
210 BT_ASSERT_PRE("bit-array-field-class-flag-bit-index-is-less-than-field-class-length",
211 range->upper.u < ba_fc->length,
212 "Flag bit index range's upper bound is greater than or "
213 "equal to bit array field length: %![bit-array-fc-]+F, "
214 "range-index=%u, upper-bound=%" PRIu64,
215 ba_fc, range_i, range->upper.u);
216 }
217
218 flag = g_new0(struct bt_field_class_bit_array_flag, 1);
219 if (!flag) {
220 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a bit_array_flag.");
221 status = BT_FIELD_CLASS_BIT_ARRAY_ADD_FLAG_STATUS_MEMORY_ERROR;
222 goto end;
223 }
224
225 flag->label = g_strdup(label);
226 if (!flag->label) {
227 BT_LIB_LOGE_APPEND_CAUSE(
228 "Failed to allocate memory for bit array flag label.");
229 status = BT_FIELD_CLASS_BIT_ARRAY_ADD_FLAG_STATUS_MEMORY_ERROR;
230 goto end;
231 }
232
233 flag->range_set = index_ranges;
234 bt_integer_range_set_unsigned_get_ref(flag->range_set);
235
236 /* Set flag->mask */
237 for (range_i = 0; range_i < index_ranges_internal->ranges->len; range_i++) {
238 const struct bt_integer_range *range = (const void *)
239 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(index_ranges_internal,
240 range_i);
241 uint64_t bit_index;
242
243 for (bit_index = range->lower.u; bit_index <= range->upper.u;
244 ++bit_index) {
245 flag->mask |= UINT64_C(1) << bit_index;
246 }
247 }
248
249 g_ptr_array_add(ba_fc->flags, flag);
250 flag = NULL;
251
252 status = BT_FIELD_CLASS_BIT_ARRAY_ADD_FLAG_STATUS_OK;
253 goto end;
254
255 end:
256 destroy_bit_array_flag(flag);
257 return status;
258 }
259
260 BT_EXPORT
261 const bt_field_class_bit_array_flag *
262 bt_field_class_bit_array_borrow_flag_by_index_const(
263 const struct bt_field_class *fc, uint64_t index)
264 {
265 struct bt_field_class_bit_array *ba_fc = (void *) fc;
266
267 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
268 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
269 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
270 BT_ASSERT_PRE_DEV_VALID_INDEX(index, ba_fc->flags->len);
271 return ba_fc->flags->pdata[index];
272 }
273
274 BT_EXPORT
275 const bt_field_class_bit_array_flag *
276 bt_field_class_bit_array_borrow_flag_by_label_const(
277 const struct bt_field_class *fc, const char *label)
278 {
279 struct bt_field_class_bit_array *ba_fc = (void *) fc;
280 const struct bt_field_class_bit_array_flag *flag = NULL;
281 uint64_t i;
282
283 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
284 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
285 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
286 BT_ASSERT_PRE_DEV_NON_NULL("label", label, "Label");
287
288 for (i = 0; i < ba_fc->flags->len; i++) {
289 const struct bt_field_class_bit_array_flag *candidate =
290 ba_fc->flags->pdata[i];
291
292 if (strcmp(candidate->label, label) == 0) {
293 flag = candidate;
294 break;
295 }
296 }
297
298 return flag;
299 }
300
301 BT_EXPORT
302 bt_field_class_bit_array_get_active_flag_labels_for_value_as_integer_status
303 bt_field_class_bit_array_get_active_flag_labels_for_value_as_integer(
304 const struct bt_field_class *fc, uint64_t value_as_integer,
305 bt_field_class_bit_array_flag_label_array *label_array,
306 uint64_t *count)
307 {
308 struct bt_field_class_bit_array *ba_fc = (void *) fc;
309 uint64_t i;
310
311 BT_ASSERT_PRE_DEV_NO_ERROR();
312 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
313 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "bit-array",
314 BT_FIELD_CLASS_TYPE_BIT_ARRAY, "Field class");
315 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
316 "Label array (output)");
317 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
318
319 g_ptr_array_set_size(ba_fc->label_buf, 0);
320
321 for (i = 0; i < ba_fc->flags->len; ++i) {
322 const struct bt_field_class_bit_array_flag *flag =
323 ba_fc->flags->pdata[i];
324
325 if (value_as_integer & flag->mask) {
326 g_ptr_array_add(ba_fc->label_buf, flag->label);
327 }
328 }
329
330 *label_array = (void *) ba_fc->label_buf->pdata;
331 *count = (uint64_t) ba_fc->label_buf->len;
332
333 return BT_FIELD_CLASS_BIT_ARRAY_GET_ACTIVE_FLAG_LABELS_FOR_VALUE_AS_INTEGER_STATUS_OK;
334 }
335
336 BT_EXPORT
337 const char *bt_field_class_bit_array_flag_get_label(
338 const struct bt_field_class_bit_array_flag *flag)
339 {
340 BT_ASSERT_PRE_DEV_BIT_ARRAY_FC_FLAG_NON_NULL(flag);
341
342 return flag->label;
343 }
344
345 BT_EXPORT
346 const bt_integer_range_set_unsigned *
347 bt_field_class_bit_array_flag_borrow_index_ranges_const(
348 const struct bt_field_class_bit_array_flag *flag)
349 {
350 BT_ASSERT_PRE_DEV_BIT_ARRAY_FC_FLAG_NON_NULL(flag);
351
352 return flag->range_set;
353 }
354
355 static
356 void destroy_bool_field_class(struct bt_object *obj)
357 {
358 BT_ASSERT(obj);
359 BT_LIB_LOGD("Destroying boolean field class object: %!+F", obj);
360 finalize_field_class((void *) obj);
361 g_free(obj);
362 }
363
364 BT_EXPORT
365 struct bt_field_class *bt_field_class_bool_create(
366 bt_trace_class *trace_class)
367 {
368 struct bt_field_class_bool *bool_fc = NULL;
369
370 BT_ASSERT_PRE_NO_ERROR();
371 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
372 BT_LOGD("Creating default boolean field class object.");
373 bool_fc = g_new0(struct bt_field_class_bool, 1);
374 if (!bool_fc) {
375 BT_LIB_LOGE_APPEND_CAUSE(
376 "Failed to allocate one boolean field class.");
377 goto error;
378 }
379
380 if (init_field_class((void *) bool_fc, BT_FIELD_CLASS_TYPE_BOOL,
381 destroy_bool_field_class, trace_class)) {
382 goto error;
383 }
384
385 BT_LIB_LOGD("Created boolean field class object: %!+F", bool_fc);
386 goto end;
387
388 error:
389 BT_OBJECT_PUT_REF_AND_RESET(bool_fc);
390
391 end:
392 return (void *) bool_fc;
393 }
394
395 static
396 int init_integer_field_class(struct bt_field_class_integer *fc,
397 enum bt_field_class_type type,
398 bt_object_release_func release_func,
399 const struct bt_trace_class *trace_class)
400 {
401 int ret;
402
403 ret = init_field_class((void *) fc, type, release_func,
404 trace_class);
405 if (ret) {
406 goto end;
407 }
408
409 fc->range = 64;
410 fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
411
412 end:
413 return ret;
414 }
415
416 static
417 void destroy_integer_field_class(struct bt_object *obj)
418 {
419 BT_ASSERT(obj);
420 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj);
421 finalize_field_class((void *) obj);
422 g_free(obj);
423 }
424
425 static inline
426 struct bt_field_class *create_integer_field_class(bt_trace_class *trace_class,
427 enum bt_field_class_type type)
428 {
429 struct bt_field_class_integer *int_fc = NULL;
430
431 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
432 BT_LOGD("Creating default integer field class object: type=%s",
433 bt_common_field_class_type_string(type));
434 int_fc = g_new0(struct bt_field_class_integer, 1);
435 if (!int_fc) {
436 BT_LIB_LOGE_APPEND_CAUSE(
437 "Failed to allocate one integer field class.");
438 goto error;
439 }
440
441 if (init_integer_field_class(int_fc, type,
442 destroy_integer_field_class, trace_class)) {
443 goto error;
444 }
445
446 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc);
447 goto end;
448
449 error:
450 BT_OBJECT_PUT_REF_AND_RESET(int_fc);
451
452 end:
453 return (void *) int_fc;
454 }
455
456 BT_EXPORT
457 struct bt_field_class *bt_field_class_integer_unsigned_create(
458 bt_trace_class *trace_class)
459 {
460 BT_ASSERT_PRE_NO_ERROR();
461
462 return create_integer_field_class(trace_class,
463 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER);
464 }
465
466 BT_EXPORT
467 struct bt_field_class *bt_field_class_integer_signed_create(
468 bt_trace_class *trace_class)
469 {
470 BT_ASSERT_PRE_NO_ERROR();
471
472 return create_integer_field_class(trace_class,
473 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER);
474 }
475
476 BT_EXPORT
477 uint64_t bt_field_class_integer_get_field_value_range(
478 const struct bt_field_class *fc)
479 {
480 const struct bt_field_class_integer *int_fc = (const void *) fc;
481
482 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
483 BT_ASSERT_PRE_DEV_FC_IS_INT("field-class", fc, "Field class");
484 return int_fc->range;
485 }
486
487 static
488 bool size_is_valid_for_enumeration_field_class(
489 struct bt_field_class *fc __attribute__((unused)),
490 uint64_t size __attribute__((unused)))
491 {
492 // TODO
493 return true;
494 }
495
496 BT_EXPORT
497 void bt_field_class_integer_set_field_value_range(
498 struct bt_field_class *fc, uint64_t size)
499 {
500 struct bt_field_class_integer *int_fc = (void *) fc;
501
502 BT_ASSERT_PRE_FC_NON_NULL(fc);
503 BT_ASSERT_PRE_FC_IS_INT("field-class", fc, "Field class");
504 BT_ASSERT_PRE_DEV_FC_HOT(fc);
505 BT_ASSERT_PRE("valid-n",
506 size >= 1 && size <= 64,
507 "Unsupported size for integer field class's field value range "
508 "(minimum is 1, maximum is 64): size=%" PRIu64, size);
509 BT_ASSERT_PRE("valid-n-for-enumeration-field-class",
510 int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
511 int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
512 size_is_valid_for_enumeration_field_class(fc, size),
513 "Invalid field value range for enumeration field class: "
514 "at least one of the current mapping ranges contains values "
515 "which are outside this range: %!+F, size=%" PRIu64, fc, size);
516 int_fc->range = size;
517 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc);
518 }
519
520 BT_EXPORT
521 enum bt_field_class_integer_preferred_display_base
522 bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc)
523 {
524 const struct bt_field_class_integer *int_fc = (const void *) fc;
525
526 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
527 BT_ASSERT_PRE_DEV_FC_IS_INT("field-class", fc, "Field class");
528 return int_fc->base;
529 }
530
531 BT_EXPORT
532 void bt_field_class_integer_set_preferred_display_base(
533 struct bt_field_class *fc,
534 enum bt_field_class_integer_preferred_display_base base)
535 {
536 struct bt_field_class_integer *int_fc = (void *) fc;
537
538 BT_ASSERT_PRE_FC_NON_NULL(fc);
539 BT_ASSERT_PRE_FC_IS_INT("field-class", fc, "Field class");
540 BT_ASSERT_PRE_DEV_FC_HOT(fc);
541 int_fc->base = base;
542 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc);
543 }
544
545 static
546 void finalize_enumeration_field_class_mapping(
547 struct bt_field_class_enumeration_mapping *mapping)
548 {
549 BT_ASSERT(mapping);
550
551 if (mapping->label) {
552 g_string_free(mapping->label, TRUE);
553 mapping->label = NULL;
554 }
555
556 BT_OBJECT_PUT_REF_AND_RESET(mapping->range_set);
557 }
558
559 static
560 void destroy_enumeration_field_class(struct bt_object *obj)
561 {
562 struct bt_field_class_enumeration *fc = (void *) obj;
563
564 BT_ASSERT(fc);
565 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc);
566 finalize_field_class((void *) obj);
567
568 if (fc->mappings) {
569 uint64_t i;
570
571 for (i = 0; i < fc->mappings->len; i++) {
572 finalize_enumeration_field_class_mapping(
573 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i));
574 }
575
576 g_array_free(fc->mappings, TRUE);
577 fc->mappings = NULL;
578 }
579
580 if (fc->label_buf) {
581 g_ptr_array_free(fc->label_buf, TRUE);
582 fc->label_buf = NULL;
583 }
584
585 g_free(fc);
586 }
587
588 static
589 struct bt_field_class *create_enumeration_field_class(
590 bt_trace_class *trace_class, enum bt_field_class_type type)
591 {
592 struct bt_field_class_enumeration *enum_fc = NULL;
593
594 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
595 BT_LOGD("Creating default enumeration field class object: type=%s",
596 bt_common_field_class_type_string(type));
597 enum_fc = g_new0(struct bt_field_class_enumeration, 1);
598 if (!enum_fc) {
599 BT_LIB_LOGE_APPEND_CAUSE(
600 "Failed to allocate one enumeration field class.");
601 goto error;
602 }
603
604 if (init_integer_field_class((void *) enum_fc, type,
605 destroy_enumeration_field_class, trace_class)) {
606 goto error;
607 }
608
609 enum_fc->mappings = g_array_new(FALSE, TRUE,
610 sizeof(struct bt_field_class_enumeration_mapping));
611 if (!enum_fc->mappings) {
612 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
613 goto error;
614 }
615
616 enum_fc->label_buf = g_ptr_array_new();
617 if (!enum_fc->label_buf) {
618 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
619 goto error;
620 }
621
622 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc);
623 goto end;
624
625 error:
626 BT_OBJECT_PUT_REF_AND_RESET(enum_fc);
627
628 end:
629 return (void *) enum_fc;
630 }
631
632 BT_EXPORT
633 struct bt_field_class *bt_field_class_enumeration_unsigned_create(
634 bt_trace_class *trace_class)
635 {
636 BT_ASSERT_PRE_NO_ERROR();
637
638 return create_enumeration_field_class(trace_class,
639 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION);
640 }
641
642 BT_EXPORT
643 struct bt_field_class *bt_field_class_enumeration_signed_create(
644 bt_trace_class *trace_class)
645 {
646 BT_ASSERT_PRE_NO_ERROR();
647
648 return create_enumeration_field_class(trace_class,
649 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
650 }
651
652 BT_EXPORT
653 uint64_t bt_field_class_enumeration_get_mapping_count(
654 const struct bt_field_class *fc)
655 {
656 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
657
658 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
659 BT_ASSERT_PRE_DEV_FC_IS_ENUM("field-class", fc, "Field class");
660 return (uint64_t) enum_fc->mappings->len;
661 }
662
663 BT_EXPORT
664 const struct bt_field_class_enumeration_unsigned_mapping *
665 bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
666 const struct bt_field_class *fc, uint64_t index)
667 {
668 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
669
670 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
671 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
672 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
673 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
674 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
675 }
676
677 BT_EXPORT
678 const struct bt_field_class_enumeration_signed_mapping *
679 bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
680 const struct bt_field_class *fc, uint64_t index)
681 {
682 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
683
684 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
685 BT_ASSERT_PRE_DEV_VALID_INDEX(index, enum_fc->mappings->len);
686 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
687 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
688 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
689 }
690
691 static
692 const struct bt_field_class_enumeration_mapping *
693 borrow_enumeration_field_class_mapping_by_label(
694 const struct bt_field_class_enumeration *fc, const char *label,
695 const char *api_func)
696 {
697 struct bt_field_class_enumeration_mapping *mapping = NULL;
698 uint64_t i;
699
700 BT_ASSERT_DBG(fc);
701 BT_ASSERT_PRE_DEV_NON_NULL_FROM_FUNC(api_func, "label", label,
702 "Label");
703
704 for (i = 0; i < fc->mappings->len; i++) {
705 struct bt_field_class_enumeration_mapping *this_mapping =
706 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i);
707
708 if (strcmp(this_mapping->label->str, label) == 0) {
709 mapping = this_mapping;
710 goto end;
711 }
712 }
713
714 end:
715 return mapping;
716 }
717
718 BT_EXPORT
719 const struct bt_field_class_enumeration_signed_mapping *
720 bt_field_class_enumeration_signed_borrow_mapping_by_label_const(
721 const struct bt_field_class *fc, const char *label)
722 {
723 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
724 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
725 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
726 return (const void *) borrow_enumeration_field_class_mapping_by_label(
727 (const void *) fc, label, __func__);
728 }
729
730 BT_EXPORT
731 const struct bt_field_class_enumeration_unsigned_mapping *
732 bt_field_class_enumeration_unsigned_borrow_mapping_by_label_const(
733 const struct bt_field_class *fc, const char *label)
734 {
735 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
736 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
737 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
738 return (const void *) borrow_enumeration_field_class_mapping_by_label(
739 (const void *) fc, label, __func__);
740 }
741
742 BT_EXPORT
743 const char *bt_field_class_enumeration_mapping_get_label(
744 const struct bt_field_class_enumeration_mapping *mapping)
745 {
746 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
747 mapping, "Enumeration field class mapping");
748 return mapping->label->str;
749 }
750
751 BT_EXPORT
752 const struct bt_integer_range_set_unsigned *
753 bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
754 const struct bt_field_class_enumeration_unsigned_mapping *u_mapping)
755 {
756 const struct bt_field_class_enumeration_mapping *mapping =
757 (const void *) u_mapping;
758
759 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
760 mapping, "Enumeration field class mapping");
761 return (const void *) mapping->range_set;
762 }
763
764 BT_EXPORT
765 const struct bt_integer_range_set_signed *
766 bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
767 const struct bt_field_class_enumeration_signed_mapping *s_mapping)
768 {
769 const struct bt_field_class_enumeration_mapping *mapping =
770 (const void *) s_mapping;
771
772 BT_ASSERT_PRE_DEV_NON_NULL("enumeration-field-class-mapping",
773 mapping, "Enumeration field class mapping");
774 return (const void *) mapping->range_set;
775 }
776
777 BT_EXPORT
778 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
779 bt_field_class_enumeration_unsigned_get_mapping_labels_for_value(
780 const struct bt_field_class *fc, uint64_t value,
781 bt_field_class_enumeration_mapping_label_array *label_array,
782 uint64_t *count)
783 {
784 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
785 uint64_t i;
786
787 BT_ASSERT_PRE_DEV_NO_ERROR();
788 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
789 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
790 "Label array (output)");
791 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
792 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "unsigned-enumeration",
793 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
794 g_ptr_array_set_size(enum_fc->label_buf, 0);
795
796 for (i = 0; i < enum_fc->mappings->len; i++) {
797 uint64_t j;
798 const struct bt_field_class_enumeration_mapping *mapping =
799 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
800
801 for (j = 0; j < mapping->range_set->ranges->len; j++) {
802 const struct bt_integer_range *range = (const void *)
803 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
804 mapping->range_set, j);
805
806 if (value >= range->lower.u &&
807 value <= range->upper.u) {
808 g_ptr_array_add(enum_fc->label_buf,
809 mapping->label->str);
810 break;
811 }
812 }
813 }
814
815 *label_array = (void *) enum_fc->label_buf->pdata;
816 *count = (uint64_t) enum_fc->label_buf->len;
817 return BT_FUNC_STATUS_OK;
818 }
819
820 BT_EXPORT
821 enum bt_field_class_enumeration_get_mapping_labels_for_value_status
822 bt_field_class_enumeration_signed_get_mapping_labels_for_value(
823 const struct bt_field_class *fc, int64_t value,
824 bt_field_class_enumeration_mapping_label_array *label_array,
825 uint64_t *count)
826 {
827 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
828 uint64_t i;
829
830 BT_ASSERT_PRE_DEV_NO_ERROR();
831 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
832 BT_ASSERT_PRE_DEV_NON_NULL("label-array-output", label_array,
833 "Label array (output)");
834 BT_ASSERT_PRE_DEV_NON_NULL("count-output", count, "Count (output)");
835 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc, "signed-enumeration",
836 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
837 g_ptr_array_set_size(enum_fc->label_buf, 0);
838
839 for (i = 0; i < enum_fc->mappings->len; i++) {
840 uint64_t j;
841 const struct bt_field_class_enumeration_mapping *mapping =
842 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
843
844 for (j = 0; j < mapping->range_set->ranges->len; j++) {
845 const struct bt_integer_range *range = (const void *)
846 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
847 mapping->range_set, j);
848
849 if (value >= range->lower.i &&
850 value <= range->upper.i) {
851 g_ptr_array_add(enum_fc->label_buf,
852 mapping->label->str);
853 break;
854 }
855 }
856 }
857
858 *label_array = (void *) enum_fc->label_buf->pdata;
859 *count = (uint64_t) enum_fc->label_buf->len;
860 return BT_FUNC_STATUS_OK;
861 }
862
863 static
864 bool enumeration_field_class_has_mapping_with_label(
865 const struct bt_field_class_enumeration *enum_fc,
866 const char *label)
867 {
868 uint64_t i;
869 bool exists = false;
870
871 BT_ASSERT(enum_fc);
872 BT_ASSERT(label);
873
874 for (i = 0; i < enum_fc->mappings->len; i++) {
875 struct bt_field_class_enumeration_mapping *mapping_candidate =
876 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
877
878 if (strcmp(mapping_candidate->label->str, label) == 0) {
879 exists = true;
880 goto end;
881 }
882 }
883
884 end:
885 return exists;
886 }
887
888 static inline
889 enum bt_field_class_enumeration_add_mapping_status
890 add_mapping_to_enumeration_field_class(struct bt_field_class *fc,
891 const char *label, const struct bt_integer_range_set *range_set,
892 const char *api_func)
893 {
894 enum bt_field_class_enumeration_add_mapping_status status =
895 BT_FUNC_STATUS_OK;
896 struct bt_field_class_enumeration *enum_fc = (void *) fc;
897 struct bt_field_class_enumeration_mapping mapping = { 0 };
898
899 BT_ASSERT_PRE_NO_ERROR_FROM_FUNC(api_func);
900 BT_ASSERT(fc);
901 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "label", label, "Label");
902 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL_FROM_FUNC(api_func, range_set);
903 BT_ASSERT_PRE_FROM_FUNC(api_func,
904 "enumeration-field-class-mapping-label-is-unique",
905 !enumeration_field_class_has_mapping_with_label(
906 enum_fc, label),
907 "Duplicate mapping name in enumeration field class: "
908 "%![enum-fc-]+F, label=\"%s\"", fc, label);
909 mapping.range_set = range_set;
910 bt_object_get_ref(mapping.range_set);
911 mapping.label = g_string_new(label);
912 if (!mapping.label) {
913 finalize_enumeration_field_class_mapping(&mapping);
914 status = BT_FUNC_STATUS_MEMORY_ERROR;
915 goto end;
916 }
917
918 g_array_append_val(enum_fc->mappings, mapping);
919 BT_LIB_LOGD("Added mapping to enumeration field class: "
920 "%![fc-]+F, label=\"%s\"", fc, label);
921
922 end:
923 return status;
924 }
925
926 BT_EXPORT
927 enum bt_field_class_enumeration_add_mapping_status
928 bt_field_class_enumeration_unsigned_add_mapping(
929 struct bt_field_class *fc, const char *label,
930 const struct bt_integer_range_set_unsigned *range_set)
931 {
932 BT_ASSERT_PRE_NO_ERROR();
933 BT_ASSERT_PRE_FC_NON_NULL(fc);
934 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
935 "unsigned-enumeration-field-class",
936 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
937 return add_mapping_to_enumeration_field_class(fc, label,
938 (const void *) range_set, __func__);
939 }
940
941 BT_EXPORT
942 enum bt_field_class_enumeration_add_mapping_status
943 bt_field_class_enumeration_signed_add_mapping(
944 struct bt_field_class *fc, const char *label,
945 const struct bt_integer_range_set_signed *range_set)
946 {
947 BT_ASSERT_PRE_NO_ERROR();
948 BT_ASSERT_PRE_FC_NON_NULL(fc);
949 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
950 "signed-enumeration-field-class",
951 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field class");
952 return add_mapping_to_enumeration_field_class(fc, label,
953 (const void *) range_set, __func__);
954 }
955
956 static
957 void destroy_real_field_class(struct bt_object *obj)
958 {
959 BT_ASSERT(obj);
960 BT_LIB_LOGD("Destroying real field class object: %!+F", obj);
961 finalize_field_class((void *) obj);
962 g_free(obj);
963 }
964
965 static
966 struct bt_field_class *create_real_field_class(bt_trace_class *trace_class,
967 enum bt_field_class_type type)
968 {
969 struct bt_field_class_real *real_fc = NULL;
970
971 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
972 BT_LOGD("Creating default real field class object: type=%s",
973 bt_common_field_class_type_string(type));
974 real_fc = g_new0(struct bt_field_class_real, 1);
975 if (!real_fc) {
976 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one real field class.");
977 goto error;
978 }
979
980 if (init_field_class((void *) real_fc, type, destroy_real_field_class,
981 trace_class)) {
982 goto error;
983 }
984
985 BT_LIB_LOGD("Created real field class object: %!+F", real_fc);
986 goto end;
987
988 error:
989 BT_OBJECT_PUT_REF_AND_RESET(real_fc);
990
991 end:
992 return (void *) real_fc;
993 }
994
995 BT_EXPORT
996 struct bt_field_class *bt_field_class_real_single_precision_create(
997 bt_trace_class *trace_class)
998 {
999 BT_ASSERT_PRE_NO_ERROR();
1000
1001 return create_real_field_class(trace_class,
1002 BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL);
1003 }
1004
1005 BT_EXPORT
1006 struct bt_field_class *bt_field_class_real_double_precision_create(
1007 bt_trace_class *trace_class)
1008 {
1009 BT_ASSERT_PRE_NO_ERROR();
1010
1011 return create_real_field_class(trace_class,
1012 BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL);
1013 }
1014
1015 static
1016 int init_named_field_classes_container(
1017 struct bt_field_class_named_field_class_container *fc,
1018 enum bt_field_class_type type,
1019 bt_object_release_func fc_release_func,
1020 GDestroyNotify named_fc_destroy_func,
1021 const struct bt_trace_class *trace_class)
1022 {
1023 int ret = 0;
1024
1025 ret = init_field_class((void *) fc, type, fc_release_func,
1026 trace_class);
1027 if (ret) {
1028 goto end;
1029 }
1030
1031 fc->named_fcs = g_ptr_array_new_with_free_func(named_fc_destroy_func);
1032 if (!fc->named_fcs) {
1033 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
1034 ret = -1;
1035 goto end;
1036 }
1037
1038 fc->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
1039 if (!fc->name_to_index) {
1040 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GHashTable.");
1041 ret = -1;
1042 goto end;
1043 }
1044
1045 end:
1046 return ret;
1047 }
1048
1049 static
1050 void finalize_named_field_class(struct bt_named_field_class *named_fc)
1051 {
1052 BT_ASSERT(named_fc);
1053 BT_LIB_LOGD("Finalizing named field class: "
1054 "addr=%p, name=\"%s\", %![fc-]+F",
1055 named_fc, named_fc->name ? named_fc->name->str : NULL,
1056 named_fc->fc);
1057 BT_OBJECT_PUT_REF_AND_RESET(named_fc->user_attributes);
1058
1059 if (named_fc->name) {
1060 g_string_free(named_fc->name, TRUE);
1061 named_fc->name = NULL;
1062 }
1063
1064 BT_LOGD_STR("Putting named field class's field class.");
1065 BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc);
1066 }
1067
1068 static
1069 void destroy_named_field_class(gpointer ptr)
1070 {
1071 struct bt_named_field_class *named_fc = ptr;
1072
1073 if (ptr) {
1074 BT_OBJECT_PUT_REF_AND_RESET(named_fc->user_attributes);
1075 finalize_named_field_class(ptr);
1076 g_free(ptr);
1077 }
1078 }
1079
1080 static
1081 void destroy_variant_with_selector_field_option(gpointer ptr)
1082 {
1083 struct bt_field_class_variant_with_selector_field_option *opt = ptr;
1084
1085 if (ptr) {
1086 finalize_named_field_class(&opt->common);
1087 BT_OBJECT_PUT_REF_AND_RESET(opt->range_set);
1088 g_free(ptr);
1089 }
1090 }
1091
1092 static
1093 void finalize_named_field_classes_container(
1094 struct bt_field_class_named_field_class_container *fc)
1095 {
1096 BT_ASSERT(fc);
1097
1098 if (fc->named_fcs) {
1099 g_ptr_array_free(fc->named_fcs, TRUE);
1100 fc->named_fcs = NULL;
1101
1102 }
1103
1104 if (fc->name_to_index) {
1105 g_hash_table_destroy(fc->name_to_index);
1106 fc->name_to_index = NULL;
1107 }
1108 }
1109
1110 static
1111 void destroy_structure_field_class(struct bt_object *obj)
1112 {
1113 BT_ASSERT(obj);
1114 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj);
1115 finalize_field_class((void *) obj);
1116 finalize_named_field_classes_container((void *) obj);
1117 g_free(obj);
1118 }
1119
1120 BT_EXPORT
1121 struct bt_field_class *bt_field_class_structure_create(
1122 bt_trace_class *trace_class)
1123 {
1124 int ret;
1125 struct bt_field_class_structure *struct_fc = NULL;
1126
1127 BT_ASSERT_PRE_NO_ERROR();
1128 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1129 BT_LOGD_STR("Creating default structure field class object.");
1130 struct_fc = g_new0(struct bt_field_class_structure, 1);
1131 if (!struct_fc) {
1132 BT_LIB_LOGE_APPEND_CAUSE(
1133 "Failed to allocate one structure field class.");
1134 goto error;
1135 }
1136
1137 ret = init_named_field_classes_container((void *) struct_fc,
1138 BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class,
1139 destroy_named_field_class, trace_class);
1140 if (ret) {
1141 /* init_named_field_classes_container() logs errors */
1142 goto error;
1143 }
1144
1145 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc);
1146 goto end;
1147
1148 error:
1149 BT_OBJECT_PUT_REF_AND_RESET(struct_fc);
1150
1151 end:
1152 return (void *) struct_fc;
1153 }
1154
1155 static
1156 int init_named_field_class(struct bt_named_field_class *named_fc,
1157 const char *name, struct bt_field_class *fc)
1158 {
1159 int status = BT_FUNC_STATUS_OK;
1160
1161 BT_ASSERT(named_fc);
1162 BT_ASSERT(fc);
1163
1164 if (name) {
1165 named_fc->name = g_string_new(name);
1166 if (!named_fc->name) {
1167 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
1168 status = BT_FUNC_STATUS_MEMORY_ERROR;
1169 goto end;
1170 }
1171 }
1172
1173 named_fc->user_attributes = bt_value_map_create();
1174 if (!named_fc->user_attributes) {
1175 BT_LIB_LOGE_APPEND_CAUSE(
1176 "Failed to create a map value object.");
1177 status = BT_FUNC_STATUS_MEMORY_ERROR;
1178 goto end;
1179 }
1180
1181 named_fc->fc = fc;
1182 bt_object_get_ref_no_null_check(named_fc->fc);
1183
1184 end:
1185 return status;
1186 }
1187
1188 static
1189 struct bt_named_field_class *create_named_field_class(const char *name,
1190 struct bt_field_class *fc)
1191 {
1192 struct bt_named_field_class *named_fc = g_new0(
1193 struct bt_named_field_class, 1);
1194
1195 if (!named_fc) {
1196 BT_LIB_LOGE_APPEND_CAUSE(
1197 "Failed to allocate a named field class.");
1198 goto error;
1199 }
1200
1201 if (init_named_field_class(named_fc, name, fc)) {
1202 /* init_named_field_class() logs errors */
1203 goto error;
1204 }
1205
1206 goto end;
1207
1208 error:
1209 destroy_named_field_class(named_fc);
1210 named_fc = NULL;
1211
1212 end:
1213 return named_fc;
1214 }
1215
1216 static
1217 struct bt_field_class_variant_with_selector_field_option *
1218 create_variant_with_selector_field_option(
1219 const char *name, struct bt_field_class *fc,
1220 const struct bt_integer_range_set *range_set)
1221 {
1222 struct bt_field_class_variant_with_selector_field_option *opt = g_new0(
1223 struct bt_field_class_variant_with_selector_field_option, 1);
1224
1225 BT_ASSERT(range_set);
1226
1227 if (!opt) {
1228 BT_LIB_LOGE_APPEND_CAUSE(
1229 "Failed to allocate a named field class.");
1230 goto error;
1231 }
1232
1233 if (init_named_field_class(&opt->common, name, fc)) {
1234 goto error;
1235 }
1236
1237 opt->range_set = range_set;
1238 bt_object_get_ref_no_null_check(opt->range_set);
1239 bt_integer_range_set_freeze(range_set);
1240 goto end;
1241
1242 error:
1243 destroy_variant_with_selector_field_option(opt);
1244 opt = NULL;
1245
1246 end:
1247 return opt;
1248 }
1249
1250 static
1251 int append_named_field_class_to_container_field_class(
1252 struct bt_field_class_named_field_class_container *container_fc,
1253 struct bt_named_field_class *named_fc, const char *api_func,
1254 const char *unique_entry_precond_id)
1255 {
1256 BT_ASSERT(container_fc);
1257 BT_ASSERT(named_fc);
1258 BT_ASSERT_PRE_DEV_FC_HOT_FROM_FUNC(api_func, container_fc);
1259 BT_ASSERT_PRE_FROM_FUNC(api_func, unique_entry_precond_id,
1260 !named_fc->name ||
1261 !bt_g_hash_table_contains(container_fc->name_to_index,
1262 named_fc->name->str),
1263 "Duplicate member/option name in structure/variant field class: "
1264 "%![container-fc-]+F, name=\"%s\"", container_fc,
1265 named_fc->name->str);
1266
1267 /*
1268 * Freeze the contained field class, but not the named field
1269 * class itself, as it's still possible afterwards to modify
1270 * properties of the member/option object.
1271 */
1272 bt_field_class_freeze(named_fc->fc);
1273 g_ptr_array_add(container_fc->named_fcs, named_fc);
1274
1275 if (named_fc->name) {
1276 /*
1277 * MIP > 0: a variant field class option may have no
1278 * name.
1279 */
1280 g_hash_table_insert(container_fc->name_to_index,
1281 named_fc->name->str,
1282 GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
1283 }
1284
1285 return BT_FUNC_STATUS_OK;
1286 }
1287
1288 BT_EXPORT
1289 enum bt_field_class_structure_append_member_status
1290 bt_field_class_structure_append_member(
1291 struct bt_field_class *fc, const char *name,
1292 struct bt_field_class *member_fc)
1293 {
1294 enum bt_field_class_structure_append_member_status status;
1295 struct bt_named_field_class *named_fc = NULL;
1296
1297 BT_ASSERT_PRE_NO_ERROR();
1298 BT_ASSERT_PRE_FC_NON_NULL(fc);
1299 BT_ASSERT_PRE_NAME_NON_NULL(name);
1300 BT_ASSERT_PRE_FC_IS_STRUCT("field-class", fc, "Field class");
1301 named_fc = create_named_field_class(name, member_fc);
1302 if (!named_fc) {
1303 /* create_named_field_class() logs errors */
1304 status = BT_FUNC_STATUS_MEMORY_ERROR;
1305 goto end;
1306 }
1307
1308 status = append_named_field_class_to_container_field_class((void *) fc,
1309 named_fc, __func__,
1310 "structure-field-class-member-name-is-unique");
1311 if (status == BT_FUNC_STATUS_OK) {
1312 /* Moved to the container */
1313 named_fc = NULL;
1314 }
1315
1316 end:
1317 return status;
1318 }
1319
1320 BT_EXPORT
1321 uint64_t bt_field_class_structure_get_member_count(
1322 const struct bt_field_class *fc)
1323 {
1324 struct bt_field_class_structure *struct_fc = (void *) fc;
1325
1326 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1327 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1328 return (uint64_t) struct_fc->common.named_fcs->len;
1329 }
1330
1331 static
1332 struct bt_named_field_class *
1333 borrow_named_field_class_from_container_field_class_at_index(
1334 struct bt_field_class_named_field_class_container *fc,
1335 uint64_t index, const char *api_func)
1336 {
1337 BT_ASSERT_DBG(fc);
1338 BT_ASSERT_PRE_DEV_VALID_INDEX_FROM_FUNC(api_func, index,
1339 fc->named_fcs->len);
1340 return fc->named_fcs->pdata[index];
1341 }
1342
1343 BT_EXPORT
1344 const struct bt_field_class_structure_member *
1345 bt_field_class_structure_borrow_member_by_index_const(
1346 const struct bt_field_class *fc, uint64_t index)
1347 {
1348 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1349 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1350 return (const void *)
1351 borrow_named_field_class_from_container_field_class_at_index(
1352 (void *) fc, index, __func__);
1353 }
1354
1355 BT_EXPORT
1356 struct bt_field_class_structure_member *
1357 bt_field_class_structure_borrow_member_by_index(
1358 struct bt_field_class *fc, uint64_t index)
1359 {
1360 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1361 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1362 return (void *)
1363 borrow_named_field_class_from_container_field_class_at_index(
1364 (void *) fc, index, __func__);
1365 }
1366
1367 static
1368 struct bt_named_field_class *
1369 borrow_named_field_class_from_container_field_class_by_name(
1370 struct bt_field_class_named_field_class_container *fc,
1371 const char *name, const char *api_func)
1372 {
1373 struct bt_named_field_class *named_fc = NULL;
1374 gpointer orig_key;
1375 gpointer value;
1376
1377 BT_ASSERT_DBG(fc);
1378 BT_ASSERT_PRE_DEV_NAME_NON_NULL_FROM_FUNC(api_func, name);
1379 if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key,
1380 &value)) {
1381 goto end;
1382 }
1383
1384 named_fc = fc->named_fcs->pdata[GPOINTER_TO_UINT(value)];
1385
1386 end:
1387 return named_fc;
1388 }
1389
1390 BT_EXPORT
1391 const struct bt_field_class_structure_member *
1392 bt_field_class_structure_borrow_member_by_name_const(
1393 const struct bt_field_class *fc, const char *name)
1394 {
1395 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1396 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1397 return (const void *)
1398 borrow_named_field_class_from_container_field_class_by_name(
1399 (void *) fc, name, __func__);
1400 }
1401
1402 BT_EXPORT
1403 struct bt_field_class_structure_member *
1404 bt_field_class_structure_borrow_member_by_name(
1405 struct bt_field_class *fc, const char *name)
1406 {
1407 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
1408 BT_ASSERT_PRE_DEV_FC_IS_STRUCT("field-class", fc, "Field class");
1409 return (void *)
1410 borrow_named_field_class_from_container_field_class_by_name(
1411 (void *) fc, name, __func__);
1412 }
1413
1414 BT_EXPORT
1415 const char *bt_field_class_structure_member_get_name(
1416 const struct bt_field_class_structure_member *member)
1417 {
1418 const struct bt_named_field_class *named_fc = (const void *) member;
1419
1420 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1421 BT_ASSERT_DBG(named_fc->name);
1422 return named_fc->name->str;
1423 }
1424
1425 BT_EXPORT
1426 const struct bt_field_class *
1427 bt_field_class_structure_member_borrow_field_class_const(
1428 const struct bt_field_class_structure_member *member)
1429 {
1430 const struct bt_named_field_class *named_fc = (const void *) member;
1431
1432 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1433 return named_fc->fc;
1434 }
1435
1436 BT_EXPORT
1437 struct bt_field_class *
1438 bt_field_class_structure_member_borrow_field_class(
1439 struct bt_field_class_structure_member *member)
1440 {
1441 struct bt_named_field_class *named_fc = (void *) member;
1442
1443 BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
1444 return named_fc->fc;
1445 }
1446
1447 static
1448 void destroy_option_field_class(struct bt_object *obj)
1449 {
1450 struct bt_field_class_option *fc = (void *) obj;
1451
1452 BT_ASSERT(fc);
1453 BT_LIB_LOGD("Destroying option field class object: %!+F", fc);
1454 finalize_field_class((void *) obj);
1455 BT_LOGD_STR("Putting content field class.");
1456 BT_OBJECT_PUT_REF_AND_RESET(fc->content_fc);
1457
1458 if (fc->common.type != BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD) {
1459 struct bt_field_class_option_with_selector_field *with_sel_fc =
1460 (void *) obj;
1461
1462 switch (with_sel_fc->selector_field_xref_kind) {
1463 case FIELD_XREF_KIND_PATH:
1464 BT_LOGD_STR("Putting selector field path.");
1465 BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_field.path.path);
1466 BT_LOGD_STR("Putting selector field class.");
1467 BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_field.path.class);
1468 break;
1469 case FIELD_XREF_KIND_LOCATION:
1470 BT_LOGD_STR("Putting selector field location.");
1471 BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_field.location);
1472 break;
1473 };
1474
1475 if (fc->common.type != BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
1476 struct bt_field_class_option_with_selector_field_integer *with_int_sel_fc =
1477 (void *) obj;
1478
1479 BT_LOGD_STR("Putting integer range set.");
1480 BT_OBJECT_PUT_REF_AND_RESET(with_int_sel_fc->range_set);
1481 }
1482 }
1483
1484 g_free(fc);
1485 }
1486
1487 static
1488 struct bt_field_class *create_option_field_class(
1489 struct bt_trace_class *trace_class,
1490 enum bt_field_class_type fc_type,
1491 struct bt_field_class *content_fc,
1492 struct bt_field_class *selector_fc,
1493 const struct bt_field_location *selector_fl,
1494 const char *api_func)
1495 {
1496 struct bt_field_class_option *opt_fc = NULL;
1497
1498 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "content-field-class",
1499 content_fc, "Content field class");
1500
1501 BT_ASSERT(!(selector_fc && selector_fl));
1502
1503 BT_LIB_LOGD("Creating option field class: "
1504 "type=%s, %![content-fc-]+F, %![sel-fc-]+F",
1505 bt_common_field_class_type_string(fc_type),
1506 content_fc, selector_fc);
1507
1508 if (fc_type != BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD) {
1509 struct bt_field_class_option_with_selector_field *opt_with_sel_fc = NULL;
1510
1511 BT_ASSERT(selector_fc || selector_fl);
1512
1513 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD) {
1514 opt_with_sel_fc = (void *) g_new0(
1515 struct bt_field_class_option_with_selector_field_bool, 1);
1516 } else {
1517 opt_with_sel_fc = (void *) g_new0(
1518 struct bt_field_class_option_with_selector_field_integer, 1);
1519 }
1520
1521 if (!opt_with_sel_fc) {
1522 BT_LIB_LOGE_APPEND_CAUSE(
1523 "Failed to allocate one option with selector field class.");
1524 goto error;
1525 }
1526
1527 if (selector_fc) {
1528 opt_with_sel_fc->selector_field_xref_kind = FIELD_XREF_KIND_PATH;
1529 opt_with_sel_fc->selector_field.path.class = selector_fc;
1530 bt_object_get_ref_no_null_check(opt_with_sel_fc->selector_field.path.class);
1531 } else {
1532 opt_with_sel_fc->selector_field_xref_kind = FIELD_XREF_KIND_LOCATION;
1533 opt_with_sel_fc->selector_field.location = selector_fl;
1534 bt_object_get_ref_no_null_check(opt_with_sel_fc->selector_field.location);
1535 }
1536
1537 opt_fc = (void *) opt_with_sel_fc;
1538 } else {
1539 BT_ASSERT(!selector_fc);
1540 BT_ASSERT(!selector_fl);
1541
1542 opt_fc = g_new0(struct bt_field_class_option, 1);
1543 if (!opt_fc) {
1544 BT_LIB_LOGE_APPEND_CAUSE(
1545 "Failed to allocate one option field class.");
1546 goto error;
1547 }
1548 }
1549
1550 BT_ASSERT(opt_fc);
1551
1552 if (init_field_class((void *) opt_fc, fc_type,
1553 destroy_option_field_class, trace_class)) {
1554 goto error;
1555 }
1556
1557 opt_fc->content_fc = content_fc;
1558 bt_object_get_ref_no_null_check(opt_fc->content_fc);
1559 bt_field_class_freeze(opt_fc->content_fc);
1560
1561 if (selector_fc) {
1562 bt_field_class_freeze(selector_fc);
1563 }
1564
1565 goto end;
1566
1567 error:
1568 BT_OBJECT_PUT_REF_AND_RESET(opt_fc);
1569
1570 end:
1571 return (void *) opt_fc;
1572 }
1573
1574 BT_EXPORT
1575 struct bt_field_class *bt_field_class_option_without_selector_create(
1576 struct bt_trace_class *trace_class,
1577 struct bt_field_class *content_fc)
1578 {
1579 struct bt_field_class *fc;
1580
1581 BT_ASSERT_PRE_NO_ERROR();
1582 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1583 BT_ASSERT_PRE_TC_MIP_VERSION_EQ(trace_class, 0);
1584
1585 fc = create_option_field_class(trace_class,
1586 BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD,
1587 content_fc, NULL, NULL, __func__);
1588
1589 BT_LIB_LOGD("Created option field class without selector field class: "
1590 "%![opt-fc-]+F", fc);
1591
1592 return fc;
1593 }
1594
1595 BT_EXPORT
1596 struct bt_field_class *bt_field_class_option_without_selector_field_location_create(
1597 struct bt_trace_class *trace_class,
1598 struct bt_field_class *content_fc)
1599 {
1600 struct bt_field_class *fc;
1601
1602 BT_ASSERT_PRE_NO_ERROR();
1603 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1604 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
1605
1606 fc = create_option_field_class(trace_class,
1607 BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD,
1608 content_fc, NULL, NULL, __func__);
1609
1610 BT_LIB_LOGD("Created option field class without selector field location: "
1611 "%![opt-fc-]+F", fc);
1612
1613 return fc;
1614 }
1615
1616 BT_EXPORT
1617 struct bt_field_class *bt_field_class_option_with_selector_field_bool_create(
1618 struct bt_trace_class *trace_class,
1619 struct bt_field_class *content_fc,
1620 struct bt_field_class *selector_fc)
1621 {
1622 struct bt_field_class *fc;
1623
1624 BT_ASSERT_PRE_NO_ERROR();
1625 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1626 BT_ASSERT_PRE_TC_MIP_VERSION_EQ(trace_class, 0);
1627 BT_ASSERT_PRE_SELECTOR_FC_NON_NULL(selector_fc);
1628 BT_ASSERT_PRE_FC_HAS_TYPE("selector-field-class", selector_fc,
1629 "boolean-field-class", BT_FIELD_CLASS_TYPE_BOOL,
1630 "Selector field class");
1631
1632 fc = create_option_field_class(trace_class,
1633 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1634 content_fc, selector_fc, NULL, __func__);
1635
1636 BT_LIB_LOGD("Created option field class with boolean selector field class: "
1637 "%![opt-fc-]+F, %![sel-fc-]+F", fc, selector_fc);
1638
1639 return fc;
1640 }
1641
1642 BT_EXPORT
1643 struct bt_field_class *bt_field_class_option_with_selector_field_location_bool_create(
1644 struct bt_trace_class *trace_class,
1645 struct bt_field_class *content_fc,
1646 const struct bt_field_location *selector_fl)
1647 {
1648 struct bt_field_class *fc;
1649
1650 BT_ASSERT_PRE_NO_ERROR();
1651 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1652 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
1653 BT_ASSERT_PRE_SELECTOR_FL_NON_NULL(selector_fl);
1654
1655 fc = create_option_field_class(trace_class,
1656 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1657 content_fc, NULL, selector_fl, __func__);
1658
1659 BT_LIB_LOGD("Created option field class with boolean selector field location: "
1660 "%![opt-fc-]+F, %![sel-fl-]+L", fc, selector_fl);
1661
1662 return fc;
1663 }
1664
1665 BT_EXPORT
1666 struct bt_field_class *
1667 bt_field_class_option_with_selector_field_integer_unsigned_create(
1668 struct bt_trace_class *trace_class,
1669 struct bt_field_class *content_fc,
1670 struct bt_field_class *selector_fc,
1671 const struct bt_integer_range_set_unsigned *u_range_set)
1672 {
1673 struct bt_field_class_option_with_selector_field_integer *fc;
1674 const struct bt_integer_range_set *range_set =
1675 (const void *) u_range_set;
1676
1677 BT_ASSERT_PRE_NO_ERROR();
1678 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1679 BT_ASSERT_PRE_TC_MIP_VERSION_EQ(trace_class, 0);
1680 BT_ASSERT_PRE_SELECTOR_FC_NON_NULL(selector_fc);
1681 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT("selector-field-class",
1682 selector_fc, "Selector field class");
1683 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1684 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
1685
1686 fc = (void *) create_option_field_class(trace_class,
1687 BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1688 content_fc, selector_fc, NULL, __func__);
1689 if (!fc) {
1690 goto end;
1691 }
1692
1693 fc->range_set = range_set;
1694 bt_object_get_ref_no_null_check(fc->range_set);
1695 bt_integer_range_set_freeze(range_set);
1696
1697 BT_LIB_LOGD("Created option field class with unsigned integer selector field class: "
1698 "%![opt-fc-]+F, %![sel-fc-]+F", fc, selector_fc);
1699
1700 end:
1701 return (void *) fc;
1702 }
1703
1704 BT_EXPORT
1705 struct bt_field_class *
1706 bt_field_class_option_with_selector_field_location_integer_unsigned_create(
1707 struct bt_trace_class *trace_class,
1708 struct bt_field_class *content_fc,
1709 const struct bt_field_location *selector_fl,
1710 const struct bt_integer_range_set_unsigned *u_range_set)
1711 {
1712 struct bt_field_class_option_with_selector_field_integer *fc;
1713 const struct bt_integer_range_set *range_set =
1714 (const void *) u_range_set;
1715
1716 BT_ASSERT_PRE_NO_ERROR();
1717 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1718 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
1719 BT_ASSERT_PRE_SELECTOR_FL_NON_NULL(selector_fl);
1720 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1721 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
1722
1723 fc = (void *) create_option_field_class(trace_class,
1724 BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
1725 content_fc, NULL, selector_fl, __func__);
1726 if (!fc) {
1727 goto end;
1728 }
1729
1730 fc->range_set = range_set;
1731 bt_object_get_ref_no_null_check(fc->range_set);
1732 bt_integer_range_set_freeze(range_set);
1733
1734 BT_LIB_LOGD("Created option field class with unsigned integer selector field location: "
1735 "%![opt-fc-]+F, %![sel-fl-]+L", fc, selector_fl);
1736
1737 end:
1738 return (void *) fc;
1739 }
1740
1741 BT_EXPORT
1742 struct bt_field_class *
1743 bt_field_class_option_with_selector_field_integer_signed_create(
1744 struct bt_trace_class *trace_class,
1745 struct bt_field_class *content_fc,
1746 struct bt_field_class *selector_fc,
1747 const struct bt_integer_range_set_signed *i_range_set)
1748 {
1749 struct bt_field_class_option_with_selector_field_integer *fc;
1750 const struct bt_integer_range_set *range_set =
1751 (const void *) i_range_set;
1752
1753 BT_ASSERT_PRE_NO_ERROR();
1754 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1755 BT_ASSERT_PRE_TC_MIP_VERSION_EQ(trace_class, 0);
1756 BT_ASSERT_PRE_SELECTOR_FC_NON_NULL(selector_fc);
1757 BT_ASSERT_PRE_FC_IS_SIGNED_INT("selector-field-class",
1758 selector_fc, "Selector field class");
1759 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1760 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
1761
1762 fc = (void *) create_option_field_class(trace_class,
1763 BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1764 content_fc, selector_fc, NULL, __func__);
1765 if (!fc) {
1766 goto end;
1767 }
1768
1769 fc->range_set = range_set;
1770 bt_object_get_ref_no_null_check(fc->range_set);
1771 bt_integer_range_set_freeze(range_set);
1772
1773 BT_LIB_LOGD("Created option field class with signed integer selector field class: "
1774 "%![opt-fc-]+F, %![sel-fc-]+F", fc, selector_fc);
1775
1776 end:
1777 return (void *) fc;
1778 }
1779
1780 BT_EXPORT
1781 struct bt_field_class *
1782 bt_field_class_option_with_selector_field_location_integer_signed_create(
1783 struct bt_trace_class *trace_class,
1784 struct bt_field_class *content_fc,
1785 const struct bt_field_location *selector_fl,
1786 const struct bt_integer_range_set_signed *i_range_set)
1787 {
1788 struct bt_field_class_option_with_selector_field_integer *fc;
1789 const struct bt_integer_range_set *range_set =
1790 (const void *) i_range_set;
1791
1792 BT_ASSERT_PRE_NO_ERROR();
1793 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
1794 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
1795 BT_ASSERT_PRE_SELECTOR_FL_NON_NULL(selector_fl);
1796 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1797 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY(range_set);
1798
1799 fc = (void *) create_option_field_class(trace_class,
1800 BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
1801 content_fc, NULL, selector_fl, __func__);
1802 if (!fc) {
1803 goto end;
1804 }
1805
1806 fc->range_set = range_set;
1807 bt_object_get_ref_no_null_check(fc->range_set);
1808 bt_integer_range_set_freeze(range_set);
1809
1810 BT_LIB_LOGD("Created option field class with signed integer selector field location: "
1811 "%![opt-fc-]+F, %![sel-fl-]+L", fc, selector_fl);
1812
1813 end:
1814 return (void *) fc;
1815 }
1816
1817 BT_EXPORT
1818 const struct bt_field_class *bt_field_class_option_borrow_field_class_const(
1819 const struct bt_field_class *fc)
1820 {
1821 struct bt_field_class_option *opt_fc = (void *) fc;
1822
1823 BT_ASSERT_PRE_FC_NON_NULL(fc);
1824 BT_ASSERT_PRE_FC_IS_OPTION("field-class", fc, "Field class");
1825 return opt_fc->content_fc;
1826 }
1827
1828 BT_EXPORT
1829 struct bt_field_class *bt_field_class_option_borrow_field_class(
1830 struct bt_field_class *fc)
1831 {
1832 struct bt_field_class_option *opt_fc = (void *) fc;
1833
1834 BT_ASSERT_PRE_FC_NON_NULL(fc);
1835 BT_ASSERT_PRE_FC_IS_OPTION("field-class", fc, "Field class");
1836 return opt_fc->content_fc;
1837 }
1838
1839 BT_EXPORT
1840 const struct bt_field_path *
1841 bt_field_class_option_with_selector_field_borrow_selector_field_path_const(
1842 const struct bt_field_class *fc)
1843 {
1844 const struct bt_field_class_option_with_selector_field *opt_fc =
1845 (const void *) fc;
1846
1847 BT_ASSERT_PRE_FC_NON_NULL(fc);
1848 BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL("field-class", fc, "Field class");
1849 BT_ASSERT_PRE_FC_MIP_VERSION_EQ(fc, 0);
1850 BT_ASSERT_DBG(opt_fc->selector_field_xref_kind == FIELD_XREF_KIND_PATH);
1851 return opt_fc->selector_field.path.path;
1852 }
1853
1854 BT_EXPORT
1855 const struct bt_field_location *
1856 bt_field_class_option_with_selector_field_borrow_selector_field_location_const(
1857 const struct bt_field_class *fc)
1858 {
1859 const struct bt_field_class_option_with_selector_field *opt_fc =
1860 (const void *) fc;
1861
1862 BT_ASSERT_PRE_FC_NON_NULL(fc);
1863 BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL("field-class", fc, "Field class");
1864 BT_ASSERT_PRE_FC_MIP_VERSION_GE(fc, 1);
1865 BT_ASSERT_DBG(opt_fc->selector_field_xref_kind == FIELD_XREF_KIND_LOCATION);
1866 return opt_fc->selector_field.location;
1867 }
1868
1869 BT_EXPORT
1870 void bt_field_class_option_with_selector_field_bool_set_selector_is_reversed(
1871 struct bt_field_class *fc, bt_bool sel_is_reversed)
1872 {
1873 struct bt_field_class_option_with_selector_field_bool *opt_fc = (void *) fc;
1874
1875 BT_ASSERT_PRE_FC_NON_NULL(fc);
1876 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1877 "option-field-class-with-boolean-selector-field",
1878 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1879 "Field class");
1880 BT_ASSERT_PRE_DEV_FC_HOT(fc);
1881 opt_fc->sel_is_reversed = sel_is_reversed;
1882 }
1883
1884 BT_EXPORT
1885 bt_bool bt_field_class_option_with_selector_field_bool_selector_is_reversed(
1886 const struct bt_field_class *fc)
1887 {
1888 struct bt_field_class_option_with_selector_field_bool *opt_fc = (void *) fc;
1889
1890 BT_ASSERT_PRE_FC_NON_NULL(fc);
1891 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
1892 "option-field-class-with-boolean-selector-field",
1893 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD,
1894 "Field class");
1895 return opt_fc->sel_is_reversed;
1896 }
1897
1898 BT_EXPORT
1899 const struct bt_integer_range_set_unsigned *
1900 bt_field_class_option_with_selector_field_integer_unsigned_borrow_selector_ranges_const(
1901 const struct bt_field_class *fc)
1902 {
1903 struct bt_field_class_option_with_selector_field_integer *opt_fc =
1904 (void *) fc;
1905
1906 BT_ASSERT_PRE_FC_NON_NULL(fc);
1907 BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL("field-class", fc,
1908 "Field class");
1909 return (const void *) opt_fc->range_set;
1910 }
1911
1912 BT_EXPORT
1913 const struct bt_integer_range_set_signed *
1914 bt_field_class_option_with_selector_field_integer_signed_borrow_selector_ranges_const(
1915 const struct bt_field_class *fc)
1916 {
1917 struct bt_field_class_option_with_selector_field_integer *opt_fc =
1918 (void *) fc;
1919
1920 BT_ASSERT_PRE_FC_NON_NULL(fc);
1921 BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL("field-class", fc,
1922 "Field class");
1923 return (const void *) opt_fc->range_set;
1924 }
1925
1926 static
1927 void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
1928 {
1929 BT_ASSERT(var_fc);
1930 BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc);
1931 finalize_field_class((void *) var_fc);
1932 finalize_named_field_classes_container((void *) var_fc);
1933 }
1934
1935 static
1936 void destroy_variant_field_class(struct bt_object *obj)
1937 {
1938 struct bt_field_class_variant *fc = (void *) obj;
1939
1940 BT_ASSERT(fc);
1941 finalize_variant_field_class(fc);
1942 g_free(fc);
1943 }
1944
1945 static
1946 void destroy_variant_with_selector_field_field_class(struct bt_object *obj)
1947 {
1948 struct bt_field_class_variant_with_selector_field *fc = (void *) obj;
1949
1950 BT_ASSERT(fc);
1951 finalize_variant_field_class(&fc->common);
1952
1953 if (fc->selector_field_xref_kind == FIELD_XREF_KIND_PATH) {
1954 BT_LOGD_STR("Putting selector field path.");
1955 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field.path.path);
1956 BT_LOGD_STR("Putting selector field class.");
1957 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field.path.class);
1958 } else {
1959 BT_ASSERT(fc->selector_field_xref_kind == FIELD_XREF_KIND_LOCATION);
1960 BT_LOGD_STR("Putting selector field location.");
1961 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field.location);
1962 }
1963
1964 g_free(fc);
1965 }
1966
1967 static
1968 struct bt_field_class *create_variant_field_class(
1969 struct bt_trace_class *trace_class,
1970 enum bt_field_class_type fc_type,
1971 struct bt_field_class *selector_fc,
1972 const struct bt_field_location *selector_fl)
1973 {
1974 int ret;
1975 struct bt_field_class_variant *var_fc = NULL;
1976 struct bt_field_class_variant_with_selector_field *var_with_sel_fc = NULL;
1977
1978 if (fc_type != BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD) {
1979 BT_ASSERT((selector_fc && !selector_fl) ||
1980 (!selector_fc && selector_fl));
1981
1982
1983 if (selector_fc) {
1984 BT_LIB_LOGD("Creating default variant field class with selector field class: %![sel-fc-]+F",
1985 selector_fc);
1986 } else {
1987 BT_LIB_LOGD("Creating default variant field class with selector field location: %![sel-fl-]+L",
1988 selector_fl);
1989 }
1990
1991 var_with_sel_fc = g_new0(
1992 struct bt_field_class_variant_with_selector_field, 1);
1993 if (!var_with_sel_fc) {
1994 BT_LIB_LOGE_APPEND_CAUSE(
1995 "Failed to allocate one variant field class with selector.");
1996 goto error;
1997 }
1998
1999 ret = init_named_field_classes_container(
2000 (void *) var_with_sel_fc, fc_type,
2001 destroy_variant_with_selector_field_field_class,
2002 destroy_variant_with_selector_field_option,
2003 trace_class);
2004 if (ret) {
2005 /* init_named_field_classes_container() logs errors */
2006 goto error;
2007 }
2008
2009 if (selector_fc) {
2010 var_with_sel_fc->selector_field_xref_kind = FIELD_XREF_KIND_PATH;
2011 var_with_sel_fc->selector_field.path.class = selector_fc;
2012 bt_object_get_ref_no_null_check(selector_fc);
2013 bt_field_class_freeze(selector_fc);
2014
2015 BT_LIB_LOGD("Created default variant field class with selector field class: "
2016 "%![var-fc-]+F, %![sel-fc-]+F", var_with_sel_fc, selector_fc);
2017 } else {
2018 var_with_sel_fc->selector_field_xref_kind = FIELD_XREF_KIND_LOCATION;
2019 var_with_sel_fc->selector_field.location = selector_fl;
2020 bt_object_get_ref_no_null_check(var_with_sel_fc->selector_field.location);
2021
2022 BT_LIB_LOGD("Created default variant field class with selector field location: "
2023 "%![var-fc-]+F, %![sel-fl-]+L", var_fc, selector_fl);
2024 }
2025
2026 var_fc = (void *) var_with_sel_fc;
2027 } else {
2028 BT_LIB_LOGD("Creating default variant field class without selector.");
2029
2030 var_fc = g_new0(struct bt_field_class_variant, 1);
2031 if (!var_fc) {
2032 BT_LIB_LOGE_APPEND_CAUSE(
2033 "Failed to allocate one variant field class without selector.");
2034 goto error;
2035 }
2036
2037 ret = init_named_field_classes_container((void *) var_fc, fc_type,
2038 destroy_variant_field_class, destroy_named_field_class,
2039 trace_class);
2040 if (ret) {
2041 /* init_named_field_classes_container() logs errors */
2042 goto error;
2043 }
2044 BT_LIB_LOGD("Created default variant field class without selector object: "
2045 "%![var-fc-]+F", var_fc);
2046 }
2047
2048 BT_ASSERT(var_fc);
2049 goto end;
2050
2051 error:
2052 BT_OBJECT_PUT_REF_AND_RESET(var_fc);
2053 BT_OBJECT_PUT_REF_AND_RESET(var_with_sel_fc);
2054
2055 end:
2056 return (void *) var_fc;
2057 }
2058
2059 BT_EXPORT
2060 struct bt_field_class *bt_field_class_variant_create(
2061 struct bt_trace_class *trace_class,
2062 struct bt_field_class *selector_fc)
2063 {
2064 enum bt_field_class_type fc_type;
2065
2066 BT_ASSERT_PRE_NO_ERROR();
2067 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2068 BT_ASSERT_PRE_TC_MIP_VERSION_EQ(trace_class, 0);
2069
2070 if (selector_fc) {
2071 bt_field_class_type selector_fc_type;
2072
2073 BT_ASSERT_PRE_FC_IS_INT("selector-field-class", selector_fc,
2074 "Selector field class");
2075
2076 selector_fc_type = bt_field_class_get_type(selector_fc);
2077
2078 if (bt_field_class_type_is(selector_fc_type,
2079 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)) {
2080 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD;
2081 } else {
2082 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD;
2083 }
2084 } else {
2085 fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD;
2086 }
2087
2088 return create_variant_field_class(trace_class, fc_type, selector_fc, NULL);
2089 }
2090
2091 BT_EXPORT
2092 struct bt_field_class *bt_field_class_variant_without_selector_field_location_create(
2093 struct bt_trace_class *trace_class)
2094 {
2095 BT_ASSERT_PRE_NO_ERROR();
2096 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2097 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
2098
2099 return create_variant_field_class(trace_class,
2100 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD, NULL, NULL);
2101 }
2102
2103 BT_EXPORT
2104 struct bt_field_class *bt_field_class_variant_with_selector_field_location_integer_unsigned_create(
2105 struct bt_trace_class *trace_class,
2106 const struct bt_field_location *selector_fl)
2107 {
2108 BT_ASSERT_PRE_NO_ERROR();
2109 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2110 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
2111 BT_ASSERT_PRE_SELECTOR_FL_NON_NULL(selector_fl);
2112
2113 return create_variant_field_class(trace_class,
2114 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
2115 NULL, selector_fl);
2116 }
2117
2118 BT_EXPORT
2119 struct bt_field_class *bt_field_class_variant_with_selector_field_location_integer_signed_create(
2120 struct bt_trace_class *trace_class,
2121 const struct bt_field_location *selector_fl)
2122 {
2123 BT_ASSERT_PRE_NO_ERROR();
2124 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2125 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
2126 BT_ASSERT_PRE_SELECTOR_FL_NON_NULL(selector_fl);
2127
2128 return create_variant_field_class(trace_class,
2129 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
2130 NULL, selector_fl);
2131 }
2132
2133 #define VAR_FC_OPT_NAME_IS_UNIQUE_ID \
2134 "variant-field-class-option-name-is-unique"
2135
2136 BT_EXPORT
2137 enum bt_field_class_variant_without_selector_append_option_status
2138 bt_field_class_variant_without_selector_append_option(struct bt_field_class *fc,
2139 const char *name, struct bt_field_class *option_fc)
2140 {
2141 enum bt_field_class_variant_without_selector_append_option_status status;
2142 struct bt_named_field_class *named_fc = NULL;
2143
2144 BT_ASSERT_PRE_NO_ERROR();
2145 BT_ASSERT_PRE_FC_NON_NULL(fc);
2146
2147 /* Name is mandatory in MIP 0, optional later. */
2148 if (fc->mip_version == 0) {
2149 BT_ASSERT_PRE_NAME_NON_NULL(name);
2150 }
2151
2152 BT_ASSERT_PRE_NON_NULL("option-field-class", option_fc,
2153 "Option field class");
2154 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2155 "variant-field-class-without-selector-field",
2156 BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD,
2157 "Field class");
2158 named_fc = create_named_field_class(name, option_fc);
2159 if (!named_fc) {
2160 /* create_named_field_class() logs errors */
2161 status = BT_FUNC_STATUS_MEMORY_ERROR;
2162 goto end;
2163 }
2164
2165 status = append_named_field_class_to_container_field_class((void *) fc,
2166 named_fc, __func__, VAR_FC_OPT_NAME_IS_UNIQUE_ID);
2167 if (status == BT_FUNC_STATUS_OK) {
2168 /* Moved to the container */
2169 named_fc = NULL;
2170 }
2171
2172 end:
2173 if (named_fc) {
2174 destroy_named_field_class(named_fc);
2175 }
2176
2177 return status;
2178 }
2179
2180 static
2181 int ranges_overlap(GPtrArray *var_fc_opts, const struct bt_integer_range_set *range_set,
2182 bool is_signed, bool *has_overlap)
2183 {
2184 int status = BT_FUNC_STATUS_OK;
2185 struct bt_integer_range_set *full_range_set;
2186 uint64_t i;
2187
2188 *has_overlap = false;
2189
2190 /*
2191 * Build a single range set with all the ranges and test for
2192 * overlaps.
2193 */
2194 if (is_signed) {
2195 full_range_set = (void *) bt_integer_range_set_signed_create();
2196 } else {
2197 full_range_set = (void *) bt_integer_range_set_unsigned_create();
2198 }
2199
2200 if (!full_range_set) {
2201 BT_LOGE_STR("Failed to create a range set.");
2202 status = BT_FUNC_STATUS_MEMORY_ERROR;
2203 goto end;
2204 }
2205
2206 /* Add existing option ranges */
2207 for (i = 0; i < var_fc_opts->len; i++) {
2208 struct bt_field_class_variant_with_selector_field_option *opt =
2209 var_fc_opts->pdata[i];
2210 uint64_t j;
2211
2212 for (j = 0; j < opt->range_set->ranges->len; j++) {
2213 struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
2214 opt->range_set, j);
2215
2216 if (is_signed) {
2217 status = bt_integer_range_set_signed_add_range(
2218 (void *) full_range_set, range->lower.i,
2219 range->upper.i);
2220 } else {
2221 status = bt_integer_range_set_unsigned_add_range(
2222 (void *) full_range_set, range->lower.u,
2223 range->upper.u);
2224 }
2225
2226 if (status) {
2227 goto end;
2228 }
2229 }
2230 }
2231
2232 /* Add new ranges */
2233 for (i = 0; i < range_set->ranges->len; i++) {
2234 struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
2235 range_set, i);
2236
2237 if (is_signed) {
2238 status = bt_integer_range_set_signed_add_range(
2239 (void *) full_range_set, range->lower.i,
2240 range->upper.i);
2241 } else {
2242 status = bt_integer_range_set_unsigned_add_range(
2243 (void *) full_range_set, range->lower.u,
2244 range->upper.u);
2245 }
2246
2247 if (status) {
2248 goto end;
2249 }
2250 }
2251
2252 /* Check overlaps */
2253 if (is_signed) {
2254 *has_overlap = bt_integer_range_set_signed_has_overlaps(full_range_set);
2255 } else {
2256 *has_overlap = bt_integer_range_set_unsigned_has_overlaps(
2257 full_range_set);
2258 }
2259
2260 end:
2261 bt_object_put_ref(full_range_set);
2262 return status;
2263 }
2264
2265 static
2266 int append_option_to_variant_with_selector_field_field_class(
2267 struct bt_field_class *fc, const char *name,
2268 struct bt_field_class *option_fc,
2269 const struct bt_integer_range_set *range_set,
2270 enum bt_field_class_type expected_type,
2271 const char *api_func)
2272 {
2273 int status;
2274 struct bt_field_class_variant_with_selector_field *var_fc = (void *) fc;
2275 struct bt_field_class_variant_with_selector_field_option *opt = NULL;
2276 bool has_overlap;
2277
2278 BT_ASSERT(fc);
2279
2280 /* Name is mandatory in MIP 0, optional later. */
2281 if (fc->mip_version == 0) {
2282 BT_ASSERT_PRE_NAME_NON_NULL_FROM_FUNC(api_func, name);
2283 }
2284
2285 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "option-field-class",
2286 option_fc, "Option field class");
2287 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL_FROM_FUNC(api_func, range_set);
2288 BT_ASSERT_PRE_INT_RANGE_SET_NOT_EMPTY_FROM_FUNC(api_func, range_set);
2289 status = ranges_overlap(var_fc->common.common.named_fcs, range_set,
2290 expected_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
2291 &has_overlap);
2292 if (status) {
2293 /* ranges_overlap() logs errors */
2294 goto end;
2295 }
2296
2297 BT_ASSERT_PRE_FROM_FUNC(api_func, "ranges-do-not-overlap",
2298 !has_overlap,
2299 "Integer range set's ranges and existing ranges have an overlap: "
2300 "%!+R", range_set);
2301 opt = create_variant_with_selector_field_option(name, option_fc, range_set);
2302 if (!opt) {
2303 /* create_variant_with_selector_field_option() logs errors */
2304 status = BT_FUNC_STATUS_MEMORY_ERROR;
2305 goto end;
2306 }
2307
2308 status = append_named_field_class_to_container_field_class((void *) fc,
2309 &opt->common, __func__, VAR_FC_OPT_NAME_IS_UNIQUE_ID);
2310 if (status == BT_FUNC_STATUS_OK) {
2311 /* Moved to the container */
2312 opt = NULL;
2313 }
2314
2315 end:
2316 if (opt) {
2317 destroy_variant_with_selector_field_option(opt);
2318 }
2319
2320 return status;
2321 }
2322
2323 BT_EXPORT
2324 enum bt_field_class_variant_with_selector_field_integer_append_option_status
2325 bt_field_class_variant_with_selector_field_integer_unsigned_append_option(
2326 struct bt_field_class *fc, const char *name,
2327 struct bt_field_class *option_fc,
2328 const struct bt_integer_range_set_unsigned *range_set)
2329 {
2330 BT_ASSERT_PRE_NO_ERROR();
2331 BT_ASSERT_PRE_FC_NON_NULL(fc);
2332 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2333 "variant-field-class-with-unsigned-integer-selector-field",
2334 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
2335 "Field class");
2336 return append_option_to_variant_with_selector_field_field_class(fc,
2337 name, option_fc, (const void *) range_set,
2338 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
2339 __func__);
2340 }
2341
2342 BT_EXPORT
2343 enum bt_field_class_variant_with_selector_field_integer_append_option_status
2344 bt_field_class_variant_with_selector_field_integer_signed_append_option(
2345 struct bt_field_class *fc, const char *name,
2346 struct bt_field_class *option_fc,
2347 const struct bt_integer_range_set_signed *range_set)
2348 {
2349 BT_ASSERT_PRE_NO_ERROR();
2350 BT_ASSERT_PRE_FC_NON_NULL(fc);
2351 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2352 "variant-field-class-with-signed-integer-selector-field",
2353 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
2354 "Field class");
2355 return append_option_to_variant_with_selector_field_field_class(fc,
2356 name, option_fc, (const void *) range_set,
2357 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
2358 __func__);
2359 }
2360
2361 BT_EXPORT
2362 uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc)
2363 {
2364 const struct bt_field_class_variant *var_fc = (const void *) fc;
2365
2366 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2367 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
2368 return (uint64_t) var_fc->common.named_fcs->len;
2369 }
2370
2371 BT_EXPORT
2372 const struct bt_field_class_variant_option *
2373 bt_field_class_variant_borrow_option_by_name_const(
2374 const struct bt_field_class *fc, const char *name)
2375 {
2376 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2377 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
2378 return (const void *)
2379 borrow_named_field_class_from_container_field_class_by_name(
2380 (void *) fc, name, __func__);
2381 }
2382
2383 BT_EXPORT
2384 const struct bt_field_class_variant_option *
2385 bt_field_class_variant_borrow_option_by_index_const(
2386 const struct bt_field_class *fc, uint64_t index)
2387 {
2388 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2389 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
2390 return (const void *)
2391 borrow_named_field_class_from_container_field_class_at_index(
2392 (void *) fc, index, __func__);
2393 }
2394
2395 BT_EXPORT
2396 struct bt_field_class_variant_option *
2397 bt_field_class_variant_borrow_option_by_name(
2398 struct bt_field_class *fc, const char *name)
2399 {
2400 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2401 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
2402 return (void *)
2403 borrow_named_field_class_from_container_field_class_by_name(
2404 (void *) fc, name, __func__);
2405 }
2406
2407 BT_EXPORT
2408 struct bt_field_class_variant_option *
2409 bt_field_class_variant_borrow_option_by_index(
2410 struct bt_field_class *fc, uint64_t index)
2411 {
2412 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2413 BT_ASSERT_PRE_DEV_FC_IS_VARIANT("field-class", fc, "Field class");
2414 return (void *)
2415 borrow_named_field_class_from_container_field_class_at_index(
2416 (void *) fc, index, __func__);
2417 }
2418
2419 BT_EXPORT
2420 const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *
2421 bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_name_const(
2422 const struct bt_field_class *fc, const char *name)
2423 {
2424 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2425 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
2426 "variant-field-class-with-unsigned-integer-selector-field",
2427 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
2428 "Field class");
2429 return (const void *)
2430 borrow_named_field_class_from_container_field_class_by_name(
2431 (void *) fc, name, __func__);
2432 }
2433
2434 BT_EXPORT
2435 const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *
2436 bt_field_class_variant_with_selector_field_integer_unsigned_borrow_option_by_index_const(
2437 const struct bt_field_class *fc, uint64_t index)
2438 {
2439 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2440 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
2441 "variant-field-class-with-unsigned-integer-selector-field",
2442 BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD,
2443 "Field class");
2444 return (const void *)
2445 borrow_named_field_class_from_container_field_class_at_index(
2446 (void *) fc, index, __func__);
2447 }
2448
2449 BT_EXPORT
2450 const struct bt_field_class_variant_with_selector_field_integer_signed_option *
2451 bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_name_const(
2452 const struct bt_field_class *fc, const char *name)
2453 {
2454 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2455 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
2456 "variant-field-class-with-signed-integer-selector-field",
2457 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
2458 "Field class");
2459 return (const void *)
2460 borrow_named_field_class_from_container_field_class_by_name(
2461 (void *) fc, name, __func__);
2462 }
2463
2464 BT_EXPORT
2465 const struct bt_field_class_variant_with_selector_field_integer_signed_option *
2466 bt_field_class_variant_with_selector_field_integer_signed_borrow_option_by_index_const(
2467 const struct bt_field_class *fc, uint64_t index)
2468 {
2469 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2470 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
2471 "variant-field-class-with-signed-integer-selector-field",
2472 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD,
2473 "Field class");
2474 return (const void *)
2475 borrow_named_field_class_from_container_field_class_at_index(
2476 (void *) fc, index, __func__);
2477 }
2478
2479 BT_EXPORT
2480 const char *bt_field_class_variant_option_get_name(
2481 const struct bt_field_class_variant_option *option)
2482 {
2483 const struct bt_named_field_class *named_fc = (const void *) option;
2484
2485 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
2486
2487 /* MIP > 0: a variant field class option may have no name */
2488 return named_fc->name ? named_fc->name->str : NULL;
2489 }
2490
2491 BT_EXPORT
2492 const struct bt_field_class *
2493 bt_field_class_variant_option_borrow_field_class_const(
2494 const struct bt_field_class_variant_option *option)
2495 {
2496 const struct bt_named_field_class *named_fc = (const void *) option;
2497
2498 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
2499 return named_fc->fc;
2500 }
2501
2502 BT_EXPORT
2503 struct bt_field_class *
2504 bt_field_class_variant_option_borrow_field_class(
2505 struct bt_field_class_variant_option *option)
2506 {
2507 struct bt_named_field_class *named_fc = (void *) option;
2508
2509 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
2510 return named_fc->fc;
2511 }
2512
2513 BT_EXPORT
2514 const struct bt_integer_range_set_unsigned *
2515 bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const(
2516 const struct bt_field_class_variant_with_selector_field_integer_unsigned_option *option)
2517 {
2518 const struct bt_field_class_variant_with_selector_field_option *opt =
2519 (const void *) option;
2520
2521 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
2522 return (const void *) opt->range_set;
2523 }
2524
2525 BT_EXPORT
2526 const struct bt_integer_range_set_signed *
2527 bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const(
2528 const struct bt_field_class_variant_with_selector_field_integer_signed_option *option)
2529 {
2530 const struct bt_field_class_variant_with_selector_field_option *opt =
2531 (const void *) option;
2532
2533 BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
2534 return (const void *) opt->range_set;
2535 }
2536
2537 BT_EXPORT
2538 const struct bt_field_path *
2539 bt_field_class_variant_with_selector_field_borrow_selector_field_path_const(
2540 const struct bt_field_class *fc)
2541 {
2542 const struct bt_field_class_variant_with_selector_field *var_fc =
2543 (const void *) fc;
2544
2545 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2546 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL("field-class", fc,
2547 "Field class");
2548 BT_ASSERT_PRE_FC_MIP_VERSION_EQ(fc, 0);
2549 BT_ASSERT_DBG(var_fc->selector_field_xref_kind == FIELD_XREF_KIND_PATH);
2550 return var_fc->selector_field.path.path;
2551 }
2552
2553 BT_EXPORT
2554 const struct bt_field_location *
2555 bt_field_class_variant_with_selector_field_borrow_selector_field_location_const(
2556 const struct bt_field_class *fc)
2557 {
2558 const struct bt_field_class_variant_with_selector_field *var_fc =
2559 (const void *) fc;
2560
2561 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2562 BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL("field-class", fc,
2563 "Field class");
2564 BT_ASSERT_PRE_DEV_FC_MIP_VERSION_GE(fc, 1);
2565 BT_ASSERT_DBG(var_fc->selector_field_xref_kind == FIELD_XREF_KIND_LOCATION);
2566 return var_fc->selector_field.location;
2567 }
2568
2569 static
2570 int init_array_field_class(struct bt_field_class_array *fc,
2571 enum bt_field_class_type type, bt_object_release_func release_func,
2572 struct bt_field_class *element_fc,
2573 const struct bt_trace_class *trace_class)
2574 {
2575 int ret;
2576
2577 BT_ASSERT(element_fc);
2578 ret = init_field_class((void *) fc, type, release_func,
2579 trace_class);
2580 if (ret) {
2581 goto end;
2582 }
2583
2584 fc->element_fc = element_fc;
2585 bt_object_get_ref_no_null_check(fc->element_fc);
2586 bt_field_class_freeze(element_fc);
2587
2588 end:
2589 return ret;
2590 }
2591
2592 static
2593 void finalize_array_field_class(struct bt_field_class_array *array_fc)
2594 {
2595 BT_ASSERT(array_fc);
2596 BT_LOGD_STR("Putting element field class.");
2597 finalize_field_class((void *) array_fc);
2598 BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc);
2599 }
2600
2601 static
2602 void destroy_static_array_field_class(struct bt_object *obj)
2603 {
2604 BT_ASSERT(obj);
2605 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj);
2606 finalize_array_field_class((void *) obj);
2607 g_free(obj);
2608 }
2609
2610 BT_EXPORT
2611 struct bt_field_class *
2612 bt_field_class_array_static_create(bt_trace_class *trace_class,
2613 struct bt_field_class *element_fc, uint64_t length)
2614 {
2615 struct bt_field_class_array_static *array_fc = NULL;
2616
2617 BT_ASSERT_PRE_NO_ERROR();
2618 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2619 BT_ASSERT_PRE_NON_NULL("element-field-class", element_fc,
2620 "Element field class");
2621 BT_LOGD_STR("Creating default static array field class object.");
2622 array_fc = g_new0(struct bt_field_class_array_static, 1);
2623 if (!array_fc) {
2624 BT_LIB_LOGE_APPEND_CAUSE(
2625 "Failed to allocate one static array field class.");
2626 goto error;
2627 }
2628
2629 if (init_array_field_class((void *) array_fc,
2630 BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
2631 destroy_static_array_field_class, element_fc,
2632 trace_class)) {
2633 goto error;
2634 }
2635
2636 array_fc->length = length;
2637 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc);
2638 goto end;
2639
2640 error:
2641 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2642
2643 end:
2644 return (void *) array_fc;
2645 }
2646
2647 BT_EXPORT
2648 const struct bt_field_class *
2649 bt_field_class_array_borrow_element_field_class_const(
2650 const struct bt_field_class *fc)
2651 {
2652 const struct bt_field_class_array *array_fc = (const void *) fc;
2653
2654 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2655 BT_ASSERT_PRE_DEV_FC_IS_ARRAY("field-class", fc, "Field class");
2656 return array_fc->element_fc;
2657 }
2658
2659 BT_EXPORT
2660 struct bt_field_class *
2661 bt_field_class_array_borrow_element_field_class(struct bt_field_class *fc)
2662 {
2663 struct bt_field_class_array *array_fc = (void *) fc;
2664
2665 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2666 BT_ASSERT_PRE_DEV_FC_IS_ARRAY("field-class", fc, "Field class");
2667 return array_fc->element_fc;
2668 }
2669
2670 BT_EXPORT
2671 uint64_t bt_field_class_array_static_get_length(const struct bt_field_class *fc)
2672 {
2673 const struct bt_field_class_array_static *array_fc = (const void *) fc;
2674
2675 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
2676 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
2677 "static-array-field-class", BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
2678 "Field class");
2679 return (uint64_t) array_fc->length;
2680 }
2681
2682 static
2683 void destroy_dynamic_array_field_class(struct bt_object *obj)
2684 {
2685 struct bt_field_class_array_dynamic *fc = (void *) obj;
2686
2687 BT_ASSERT(fc);
2688 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc);
2689 finalize_array_field_class((void *) fc);
2690
2691 if (fc->common.common.type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) {
2692 switch (fc->length_field.xref_kind) {
2693 case FIELD_XREF_KIND_PATH:
2694 BT_LOGD_STR("Putting length field class.");
2695 BT_OBJECT_PUT_REF_AND_RESET(fc->length_field.path.class);
2696 fc->length_field.path.class = NULL;
2697
2698 BT_LOGD_STR("Putting length field path.");
2699 BT_OBJECT_PUT_REF_AND_RESET(fc->length_field.path.path);
2700 fc->length_field.path.path = NULL;
2701 break;
2702 case FIELD_XREF_KIND_LOCATION:
2703 BT_LOGD_STR("Putting length field location.");
2704 BT_OBJECT_PUT_REF_AND_RESET(fc->length_field.location);
2705 fc->length_field.location = NULL;
2706 break;
2707 };
2708 }
2709
2710 g_free(fc);
2711 }
2712
2713 static
2714 struct bt_field_class_array_dynamic *create_dynamic_array_field_class(
2715 struct bt_trace_class *trace_class,
2716 struct bt_field_class *element_fc,
2717 enum bt_field_class_type fc_type,
2718 const char *api_func)
2719 {
2720 struct bt_field_class_array_dynamic *array_fc = NULL;
2721
2722 BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "element-field-class", element_fc,
2723 "Element field class");
2724 BT_LOGD_STR("Creating default dynamic array field class object.");
2725 array_fc = g_new0(struct bt_field_class_array_dynamic, 1);
2726 if (!array_fc) {
2727 BT_LIB_LOGE_APPEND_CAUSE(
2728 "Failed to allocate one dynamic array field class.");
2729 goto error;
2730 }
2731
2732 if (init_array_field_class((void *) array_fc, fc_type,
2733 destroy_dynamic_array_field_class, element_fc,
2734 trace_class)) {
2735 goto error;
2736 }
2737
2738 goto end;
2739
2740 error:
2741 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2742
2743 end:
2744 return array_fc;
2745 }
2746
2747 BT_EXPORT
2748 struct bt_field_class *bt_field_class_array_dynamic_create(
2749 struct bt_trace_class *trace_class,
2750 struct bt_field_class *element_fc,
2751 struct bt_field_class *length_fc)
2752 {
2753 struct bt_field_class_array_dynamic *array_fc = NULL;
2754
2755
2756 BT_ASSERT_PRE_NO_ERROR();
2757 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2758 BT_ASSERT_PRE_TC_MIP_VERSION_EQ(trace_class, 0);
2759
2760 array_fc = create_dynamic_array_field_class(trace_class, element_fc,
2761 length_fc ?
2762 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD :
2763 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD,
2764 __func__);
2765 if (!array_fc) {
2766 goto error;
2767 }
2768
2769 if (length_fc) {
2770 array_fc->length_field.xref_kind = FIELD_XREF_KIND_PATH;
2771
2772 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT("length-field-class",
2773 length_fc, "Length field class");
2774 array_fc->length_field.path.class = length_fc;
2775 bt_object_get_ref_no_null_check(length_fc);
2776 bt_field_class_freeze(length_fc);
2777 }
2778
2779 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc);
2780
2781 goto end;
2782
2783 error:
2784 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2785
2786 end:
2787 return (void *) array_fc;
2788 }
2789
2790 BT_EXPORT
2791 struct bt_field_class *bt_field_class_array_dynamic_without_length_field_location_create(
2792 struct bt_trace_class *trace_class,
2793 struct bt_field_class *element_field_class)
2794 {
2795 struct bt_field_class_array_dynamic *array_fc = NULL;
2796
2797 BT_ASSERT_PRE_NO_ERROR();
2798 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2799 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
2800
2801 array_fc = create_dynamic_array_field_class(trace_class,
2802 element_field_class, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD,
2803 __func__);
2804 if (!array_fc) {
2805 goto error;
2806 }
2807
2808 BT_LIB_LOGD("Created dynamic array field class without field location object: %!+F",
2809 array_fc);
2810
2811 goto end;
2812
2813 error:
2814 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2815
2816 end:
2817 return (void *) array_fc;
2818 }
2819
2820 BT_EXPORT
2821 struct bt_field_class *bt_field_class_array_dynamic_with_length_field_location_create(
2822 struct bt_trace_class *trace_class,
2823 struct bt_field_class *element_field_class,
2824 const struct bt_field_location *length_field_location)
2825 {
2826 struct bt_field_class_array_dynamic *array_fc = NULL;
2827
2828 BT_ASSERT_PRE_NO_ERROR();
2829 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2830 BT_ASSERT_PRE_FL_NON_NULL(length_field_location);
2831 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
2832
2833 array_fc = create_dynamic_array_field_class(trace_class,
2834 element_field_class, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD,
2835 __func__);
2836 if (!array_fc) {
2837 goto error;
2838 }
2839
2840 array_fc->length_field.xref_kind = FIELD_XREF_KIND_LOCATION;
2841 array_fc->length_field.location = length_field_location;
2842 bt_object_get_ref_no_null_check(length_field_location);
2843
2844 BT_LIB_LOGD("Created dynamic array field class with field location object: %!+F",
2845 array_fc);
2846
2847 goto end;
2848
2849 error:
2850 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
2851
2852 end:
2853 return (void *) array_fc;
2854 }
2855
2856 BT_EXPORT
2857 const struct bt_field_path *
2858 bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const(
2859 const struct bt_field_class *fc)
2860 {
2861 const struct bt_field_class_array_dynamic *seq_fc = (const void *) fc;
2862
2863 BT_ASSERT_PRE_NO_ERROR();
2864 BT_ASSERT_PRE_FC_NON_NULL(fc);
2865 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2866 "dynamic-array-field-class-with-length-field",
2867 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD,
2868 "Field class");
2869 BT_ASSERT_PRE_FC_MIP_VERSION_EQ(fc, 0);
2870 BT_ASSERT_DBG(seq_fc->length_field.xref_kind == FIELD_XREF_KIND_PATH);
2871 return seq_fc->length_field.path.path;
2872 }
2873
2874 BT_EXPORT
2875 const struct bt_field_location *
2876 bt_field_class_array_dynamic_with_length_field_borrow_length_field_location_const(
2877 const struct bt_field_class *fc)
2878 {
2879 const struct bt_field_class_array_dynamic *seq_fc = (const void *) fc;
2880
2881 BT_ASSERT_PRE_NO_ERROR();
2882 BT_ASSERT_PRE_FC_NON_NULL(fc);
2883 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
2884 "dynamic-array-field-class-with-length-field",
2885 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD,
2886 "Field class");
2887 BT_ASSERT_PRE_FC_MIP_VERSION_GE(fc, 1);
2888 BT_ASSERT_DBG(seq_fc->length_field.xref_kind == FIELD_XREF_KIND_LOCATION);
2889 return seq_fc->length_field.location;
2890 }
2891
2892 static
2893 void destroy_string_field_class(struct bt_object *obj)
2894 {
2895 BT_ASSERT(obj);
2896 BT_LIB_LOGD("Destroying string field class object: %!+F", obj);
2897 finalize_field_class((void *) obj);
2898 g_free(obj);
2899 }
2900
2901 BT_EXPORT
2902 struct bt_field_class *bt_field_class_string_create(bt_trace_class *trace_class)
2903 {
2904 struct bt_field_class_string *string_fc = NULL;
2905
2906 BT_ASSERT_PRE_NO_ERROR();
2907 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
2908 BT_LOGD_STR("Creating default string field class object.");
2909 string_fc = g_new0(struct bt_field_class_string, 1);
2910 if (!string_fc) {
2911 BT_LIB_LOGE_APPEND_CAUSE(
2912 "Failed to allocate one string field class.");
2913 goto error;
2914 }
2915
2916 if (init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING,
2917 destroy_string_field_class, trace_class)) {
2918 goto error;
2919 }
2920
2921 BT_LIB_LOGD("Created string field class object: %!+F", string_fc);
2922 goto end;
2923
2924 error:
2925 BT_OBJECT_PUT_REF_AND_RESET(string_fc);
2926
2927 end:
2928 return (void *) string_fc;
2929 }
2930
2931 void _bt_field_class_freeze(const struct bt_field_class *c_fc)
2932 {
2933 struct bt_field_class *fc = (void *) c_fc;
2934
2935 /*
2936 * Element/member/option field classes are frozen when added to
2937 * their owner.
2938 */
2939 BT_ASSERT(fc);
2940 bt_value_freeze(fc->user_attributes);
2941 fc->frozen = true;
2942
2943 if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
2944 bt_field_class_type_is(fc->type,
2945 BT_FIELD_CLASS_TYPE_VARIANT)) {
2946 struct bt_field_class_named_field_class_container *container_fc =
2947 (void *) fc;
2948 uint64_t i;
2949
2950 for (i = 0; i < container_fc->named_fcs->len; i++) {
2951 bt_named_field_class_freeze(
2952 container_fc->named_fcs->pdata[i]);
2953 }
2954 }
2955 }
2956
2957 void _bt_named_field_class_freeze(const struct bt_named_field_class *named_fc)
2958 {
2959 BT_ASSERT(named_fc);
2960 BT_ASSERT(named_fc->fc->frozen);
2961 BT_LIB_LOGD("Freezing named field class's user attributes: %!+v",
2962 named_fc->user_attributes);
2963 bt_value_freeze(named_fc->user_attributes);
2964 ((struct bt_named_field_class *) named_fc)->frozen = true;
2965 }
2966
2967 void bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc)
2968 {
2969 struct bt_field_class *fc = (void *) c_fc;
2970
2971 BT_ASSERT(fc);
2972 BT_ASSERT_PRE("field-class-is-not-part-of-trace-class",
2973 !fc->part_of_trace_class,
2974 "Field class is already part of a trace class: %!+F", fc);
2975 fc->part_of_trace_class = true;
2976
2977 if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
2978 bt_field_class_type_is(fc->type,
2979 BT_FIELD_CLASS_TYPE_VARIANT)) {
2980 struct bt_field_class_named_field_class_container *container_fc =
2981 (void *) fc;
2982 uint64_t i;
2983
2984 for (i = 0; i < container_fc->named_fcs->len; i++) {
2985 struct bt_named_field_class *named_fc =
2986 container_fc->named_fcs->pdata[i];
2987
2988 bt_field_class_make_part_of_trace_class(named_fc->fc);
2989 }
2990 } else if (bt_field_class_type_is(fc->type,
2991 BT_FIELD_CLASS_TYPE_ARRAY)) {
2992 struct bt_field_class_array *array_fc = (void *) fc;
2993
2994 bt_field_class_make_part_of_trace_class(array_fc->element_fc);
2995 }
2996 }
2997
2998 BT_EXPORT
2999 const struct bt_value *bt_field_class_borrow_user_attributes_const(
3000 const struct bt_field_class *fc)
3001 {
3002 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
3003 return fc->user_attributes;
3004 }
3005
3006 BT_EXPORT
3007 struct bt_value *bt_field_class_borrow_user_attributes(
3008 struct bt_field_class *field_class)
3009 {
3010 return (void *) bt_field_class_borrow_user_attributes_const(
3011 (void *) field_class);
3012 }
3013
3014
3015 BT_EXPORT
3016 void bt_field_class_set_user_attributes(
3017 struct bt_field_class *fc,
3018 const struct bt_value *user_attributes)
3019 {
3020 BT_ASSERT_PRE_FC_NON_NULL(fc);
3021 BT_ASSERT_PRE_USER_ATTRS_NON_NULL(user_attributes);
3022 BT_ASSERT_PRE_USER_ATTRS_IS_MAP(user_attributes);
3023 BT_ASSERT_PRE_DEV_FC_HOT(fc);
3024 bt_object_put_ref_no_null_check(fc->user_attributes);
3025 fc->user_attributes = (void *) user_attributes;
3026 bt_object_get_ref_no_null_check(fc->user_attributes);
3027 }
3028
3029 static
3030 const struct bt_value *bt_named_field_class_borrow_user_attributes_const(
3031 const struct bt_named_field_class *named_fc)
3032 {
3033 return named_fc->user_attributes;
3034 }
3035
3036 static
3037 void set_named_field_class_user_attributes(
3038 struct bt_named_field_class *named_fc,
3039 const struct bt_value *user_attributes, const char *api_func)
3040 {
3041 BT_ASSERT_PRE_USER_ATTRS_NON_NULL_FROM_FUNC(api_func, user_attributes);
3042 BT_ASSERT_PRE_USER_ATTRS_NON_NULL_FROM_FUNC(api_func, user_attributes);
3043 bt_object_put_ref_no_null_check(named_fc->user_attributes);
3044 named_fc->user_attributes = (void *) user_attributes;
3045 bt_object_get_ref_no_null_check(named_fc->user_attributes);
3046 }
3047
3048 BT_EXPORT
3049 const struct bt_value *
3050 bt_field_class_structure_member_borrow_user_attributes_const(
3051 const struct bt_field_class_structure_member *member)
3052 {
3053 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
3054 return bt_named_field_class_borrow_user_attributes_const(
3055 (const void *) member);
3056 }
3057
3058 BT_EXPORT
3059 struct bt_value *
3060 bt_field_class_structure_member_borrow_user_attributes(
3061 struct bt_field_class_structure_member *member)
3062 {
3063 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
3064 return (void *) bt_named_field_class_borrow_user_attributes_const(
3065 (void *) member);
3066 }
3067
3068 BT_EXPORT
3069 void bt_field_class_structure_member_set_user_attributes(
3070 struct bt_field_class_structure_member *member,
3071 const struct bt_value *user_attributes)
3072 {
3073 BT_ASSERT_PRE_STRUCT_FC_MEMBER_NON_NULL(member);
3074 BT_ASSERT_PRE_DEV_HOT("structure-field-class-member",
3075 (struct bt_named_field_class *) member,
3076 "Structure field class member", ".");
3077 set_named_field_class_user_attributes((void *) member,
3078 user_attributes, __func__);
3079 }
3080
3081 BT_EXPORT
3082 const struct bt_value *bt_field_class_variant_option_borrow_user_attributes_const(
3083 const struct bt_field_class_variant_option *option)
3084 {
3085 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
3086 return bt_named_field_class_borrow_user_attributes_const(
3087 (const void *) option);
3088 }
3089
3090 BT_EXPORT
3091 struct bt_value *bt_field_class_variant_option_borrow_user_attributes(
3092 struct bt_field_class_variant_option *option)
3093 {
3094 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
3095 return (void *) bt_named_field_class_borrow_user_attributes_const(
3096 (void *) option);
3097 }
3098
3099 BT_EXPORT
3100 void bt_field_class_variant_option_set_user_attributes(
3101 struct bt_field_class_variant_option *option,
3102 const struct bt_value *user_attributes)
3103 {
3104 BT_ASSERT_PRE_VAR_FC_OPT_NON_NULL(option);
3105 BT_ASSERT_PRE_DEV_HOT("variant-field-class-option",
3106 (struct bt_named_field_class *) option,
3107 "Variant field class option", ".");
3108 set_named_field_class_user_attributes((void *) option,
3109 user_attributes, __func__);
3110 }
3111
3112 BT_EXPORT
3113 bt_field_class_blob_set_media_type_status bt_field_class_blob_set_media_type(
3114 struct bt_field_class *fc, const char *media_type)
3115 {
3116 struct bt_field_class_blob *fc_blob = (void *) fc;
3117
3118 BT_ASSERT_PRE_FC_NON_NULL(fc);
3119 BT_ASSERT_PRE_FC_IS_BLOB("field-class", fc, "Field class");
3120 BT_ASSERT_PRE_DEV_FC_HOT(fc);
3121 BT_ASSERT_PRE_NON_NULL("media-type", media_type, "Media type");
3122
3123 g_string_assign(fc_blob->media_type, media_type);
3124
3125 return BT_FIELD_CLASS_BLOB_SET_MEDIA_TYPE_STATUS_OK;
3126 }
3127
3128 BT_EXPORT
3129 const char *bt_field_class_blob_get_media_type(
3130 const bt_field_class *fc)
3131 {
3132 struct bt_field_class_blob *fc_blob = (void *) fc;
3133
3134 BT_ASSERT_PRE_FC_NON_NULL(fc);
3135 BT_ASSERT_PRE_FC_IS_BLOB("field-class", fc, "Field class");
3136
3137 return fc_blob->media_type->str;
3138 }
3139
3140 static
3141 int init_blob_field_class(struct bt_field_class_blob *fc,
3142 enum bt_field_class_type type,
3143 bt_object_release_func release_func,
3144 bt_trace_class *trace_class)
3145 {
3146 int ret;
3147
3148 ret = init_field_class((void *) fc, type, release_func,
3149 trace_class);
3150 if (ret) {
3151 goto end;
3152 }
3153
3154 fc->media_type = g_string_new("application/octet-stream");
3155
3156 end:
3157 return ret;
3158 }
3159
3160 static
3161 void destroy_blob_field_class(struct bt_object *obj)
3162 {
3163 struct bt_field_class_blob *blob = (void *) obj;
3164
3165 BT_ASSERT(obj);
3166 g_string_free(blob->media_type, TRUE);
3167 finalize_field_class((void *) obj);
3168 g_free(obj);
3169 }
3170
3171 static
3172 void destroy_static_blob_field_class(struct bt_object *obj)
3173 {
3174 struct bt_field_class_blob_static *fc = (void *) obj;
3175
3176 BT_ASSERT(fc);
3177 BT_LIB_LOGD("Destroying static BLOB field class object: %!+F", fc);
3178
3179 destroy_blob_field_class(obj);
3180 }
3181
3182 BT_EXPORT
3183 struct bt_field_class *bt_field_class_blob_static_create(
3184 struct bt_trace_class *trace_class, uint64_t length)
3185 {
3186 struct bt_field_class_blob_static *blob_fc = NULL;
3187 int ret;
3188
3189 BT_ASSERT_PRE_NO_ERROR();
3190 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
3191 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
3192
3193 BT_LOGD_STR("Creating default static BLOB field class object.");
3194 blob_fc = g_new0(struct bt_field_class_blob_static, 1);
3195 if (!blob_fc) {
3196 BT_LIB_LOGE_APPEND_CAUSE(
3197 "Failed to allocate one static BLOB field class.");
3198 goto error;
3199 }
3200
3201 ret = init_blob_field_class((void *) blob_fc,
3202 BT_FIELD_CLASS_TYPE_STATIC_BLOB,
3203 destroy_static_blob_field_class,
3204 trace_class);
3205 if (ret) {
3206 goto end;
3207 }
3208
3209 blob_fc->length = length;
3210 BT_LIB_LOGD("Created static BLOB field class object: %!+F", blob_fc);
3211 goto end;
3212
3213 error:
3214 BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
3215
3216 end:
3217 return (void *) blob_fc;
3218 }
3219
3220 BT_EXPORT
3221 uint64_t bt_field_class_blob_static_get_length(
3222 const bt_field_class *fc)
3223 {
3224 const struct bt_field_class_blob_static *blob_fc = (const void *) fc;
3225
3226 BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
3227 BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
3228 "static-blob-field-class", BT_FIELD_CLASS_TYPE_STATIC_BLOB,
3229 "Field class");
3230
3231 return blob_fc->length;
3232 }
3233
3234 static
3235 void destroy_dynamic_blob_field_class(struct bt_object *obj)
3236 {
3237 struct bt_field_class_blob_dynamic *fc = (void *) obj;
3238
3239 BT_ASSERT(fc);
3240 BT_LIB_LOGD("Destroying dynamic BLOB field class object: %!+F", fc);
3241
3242 bt_object_put_ref(fc->length_fl);
3243 fc->length_fl = NULL;
3244
3245 destroy_blob_field_class(obj);
3246 }
3247
3248 static
3249 struct bt_field_class_blob_dynamic *create_dynamic_blob_field_class(
3250 struct bt_trace_class *trace_class, enum bt_field_class_type type)
3251 {
3252 struct bt_field_class_blob_dynamic *blob_fc = NULL;
3253 int ret;
3254
3255 BT_LOGD_STR("Creating default dynamic BLOB field class object.");
3256 blob_fc = g_new0(struct bt_field_class_blob_dynamic, 1);
3257 if (!blob_fc) {
3258 BT_LIB_LOGE_APPEND_CAUSE(
3259 "Failed to allocate one dynamic BLOB field class.");
3260 goto error;
3261 }
3262
3263 ret = init_blob_field_class((void *) blob_fc, type,
3264 destroy_dynamic_blob_field_class, trace_class);
3265 if (ret) {
3266 goto error;
3267 }
3268
3269 goto end;
3270
3271 error:
3272 BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
3273
3274 end:
3275 return blob_fc;
3276 }
3277
3278 BT_EXPORT
3279 struct bt_field_class *bt_field_class_blob_dynamic_without_length_field_location_create(
3280 struct bt_trace_class *trace_class)
3281 {
3282 struct bt_field_class_blob_dynamic *blob_fc = NULL;
3283
3284 BT_ASSERT_PRE_NO_ERROR();
3285 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
3286 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
3287
3288 blob_fc = create_dynamic_blob_field_class(trace_class,
3289 BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD);
3290 if (!blob_fc) {
3291 goto error;
3292 }
3293
3294 BT_LIB_LOGD("Created dynamic BLOB field class without field location object: %!+F",
3295 blob_fc);
3296
3297 goto end;
3298
3299 error:
3300 BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
3301
3302 end:
3303 return (void *) blob_fc;
3304 }
3305
3306 BT_EXPORT
3307 struct bt_field_class *bt_field_class_blob_dynamic_with_length_field_location_create(
3308 bt_trace_class *trace_class,
3309 const bt_field_location *length_field_location)
3310 {
3311 struct bt_field_class_blob_dynamic *blob_fc = NULL;
3312
3313 BT_ASSERT_PRE_NO_ERROR();
3314 BT_ASSERT_PRE_TC_NON_NULL(trace_class);
3315 BT_ASSERT_PRE_FL_NON_NULL(length_field_location);
3316 BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
3317
3318 blob_fc = create_dynamic_blob_field_class(trace_class,
3319 BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD);
3320 if (!blob_fc) {
3321 goto error;
3322 }
3323
3324 blob_fc->length_fl = length_field_location;
3325 bt_object_get_ref_no_null_check(length_field_location);
3326
3327 BT_LIB_LOGD("Created dynamic BLOB field class with field location object: %!+F",
3328 blob_fc);
3329
3330 goto end;
3331
3332 error:
3333 BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
3334
3335 end:
3336 return (void *) blob_fc;
3337 }
3338
3339 BT_EXPORT
3340 const bt_field_location *
3341 bt_field_class_blob_dynamic_with_length_field_borrow_length_field_location_const(
3342 const bt_field_class *fc)
3343 {
3344 const struct bt_field_class_blob_dynamic *blob_fc = (const void *) fc;
3345
3346 BT_ASSERT_PRE_NO_ERROR();
3347 BT_ASSERT_PRE_FC_NON_NULL(fc);
3348 BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
3349 "dynamic-blob-field-class-with-length-field",
3350 BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD,
3351 "Field class");
3352 BT_ASSERT_PRE_FC_MIP_VERSION_GE(fc, 1);
3353 BT_ASSERT(blob_fc->length_fl);
3354
3355 return blob_fc->length_fl;
3356 }
3357
3358 BT_EXPORT
3359 void bt_field_class_get_ref(const struct bt_field_class *field_class)
3360 {
3361 bt_object_get_ref(field_class);
3362 }
3363
3364 BT_EXPORT
3365 void bt_field_class_put_ref(const struct bt_field_class *field_class)
3366 {
3367 bt_object_put_ref(field_class);
3368 }
This page took 0.124195 seconds and 5 git commands to generate.