Cleanup: add `#include <stdbool.h>` whenever `bool` type is used
[babeltrace.git] / src / ctf-writer / field-types.c
CommitLineData
3dca2276
PP
1/*
2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
350ad6c1 25#define BT_LOG_TAG "CTF-WRITER/FIELD-TYPES"
67d2ce02 26#include "logging.h"
3dca2276 27
3dca2276
PP
28#include <float.h>
29#include <inttypes.h>
c4f23e30 30#include <stdbool.h>
3dca2276
PP
31#include <stdlib.h>
32
217cf9d3
PP
33#include <babeltrace2-ctf-writer/fields.h>
34#include <babeltrace2-ctf-writer/field-types.h>
35#include <babeltrace2-ctf-writer/object.h>
36#include <babeltrace2-ctf-writer/utils.h>
578e048b
MJ
37
38#include "common/assert.h"
39#include "compat/compiler.h"
40#include "compat/endian.h"
41
42#include "assert-pre.h"
43#include "clock-class.h"
44#include "clock.h"
45#include "field-path.h"
46#include "fields.h"
47#include "field-types.h"
48#include "object.h"
49#include "utils.h"
50
16ca5ff0
PP
51static
52void destroy_enumeration_mapping(struct bt_ctf_enumeration_mapping *mapping)
53{
54 g_free(mapping);
55}
56
57BT_HIDDEN
58void bt_ctf_field_type_common_initialize(struct bt_ctf_field_type_common *ft,
e1e02a22 59 bool init_bo, bt_ctf_object_release_func release_func,
16ca5ff0
PP
60 struct bt_ctf_field_type_common_methods *methods)
61{
98b15851 62 BT_ASSERT_DBG(ft && (ft->id > BT_CTF_FIELD_TYPE_ID_UNKNOWN) &&
16ca5ff0
PP
63 (ft->id < BT_CTF_FIELD_TYPE_ID_NR));
64
e1e02a22 65 bt_ctf_object_init_shared(&ft->base, release_func);
16ca5ff0
PP
66 ft->methods = methods;
67
68 if (init_bo) {
69 int ret;
70 const enum bt_ctf_byte_order bo = BT_CTF_BYTE_ORDER_NATIVE;
71
72 BT_LOGD("Setting initial field type's byte order: bo=%s",
73 bt_ctf_byte_order_string(bo));
74 ret = bt_ctf_field_type_common_set_byte_order(ft, bo);
98b15851 75 BT_ASSERT_DBG(ret == 0);
16ca5ff0
PP
76 }
77
78 ft->alignment = 1;
79}
80
81BT_HIDDEN
82void bt_ctf_field_type_common_integer_initialize(
83 struct bt_ctf_field_type_common *ft,
e1e02a22 84 unsigned int size, bt_ctf_object_release_func release_func,
16ca5ff0
PP
85 struct bt_ctf_field_type_common_methods *methods)
86{
87 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
88
98b15851 89 BT_ASSERT_DBG(size > 0);
16ca5ff0
PP
90 BT_LOGD("Initializing common integer field type object: size=%u",
91 size);
92 ft->id = BT_CTF_FIELD_TYPE_ID_INTEGER;
93 int_ft->size = size;
94 int_ft->base = BT_CTF_INTEGER_BASE_DECIMAL;
95 int_ft->encoding = BT_CTF_STRING_ENCODING_NONE;
96 bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
97 BT_LOGD("Initialized common integer field type object: addr=%p, size=%u",
98 ft, size);
99}
100
101BT_HIDDEN
102void bt_ctf_field_type_common_floating_point_initialize(
103 struct bt_ctf_field_type_common *ft,
e1e02a22 104 bt_ctf_object_release_func release_func,
16ca5ff0
PP
105 struct bt_ctf_field_type_common_methods *methods)
106{
107 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
108
109 BT_LOGD_STR("Initializing common floating point number field type object.");
110 ft->id = BT_CTF_FIELD_TYPE_ID_FLOAT;
111 flt_ft->exp_dig = sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
112 flt_ft->mant_dig = FLT_MANT_DIG;
113 bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
114 BT_LOGD("Initialized common floating point number field type object: addr=%p, "
115 "exp-size=%u, mant-size=%u", ft, flt_ft->exp_dig,
116 flt_ft->mant_dig);
117}
118
119BT_HIDDEN
120void bt_ctf_field_type_common_enumeration_initialize(
121 struct bt_ctf_field_type_common *ft,
122 struct bt_ctf_field_type_common *container_ft,
e1e02a22 123 bt_ctf_object_release_func release_func,
16ca5ff0
PP
124 struct bt_ctf_field_type_common_methods *methods)
125{
126 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
127
98b15851 128 BT_ASSERT_DBG(container_ft);
16ca5ff0
PP
129 BT_LOGD("Initializing common enumeration field type object: int-ft-addr=%p",
130 container_ft);
131 ft->id = BT_CTF_FIELD_TYPE_ID_ENUM;
e1e02a22 132 enum_ft->container_ft = bt_ctf_object_get_ref(container_ft);
16ca5ff0
PP
133 enum_ft->entries = g_ptr_array_new_with_free_func(
134 (GDestroyNotify) destroy_enumeration_mapping);
135 bt_ctf_field_type_common_initialize(ft, false, release_func, methods);
136 BT_LOGD("Initialized common enumeration field type object: addr=%p, "
137 "int-ft-addr=%p, int-ft-size=%u", ft, container_ft,
138 bt_ctf_field_type_common_integer_get_size(container_ft));
139}
140
141BT_HIDDEN
142void bt_ctf_field_type_common_string_initialize(
143 struct bt_ctf_field_type_common *ft,
e1e02a22 144 bt_ctf_object_release_func release_func,
16ca5ff0
PP
145 struct bt_ctf_field_type_common_methods *methods)
146{
147 struct bt_ctf_field_type_common_string *string_ft = BT_CTF_FROM_COMMON(ft);
148
149 BT_LOGD_STR("Initializing common string field type object.");
150 ft->id = BT_CTF_FIELD_TYPE_ID_STRING;
151 bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
152 string_ft->encoding = BT_CTF_STRING_ENCODING_UTF8;
153 ft->alignment = CHAR_BIT;
154 BT_LOGD("Initialized common string field type object: addr=%p", ft);
155}
156
157BT_HIDDEN
158void bt_ctf_field_type_common_structure_initialize(
159 struct bt_ctf_field_type_common *ft,
e1e02a22 160 bt_ctf_object_release_func release_func,
16ca5ff0
PP
161 struct bt_ctf_field_type_common_methods *methods)
162{
163 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
164
165 BT_LOGD_STR("Initializing common structure field type object.");
166 ft->id = BT_CTF_FIELD_TYPE_ID_STRUCT;
167 struct_ft->fields = g_array_new(FALSE, TRUE,
168 sizeof(struct bt_ctf_field_type_common_structure_field));
169 struct_ft->field_name_to_index = g_hash_table_new(NULL, NULL);
170 bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
171 BT_LOGD("Initialized common structure field type object: addr=%p", ft);
172}
173
174BT_HIDDEN
175void bt_ctf_field_type_common_array_initialize(
176 struct bt_ctf_field_type_common *ft,
177 struct bt_ctf_field_type_common *element_ft,
e1e02a22 178 unsigned int length, bt_ctf_object_release_func release_func,
16ca5ff0
PP
179 struct bt_ctf_field_type_common_methods *methods)
180{
181 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
182
98b15851 183 BT_ASSERT_DBG(element_ft);
16ca5ff0
PP
184 BT_LOGD("Initializing common array field type object: element-ft-addr=%p, "
185 "length=%u", element_ft, length);
186 ft->id = BT_CTF_FIELD_TYPE_ID_ARRAY;
e1e02a22 187 array_ft->element_ft = bt_ctf_object_get_ref(element_ft);
16ca5ff0
PP
188 array_ft->length = length;
189 bt_ctf_field_type_common_initialize(ft, false, release_func, methods);
190 BT_LOGD("Initialized common array field type object: addr=%p, "
191 "element-ft-addr=%p, length=%u", ft, element_ft, length);
192}
193
194BT_HIDDEN
195void bt_ctf_field_type_common_sequence_initialize(
196 struct bt_ctf_field_type_common *ft,
197 struct bt_ctf_field_type_common *element_ft,
198 const char *length_field_name,
e1e02a22 199 bt_ctf_object_release_func release_func,
16ca5ff0
PP
200 struct bt_ctf_field_type_common_methods *methods)
201{
202 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
203
98b15851
PP
204 BT_ASSERT_DBG(element_ft);
205 BT_ASSERT_DBG(length_field_name);
206 BT_ASSERT_DBG(bt_ctf_identifier_is_valid(length_field_name));
16ca5ff0
PP
207 BT_LOGD("Initializing common sequence field type object: element-ft-addr=%p, "
208 "length-field-name=\"%s\"", element_ft, length_field_name);
209 ft->id = BT_CTF_FIELD_TYPE_ID_SEQUENCE;
e1e02a22 210 seq_ft->element_ft = bt_ctf_object_get_ref(element_ft);
16ca5ff0
PP
211 seq_ft->length_field_name = g_string_new(length_field_name);
212 bt_ctf_field_type_common_initialize(ft, false, release_func, methods);
213 BT_LOGD("Initialized common sequence field type object: addr=%p, "
214 "element-ft-addr=%p, length-field-name=\"%s\"",
215 ft, element_ft, length_field_name);
216}
217
218BT_HIDDEN
219void bt_ctf_field_type_common_variant_initialize(
220 struct bt_ctf_field_type_common *ft,
221 struct bt_ctf_field_type_common *tag_ft,
222 const char *tag_name,
e1e02a22 223 bt_ctf_object_release_func release_func,
16ca5ff0
PP
224 struct bt_ctf_field_type_common_methods *methods)
225{
226 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
227
98b15851 228 BT_ASSERT_DBG(!tag_name || bt_ctf_identifier_is_valid(tag_name));
16ca5ff0
PP
229 BT_LOGD("Initializing common variant field type object: "
230 "tag-ft-addr=%p, tag-field-name=\"%s\"",
231 tag_ft, tag_name);
232 ft->id = BT_CTF_FIELD_TYPE_ID_VARIANT;
233 var_ft->tag_name = g_string_new(tag_name);
234 var_ft->choice_name_to_index = g_hash_table_new(NULL, NULL);
235 var_ft->choices = g_array_new(FALSE, TRUE,
236 sizeof(struct bt_ctf_field_type_common_variant_choice));
237
238 if (tag_ft) {
e1e02a22 239 var_ft->tag_ft = bt_ctf_object_get_ref(tag_ft);
16ca5ff0
PP
240 }
241
242 bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
243 /* A variant's alignment is undefined */
244 ft->alignment = 0;
245 BT_LOGD("Initialized common variant field type object: addr=%p, "
246 "tag-ft-addr=%p, tag-field-name=\"%s\"",
247 ft, tag_ft, tag_name);
248}
249
250BT_HIDDEN
e1e02a22 251void bt_ctf_field_type_common_integer_destroy(struct bt_ctf_object *obj)
16ca5ff0
PP
252{
253 struct bt_ctf_field_type_common_integer *ft = (void *) obj;
254
255 if (!ft) {
256 return;
257 }
258
259 BT_LOGD("Destroying integer field type object: addr=%p", ft);
260 BT_LOGD_STR("Putting mapped clock class.");
e1e02a22 261 bt_ctf_object_put_ref(ft->mapped_clock_class);
16ca5ff0
PP
262 g_free(ft);
263}
264
265BT_HIDDEN
e1e02a22 266void bt_ctf_field_type_common_floating_point_destroy(struct bt_ctf_object *obj)
16ca5ff0
PP
267{
268 struct bt_ctf_field_type_common_floating_point *ft = (void *) obj;
269
270 if (!ft) {
271 return;
272 }
273
274 BT_LOGD("Destroying floating point number field type object: addr=%p", ft);
275 g_free(ft);
276}
277
278BT_HIDDEN
e1e02a22 279void bt_ctf_field_type_common_enumeration_destroy_recursive(struct bt_ctf_object *obj)
16ca5ff0
PP
280{
281 struct bt_ctf_field_type_common_enumeration *ft = (void *) obj;
282
283 if (!ft) {
284 return;
285 }
286
287 BT_LOGD("Destroying enumeration field type object: addr=%p", ft);
288 g_ptr_array_free(ft->entries, TRUE);
289 BT_LOGD_STR("Putting container field type.");
e1e02a22 290 bt_ctf_object_put_ref(ft->container_ft);
16ca5ff0
PP
291 g_free(ft);
292}
293
294BT_HIDDEN
e1e02a22 295void bt_ctf_field_type_common_string_destroy(struct bt_ctf_object *obj)
16ca5ff0
PP
296{
297 struct bt_ctf_field_type_common_string *ft = (void *) obj;
298
299 if (!ft) {
300 return;
301 }
302
303 BT_LOGD("Destroying string field type object: addr=%p", ft);
304 g_free(ft);
305}
306
307static
308void bt_ctf_field_type_common_structure_field_finalize(
309 struct bt_ctf_field_type_common_structure_field *field)
310{
311 if (!field) {
312 return;
313 }
314
315 BT_LOGD("Finalizing structure field type's field: "
316 "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
317 field, field->type, g_quark_to_string(field->name));
318 BT_LOGD_STR("Putting field type.");
e1e02a22 319 bt_ctf_object_put_ref(field->type);
16ca5ff0
PP
320}
321
322BT_HIDDEN
e1e02a22 323void bt_ctf_field_type_common_structure_destroy_recursive(struct bt_ctf_object *obj)
16ca5ff0
PP
324{
325 struct bt_ctf_field_type_common_structure *ft = (void *) obj;
326 uint64_t i;
327
328 if (!ft) {
329 return;
330 }
331
332 BT_LOGD("Destroying structure field type object: addr=%p", ft);
333
334 if (ft->fields) {
335 for (i = 0; i < ft->fields->len; i++) {
336 bt_ctf_field_type_common_structure_field_finalize(
337 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
338 ft, i));
339 }
340
341 g_array_free(ft->fields, TRUE);
342 }
343
344 if (ft->field_name_to_index) {
345 g_hash_table_destroy(ft->field_name_to_index);
346 }
347
348 g_free(ft);
349}
350
351BT_HIDDEN
e1e02a22 352void bt_ctf_field_type_common_array_destroy_recursive(struct bt_ctf_object *obj)
16ca5ff0
PP
353{
354 struct bt_ctf_field_type_common_array *ft = (void *) obj;
355
356 if (!ft) {
357 return;
358 }
359
360 BT_LOGD("Destroying array field type object: addr=%p", ft);
361 BT_LOGD_STR("Putting element field type.");
e1e02a22 362 bt_ctf_object_put_ref(ft->element_ft);
16ca5ff0
PP
363 g_free(ft);
364}
365
366BT_HIDDEN
e1e02a22 367void bt_ctf_field_type_common_sequence_destroy_recursive(struct bt_ctf_object *obj)
16ca5ff0
PP
368{
369 struct bt_ctf_field_type_common_sequence *ft = (void *) obj;
370
371 if (!ft) {
372 return;
373 }
374
375 BT_LOGD("Destroying sequence field type object: addr=%p", ft);
376 BT_LOGD_STR("Putting element field type.");
e1e02a22 377 bt_ctf_object_put_ref(ft->element_ft);
16ca5ff0
PP
378 g_string_free(ft->length_field_name, TRUE);
379 BT_LOGD_STR("Putting length field path.");
e1e02a22 380 bt_ctf_object_put_ref(ft->length_field_path);
16ca5ff0
PP
381 g_free(ft);
382}
383
384static
385void bt_ctf_field_type_common_variant_choice_finalize(
386 struct bt_ctf_field_type_common_variant_choice *choice)
387{
388 if (!choice) {
389 return;
390 }
391
392 BT_LOGD("Finalizing variant field type's choice: "
393 "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
394 choice, choice->type, g_quark_to_string(choice->name));
395 BT_LOGD_STR("Putting field type.");
e1e02a22 396 bt_ctf_object_put_ref(choice->type);
16ca5ff0
PP
397
398 if (choice->ranges) {
399 g_array_free(choice->ranges, TRUE);
400 }
401}
402
403BT_HIDDEN
e1e02a22 404void bt_ctf_field_type_common_variant_destroy_recursive(struct bt_ctf_object *obj)
16ca5ff0
PP
405{
406 struct bt_ctf_field_type_common_variant *ft = (void *) obj;
407 uint64_t i;
408
409 if (!ft) {
410 return;
411 }
412
413 BT_LOGD("Destroying variant field type object: addr=%p", ft);
414
415 if (ft->choices) {
416 for (i = 0; i < ft->choices->len; i++) {
417 bt_ctf_field_type_common_variant_choice_finalize(
418 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
419 ft, i));
420 }
421
422 g_array_free(ft->choices, TRUE);
423 }
424
425 if (ft->choice_name_to_index) {
426 g_hash_table_destroy(ft->choice_name_to_index);
427 }
428
429 if (ft->tag_name) {
430 g_string_free(ft->tag_name, TRUE);
431 }
432
433 BT_LOGD_STR("Putting tag field type.");
e1e02a22 434 bt_ctf_object_put_ref(ft->tag_ft);
16ca5ff0 435 BT_LOGD_STR("Putting tag field path.");
e1e02a22 436 bt_ctf_object_put_ref(ft->tag_field_path);
16ca5ff0
PP
437 g_free(ft);
438}
439
440struct range_overlap_query {
441 union {
442 uint64_t _unsigned;
443 int64_t _signed;
444 } range_start;
445
446 union {
447 uint64_t _unsigned;
448 int64_t _signed;
449 } range_end;
450 int overlaps;
451 GQuark mapping_name;
452};
453
454static
455void check_ranges_overlap(gpointer element, gpointer query)
456{
457 struct bt_ctf_enumeration_mapping *mapping = element;
458 struct range_overlap_query *overlap_query = query;
459
460 if (mapping->range_start._signed <= overlap_query->range_end._signed
461 && overlap_query->range_start._signed <=
462 mapping->range_end._signed) {
463 overlap_query->overlaps = 1;
464 overlap_query->mapping_name = mapping->string;
465 }
466
467 overlap_query->overlaps |=
468 mapping->string == overlap_query->mapping_name;
469
470 if (overlap_query->overlaps) {
ef267d12 471 BT_LOGT("Overlapping enumeration field type mappings: "
16ca5ff0
PP
472 "mapping-name=\"%s\", "
473 "mapping-a-range-start=%" PRId64 ", "
474 "mapping-a-range-end=%" PRId64 ", "
475 "mapping-b-range-start=%" PRId64 ", "
476 "mapping-b-range-end=%" PRId64,
477 g_quark_to_string(mapping->string),
478 mapping->range_start._signed,
479 mapping->range_end._signed,
480 overlap_query->range_start._signed,
481 overlap_query->range_end._signed);
482 }
483}
484
485static
486void check_ranges_overlap_unsigned(gpointer element, gpointer query)
487{
488 struct bt_ctf_enumeration_mapping *mapping = element;
489 struct range_overlap_query *overlap_query = query;
490
491 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
492 && overlap_query->range_start._unsigned <=
493 mapping->range_end._unsigned) {
494 overlap_query->overlaps = 1;
495 overlap_query->mapping_name = mapping->string;
496 }
497
498 overlap_query->overlaps |=
499 mapping->string == overlap_query->mapping_name;
500
501 if (overlap_query->overlaps) {
502 BT_LOGW("Overlapping enumeration field type mappings: "
503 "mapping-name=\"%s\", "
504 "mapping-a-range-start=%" PRIu64 ", "
505 "mapping-a-range-end=%" PRIu64 ", "
506 "mapping-b-range-start=%" PRIu64 ", "
507 "mapping-b-range-end=%" PRIu64,
508 g_quark_to_string(mapping->string),
509 mapping->range_start._unsigned,
510 mapping->range_end._unsigned,
511 overlap_query->range_start._unsigned,
512 overlap_query->range_end._unsigned);
513 }
514}
515
516static
517gint compare_enumeration_mappings_signed(struct bt_ctf_enumeration_mapping **a,
518 struct bt_ctf_enumeration_mapping **b)
519{
520 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
521}
522
523static
524gint compare_enumeration_mappings_unsigned(struct bt_ctf_enumeration_mapping **a,
525 struct bt_ctf_enumeration_mapping **b)
526{
527 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
528}
529
530static
531int add_structure_variant_member(GArray *members,
532 GHashTable *field_name_to_index,
533 struct bt_ctf_field_type_common *field_type, const char *field_name,
534 bool is_variant)
535{
536 int ret = 0;
537 GQuark name_quark = g_quark_from_string(field_name);
538 struct bt_ctf_field_type_common **member_ft;
539 GQuark *member_name;
540
541 /* Make sure structure does not contain a field of the same name */
542 if (g_hash_table_lookup_extended(field_name_to_index,
543 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
544 BT_LOGW("Structure or variant field type already contains a field type with this name: "
545 "field-name=\"%s\"", field_name);
546 ret = -1;
547 goto end;
548 }
549
550 g_array_set_size(members, members->len + 1);
551
552 if (is_variant) {
553 struct bt_ctf_field_type_common_variant_choice *choice =
554 &g_array_index(members,
555 struct bt_ctf_field_type_common_variant_choice,
556 members->len - 1);
557
558 member_ft = &choice->type;
559 member_name = &choice->name;
98b15851 560 BT_ASSERT_DBG(!choice->ranges);
16ca5ff0
PP
561 choice->ranges = g_array_new(FALSE, TRUE,
562 sizeof(struct bt_ctf_field_type_common_variant_choice_range));
98b15851 563 BT_ASSERT_DBG(choice->ranges);
16ca5ff0
PP
564 } else {
565 struct bt_ctf_field_type_common_structure_field *field =
566 &g_array_index(members,
567 struct bt_ctf_field_type_common_structure_field,
568 members->len - 1);
569
570 member_ft = &field->type;
571 member_name = &field->name;
572 }
573
574 *member_name = name_quark;
e1e02a22 575 *member_ft = bt_ctf_object_get_ref(field_type);
16ca5ff0
PP
576 g_hash_table_insert(field_name_to_index,
577 GUINT_TO_POINTER(name_quark),
578 GUINT_TO_POINTER(members->len - 1));
ef267d12 579 BT_LOGT("Added structure/variant field type member: member-ft-addr=%p, "
16ca5ff0
PP
580 "member-name=\"%s\"", field_type, field_name);
581
582end:
583 return ret;
584}
585
586BT_HIDDEN
587int bt_ctf_field_type_common_integer_validate(struct bt_ctf_field_type_common *ft)
588{
589 int ret = 0;
590 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
591
592 if (int_ft->mapped_clock_class && int_ft->is_signed) {
593 BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
594 "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
595 ft, int_ft->mapped_clock_class,
596 bt_ctf_clock_class_get_name(int_ft->mapped_clock_class));
597 ret = -1;
598 goto end;
599 }
600
601end:
602 return ret;
603}
604
605static
e1e02a22 606void bt_ctf_field_type_enum_iter_destroy(struct bt_ctf_object *obj)
16ca5ff0
PP
607{
608 struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
609 container_of(obj,
610 struct bt_ctf_field_type_enumeration_mapping_iterator,
611 base);
612
613 BT_LOGD("Destroying enumeration field type mapping iterator: addr=%p",
614 obj);
615 BT_LOGD_STR("Putting parent enumeration field type.");
e1e02a22 616 bt_ctf_object_put_ref(iter->enumeration_ft);
16ca5ff0
PP
617 g_free(iter);
618}
619
620static
621struct bt_ctf_field_type_enumeration_mapping_iterator *
622bt_ctf_field_type_common_enumeration_find_mappings_type(
623 struct bt_ctf_field_type_common *ft,
624 enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type)
625{
626 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
627
67d2ce02
MJ
628 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
629 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM,
16ca5ff0
PP
630 "Field type");
631 iter = g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator, 1);
632 if (!iter) {
633 BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
634 goto end;
635 }
636
e1e02a22
PP
637 bt_ctf_object_init_shared(&iter->base, bt_ctf_field_type_enum_iter_destroy);
638 iter->enumeration_ft = bt_ctf_object_get_ref(ft);
16ca5ff0
PP
639 iter->index = -1;
640 iter->type = iterator_type;
641
642end:
643 return iter;
644}
645
646BT_HIDDEN
647struct bt_ctf_field_type_enumeration_mapping_iterator *
648bt_ctf_field_type_common_enumeration_find_mappings_by_name(
649 struct bt_ctf_field_type_common *ft, const char *name)
650{
651 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
652
653 iter = bt_ctf_field_type_common_enumeration_find_mappings_type(
654 ft, CTF_ITERATOR_BY_NAME);
655 if (!iter) {
656 BT_LOGW("Cannot create enumeration field type mapping iterator: "
657 "ft-addr=%p, mapping-name=\"%s\"", ft, name);
658 goto error;
659 }
660
661 iter->u.name_quark = g_quark_try_string(name);
662 if (!iter->u.name_quark) {
663 /*
664 * No results are possible, set the iterator's position at the
665 * end.
666 */
667 iter->index = iter->enumeration_ft->entries->len;
668 }
669
670 return iter;
671
672error:
e1e02a22 673 bt_ctf_object_put_ref(iter);
16ca5ff0
PP
674 return NULL;
675}
676
677static
678struct bt_ctf_enumeration_mapping *bt_ctf_field_type_common_enumeration_get_mapping_by_index(
679 struct bt_ctf_field_type_common *ft, uint64_t index)
680{
681 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
682 struct bt_ctf_enumeration_mapping *mapping = NULL;
683
684 if (index >= enum_ft->entries->len) {
685 BT_LOGW("Invalid parameter: index is out of bounds: "
686 "addr=%p, index=%" PRIu64 ", count=%u",
687 ft, index, enum_ft->entries->len);
688 goto end;
689 }
690
691 mapping = g_ptr_array_index(enum_ft->entries, index);
692
693end:
694 return mapping;
695}
696
697BT_HIDDEN
698int bt_ctf_field_type_enumeration_mapping_iterator_next(
699 struct bt_ctf_field_type_enumeration_mapping_iterator *iter)
700{
701 struct bt_ctf_field_type_common_enumeration *enum_ft = iter->enumeration_ft;
702 int i, ret = 0, len;
703
67d2ce02 704 BT_CTF_ASSERT_PRE_NON_NULL(iter, "Enumeration field type mapping iterator");
16ca5ff0
PP
705 len = enum_ft->entries->len;
706 for (i = iter->index + 1; i < len; i++) {
707 struct bt_ctf_enumeration_mapping *mapping =
708 bt_ctf_field_type_common_enumeration_get_mapping_by_index(
709 BT_CTF_TO_COMMON(enum_ft), i);
710
711 switch (iter->type) {
712 case CTF_ITERATOR_BY_NAME:
713 if (mapping->string == iter->u.name_quark) {
714 iter->index = i;
715 goto end;
716 }
717 break;
718 case CTF_ITERATOR_BY_SIGNED_VALUE:
719 {
720 int64_t value = iter->u.signed_value;
721
722 if (value >= mapping->range_start._signed &&
723 value <= mapping->range_end._signed) {
724 iter->index = i;
725 goto end;
726 }
727 break;
728 }
729 case CTF_ITERATOR_BY_UNSIGNED_VALUE:
730 {
731 uint64_t value = iter->u.unsigned_value;
732
733 if (value >= mapping->range_start._unsigned &&
734 value <= mapping->range_end._unsigned) {
735 iter->index = i;
736 goto end;
737 }
738 break;
739 }
740 default:
741 BT_LOGF("Invalid enumeration field type mapping iterator type: "
742 "type=%d", iter->type);
743 abort();
744 }
745 }
746
747 ret = -1;
748
749end:
750 return ret;
751}
752
753BT_HIDDEN
754struct bt_ctf_field_type_enumeration_mapping_iterator *
755bt_ctf_field_type_common_enumeration_signed_find_mappings_by_value(
756 struct bt_ctf_field_type_common *ft, int64_t value)
757{
758 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
759
760 iter = bt_ctf_field_type_common_enumeration_find_mappings_type(
761 ft, CTF_ITERATOR_BY_SIGNED_VALUE);
762 if (!iter) {
763 BT_LOGW("Cannot create enumeration field type mapping iterator: "
764 "ft-addr=%p, value=%" PRId64, ft, value);
765 goto error;
766 }
767
768 if (bt_ctf_field_type_common_integer_is_signed(
769 BT_CTF_TO_COMMON(iter->enumeration_ft->container_ft)) != 1) {
770 BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
771 "enum-ft-addr=%p, int-ft-addr=%p",
772 ft, iter->enumeration_ft->container_ft);
773 goto error;
774 }
775
776 iter->u.signed_value = value;
777 return iter;
778
779error:
e1e02a22 780 bt_ctf_object_put_ref(iter);
16ca5ff0
PP
781 return NULL;
782}
783
784BT_HIDDEN
785struct bt_ctf_field_type_enumeration_mapping_iterator *
786bt_ctf_field_type_common_enumeration_unsigned_find_mappings_by_value(
787 struct bt_ctf_field_type_common *ft, uint64_t value)
788{
789 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
790
791 iter = bt_ctf_field_type_common_enumeration_find_mappings_type(
792 ft, CTF_ITERATOR_BY_UNSIGNED_VALUE);
793 if (!iter) {
794 BT_LOGW("Cannot create enumeration field type mapping iterator: "
795 "ft-addr=%p, value=%" PRIu64, ft, value);
796 goto error;
797 }
798
799 if (bt_ctf_field_type_common_integer_is_signed(
800 BT_CTF_TO_COMMON(iter->enumeration_ft->container_ft)) != 0) {
801 BT_LOGW("Invalid parameter: enumeration field type is signed: "
802 "enum-ft-addr=%p, int-ft-addr=%p",
803 ft, iter->enumeration_ft->container_ft);
804 goto error;
805 }
806
807 iter->u.unsigned_value = value;
808 return iter;
809
810error:
e1e02a22 811 bt_ctf_object_put_ref(iter);
16ca5ff0
PP
812 return NULL;
813}
814
815BT_HIDDEN
816int bt_ctf_field_type_enumeration_mapping_iterator_signed_get(
817 struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
818 const char **mapping_name, int64_t *range_begin,
819 int64_t *range_end)
820{
67d2ce02
MJ
821 BT_CTF_ASSERT_PRE_NON_NULL(iter, "Enumeration field type mapping iterator");
822 BT_CTF_ASSERT_PRE(iter->index != -1,
16ca5ff0
PP
823 "Invalid enumeration field type mapping iterator access: "
824 "addr=%p, position=-1", iter);
825 return bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
826 (void *) iter->enumeration_ft, iter->index,
827 mapping_name, range_begin, range_end);
828}
829
830BT_HIDDEN
831int bt_ctf_field_type_enumeration_mapping_iterator_unsigned_get(
832 struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
833 const char **mapping_name, uint64_t *range_begin,
834 uint64_t *range_end)
835{
67d2ce02
MJ
836 BT_CTF_ASSERT_PRE_NON_NULL(iter, "Enumeration field type mapping iterator");
837 BT_CTF_ASSERT_PRE(iter->index != -1,
16ca5ff0
PP
838 "Invalid enumeration field type mapping iterator access: "
839 "addr=%p, position=-1", iter);
840 return bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
841 (void *) iter->enumeration_ft, iter->index,
842 mapping_name, range_begin, range_end);
843}
844
845/*
846 * Note: This algorithm is O(n^2) vs number of enumeration mappings.
847 * Only used when freezing an enumeration.
848 */
849static
850void bt_ctf_field_type_common_enumeration_set_range_overlap(
851 struct bt_ctf_field_type_common_enumeration *ft)
852{
853 int64_t i, j, len;
854 int is_signed;
855
ef267d12 856 BT_LOGT("Setting enumeration field type's overlap flag: addr=%p",
16ca5ff0
PP
857 ft);
858 len = ft->entries->len;
859 is_signed = bt_ctf_field_type_common_integer_is_signed(
860 BT_CTF_TO_COMMON(ft->container_ft));
861
862 for (i = 0; i < len; i++) {
863 for (j = i + 1; j < len; j++) {
864 struct bt_ctf_enumeration_mapping *mapping[2];
865
866 mapping[0] = bt_ctf_field_type_common_enumeration_get_mapping_by_index(
867 BT_CTF_TO_COMMON(ft), i);
868 mapping[1] = bt_ctf_field_type_common_enumeration_get_mapping_by_index(
869 BT_CTF_TO_COMMON(ft), j);
870 if (is_signed) {
871 if (mapping[0]->range_start._signed
872 <= mapping[1]->range_end._signed
873 && mapping[0]->range_end._signed
874 >= mapping[1]->range_start._signed) {
00409097 875 ft->has_overlapping_ranges = BT_CTF_TRUE;
16ca5ff0
PP
876 goto end;
877 }
878 } else {
879 if (mapping[0]->range_start._unsigned
880 <= mapping[1]->range_end._unsigned
881 && mapping[0]->range_end._unsigned
882 >= mapping[1]->range_start._unsigned) {
00409097 883 ft->has_overlapping_ranges = BT_CTF_TRUE;
16ca5ff0
PP
884 goto end;
885 }
886 }
887 }
888 }
889
890end:
891 if (ft->has_overlapping_ranges) {
ef267d12 892 BT_LOGT_STR("Enumeration field type has overlapping ranges.");
16ca5ff0 893 } else {
ef267d12 894 BT_LOGT_STR("Enumeration field type has no overlapping ranges.");
16ca5ff0
PP
895 }
896}
897
898BT_HIDDEN
899int bt_ctf_field_type_common_enumeration_validate_recursive(
900 struct bt_ctf_field_type_common *ft)
901{
902 int ret = 0;
903 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
904
905 ret = bt_ctf_field_type_common_integer_validate(
906 BT_CTF_TO_COMMON(enum_ft->container_ft));
907 if (ret) {
908 BT_LOGW("Invalid enumeration field type: container type is invalid: "
909 "enum-ft-addr=%p, int-ft-addr=%p",
910 ft, enum_ft->container_ft);
911 goto end;
912 }
913
914 /* Ensure enum has entries */
915 if (enum_ft->entries->len == 0) {
916 BT_LOGW("Invalid enumeration field type: no entries: "
917 "addr=%p", ft);
918 ret = -1;
919 goto end;
920 }
921
922end:
923 return ret;
924}
925
926BT_HIDDEN
927int bt_ctf_field_type_common_sequence_validate_recursive(
928 struct bt_ctf_field_type_common *ft)
929{
930 int ret = 0;
931 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
932
933 /* Length field name should be set at this point */
934 if (seq_ft->length_field_name->len == 0) {
935 BT_LOGW("Invalid sequence field type: no length field name: "
936 "addr=%p", ft);
937 ret = -1;
938 goto end;
939 }
940
941 ret = bt_ctf_field_type_common_validate(seq_ft->element_ft);
942 if (ret) {
943 BT_LOGW("Invalid sequence field type: invalid element field type: "
944 "seq-ft-addr=%p, element-ft-add=%p",
945 ft, seq_ft->element_ft);
946 }
947
948end:
949 return ret;
950}
951
952BT_HIDDEN
953int bt_ctf_field_type_common_array_validate_recursive(
954 struct bt_ctf_field_type_common *ft)
955{
956 int ret = 0;
957 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
958
959 ret = bt_ctf_field_type_common_validate(array_ft->element_ft);
960 if (ret) {
961 BT_LOGW("Invalid array field type: invalid element field type: "
962 "array-ft-addr=%p, element-ft-add=%p",
963 ft, array_ft->element_ft);
964 }
965
966 return ret;
967}
968
969BT_HIDDEN
970int bt_ctf_field_type_common_structure_validate_recursive(
971 struct bt_ctf_field_type_common *ft)
972{
973 int ret = 0;
974 struct bt_ctf_field_type_common *child_ft = NULL;
975 int64_t field_count =
976 bt_ctf_field_type_common_structure_get_field_count(ft);
977 int64_t i;
978
98b15851 979 BT_ASSERT_DBG(field_count >= 0);
16ca5ff0
PP
980
981 for (i = 0; i < field_count; ++i) {
982 const char *field_name;
983
984 ret = bt_ctf_field_type_common_structure_borrow_field_by_index(ft,
985 &field_name, &child_ft, i);
98b15851 986 BT_ASSERT_DBG(ret == 0);
16ca5ff0
PP
987 ret = bt_ctf_field_type_common_validate(child_ft);
988 if (ret) {
989 BT_LOGW("Invalid structure field type: "
990 "a contained field type is invalid: "
991 "struct-ft-addr=%p, field-ft-addr=%p, "
992 "field-name=\"%s\", field-index=%" PRId64,
993 ft, child_ft, field_name, i);
994 goto end;
995 }
996 }
997
998end:
999 return ret;
1000}
1001
1002static
00409097 1003bt_ctf_bool bt_ctf_field_type_common_enumeration_has_overlapping_ranges(
16ca5ff0
PP
1004 struct bt_ctf_field_type_common_enumeration *enum_ft)
1005{
1006 if (!enum_ft->common.frozen) {
1007 bt_ctf_field_type_common_enumeration_set_range_overlap(enum_ft);
1008 }
1009
1010 return enum_ft->has_overlapping_ranges;
1011}
1012
1013BT_HIDDEN
1014int bt_ctf_field_type_common_variant_validate_recursive(
1015 struct bt_ctf_field_type_common *ft)
1016{
1017 int ret = 0;
1018 int64_t field_count;
1019 struct bt_ctf_field_type_common *child_ft = NULL;
1020 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
1021 int64_t i;
1022
1023 if (var_ft->tag_name->len == 0) {
1024 BT_LOGW("Invalid variant field type: no tag field name: "
1025 "addr=%p", ft);
1026 ret = -1;
1027 goto end;
1028 }
1029
1030 if (!var_ft->tag_ft) {
1031 BT_LOGW("Invalid variant field type: no tag field type: "
1032 "addr=%p, tag-field-name=\"%s\"", var_ft,
1033 var_ft->tag_name->str);
1034 ret = -1;
1035 goto end;
1036 }
1037
1038 if (bt_ctf_field_type_common_enumeration_has_overlapping_ranges(var_ft->tag_ft)) {
1039 BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
1040 "variant-ft-addr=%p, tag-field-name=\"%s\", "
1041 "enum-ft-addr=%p", ft, var_ft->tag_name->str,
1042 var_ft->tag_ft);
1043 ret = -1;
1044 goto end;
1045 }
1046
1047 /*
1048 * It is valid to have a variant field type which does not have
1049 * the fields corresponding to each label in the associated
1050 * enumeration.
1051 *
1052 * It is also valid to have variant field type fields which
1053 * cannot be selected because the variant field type tag has no
1054 * mapping named as such. This scenario, while not ideal, cannot
1055 * cause any error.
1056 *
1057 * If a non-existing field happens to be selected by an
1058 * enumeration while reading a variant field, an error will be
1059 * generated at that point (while reading the stream).
1060 */
1061 field_count = bt_ctf_field_type_common_variant_get_field_count(ft);
1062 if (field_count < 0) {
1063 BT_LOGW("Invalid variant field type: no fields: "
1064 "addr=%p, tag-field-name=\"%s\"",
1065 ft, var_ft->tag_name->str);
1066 ret = -1;
1067 goto end;
1068 }
1069
1070 for (i = 0; i < field_count; ++i) {
1071 const char *field_name;
1072
1073 ret = bt_ctf_field_type_common_variant_borrow_field_by_index(ft,
1074 &field_name, &child_ft, i);
98b15851 1075 BT_ASSERT_DBG(ret == 0);
16ca5ff0
PP
1076 ret = bt_ctf_field_type_common_validate(child_ft);
1077 if (ret) {
1078 BT_LOGW("Invalid variant field type: "
1079 "a contained field type is invalid: "
1080 "variant-ft-addr=%p, tag-field-name=\"%s\", "
1081 "field-ft-addr=%p, field-name=\"%s\", "
1082 "field-index=%" PRId64,
1083 ft, var_ft->tag_name->str, child_ft,
1084 field_name, i);
1085 goto end;
1086 }
1087 }
1088
1089end:
1090 return ret;
1091}
1092
1093/*
1094 * This function validates a given field type without considering
1095 * where this field type is located. It only validates the properties
1096 * of the given field type and the properties of its children if
1097 * applicable.
1098 */
1099BT_HIDDEN
1100int bt_ctf_field_type_common_validate(struct bt_ctf_field_type_common *ft)
1101{
1102 int ret = 0;
1103
98b15851 1104 BT_ASSERT_DBG(ft);
16ca5ff0
PP
1105
1106 if (ft->valid) {
1107 /* Already marked as valid */
1108 goto end;
1109 }
1110
1111 if (ft->methods->validate) {
1112 ret = ft->methods->validate(ft);
1113 }
1114
1115 if (ret == 0 && ft->frozen) {
1116 /* Field type is valid */
ef267d12 1117 BT_LOGT("Marking field type as valid: addr=%p", ft);
16ca5ff0
PP
1118 ft->valid = 1;
1119 }
1120
1121end:
1122 return ret;
1123}
1124
1125BT_HIDDEN
1126int bt_ctf_field_type_common_integer_get_size(struct bt_ctf_field_type_common *ft)
1127{
1128 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1129
67d2ce02
MJ
1130 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1131 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
16ca5ff0
PP
1132 "Field type");
1133 return (int) int_ft->size;
1134}
1135
1136BT_HIDDEN
00409097 1137bt_ctf_bool bt_ctf_field_type_common_integer_is_signed(struct bt_ctf_field_type_common *ft)
16ca5ff0
PP
1138{
1139 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1140
67d2ce02
MJ
1141 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1142 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
16ca5ff0
PP
1143 "Field type");
1144 return int_ft->is_signed;
1145}
1146
1147BT_HIDDEN
1148int bt_ctf_field_type_common_integer_set_is_signed(struct bt_ctf_field_type_common *ft,
00409097 1149 bt_ctf_bool is_signed)
16ca5ff0
PP
1150{
1151 int ret = 0;
1152 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1153
1154 if (!ft) {
1155 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1156 ret = -1;
1157 goto end;
1158 }
1159
1160 if (ft->frozen) {
1161 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1162 ft);
1163 ret = -1;
1164 goto end;
1165 }
1166
1167 if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1168 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1169 "addr=%p, ft-id=%s", ft,
1170 bt_ctf_field_type_id_string(ft->id));
1171 ret = -1;
1172 goto end;
1173 }
1174
1175 int_ft->is_signed = !!is_signed;
ef267d12 1176 BT_LOGT("Set integer field type's signedness: addr=%p, is-signed=%d",
16ca5ff0
PP
1177 ft, is_signed);
1178
1179end:
1180 return ret;
1181}
1182
1183BT_HIDDEN
1184int bt_ctf_field_type_common_integer_set_size(struct bt_ctf_field_type_common *ft,
1185 unsigned int size)
1186{
1187 int ret = 0;
1188 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1189
1190 if (!ft) {
1191 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1192 ret = -1;
1193 goto end;
1194 }
1195
1196 if (ft->frozen) {
1197 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1198 ft);
1199 ret = -1;
1200 goto end;
1201 }
1202
1203 if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1204 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1205 "addr=%p, ft-id=%s", ft,
1206 bt_ctf_field_type_id_string(ft->id));
1207 ret = -1;
1208 goto end;
1209 }
1210
1211 if (size == 0 || size > 64) {
1212 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
1213 "addr=%p, size=%u", ft, size);
1214 ret = -1;
1215 goto end;
1216 }
1217
1218 int_ft->size = size;
ef267d12 1219 BT_LOGT("Set integer field type's size: addr=%p, size=%u",
16ca5ff0
PP
1220 ft, size);
1221
1222end:
1223 return ret;
1224}
1225
1226BT_HIDDEN
1227enum bt_ctf_integer_base bt_ctf_field_type_common_integer_get_base(
1228 struct bt_ctf_field_type_common *ft)
1229{
1230 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1231
67d2ce02
MJ
1232 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1233 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
16ca5ff0
PP
1234 "Field type");
1235 return int_ft->base;
1236}
1237
1238BT_HIDDEN
1239int bt_ctf_field_type_common_integer_set_base(struct bt_ctf_field_type_common *ft,
1240 enum bt_ctf_integer_base base)
1241{
1242 int ret = 0;
1243 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1244
1245 if (!ft) {
1246 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1247 ret = -1;
1248 goto end;
1249 }
1250
1251 if (ft->frozen) {
1252 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1253 ft);
1254 ret = -1;
1255 goto end;
1256 }
1257
1258 if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1259 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1260 "addr=%p, ft-id=%s", ft,
1261 bt_ctf_field_type_id_string(ft->id));
1262 ret = -1;
1263 goto end;
1264 }
1265
1266 switch (base) {
1267 case BT_CTF_INTEGER_BASE_UNSPECIFIED:
1268 case BT_CTF_INTEGER_BASE_BINARY:
1269 case BT_CTF_INTEGER_BASE_OCTAL:
1270 case BT_CTF_INTEGER_BASE_DECIMAL:
1271 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
1272 {
1273 int_ft->base = base;
1274 break;
1275 }
1276 default:
1277 BT_LOGW("Invalid parameter: unknown integer field type base: "
1278 "addr=%p, base=%d", ft, base);
1279 ret = -1;
1280 }
1281
ef267d12 1282 BT_LOGT("Set integer field type's base: addr=%p, base=%s",
16ca5ff0
PP
1283 ft, bt_ctf_integer_base_string(base));
1284
1285end:
1286 return ret;
1287}
1288
1289BT_HIDDEN
1290enum bt_ctf_string_encoding bt_ctf_field_type_common_integer_get_encoding(
1291 struct bt_ctf_field_type_common *ft)
1292{
1293 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1294
67d2ce02
MJ
1295 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1296 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
16ca5ff0
PP
1297 "Field type");
1298 return int_ft->encoding;
1299}
1300
1301BT_HIDDEN
1302int bt_ctf_field_type_common_integer_set_encoding(struct bt_ctf_field_type_common *ft,
1303 enum bt_ctf_string_encoding encoding)
1304{
1305 int ret = 0;
1306 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1307
1308 if (!ft) {
1309 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1310 ret = -1;
1311 goto end;
1312 }
1313
1314 if (ft->frozen) {
1315 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1316 ft);
1317 ret = -1;
1318 goto end;
1319 }
1320
1321 if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1322 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1323 "addr=%p, ft-id=%s", ft,
1324 bt_ctf_field_type_id_string(ft->id));
1325 ret = -1;
1326 goto end;
1327 }
1328
1329 if (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
1330 encoding != BT_CTF_STRING_ENCODING_ASCII &&
1331 encoding != BT_CTF_STRING_ENCODING_NONE) {
1332 BT_LOGW("Invalid parameter: unknown string encoding: "
1333 "addr=%p, encoding=%d", ft, encoding);
1334 ret = -1;
1335 goto end;
1336 }
1337
1338 int_ft->encoding = encoding;
ef267d12 1339 BT_LOGT("Set integer field type's encoding: addr=%p, encoding=%s",
16ca5ff0
PP
1340 ft, bt_ctf_string_encoding_string(encoding));
1341
1342end:
1343 return ret;
1344}
1345
1346BT_HIDDEN
1347struct bt_ctf_clock_class *bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
1348 struct bt_ctf_field_type_common *ft)
1349{
1350 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1351
67d2ce02
MJ
1352 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1353 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
16ca5ff0
PP
1354 "Field type");
1355 return int_ft->mapped_clock_class;
1356}
1357
1358BT_HIDDEN
1359int bt_ctf_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
1360 struct bt_ctf_field_type_common *ft,
1361 struct bt_ctf_clock_class *clock_class)
1362{
1363 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
1364 int ret = 0;
1365
1366 if (!clock_class) {
1367 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
1368 ret = -1;
1369 goto end;
1370 }
1371
1372 if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1373 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1374 "addr=%p, ft-id=%s", ft,
1375 bt_ctf_field_type_id_string(ft->id));
1376 goto end;
1377 }
1378
1379 if (!bt_ctf_clock_class_is_valid(clock_class)) {
1380 BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
1381 "clock-class-addr=%p, clock-class-name=\"%s\"",
1382 ft, clock_class,
1383 bt_ctf_clock_class_get_name(clock_class));
1384 ret = -1;
1385 goto end;
1386 }
1387
e1e02a22
PP
1388 bt_ctf_object_put_ref(int_ft->mapped_clock_class);
1389 int_ft->mapped_clock_class = bt_ctf_object_get_ref(clock_class);
ef267d12 1390 BT_LOGT("Set integer field type's mapped clock class: ft-addr=%p, "
16ca5ff0
PP
1391 "clock-class-addr=%p, clock-class-name=\"%s\"",
1392 ft, clock_class, bt_ctf_clock_class_get_name(clock_class));
1393
1394end:
1395 return ret;
1396}
1397
1398BT_HIDDEN
1399int bt_ctf_field_type_common_integer_set_mapped_clock_class(
1400 struct bt_ctf_field_type_common *ft,
1401 struct bt_ctf_clock_class *clock_class)
1402{
1403 int ret = 0;
1404
1405 if (!ft) {
1406 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1407 ret = -1;
1408 goto end;
1409 }
1410
1411 if (ft->frozen) {
1412 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1413 ft);
1414 ret = -1;
1415 goto end;
1416 }
1417
1418 ret = bt_ctf_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
1419 ft, clock_class);
1420
1421end:
1422 return ret;
1423}
1424
1425BT_HIDDEN
1426int bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
1427 struct bt_ctf_field_type_common *ft, uint64_t index,
1428 const char **mapping_name, int64_t *range_begin,
1429 int64_t *range_end)
1430{
1431 int ret = 0;
1432 struct bt_ctf_enumeration_mapping *mapping;
1433
67d2ce02
MJ
1434 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1435 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft,
16ca5ff0
PP
1436 BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
1437 mapping = bt_ctf_field_type_common_enumeration_get_mapping_by_index(ft,
1438 index);
1439 if (!mapping) {
1440 /* bt_ctf_field_type_common_enumeration_get_mapping_by_index() logs errors */
1441 ret = -1;
1442 goto end;
1443 }
1444
1445 if (mapping_name) {
1446 *mapping_name = g_quark_to_string(mapping->string);
98b15851 1447 BT_ASSERT_DBG(*mapping_name);
16ca5ff0
PP
1448 }
1449
1450 if (range_begin) {
1451 *range_begin = mapping->range_start._signed;
1452 }
1453
1454 if (range_end) {
1455 *range_end = mapping->range_end._signed;
1456 }
1457
1458end:
1459 return ret;
1460}
1461
1462BT_HIDDEN
1463int bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
1464 struct bt_ctf_field_type_common *ft, uint64_t index,
1465 const char **mapping_name, uint64_t *range_begin,
1466 uint64_t *range_end)
1467{
1468 int ret = 0;
1469 struct bt_ctf_enumeration_mapping *mapping;
1470
67d2ce02
MJ
1471 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1472 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
16ca5ff0
PP
1473 mapping = bt_ctf_field_type_common_enumeration_get_mapping_by_index(
1474 ft, index);
1475 if (!mapping) {
1476 /* bt_ctf_field_type_common_enumeration_get_mapping_by_index() reports any error */
1477 ret = -1;
1478 goto end;
1479 }
1480
1481 if (mapping_name) {
1482 *mapping_name = g_quark_to_string(mapping->string);
98b15851 1483 BT_ASSERT_DBG(*mapping_name);
16ca5ff0
PP
1484 }
1485
1486 if (range_begin) {
1487 *range_begin = mapping->range_start._unsigned;
1488 }
1489
1490 if (range_end) {
1491 *range_end = mapping->range_end._unsigned;
1492 }
1493
1494end:
1495 return ret;
1496}
1497
1498BT_HIDDEN
1499struct bt_ctf_field_type_common *
1500bt_ctf_field_type_common_enumeration_borrow_container_field_type(
1501 struct bt_ctf_field_type_common *ft)
1502{
1503 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
1504
67d2ce02
MJ
1505 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1506 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
16ca5ff0
PP
1507 return BT_CTF_TO_COMMON(enum_ft->container_ft);
1508}
1509
1510BT_HIDDEN
1511int bt_ctf_field_type_common_enumeration_signed_add_mapping(
1512 struct bt_ctf_field_type_common *ft, const char *string,
1513 int64_t range_start, int64_t range_end)
1514{
1515 int ret = 0;
1516 GQuark mapping_name;
1517 struct bt_ctf_enumeration_mapping *mapping;
1518 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
1519 char *escaped_string;
1520
1521 if (!ft) {
1522 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1523 ret = -1;
1524 goto end;
1525 }
1526
1527 if (!string) {
1528 BT_LOGW_STR("Invalid parameter: string is NULL.");
1529 ret = -1;
1530 goto end;
1531 }
1532
1533 if (ft->frozen) {
1534 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1535 ft);
1536 ret = -1;
1537 goto end;
1538 }
1539
1540 if (ft->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
1541 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1542 "addr=%p, ft-id=%s", ft,
1543 bt_ctf_field_type_id_string(ft->id));
1544 ret = -1;
1545 goto end;
1546 }
1547
1548 if (range_end < range_start) {
1549 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1550 "addr=%p, range-start=%" PRId64 ", range-end=%" PRId64,
1551 ft, range_start, range_end);
1552 ret = -1;
1553 goto end;
1554 }
1555
1556 if (strlen(string) == 0) {
1557 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1558 "enum-ft-addr=%p, mapping-name-addr=%p", ft,
1559 string);
1560 ret = -1;
1561 goto end;
1562 }
1563
1564 escaped_string = g_strescape(string, NULL);
1565 if (!escaped_string) {
1566 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1567 "mapping-name-addr=%p, mapping-name=\"%s\"",
1568 ft, string, string);
1569 ret = -1;
1570 goto end;
1571 }
1572
1573 mapping = g_new(struct bt_ctf_enumeration_mapping, 1);
1574 if (!mapping) {
1575 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1576 ret = -1;
1577 goto error_free;
1578 }
1579 mapping_name = g_quark_from_string(escaped_string);
1580 *mapping = (struct bt_ctf_enumeration_mapping) {
1581 .range_start._signed = range_start,
1582 .range_end._signed = range_end,
1583 .string = mapping_name,
1584 };
1585 g_ptr_array_add(enum_ft->entries, mapping);
1586 g_ptr_array_sort(enum_ft->entries,
1587 (GCompareFunc) compare_enumeration_mappings_signed);
ef267d12 1588 BT_LOGT("Added mapping to signed enumeration field type: addr=%p, "
16ca5ff0
PP
1589 "name=\"%s\", range-start=%" PRId64 ", "
1590 "range-end=%" PRId64,
1591 ft, string, range_start, range_end);
1592
1593error_free:
1594 free(escaped_string);
1595
1596end:
1597 return ret;
1598}
1599
1600BT_HIDDEN
1601int bt_ctf_field_type_common_enumeration_unsigned_add_mapping(
1602 struct bt_ctf_field_type_common *ft, const char *string,
1603 uint64_t range_start, uint64_t range_end)
1604{
1605 int ret = 0;
1606 GQuark mapping_name;
1607 struct bt_ctf_enumeration_mapping *mapping;
1608 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
1609 char *escaped_string;
1610
1611 if (!ft) {
1612 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1613 ret = -1;
1614 goto end;
1615 }
1616
1617 if (!string) {
1618 BT_LOGW_STR("Invalid parameter: string is NULL.");
1619 ret = -1;
1620 goto end;
1621 }
1622
1623 if (ft->frozen) {
1624 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1625 ft);
1626 ret = -1;
1627 goto end;
1628 }
1629
1630 if (ft->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
1631 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1632 "addr=%p, ft-id=%s", ft,
1633 bt_ctf_field_type_id_string(ft->id));
1634 ret = -1;
1635 goto end;
1636 }
1637
1638 if (range_end < range_start) {
1639 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1640 "addr=%p, range-start=%" PRIu64 ", range-end=%" PRIu64,
1641 ft, range_start, range_end);
1642 ret = -1;
1643 goto end;
1644 }
1645
1646 if (strlen(string) == 0) {
1647 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1648 "enum-ft-addr=%p, mapping-name-addr=%p", ft,
1649 string);
1650 ret = -1;
1651 goto end;
1652 }
1653
1654 escaped_string = g_strescape(string, NULL);
1655 if (!escaped_string) {
1656 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1657 "mapping-name-addr=%p, mapping-name=\"%s\"",
1658 ft, string, string);
1659 ret = -1;
1660 goto end;
1661 }
1662
1663 mapping = g_new(struct bt_ctf_enumeration_mapping, 1);
1664 if (!mapping) {
1665 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1666 ret = -1;
1667 goto error_free;
1668 }
1669 mapping_name = g_quark_from_string(escaped_string);
1670 *mapping = (struct bt_ctf_enumeration_mapping) {
1671 .range_start._unsigned = range_start,
1672 .range_end._unsigned = range_end,
1673 .string = mapping_name,
1674 };
1675 g_ptr_array_add(enum_ft->entries, mapping);
1676 g_ptr_array_sort(enum_ft->entries,
1677 (GCompareFunc) compare_enumeration_mappings_unsigned);
ef267d12 1678 BT_LOGT("Added mapping to unsigned enumeration field type: addr=%p, "
16ca5ff0
PP
1679 "name=\"%s\", range-start=%" PRIu64 ", "
1680 "range-end=%" PRIu64,
1681 ft, string, range_start, range_end);
1682
1683error_free:
1684 free(escaped_string);
1685
1686end:
1687 return ret;
1688}
1689
1690BT_HIDDEN
1691int64_t bt_ctf_field_type_common_enumeration_get_mapping_count(
1692 struct bt_ctf_field_type_common *ft)
1693{
1694 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
1695
67d2ce02
MJ
1696 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1697 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
16ca5ff0
PP
1698 return (int64_t) enum_ft->entries->len;
1699}
1700
1701BT_HIDDEN
1702int bt_ctf_field_type_common_floating_point_get_exponent_digits(
1703 struct bt_ctf_field_type_common *ft)
1704{
1705 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
1706
67d2ce02
MJ
1707 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1708 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_FLOAT,
16ca5ff0
PP
1709 "Field type");
1710 return (int) flt_ft->exp_dig;
1711}
1712
1713BT_HIDDEN
1714int bt_ctf_field_type_common_floating_point_set_exponent_digits(
1715 struct bt_ctf_field_type_common *ft,
1716 unsigned int exponent_digits)
1717{
1718 int ret = 0;
1719 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
1720
1721 if (!ft) {
1722 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1723 ret = -1;
1724 goto end;
1725 }
1726
1727 if (ft->frozen) {
1728 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1729 ft);
1730 ret = -1;
1731 goto end;
1732 }
1733
1734 if (ft->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
1735 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1736 "addr=%p, ft-id=%s", ft,
1737 bt_ctf_field_type_id_string(ft->id));
1738 ret = -1;
1739 goto end;
1740 }
1741
1742 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1743 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1744 (exponent_digits !=
1745 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1746 BT_LOGW("Invalid parameter: invalid exponent size: "
1747 "addr=%p, exp-size=%u", ft, exponent_digits);
1748 ret = -1;
1749 goto end;
1750 }
1751
1752 flt_ft->exp_dig = exponent_digits;
ef267d12 1753 BT_LOGT("Set floating point number field type's exponent size: addr=%p, "
16ca5ff0
PP
1754 "exp-size=%u", ft, exponent_digits);
1755
1756end:
1757 return ret;
1758}
1759
1760BT_HIDDEN
1761int bt_ctf_field_type_common_floating_point_get_mantissa_digits(
1762 struct bt_ctf_field_type_common *ft)
1763{
1764 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
1765
67d2ce02
MJ
1766 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1767 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_FLOAT,
16ca5ff0
PP
1768 "Field type");
1769 return (int) flt_ft->mant_dig;
1770}
1771
1772BT_HIDDEN
1773int bt_ctf_field_type_common_floating_point_set_mantissa_digits(
1774 struct bt_ctf_field_type_common *ft, unsigned int mantissa_digits)
1775{
1776 int ret = 0;
1777 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
1778
1779 if (!ft) {
1780 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1781 ret = -1;
1782 goto end;
1783 }
1784
1785 if (ft->frozen) {
1786 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1787 ft);
1788 ret = -1;
1789 goto end;
1790 }
1791
1792 if (ft->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
1793 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1794 "addr=%p, ft-id=%s", ft,
1795 bt_ctf_field_type_id_string(ft->id));
1796 ret = -1;
1797 goto end;
1798 }
1799
1800 if ((mantissa_digits != FLT_MANT_DIG) &&
1801 (mantissa_digits != DBL_MANT_DIG) &&
1802 (mantissa_digits != LDBL_MANT_DIG)) {
1803 BT_LOGW("Invalid parameter: invalid mantissa size: "
1804 "addr=%p, mant-size=%u", ft, mantissa_digits);
1805 ret = -1;
1806 goto end;
1807 }
1808
1809 flt_ft->mant_dig = mantissa_digits;
ef267d12 1810 BT_LOGT("Set floating point number field type's mantissa size: addr=%p, "
16ca5ff0
PP
1811 "mant-size=%u", ft, mantissa_digits);
1812
1813end:
1814 return ret;
1815}
1816
1817BT_HIDDEN
1818int bt_ctf_field_type_common_structure_replace_field(
1819 struct bt_ctf_field_type_common *ft,
1820 const char *field_name,
1821 struct bt_ctf_field_type_common *field_type)
1822{
1823 int ret = 0;
1824 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
1825 GQuark name_quark;
1826 uint64_t i;
1827
98b15851
PP
1828 BT_ASSERT_DBG(ft);
1829 BT_ASSERT_DBG(field_name);
1830 BT_ASSERT_DBG(field_type);
1831 BT_ASSERT_DBG(ft->id == BT_CTF_FIELD_TYPE_ID_STRUCT);
16ca5ff0
PP
1832 name_quark = g_quark_from_string(field_name);
1833
1834 for (i = 0; i < struct_ft->fields->len; i++) {
1835 struct bt_ctf_field_type_common_structure_field *field =
1836 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, i);
1837
1838 if (field->name == name_quark) {
e1e02a22
PP
1839 bt_ctf_object_put_ref(field->type);
1840 field->type = bt_ctf_object_get_ref(field_type);
16ca5ff0
PP
1841 }
1842 }
1843
1844 return ret;
1845}
1846
1847BT_HIDDEN
1848int bt_ctf_field_type_common_structure_add_field(struct bt_ctf_field_type_common *ft,
1849 struct bt_ctf_field_type_common *field_type,
1850 const char *field_name)
1851{
1852 int ret = 0;
1853 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
1854
1855 /*
1856 * TODO: check that `field_type` does not contain `type`,
1857 * recursively.
1858 */
1859 if (!ft) {
1860 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1861 ret = -1;
1862 goto end;
1863 }
1864
1865 if (!field_name) {
1866 BT_LOGW_STR("Invalid parameter: field name is NULL.");
1867 ret = -1;
1868 goto end;
1869 }
1870
1871 if (ft->frozen) {
1872 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1873 ft);
1874 ret = -1;
1875 goto end;
1876 }
1877
1878 if (ft->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
1879 BT_LOGW("Invalid parameter: field type is not a structure field type: "
1880 "addr=%p, ft-id=%s", ft,
1881 bt_ctf_field_type_id_string(ft->id));
1882 ret = -1;
1883 goto end;
1884 }
1885
1886 if (ft == field_type) {
1887 BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
1888 "addr=%p", ft);
1889 ret = -1;
1890 goto end;
1891 }
1892
1893 if (add_structure_variant_member(struct_ft->fields,
1894 struct_ft->field_name_to_index, field_type, field_name,
1895 false)) {
1896 BT_LOGW("Cannot add field to structure field type: "
1897 "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
1898 ft, field_type, field_name);
1899 ret = -1;
1900 goto end;
1901 }
1902
ef267d12 1903 BT_LOGT("Added structure field type field: struct-ft-addr=%p, "
16ca5ff0
PP
1904 "field-ft-addr=%p, field-name=\"%s\"", ft,
1905 field_type, field_name);
1906
1907end:
1908 return ret;
1909}
1910
1911BT_HIDDEN
1912int64_t bt_ctf_field_type_common_structure_get_field_count(
1913 struct bt_ctf_field_type_common *ft)
1914{
1915 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
1916
67d2ce02
MJ
1917 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1918 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
16ca5ff0
PP
1919 "Field type");
1920 return (int64_t) struct_ft->fields->len;
1921}
1922
1923BT_HIDDEN
1924int bt_ctf_field_type_common_structure_borrow_field_by_index(
1925 struct bt_ctf_field_type_common *ft,
1926 const char **field_name,
1927 struct bt_ctf_field_type_common **field_type, uint64_t index)
1928{
1929 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
1930 struct bt_ctf_field_type_common_structure_field *field;
1931
67d2ce02
MJ
1932 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1933 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
16ca5ff0 1934 "Field type");
67d2ce02 1935 BT_CTF_ASSERT_PRE(index < struct_ft->fields->len,
16ca5ff0
PP
1936 "Index is out of bounds: index=%" PRIu64 ", "
1937 "count=%u, ft-addr=%p",
1938 index, struct_ft->fields->len, ft);
1939 field = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(struct_ft, index);
1940
1941 if (field_type) {
1942 *field_type = field->type;
1943 }
1944
1945 if (field_name) {
1946 *field_name = g_quark_to_string(field->name);
98b15851 1947 BT_ASSERT_DBG(*field_name);
16ca5ff0
PP
1948 }
1949
1950 return 0;
1951}
1952
1953BT_HIDDEN
1954struct bt_ctf_field_type_common *
1955bt_ctf_field_type_common_structure_borrow_field_type_by_name(
1956 struct bt_ctf_field_type_common *ft, const char *name)
1957{
1958 size_t index;
1959 GQuark name_quark;
1960 struct bt_ctf_field_type_common_structure_field *field;
1961 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
1962 struct bt_ctf_field_type_common *field_type = NULL;
1963
67d2ce02
MJ
1964 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
1965 BT_CTF_ASSERT_PRE_NON_NULL(name, "Name");
1966 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
16ca5ff0
PP
1967 "Field type");
1968 name_quark = g_quark_try_string(name);
1969 if (!name_quark) {
ef267d12 1970 BT_LOGT("No such structure field type field name: "
16ca5ff0
PP
1971 "ft-addr=%p, field-name=\"%s\"",
1972 ft, name);
1973 goto end;
1974 }
1975
1976 if (!g_hash_table_lookup_extended(struct_ft->field_name_to_index,
1977 GUINT_TO_POINTER(name_quark), NULL, (gpointer *) &index)) {
ef267d12 1978 BT_LOGT("No such structure field type field name: "
16ca5ff0
PP
1979 "ft-addr=%p, field-name=\"%s\"",
1980 ft, name);
1981 goto end;
1982 }
1983
1984 field = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, index);
1985 field_type = field->type;
1986
1987end:
1988 return field_type;
1989}
1990
1991BT_HIDDEN
1992struct bt_ctf_field_type_common *
1993bt_ctf_field_type_common_variant_borrow_tag_field_type(
1994 struct bt_ctf_field_type_common *ft)
1995{
1996 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
1997 struct bt_ctf_field_type_common *tag_ft = NULL;
1998
67d2ce02
MJ
1999 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2000 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0
PP
2001 "Field type");
2002
2003 if (!var_ft->tag_ft) {
ef267d12 2004 BT_LOGT("Variant field type has no tag field type: "
16ca5ff0
PP
2005 "addr=%p", ft);
2006 goto end;
2007 }
2008
2009 tag_ft = BT_CTF_TO_COMMON(var_ft->tag_ft);
2010
2011end:
2012 return tag_ft;
2013}
2014
2015BT_HIDDEN
2016const char *bt_ctf_field_type_common_variant_get_tag_name(
2017 struct bt_ctf_field_type_common *ft)
2018{
2019 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2020 const char *tag_name = NULL;
2021
67d2ce02
MJ
2022 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2023 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0
PP
2024 "Field type");
2025
2026 if (var_ft->tag_name->len == 0) {
ef267d12 2027 BT_LOGT("Variant field type has no tag field name: "
16ca5ff0
PP
2028 "addr=%p", ft);
2029 goto end;
2030 }
2031
2032 tag_name = var_ft->tag_name->str;
2033
2034end:
2035 return tag_name;
2036}
2037
2038BT_HIDDEN
2039int bt_ctf_field_type_common_variant_set_tag_name(
2040 struct bt_ctf_field_type_common *ft, const char *name)
2041{
2042 int ret = 0;
2043 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2044
2045 if (!ft) {
2046 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2047 ret = -1;
2048 goto end;
2049 }
2050
2051 if (ft->frozen) {
2052 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2053 ft);
2054 ret = -1;
2055 goto end;
2056 }
2057
2058 if (ft->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2059 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2060 "addr=%p, ft-id=%s", ft, bt_ctf_field_type_id_string(ft->id));
2061 ret = -1;
2062 goto end;
2063 }
2064
2065 if (!bt_ctf_identifier_is_valid(name)) {
2066 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2067 "variant-ft-addr=%p, tag-field-name=\"%s\"",
2068 ft, name);
2069 ret = -1;
2070 goto end;
2071 }
2072
2073 g_string_assign(var_ft->tag_name, name);
ef267d12 2074 BT_LOGT("Set variant field type's tag field name: addr=%p, "
16ca5ff0
PP
2075 "tag-field-name=\"%s\"", ft, name);
2076
2077end:
2078 return ret;
2079}
2080
2081BT_HIDDEN
2082int bt_ctf_field_type_common_variant_add_field(struct bt_ctf_field_type_common *ft,
2083 struct bt_ctf_field_type_common *field_type,
2084 const char *field_name)
2085{
2086 size_t i;
2087 int ret = 0;
2088 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2089 GQuark field_name_quark = g_quark_from_string(field_name);
2090
2091 /*
2092 * TODO: check that `field_type` does not contain `type`,
2093 * recursively.
2094 */
2095 if (!ft) {
2096 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2097 ret = -1;
2098 goto end;
2099 }
2100
2101 if (ft->frozen) {
2102 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2103 ft);
2104 ret = -1;
2105 goto end;
2106 }
2107
2108 if (ft->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2109 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2110 "addr=%p, ft-id=%s", ft,
2111 bt_ctf_field_type_id_string(ft->id));
2112 ret = -1;
2113 goto end;
2114 }
2115
2116 if (ft == field_type) {
2117 BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
2118 "addr=%p", ft);
2119 ret = -1;
2120 goto end;
2121 }
2122
2123 /* The user has explicitly provided a tag; validate against it. */
2124 if (var_ft->tag_ft) {
2125 int name_found = 0;
2126
2127 /* Make sure this name is present in the enum tag */
2128 for (i = 0; i < var_ft->tag_ft->entries->len; i++) {
2129 struct bt_ctf_enumeration_mapping *mapping =
2130 g_ptr_array_index(var_ft->tag_ft->entries, i);
2131
2132 if (mapping->string == field_name_quark) {
2133 name_found = 1;
2134 break;
2135 }
2136 }
2137
2138 if (!name_found) {
2139 /* Validation failed */
2140 BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
2141 "variant-ft-addr=%p, tag-ft-addr=%p, "
2142 "tag-field-name=\"%s\""
2143 "field-ft-addr=%p, field-name=\"%s\"",
2144 ft, var_ft->tag_ft, var_ft->tag_name->str,
2145 field_type, field_name);
2146 ret = -1;
2147 goto end;
2148 }
2149 }
2150
2151 if (add_structure_variant_member(var_ft->choices,
2152 var_ft->choice_name_to_index, field_type,
2153 field_name, true)) {
2154 BT_LOGW("Cannot add field to variant field type: "
2155 "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2156 ft, field_type, field_name);
2157 ret = -1;
2158 goto end;
2159 }
2160
ef267d12 2161 BT_LOGT("Added variant field type field: variant-ft-addr=%p, "
16ca5ff0
PP
2162 "field-ft-addr=%p, field-name=\"%s\"", ft,
2163 field_type, field_name);
2164
2165end:
2166 return ret;
2167}
2168
2169BT_HIDDEN
2170struct bt_ctf_field_type_common *
2171bt_ctf_field_type_common_variant_borrow_field_type_by_name(
2172 struct bt_ctf_field_type_common *ft,
2173 const char *field_name)
2174{
2175 size_t index;
2176 GQuark name_quark;
2177 struct bt_ctf_field_type_common_variant_choice *choice;
2178 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2179 struct bt_ctf_field_type_common *field_type = NULL;
2180
67d2ce02
MJ
2181 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2182 BT_CTF_ASSERT_PRE_NON_NULL(field_name, "Name");
2183 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0
PP
2184 "Field type");
2185 name_quark = g_quark_try_string(field_name);
2186 if (!name_quark) {
ef267d12 2187 BT_LOGT("No such variant field type field name: "
16ca5ff0
PP
2188 "ft-addr=%p, field-name=\"%s\"",
2189 ft, field_name);
2190 goto end;
2191 }
2192
2193 if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
2194 GUINT_TO_POINTER(name_quark), NULL, (gpointer *) &index)) {
ef267d12 2195 BT_LOGT("No such variant field type field name: "
16ca5ff0
PP
2196 "ft-addr=%p, field-name=\"%s\"",
2197 ft, field_name);
2198 goto end;
2199 }
2200
2201 choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, index);
2202 field_type = choice->type;
2203
2204end:
2205 return field_type;
2206}
2207
2208BT_HIDDEN
2209int64_t bt_ctf_field_type_common_variant_get_field_count(
2210 struct bt_ctf_field_type_common *ft)
2211{
2212 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2213
67d2ce02
MJ
2214 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Variant field type");
2215 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0
PP
2216 "Field type");
2217 return (int64_t) var_ft->choices->len;
2218}
2219
2220BT_HIDDEN
2221int bt_ctf_field_type_common_variant_borrow_field_by_index(
2222 struct bt_ctf_field_type_common *ft,
2223 const char **field_name,
2224 struct bt_ctf_field_type_common **field_type, uint64_t index)
2225{
2226 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2227 struct bt_ctf_field_type_common_variant_choice *choice;
2228
67d2ce02
MJ
2229 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2230 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0 2231 "Field type");
67d2ce02 2232 BT_CTF_ASSERT_PRE(index < var_ft->choices->len,
16ca5ff0
PP
2233 "Index is out of bounds: index=%" PRIu64 ", "
2234 "count=%u, ft-addr=%p",
2235 index, var_ft->choices->len, ft);
2236 choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, index);
2237
2238 if (field_type) {
2239 *field_type = choice->type;
2240 }
2241
2242 if (field_name) {
2243 *field_name = g_quark_to_string(choice->name);
98b15851 2244 BT_ASSERT_DBG(*field_name);
16ca5ff0
PP
2245 }
2246
2247 return 0;
2248}
2249
2250BT_HIDDEN
2251int64_t bt_ctf_field_type_common_variant_find_choice_index(
2252 struct bt_ctf_field_type_common *ft, uint64_t uval,
2253 bool is_signed)
2254{
2255 int64_t ret;
2256 uint64_t i;
2257 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2258
98b15851
PP
2259 BT_ASSERT_DBG(ft);
2260 BT_ASSERT_DBG(ft->id == BT_CTF_FIELD_TYPE_ID_VARIANT);
16ca5ff0
PP
2261
2262 if (bt_ctf_field_type_common_variant_update_choices(ft)) {
2263 ret = INT64_C(-1);
2264 goto end;
2265 }
2266
2267 for (i = 0; i < var_ft->choices->len; i++) {
2268 uint64_t range_i;
2269 struct bt_ctf_field_type_common_variant_choice *choice =
2270 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
2271 var_ft, i);
2272
2273 for (range_i = 0; range_i < choice->ranges->len; range_i++) {
2274 struct bt_ctf_field_type_common_variant_choice_range *range =
2275 &g_array_index(
2276 choice->ranges,
2277 struct bt_ctf_field_type_common_variant_choice_range,
2278 range_i);
2279
2280 if (is_signed) {
2281 int64_t tag_ival = (int64_t) uval;
2282
2283 if (tag_ival >= range->lower.i &&
2284 tag_ival <= range->upper.i) {
2285 goto found;
2286 }
2287 } else {
2288 if (uval >= range->lower.u &&
2289 uval <= range->upper.u) {
2290 goto found;
2291 }
2292 }
2293 }
2294 }
2295
2296 /* Range not found */
2297 ret = INT64_C(-1);
2298 goto end;
2299
2300found:
2301 ret = (int64_t) i;
2302
2303end:
2304 return ret;
2305}
2306
2307BT_HIDDEN
2308struct bt_ctf_field_type_common *
2309bt_ctf_field_type_common_array_borrow_element_field_type(
2310 struct bt_ctf_field_type_common *ft)
2311{
2312 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
2313
67d2ce02
MJ
2314 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2315 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ARRAY,
16ca5ff0 2316 "Field type");
98b15851 2317 BT_ASSERT_DBG(array_ft && array_ft->element_ft);
16ca5ff0
PP
2318 return array_ft->element_ft;
2319}
2320
2321BT_HIDDEN
2322int bt_ctf_field_type_common_array_set_element_field_type(
2323 struct bt_ctf_field_type_common *ft,
2324 struct bt_ctf_field_type_common *element_ft)
2325{
2326 int ret = 0;
2327 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
2328
2329 if (!ft) {
2330 BT_LOGW_STR("Invalid parameter: array field type is NULL.");
2331 ret = -1;
2332 goto end;
2333 }
2334
2335 if (!element_ft) {
2336 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2337 ret = -1;
2338 goto end;
2339 }
2340
2341 if (ft->id != BT_CTF_FIELD_TYPE_ID_ARRAY) {
2342 BT_LOGW("Invalid parameter: field type is not an array field type: "
2343 "addr=%p, ft-id=%s", ft,
2344 bt_ctf_field_type_id_string(ft->id));
2345 ret = -1;
2346 goto end;
2347 }
2348
2349 if (array_ft->element_ft) {
e1e02a22 2350 BT_CTF_OBJECT_PUT_REF_AND_RESET(array_ft->element_ft);
16ca5ff0
PP
2351 }
2352
e1e02a22 2353 array_ft->element_ft = bt_ctf_object_get_ref(element_ft);
ef267d12 2354 BT_LOGT("Set array field type's element field type: array-ft-addr=%p, "
16ca5ff0
PP
2355 "element-ft-addr=%p", ft, element_ft);
2356
2357end:
2358 return ret;
2359}
2360
2361BT_HIDDEN
2362int64_t bt_ctf_field_type_common_array_get_length(struct bt_ctf_field_type_common *ft)
2363{
2364 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
2365
67d2ce02
MJ
2366 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2367 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ARRAY,
16ca5ff0
PP
2368 "Field type");
2369 return (int64_t) array_ft->length;
2370}
2371
2372BT_HIDDEN
2373struct bt_ctf_field_type_common *bt_ctf_field_type_common_sequence_borrow_element_field_type(
2374 struct bt_ctf_field_type_common *ft)
2375{
2376 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
2377
67d2ce02
MJ
2378 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2379 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
16ca5ff0
PP
2380 "Field type");
2381 return seq_ft->element_ft;
2382}
2383
2384BT_HIDDEN
2385int bt_ctf_field_type_common_sequence_set_element_field_type(
2386 struct bt_ctf_field_type_common *ft,
2387 struct bt_ctf_field_type_common *element_ft)
2388{
2389 int ret = 0;
2390 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
2391
2392 if (!ft) {
2393 BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
2394 ret = -1;
2395 goto end;
2396 }
2397
2398 if (!element_ft) {
2399 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2400 ret = -1;
2401 goto end;
2402 }
2403
2404 if (ft->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
2405 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2406 "addr=%p, ft-id=%s", ft,
2407 bt_ctf_field_type_id_string(ft->id));
2408 ret = -1;
2409 goto end;
2410 }
2411
2412 if (seq_ft->element_ft) {
e1e02a22 2413 BT_CTF_OBJECT_PUT_REF_AND_RESET(seq_ft->element_ft);
16ca5ff0
PP
2414 }
2415
2416 seq_ft->element_ft = element_ft;
e1e02a22 2417 bt_ctf_object_get_ref(seq_ft->element_ft);
ef267d12 2418 BT_LOGT("Set sequence field type's element field type: sequence-ft-addr=%p, "
16ca5ff0
PP
2419 "element-ft-addr=%p", ft, element_ft);
2420
2421end:
2422 return ret;
2423}
2424
2425BT_HIDDEN
2426const char *bt_ctf_field_type_common_sequence_get_length_field_name(
2427 struct bt_ctf_field_type_common *ft)
2428{
2429 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
2430
67d2ce02
MJ
2431 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2432 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
16ca5ff0
PP
2433 "Field type");
2434 return seq_ft->length_field_name ?
2435 seq_ft->length_field_name->str : NULL;
2436}
2437
2438BT_HIDDEN
2439enum bt_ctf_string_encoding bt_ctf_field_type_common_string_get_encoding(
2440 struct bt_ctf_field_type_common *ft)
2441{
2442 struct bt_ctf_field_type_common_string *string_ft = BT_CTF_FROM_COMMON(ft);
2443
67d2ce02
MJ
2444 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2445 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRING,
16ca5ff0
PP
2446 "Field type");
2447 return string_ft->encoding;
2448}
2449
2450BT_HIDDEN
2451int bt_ctf_field_type_common_string_set_encoding(struct bt_ctf_field_type_common *ft,
2452 enum bt_ctf_string_encoding encoding)
2453{
2454 int ret = 0;
2455 struct bt_ctf_field_type_common_string *string_ft = BT_CTF_FROM_COMMON(ft);
2456
2457 if (!ft) {
2458 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2459 ret = -1;
2460 goto end;
2461 }
2462
2463 if (ft->id != BT_CTF_FIELD_TYPE_ID_STRING) {
2464 BT_LOGW("Invalid parameter: field type is not a string field type: "
2465 "addr=%p, ft-id=%s", ft,
2466 bt_ctf_field_type_id_string(ft->id));
2467 ret = -1;
2468 goto end;
2469 }
2470
2471 if (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
2472 encoding != BT_CTF_STRING_ENCODING_ASCII) {
2473 BT_LOGW("Invalid parameter: unknown string encoding: "
2474 "addr=%p, encoding=%d", ft, encoding);
2475 ret = -1;
2476 goto end;
2477 }
2478
2479 string_ft->encoding = encoding;
ef267d12 2480 BT_LOGT("Set string field type's encoding: addr=%p, encoding=%s",
16ca5ff0
PP
2481 ft, bt_ctf_string_encoding_string(encoding));
2482
2483end:
2484 return ret;
2485}
2486
2487BT_HIDDEN
2488int bt_ctf_field_type_common_get_alignment(struct bt_ctf_field_type_common *ft)
2489{
2490 int ret;
2491 enum bt_ctf_field_type_id type_id;
2492
67d2ce02 2493 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
16ca5ff0
PP
2494
2495 if (ft->frozen) {
2496 ret = (int) ft->alignment;
2497 goto end;
2498 }
2499
2500 type_id = bt_ctf_field_type_common_get_type_id(ft);
2501 switch (type_id) {
2502 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
2503 {
2504 struct bt_ctf_field_type_common *element_ft =
2505 bt_ctf_field_type_common_sequence_borrow_element_field_type(ft);
2506
98b15851 2507 BT_ASSERT_DBG(element_ft);
16ca5ff0
PP
2508 ret = bt_ctf_field_type_common_get_alignment(element_ft);
2509 break;
2510 }
2511 case BT_CTF_FIELD_TYPE_ID_ARRAY:
2512 {
2513 struct bt_ctf_field_type_common *element_ft =
2514 bt_ctf_field_type_common_array_borrow_element_field_type(ft);
2515
98b15851 2516 BT_ASSERT_DBG(element_ft);
16ca5ff0
PP
2517 ret = bt_ctf_field_type_common_get_alignment(element_ft);
2518 break;
2519 }
2520 case BT_CTF_FIELD_TYPE_ID_STRUCT:
2521 {
2522 int64_t i, element_count;
2523
2524 element_count = bt_ctf_field_type_common_structure_get_field_count(
2525 ft);
98b15851 2526 BT_ASSERT_DBG(element_count >= 0);
16ca5ff0
PP
2527
2528 for (i = 0; i < element_count; i++) {
2529 struct bt_ctf_field_type_common *field = NULL;
2530 int field_alignment;
2531
2532 ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
2533 ft, NULL, &field, i);
98b15851
PP
2534 BT_ASSERT_DBG(ret == 0);
2535 BT_ASSERT_DBG(field);
16ca5ff0
PP
2536 field_alignment = bt_ctf_field_type_common_get_alignment(
2537 field);
2538 if (field_alignment < 0) {
2539 ret = field_alignment;
2540 goto end;
2541 }
2542
2543 ft->alignment = MAX(field_alignment, ft->alignment);
2544 }
2545 ret = (int) ft->alignment;
2546 break;
2547 }
2548 case BT_CTF_FIELD_TYPE_ID_UNKNOWN:
2549 BT_LOGW("Invalid parameter: unknown field type ID: "
2550 "addr=%p, ft-id=%d", ft, type_id);
2551 ret = -1;
2552 break;
2553 default:
2554 ret = (int) ft->alignment;
2555 break;
2556 }
2557
2558end:
2559 return ret;
2560}
2561
2562static inline
2563int is_power_of_two(unsigned int value)
2564{
2565 return ((value & (value - 1)) == 0) && value > 0;
2566}
2567
2568BT_HIDDEN
2569int bt_ctf_field_type_common_set_alignment(struct bt_ctf_field_type_common *ft,
2570 unsigned int alignment)
2571{
2572 int ret = 0;
2573 enum bt_ctf_field_type_id type_id;
2574
2575 /* Alignment must be a power of two */
2576 if (!ft) {
2577 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2578 ret = -1;
2579 goto end;
2580 }
2581
2582 if (ft->frozen) {
2583 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2584 ft);
2585 ret = -1;
2586 goto end;
2587 }
2588
2589 if (!is_power_of_two(alignment)) {
2590 BT_LOGW("Invalid parameter: alignment is not a power of two: "
2591 "addr=%p, align=%u", ft, alignment);
2592 ret = -1;
2593 goto end;
2594 }
2595
2596 type_id = bt_ctf_field_type_common_get_type_id(ft);
2597 if (type_id == BT_CTF_FIELD_TYPE_ID_UNKNOWN) {
2598 BT_LOGW("Invalid parameter: unknown field type ID: "
2599 "addr=%p, ft-id=%d", ft, type_id);
2600 ret = -1;
2601 goto end;
2602 }
2603
2604 if (ft->id == BT_CTF_FIELD_TYPE_ID_STRING && alignment != CHAR_BIT) {
2605 BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
2606 "addr=%p, align=%u", CHAR_BIT, ft, alignment);
2607 ret = -1;
2608 goto end;
2609 }
2610
2611 if (type_id == BT_CTF_FIELD_TYPE_ID_VARIANT ||
2612 type_id == BT_CTF_FIELD_TYPE_ID_SEQUENCE ||
2613 type_id == BT_CTF_FIELD_TYPE_ID_ARRAY) {
2614 /* Setting an alignment on these types makes no sense */
2615 BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
2616 "addr=%p, ft-id=%s", ft,
2617 bt_ctf_field_type_id_string(ft->id));
2618 ret = -1;
2619 goto end;
2620 }
2621
2622 ft->alignment = alignment;
2623 ret = 0;
ef267d12 2624 BT_LOGT("Set field type's alignment: addr=%p, align=%u",
16ca5ff0
PP
2625 ft, alignment);
2626
2627end:
2628 return ret;
2629}
2630
2631BT_HIDDEN
2632enum bt_ctf_byte_order bt_ctf_field_type_common_get_byte_order(
2633 struct bt_ctf_field_type_common *ft)
2634{
2635 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
2636
67d2ce02 2637 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
16ca5ff0
PP
2638
2639 switch (ft->id) {
2640 case BT_CTF_FIELD_TYPE_ID_INTEGER:
2641 {
2642 struct bt_ctf_field_type_common_integer *integer =
2643 BT_CTF_FROM_COMMON(ft);
2644
2645 ret = integer->user_byte_order;
2646 break;
2647 }
2648 case BT_CTF_FIELD_TYPE_ID_ENUM:
2649 {
2650 struct bt_ctf_field_type_common_enumeration *enum_ft =
2651 BT_CTF_FROM_COMMON(ft);
2652
2653 ret = bt_ctf_field_type_common_get_byte_order(
2654 BT_CTF_TO_COMMON(enum_ft->container_ft));
2655 break;
2656 }
2657 case BT_CTF_FIELD_TYPE_ID_FLOAT:
2658 {
2659 struct bt_ctf_field_type_common_floating_point *floating_point =
2660 BT_CTF_FROM_COMMON(ft);
2661 ret = floating_point->user_byte_order;
2662 break;
2663 }
2664 default:
2665 BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
2666 "addr=%p, ft-id=%s", ft,
2667 bt_ctf_field_type_id_string(ft->id));
2668 goto end;
2669 }
2670
98b15851 2671 BT_ASSERT_DBG(ret == BT_CTF_BYTE_ORDER_NATIVE ||
16ca5ff0
PP
2672 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2673 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2674 ret == BT_CTF_BYTE_ORDER_NETWORK);
2675
2676end:
2677 return ret;
2678}
2679
2680BT_HIDDEN
2681int bt_ctf_field_type_common_set_byte_order(struct bt_ctf_field_type_common *ft,
2682 enum bt_ctf_byte_order byte_order)
2683{
2684 int ret = 0;
2685
2686 if (!ft) {
2687 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2688 ret = -1;
2689 goto end;
2690 }
2691
2692 if (ft->frozen) {
2693 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2694 ft);
2695 ret = -1;
2696 goto end;
2697 }
2698
2699 if (byte_order != BT_CTF_BYTE_ORDER_NATIVE &&
2700 byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
2701 byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
2702 byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
2703 BT_LOGW("Invalid parameter: invalid byte order: "
2704 "addr=%p, bo=%s", ft,
2705 bt_ctf_byte_order_string(byte_order));
2706 ret = -1;
2707 goto end;
2708 }
2709
2710 if (ft->methods->set_byte_order) {
2711 ft->methods->set_byte_order(ft, byte_order);
2712 }
2713
ef267d12 2714 BT_LOGT("Set field type's byte order: addr=%p, bo=%s",
16ca5ff0
PP
2715 ft, bt_ctf_byte_order_string(byte_order));
2716
2717end:
2718 return ret;
2719}
2720
2721BT_HIDDEN
2722enum bt_ctf_field_type_id bt_ctf_field_type_common_get_type_id(
2723 struct bt_ctf_field_type_common *ft)
2724{
67d2ce02 2725 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
16ca5ff0
PP
2726 return ft->id;
2727}
2728
2729BT_HIDDEN
2730void bt_ctf_field_type_common_freeze(struct bt_ctf_field_type_common *ft)
2731{
2732 if (!ft || ft->frozen) {
2733 return;
2734 }
2735
98b15851 2736 BT_ASSERT_DBG(ft->methods->freeze);
16ca5ff0
PP
2737 ft->methods->freeze(ft);
2738}
2739
2740BT_HIDDEN
2741struct bt_ctf_field_type_common *
2742bt_ctf_field_type_common_variant_borrow_field_type_signed(
2743 struct bt_ctf_field_type_common_variant *var_ft,
2744 int64_t tag_value)
2745{
2746 struct bt_ctf_field_type_common *field_type = NULL;
2747 GQuark field_name_quark;
2748 gpointer index;
2749 struct bt_ctf_field_type_common_variant_choice *choice;
2750 struct range_overlap_query query = {
2751 .range_start._signed = tag_value,
2752 .range_end._signed = tag_value,
2753 .mapping_name = 0,
2754 .overlaps = 0,
2755 };
2756
2757 g_ptr_array_foreach(var_ft->tag_ft->entries, check_ranges_overlap,
2758 &query);
2759 if (!query.overlaps) {
2760 goto end;
2761 }
2762
2763 field_name_quark = query.mapping_name;
2764 if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
2765 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2766 goto end;
2767 }
2768
2769 choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft,
2770 (size_t) index);
2771 field_type = choice->type;
2772
2773end:
2774 return field_type;
2775}
2776
2777BT_HIDDEN
2778struct bt_ctf_field_type_common *
2779bt_ctf_field_type_common_variant_borrow_field_type_unsigned(
2780 struct bt_ctf_field_type_common_variant *var_ft,
2781 uint64_t tag_value)
2782{
2783 struct bt_ctf_field_type_common *field_type = NULL;
2784 GQuark field_name_quark;
2785 gpointer index;
2786 struct bt_ctf_field_type_common_variant_choice *choice;
2787 struct range_overlap_query query = {
2788 .range_start._unsigned = tag_value,
2789 .range_end._unsigned = tag_value,
2790 .mapping_name = 0,
2791 .overlaps = 0,
2792 };
2793
2794 g_ptr_array_foreach(var_ft->tag_ft->entries,
2795 check_ranges_overlap_unsigned, &query);
2796 if (!query.overlaps) {
2797 goto end;
2798 }
2799
2800 field_name_quark = query.mapping_name;
2801 if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
2802 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2803 goto end;
2804 }
2805
2806 choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft,
2807 (size_t) index);
2808 field_type = choice->type;
2809
2810end:
2811 return field_type;
2812}
2813
2814BT_HIDDEN
2815struct bt_ctf_field_type_common *bt_ctf_field_type_common_copy(
2816 struct bt_ctf_field_type_common *ft)
2817{
2818 struct bt_ctf_field_type_common *ft_copy = NULL;
2819
67d2ce02 2820 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
98b15851 2821 BT_ASSERT_DBG(ft->methods->copy);
16ca5ff0
PP
2822 ft_copy = ft->methods->copy(ft);
2823 if (!ft_copy) {
2824 BT_LOGE_STR("Cannot copy field type.");
2825 goto end;
2826 }
2827
2828 ft_copy->alignment = ft->alignment;
2829
2830end:
2831 return ft_copy;
2832}
2833
2834BT_HIDDEN
2835int bt_ctf_field_type_common_structure_get_field_name_index(
2836 struct bt_ctf_field_type_common *ft, const char *name)
2837{
2838 int ret;
2839 size_t index;
2840 GQuark name_quark;
2841 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
2842
67d2ce02
MJ
2843 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2844 BT_CTF_ASSERT_PRE_NON_NULL(name, "Name");
2845 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
16ca5ff0
PP
2846 "Field type");
2847
2848 name_quark = g_quark_try_string(name);
2849 if (!name_quark) {
ef267d12 2850 BT_LOGT("No such structure field type field name: "
16ca5ff0
PP
2851 "ft-addr=%p, field-name=\"%s\"",
2852 ft, name);
2853 ret = -1;
2854 goto end;
2855 }
2856
2857 if (!g_hash_table_lookup_extended(struct_ft->field_name_to_index,
2858 GUINT_TO_POINTER(name_quark),
2859 NULL, (gpointer *) &index)) {
ef267d12 2860 BT_LOGT("No such structure field type field name: "
16ca5ff0
PP
2861 "ft-addr=%p, field-name=\"%s\"",
2862 ft, name);
2863 ret = -1;
2864 goto end;
2865 }
2866
2867 ret = (int) index;
2868
2869end:
2870 return ret;
2871}
2872
2873BT_HIDDEN
2874int bt_ctf_field_type_common_variant_get_field_name_index(
2875 struct bt_ctf_field_type_common *ft, const char *name)
2876{
2877 int ret;
2878 size_t index;
2879 GQuark name_quark;
2880 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2881
67d2ce02
MJ
2882 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
2883 BT_CTF_ASSERT_PRE_NON_NULL(name, "Name");
2884 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0
PP
2885 "Field type");
2886 name_quark = g_quark_try_string(name);
2887 if (!name_quark) {
ef267d12 2888 BT_LOGT("No such variant field type field name: "
16ca5ff0
PP
2889 "ft-addr=%p, field-name=\"%s\"",
2890 ft, name);
2891 ret = -1;
2892 goto end;
2893 }
2894
2895 if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
2896 GUINT_TO_POINTER(name_quark),
2897 NULL, (gpointer *) &index)) {
ef267d12 2898 BT_LOGT("No such variant field type field name: "
16ca5ff0
PP
2899 "ft-addr=%p, field-name=\"%s\"",
2900 ft, name);
2901 ret = -1;
2902 goto end;
2903 }
2904
2905 ret = (int) index;
2906
2907end:
2908 return ret;
2909}
2910
2911BT_HIDDEN
2912int bt_ctf_field_type_common_sequence_set_length_field_path(
2913 struct bt_ctf_field_type_common *ft, struct bt_ctf_field_path *path)
2914{
2915 int ret = 0;
2916 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
2917
2918 if (!ft) {
2919 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2920 ret = -1;
2921 goto end;
2922 }
2923
2924 if (ft->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
2925 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2926 "addr=%p, ft-id=%s", ft,
2927 bt_ctf_field_type_id_string(ft->id));
2928 ret = -1;
2929 goto end;
2930 }
2931
e1e02a22
PP
2932 bt_ctf_object_get_ref(path);
2933 BT_CTF_OBJECT_MOVE_REF(seq_ft->length_field_path, path);
ef267d12 2934 BT_LOGT("Set sequence field type's length field path: ft-addr=%p, "
16ca5ff0
PP
2935 "field-path-addr=%p", ft, path);
2936
2937end:
2938 return ret;
2939}
2940
2941BT_HIDDEN
2942int bt_ctf_field_type_common_variant_set_tag_field_path(
2943 struct bt_ctf_field_type_common *ft,
2944 struct bt_ctf_field_path *path)
2945{
2946 int ret = 0;
2947 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2948
2949 if (!ft) {
2950 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2951 ret = -1;
2952 goto end;
2953 }
2954
2955 if (ft->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2956 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2957 "addr=%p, ft-id=%s", ft,
2958 bt_ctf_field_type_id_string(ft->id));
2959 ret = -1;
2960 goto end;
2961 }
2962
e1e02a22
PP
2963 bt_ctf_object_get_ref(path);
2964 BT_CTF_OBJECT_MOVE_REF(var_ft->tag_field_path, path);
ef267d12 2965 BT_LOGT("Set variant field type's tag field path: ft-addr=%p, "
16ca5ff0
PP
2966 "field-path-addr=%p", ft, path);
2967
2968end:
2969 return ret;
2970}
2971
2972BT_HIDDEN
2973int bt_ctf_field_type_common_variant_set_tag_field_type(
2974 struct bt_ctf_field_type_common *ft,
2975 struct bt_ctf_field_type_common *tag_ft)
2976{
2977 int ret = 0;
2978 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
2979
2980 if (!ft) {
2981 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
2982 ret = -1;
2983 goto end;
2984 }
2985
2986 if (!tag_ft) {
2987 BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
2988 ret = -1;
2989 goto end;
2990 }
2991
2992 if (tag_ft->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
2993 BT_LOGW("Invalid parameter: tag field type is not an enumeration field type: "
2994 "addr=%p, ft-id=%s", tag_ft,
2995 bt_ctf_field_type_id_string(tag_ft->id));
2996 ret = -1;
2997 goto end;
2998 }
2999
e1e02a22
PP
3000 bt_ctf_object_put_ref(var_ft->tag_ft);
3001 var_ft->tag_ft = bt_ctf_object_get_ref(tag_ft);
ef267d12 3002 BT_LOGT("Set variant field type's tag field type: variant-ft-addr=%p, "
16ca5ff0
PP
3003 "tag-ft-addr=%p", ft, tag_ft);
3004
3005end:
3006 return ret;
3007}
3008
3009BT_HIDDEN
3010void bt_ctf_field_type_common_generic_freeze(struct bt_ctf_field_type_common *ft)
3011{
3012 ft->frozen = 1;
3013}
3014
3015BT_HIDDEN
3016void bt_ctf_field_type_common_enumeration_freeze_recursive(
3017 struct bt_ctf_field_type_common *ft)
3018{
3019 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
3020
3021 BT_LOGD("Freezing enumeration field type object: addr=%p", ft);
3022 bt_ctf_field_type_common_enumeration_set_range_overlap(enum_ft);
3023 bt_ctf_field_type_common_generic_freeze(ft);
3024 BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
3025 enum_ft->container_ft);
3026 bt_ctf_field_type_common_freeze(BT_CTF_TO_COMMON(enum_ft->container_ft));
3027}
3028
3029BT_HIDDEN
3030void bt_ctf_field_type_common_structure_freeze_recursive(
3031 struct bt_ctf_field_type_common *ft)
3032{
3033 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
3034 uint64_t i;
3035
3036 /* Cache the alignment */
3037 BT_LOGD("Freezing structure field type object: addr=%p", ft);
3038 ft->alignment = bt_ctf_field_type_common_get_alignment(ft);
3039 bt_ctf_field_type_common_generic_freeze(ft);
3040
3041 for (i = 0; i < struct_ft->fields->len; i++) {
3042 struct bt_ctf_field_type_common_structure_field *field =
3043 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, i);
3044
3045 BT_LOGD("Freezing structure field type field: "
3046 "ft-addr=%p, name=\"%s\"",
3047 field->type, g_quark_to_string(field->name));
3048 bt_ctf_field_type_common_freeze(field->type);
3049 }
3050}
3051
3052BT_HIDDEN
3053int bt_ctf_field_type_common_variant_update_choices(struct bt_ctf_field_type_common *ft)
3054{
3055 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
3056 uint64_t i;
3057 int ret = 0;
3058 bool is_signed;
3059
3060 if (ft->frozen && var_ft->choices_up_to_date) {
3061 goto end;
3062 }
3063
98b15851 3064 BT_ASSERT_DBG(var_ft->tag_ft);
16ca5ff0
PP
3065 is_signed = !!var_ft->tag_ft->container_ft->is_signed;
3066
3067 for (i = 0; i < var_ft->choices->len; i++) {
3068 struct bt_ctf_field_type_common_variant_choice *choice =
3069 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, i);
3070 const char *choice_name = g_quark_to_string(choice->name);
3071 struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
3072 bt_ctf_field_type_common_enumeration_find_mappings_by_name(
3073 BT_CTF_TO_COMMON(var_ft->tag_ft), choice_name);
3074
3075 if (!iter) {
3076 ret = -1;
3077 goto end;
3078 }
3079
98b15851 3080 BT_ASSERT_DBG(choice->ranges);
16ca5ff0
PP
3081 g_array_set_size(choice->ranges, 0);
3082
3083 while (bt_ctf_field_type_enumeration_mapping_iterator_next(iter) == 0) {
3084 struct bt_ctf_field_type_common_variant_choice_range range;
3085
3086 if (is_signed) {
3087 ret = bt_ctf_field_type_enumeration_mapping_iterator_signed_get(
3088 iter, NULL,
3089 &range.lower.i, &range.upper.i);
3090 } else {
3091 ret = bt_ctf_field_type_enumeration_mapping_iterator_unsigned_get(
3092 iter, NULL,
3093 &range.lower.u, &range.upper.u);
3094 }
3095
98b15851 3096 BT_ASSERT_DBG(ret == 0);
16ca5ff0
PP
3097 g_array_append_val(choice->ranges, range);
3098 }
3099
e1e02a22 3100 bt_ctf_object_put_ref(iter);
16ca5ff0
PP
3101 }
3102
3103 var_ft->choices_up_to_date = true;
3104
3105end:
3106 return ret;
3107}
3108
3109BT_HIDDEN
3110void bt_ctf_field_type_common_variant_freeze_recursive(
3111 struct bt_ctf_field_type_common *ft)
3112{
3113 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
3114 uint64_t i;
3115
3116 BT_LOGD("Freezing variant field type object: addr=%p", ft);
3117 bt_ctf_field_type_common_generic_freeze(ft);
3118
3119 for (i = 0; i < var_ft->choices->len; i++) {
3120 struct bt_ctf_field_type_common_variant_choice *choice =
3121 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, i);
3122
3123 BT_LOGD("Freezing variant field type member: "
3124 "ft-addr=%p, name=\"%s\"",
3125 choice->type, g_quark_to_string(choice->name));
3126 bt_ctf_field_type_common_freeze(choice->type);
3127 }
3128}
3129
3130BT_HIDDEN
3131void bt_ctf_field_type_common_array_freeze_recursive(
3132 struct bt_ctf_field_type_common *ft)
3133{
3134 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
3135
3136 /* Cache the alignment */
3137 BT_LOGD("Freezing array field type object: addr=%p", ft);
3138 ft->alignment = bt_ctf_field_type_common_get_alignment(ft);
3139 bt_ctf_field_type_common_generic_freeze(ft);
3140 BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
3141 array_ft->element_ft);
3142 bt_ctf_field_type_common_freeze(array_ft->element_ft);
3143}
3144
3145BT_HIDDEN
3146void bt_ctf_field_type_common_sequence_freeze_recursive(
3147 struct bt_ctf_field_type_common *ft)
3148{
3149 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
3150
3151 /* Cache the alignment */
3152 BT_LOGD("Freezing sequence field type object: addr=%p", ft);
3153 ft->alignment = bt_ctf_field_type_common_get_alignment(ft);
3154 bt_ctf_field_type_common_generic_freeze(ft);
3155 BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
3156 seq_ft->element_ft);
3157 bt_ctf_field_type_common_freeze(seq_ft->element_ft);
3158}
3159
3160BT_HIDDEN
3161void bt_ctf_field_type_common_integer_set_byte_order(
3162 struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order)
3163{
3164 struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
3165
3166 int_ft->user_byte_order = byte_order;
3167}
3168
3169BT_HIDDEN
3170void bt_ctf_field_type_common_enumeration_set_byte_order_recursive(
3171 struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order)
3172{
3173 struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
3174
3175 bt_ctf_field_type_common_set_byte_order(BT_CTF_TO_COMMON(enum_ft->container_ft),
3176 byte_order);
3177}
3178
3179BT_HIDDEN
3180void bt_ctf_field_type_common_floating_point_set_byte_order(
3181 struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order)
3182{
3183 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
3184
3185 flt_ft->user_byte_order = byte_order;
3186}
3187
3188BT_HIDDEN
3189void bt_ctf_field_type_common_structure_set_byte_order_recursive(
3190 struct bt_ctf_field_type_common *ft,
3191 enum bt_ctf_byte_order byte_order)
3192{
3193 int i;
3194 struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
3195
3196 for (i = 0; i < struct_ft->fields->len; i++) {
3197 struct bt_ctf_field_type_common_structure_field *field =
3198 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
3199 struct_ft, i);
3200 struct bt_ctf_field_type_common *field_type = field->type;
3201
3202 bt_ctf_field_type_common_set_byte_order(field_type, byte_order);
3203 }
3204}
3205
3206BT_HIDDEN
3207void bt_ctf_field_type_common_variant_set_byte_order_recursive(
3208 struct bt_ctf_field_type_common *ft,
3209 enum bt_ctf_byte_order byte_order)
3210{
3211 int i;
3212 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
3213
3214 for (i = 0; i < var_ft->choices->len; i++) {
3215 struct bt_ctf_field_type_common_variant_choice *choice =
3216 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
3217 var_ft, i);
3218 struct bt_ctf_field_type_common *field_type = choice->type;
3219
3220 bt_ctf_field_type_common_set_byte_order(field_type, byte_order);
3221 }
3222}
3223
3224BT_HIDDEN
3225void bt_ctf_field_type_common_array_set_byte_order_recursive(
3226 struct bt_ctf_field_type_common *ft,
3227 enum bt_ctf_byte_order byte_order)
3228{
3229 struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
3230
3231 bt_ctf_field_type_common_set_byte_order(array_ft->element_ft, byte_order);
3232}
3233
3234BT_HIDDEN
3235void bt_ctf_field_type_common_sequence_set_byte_order_recursive(
3236 struct bt_ctf_field_type_common *ft,
3237 enum bt_ctf_byte_order byte_order)
3238{
3239 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
3240
3241 bt_ctf_field_type_common_set_byte_order(seq_ft->element_ft, byte_order);
3242}
3243
3244
3245BT_HIDDEN
3246int bt_ctf_field_type_common_integer_compare(struct bt_ctf_field_type_common *ft_a,
3247 struct bt_ctf_field_type_common *ft_b)
3248{
3249 int ret = 1;
3250 struct bt_ctf_field_type_common_integer *int_ft_a = BT_CTF_FROM_COMMON(ft_a);
3251 struct bt_ctf_field_type_common_integer *int_ft_b = BT_CTF_FROM_COMMON(ft_b);
3252
3253 /* Length */
3254 if (int_ft_a->size != int_ft_b->size) {
ef267d12 3255 BT_LOGT("Integer field types differ: different sizes: "
16ca5ff0
PP
3256 "ft-a-size=%u, ft-b-size=%u",
3257 int_ft_a->size, int_ft_b->size);
3258 goto end;
3259 }
3260
3261 /* Byte order */
3262 if (int_ft_a->user_byte_order != int_ft_b->user_byte_order) {
ef267d12 3263 BT_LOGT("Integer field types differ: different byte orders: "
16ca5ff0
PP
3264 "ft-a-bo=%s, ft-b-bo=%s",
3265 bt_ctf_byte_order_string(int_ft_a->user_byte_order),
3266 bt_ctf_byte_order_string(int_ft_b->user_byte_order));
3267 goto end;
3268 }
3269
3270 /* Signedness */
3271 if (int_ft_a->is_signed != int_ft_b->is_signed) {
ef267d12 3272 BT_LOGT("Integer field types differ: different signedness: "
16ca5ff0
PP
3273 "ft-a-is-signed=%d, ft-b-is-signed=%d",
3274 int_ft_a->is_signed,
3275 int_ft_b->is_signed);
3276 goto end;
3277 }
3278
3279 /* Base */
3280 if (int_ft_a->base != int_ft_b->base) {
ef267d12 3281 BT_LOGT("Integer field types differ: different bases: "
16ca5ff0
PP
3282 "ft-a-base=%s, ft-b-base=%s",
3283 bt_ctf_integer_base_string(int_ft_a->base),
3284 bt_ctf_integer_base_string(int_ft_b->base));
3285 goto end;
3286 }
3287
3288 /* Encoding */
3289 if (int_ft_a->encoding != int_ft_b->encoding) {
ef267d12 3290 BT_LOGT("Integer field types differ: different encodings: "
16ca5ff0
PP
3291 "ft-a-encoding=%s, ft-b-encoding=%s",
3292 bt_ctf_string_encoding_string(int_ft_a->encoding),
3293 bt_ctf_string_encoding_string(int_ft_b->encoding));
3294 goto end;
3295 }
3296
3297 /* Mapped clock class */
3298 if (int_ft_a->mapped_clock_class) {
3299 if (!int_ft_b->mapped_clock_class) {
ef267d12 3300 BT_LOGT_STR("Integer field types differ: field type A "
16ca5ff0
PP
3301 "has a mapped clock class, but field type B "
3302 "does not.");
3303 goto end;
3304 }
3305
3306 if (bt_ctf_clock_class_compare(int_ft_a->mapped_clock_class,
3307 int_ft_b->mapped_clock_class) != 0) {
ef267d12 3308 BT_LOGT_STR("Integer field types differ: different "
16ca5ff0
PP
3309 "mapped clock classes.");
3310 }
3311 } else {
3312 if (int_ft_b->mapped_clock_class) {
ef267d12 3313 BT_LOGT_STR("Integer field types differ: field type A "
16ca5ff0
PP
3314 "has no description, but field type B has one.");
3315 goto end;
3316 }
3317 }
3318
3319 /* Equal */
3320 ret = 0;
3321
3322end:
3323 return ret;
3324}
3325
3326BT_HIDDEN
3327int bt_ctf_field_type_common_floating_point_compare(
3328 struct bt_ctf_field_type_common *ft_a,
3329 struct bt_ctf_field_type_common *ft_b)
3330{
3331 int ret = 1;
3332 struct bt_ctf_field_type_common_floating_point *flt_ft_a =
3333 BT_CTF_FROM_COMMON(ft_a);
3334 struct bt_ctf_field_type_common_floating_point *flt_ft_b =
3335 BT_CTF_FROM_COMMON(ft_b);
3336
3337 /* Byte order */
3338 if (flt_ft_a->user_byte_order != flt_ft_b->user_byte_order) {
ef267d12 3339 BT_LOGT("Floating point number field types differ: different byte orders: "
16ca5ff0
PP
3340 "ft-a-bo=%s, ft-b-bo=%s",
3341 bt_ctf_byte_order_string(flt_ft_a->user_byte_order),
3342 bt_ctf_byte_order_string(flt_ft_b->user_byte_order));
3343 goto end;
3344 }
3345
3346 /* Exponent length */
3347 if (flt_ft_a->exp_dig != flt_ft_b->exp_dig) {
ef267d12 3348 BT_LOGT("Floating point number field types differ: different exponent sizes: "
16ca5ff0
PP
3349 "ft-a-exp-size=%u, ft-b-exp-size=%u",
3350 flt_ft_a->exp_dig, flt_ft_b->exp_dig);
3351 goto end;
3352 }
3353
3354 /* Mantissa length */
3355 if (flt_ft_a->mant_dig != flt_ft_b->mant_dig) {
ef267d12 3356 BT_LOGT("Floating point number field types differ: different mantissa sizes: "
16ca5ff0
PP
3357 "ft-a-mant-size=%u, ft-b-mant-size=%u",
3358 flt_ft_a->mant_dig, flt_ft_b->mant_dig);
3359 goto end;
3360 }
3361
3362 /* Equal */
3363 ret = 0;
3364
3365end:
3366 return ret;
3367}
3368
3369static
3370int compare_enumeration_mappings(struct bt_ctf_enumeration_mapping *mapping_a,
3371 struct bt_ctf_enumeration_mapping *mapping_b)
3372{
3373 int ret = 1;
3374
3375 /* Label */
3376 if (mapping_a->string != mapping_b->string) {
ef267d12 3377 BT_LOGT("Enumeration field type mappings differ: different names: "
16ca5ff0
PP
3378 "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
3379 g_quark_to_string(mapping_a->string),
3380 g_quark_to_string(mapping_b->string));
3381 goto end;
3382 }
3383
3384 /* Range start */
3385 if (mapping_a->range_start._unsigned !=
3386 mapping_b->range_start._unsigned) {
ef267d12 3387 BT_LOGT("Enumeration field type mappings differ: different starts of range: "
16ca5ff0
PP
3388 "mapping-a-range-start-unsigned=%" PRIu64 ", "
3389 "mapping-b-range-start-unsigned=%" PRIu64,
3390 mapping_a->range_start._unsigned,
3391 mapping_b->range_start._unsigned);
3392 goto end;
3393 }
3394
3395 /* Range end */
3396 if (mapping_a->range_end._unsigned !=
3397 mapping_b->range_end._unsigned) {
ef267d12 3398 BT_LOGT("Enumeration field type mappings differ: different ends of range: "
16ca5ff0
PP
3399 "mapping-a-range-end-unsigned=%" PRIu64 ", "
3400 "mapping-b-range-end-unsigned=%" PRIu64,
3401 mapping_a->range_end._unsigned,
3402 mapping_b->range_end._unsigned);
3403 goto end;
3404 }
3405
3406 /* Equal */
3407 ret = 0;
3408
3409end:
3410 return ret;
3411}
3412
3413BT_HIDDEN
3414int bt_ctf_field_type_common_enumeration_compare_recursive(
3415 struct bt_ctf_field_type_common *ft_a,
3416 struct bt_ctf_field_type_common *ft_b)
3417{
3418 int ret = 1;
3419 int i;
3420 struct bt_ctf_field_type_common_enumeration *enum_ft_a =
3421 BT_CTF_FROM_COMMON(ft_a);
3422 struct bt_ctf_field_type_common_enumeration *enum_ft_b =
3423 BT_CTF_FROM_COMMON(ft_b);
3424
3425 /* Container field type */
3426 ret = bt_ctf_field_type_common_compare(
3427 BT_CTF_TO_COMMON(enum_ft_a->container_ft),
3428 BT_CTF_TO_COMMON(enum_ft_b->container_ft));
3429 if (ret) {
ef267d12 3430 BT_LOGT("Enumeration field types differ: different container field types: "
16ca5ff0
PP
3431 "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
3432 enum_ft_a->container_ft, enum_ft_b->container_ft);
3433 goto end;
3434 }
3435
3436 ret = 1;
3437
3438 /* Entries */
3439 if (enum_ft_a->entries->len != enum_ft_b->entries->len) {
3440 goto end;
3441 }
3442
3443 for (i = 0; i < enum_ft_a->entries->len; ++i) {
3444 struct bt_ctf_enumeration_mapping *mapping_a =
3445 g_ptr_array_index(enum_ft_a->entries, i);
3446 struct bt_ctf_enumeration_mapping *mapping_b =
3447 g_ptr_array_index(enum_ft_b->entries, i);
3448
3449 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
ef267d12 3450 BT_LOGT("Enumeration field types differ: different mappings: "
16ca5ff0
PP
3451 "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
3452 "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
3453 mapping_a, mapping_b,
3454 g_quark_to_string(mapping_a->string),
3455 g_quark_to_string(mapping_b->string));
3456 goto end;
3457 }
3458 }
3459
3460 /* Equal */
3461 ret = 0;
3462
3463end:
3464 return ret;
3465}
3466
3467BT_HIDDEN
3468int bt_ctf_field_type_common_string_compare(struct bt_ctf_field_type_common *ft_a,
3469 struct bt_ctf_field_type_common *ft_b)
3470{
3471 int ret = 1;
3472 struct bt_ctf_field_type_common_string *string_ft_a = BT_CTF_FROM_COMMON(ft_a);
3473 struct bt_ctf_field_type_common_string *string_ft_b = BT_CTF_FROM_COMMON(ft_b);
3474
3475 /* Encoding */
3476 if (string_ft_a->encoding != string_ft_b->encoding) {
ef267d12 3477 BT_LOGT("String field types differ: different encodings: "
16ca5ff0
PP
3478 "ft-a-encoding=%s, ft-b-encoding=%s",
3479 bt_ctf_string_encoding_string(string_ft_a->encoding),
3480 bt_ctf_string_encoding_string(string_ft_b->encoding));
3481 goto end;
3482 }
3483
3484 /* Equal */
3485 ret = 0;
3486
3487end:
3488 return ret;
3489}
3490
3491static
3492int compare_structure_variant_members(
3493 struct bt_ctf_field_type_common *member_a_ft,
3494 struct bt_ctf_field_type_common *member_b_ft,
3495 GQuark member_a_name, GQuark member_b_name)
3496{
3497 int ret = 1;
3498
3499 /* Label */
3500 if (member_a_name != member_b_name) {
ef267d12 3501 BT_LOGT("Structure/variant field type fields differ: different names: "
16ca5ff0
PP
3502 "field-a-name=%s, field-b-name=%s",
3503 g_quark_to_string(member_a_name),
3504 g_quark_to_string(member_b_name));
3505 goto end;
3506 }
3507
3508 /* Type */
3509 ret = bt_ctf_field_type_common_compare(member_a_ft, member_b_ft);
3510 if (ret == 1) {
ef267d12 3511 BT_LOGT("Structure/variant field type fields differ: different field types: "
16ca5ff0
PP
3512 "field-name=\"%s\", field-a-ft-addr=%p, field-b-ft-addr=%p",
3513 g_quark_to_string(member_a_name),
3514 member_a_ft, member_b_ft);
3515 }
3516
3517end:
3518 return ret;
3519}
3520
3521BT_HIDDEN
3522int bt_ctf_field_type_common_structure_compare_recursive(
3523 struct bt_ctf_field_type_common *ft_a,
3524 struct bt_ctf_field_type_common *ft_b)
3525{
3526 int ret = 1;
3527 int i;
3528 struct bt_ctf_field_type_common_structure *struct_ft_a =
3529 BT_CTF_FROM_COMMON(ft_a);
3530 struct bt_ctf_field_type_common_structure *struct_ft_b =
3531 BT_CTF_FROM_COMMON(ft_b);
3532
3533 /* Alignment */
3534 if (bt_ctf_field_type_common_get_alignment(ft_a) !=
3535 bt_ctf_field_type_common_get_alignment(ft_b)) {
ef267d12 3536 BT_LOGT("Structure field types differ: different alignments: "
16ca5ff0
PP
3537 "ft-a-align=%u, ft-b-align=%u",
3538 bt_ctf_field_type_common_get_alignment(ft_a),
3539 bt_ctf_field_type_common_get_alignment(ft_b));
3540 goto end;
3541 }
3542
3543 /* Fields */
3544 if (struct_ft_a->fields->len != struct_ft_b->fields->len) {
ef267d12 3545 BT_LOGT("Structure field types differ: different field counts: "
16ca5ff0
PP
3546 "ft-a-field-count=%u, ft-b-field-count=%u",
3547 struct_ft_a->fields->len, struct_ft_b->fields->len);
3548 goto end;
3549 }
3550
3551 for (i = 0; i < struct_ft_a->fields->len; ++i) {
3552 struct bt_ctf_field_type_common_structure_field *field_a =
3553 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
3554 struct_ft_a, i);
3555 struct bt_ctf_field_type_common_structure_field *field_b =
3556 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
3557 struct_ft_b, i);
3558
3559 ret = compare_structure_variant_members(field_a->type,
3560 field_b->type, field_a->name, field_b->name);
3561 if (ret) {
3562 /* compare_structure_variant_members() logs what differs */
ef267d12 3563 BT_LOGT_STR("Structure field types differ: different fields.");
16ca5ff0
PP
3564 goto end;
3565 }
3566 }
3567
3568 /* Equal */
3569 ret = 0;
3570
3571end:
3572 return ret;
3573}
3574
3575BT_HIDDEN
3576int bt_ctf_field_type_common_variant_compare_recursive(
3577 struct bt_ctf_field_type_common *ft_a,
3578 struct bt_ctf_field_type_common *ft_b)
3579{
3580 int ret = 1;
3581 int i;
3582 struct bt_ctf_field_type_common_variant *var_ft_a = BT_CTF_FROM_COMMON(ft_a);
3583 struct bt_ctf_field_type_common_variant *var_ft_b = BT_CTF_FROM_COMMON(ft_b);
3584
3585 /* Tag name */
3586 if (strcmp(var_ft_a->tag_name->str, var_ft_b->tag_name->str)) {
ef267d12 3587 BT_LOGT("Variant field types differ: different tag field names: "
16ca5ff0
PP
3588 "ft-a-tag-field-name=\"%s\", ft-b-tag-field-name=\"%s\"",
3589 var_ft_a->tag_name->str, var_ft_b->tag_name->str);
3590 goto end;
3591 }
3592
3593 /* Tag type */
3594 ret = bt_ctf_field_type_common_compare(BT_CTF_TO_COMMON(var_ft_a->tag_ft),
3595 BT_CTF_TO_COMMON(var_ft_b->tag_ft));
3596 if (ret) {
ef267d12 3597 BT_LOGT("Variant field types differ: different tag field types: "
16ca5ff0
PP
3598 "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
3599 var_ft_a->tag_ft, var_ft_b->tag_ft);
3600 goto end;
3601 }
3602
3603 ret = 1;
3604
3605 /* Fields */
3606 if (var_ft_a->choices->len != var_ft_b->choices->len) {
ef267d12 3607 BT_LOGT("Variant field types differ: different field counts: "
16ca5ff0
PP
3608 "ft-a-field-count=%u, ft-b-field-count=%u",
3609 var_ft_a->choices->len, var_ft_b->choices->len);
3610 goto end;
3611 }
3612
3613 for (i = 0; i < var_ft_a->choices->len; ++i) {
3614 struct bt_ctf_field_type_common_variant_choice *choice_a =
3615 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
3616 var_ft_a, i);
3617 struct bt_ctf_field_type_common_variant_choice *choice_b =
3618 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
3619 var_ft_b, i);
3620
3621 ret = compare_structure_variant_members(choice_a->type,
3622 choice_b->type, choice_a->name, choice_b->name);
3623 if (ret) {
3624 /* compare_structure_variant_members() logs what differs */
ef267d12 3625 BT_LOGT_STR("Variant field types differ: different fields.");
16ca5ff0
PP
3626 goto end;
3627 }
3628 }
3629
3630 /* Equal */
3631 ret = 0;
3632
3633end:
3634 return ret;
3635}
3636
3637BT_HIDDEN
3638int bt_ctf_field_type_common_array_compare_recursive(
3639 struct bt_ctf_field_type_common *ft_a,
3640 struct bt_ctf_field_type_common *ft_b)
3641{
3642 int ret = 1;
3643 struct bt_ctf_field_type_common_array *array_ft_a = BT_CTF_FROM_COMMON(ft_a);
3644 struct bt_ctf_field_type_common_array *array_ft_b = BT_CTF_FROM_COMMON(ft_b);
3645
3646 /* Length */
3647 if (array_ft_a->length != array_ft_b->length) {
ef267d12 3648 BT_LOGT("Structure field types differ: different lengths: "
16ca5ff0
PP
3649 "ft-a-length=%u, ft-b-length=%u",
3650 array_ft_a->length, array_ft_b->length);
3651 goto end;
3652 }
3653
3654 /* Element type */
3655 ret = bt_ctf_field_type_common_compare(array_ft_a->element_ft,
3656 array_ft_b->element_ft);
3657 if (ret == 1) {
ef267d12 3658 BT_LOGT("Array field types differ: different element field types: "
16ca5ff0
PP
3659 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
3660 array_ft_a->element_ft, array_ft_b->element_ft);
3661 }
3662
3663end:
3664 return ret;
3665}
3666
3667BT_HIDDEN
3668int bt_ctf_field_type_common_sequence_compare_recursive(
3669 struct bt_ctf_field_type_common *ft_a,
3670 struct bt_ctf_field_type_common *ft_b)
3671{
3672 int ret = -1;
3673 struct bt_ctf_field_type_common_sequence *seq_ft_a = BT_CTF_FROM_COMMON(ft_a);
3674 struct bt_ctf_field_type_common_sequence *seq_ft_b = BT_CTF_FROM_COMMON(ft_b);
3675
3676 /* Length name */
3677 if (strcmp(seq_ft_a->length_field_name->str,
3678 seq_ft_b->length_field_name->str)) {
ef267d12 3679 BT_LOGT("Sequence field types differ: different length field names: "
16ca5ff0
PP
3680 "ft-a-length-field-name=\"%s\", "
3681 "ft-b-length-field-name=\"%s\"",
3682 seq_ft_a->length_field_name->str,
3683 seq_ft_b->length_field_name->str);
3684 goto end;
3685 }
3686
3687 /* Element type */
3688 ret = bt_ctf_field_type_common_compare(seq_ft_a->element_ft,
3689 seq_ft_b->element_ft);
3690 if (ret == 1) {
ef267d12 3691 BT_LOGT("Sequence field types differ: different element field types: "
16ca5ff0
PP
3692 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
3693 seq_ft_a->element_ft, seq_ft_b->element_ft);
3694 }
3695
3696end:
3697 return ret;
3698}
3699
3700BT_HIDDEN
3701int bt_ctf_field_type_common_compare(struct bt_ctf_field_type_common *ft_a,
3702 struct bt_ctf_field_type_common *ft_b)
3703{
3704 int ret = 1;
3705
67d2ce02
MJ
3706 BT_CTF_ASSERT_PRE_NON_NULL(ft_a, "Field type A");
3707 BT_CTF_ASSERT_PRE_NON_NULL(ft_b, "Field type B");
16ca5ff0
PP
3708
3709 if (ft_a == ft_b) {
3710 /* Same reference: equal (even if both are NULL) */
3711 ret = 0;
3712 goto end;
3713 }
3714
3715 if (!ft_a) {
3716 BT_LOGW_STR("Invalid parameter: field type A is NULL.");
3717 ret = -1;
3718 goto end;
3719 }
3720
3721 if (!ft_b) {
3722 BT_LOGW_STR("Invalid parameter: field type B is NULL.");
3723 ret = -1;
3724 goto end;
3725 }
3726
3727 if (ft_a->id != ft_b->id) {
3728 /* Different type IDs */
ef267d12 3729 BT_LOGT("Field types differ: different IDs: "
16ca5ff0
PP
3730 "ft-a-addr=%p, ft-b-addr=%p, "
3731 "ft-a-id=%s, ft-b-id=%s",
3732 ft_a, ft_b,
3733 bt_ctf_field_type_id_string(ft_a->id),
3734 bt_ctf_field_type_id_string(ft_b->id));
3735 goto end;
3736 }
3737
3738 if (ft_a->id == BT_CTF_FIELD_TYPE_ID_UNKNOWN) {
3739 /* Both have unknown type IDs */
3740 BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
3741 goto end;
3742 }
3743
98b15851 3744 BT_ASSERT_DBG(ft_a->methods->compare);
16ca5ff0
PP
3745 ret = ft_a->methods->compare(ft_a, ft_b);
3746 if (ret == 1) {
ef267d12 3747 BT_LOGT("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
16ca5ff0
PP
3748 ft_a, ft_b);
3749 }
3750
3751end:
3752 return ret;
3753}
3754
3755BT_HIDDEN
3756int64_t bt_ctf_field_type_common_get_field_count(struct bt_ctf_field_type_common *ft)
3757{
3758 int64_t field_count = -1;
3759
3760 switch (ft->id) {
3761 case BT_CTF_FIELD_TYPE_ID_STRUCT:
3762 field_count =
3763 bt_ctf_field_type_common_structure_get_field_count(ft);
3764 break;
3765 case BT_CTF_FIELD_TYPE_ID_VARIANT:
3766 field_count =
3767 bt_ctf_field_type_common_variant_get_field_count(ft);
3768 break;
3769 case BT_CTF_FIELD_TYPE_ID_ARRAY:
3770 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
3771 /*
3772 * Array and sequence types always contain a single member
3773 * (the element type).
3774 */
3775 field_count = 1;
3776 break;
3777 default:
3778 break;
3779 }
3780
3781 return field_count;
3782}
3783
3784BT_HIDDEN
3785struct bt_ctf_field_type_common *bt_ctf_field_type_common_borrow_field_at_index(
3786 struct bt_ctf_field_type_common *ft, int index)
3787{
3788 struct bt_ctf_field_type_common *field_type = NULL;
3789
3790 switch (ft->id) {
3791 case BT_CTF_FIELD_TYPE_ID_STRUCT:
3792 {
3793 int ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
3794 ft, NULL, &field_type, index);
3795 if (ret) {
3796 field_type = NULL;
3797 goto end;
3798 }
3799 break;
3800 }
3801 case BT_CTF_FIELD_TYPE_ID_VARIANT:
3802 {
3803 int ret = bt_ctf_field_type_common_variant_borrow_field_by_index(
3804 ft, NULL, &field_type, index);
3805 if (ret) {
3806 field_type = NULL;
3807 goto end;
3808 }
3809 break;
3810 }
3811 case BT_CTF_FIELD_TYPE_ID_ARRAY:
3812 field_type =
3813 bt_ctf_field_type_common_array_borrow_element_field_type(ft);
3814 break;
3815 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
3816 field_type =
3817 bt_ctf_field_type_common_sequence_borrow_element_field_type(ft);
3818 break;
3819 default:
3820 break;
3821 }
3822
3823end:
3824 return field_type;
3825}
3826
3827BT_HIDDEN
3828int bt_ctf_field_type_common_get_field_index(struct bt_ctf_field_type_common *ft,
3829 const char *name)
3830{
3831 int field_index = -1;
3832
3833 switch (ft->id) {
3834 case BT_CTF_FIELD_TYPE_ID_STRUCT:
3835 field_index = bt_ctf_field_type_common_structure_get_field_name_index(
3836 ft, name);
3837 break;
3838 case BT_CTF_FIELD_TYPE_ID_VARIANT:
3839 field_index = bt_ctf_field_type_common_variant_get_field_name_index(
3840 ft, name);
3841 break;
3842 default:
3843 break;
3844 }
3845
3846 return field_index;
3847}
3848
3849BT_HIDDEN
3850struct bt_ctf_field_path *bt_ctf_field_type_common_variant_borrow_tag_field_path(
3851 struct bt_ctf_field_type_common *ft)
3852{
3853 struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
3854
67d2ce02
MJ
3855 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
3856 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
16ca5ff0
PP
3857 "Field type");
3858 return var_ft->tag_field_path;
3859}
3860
3861BT_HIDDEN
3862struct bt_ctf_field_path *bt_ctf_field_type_common_sequence_borrow_length_field_path(
3863 struct bt_ctf_field_type_common *ft)
3864{
3865 struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
3866
67d2ce02
MJ
3867 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
3868 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
16ca5ff0
PP
3869 "Field type");
3870 return seq_ft->length_field_path;
3871}
3872
3873BT_HIDDEN
3874int bt_ctf_field_type_common_validate_single_clock_class(
3875 struct bt_ctf_field_type_common *ft,
3876 struct bt_ctf_clock_class **expected_clock_class)
3877{
3878 int ret = 0;
3879
3880 if (!ft) {
3881 goto end;
3882 }
3883
98b15851 3884 BT_ASSERT_DBG(expected_clock_class);
16ca5ff0
PP
3885
3886 switch (ft->id) {
3887 case BT_CTF_FIELD_TYPE_ID_INTEGER:
3888 {
3889 struct bt_ctf_clock_class *mapped_clock_class =
3890 bt_ctf_field_type_common_integer_borrow_mapped_clock_class(ft);
3891
3892 if (!mapped_clock_class) {
3893 goto end;
3894 }
3895
3896 if (!*expected_clock_class) {
3897 /* Move reference to output parameter */
e1e02a22 3898 *expected_clock_class = bt_ctf_object_get_ref(mapped_clock_class);
16ca5ff0 3899 mapped_clock_class = NULL;
ef267d12 3900 BT_LOGT("Setting expected clock class: "
16ca5ff0
PP
3901 "expected-clock-class-addr=%p",
3902 *expected_clock_class);
3903 } else {
3904 if (mapped_clock_class != *expected_clock_class) {
3905 BT_LOGW("Integer field type is not mapped to "
3906 "the expected clock class: "
3907 "mapped-clock-class-addr=%p, "
3908 "mapped-clock-class-name=\"%s\", "
3909 "expected-clock-class-addr=%p, "
3910 "expected-clock-class-name=\"%s\"",
3911 mapped_clock_class,
3912 bt_ctf_clock_class_get_name(mapped_clock_class),
3913 *expected_clock_class,
3914 bt_ctf_clock_class_get_name(*expected_clock_class));
e1e02a22 3915 bt_ctf_object_put_ref(mapped_clock_class);
16ca5ff0
PP
3916 ret = -1;
3917 goto end;
3918 }
3919 }
3920
3921 break;
3922 }
3923 case BT_CTF_FIELD_TYPE_ID_ENUM:
3924 case BT_CTF_FIELD_TYPE_ID_ARRAY:
3925 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
3926 {
3927 struct bt_ctf_field_type_common *sub_ft = NULL;
3928
3929 switch (ft->id) {
3930 case BT_CTF_FIELD_TYPE_ID_ENUM:
3931 sub_ft = bt_ctf_field_type_common_enumeration_borrow_container_field_type(
3932 ft);
3933 break;
3934 case BT_CTF_FIELD_TYPE_ID_ARRAY:
3935 sub_ft = bt_ctf_field_type_common_array_borrow_element_field_type(
3936 ft);
3937 break;
3938 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
3939 sub_ft = bt_ctf_field_type_common_sequence_borrow_element_field_type(
3940 ft);
3941 break;
3942 default:
3943 BT_LOGF("Unexpected field type ID: id=%d", ft->id);
3944 abort();
3945 }
3946
98b15851 3947 BT_ASSERT_DBG(sub_ft);
16ca5ff0
PP
3948 ret = bt_ctf_field_type_common_validate_single_clock_class(sub_ft,
3949 expected_clock_class);
3950 break;
3951 }
3952 case BT_CTF_FIELD_TYPE_ID_STRUCT:
3953 {
3954 uint64_t i;
3955 int64_t count = bt_ctf_field_type_common_structure_get_field_count(
3956 ft);
3957
3958 for (i = 0; i < count; i++) {
3959 const char *name;
3960 struct bt_ctf_field_type_common *member_type;
3961
3962 ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
3963 ft, &name, &member_type, i);
98b15851 3964 BT_ASSERT_DBG(ret == 0);
16ca5ff0
PP
3965 ret = bt_ctf_field_type_common_validate_single_clock_class(
3966 member_type, expected_clock_class);
3967 if (ret) {
3968 BT_LOGW("Structure field type's field's type "
3969 "is not recursively mapped to the "
3970 "expected clock class: "
3971 "field-ft-addr=%p, field-name=\"%s\"",
3972 member_type, name);
3973 goto end;
3974 }
3975 }
3976 break;
3977 }
3978 case BT_CTF_FIELD_TYPE_ID_VARIANT:
3979 {
3980 uint64_t i;
3981 int64_t count = bt_ctf_field_type_common_variant_get_field_count(
3982 ft);
3983
3984 for (i = 0; i < count; i++) {
3985 const char *name;
3986 struct bt_ctf_field_type_common *member_type;
3987
3988 ret = bt_ctf_field_type_common_variant_borrow_field_by_index(
3989 ft, &name, &member_type, i);
98b15851 3990 BT_ASSERT_DBG(ret == 0);
16ca5ff0
PP
3991 ret = bt_ctf_field_type_common_validate_single_clock_class(
3992 member_type, expected_clock_class);
3993 if (ret) {
3994 BT_LOGW("Variant field type's field's type "
3995 "is not recursively mapped to the "
3996 "expected clock class: "
3997 "field-ft-addr=%p, field-name=\"%s\"",
3998 member_type, name);
3999 goto end;
4000 }
4001 }
4002 break;
4003 }
4004 default:
4005 break;
4006 }
4007
4008end:
4009 return ret;
4010}
4011
3dca2276
PP
4012static
4013struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
4014 struct bt_ctf_field_type *ft);
4015
4016static
4017struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy_recursive(
4018 struct bt_ctf_field_type *ft);
4019
4020static
4021struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
4022 struct bt_ctf_field_type *ft);
4023
4024static
4025struct bt_ctf_field_type *bt_ctf_field_type_structure_copy_recursive(
4026 struct bt_ctf_field_type *ft);
4027
4028static
4029struct bt_ctf_field_type *bt_ctf_field_type_variant_copy_recursive(
4030 struct bt_ctf_field_type *ft);
4031
4032static
4033struct bt_ctf_field_type *bt_ctf_field_type_array_copy_recursive(
4034 struct bt_ctf_field_type *ft);
4035
4036static
4037struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy_recursive(
4038 struct bt_ctf_field_type *type);
4039
4040static
4041struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
4042 struct bt_ctf_field_type *type);
4043
16ca5ff0
PP
4044static struct bt_ctf_field_type_common_methods bt_ctf_field_type_integer_methods = {
4045 .freeze = bt_ctf_field_type_common_generic_freeze,
4046 .validate = bt_ctf_field_type_common_integer_validate,
4047 .set_byte_order = bt_ctf_field_type_common_integer_set_byte_order,
4048 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4049 bt_ctf_field_type_integer_copy,
16ca5ff0 4050 .compare = bt_ctf_field_type_common_integer_compare,
3dca2276
PP
4051};
4052
16ca5ff0
PP
4053static struct bt_ctf_field_type_common_methods bt_ctf_field_type_floating_point_methods = {
4054 .freeze = bt_ctf_field_type_common_generic_freeze,
3dca2276 4055 .validate = NULL,
16ca5ff0
PP
4056 .set_byte_order = bt_ctf_field_type_common_floating_point_set_byte_order,
4057 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4058 bt_ctf_field_type_floating_point_copy,
16ca5ff0 4059 .compare = bt_ctf_field_type_common_floating_point_compare,
3dca2276
PP
4060};
4061
16ca5ff0
PP
4062static struct bt_ctf_field_type_common_methods bt_ctf_field_type_enumeration_methods = {
4063 .freeze = bt_ctf_field_type_common_enumeration_freeze_recursive,
4064 .validate = bt_ctf_field_type_common_enumeration_validate_recursive,
4065 .set_byte_order = bt_ctf_field_type_common_enumeration_set_byte_order_recursive,
4066 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4067 bt_ctf_field_type_enumeration_copy_recursive,
16ca5ff0 4068 .compare = bt_ctf_field_type_common_enumeration_compare_recursive,
3dca2276
PP
4069};
4070
16ca5ff0
PP
4071static struct bt_ctf_field_type_common_methods bt_ctf_field_type_string_methods = {
4072 .freeze = bt_ctf_field_type_common_generic_freeze,
3dca2276
PP
4073 .validate = NULL,
4074 .set_byte_order = NULL,
16ca5ff0 4075 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4076 bt_ctf_field_type_string_copy,
16ca5ff0 4077 .compare = bt_ctf_field_type_common_string_compare,
3dca2276
PP
4078};
4079
16ca5ff0
PP
4080static struct bt_ctf_field_type_common_methods bt_ctf_field_type_array_methods = {
4081 .freeze = bt_ctf_field_type_common_array_freeze_recursive,
4082 .validate = bt_ctf_field_type_common_array_validate_recursive,
4083 .set_byte_order = bt_ctf_field_type_common_array_set_byte_order_recursive,
4084 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4085 bt_ctf_field_type_array_copy_recursive,
16ca5ff0 4086 .compare = bt_ctf_field_type_common_array_compare_recursive,
3dca2276
PP
4087};
4088
16ca5ff0
PP
4089static struct bt_ctf_field_type_common_methods bt_ctf_field_type_sequence_methods = {
4090 .freeze = bt_ctf_field_type_common_sequence_freeze_recursive,
4091 .validate = bt_ctf_field_type_common_sequence_validate_recursive,
4092 .set_byte_order = bt_ctf_field_type_common_sequence_set_byte_order_recursive,
4093 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4094 bt_ctf_field_type_sequence_copy_recursive,
16ca5ff0 4095 .compare = bt_ctf_field_type_common_sequence_compare_recursive,
3dca2276
PP
4096};
4097
16ca5ff0
PP
4098static struct bt_ctf_field_type_common_methods bt_ctf_field_type_structure_methods = {
4099 .freeze = bt_ctf_field_type_common_structure_freeze_recursive,
4100 .validate = bt_ctf_field_type_common_structure_validate_recursive,
4101 .set_byte_order = bt_ctf_field_type_common_structure_set_byte_order_recursive,
4102 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4103 bt_ctf_field_type_structure_copy_recursive,
16ca5ff0 4104 .compare = bt_ctf_field_type_common_structure_compare_recursive,
3dca2276
PP
4105};
4106
16ca5ff0
PP
4107static struct bt_ctf_field_type_common_methods bt_ctf_field_type_variant_methods = {
4108 .freeze = bt_ctf_field_type_common_variant_freeze_recursive,
4109 .validate = bt_ctf_field_type_common_variant_validate_recursive,
4110 .set_byte_order = bt_ctf_field_type_common_variant_set_byte_order_recursive,
4111 .copy = (bt_ctf_field_type_common_method_copy)
3dca2276 4112 bt_ctf_field_type_variant_copy_recursive,
16ca5ff0 4113 .compare = bt_ctf_field_type_common_variant_compare_recursive,
3dca2276
PP
4114};
4115
16ca5ff0 4116typedef int (*bt_ctf_field_type_serialize_func)(struct bt_ctf_field_type_common *,
3dca2276
PP
4117 struct metadata_context *);
4118
4119BT_HIDDEN
4120int bt_ctf_field_type_serialize_recursive(struct bt_ctf_field_type *type,
4121 struct metadata_context *context)
4122{
4123 int ret;
16ca5ff0 4124 struct bt_ctf_field_type_common *type_common = (void *) type;
3dca2276
PP
4125 bt_ctf_field_type_serialize_func serialize_func;
4126
98b15851
PP
4127 BT_ASSERT_DBG(type);
4128 BT_ASSERT_DBG(context);
3dca2276
PP
4129
4130 /* Make sure field type is valid before serializing it */
16ca5ff0 4131 ret = bt_ctf_field_type_common_validate((void *) type);
3dca2276
PP
4132 if (ret) {
4133 BT_LOGW("Cannot serialize field type's metadata: field type is invalid: "
4134 "addr=%p", type);
4135 goto end;
4136 }
4137
4138 serialize_func = type_common->spec.writer.serialize_func;
4139 ret = serialize_func((void *) type, context);
4140
4141end:
4142 return ret;
4143}
4144
4145static
16ca5ff0 4146const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
3dca2276
PP
4147{
4148 const char *encoding_string;
4149
4150 switch (encoding) {
16ca5ff0 4151 case BT_CTF_STRING_ENCODING_NONE:
3dca2276
PP
4152 encoding_string = "none";
4153 break;
16ca5ff0 4154 case BT_CTF_STRING_ENCODING_ASCII:
3dca2276
PP
4155 encoding_string = "ASCII";
4156 break;
16ca5ff0 4157 case BT_CTF_STRING_ENCODING_UTF8:
3dca2276
PP
4158 encoding_string = "UTF8";
4159 break;
4160 default:
4161 encoding_string = "unknown";
4162 break;
4163 }
4164
4165 return encoding_string;
4166}
4167
4168static
16ca5ff0 4169const char *get_integer_base_string(enum bt_ctf_integer_base base)
3dca2276
PP
4170{
4171 const char *base_string;
4172
4173 switch (base) {
16ca5ff0
PP
4174 case BT_CTF_INTEGER_BASE_DECIMAL:
4175 case BT_CTF_INTEGER_BASE_UNSPECIFIED:
3dca2276
PP
4176 base_string = "decimal";
4177 break;
16ca5ff0 4178 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
3dca2276
PP
4179 base_string = "hexadecimal";
4180 break;
16ca5ff0 4181 case BT_CTF_INTEGER_BASE_OCTAL:
3dca2276
PP
4182 base_string = "octal";
4183 break;
16ca5ff0 4184 case BT_CTF_INTEGER_BASE_BINARY:
3dca2276
PP
4185 base_string = "binary";
4186 break;
4187 default:
4188 base_string = "unknown";
4189 break;
4190 }
4191
4192 return base_string;
4193}
4194
4195static
4196void append_field_name(struct metadata_context *context,
4197 const char *name)
4198{
4199 g_string_append_c(context->string, ' ');
4200
16ca5ff0 4201 if (!bt_ctf_identifier_is_valid(name) || *name == '_') {
3dca2276
PP
4202 g_string_append_c(context->string, '_');
4203 }
4204
4205 g_string_append(context->string, name);
4206}
4207
4208static
16ca5ff0 4209int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type_common *type,
3dca2276
PP
4210 struct metadata_context *context)
4211{
16ca5ff0 4212 struct bt_ctf_field_type_common_integer *integer = BT_CTF_FROM_COMMON(type);
3dca2276
PP
4213 int ret = 0;
4214
4215 BT_LOGD("Serializing CTF writer integer field type's metadata: "
4216 "ft-addr=%p, metadata-context-addr=%p", type, context);
4217 g_string_append_printf(context->string,
4218 "integer { size = %u; align = %u; signed = %s; encoding = %s; base = %s; byte_order = %s",
4219 integer->size, type->alignment,
4220 (integer->is_signed ? "true" : "false"),
4221 get_encoding_string(integer->encoding),
4222 get_integer_base_string(integer->base),
16ca5ff0 4223 bt_ctf_get_byte_order_string(integer->user_byte_order));
3dca2276 4224 if (integer->mapped_clock_class) {
16ca5ff0 4225 const char *clock_name = bt_ctf_clock_class_get_name(
3dca2276
PP
4226 integer->mapped_clock_class);
4227
98b15851 4228 BT_ASSERT_DBG(clock_name);
3dca2276
PP
4229 g_string_append_printf(context->string,
4230 "; map = clock.%s.value", clock_name);
4231 }
4232
4233 g_string_append(context->string, "; }");
4234 return ret;
4235}
4236
4237static
4238int bt_ctf_field_type_enumeration_serialize_recursive(
16ca5ff0 4239 struct bt_ctf_field_type_common *type,
3dca2276
PP
4240 struct metadata_context *context)
4241{
4242 size_t entry;
4243 int ret;
16ca5ff0
PP
4244 struct bt_ctf_field_type_common_enumeration *enumeration =
4245 BT_CTF_FROM_COMMON(type);
4246 struct bt_ctf_field_type_common *container_type;
3dca2276
PP
4247 int container_signed;
4248
4249 BT_LOGD("Serializing CTF writer enumeration field type's metadata: "
4250 "ft-addr=%p, metadata-context-addr=%p", type, context);
4251 container_type =
16ca5ff0 4252 bt_ctf_field_type_common_enumeration_borrow_container_field_type(type);
98b15851 4253 BT_ASSERT_DBG(container_type);
16ca5ff0 4254 container_signed = bt_ctf_field_type_common_integer_is_signed(
3dca2276 4255 container_type);
98b15851 4256 BT_ASSERT_DBG(container_signed >= 0);
3dca2276
PP
4257 g_string_append(context->string, "enum : ");
4258 BT_LOGD_STR("Serializing CTF writer enumeration field type's container field type's metadata.");
4259 ret = bt_ctf_field_type_serialize_recursive(
4260 (void *) enumeration->container_ft, context);
4261 if (ret) {
4262 BT_LOGW("Cannot serialize CTF writer enumeration field type's container field type's metadata: "
4263 "container-ft-addr=%p", enumeration->container_ft);
4264 goto end;
4265 }
4266
4267 g_string_append(context->string, " { ");
4268 for (entry = 0; entry < enumeration->entries->len; entry++) {
16ca5ff0 4269 struct bt_ctf_enumeration_mapping *mapping =
3dca2276
PP
4270 enumeration->entries->pdata[entry];
4271 const char *label = g_quark_to_string(mapping->string);
4272
4273 g_string_append(context->string, "\"");
4274
16ca5ff0 4275 if (!bt_ctf_identifier_is_valid(label) || label[0] == '_') {
3dca2276
PP
4276 g_string_append(context->string, "_");
4277 }
4278
4279 g_string_append_printf(context->string, "%s\" = ", label);
4280
4281 if (container_signed) {
4282 if (mapping->range_start._signed ==
4283 mapping->range_end._signed) {
4284 g_string_append_printf(context->string,
4285 "%" PRId64,
4286 mapping->range_start._signed);
4287 } else {
4288 g_string_append_printf(context->string,
4289 "%" PRId64 " ... %" PRId64,
4290 mapping->range_start._signed,
4291 mapping->range_end._signed);
4292 }
4293 } else {
4294 if (mapping->range_start._unsigned ==
4295 mapping->range_end._unsigned) {
4296 g_string_append_printf(context->string,
4297 "%" PRIu64,
4298 mapping->range_start._unsigned);
4299 } else {
4300 g_string_append_printf(context->string,
4301 "%" PRIu64 " ... %" PRIu64,
4302 mapping->range_start._unsigned,
4303 mapping->range_end._unsigned);
4304 }
4305 }
4306
4307 g_string_append(context->string,
4308 ((entry != (enumeration->entries->len - 1)) ?
4309 ", " : " }"));
4310 }
4311
4312 if (context->field_name->len) {
4313 append_field_name(context,
4314 context->field_name->str);
4315 g_string_assign(context->field_name, "");
4316 }
4317
4318end:
3dca2276
PP
4319 return ret;
4320}
4321
4322static
16ca5ff0 4323int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type_common *type,
3dca2276
PP
4324 struct metadata_context *context)
4325{
16ca5ff0
PP
4326 struct bt_ctf_field_type_common_floating_point *floating_point =
4327 BT_CTF_FROM_COMMON(type);
3dca2276
PP
4328
4329 BT_LOGD("Serializing CTF writer floating point number field type's metadata: "
4330 "ft-addr=%p, metadata-context-addr=%p", type, context);
4331 g_string_append_printf(context->string,
4332 "floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
4333 floating_point->exp_dig,
4334 floating_point->mant_dig,
16ca5ff0 4335 bt_ctf_get_byte_order_string(floating_point->user_byte_order),
3dca2276
PP
4336 type->alignment);
4337 return 0;
4338}
4339
4340static
4341int bt_ctf_field_type_structure_serialize_recursive(
16ca5ff0 4342 struct bt_ctf_field_type_common *type,
3dca2276
PP
4343 struct metadata_context *context)
4344{
4345 size_t i;
4346 unsigned int indent;
4347 int ret = 0;
16ca5ff0 4348 struct bt_ctf_field_type_common_structure *structure = BT_CTF_FROM_COMMON(type);
3dca2276
PP
4349 GString *structure_field_name = context->field_name;
4350
4351 BT_LOGD("Serializing CTF writer structure field type's metadata: "
4352 "ft-addr=%p, metadata-context-addr=%p", type, context);
4353 context->field_name = g_string_new("");
4354
4355 context->current_indentation_level++;
4356 g_string_append(context->string, "struct {\n");
4357
4358 for (i = 0; i < structure->fields->len; i++) {
16ca5ff0
PP
4359 struct bt_ctf_field_type_common_structure_field *field =
4360 BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
312c056a 4361 structure, i);
3dca2276
PP
4362
4363 BT_LOGD("Serializing CTF writer structure field type's field metadata: "
4364 "index=%zu, "
4365 "field-ft-addr=%p, field-name=\"%s\"",
4366 i, field, g_quark_to_string(field->name));
4367
4368 for (indent = 0; indent < context->current_indentation_level;
4369 indent++) {
4370 g_string_append_c(context->string, '\t');
4371 }
4372
4373 g_string_assign(context->field_name,
4374 g_quark_to_string(field->name));
4375 ret = bt_ctf_field_type_serialize_recursive(
4376 (void *) field->type, context);
4377 if (ret) {
4378 BT_LOGW("Cannot serialize CTF writer structure field type's field's metadata: "
4379 "index=%zu, "
4380 "field-ft-addr=%p, field-name=\"%s\"",
4381 i, field->type,
4382 g_quark_to_string(field->name));
4383 goto end;
4384 }
4385
4386 if (context->field_name->len) {
4387 append_field_name(context,
4388 context->field_name->str);
4389 }
4390 g_string_append(context->string, ";\n");
4391 }
4392
4393 context->current_indentation_level--;
4394 for (indent = 0; indent < context->current_indentation_level;
4395 indent++) {
4396 g_string_append_c(context->string, '\t');
4397 }
4398
4399 g_string_append_printf(context->string, "} align(%u)",
4400 type->alignment);
4401
4402end:
4403 g_string_free(context->field_name, TRUE);
4404 context->field_name = structure_field_name;
4405 return ret;
4406}
4407
4408static
4409int bt_ctf_field_type_variant_serialize_recursive(
16ca5ff0 4410 struct bt_ctf_field_type_common *type,
3dca2276
PP
4411 struct metadata_context *context)
4412{
4413 size_t i;
4414 unsigned int indent;
4415 int ret = 0;
16ca5ff0 4416 struct bt_ctf_field_type_common_variant *variant = BT_CTF_FROM_COMMON(type);
3dca2276
PP
4417 GString *variant_field_name = context->field_name;
4418
4419 BT_LOGD("Serializing CTF writer variant field type's metadata: "
4420 "ft-addr=%p, metadata-context-addr=%p", type, context);
4421 context->field_name = g_string_new("");
4422 if (variant->tag_name->len > 0) {
4423 g_string_append(context->string, "variant <");
4424 append_field_name(context, variant->tag_name->str);
4425 g_string_append(context->string, "> {\n");
4426 } else {
4427 g_string_append(context->string, "variant {\n");
4428 }
4429
4430 context->current_indentation_level++;
312c056a 4431 for (i = 0; i < variant->choices->len; i++) {
16ca5ff0
PP
4432 struct bt_ctf_field_type_common_variant_choice *field =
4433 BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
312c056a 4434 variant, i);
3dca2276
PP
4435
4436 BT_LOGD("Serializing CTF writer variant field type's field metadata: "
4437 "index=%zu, "
4438 "field-ft-addr=%p, field-name=\"%s\"",
4439 i, field, g_quark_to_string(field->name));
4440
4441 g_string_assign(context->field_name,
4442 g_quark_to_string(field->name));
4443 for (indent = 0; indent < context->current_indentation_level;
4444 indent++) {
4445 g_string_append_c(context->string, '\t');
4446 }
4447
4448 g_string_assign(context->field_name,
4449 g_quark_to_string(field->name));
4450 ret = bt_ctf_field_type_serialize_recursive(
4451 (void *) field->type, context);
4452 if (ret) {
4453 BT_LOGW("Cannot serialize CTF writer variant field type's field's metadata: "
4454 "index=%zu, "
4455 "field-ft-addr=%p, field-name=\"%s\"",
4456 i, field->type,
4457 g_quark_to_string(field->name));
4458 goto end;
4459 }
4460
4461 if (context->field_name->len) {
4462 append_field_name(context,
4463 context->field_name->str);
4464 g_string_append_c(context->string, ';');
4465 }
4466
4467 g_string_append_c(context->string, '\n');
4468 }
4469
4470 context->current_indentation_level--;
4471 for (indent = 0; indent < context->current_indentation_level;
4472 indent++) {
4473 g_string_append_c(context->string, '\t');
4474 }
4475
4476 g_string_append(context->string, "}");
4477
4478end:
4479 g_string_free(context->field_name, TRUE);
4480 context->field_name = variant_field_name;
4481 return ret;
4482}
4483
4484static
4485int bt_ctf_field_type_array_serialize_recursive(
16ca5ff0 4486 struct bt_ctf_field_type_common *type,
3dca2276
PP
4487 struct metadata_context *context)
4488{
4489 int ret = 0;
16ca5ff0 4490 struct bt_ctf_field_type_common_array *array = BT_CTF_FROM_COMMON(type);
3dca2276
PP
4491
4492 BT_LOGD("Serializing CTF writer array field type's metadata: "
4493 "ft-addr=%p, metadata-context-addr=%p", type, context);
4494 BT_LOGD_STR("Serializing CTF writer array field type's element field type's metadata.");
4495 ret = bt_ctf_field_type_serialize_recursive(
4496 (void *) array->element_ft, context);
4497 if (ret) {
4498 BT_LOGW("Cannot serialize CTF writer array field type's element field type's metadata: "
4499 "element-ft-addr=%p", array->element_ft);
4500 goto end;
4501 }
4502
4503 if (context->field_name->len) {
4504 append_field_name(context,
4505 context->field_name->str);
4506
4507 g_string_append_printf(context->string, "[%u]", array->length);
4508 g_string_assign(context->field_name, "");
4509 } else {
4510 g_string_append_printf(context->string, "[%u]", array->length);
4511 }
4512
4513end:
4514 return ret;
4515}
4516
4517static
4518int bt_ctf_field_type_sequence_serialize_recursive(
16ca5ff0 4519 struct bt_ctf_field_type_common *type,
3dca2276
PP
4520 struct metadata_context *context)
4521{
4522 int ret = 0;
16ca5ff0 4523 struct bt_ctf_field_type_common_sequence *sequence = BT_CTF_FROM_COMMON(type);
3dca2276
PP
4524
4525 BT_LOGD("Serializing CTF writer sequence field type's metadata: "
4526 "ft-addr=%p, metadata-context-addr=%p", type, context);
4527 BT_LOGD_STR("Serializing CTF writer sequence field type's element field type's metadata.");
4528 ret = bt_ctf_field_type_serialize_recursive(
4529 (void *) sequence->element_ft, context);
4530 if (ret) {
4531 BT_LOGW("Cannot serialize CTF writer sequence field type's element field type's metadata: "
4532 "element-ft-addr=%p", sequence->element_ft);
4533 goto end;
4534 }
4535
4536 if (context->field_name->len) {
4537 append_field_name(context, context->field_name->str);
4538 g_string_assign(context->field_name, "");
4539 }
4540 g_string_append(context->string, "[");
4541 append_field_name(context, sequence->length_field_name->str);
4542 g_string_append(context->string, "]");
4543
4544end:
4545 return ret;
4546}
4547
4548static
16ca5ff0 4549int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type_common *type,
3dca2276
PP
4550 struct metadata_context *context)
4551{
16ca5ff0 4552 struct bt_ctf_field_type_common_string *string = BT_CTF_FROM_COMMON(type);
3dca2276
PP
4553
4554 BT_LOGD("Serializing CTF writer string field type's metadata: "
4555 "ft-addr=%p, metadata-context-addr=%p", type, context);
4556 g_string_append_printf(context->string,
4557 "string { encoding = %s; }",
4558 get_encoding_string(string->encoding));
4559 return 0;
4560}
4561
4562struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
4563{
16ca5ff0 4564 struct bt_ctf_field_type_common_integer *integer = NULL;
3dca2276
PP
4565
4566 BT_LOGD("Creating CTF writer integer field type object: size=%u", size);
4567
4568 if (size == 0 || size > 64) {
4569 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
4570 "size=%u", size);
4571 goto error;
4572 }
4573
16ca5ff0 4574 integer = g_new0(struct bt_ctf_field_type_common_integer, 1);
3dca2276
PP
4575 if (!integer) {
4576 BT_LOGE_STR("Failed to allocate one integer field type.");
4577 goto error;
4578 }
4579
16ca5ff0
PP
4580 bt_ctf_field_type_common_integer_initialize(BT_CTF_TO_COMMON(integer),
4581 size, bt_ctf_field_type_common_integer_destroy,
3dca2276
PP
4582 &bt_ctf_field_type_integer_methods);
4583 integer->common.spec.writer.serialize_func =
4584 bt_ctf_field_type_integer_serialize;
4585 BT_LOGD("Created CTF writer integer field type object: addr=%p, size=%u",
4586 integer, size);
4587 goto end;
4588
4589error:
e1e02a22 4590 BT_CTF_OBJECT_PUT_REF_AND_RESET(integer);
3dca2276
PP
4591
4592end:
4593 return (void *) integer;
4594}
4595
4596int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *ft)
4597{
16ca5ff0 4598 return bt_ctf_field_type_common_integer_get_size((void *) ft);
3dca2276
PP
4599}
4600
00409097 4601bt_ctf_bool bt_ctf_field_type_integer_is_signed(struct bt_ctf_field_type *ft)
3dca2276 4602{
16ca5ff0 4603 return bt_ctf_field_type_common_integer_is_signed((void *) ft);
3dca2276
PP
4604}
4605
4606int bt_ctf_field_type_integer_set_is_signed(struct bt_ctf_field_type *ft,
00409097 4607 bt_ctf_bool is_signed)
3dca2276 4608{
16ca5ff0 4609 return bt_ctf_field_type_common_integer_set_is_signed((void *) ft,
3dca2276
PP
4610 is_signed);
4611}
4612
4613int bt_ctf_field_type_integer_set_size(struct bt_ctf_field_type *ft,
4614 unsigned int size)
4615{
16ca5ff0 4616 return bt_ctf_field_type_common_integer_set_size((void *) ft, size);
3dca2276
PP
4617}
4618
4619enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
4620 struct bt_ctf_field_type *ft)
4621{
16ca5ff0 4622 return (int) bt_ctf_field_type_common_integer_get_base((void *) ft);
3dca2276
PP
4623}
4624
4625int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *ft,
4626 enum bt_ctf_integer_base base)
4627{
16ca5ff0 4628 return bt_ctf_field_type_common_integer_set_base((void *) ft,
3dca2276
PP
4629 (int) base);
4630}
4631
4632enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
4633 struct bt_ctf_field_type *ft)
4634{
16ca5ff0 4635 return (int) bt_ctf_field_type_common_integer_get_encoding((void *) ft);
3dca2276
PP
4636}
4637
4638int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *ft,
4639 enum bt_ctf_string_encoding encoding)
4640{
16ca5ff0 4641 return bt_ctf_field_type_common_integer_set_encoding((void *) ft,
3dca2276
PP
4642 (int) encoding);
4643}
4644
4645struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
4646 struct bt_ctf_field_type *ft)
4647{
e1e02a22 4648 return bt_ctf_object_get_ref(bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
094ff7c0 4649 (void *) ft));
3dca2276
PP
4650}
4651
4652int bt_ctf_field_type_integer_set_mapped_clock_class(
4653 struct bt_ctf_field_type *ft,
4654 struct bt_ctf_clock_class *clock_class)
4655{
16ca5ff0
PP
4656 return bt_ctf_field_type_common_integer_set_mapped_clock_class((void *) ft,
4657 clock_class);
3dca2276
PP
4658}
4659
4660int bt_ctf_field_type_enumeration_signed_get_mapping_by_index(
4661 struct bt_ctf_field_type *ft, uint64_t index,
4662 const char **mapping_name, int64_t *range_begin,
4663 int64_t *range_end)
4664{
16ca5ff0 4665 return bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
3dca2276
PP
4666 (void *) ft, index, mapping_name, range_begin, range_end);
4667}
4668
4669int bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(
4670 struct bt_ctf_field_type *ft, uint64_t index,
4671 const char **mapping_name, uint64_t *range_begin,
4672 uint64_t *range_end)
4673{
16ca5ff0 4674 return bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
3dca2276
PP
4675 (void *) ft, index, mapping_name, range_begin, range_end);
4676}
4677
4678struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
4679 struct bt_ctf_field_type *container_ft)
4680{
16ca5ff0
PP
4681 struct bt_ctf_field_type_common_enumeration *enumeration = NULL;
4682 struct bt_ctf_field_type_common *int_ft = (void *) container_ft;
3dca2276
PP
4683
4684 BT_LOGD("Creating CTF writer enumeration field type object: int-ft-addr=%p",
4685 container_ft);
4686
4687 if (!container_ft) {
4688 BT_LOGW_STR("Invalid parameter: field type is NULL.");
4689 goto error;
4690 }
4691
16ca5ff0 4692 if (int_ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
3dca2276
PP
4693 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
4694 "container-ft-addr=%p, container-ft-id=%s",
16ca5ff0 4695 container_ft, bt_ctf_field_type_id_string(int_ft->id));
3dca2276
PP
4696 goto error;
4697 }
4698
16ca5ff0 4699 enumeration = g_new0(struct bt_ctf_field_type_common_enumeration, 1);
3dca2276
PP
4700 if (!enumeration) {
4701 BT_LOGE_STR("Failed to allocate one enumeration field type.");
4702 goto error;
4703 }
4704
16ca5ff0
PP
4705 bt_ctf_field_type_common_enumeration_initialize(BT_CTF_TO_COMMON(enumeration),
4706 int_ft, bt_ctf_field_type_common_enumeration_destroy_recursive,
3dca2276
PP
4707 &bt_ctf_field_type_enumeration_methods);
4708 enumeration->common.spec.writer.serialize_func =
4709 bt_ctf_field_type_enumeration_serialize_recursive;
4710 BT_LOGD("Created CTF writer enumeration field type object: addr=%p, "
4711 "int-ft-addr=%p, int-ft-size=%u",
4712 enumeration, container_ft,
4713 bt_ctf_field_type_integer_get_size(container_ft));
4714 goto end;
4715
4716error:
e1e02a22 4717 BT_CTF_OBJECT_PUT_REF_AND_RESET(enumeration);
3dca2276
PP
4718
4719end:
4720 return (void *) enumeration;
4721}
4722
4723struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_field_type(
4724 struct bt_ctf_field_type *ft)
4725{
e1e02a22 4726 return bt_ctf_object_get_ref(
16ca5ff0 4727 bt_ctf_field_type_common_enumeration_borrow_container_field_type(
094ff7c0 4728 (void *) ft));
3dca2276
PP
4729}
4730
4731int bt_ctf_field_type_enumeration_signed_add_mapping(
4732 struct bt_ctf_field_type *ft, const char *string,
4733 int64_t range_start, int64_t range_end)
4734{
16ca5ff0 4735 return bt_ctf_field_type_common_enumeration_signed_add_mapping(
3dca2276
PP
4736 (void *) ft, string, range_start, range_end);
4737}
4738
4739int bt_ctf_field_type_enumeration_unsigned_add_mapping(
4740 struct bt_ctf_field_type *ft, const char *string,
4741 uint64_t range_start, uint64_t range_end)
4742{
16ca5ff0 4743 return bt_ctf_field_type_common_enumeration_unsigned_add_mapping(
3dca2276
PP
4744 (void *) ft, string, range_start, range_end);
4745}
4746
4747int64_t bt_ctf_field_type_enumeration_get_mapping_count(
4748 struct bt_ctf_field_type *ft)
4749{
16ca5ff0 4750 return bt_ctf_field_type_common_enumeration_get_mapping_count((void *) ft);
3dca2276
PP
4751}
4752
4753struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
4754{
16ca5ff0
PP
4755 struct bt_ctf_field_type_common_floating_point *floating_point =
4756 g_new0(struct bt_ctf_field_type_common_floating_point, 1);
3dca2276
PP
4757
4758 BT_LOGD_STR("Creating CTF writer floating point number field type object.");
4759
4760 if (!floating_point) {
4761 BT_LOGE_STR("Failed to allocate one floating point number field type.");
4762 goto end;
4763 }
4764
16ca5ff0
PP
4765 bt_ctf_field_type_common_floating_point_initialize(
4766 BT_CTF_TO_COMMON(floating_point),
4767 bt_ctf_field_type_common_floating_point_destroy,
3dca2276
PP
4768 &bt_ctf_field_type_floating_point_methods);
4769 floating_point->common.spec.writer.serialize_func =
4770 bt_ctf_field_type_floating_point_serialize;
4771 BT_LOGD("Created CTF writer floating point number field type object: addr=%p, "
4772 "exp-size=%u, mant-size=%u", floating_point,
4773 floating_point->exp_dig, floating_point->mant_dig);
4774
4775end:
4776 return (void *) floating_point;
4777}
4778
4779int bt_ctf_field_type_floating_point_get_exponent_digits(
4780 struct bt_ctf_field_type *ft)
4781{
16ca5ff0 4782 return bt_ctf_field_type_common_floating_point_get_exponent_digits(
3dca2276
PP
4783 (void *) ft);
4784}
4785
4786int bt_ctf_field_type_floating_point_set_exponent_digits(
4787 struct bt_ctf_field_type *ft, unsigned int exponent_digits)
4788{
16ca5ff0 4789 return bt_ctf_field_type_common_floating_point_set_exponent_digits(
3dca2276
PP
4790 (void *) ft, exponent_digits);
4791}
4792
4793int bt_ctf_field_type_floating_point_get_mantissa_digits(
4794 struct bt_ctf_field_type *ft)
4795{
16ca5ff0 4796 return bt_ctf_field_type_common_floating_point_get_mantissa_digits(
3dca2276
PP
4797 (void *) ft);
4798}
4799
4800int bt_ctf_field_type_floating_point_set_mantissa_digits(
4801 struct bt_ctf_field_type *ft, unsigned int mantissa_digits)
4802{
16ca5ff0 4803 return bt_ctf_field_type_common_floating_point_set_mantissa_digits(
3dca2276
PP
4804 (void *) ft, mantissa_digits);
4805}
4806
4807struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
4808{
16ca5ff0
PP
4809 struct bt_ctf_field_type_common_structure *structure =
4810 g_new0(struct bt_ctf_field_type_common_structure, 1);
3dca2276
PP
4811
4812 BT_LOGD_STR("Creating CTF writer structure field type object.");
4813
4814 if (!structure) {
4815 BT_LOGE_STR("Failed to allocate one structure field type.");
4816 goto error;
4817 }
4818
16ca5ff0
PP
4819 bt_ctf_field_type_common_structure_initialize(BT_CTF_TO_COMMON(structure),
4820 bt_ctf_field_type_common_structure_destroy_recursive,
3dca2276
PP
4821 &bt_ctf_field_type_structure_methods);
4822 structure->common.spec.writer.serialize_func =
4823 bt_ctf_field_type_structure_serialize_recursive;
4824 BT_LOGD("Created CTF writer structure field type object: addr=%p",
4825 structure);
4826 goto end;
4827
4828error:
e1e02a22 4829 BT_CTF_OBJECT_PUT_REF_AND_RESET(structure);
3dca2276
PP
4830
4831end:
4832 return (void *) structure;
4833}
4834
4835int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *ft,
4836 struct bt_ctf_field_type *field_type,
4837 const char *field_name)
4838{
16ca5ff0 4839 return bt_ctf_field_type_common_structure_add_field((void *) ft,
3dca2276
PP
4840 (void *) field_type, field_name);
4841}
4842
4843int64_t bt_ctf_field_type_structure_get_field_count(struct bt_ctf_field_type *ft)
4844{
16ca5ff0 4845 return bt_ctf_field_type_common_structure_get_field_count((void *) ft);
3dca2276
PP
4846}
4847
4848int bt_ctf_field_type_structure_get_field_by_index(
4849 struct bt_ctf_field_type *ft,
4850 const char **field_name,
4851 struct bt_ctf_field_type **field_type, uint64_t index)
4852{
16ca5ff0 4853 int ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
3dca2276 4854 (void *) ft, field_name, (void *) field_type, index);
094ff7c0
PP
4855
4856 if (ret == 0 && field_type) {
e1e02a22 4857 bt_ctf_object_get_ref(*field_type);
094ff7c0
PP
4858 }
4859
4860 return ret;
3dca2276
PP
4861}
4862
4863struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
4864 struct bt_ctf_field_type *ft, const char *name)
4865{
e1e02a22 4866 return bt_ctf_object_get_ref(bt_ctf_field_type_common_structure_borrow_field_type_by_name(
094ff7c0 4867 (void *) ft, name));
3dca2276
PP
4868}
4869
4870struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
4871 struct bt_ctf_field_type *tag_ft, const char *tag_name)
4872{
16ca5ff0 4873 struct bt_ctf_field_type_common_variant *var_ft = NULL;
3dca2276
PP
4874
4875 BT_LOGD("Creating CTF writer variant field type object: "
4876 "tag-ft-addr=%p, tag-field-name=\"%s\"",
4877 tag_ft, tag_name);
4878
16ca5ff0 4879 if (tag_name && !bt_ctf_identifier_is_valid(tag_name)) {
3dca2276
PP
4880 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
4881 "tag-ft-addr=%p, tag-field-name=\"%s\"",
4882 tag_ft, tag_name);
4883 goto error;
4884 }
4885
16ca5ff0 4886 var_ft = g_new0(struct bt_ctf_field_type_common_variant, 1);
3dca2276
PP
4887 if (!var_ft) {
4888 BT_LOGE_STR("Failed to allocate one variant field type.");
4889 goto error;
4890 }
4891
16ca5ff0 4892 bt_ctf_field_type_common_variant_initialize(BT_CTF_TO_COMMON(var_ft),
3dca2276 4893 (void *) tag_ft, tag_name,
16ca5ff0 4894 bt_ctf_field_type_common_variant_destroy_recursive,
3dca2276
PP
4895 &bt_ctf_field_type_variant_methods);
4896 var_ft->common.spec.writer.serialize_func =
4897 bt_ctf_field_type_variant_serialize_recursive;
4898 BT_LOGD("Created CTF writer variant field type object: addr=%p, "
4899 "tag-ft-addr=%p, tag-field-name=\"%s\"",
4900 var_ft, tag_ft, tag_name);
4901 goto end;
4902
4903error:
e1e02a22 4904 BT_CTF_OBJECT_PUT_REF_AND_RESET(var_ft);
3dca2276
PP
4905
4906end:
4907 return (void *) var_ft;
4908}
4909
4910struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_field_type(
4911 struct bt_ctf_field_type *ft)
4912{
e1e02a22 4913 return bt_ctf_object_get_ref(bt_ctf_field_type_common_variant_borrow_tag_field_type(
094ff7c0 4914 (void *) ft));
3dca2276
PP
4915}
4916
4917const char *bt_ctf_field_type_variant_get_tag_name(struct bt_ctf_field_type *ft)
4918{
16ca5ff0 4919 return bt_ctf_field_type_common_variant_get_tag_name((void *) ft);
3dca2276
PP
4920}
4921
4922int bt_ctf_field_type_variant_set_tag_name(
4923 struct bt_ctf_field_type *ft, const char *name)
4924{
16ca5ff0 4925 return bt_ctf_field_type_common_variant_set_tag_name((void *) ft, name);
3dca2276
PP
4926}
4927
4928int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *ft,
4929 struct bt_ctf_field_type *field_type,
4930 const char *field_name)
4931{
16ca5ff0 4932 return bt_ctf_field_type_common_variant_add_field((void *) ft,
3dca2276
PP
4933 (void *) field_type, field_name);
4934}
4935
4936struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
4937 struct bt_ctf_field_type *ft,
4938 const char *field_name)
4939{
e1e02a22 4940 return bt_ctf_object_get_ref(bt_ctf_field_type_common_variant_borrow_field_type_by_name(
094ff7c0 4941 (void *) ft, field_name));
3dca2276
PP
4942}
4943
4944struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
4945 struct bt_ctf_field_type *ft,
4946 struct bt_ctf_field *tag_field)
4947{
312c056a
PP
4948 int ret;
4949 int64_t choice_index;
4950 struct bt_ctf_field *container;
16ca5ff0 4951 struct bt_ctf_field_type_common_variant *var_ft = (void *) ft;
312c056a
PP
4952 struct bt_ctf_field_type *ret_ft = NULL;
4953
67d2ce02
MJ
4954 BT_CTF_ASSERT_PRE_NON_NULL(ft, "Field type");
4955 BT_CTF_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
312c056a 4956 "Field type");
67d2ce02
MJ
4957 BT_CTF_ASSERT_PRE_NON_NULL(tag_field, "Tag field");
4958 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
16ca5ff0 4959 (struct bt_ctf_field_common *) tag_field,
312c056a 4960 BT_CTF_FIELD_TYPE_ID_ENUM, "Tag field");
67d2ce02 4961 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((struct bt_ctf_field_common *) tag_field,
312c056a
PP
4962 "Tag field");
4963
4964 container = bt_ctf_field_enumeration_borrow_container(tag_field);
98b15851 4965 BT_ASSERT_DBG(container);
312c056a
PP
4966
4967 if (var_ft->tag_ft->container_ft->is_signed) {
4968 int64_t val;
4969
4970 ret = bt_ctf_field_integer_signed_get_value(container,
4971 &val);
98b15851 4972 BT_ASSERT_DBG(ret == 0);
16ca5ff0 4973 choice_index = bt_ctf_field_type_common_variant_find_choice_index(
312c056a
PP
4974 (void *) ft, (uint64_t) val, true);
4975 } else {
4976 uint64_t val;
4977
4978 ret = bt_ctf_field_integer_unsigned_get_value(container,
4979 &val);
98b15851 4980 BT_ASSERT_DBG(ret == 0);
16ca5ff0 4981 choice_index = bt_ctf_field_type_common_variant_find_choice_index(
312c056a
PP
4982 (void *) ft, val, false);
4983 }
4984
4985 if (choice_index < 0) {
67d2ce02 4986 BT_LOGW("Cannot find variant field type's field: "
16ca5ff0 4987 "var-ft-addr=%p, tag-field-addr=%p", ft, tag_field);
312c056a
PP
4988 goto end;
4989 }
4990
4991 ret = bt_ctf_field_type_variant_get_field_by_index(ft, NULL,
4992 &ret_ft, choice_index);
98b15851 4993 BT_ASSERT_DBG(ret == 0);
312c056a
PP
4994
4995end:
4996 return ret_ft;
3dca2276
PP
4997}
4998
4999int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *ft)
5000{
16ca5ff0 5001 return bt_ctf_field_type_common_variant_get_field_count((void *) ft);
3dca2276
PP
5002}
5003
5004int bt_ctf_field_type_variant_get_field_by_index(struct bt_ctf_field_type *ft,
5005 const char **field_name, struct bt_ctf_field_type **field_type,
5006 uint64_t index)
5007{
16ca5ff0 5008 int ret = bt_ctf_field_type_common_variant_borrow_field_by_index(
094ff7c0
PP
5009 (void *) ft, field_name, (void *) field_type, index);
5010
5011 if (ret == 0 && field_type) {
e1e02a22 5012 bt_ctf_object_get_ref(*field_type);
094ff7c0
PP
5013 }
5014
5015 return ret;
3dca2276
PP
5016}
5017
5018struct bt_ctf_field_type *bt_ctf_field_type_array_create(
5019 struct bt_ctf_field_type *element_ft, unsigned int length)
5020{
16ca5ff0 5021 struct bt_ctf_field_type_common_array *array = NULL;
3dca2276
PP
5022
5023 BT_LOGD("Creating CTF writer array field type object: element-ft-addr=%p, "
5024 "length=%u", element_ft, length);
5025
5026 if (!element_ft) {
5027 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
5028 goto error;
5029 }
5030
5031 if (length == 0) {
5032 BT_LOGW_STR("Invalid parameter: length is zero.");
5033 goto error;
5034 }
5035
16ca5ff0 5036 array = g_new0(struct bt_ctf_field_type_common_array, 1);
3dca2276
PP
5037 if (!array) {
5038 BT_LOGE_STR("Failed to allocate one array field type.");
5039 goto error;
5040 }
5041
16ca5ff0 5042 bt_ctf_field_type_common_array_initialize(BT_CTF_TO_COMMON(array),
3dca2276 5043 (void *) element_ft, length,
16ca5ff0 5044 bt_ctf_field_type_common_array_destroy_recursive,
3dca2276
PP
5045 &bt_ctf_field_type_array_methods);
5046 array->common.spec.writer.serialize_func =
5047 bt_ctf_field_type_array_serialize_recursive;
5048 BT_LOGD("Created CTF writer array field type object: addr=%p, "
5049 "element-ft-addr=%p, length=%u",
5050 array, element_ft, length);
5051 goto end;
5052
5053error:
e1e02a22 5054 BT_CTF_OBJECT_PUT_REF_AND_RESET(array);
3dca2276
PP
5055
5056end:
5057 return (void *) array;
5058}
5059
5060struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_field_type(
5061 struct bt_ctf_field_type *ft)
5062{
e1e02a22 5063 return bt_ctf_object_get_ref(bt_ctf_field_type_common_array_borrow_element_field_type(
094ff7c0 5064 (void *) ft));
3dca2276
PP
5065}
5066
5067int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *ft)
5068{
16ca5ff0 5069 return bt_ctf_field_type_common_array_get_length((void *) ft);
3dca2276
PP
5070}
5071
5072struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
5073 struct bt_ctf_field_type *element_ft,
5074 const char *length_field_name)
5075{
16ca5ff0 5076 struct bt_ctf_field_type_common_sequence *sequence = NULL;
3dca2276
PP
5077
5078 BT_LOGD("Creating CTF writer sequence field type object: element-ft-addr=%p, "
5079 "length-field-name=\"%s\"", element_ft, length_field_name);
5080
5081 if (!element_ft) {
5082 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
5083 goto error;
5084 }
5085
16ca5ff0 5086 if (!bt_ctf_identifier_is_valid(length_field_name)) {
3dca2276
PP
5087 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
5088 "length-field-name=\"%s\"", length_field_name);
5089 goto error;
5090 }
5091
16ca5ff0 5092 sequence = g_new0(struct bt_ctf_field_type_common_sequence, 1);
3dca2276
PP
5093 if (!sequence) {
5094 BT_LOGE_STR("Failed to allocate one sequence field type.");
5095 goto error;
5096 }
5097
16ca5ff0 5098 bt_ctf_field_type_common_sequence_initialize(BT_CTF_TO_COMMON(sequence),
3dca2276 5099 (void *) element_ft, length_field_name,
16ca5ff0 5100 bt_ctf_field_type_common_sequence_destroy_recursive,
3dca2276
PP
5101 &bt_ctf_field_type_sequence_methods);
5102 sequence->common.spec.writer.serialize_func =
5103 bt_ctf_field_type_sequence_serialize_recursive;
5104 BT_LOGD("Created CTF writer sequence field type object: addr=%p, "
5105 "element-ft-addr=%p, length-field-name=\"%s\"",
5106 sequence, element_ft, length_field_name);
5107 goto end;
5108
5109error:
e1e02a22 5110 BT_CTF_OBJECT_PUT_REF_AND_RESET(sequence);
3dca2276
PP
5111
5112end:
5113 return (void *) sequence;
5114}
5115
5116struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_field_type(
5117 struct bt_ctf_field_type *ft)
5118{
e1e02a22 5119 return bt_ctf_object_get_ref(bt_ctf_field_type_common_sequence_borrow_element_field_type(
094ff7c0 5120 (void *) ft));
3dca2276
PP
5121}
5122
5123const char *bt_ctf_field_type_sequence_get_length_field_name(
5124 struct bt_ctf_field_type *ft)
5125{
16ca5ff0 5126 return bt_ctf_field_type_common_sequence_get_length_field_name((void *) ft);
3dca2276
PP
5127}
5128
5129struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
5130{
16ca5ff0
PP
5131 struct bt_ctf_field_type_common_string *string =
5132 g_new0(struct bt_ctf_field_type_common_string, 1);
3dca2276
PP
5133
5134 BT_LOGD_STR("Creating CTF writer string field type object.");
5135
5136 if (!string) {
5137 BT_LOGE_STR("Failed to allocate one string field type.");
5138 return NULL;
5139 }
5140
16ca5ff0
PP
5141 bt_ctf_field_type_common_string_initialize(BT_CTF_TO_COMMON(string),
5142 bt_ctf_field_type_common_string_destroy,
3dca2276
PP
5143 &bt_ctf_field_type_string_methods);
5144 string->common.spec.writer.serialize_func =
5145 bt_ctf_field_type_string_serialize;
5146 BT_LOGD("Created CTF writer string field type object: addr=%p", string);
5147 return (void *) string;
5148}
5149
5150enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
5151 struct bt_ctf_field_type *ft)
5152{
16ca5ff0 5153 return (int) bt_ctf_field_type_common_string_get_encoding((void *) ft);
3dca2276
PP
5154}
5155
5156int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *ft,
5157 enum bt_ctf_string_encoding encoding)
5158{
16ca5ff0 5159 return bt_ctf_field_type_common_string_set_encoding((void *) ft,
3dca2276
PP
5160 (int) encoding);
5161}
5162
5163int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *ft)
5164{
16ca5ff0 5165 return bt_ctf_field_type_common_get_alignment((void *) ft);
3dca2276
PP
5166}
5167
5168int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *ft,
5169 unsigned int alignment)
5170{
16ca5ff0 5171 return bt_ctf_field_type_common_set_alignment((void *) ft, alignment);
3dca2276
PP
5172}
5173
5174enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
5175 struct bt_ctf_field_type *ft)
5176{
16ca5ff0 5177 return (int) bt_ctf_field_type_common_get_byte_order((void *) ft);
3dca2276
PP
5178}
5179
5180int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *ft,
5181 enum bt_ctf_byte_order byte_order)
5182{
16ca5ff0 5183 return bt_ctf_field_type_common_set_byte_order((void *) ft,
3dca2276
PP
5184 (int) byte_order);
5185}
5186
5187enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
5188 struct bt_ctf_field_type *ft)
5189{
16ca5ff0 5190 return (int) bt_ctf_field_type_common_get_type_id((void *) ft);
3dca2276
PP
5191}
5192
5193BT_HIDDEN
5194struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *ft)
5195{
16ca5ff0 5196 return (void *) bt_ctf_field_type_common_copy((void *) ft);
3dca2276
PP
5197}
5198
5199static
5200struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
5201 struct bt_ctf_field_type *ft)
5202{
16ca5ff0
PP
5203 struct bt_ctf_field_type_common_integer *int_ft = (void *) ft;
5204 struct bt_ctf_field_type_common_integer *copy_ft;
3dca2276
PP
5205
5206 BT_LOGD("Copying CTF writer integer field type's: addr=%p", ft);
5207 copy_ft = (void *) bt_ctf_field_type_integer_create(int_ft->size);
5208 if (!copy_ft) {
5209 BT_LOGE_STR("Cannot create CTF writer integer field type.");
5210 goto end;
5211 }
5212
e1e02a22 5213 copy_ft->mapped_clock_class = bt_ctf_object_get_ref(int_ft->mapped_clock_class);
3dca2276
PP
5214 copy_ft->user_byte_order = int_ft->user_byte_order;
5215 copy_ft->is_signed = int_ft->is_signed;
5216 copy_ft->size = int_ft->size;
5217 copy_ft->base = int_ft->base;
5218 copy_ft->encoding = int_ft->encoding;
5219 BT_LOGD("Copied CTF writer integer field type: original-ft-addr=%p, copy-ft-addr=%p",
5220 ft, copy_ft);
5221
5222end:
5223 return (void *) copy_ft;
5224}
5225
5226static
5227struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy_recursive(
5228 struct bt_ctf_field_type *ft)
5229{
5230 size_t i;
16ca5ff0
PP
5231 struct bt_ctf_field_type_common_enumeration *enum_ft = (void *) ft;
5232 struct bt_ctf_field_type_common_enumeration *copy_ft = NULL;
5233 struct bt_ctf_field_type_common_enumeration *container_copy_ft;
3dca2276
PP
5234
5235 BT_LOGD("Copying CTF writer enumeration field type's: addr=%p", ft);
5236
5237 /* Copy the source enumeration's container */
5238 BT_LOGD_STR("Copying CTF writer enumeration field type's container field type.");
16ca5ff0
PP
5239 container_copy_ft = BT_CTF_FROM_COMMON(bt_ctf_field_type_common_copy(
5240 BT_CTF_TO_COMMON(enum_ft->container_ft)));
3dca2276
PP
5241 if (!container_copy_ft) {
5242 BT_LOGE_STR("Cannot copy CTF writer enumeration field type's container field type.");
5243 goto end;
5244 }
5245
5246 copy_ft = (void *) bt_ctf_field_type_enumeration_create(
5247 (void *) container_copy_ft);
5248 if (!copy_ft) {
5249 BT_LOGE_STR("Cannot create CTF writer enumeration field type.");
5250 goto end;
5251 }
5252
5253 /* Copy all enumaration entries */
5254 for (i = 0; i < enum_ft->entries->len; i++) {
16ca5ff0 5255 struct bt_ctf_enumeration_mapping *mapping = g_ptr_array_index(
3dca2276 5256 enum_ft->entries, i);
16ca5ff0
PP
5257 struct bt_ctf_enumeration_mapping *copy_mapping = g_new0(
5258 struct bt_ctf_enumeration_mapping, 1);
3dca2276
PP
5259
5260 if (!copy_mapping) {
5261 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
5262 goto error;
5263 }
5264
5265 *copy_mapping = *mapping;
5266 g_ptr_array_add(copy_ft->entries, copy_mapping);
5267 }
5268
5269 BT_LOGD("Copied CTF writer enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
5270 ft, copy_ft);
5271
5272end:
e1e02a22 5273 bt_ctf_object_put_ref(container_copy_ft);
3dca2276
PP
5274 return (void *) copy_ft;
5275
5276error:
e1e02a22
PP
5277 bt_ctf_object_put_ref(container_copy_ft);
5278 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_ft);
3dca2276
PP
5279 return (void *) copy_ft;
5280}
5281
5282static
5283struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
5284 struct bt_ctf_field_type *ft)
5285{
16ca5ff0
PP
5286 struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
5287 struct bt_ctf_field_type_common_floating_point *copy_ft;
3dca2276
PP
5288
5289 BT_LOGD("Copying CTF writer floating point number field type's: addr=%p", ft);
5290 copy_ft = (void *) bt_ctf_field_type_floating_point_create();
5291 if (!copy_ft) {
5292 BT_LOGE_STR("Cannot create CTF writer floating point number field type.");
5293 goto end;
5294 }
5295
5296 copy_ft->user_byte_order = flt_ft->user_byte_order;
5297 copy_ft->exp_dig = flt_ft->exp_dig;
5298 copy_ft->mant_dig = flt_ft->mant_dig;
5299 BT_LOGD("Copied CTF writer floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
5300 ft, copy_ft);
5301
5302end:
5303 return (void *) copy_ft;
5304}
5305
5306static
5307struct bt_ctf_field_type *bt_ctf_field_type_structure_copy_recursive(
5308 struct bt_ctf_field_type *ft)
5309{
5310 int64_t i;
5311 GHashTableIter iter;
5312 gpointer key, value;
16ca5ff0
PP
5313 struct bt_ctf_field_type_common_structure *struct_ft = (void *) ft;
5314 struct bt_ctf_field_type_common_structure *copy_ft;
3dca2276
PP
5315
5316 BT_LOGD("Copying CTF writer structure field type's: addr=%p", ft);
5317 copy_ft = (void *) bt_ctf_field_type_structure_create();
5318 if (!copy_ft) {
5319 BT_LOGE_STR("Cannot create CTF writer structure field type.");
5320 goto end;
5321 }
5322
5323 /* Copy field_name_to_index */
5324 g_hash_table_iter_init(&iter, struct_ft->field_name_to_index);
5325 while (g_hash_table_iter_next(&iter, &key, &value)) {
5326 g_hash_table_insert(copy_ft->field_name_to_index,
5327 key, value);
5328 }
5329
312c056a
PP
5330 g_array_set_size(copy_ft->fields, struct_ft->fields->len);
5331
3dca2276 5332 for (i = 0; i < struct_ft->fields->len; i++) {
16ca5ff0
PP
5333 struct bt_ctf_field_type_common_structure_field *entry, *copy_entry;
5334 struct bt_ctf_field_type_common *field_ft_copy;
3dca2276 5335
16ca5ff0 5336 entry = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
312c056a 5337 struct_ft, i);
16ca5ff0 5338 copy_entry = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
312c056a 5339 copy_ft, i);
3dca2276
PP
5340 BT_LOGD("Copying CTF writer structure field type's field: "
5341 "index=%" PRId64 ", "
5342 "field-ft-addr=%p, field-name=\"%s\"",
5343 i, entry, g_quark_to_string(entry->name));
3dca2276
PP
5344
5345 field_ft_copy = (void *) bt_ctf_field_type_copy(
5346 (void *) entry->type);
5347 if (!field_ft_copy) {
5348 BT_LOGE("Cannot copy CTF writer structure field type's field: "
5349 "index=%" PRId64 ", "
5350 "field-ft-addr=%p, field-name=\"%s\"",
5351 i, entry, g_quark_to_string(entry->name));
3dca2276
PP
5352 goto error;
5353 }
5354
5355 copy_entry->name = entry->name;
5356 copy_entry->type = field_ft_copy;
3dca2276
PP
5357 }
5358
5359 BT_LOGD("Copied CTF writer structure field type: original-ft-addr=%p, copy-ft-addr=%p",
5360 ft, copy_ft);
5361
5362end:
5363 return (void *) copy_ft;
5364
5365error:
e1e02a22 5366 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_ft);
3dca2276
PP
5367 return NULL;
5368}
5369
5370static
5371struct bt_ctf_field_type *bt_ctf_field_type_variant_copy_recursive(
5372 struct bt_ctf_field_type *ft)
5373{
5374 int64_t i;
5375 GHashTableIter iter;
5376 gpointer key, value;
16ca5ff0
PP
5377 struct bt_ctf_field_type_common *tag_ft_copy = NULL;
5378 struct bt_ctf_field_type_common_variant *var_ft = (void *) ft;
5379 struct bt_ctf_field_type_common_variant *copy_ft = NULL;
3dca2276
PP
5380
5381 BT_LOGD("Copying CTF writer variant field type's: addr=%p", ft);
5382 if (var_ft->tag_ft) {
5383 BT_LOGD_STR("Copying CTF writer variant field type's tag field type.");
16ca5ff0
PP
5384 tag_ft_copy = bt_ctf_field_type_common_copy(
5385 BT_CTF_TO_COMMON(var_ft->tag_ft));
3dca2276
PP
5386 if (!tag_ft_copy) {
5387 BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field type.");
5388 goto end;
5389 }
5390 }
5391
5392 copy_ft = (void *) bt_ctf_field_type_variant_create(
5393 (void *) tag_ft_copy,
5394 var_ft->tag_name->len ? var_ft->tag_name->str : NULL);
5395 if (!copy_ft) {
5396 BT_LOGE_STR("Cannot create CTF writer variant field type.");
5397 goto end;
5398 }
5399
5400 /* Copy field_name_to_index */
312c056a 5401 g_hash_table_iter_init(&iter, var_ft->choice_name_to_index);
3dca2276 5402 while (g_hash_table_iter_next(&iter, &key, &value)) {
312c056a 5403 g_hash_table_insert(copy_ft->choice_name_to_index,
3dca2276
PP
5404 key, value);
5405 }
5406
312c056a
PP
5407 g_array_set_size(copy_ft->choices, var_ft->choices->len);
5408
5409 for (i = 0; i < var_ft->choices->len; i++) {
16ca5ff0
PP
5410 struct bt_ctf_field_type_common_variant_choice *entry, *copy_entry;
5411 struct bt_ctf_field_type_common *field_ft_copy;
312c056a 5412 uint64_t range_i;
3dca2276 5413
16ca5ff0
PP
5414 entry = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, i);
5415 copy_entry = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
312c056a 5416 copy_ft, i);
3dca2276
PP
5417 BT_LOGD("Copying CTF writer variant field type's field: "
5418 "index=%" PRId64 ", "
5419 "field-ft-addr=%p, field-name=\"%s\"",
5420 i, entry, g_quark_to_string(entry->name));
3dca2276
PP
5421
5422 field_ft_copy = (void *) bt_ctf_field_type_copy(
5423 (void *) entry->type);
5424 if (!field_ft_copy) {
5425 BT_LOGE("Cannot copy CTF writer variant field type's field: "
5426 "index=%" PRId64 ", "
5427 "field-ft-addr=%p, field-name=\"%s\"",
5428 i, entry, g_quark_to_string(entry->name));
5429 g_free(copy_entry);
5430 goto error;
5431 }
5432
5433 copy_entry->name = entry->name;
5434 copy_entry->type = field_ft_copy;
312c056a
PP
5435
5436 /* Copy ranges */
5437 copy_entry->ranges = g_array_new(FALSE, TRUE,
16ca5ff0 5438 sizeof(struct bt_ctf_field_type_common_variant_choice_range));
98b15851 5439 BT_ASSERT_DBG(copy_entry->ranges);
312c056a
PP
5440 g_array_set_size(copy_entry->ranges, entry->ranges->len);
5441
5442 for (range_i = 0; range_i < entry->ranges->len; range_i++) {
5443 copy_entry->ranges[range_i] = entry->ranges[range_i];
5444 }
3dca2276
PP
5445 }
5446
5447 if (var_ft->tag_field_path) {
5448 BT_LOGD_STR("Copying CTF writer variant field type's tag field path.");
16ca5ff0 5449 copy_ft->tag_field_path = bt_ctf_field_path_copy(
3dca2276
PP
5450 var_ft->tag_field_path);
5451 if (!copy_ft->tag_field_path) {
5452 BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field path.");
5453 goto error;
5454 }
5455 }
5456
312c056a
PP
5457 copy_ft->choices_up_to_date = var_ft->choices_up_to_date;
5458 BT_LOGD("Copied CTF writer variant field type: original-ft-addr=%p, copy-ft-addr=%p",
3dca2276
PP
5459 ft, copy_ft);
5460
5461end:
e1e02a22 5462 bt_ctf_object_put_ref(tag_ft_copy);
3dca2276
PP
5463 return (void *) copy_ft;
5464
5465error:
e1e02a22
PP
5466 bt_ctf_object_put_ref(tag_ft_copy);
5467 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_ft);
3dca2276
PP
5468 return NULL;
5469}
5470
5471static
5472struct bt_ctf_field_type *bt_ctf_field_type_array_copy_recursive(
5473 struct bt_ctf_field_type *ft)
5474{
16ca5ff0
PP
5475 struct bt_ctf_field_type_common *container_ft_copy = NULL;
5476 struct bt_ctf_field_type_common_array *array_ft = (void *) ft;
5477 struct bt_ctf_field_type_common_array *copy_ft = NULL;
3dca2276
PP
5478
5479 BT_LOGD("Copying CTF writer array field type's: addr=%p", ft);
5480 BT_LOGD_STR("Copying CTF writer array field type's element field type.");
16ca5ff0 5481 container_ft_copy = bt_ctf_field_type_common_copy(array_ft->element_ft);
3dca2276
PP
5482 if (!container_ft_copy) {
5483 BT_LOGE_STR("Cannot copy CTF writer array field type's element field type.");
5484 goto end;
5485 }
5486
5487 copy_ft = (void *) bt_ctf_field_type_array_create(
5488 (void *) container_ft_copy, array_ft->length);
5489 if (!copy_ft) {
5490 BT_LOGE_STR("Cannot create CTF writer array field type.");
5491 goto end;
5492 }
5493
5494 BT_LOGD("Copied CTF writer array field type: original-ft-addr=%p, copy-ft-addr=%p",
5495 ft, copy_ft);
5496
5497end:
e1e02a22 5498 bt_ctf_object_put_ref(container_ft_copy);
3dca2276
PP
5499 return (void *) copy_ft;
5500}
5501
5502static
5503struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy_recursive(
5504 struct bt_ctf_field_type *ft)
5505{
16ca5ff0
PP
5506 struct bt_ctf_field_type_common *container_ft_copy = NULL;
5507 struct bt_ctf_field_type_common_sequence *seq_ft = (void *) ft;
5508 struct bt_ctf_field_type_common_sequence *copy_ft = NULL;
3dca2276
PP
5509
5510 BT_LOGD("Copying CTF writer sequence field type's: addr=%p", ft);
5511 BT_LOGD_STR("Copying CTF writer sequence field type's element field type.");
16ca5ff0 5512 container_ft_copy = bt_ctf_field_type_common_copy(seq_ft->element_ft);
3dca2276
PP
5513 if (!container_ft_copy) {
5514 BT_LOGE_STR("Cannot copy CTF writer sequence field type's element field type.");
5515 goto end;
5516 }
5517
5518 copy_ft = (void *) bt_ctf_field_type_sequence_create(
5519 (void *) container_ft_copy,
5520 seq_ft->length_field_name->len ?
5521 seq_ft->length_field_name->str : NULL);
5522 if (!copy_ft) {
5523 BT_LOGE_STR("Cannot create CTF writer sequence field type.");
5524 goto end;
5525 }
5526
5527 if (seq_ft->length_field_path) {
5528 BT_LOGD_STR("Copying CTF writer sequence field type's length field path.");
16ca5ff0 5529 copy_ft->length_field_path = bt_ctf_field_path_copy(
3dca2276
PP
5530 seq_ft->length_field_path);
5531 if (!copy_ft->length_field_path) {
5532 BT_LOGE_STR("Cannot copy CTF writer sequence field type's length field path.");
5533 goto error;
5534 }
5535 }
5536
5537 BT_LOGD("Copied CTF writer sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
5538 ft, copy_ft);
5539
5540end:
e1e02a22 5541 bt_ctf_object_put_ref(container_ft_copy);
3dca2276
PP
5542 return (void *) copy_ft;
5543error:
e1e02a22
PP
5544 bt_ctf_object_put_ref(container_ft_copy);
5545 BT_CTF_OBJECT_PUT_REF_AND_RESET(copy_ft);
3dca2276
PP
5546 return NULL;
5547}
5548
5549static
5550struct bt_ctf_field_type *bt_ctf_field_type_string_copy(struct bt_ctf_field_type *ft)
5551{
16ca5ff0
PP
5552 struct bt_ctf_field_type_common_string *string_ft = (void *) ft;
5553 struct bt_ctf_field_type_common_string *copy_ft = NULL;
3dca2276
PP
5554
5555 BT_LOGD("Copying CTF writer string field type's: addr=%p", ft);
5556 copy_ft = (void *) bt_ctf_field_type_string_create();
5557 if (!copy_ft) {
5558 BT_LOGE_STR("Cannot create CTF writer string field type.");
5559 goto end;
5560 }
5561
5562 copy_ft->encoding = string_ft->encoding;
5563 BT_LOGD("Copied CTF writer string field type: original-ft-addr=%p, copy-ft-addr=%p",
5564 ft, copy_ft);
5565
5566end:
5567 return (void *) copy_ft;
5568}
This page took 0.373511 seconds and 4 git commands to generate.