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