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