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