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