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