lib: rename `lib-logging.h` to `logging.h`
[babeltrace.git] / src / lib / trace-ir / field-class.c
CommitLineData
5cd6d0e5 1/*
e2f7325d 2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
5cd6d0e5
PP
3 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5cd6d0e5
PP
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
350ad6c1 24#define BT_LOG_TAG "LIB/FIELD-CLASS"
c2d9d9cf 25#include "lib/logging.h"
5cd6d0e5 26
578e048b 27#include "lib/assert-pre.h"
3fadfbc0
MJ
28#include <babeltrace2/trace-ir/field-class.h>
29#include <babeltrace2/trace-ir/field-class-const.h>
3fadfbc0
MJ
30#include <babeltrace2/trace-ir/field-const.h>
31#include <babeltrace2/trace-ir/field.h>
3fadfbc0 32#include <babeltrace2/trace-ir/clock-class.h>
578e048b
MJ
33#include "lib/object.h"
34#include "compat/compiler.h"
35#include "compat/endian.h"
36#include "common/assert.h"
37#include "compat/glib.h"
5cd6d0e5
PP
38#include <float.h>
39#include <inttypes.h>
40#include <stdlib.h>
41
578e048b
MJ
42#include "clock-class.h"
43#include "field-class.h"
44#include "field.h"
45#include "field-path.h"
46#include "utils.h"
47
40f4ba76
PP
48enum bt_field_class_type bt_field_class_get_type(
49 const struct bt_field_class *fc)
5cd6d0e5
PP
50{
51 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 52 return fc->type;
5cd6d0e5
PP
53}
54
55static
864cad70 56void init_field_class(struct bt_field_class *fc, enum bt_field_class_type type,
5cd6d0e5
PP
57 bt_object_release_func release_func)
58{
59 BT_ASSERT(fc);
864cad70 60 BT_ASSERT(bt_field_class_has_known_type(fc));
5cd6d0e5
PP
61 BT_ASSERT(release_func);
62 bt_object_init_shared(&fc->base, release_func);
864cad70 63 fc->type = type;
5cd6d0e5
PP
64}
65
66static
864cad70
PP
67void init_integer_field_class(struct bt_field_class_integer *fc,
68 enum bt_field_class_type type,
5cd6d0e5
PP
69 bt_object_release_func release_func)
70{
864cad70 71 init_field_class((void *) fc, type, release_func);
5cd6d0e5
PP
72 fc->range = 64;
73 fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
74}
75
76static
77void destroy_integer_field_class(struct bt_object *obj)
78{
79 BT_ASSERT(obj);
e5be10ef 80 BT_LIB_LOGD("Destroying integer field class object: %!+F", obj);
5cd6d0e5
PP
81 g_free(obj);
82}
83
84static inline
1122a43a
PP
85struct bt_field_class *create_integer_field_class(bt_trace_class *trace_class,
86 enum bt_field_class_type type)
5cd6d0e5
PP
87{
88 struct bt_field_class_integer *int_fc = NULL;
89
1122a43a 90 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 91 BT_LOGD("Creating default integer field class object: type=%s",
864cad70 92 bt_common_field_class_type_string(type));
5cd6d0e5
PP
93 int_fc = g_new0(struct bt_field_class_integer, 1);
94 if (!int_fc) {
e5be10ef 95 BT_LOGE_STR("Failed to allocate one integer field class.");
5cd6d0e5
PP
96 goto error;
97 }
98
864cad70 99 init_integer_field_class(int_fc, type, destroy_integer_field_class);
e5be10ef 100 BT_LIB_LOGD("Created integer field class object: %!+F", int_fc);
5cd6d0e5
PP
101 goto end;
102
103error:
65300d60 104 BT_OBJECT_PUT_REF_AND_RESET(int_fc);
5cd6d0e5
PP
105
106end:
107 return (void *) int_fc;
108}
109
1122a43a
PP
110struct bt_field_class *bt_field_class_unsigned_integer_create(
111 bt_trace_class *trace_class)
5cd6d0e5 112{
1122a43a 113 return create_integer_field_class(trace_class,
e5be10ef 114 BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER);
5cd6d0e5
PP
115}
116
1122a43a
PP
117struct bt_field_class *bt_field_class_signed_integer_create(
118 bt_trace_class *trace_class)
5cd6d0e5 119{
1122a43a 120 return create_integer_field_class(trace_class,
e5be10ef 121 BT_FIELD_CLASS_TYPE_SIGNED_INTEGER);
5cd6d0e5
PP
122}
123
124uint64_t bt_field_class_integer_get_field_value_range(
40f4ba76 125 const struct bt_field_class *fc)
5cd6d0e5 126{
40f4ba76 127 const struct bt_field_class_integer *int_fc = (const void *) fc;
5cd6d0e5
PP
128
129 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
130 BT_ASSERT_PRE_FC_IS_INT(fc, "Field class");
131 return int_fc->range;
132}
133
134BT_ASSERT_PRE_FUNC
135static
136bool size_is_valid_for_enumeration_field_class(struct bt_field_class *fc,
137 uint64_t size)
138{
139 // TODO
140 return true;
141}
142
40f4ba76
PP
143void bt_field_class_integer_set_field_value_range(
144 struct bt_field_class *fc, uint64_t size)
5cd6d0e5
PP
145{
146 struct bt_field_class_integer *int_fc = (void *) fc;
147
148 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
149 BT_ASSERT_PRE_FC_IS_INT(fc, "Field class");
150 BT_ASSERT_PRE_FC_HOT(fc, "Field class");
151 BT_ASSERT_PRE(size <= 64,
e5be10ef 152 "Unsupported size for integer field class's field value range "
5cd6d0e5 153 "(maximum is 64): size=%" PRIu64, size);
864cad70
PP
154 BT_ASSERT_PRE(
155 int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
156 int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
5cd6d0e5 157 size_is_valid_for_enumeration_field_class(fc, size),
e5be10ef 158 "Invalid field value range for enumeration field class: "
5cd6d0e5
PP
159 "at least one of the current mapping ranges contains values "
160 "which are outside this range: %!+F, size=%" PRIu64, fc, size);
161 int_fc->range = size;
3f7d4d90 162 BT_LIB_LOGD("Set integer field class's field value range: %!+F", fc);
5cd6d0e5
PP
163}
164
165enum bt_field_class_integer_preferred_display_base
40f4ba76 166bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc)
5cd6d0e5 167{
40f4ba76 168 const struct bt_field_class_integer *int_fc = (const void *) fc;
5cd6d0e5
PP
169
170 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
171 BT_ASSERT_PRE_FC_IS_INT(fc, "Field class");
172 return int_fc->base;
173}
174
40f4ba76
PP
175void bt_field_class_integer_set_preferred_display_base(
176 struct bt_field_class *fc,
5cd6d0e5
PP
177 enum bt_field_class_integer_preferred_display_base base)
178{
179 struct bt_field_class_integer *int_fc = (void *) fc;
180
181 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
182 BT_ASSERT_PRE_FC_IS_INT(fc, "Field class");
183 BT_ASSERT_PRE_FC_HOT(fc, "Field class");
184 int_fc->base = base;
3f7d4d90 185 BT_LIB_LOGD("Set integer field class's preferred display base: %!+F", fc);
5cd6d0e5
PP
186}
187
188static
189void finalize_enumeration_field_class_mapping(
190 struct bt_field_class_enumeration_mapping *mapping)
191{
192 BT_ASSERT(mapping);
193
194 if (mapping->label) {
195 g_string_free(mapping->label, TRUE);
196 }
197
198 if (mapping->ranges) {
199 g_array_free(mapping->ranges, TRUE);
200 }
201}
202
203static
204void destroy_enumeration_field_class(struct bt_object *obj)
205{
206 struct bt_field_class_enumeration *fc = (void *) obj;
207
208 BT_ASSERT(fc);
e5be10ef 209 BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc);
5cd6d0e5
PP
210
211 if (fc->mappings) {
212 uint64_t i;
213
214 for (i = 0; i < fc->mappings->len; i++) {
215 finalize_enumeration_field_class_mapping(
216 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i));
217 }
218
219 g_array_free(fc->mappings, TRUE);
238b7404 220 fc->mappings = NULL;
5cd6d0e5
PP
221 }
222
223 if (fc->label_buf) {
224 g_ptr_array_free(fc->label_buf, TRUE);
238b7404 225 fc->label_buf = NULL;
5cd6d0e5
PP
226 }
227
228 g_free(fc);
229}
230
231static
40f4ba76 232struct bt_field_class *create_enumeration_field_class(
1122a43a 233 bt_trace_class *trace_class, enum bt_field_class_type type)
5cd6d0e5
PP
234{
235 struct bt_field_class_enumeration *enum_fc = NULL;
236
1122a43a 237 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 238 BT_LOGD("Creating default enumeration field class object: type=%s",
864cad70 239 bt_common_field_class_type_string(type));
5cd6d0e5
PP
240 enum_fc = g_new0(struct bt_field_class_enumeration, 1);
241 if (!enum_fc) {
e5be10ef 242 BT_LOGE_STR("Failed to allocate one enumeration field class.");
5cd6d0e5
PP
243 goto error;
244 }
245
864cad70 246 init_integer_field_class((void *) enum_fc, type,
5cd6d0e5
PP
247 destroy_enumeration_field_class);
248 enum_fc->mappings = g_array_new(FALSE, TRUE,
249 sizeof(struct bt_field_class_enumeration_mapping));
250 if (!enum_fc->mappings) {
251 BT_LOGE_STR("Failed to allocate a GArray.");
252 goto error;
253 }
254
255 enum_fc->label_buf = g_ptr_array_new();
256 if (!enum_fc->label_buf) {
257 BT_LOGE_STR("Failed to allocate a GArray.");
258 goto error;
259 }
260
e5be10ef 261 BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc);
5cd6d0e5
PP
262 goto end;
263
264error:
65300d60 265 BT_OBJECT_PUT_REF_AND_RESET(enum_fc);
5cd6d0e5
PP
266
267end:
268 return (void *) enum_fc;
269}
270
1122a43a
PP
271struct bt_field_class *bt_field_class_unsigned_enumeration_create(
272 bt_trace_class *trace_class)
5cd6d0e5 273{
1122a43a 274 return create_enumeration_field_class(trace_class,
864cad70 275 BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION);
5cd6d0e5
PP
276}
277
1122a43a
PP
278struct bt_field_class *bt_field_class_signed_enumeration_create(
279 bt_trace_class *trace_class)
5cd6d0e5 280{
1122a43a 281 return create_enumeration_field_class(trace_class,
864cad70 282 BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION);
5cd6d0e5
PP
283}
284
40f4ba76
PP
285uint64_t bt_field_class_enumeration_get_mapping_count(
286 const struct bt_field_class *fc)
5cd6d0e5 287{
40f4ba76 288 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
289
290 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
291 BT_ASSERT_PRE_FC_IS_ENUM(fc, "Field class");
292 return (uint64_t) enum_fc->mappings->len;
293}
294
8f3ccfbc
PP
295const struct bt_field_class_unsigned_enumeration_mapping *
296bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
297 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 298{
40f4ba76 299 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
300
301 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
5cd6d0e5 302 BT_ASSERT_PRE_VALID_INDEX(index, enum_fc->mappings->len);
864cad70 303 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
5cd6d0e5 304 "Field class");
8f3ccfbc 305 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
5cd6d0e5
PP
306}
307
8f3ccfbc
PP
308const struct bt_field_class_signed_enumeration_mapping *
309bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
310 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5 311{
40f4ba76 312 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
313
314 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
5cd6d0e5 315 BT_ASSERT_PRE_VALID_INDEX(index, enum_fc->mappings->len);
864cad70 316 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
5cd6d0e5 317 "Field class");
8f3ccfbc 318 return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
5cd6d0e5
PP
319}
320
8f3ccfbc 321const char *bt_field_class_enumeration_mapping_get_label(
40f4ba76 322 const struct bt_field_class_enumeration_mapping *mapping)
5cd6d0e5 323{
8f3ccfbc
PP
324 BT_ASSERT_PRE_NON_NULL(mapping, "Enumeration field class mapping");
325 return mapping->label->str;
5cd6d0e5
PP
326}
327
8f3ccfbc
PP
328uint64_t bt_field_class_enumeration_mapping_get_range_count(
329 const struct bt_field_class_enumeration_mapping *mapping)
5cd6d0e5 330{
8f3ccfbc
PP
331 BT_ASSERT_PRE_NON_NULL(mapping, "Enumeration field class mapping");
332 return (uint64_t) mapping->ranges->len;
5cd6d0e5
PP
333}
334
335static inline
336void get_enumeration_field_class_mapping_range_at_index(
40f4ba76 337 const struct bt_field_class_enumeration_mapping *mapping,
5cd6d0e5
PP
338 uint64_t index, uint64_t *lower, uint64_t *upper)
339{
40f4ba76 340 const struct bt_field_class_enumeration_mapping_range *range;
5cd6d0e5
PP
341
342 BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
343 BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)");
344 BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)");
345 BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len);
346 range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index);
347 *lower = range->lower.u;
348 *upper = range->upper.u;
349}
350
8f3ccfbc
PP
351void bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
352 const struct bt_field_class_unsigned_enumeration_mapping *ranges,
5cd6d0e5
PP
353 uint64_t index, uint64_t *lower, uint64_t *upper)
354{
40f4ba76
PP
355 get_enumeration_field_class_mapping_range_at_index(
356 (const void *) ranges, index, lower, upper);
5cd6d0e5
PP
357}
358
8f3ccfbc
PP
359void bt_field_class_signed_enumeration_mapping_get_range_by_index(
360 const struct bt_field_class_signed_enumeration_mapping *ranges,
5cd6d0e5
PP
361 uint64_t index, int64_t *lower, int64_t *upper)
362{
40f4ba76
PP
363 get_enumeration_field_class_mapping_range_at_index(
364 (const void *) ranges, index,
365 (uint64_t *) lower, (uint64_t *) upper);
5cd6d0e5
PP
366}
367
4295b9e0
PP
368enum bt_field_class_status
369bt_field_class_unsigned_enumeration_get_mapping_labels_by_value(
40f4ba76 370 const struct bt_field_class *fc, uint64_t value,
5cd6d0e5
PP
371 bt_field_class_enumeration_mapping_label_array *label_array,
372 uint64_t *count)
373{
40f4ba76 374 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
375 uint64_t i;
376
377 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
378 BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
379 BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
864cad70 380 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
5cd6d0e5
PP
381 "Field class");
382 g_ptr_array_set_size(enum_fc->label_buf, 0);
383
384 for (i = 0; i < enum_fc->mappings->len; i++) {
385 uint64_t j;
40f4ba76 386 const struct bt_field_class_enumeration_mapping *mapping =
5cd6d0e5
PP
387 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
388
389 for (j = 0; j < mapping->ranges->len; j++) {
40f4ba76 390 const struct bt_field_class_enumeration_mapping_range *range =
5cd6d0e5
PP
391 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
392 mapping, j);
393
394 if (value >= range->lower.u &&
395 value <= range->upper.u) {
396 g_ptr_array_add(enum_fc->label_buf,
397 mapping->label->str);
398 break;
399 }
400 }
401 }
402
403 *label_array = (void *) enum_fc->label_buf->pdata;
404 *count = (uint64_t) enum_fc->label_buf->len;
4295b9e0 405 return BT_FIELD_CLASS_STATUS_OK;
5cd6d0e5
PP
406}
407
4295b9e0
PP
408enum bt_field_class_status
409bt_field_class_signed_enumeration_get_mapping_labels_by_value(
40f4ba76 410 const struct bt_field_class *fc, int64_t value,
5cd6d0e5
PP
411 bt_field_class_enumeration_mapping_label_array *label_array,
412 uint64_t *count)
413{
40f4ba76 414 const struct bt_field_class_enumeration *enum_fc = (const void *) fc;
5cd6d0e5
PP
415 uint64_t i;
416
417 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
418 BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
419 BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
864cad70 420 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
5cd6d0e5
PP
421 "Field class");
422 g_ptr_array_set_size(enum_fc->label_buf, 0);
423
424 for (i = 0; i < enum_fc->mappings->len; i++) {
425 uint64_t j;
40f4ba76 426 const struct bt_field_class_enumeration_mapping *mapping =
5cd6d0e5
PP
427 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
428
429 for (j = 0; j < mapping->ranges->len; j++) {
40f4ba76 430 const struct bt_field_class_enumeration_mapping_range *range =
5cd6d0e5
PP
431 BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
432 mapping, j);
433
434 if (value >= range->lower.i &&
435 value <= range->upper.i) {
436 g_ptr_array_add(enum_fc->label_buf,
437 mapping->label->str);
438 break;
439 }
440 }
441 }
442
443 *label_array = (void *) enum_fc->label_buf->pdata;
444 *count = (uint64_t) enum_fc->label_buf->len;
4295b9e0 445 return BT_FIELD_CLASS_STATUS_OK;
5cd6d0e5
PP
446}
447
448static inline
4295b9e0
PP
449enum bt_field_class_status add_mapping_to_enumeration_field_class(
450 struct bt_field_class *fc,
5cd6d0e5
PP
451 const char *label, uint64_t lower, uint64_t upper)
452{
4295b9e0 453 int ret = BT_FIELD_CLASS_STATUS_OK;
5cd6d0e5
PP
454 uint64_t i;
455 struct bt_field_class_enumeration *enum_fc = (void *) fc;
456 struct bt_field_class_enumeration_mapping *mapping = NULL;
457 struct bt_field_class_enumeration_mapping_range *range;
458
459 BT_ASSERT(fc);
460 BT_ASSERT_PRE_NON_NULL(label, "Label");
461
462 /* Find existing mapping identified by this label */
463 for (i = 0; i < enum_fc->mappings->len; i++) {
464 struct bt_field_class_enumeration_mapping *mapping_candidate =
465 BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
466
467 if (strcmp(mapping_candidate->label->str, label) == 0) {
468 mapping = mapping_candidate;
469 break;
470 }
471 }
472
473 if (!mapping) {
474 /* Create new mapping for this label */
475 g_array_set_size(enum_fc->mappings, enum_fc->mappings->len + 1);
476 mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc,
477 enum_fc->mappings->len - 1);
478 mapping->ranges = g_array_new(FALSE, TRUE,
479 sizeof(struct bt_field_class_enumeration_mapping_range));
480 if (!mapping->ranges) {
481 finalize_enumeration_field_class_mapping(mapping);
482 g_array_set_size(enum_fc->mappings,
483 enum_fc->mappings->len - 1);
4295b9e0 484 ret = BT_FIELD_CLASS_STATUS_NOMEM;
5cd6d0e5
PP
485 goto end;
486 }
487
488 mapping->label = g_string_new(label);
489 if (!mapping->label) {
490 finalize_enumeration_field_class_mapping(mapping);
491 g_array_set_size(enum_fc->mappings,
492 enum_fc->mappings->len - 1);
4295b9e0 493 ret = BT_FIELD_CLASS_STATUS_NOMEM;
5cd6d0e5
PP
494 goto end;
495 }
496 }
497
498 /* Add range */
499 BT_ASSERT(mapping);
500 g_array_set_size(mapping->ranges, mapping->ranges->len + 1);
501 range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping,
502 mapping->ranges->len - 1);
503 range->lower.u = lower;
504 range->upper.u = upper;
3f7d4d90 505 BT_LIB_LOGD("Added mapping to enumeration field class: "
5cd6d0e5
PP
506 "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", "
507 "upper-unsigned=%" PRIu64, fc, label, lower, upper);
508
509end:
510 return ret;
511}
512
4295b9e0 513enum bt_field_class_status bt_field_class_unsigned_enumeration_map_range(
40f4ba76 514 struct bt_field_class *fc, const char *label,
5cd6d0e5
PP
515 uint64_t range_lower, uint64_t range_upper)
516{
517 struct bt_field_class_enumeration *enum_fc = (void *) fc;
518
519 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 520 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
5cd6d0e5
PP
521 "Field class");
522 BT_ASSERT_PRE(range_lower <= range_upper,
523 "Range's upper bound is less than lower bound: "
524 "upper=%" PRIu64 ", lower=%" PRIu64,
525 range_lower, range_upper);
526 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range,
527 range_lower),
e5be10ef 528 "Range's lower bound is outside the enumeration field class's value range: "
5cd6d0e5
PP
529 "%![fc-]+F, lower=%" PRIu64, fc, range_lower);
530 BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range,
531 range_upper),
e5be10ef 532 "Range's upper bound is outside the enumeration field class's value range: "
5cd6d0e5
PP
533 "%![fc-]+F, upper=%" PRIu64, fc, range_upper);
534 return add_mapping_to_enumeration_field_class(fc, label, range_lower,
535 range_upper);
536}
537
4295b9e0 538enum bt_field_class_status bt_field_class_signed_enumeration_map_range(
40f4ba76 539 struct bt_field_class *fc, const char *label,
5cd6d0e5
PP
540 int64_t range_lower, int64_t range_upper)
541{
542 struct bt_field_class_enumeration *enum_fc = (void *) fc;
543
544 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 545 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
5cd6d0e5
PP
546 "Field class");
547 BT_ASSERT_PRE(range_lower <= range_upper,
548 "Range's upper bound is less than lower bound: "
549 "upper=%" PRId64 ", lower=%" PRId64,
550 range_lower, range_upper);
551 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range,
552 range_lower),
e5be10ef 553 "Range's lower bound is outside the enumeration field class's value range: "
5cd6d0e5
PP
554 "%![fc-]+F, lower=%" PRId64, fc, range_lower);
555 BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range,
556 range_upper),
e5be10ef 557 "Range's upper bound is outside the enumeration field class's value range: "
5cd6d0e5
PP
558 "%![fc-]+F, upper=%" PRId64, fc, range_upper);
559 return add_mapping_to_enumeration_field_class(fc, label, range_lower,
560 range_upper);
561}
562
563static
564void destroy_real_field_class(struct bt_object *obj)
565{
566 BT_ASSERT(obj);
e5be10ef 567 BT_LIB_LOGD("Destroying real field class object: %!+F", obj);
5cd6d0e5
PP
568 g_free(obj);
569}
570
1122a43a 571struct bt_field_class *bt_field_class_real_create(bt_trace_class *trace_class)
5cd6d0e5
PP
572{
573 struct bt_field_class_real *real_fc = NULL;
574
1122a43a 575 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 576 BT_LOGD_STR("Creating default real field class object.");
5cd6d0e5
PP
577 real_fc = g_new0(struct bt_field_class_real, 1);
578 if (!real_fc) {
e5be10ef 579 BT_LOGE_STR("Failed to allocate one real field class.");
5cd6d0e5
PP
580 goto error;
581 }
582
864cad70 583 init_field_class((void *) real_fc, BT_FIELD_CLASS_TYPE_REAL,
5cd6d0e5 584 destroy_real_field_class);
e5be10ef 585 BT_LIB_LOGD("Created real field class object: %!+F", real_fc);
5cd6d0e5
PP
586 goto end;
587
588error:
65300d60 589 BT_OBJECT_PUT_REF_AND_RESET(real_fc);
5cd6d0e5
PP
590
591end:
592 return (void *) real_fc;
593}
594
40f4ba76 595bt_bool bt_field_class_real_is_single_precision(const struct bt_field_class *fc)
5cd6d0e5 596{
40f4ba76 597 const struct bt_field_class_real *real_fc = (const void *) fc;
5cd6d0e5
PP
598
599 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 600 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class");
5cd6d0e5
PP
601 return real_fc->is_single_precision;
602}
603
40f4ba76 604void bt_field_class_real_set_is_single_precision(struct bt_field_class *fc,
5cd6d0e5
PP
605 bt_bool is_single_precision)
606{
607 struct bt_field_class_real *real_fc = (void *) fc;
608
609 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 610 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class");
5cd6d0e5
PP
611 BT_ASSERT_PRE_FC_HOT(fc, "Field class");
612 real_fc->is_single_precision = (bool) is_single_precision;
3f7d4d90 613 BT_LIB_LOGD("Set real field class's \"is single precision\" property: "
5cd6d0e5 614 "%!+F", fc);
5cd6d0e5
PP
615}
616
617static
618int init_named_field_classes_container(
619 struct bt_field_class_named_field_class_container *fc,
40f4ba76
PP
620 enum bt_field_class_type type,
621 bt_object_release_func release_func)
5cd6d0e5
PP
622{
623 int ret = 0;
624
864cad70 625 init_field_class((void *) fc, type, release_func);
5cd6d0e5
PP
626 fc->named_fcs = g_array_new(FALSE, TRUE,
627 sizeof(struct bt_named_field_class));
628 if (!fc->named_fcs) {
629 BT_LOGE_STR("Failed to allocate a GArray.");
630 ret = -1;
631 goto end;
632 }
633
634 fc->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
635 if (!fc->name_to_index) {
636 BT_LOGE_STR("Failed to allocate a GHashTable.");
637 ret = -1;
638 goto end;
639 }
640
641end:
642 return ret;
643}
644
645static
646void finalize_named_field_class(struct bt_named_field_class *named_fc)
647{
648 BT_ASSERT(named_fc);
e5be10ef 649 BT_LIB_LOGD("Finalizing named field class: "
5cd6d0e5
PP
650 "addr=%p, name=\"%s\", %![fc-]+F",
651 named_fc, named_fc->name ? named_fc->name->str : NULL,
652 named_fc->fc);
653
654 if (named_fc->name) {
655 g_string_free(named_fc->name, TRUE);
656 }
657
e5be10ef 658 BT_LOGD_STR("Putting named field class's field class.");
238b7404 659 BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc);
5cd6d0e5
PP
660}
661
662static
663void finalize_named_field_classes_container(
664 struct bt_field_class_named_field_class_container *fc)
665{
666 uint64_t i;
667
668 BT_ASSERT(fc);
669
670 if (fc->named_fcs) {
671 for (i = 0; i < fc->named_fcs->len; i++) {
672 finalize_named_field_class(
673 &g_array_index(fc->named_fcs,
674 struct bt_named_field_class, i));
675 }
676
677 g_array_free(fc->named_fcs, TRUE);
678 }
679
680 if (fc->name_to_index) {
681 g_hash_table_destroy(fc->name_to_index);
682 }
683}
684
685static
686void destroy_structure_field_class(struct bt_object *obj)
687{
688 BT_ASSERT(obj);
1998d1ab 689 BT_LIB_LOGD("Destroying structure field class object: %!+F", obj);
5cd6d0e5
PP
690 finalize_named_field_classes_container((void *) obj);
691 g_free(obj);
692}
693
1122a43a
PP
694struct bt_field_class *bt_field_class_structure_create(
695 bt_trace_class *trace_class)
5cd6d0e5
PP
696{
697 int ret;
698 struct bt_field_class_structure *struct_fc = NULL;
699
1122a43a 700 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 701 BT_LOGD_STR("Creating default structure field class object.");
5cd6d0e5
PP
702 struct_fc = g_new0(struct bt_field_class_structure, 1);
703 if (!struct_fc) {
e5be10ef 704 BT_LOGE_STR("Failed to allocate one structure field class.");
5cd6d0e5
PP
705 goto error;
706 }
707
708 ret = init_named_field_classes_container((void *) struct_fc,
864cad70 709 BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class);
5cd6d0e5
PP
710 if (ret) {
711 goto error;
712 }
713
e5be10ef 714 BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc);
5cd6d0e5
PP
715 goto end;
716
717error:
65300d60 718 BT_OBJECT_PUT_REF_AND_RESET(struct_fc);
5cd6d0e5
PP
719
720end:
721 return (void *) struct_fc;
722}
723
724static
4295b9e0 725enum bt_field_class_status append_named_field_class_to_container_field_class(
5cd6d0e5
PP
726 struct bt_field_class_named_field_class_container *container_fc,
727 const char *name, struct bt_field_class *fc)
728{
4295b9e0 729 int ret = BT_FIELD_CLASS_STATUS_OK;
5cd6d0e5
PP
730 struct bt_named_field_class *named_fc;
731 GString *name_str;
732
733 BT_ASSERT(container_fc);
734 BT_ASSERT_PRE_FC_HOT(container_fc, "Field class");
735 BT_ASSERT_PRE_NON_NULL(name, "Name");
736 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
737 BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc->name_to_index,
738 name),
e5be10ef 739 "Duplicate member/option name in structure/variant field class: "
5cd6d0e5
PP
740 "%![container-fc-]+F, name=\"%s\"", container_fc, name);
741 name_str = g_string_new(name);
742 if (!name_str) {
743 BT_LOGE_STR("Failed to allocate a GString.");
4295b9e0 744 ret = BT_FIELD_CLASS_STATUS_NOMEM;
5cd6d0e5
PP
745 goto end;
746 }
747
748 g_array_set_size(container_fc->named_fcs,
749 container_fc->named_fcs->len + 1);
750 named_fc = &g_array_index(container_fc->named_fcs,
751 struct bt_named_field_class, container_fc->named_fcs->len - 1);
752 named_fc->name = name_str;
398454ed
PP
753 named_fc->fc = fc;
754 bt_object_get_no_null_check(fc);
5cd6d0e5
PP
755 g_hash_table_insert(container_fc->name_to_index, named_fc->name->str,
756 GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
1e6fd1d7
PP
757
758 /*
759 * Freeze the field class, but not the named field class (the
760 * user can still modify it, if possible, until the container
761 * itself is frozen).
762 */
5cd6d0e5
PP
763 bt_field_class_freeze(fc);
764
765end:
766 return ret;
767}
768
4295b9e0
PP
769enum bt_field_class_status bt_field_class_structure_append_member(
770 struct bt_field_class *fc, const char *name,
771 struct bt_field_class *member_fc)
5cd6d0e5 772{
e5be10ef 773
5cd6d0e5 774 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
740faaf4
PP
775 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
776 "Field class");
5cd6d0e5 777 return append_named_field_class_to_container_field_class((void *) fc,
40f4ba76 778 name, member_fc);
5cd6d0e5
PP
779}
780
40f4ba76
PP
781uint64_t bt_field_class_structure_get_member_count(
782 const struct bt_field_class *fc)
5cd6d0e5
PP
783{
784 struct bt_field_class_structure *struct_fc = (void *) fc;
785
786 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
740faaf4
PP
787 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
788 "Field class");
5cd6d0e5
PP
789 return (uint64_t) struct_fc->common.named_fcs->len;
790}
791
792static
1e6fd1d7
PP
793struct bt_named_field_class *
794borrow_named_field_class_from_container_field_class_at_index(
740faaf4 795 struct bt_field_class_named_field_class_container *fc,
1e6fd1d7 796 uint64_t index)
5cd6d0e5 797{
5cd6d0e5 798 BT_ASSERT(fc);
5cd6d0e5 799 BT_ASSERT_PRE_VALID_INDEX(index, fc->named_fcs->len);
1e6fd1d7 800 return BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, index);
5cd6d0e5
PP
801}
802
1e6fd1d7
PP
803const struct bt_field_class_structure_member *
804bt_field_class_structure_borrow_member_by_index_const(
805 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5
PP
806{
807 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
740faaf4
PP
808 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
809 "Field class");
1e6fd1d7
PP
810 return (const void *)
811 borrow_named_field_class_from_container_field_class_at_index(
812 (void *) fc, index);
740faaf4
PP
813}
814
1e6fd1d7
PP
815struct bt_field_class_structure_member *
816bt_field_class_structure_borrow_member_by_index(
817 struct bt_field_class *fc, uint64_t index)
740faaf4
PP
818{
819 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
820 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
821 "Field class");
1e6fd1d7
PP
822 return (void *)
823 borrow_named_field_class_from_container_field_class_at_index(
824 (void *) fc, index);
e5be10ef
PP
825}
826
5cd6d0e5 827static
1e6fd1d7
PP
828struct bt_named_field_class *
829borrow_named_field_class_from_container_field_class_by_name(
740faaf4 830 struct bt_field_class_named_field_class_container *fc,
5cd6d0e5
PP
831 const char *name)
832{
1e6fd1d7 833 struct bt_named_field_class *named_fc = NULL;
5cd6d0e5
PP
834 gpointer orig_key;
835 gpointer value;
836
837 BT_ASSERT(fc);
838 BT_ASSERT_PRE_NON_NULL(name, "Name");
839 if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key,
840 &value)) {
841 goto end;
842 }
843
844 named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc,
845 GPOINTER_TO_UINT(value));
5cd6d0e5
PP
846
847end:
1e6fd1d7 848 return named_fc;
5cd6d0e5
PP
849}
850
1e6fd1d7 851const struct bt_field_class_structure_member *
7c06e353 852bt_field_class_structure_borrow_member_by_name_const(
40f4ba76 853 const struct bt_field_class *fc, const char *name)
5cd6d0e5
PP
854{
855 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
740faaf4
PP
856 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
857 "Field class");
1e6fd1d7
PP
858 return (const void *)
859 borrow_named_field_class_from_container_field_class_by_name(
740faaf4
PP
860 (void *) fc, name);
861}
862
1e6fd1d7 863struct bt_field_class_structure_member *
fffedc87 864bt_field_class_structure_borrow_member_by_name(
740faaf4
PP
865 struct bt_field_class *fc, const char *name)
866{
867 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
868 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
869 "Field class");
1e6fd1d7
PP
870 return (void *)
871 borrow_named_field_class_from_container_field_class_by_name(
40f4ba76 872 (void *) fc, name);
e5be10ef
PP
873}
874
1e6fd1d7
PP
875const char *bt_field_class_structure_member_get_name(
876 const struct bt_field_class_structure_member *member)
877{
878 const struct bt_named_field_class *named_fc = (const void *) member;
879
880 BT_ASSERT_PRE_NON_NULL(member, "Structure field class member");
881 return named_fc->name->str;
882}
883
884const struct bt_field_class *
885bt_field_class_structure_member_borrow_field_class_const(
886 const struct bt_field_class_structure_member *member)
887{
888 const struct bt_named_field_class *named_fc = (const void *) member;
889
890 BT_ASSERT_PRE_NON_NULL(member, "Structure field class member");
891 return named_fc->fc;
892}
893
894struct bt_field_class *
895bt_field_class_structure_member_borrow_field_class(
896 struct bt_field_class_structure_member *member)
897{
898 struct bt_named_field_class *named_fc = (void *) member;
899
900 BT_ASSERT_PRE_NON_NULL(member, "Structure field class member");
901 return named_fc->fc;
902}
903
5cd6d0e5
PP
904static
905void destroy_variant_field_class(struct bt_object *obj)
906{
907 struct bt_field_class_variant *fc = (void *) obj;
908
909 BT_ASSERT(fc);
e5be10ef 910 BT_LIB_LOGD("Destroying variant field class object: %!+F", fc);
5cd6d0e5
PP
911 finalize_named_field_classes_container((void *) fc);
912 BT_LOGD_STR("Putting selector field path.");
238b7404
PP
913 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path);
914 BT_LOGD_STR("Putting selector field class.");
915 BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc);
5cd6d0e5
PP
916 g_free(fc);
917}
918
1122a43a
PP
919struct bt_field_class *bt_field_class_variant_create(
920 bt_trace_class *trace_class)
5cd6d0e5
PP
921{
922 int ret;
923 struct bt_field_class_variant *var_fc = NULL;
924
1122a43a 925 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 926 BT_LOGD_STR("Creating default variant field class object.");
5cd6d0e5
PP
927 var_fc = g_new0(struct bt_field_class_variant, 1);
928 if (!var_fc) {
e5be10ef 929 BT_LOGE_STR("Failed to allocate one variant field class.");
5cd6d0e5
PP
930 goto error;
931 }
932
933 ret = init_named_field_classes_container((void *) var_fc,
864cad70 934 BT_FIELD_CLASS_TYPE_VARIANT, destroy_variant_field_class);
5cd6d0e5
PP
935 if (ret) {
936 goto error;
937 }
938
e5be10ef 939 BT_LIB_LOGD("Created variant field class object: %!+F", var_fc);
5cd6d0e5
PP
940 goto end;
941
942error:
65300d60 943 BT_OBJECT_PUT_REF_AND_RESET(var_fc);
5cd6d0e5
PP
944
945end:
946 return (void *) var_fc;
947}
948
4295b9e0 949enum bt_field_class_status bt_field_class_variant_set_selector_field_class(
40f4ba76
PP
950 struct bt_field_class *fc,
951 struct bt_field_class *selector_fc)
5cd6d0e5
PP
952{
953 struct bt_field_class_variant *var_fc = (void *) fc;
954
e5be10ef
PP
955 BT_ASSERT_PRE_NON_NULL(fc, "Variant field class");
956 BT_ASSERT_PRE_NON_NULL(selector_fc, "Selector field class");
864cad70 957 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
e5be10ef
PP
958 BT_ASSERT_PRE_FC_IS_ENUM(selector_fc, "Selector field class");
959 BT_ASSERT_PRE_FC_HOT(fc, "Variant field class");
40f4ba76 960 var_fc->selector_fc = selector_fc;
398454ed 961 bt_object_get_no_null_check(selector_fc);
40f4ba76 962 bt_field_class_freeze(selector_fc);
4295b9e0 963 return BT_FIELD_CLASS_STATUS_OK;
5cd6d0e5
PP
964}
965
4295b9e0 966enum bt_field_class_status bt_field_class_variant_append_option(
40f4ba76
PP
967 struct bt_field_class *fc,
968 const char *name, struct bt_field_class *option_fc)
5cd6d0e5 969{
e5be10ef 970
5cd6d0e5 971 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 972 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
5cd6d0e5 973 return append_named_field_class_to_container_field_class((void *) fc,
40f4ba76 974 name, option_fc);
5cd6d0e5
PP
975}
976
1e6fd1d7 977const struct bt_field_class_variant_option *
7c06e353 978bt_field_class_variant_borrow_option_by_name_const(
40f4ba76 979 const struct bt_field_class *fc, const char *name)
5cd6d0e5
PP
980{
981 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 982 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
1e6fd1d7
PP
983 return (const void *)
984 borrow_named_field_class_from_container_field_class_by_name(
985 (void *) fc, name);
740faaf4
PP
986}
987
1e6fd1d7 988struct bt_field_class_variant_option *
7c06e353 989bt_field_class_variant_borrow_option_by_name(
740faaf4
PP
990 struct bt_field_class *fc, const char *name)
991{
992 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
993 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
1e6fd1d7
PP
994 return (void *)
995 borrow_named_field_class_from_container_field_class_by_name(
996 (void *) fc, name);
e5be10ef
PP
997}
998
40f4ba76 999uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc)
5cd6d0e5 1000{
40f4ba76 1001 const struct bt_field_class_variant *var_fc = (const void *) fc;
5cd6d0e5
PP
1002
1003 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 1004 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
5cd6d0e5
PP
1005 return (uint64_t) var_fc->common.named_fcs->len;
1006}
1007
1e6fd1d7
PP
1008const struct bt_field_class_variant_option *
1009bt_field_class_variant_borrow_option_by_index_const(
1010 const struct bt_field_class *fc, uint64_t index)
5cd6d0e5
PP
1011{
1012 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 1013 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
1e6fd1d7
PP
1014 return (const void *)
1015 borrow_named_field_class_from_container_field_class_at_index(
1016 (void *) fc, index);
740faaf4
PP
1017}
1018
1e6fd1d7
PP
1019struct bt_field_class_variant_option *
1020bt_field_class_variant_borrow_option_by_index(
1021 struct bt_field_class *fc, uint64_t index)
740faaf4
PP
1022{
1023 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
1024 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
1e6fd1d7
PP
1025 return (void *)
1026 borrow_named_field_class_from_container_field_class_at_index(
1027 (void *) fc, index);
1028}
1029
1030const char *bt_field_class_variant_option_get_name(
1031 const struct bt_field_class_variant_option *option)
1032{
1033 const struct bt_named_field_class *named_fc = (const void *) option;
1034
1035 BT_ASSERT_PRE_NON_NULL(option, "Variant field class option");
1036 return named_fc->name->str;
1037}
1038
1039const struct bt_field_class *
1040bt_field_class_variant_option_borrow_field_class_const(
1041 const struct bt_field_class_variant_option *option)
1042{
1043 const struct bt_named_field_class *named_fc = (const void *) option;
1044
1045 BT_ASSERT_PRE_NON_NULL(option, "Variant field class option");
1046 return named_fc->fc;
1047}
1048
1049struct bt_field_class *
1050bt_field_class_variant_option_borrow_field_class(
1051 struct bt_field_class_variant_option *option)
1052{
1053 struct bt_named_field_class *named_fc = (void *) option;
1054
1055 BT_ASSERT_PRE_NON_NULL(option, "Variant field class option");
1056 return named_fc->fc;
5cd6d0e5
PP
1057}
1058
40f4ba76
PP
1059const struct bt_field_path *
1060bt_field_class_variant_borrow_selector_field_path_const(
1061 const struct bt_field_class *fc)
e5be10ef 1062{
40f4ba76 1063 const struct bt_field_class_variant *var_fc = (const void *) fc;
5cd6d0e5
PP
1064
1065 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 1066 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT,
5cd6d0e5
PP
1067 "Field class");
1068 return var_fc->selector_field_path;
1069}
1070
1071static
1072void init_array_field_class(struct bt_field_class_array *fc,
864cad70 1073 enum bt_field_class_type type, bt_object_release_func release_func,
5cd6d0e5
PP
1074 struct bt_field_class *element_fc)
1075{
1076 BT_ASSERT(element_fc);
864cad70 1077 init_field_class((void *) fc, type, release_func);
398454ed
PP
1078 fc->element_fc = element_fc;
1079 bt_object_get_no_null_check(element_fc);
5cd6d0e5
PP
1080 bt_field_class_freeze(element_fc);
1081}
1082
1083static
1084void finalize_array_field_class(struct bt_field_class_array *array_fc)
1085{
1086 BT_ASSERT(array_fc);
e5be10ef 1087 BT_LOGD_STR("Putting element field class.");
238b7404 1088 BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc);
5cd6d0e5
PP
1089}
1090
1091static
1092void destroy_static_array_field_class(struct bt_object *obj)
1093{
1094 BT_ASSERT(obj);
e5be10ef 1095 BT_LIB_LOGD("Destroying static array field class object: %!+F", obj);
5cd6d0e5
PP
1096 finalize_array_field_class((void *) obj);
1097 g_free(obj);
1098}
1099
40f4ba76 1100struct bt_field_class *
1122a43a
PP
1101bt_field_class_static_array_create(bt_trace_class *trace_class,
1102 struct bt_field_class *element_fc, uint64_t length)
5cd6d0e5
PP
1103{
1104 struct bt_field_class_static_array *array_fc = NULL;
1105
1122a43a 1106 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef
PP
1107 BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class");
1108 BT_LOGD_STR("Creating default static array field class object.");
5cd6d0e5
PP
1109 array_fc = g_new0(struct bt_field_class_static_array, 1);
1110 if (!array_fc) {
e5be10ef 1111 BT_LOGE_STR("Failed to allocate one static array field class.");
5cd6d0e5
PP
1112 goto error;
1113 }
1114
864cad70 1115 init_array_field_class((void *) array_fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
5cd6d0e5
PP
1116 destroy_static_array_field_class, element_fc);
1117 array_fc->length = length;
e5be10ef 1118 BT_LIB_LOGD("Created static array field class object: %!+F", array_fc);
5cd6d0e5
PP
1119 goto end;
1120
1121error:
65300d60 1122 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
5cd6d0e5
PP
1123
1124end:
1125 return (void *) array_fc;
1126}
1127
40f4ba76
PP
1128const struct bt_field_class *
1129bt_field_class_array_borrow_element_field_class_const(
1130 const struct bt_field_class *fc)
5cd6d0e5 1131{
40f4ba76 1132 const struct bt_field_class_array *array_fc = (const void *) fc;
5cd6d0e5
PP
1133
1134 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
1135 BT_ASSERT_PRE_FC_IS_ARRAY(fc, "Field class");
1136 return array_fc->element_fc;
1137}
1138
740faaf4
PP
1139struct bt_field_class *
1140bt_field_class_array_borrow_element_field_class(struct bt_field_class *fc)
1141{
1142 struct bt_field_class_array *array_fc = (void *) fc;
1143
1144 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
1145 BT_ASSERT_PRE_FC_IS_ARRAY(fc, "Field class");
1146 return array_fc->element_fc;
1147}
1148
40f4ba76 1149uint64_t bt_field_class_static_array_get_length(const struct bt_field_class *fc)
e5be10ef 1150{
40f4ba76 1151 const struct bt_field_class_static_array *array_fc = (const void *) fc;
5cd6d0e5
PP
1152
1153 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 1154 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
5cd6d0e5
PP
1155 "Field class");
1156 return (uint64_t) array_fc->length;
1157}
1158
1159static
1160void destroy_dynamic_array_field_class(struct bt_object *obj)
1161{
1162 struct bt_field_class_dynamic_array *fc = (void *) obj;
1163
1164 BT_ASSERT(fc);
e5be10ef 1165 BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc);
5cd6d0e5
PP
1166 finalize_array_field_class((void *) fc);
1167 BT_LOGD_STR("Putting length field path.");
238b7404
PP
1168 BT_OBJECT_PUT_REF_AND_RESET(fc->length_field_path);
1169 BT_LOGD_STR("Putting length field class.");
1170 BT_OBJECT_PUT_REF_AND_RESET(fc->length_fc);
5cd6d0e5
PP
1171 g_free(fc);
1172}
1173
40f4ba76 1174struct bt_field_class *bt_field_class_dynamic_array_create(
1122a43a 1175 bt_trace_class *trace_class,
40f4ba76 1176 struct bt_field_class *element_fc)
5cd6d0e5
PP
1177{
1178 struct bt_field_class_dynamic_array *array_fc = NULL;
1179
1122a43a 1180 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef
PP
1181 BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class");
1182 BT_LOGD_STR("Creating default dynamic array field class object.");
5cd6d0e5
PP
1183 array_fc = g_new0(struct bt_field_class_dynamic_array, 1);
1184 if (!array_fc) {
e5be10ef 1185 BT_LOGE_STR("Failed to allocate one dynamic array field class.");
5cd6d0e5
PP
1186 goto error;
1187 }
1188
40f4ba76
PP
1189 init_array_field_class((void *) array_fc,
1190 BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
5cd6d0e5 1191 destroy_dynamic_array_field_class, element_fc);
e5be10ef 1192 BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc);
5cd6d0e5
PP
1193 goto end;
1194
1195error:
65300d60 1196 BT_OBJECT_PUT_REF_AND_RESET(array_fc);
5cd6d0e5
PP
1197
1198end:
1199 return (void *) array_fc;
1200}
1201
4295b9e0 1202enum bt_field_class_status bt_field_class_dynamic_array_set_length_field_class(
40f4ba76
PP
1203 struct bt_field_class *fc,
1204 struct bt_field_class *length_fc)
5cd6d0e5
PP
1205{
1206 struct bt_field_class_dynamic_array *array_fc = (void *) fc;
1207
e5be10ef
PP
1208 BT_ASSERT_PRE_NON_NULL(fc, "Dynamic array field class");
1209 BT_ASSERT_PRE_NON_NULL(length_fc, "Length field class");
864cad70 1210 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
5cd6d0e5 1211 "Field class");
e5be10ef
PP
1212 BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc, "Length field class");
1213 BT_ASSERT_PRE_FC_HOT(fc, "Dynamic array field class");
40f4ba76 1214 array_fc->length_fc = length_fc;
398454ed 1215 bt_object_get_no_null_check(length_fc);
5cd6d0e5 1216 bt_field_class_freeze(length_fc);
4295b9e0 1217 return BT_FIELD_CLASS_STATUS_OK;
5cd6d0e5
PP
1218}
1219
40f4ba76
PP
1220const struct bt_field_path *
1221bt_field_class_dynamic_array_borrow_length_field_path_const(
1222 const struct bt_field_class *fc)
5cd6d0e5 1223{
40f4ba76 1224 const struct bt_field_class_dynamic_array *seq_fc = (const void *) fc;
5cd6d0e5
PP
1225
1226 BT_ASSERT_PRE_NON_NULL(fc, "Field class");
864cad70 1227 BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
5cd6d0e5
PP
1228 "Field class");
1229 return seq_fc->length_field_path;
1230}
1231
1232static
1233void destroy_string_field_class(struct bt_object *obj)
1234{
1235 BT_ASSERT(obj);
e5be10ef 1236 BT_LIB_LOGD("Destroying string field class object: %!+F", obj);
5cd6d0e5
PP
1237 g_free(obj);
1238}
1239
1122a43a 1240struct bt_field_class *bt_field_class_string_create(bt_trace_class *trace_class)
5cd6d0e5
PP
1241{
1242 struct bt_field_class_string *string_fc = NULL;
1243
1122a43a 1244 BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
e5be10ef 1245 BT_LOGD_STR("Creating default string field class object.");
5cd6d0e5
PP
1246 string_fc = g_new0(struct bt_field_class_string, 1);
1247 if (!string_fc) {
e5be10ef 1248 BT_LOGE_STR("Failed to allocate one string field class.");
5cd6d0e5
PP
1249 goto error;
1250 }
1251
864cad70 1252 init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING,
5cd6d0e5 1253 destroy_string_field_class);
e5be10ef 1254 BT_LIB_LOGD("Created string field class object: %!+F", string_fc);
5cd6d0e5
PP
1255 goto end;
1256
1257error:
65300d60 1258 BT_OBJECT_PUT_REF_AND_RESET(string_fc);
5cd6d0e5
PP
1259
1260end:
1261 return (void *) string_fc;
1262}
1263
1264BT_HIDDEN
1e6fd1d7 1265void _bt_field_class_freeze(const struct bt_field_class *c_fc)
5cd6d0e5 1266{
1e6fd1d7
PP
1267 struct bt_field_class *fc = (void *) c_fc;
1268
5cd6d0e5
PP
1269 /*
1270 * Element/member/option field classes are frozen when added to
1271 * their owner.
1272 */
1273 BT_ASSERT(fc);
1e6fd1d7
PP
1274 fc->frozen = true;
1275
1276 switch (fc->type) {
1277 case BT_FIELD_CLASS_TYPE_STRUCTURE:
1278 case BT_FIELD_CLASS_TYPE_VARIANT:
1279 {
1280 struct bt_field_class_named_field_class_container *container_fc =
1281 (void *) fc;
1282 uint64_t i;
1283
1284 for (i = 0; i < container_fc->named_fcs->len; i++) {
1285 struct bt_named_field_class *named_fc =
1286 BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
1287 container_fc, i);
1288
1289 bt_named_field_class_freeze(named_fc);
1290 }
1291
1292 break;
1293 }
1294 default:
1295 break;
1296 }
1297}
1298
1299BT_HIDDEN
1300void _bt_named_field_class_freeze(const struct bt_named_field_class *named_fc)
1301{
1302 BT_ASSERT(named_fc);
1303 ((struct bt_named_field_class *) named_fc)->frozen = true;
1304 bt_field_class_freeze(named_fc->fc);
5cd6d0e5
PP
1305}
1306
1307BT_HIDDEN
862ca4ed 1308void _bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc)
5cd6d0e5 1309{
40f4ba76
PP
1310 struct bt_field_class *fc = (void *) c_fc;
1311
5cd6d0e5 1312 BT_ASSERT(fc);
862ca4ed 1313 BT_ASSERT_PRE(!fc->part_of_trace_class,
5cd6d0e5 1314 "Field class is already part of a trace: %!+F", fc);
862ca4ed 1315 fc->part_of_trace_class = true;
5cd6d0e5 1316
864cad70
PP
1317 switch (fc->type) {
1318 case BT_FIELD_CLASS_TYPE_STRUCTURE:
1319 case BT_FIELD_CLASS_TYPE_VARIANT:
5cd6d0e5
PP
1320 {
1321 struct bt_field_class_named_field_class_container *container_fc =
1322 (void *) fc;
1323 uint64_t i;
1324
1325 for (i = 0; i < container_fc->named_fcs->len; i++) {
1326 struct bt_named_field_class *named_fc =
1327 BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
1328 container_fc, i);
1329
862ca4ed 1330 bt_field_class_make_part_of_trace_class(named_fc->fc);
5cd6d0e5
PP
1331 }
1332
1333 break;
1334 }
864cad70
PP
1335 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
1336 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
5cd6d0e5
PP
1337 {
1338 struct bt_field_class_array *array_fc = (void *) fc;
1339
862ca4ed 1340 bt_field_class_make_part_of_trace_class(array_fc->element_fc);
5cd6d0e5
PP
1341 break;
1342 }
1343 default:
1344 break;
1345 }
1346}
c5b9b441
PP
1347
1348void bt_field_class_get_ref(const struct bt_field_class *field_class)
1349{
1350 bt_object_get_ref(field_class);
1351}
1352
1353void bt_field_class_put_ref(const struct bt_field_class *field_class)
1354{
1355 bt_object_put_ref(field_class);
1356}
This page took 0.135633 seconds and 4 git commands to generate.