Hide new bt_ctf_field_type_* symbols
[babeltrace.git] / formats / ctf / ir / field-types.c
CommitLineData
1c822dfb
JG
1/*
2 * field-types.c
3 *
4 * Babeltrace CTF IR - Event Types
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <babeltrace/ctf-ir/field-types-internal.h>
30#include <babeltrace/ctf-ir/field-path-internal.h>
31#include <babeltrace/ctf-ir/utils.h>
32#include <babeltrace/ref.h>
33#include <babeltrace/ctf-ir/clock.h>
34#include <babeltrace/ctf-ir/clock-internal.h>
35#include <babeltrace/ctf-writer/writer-internal.h>
36#include <babeltrace/object-internal.h>
37#include <babeltrace/ref.h>
38#include <babeltrace/compiler.h>
39#include <babeltrace/endian.h>
40#include <float.h>
41#include <inttypes.h>
42#include <stdlib.h>
43
44struct range_overlap_query {
45 union {
46 uint64_t _unsigned;
47 int64_t _signed;
48 } range_start;
49
50 union {
51 uint64_t _unsigned;
52 int64_t _signed;
53 } range_end;
54 int overlaps;
55 GQuark mapping_name;
56};
57
58static
59void bt_ctf_field_type_destroy(struct bt_object *);
60static
61void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
62static
63void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
64static
65void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
66static
67void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
68static
69void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
70static
71void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
72static
73void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
74static
75void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
76
77static
78void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
79 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_destroy,
80 [BT_CTF_TYPE_ID_ENUM] =
81 bt_ctf_field_type_enumeration_destroy,
82 [BT_CTF_TYPE_ID_FLOAT] =
83 bt_ctf_field_type_floating_point_destroy,
84 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_destroy,
85 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_destroy,
86 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_destroy,
87 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
88 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_destroy,
89};
90
91static
92void generic_field_type_freeze(struct bt_ctf_field_type *);
93static
94void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
95static
96void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
97static
98void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
99static
100void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
101static
102void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
103static
104void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
105
106static
107type_freeze_func const type_freeze_funcs[] = {
108 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_freeze,
109 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_freeze,
110 [BT_CTF_TYPE_ID_FLOAT] = generic_field_type_freeze,
111 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_freeze,
112 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_freeze,
113 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_freeze,
114 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
115 [BT_CTF_TYPE_ID_STRING] = generic_field_type_freeze,
116};
117
118static
119int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
120 struct metadata_context *);
121static
122int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
123 struct metadata_context *);
124static
125int bt_ctf_field_type_floating_point_serialize(
126 struct bt_ctf_field_type *, struct metadata_context *);
127static
128int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
129 struct metadata_context *);
130static
131int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
132 struct metadata_context *);
133static
134int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
135 struct metadata_context *);
136static
137int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
138 struct metadata_context *);
139static
140int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
141 struct metadata_context *);
142
143static
144type_serialize_func const type_serialize_funcs[] = {
145 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_serialize,
146 [BT_CTF_TYPE_ID_ENUM] =
147 bt_ctf_field_type_enumeration_serialize,
148 [BT_CTF_TYPE_ID_FLOAT] =
149 bt_ctf_field_type_floating_point_serialize,
150 [BT_CTF_TYPE_ID_STRUCT] =
151 bt_ctf_field_type_structure_serialize,
152 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_serialize,
153 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_serialize,
154 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
155 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_serialize,
156};
157
158static
159void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
160 int byte_order, int set_native);
161static
162void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
163 int byte_order, int set_native);
164static
165void bt_ctf_field_type_floating_point_set_byte_order(
166 struct bt_ctf_field_type *, int byte_order, int set_native);
167static
168void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
169 int byte_order, int set_native);
170static
171void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
172 int byte_order, int set_native);
173static
174void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
175 int byte_order, int set_native);
176static
177void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
178 int byte_order, int set_native);
179
180/* The set_native flag only set the byte order if it is set to native */
181static
182void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
183 int byte_order, int set_native) = {
184 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
185 [BT_CTF_TYPE_ID_ENUM] =
186 bt_ctf_field_type_enumeration_set_byte_order,
187 [BT_CTF_TYPE_ID_FLOAT] =
188 bt_ctf_field_type_floating_point_set_byte_order,
189 [BT_CTF_TYPE_ID_STRUCT] =
190 bt_ctf_field_type_structure_set_byte_order,
191 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
192 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_set_byte_order,
193 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
194 [BT_CTF_TYPE_ID_STRING] = NULL,
195};
196
197static
198struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
199 struct bt_ctf_field_type *);
200static
201struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
202 struct bt_ctf_field_type *);
203static
204struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
205 struct bt_ctf_field_type *);
206static
207struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
208 struct bt_ctf_field_type *);
209static
210struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
211 struct bt_ctf_field_type *);
212static
213struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
214 struct bt_ctf_field_type *);
215static
216struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
217 struct bt_ctf_field_type *);
218static
219struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
220 struct bt_ctf_field_type *);
221
222static
223struct bt_ctf_field_type *(* const type_copy_funcs[])(
224 struct bt_ctf_field_type *) = {
225 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_copy,
226 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_copy,
227 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_copy,
228 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_copy,
229 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_copy,
230 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_copy,
231 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_copy,
232 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_copy,
233};
234
235static
236int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
237 struct bt_ctf_field_type *);
238static
239int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
240 struct bt_ctf_field_type *);
241static
242int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
243 struct bt_ctf_field_type *);
244static
245int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
246 struct bt_ctf_field_type *);
247static
248int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
249 struct bt_ctf_field_type *);
250static
251int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
252 struct bt_ctf_field_type *);
253static
254int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
255 struct bt_ctf_field_type *);
256static
257int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
258 struct bt_ctf_field_type *);
259
260static
261int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
262 struct bt_ctf_field_type *) = {
263 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_compare,
264 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_compare,
265 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_compare,
266 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_compare,
267 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_compare,
268 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_compare,
269 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_compare,
270 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_compare,
271};
272
273static
274int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *);
275static
276int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
277static
278int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
279static
280int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
281static
282int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
283static
284int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
285
286static
287int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
288 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_validate,
289 [BT_CTF_TYPE_ID_FLOAT] = NULL,
290 [BT_CTF_TYPE_ID_STRING] = NULL,
291 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_validate,
292 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_validate,
293 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_validate,
294 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_validate,
295 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_validate,
296};
297
298static
299void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
300{
301 g_free(mapping);
302}
303
304static
305void destroy_structure_field(struct structure_field *field)
306{
307 bt_put(field->type);
308 g_free(field);
309}
310
311static
312void check_ranges_overlap(gpointer element, gpointer query)
313{
314 struct enumeration_mapping *mapping = element;
315 struct range_overlap_query *overlap_query = query;
316
317 if (mapping->range_start._signed <= overlap_query->range_end._signed
318 && overlap_query->range_start._signed <=
319 mapping->range_end._signed) {
320 overlap_query->overlaps = 1;
321 overlap_query->mapping_name = mapping->string;
322 }
323
324 overlap_query->overlaps |=
325 mapping->string == overlap_query->mapping_name;
326}
327
328static
329void check_ranges_overlap_unsigned(gpointer element, gpointer query)
330{
331 struct enumeration_mapping *mapping = element;
332 struct range_overlap_query *overlap_query = query;
333
334 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
335 && overlap_query->range_start._unsigned <=
336 mapping->range_end._unsigned) {
337 overlap_query->overlaps = 1;
338 overlap_query->mapping_name = mapping->string;
339 }
340
341 overlap_query->overlaps |=
342 mapping->string == overlap_query->mapping_name;
343}
344
345static
346gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
347 struct enumeration_mapping **b)
348{
349 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
350}
351
352static
353gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
354 struct enumeration_mapping **b)
355{
356 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
357}
358
359static
360void bt_ctf_field_type_init(struct bt_ctf_field_type *type, int init_bo)
361{
362 enum bt_ctf_type_id type_id = type->declaration->id;
363
364 assert(type && (type_id > BT_CTF_TYPE_ID_UNKNOWN) &&
365 (type_id < BT_CTF_NR_TYPE_IDS));
366
367 bt_object_init(type, bt_ctf_field_type_destroy);
368 type->freeze = type_freeze_funcs[type_id];
369 type->serialize = type_serialize_funcs[type_id];
370
371 if (init_bo) {
372 int ret = bt_ctf_field_type_set_byte_order(type,
373 BT_CTF_BYTE_ORDER_NATIVE);
374 assert(!ret);
375 }
376
377 type->declaration->alignment = 1;
378}
379
380static
381int add_structure_field(GPtrArray *fields,
382 GHashTable *field_name_to_index,
383 struct bt_ctf_field_type *field_type,
384 const char *field_name)
385{
386 int ret = 0;
387 GQuark name_quark = g_quark_from_string(field_name);
388 struct structure_field *field;
389
390 /* Make sure structure does not contain a field of the same name */
391 if (g_hash_table_lookup_extended(field_name_to_index,
392 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
393 ret = -1;
394 goto end;
395 }
396
397 field = g_new0(struct structure_field, 1);
398 if (!field) {
399 ret = -1;
400 goto end;
401 }
402
403 bt_get(field_type);
404 field->name = name_quark;
405 field->type = field_type;
406 g_hash_table_insert(field_name_to_index,
407 (gpointer) (unsigned long) name_quark,
408 (gpointer) (unsigned long) fields->len);
409 g_ptr_array_add(fields, field);
410end:
411 return ret;
412}
413
414static
415void bt_ctf_field_type_destroy(struct bt_object *obj)
416{
417 struct bt_ctf_field_type *type;
418 enum bt_ctf_type_id type_id;
419
420 type = container_of(obj, struct bt_ctf_field_type, base);
421 type_id = type->declaration->id;
422 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
423 type_id >= BT_CTF_NR_TYPE_IDS) {
424 return;
425 }
426
427 type_destroy_funcs[type_id](type);
428}
429
430static
431int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type)
432{
433 int ret = 0;
434
435 struct bt_ctf_field_type_integer *integer =
436 container_of(type, struct bt_ctf_field_type_integer,
437 parent);
438
439 if (integer->mapped_clock && integer->declaration.signedness) {
440 ret = -1;
441 goto end;
442 }
443
444end:
445 return ret;
446}
447
448static
449int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
450{
451 int ret = 0;
452
453 struct bt_ctf_field_type_enumeration *enumeration =
454 container_of(type, struct bt_ctf_field_type_enumeration,
455 parent);
456 struct bt_ctf_field_type *container_type =
457 bt_ctf_field_type_enumeration_get_container_type(type);
458
459 if (!container_type) {
460 ret = -1;
461 goto end;
462 }
463
464 ret = bt_ctf_field_type_validate(container_type);
465 if (ret) {
466 goto end;
467 }
468
469 /* Ensure enum has entries */
470 ret = enumeration->entries->len ? 0 : -1;
471
472end:
473 BT_PUT(container_type);
474 return ret;
475}
476
477static
478int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type)
479{
480 int ret = 0;
481 struct bt_ctf_field_type *element_type = NULL;
482 struct bt_ctf_field_type_sequence *sequence =
483 container_of(type, struct bt_ctf_field_type_sequence,
484 parent);
485
486 /* Length field name should be set at this point */
487 if (sequence->length_field_name->len == 0) {
488 ret = -1;
489 goto end;
490 }
491
492 element_type = bt_ctf_field_type_sequence_get_element_type(type);
493 if (!element_type) {
494 ret = -1;
495 goto end;
496 }
497
498 ret = bt_ctf_field_type_validate(element_type);
499
500end:
501 BT_PUT(element_type);
502
503 return ret;
504}
505
506static
507int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type)
508{
509 int ret = 0;
510 struct bt_ctf_field_type *element_type = NULL;
511
512 element_type = bt_ctf_field_type_array_get_element_type(type);
513 if (!element_type) {
514 ret = -1;
515 goto end;
516 }
517
518 ret = bt_ctf_field_type_validate(element_type);
519
520end:
521 BT_PUT(element_type);
522
523 return ret;
524}
525
526static
527int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type)
528{
529 int ret = 0;
530 struct bt_ctf_field_type *child_type = NULL;
531 int field_count = bt_ctf_field_type_structure_get_field_count(type);
532 int i;
533
534 if (field_count < 0) {
535 ret = -1;
536 goto end;
537 }
538
539 for (i = 0; i < field_count; ++i) {
540 ret = bt_ctf_field_type_structure_get_field(type,
541 NULL, &child_type, i);
542 if (ret) {
543 goto end;
544 }
545
546 ret = bt_ctf_field_type_validate(child_type);
547 if (ret) {
548 goto end;
549 }
550
551 BT_PUT(child_type);
552 }
553
554end:
555 BT_PUT(child_type);
556
557 return ret;
558}
559
560static
561int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type)
562{
563 int ret = 0;
564 int field_count;
565 struct bt_ctf_field_type *child_type = NULL;
566 struct bt_ctf_field_type_variant *variant =
567 container_of(type, struct bt_ctf_field_type_variant,
568 parent);
569 int i;
570 int tag_mappings_count;
571
572 if (variant->tag_name->len == 0 || !variant->tag) {
573 ret = -1;
574 goto end;
575 }
576
577 tag_mappings_count =
578 bt_ctf_field_type_enumeration_get_mapping_count(
579 (struct bt_ctf_field_type *) variant->tag);
580
581 if (tag_mappings_count != variant->fields->len) {
582 ret = -1;
583 goto end;
584 }
585
586 for (i = 0; i < tag_mappings_count; ++i) {
587 const char *label;
588 int64_t range_start, range_end;
589 struct bt_ctf_field_type *ft;
590
591 ret = bt_ctf_field_type_enumeration_get_mapping(
592 (struct bt_ctf_field_type *) variant->tag,
593 i, &label, &range_start, &range_end);
594 if (ret) {
595 goto end;
596 }
597 if (!label) {
598 ret = -1;
599 goto end;
600 }
601
602 ft = bt_ctf_field_type_variant_get_field_type_by_name(
603 type, label);
604 if (!ft) {
605 ret = -1;
606 goto end;
607 }
608
609 BT_PUT(ft);
610 }
611
612 field_count = bt_ctf_field_type_variant_get_field_count(type);
613 if (field_count < 0) {
614 ret = -1;
615 goto end;
616 }
617
618 for (i = 0; i < field_count; ++i) {
619 ret = bt_ctf_field_type_variant_get_field(type,
620 NULL, &child_type, i);
621 if (ret) {
622 goto end;
623 }
624
625 ret = bt_ctf_field_type_validate(child_type);
626 if (ret) {
627 goto end;
628 }
629
630 BT_PUT(child_type);
631 }
632
633end:
634 BT_PUT(child_type);
635
636 return ret;
637}
638
639/*
640 * This function validates a given field type without considering
641 * where this field type is located. It only validates the properties
642 * of the given field type and the properties of its children if
643 * applicable.
644 */
645BT_HIDDEN
646int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
647{
648 int ret = 0;
649 enum bt_ctf_type_id id = bt_ctf_field_type_get_type_id(type);
650
651 if (!type) {
652 ret = -1;
653 goto end;
654 }
655
656 if (type->valid) {
657 /* Already marked as valid */
658 goto end;
659 }
660
661 if (type_validate_funcs[id]) {
662 ret = type_validate_funcs[id](type);
663 }
664
665 if (!ret && type->frozen) {
666 /* Field type is valid */
667 type->valid = 1;
668 }
669
670end:
671 return ret;
672}
673
674struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
675{
676 struct bt_ctf_field_type_integer *integer =
677 g_new0(struct bt_ctf_field_type_integer, 1);
678
679 if (!integer || size == 0 || size > 64) {
680 return NULL;
681 }
682
683 integer->parent.declaration = &integer->declaration.p;
684 integer->parent.declaration->id = BT_CTF_TYPE_ID_INTEGER;
685 integer->declaration.len = size;
686 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
687 integer->declaration.encoding = BT_CTF_STRING_ENCODING_NONE;
688 bt_ctf_field_type_init(&integer->parent, TRUE);
689 return &integer->parent;
690}
691
5ad19bf0 692BT_HIDDEN
1c822dfb
JG
693int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
694{
695 int ret = 0;
696 struct bt_ctf_field_type_integer *integer;
697
698 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
699 ret = -1;
700 goto end;
701 }
702
703 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
704 ret = (int) integer->declaration.len;
705end:
706 return ret;
707}
708
709int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
710{
711 int ret = 0;
712 struct bt_ctf_field_type_integer *integer;
713
714 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
715 ret = -1;
716 goto end;
717 }
718
719 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
720 ret = integer->declaration.signedness;
721end:
722 return ret;
723}
724
725int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
726 int is_signed)
727{
728 int ret = 0;
729 struct bt_ctf_field_type_integer *integer;
730
731 if (!type || type->frozen ||
732 type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
733 ret = -1;
734 goto end;
735 }
736
737 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
738 integer->declaration.signedness = !!is_signed;
739end:
740 return ret;
741}
742
5ad19bf0 743BT_HIDDEN
1c822dfb
JG
744enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
745 struct bt_ctf_field_type *type)
746{
747 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
748 struct bt_ctf_field_type_integer *integer;
749
750 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
751 goto end;
752 }
753
754 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
755 ret = integer->declaration.base;
756end:
757 return ret;
758}
759
760int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
761 enum bt_ctf_integer_base base)
762{
763 int ret = 0;
764
765 if (!type || type->frozen ||
766 type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
767 ret = -1;
768 goto end;
769 }
770
771 switch (base) {
772 case BT_CTF_INTEGER_BASE_BINARY:
773 case BT_CTF_INTEGER_BASE_OCTAL:
774 case BT_CTF_INTEGER_BASE_DECIMAL:
775 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
776 {
777 struct bt_ctf_field_type_integer *integer = container_of(type,
778 struct bt_ctf_field_type_integer, parent);
779 integer->declaration.base = base;
780 break;
781 }
782 default:
783 ret = -1;
784 }
785end:
786 return ret;
787}
788
5ad19bf0 789BT_HIDDEN
1c822dfb
JG
790enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
791 struct bt_ctf_field_type *type)
792{
793 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
794 struct bt_ctf_field_type_integer *integer;
795
796 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
797 goto end;
798 }
799
800 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
801 ret = integer->declaration.encoding;
802end:
803 return ret;
804}
805
806int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
807 enum bt_ctf_string_encoding encoding)
808{
809 int ret = 0;
810 struct bt_ctf_field_type_integer *integer;
811
812 if (!type || type->frozen ||
813 (type->declaration->id != BT_CTF_TYPE_ID_INTEGER) ||
814 (encoding < BT_CTF_STRING_ENCODING_NONE) ||
815 (encoding >= BT_CTF_STRING_ENCODING_UNKNOWN)) {
816 ret = -1;
817 goto end;
818 }
819
820 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
821 integer->declaration.encoding = encoding;
822end:
823 return ret;
824}
825
5ad19bf0 826BT_HIDDEN
1c822dfb
JG
827struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
828 struct bt_ctf_field_type *type)
829{
830 struct bt_ctf_field_type_integer *integer;
831 struct bt_ctf_clock *clock = NULL;
832
833 if (!type) {
834 goto end;
835 }
836
837 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
838 clock = integer->mapped_clock;
839 bt_get(clock);
840end:
841 return clock;
842}
843
5ad19bf0 844BT_HIDDEN
1c822dfb
JG
845int bt_ctf_field_type_integer_set_mapped_clock(
846 struct bt_ctf_field_type *type,
847 struct bt_ctf_clock *clock)
848{
849 struct bt_ctf_field_type_integer *integer;
850 int ret = 0;
851
852 if (!type || type->frozen) {
853 ret = -1;
854 goto end;
855 }
856
857 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
858 bt_put(integer->mapped_clock);
859 bt_get(clock);
860 integer->mapped_clock = clock;
861end:
862 return ret;
863}
864
865struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
866 struct bt_ctf_field_type *integer_container_type)
867{
868 struct bt_ctf_field_type_enumeration *enumeration = NULL;
869
870 if (!integer_container_type) {
871 goto error;
872 }
873
874 if (integer_container_type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
875 goto error;
876 }
877
878 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
879 if (!enumeration) {
880 goto error;
881 }
882
883 enumeration->parent.declaration = &enumeration->declaration.p;
884 enumeration->parent.declaration->id = BT_CTF_TYPE_ID_ENUM;
885 bt_get(integer_container_type);
886 enumeration->container = integer_container_type;
887 enumeration->entries = g_ptr_array_new_with_free_func(
888 (GDestroyNotify)destroy_enumeration_mapping);
889 bt_ctf_field_type_init(&enumeration->parent, FALSE);
890 return &enumeration->parent;
891error:
892 g_free(enumeration);
893 return NULL;
894}
895
5ad19bf0 896BT_HIDDEN
1c822dfb
JG
897struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
898 struct bt_ctf_field_type *type)
899{
900 struct bt_ctf_field_type *container_type = NULL;
901 struct bt_ctf_field_type_enumeration *enumeration_type;
902
903 if (!type) {
904 goto end;
905 }
906
907 if (type->declaration->id != BT_CTF_TYPE_ID_ENUM) {
908 goto end;
909 }
910
911 enumeration_type = container_of(type,
912 struct bt_ctf_field_type_enumeration, parent);
913 container_type = enumeration_type->container;
914 bt_get(container_type);
915end:
916 return container_type;
917}
918
919int bt_ctf_field_type_enumeration_add_mapping(
920 struct bt_ctf_field_type *type, const char *string,
921 int64_t range_start, int64_t range_end)
922{
923 int ret = 0;
924 GQuark mapping_name;
925 struct enumeration_mapping *mapping;
926 struct bt_ctf_field_type_enumeration *enumeration;
927 struct range_overlap_query query;
928 char *escaped_string;
929
930 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
931 type->frozen ||
932 (range_end < range_start)) {
933 ret = -1;
934 goto end;
935 }
936
937 if (!string || strlen(string) == 0) {
938 ret = -1;
939 goto end;
940 }
941
942 escaped_string = g_strescape(string, NULL);
943 if (!escaped_string) {
944 ret = -1;
945 goto end;
946 }
947
948 mapping_name = g_quark_from_string(escaped_string);
949 query = (struct range_overlap_query) {
950 .range_start._signed = range_start,
951 .range_end._signed = range_end,
952 .mapping_name = mapping_name,
953 .overlaps = 0 };
954 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
955 parent);
956
957 /* Check that the range does not overlap with one already present */
958 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
959 if (query.overlaps) {
960 ret = -1;
961 goto error_free;
962 }
963
964 mapping = g_new(struct enumeration_mapping, 1);
965 if (!mapping) {
966 ret = -1;
967 goto error_free;
968 }
969
970 *mapping = (struct enumeration_mapping) {
971 .range_start._signed = range_start,
972 .range_end._signed = range_end, .string = mapping_name};
973 g_ptr_array_add(enumeration->entries, mapping);
974 g_ptr_array_sort(enumeration->entries,
975 (GCompareFunc)compare_enumeration_mappings_signed);
976error_free:
977 free(escaped_string);
978end:
979 return ret;
980}
981
5ad19bf0 982BT_HIDDEN
1c822dfb
JG
983int bt_ctf_field_type_enumeration_add_mapping_unsigned(
984 struct bt_ctf_field_type *type, const char *string,
985 uint64_t range_start, uint64_t range_end)
986{
987 int ret = 0;
988 GQuark mapping_name;
989 struct enumeration_mapping *mapping;
990 struct bt_ctf_field_type_enumeration *enumeration;
991 struct range_overlap_query query;
992 char *escaped_string;
993
994 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
995 type->frozen ||
996 (range_end < range_start)) {
997 ret = -1;
998 goto end;
999 }
1000
1001 if (!string || strlen(string) == 0) {
1002 ret = -1;
1003 goto end;
1004 }
1005
1006 escaped_string = g_strescape(string, NULL);
1007 if (!escaped_string) {
1008 ret = -1;
1009 goto end;
1010 }
1011
1012 mapping_name = g_quark_from_string(escaped_string);
1013 query = (struct range_overlap_query) {
1014 .range_start._unsigned = range_start,
1015 .range_end._unsigned = range_end,
1016 .mapping_name = mapping_name,
1017 .overlaps = 0 };
1018 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1019 parent);
1020
1021 /* Check that the range does not overlap with one already present */
1022 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned,
1023 &query);
1024 if (query.overlaps) {
1025 ret = -1;
1026 goto error_free;
1027 }
1028
1029 mapping = g_new(struct enumeration_mapping, 1);
1030 if (!mapping) {
1031 ret = -1;
1032 goto error_free;
1033 }
1034
1035 *mapping = (struct enumeration_mapping) {
1036 .range_start._unsigned = range_start,
1037 .range_end._unsigned = range_end, .string = mapping_name};
1038 g_ptr_array_add(enumeration->entries, mapping);
1039 g_ptr_array_sort(enumeration->entries,
1040 (GCompareFunc)compare_enumeration_mappings_unsigned);
1041error_free:
1042 free(escaped_string);
1043end:
1044 return ret;
1045}
1046
5ad19bf0 1047BT_HIDDEN
1c822dfb
JG
1048const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
1049 struct bt_ctf_field_type_enumeration *enumeration_type,
1050 uint64_t value)
1051{
1052 const char *name = NULL;
1053 struct range_overlap_query query =
1054 (struct range_overlap_query) {
1055 .range_start._unsigned = value,
1056 .range_end._unsigned = value,
1057 .overlaps = 0 };
1058
1059 g_ptr_array_foreach(enumeration_type->entries,
1060 check_ranges_overlap_unsigned,
1061 &query);
1062 if (!query.overlaps) {
1063 goto end;
1064 }
1065
1066 name = g_quark_to_string(query.mapping_name);
1067end:
1068 return name;
1069}
1070
1071const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
1072 struct bt_ctf_field_type_enumeration *enumeration_type,
1073 int64_t value)
1074{
1075 const char *name = NULL;
1076 struct range_overlap_query query =
1077 (struct range_overlap_query) {
1078 .range_start._signed = value,
1079 .range_end._signed = value,
1080 .overlaps = 0 };
1081
1082 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
1083 &query);
1084 if (!query.overlaps) {
1085 goto end;
1086 }
1087
1088 name = g_quark_to_string(query.mapping_name);
1089end:
1090 return name;
1091}
1092
1093int bt_ctf_field_type_enumeration_get_mapping_count(
1094 struct bt_ctf_field_type *type)
1095{
1096 int ret = 0;
1097 struct bt_ctf_field_type_enumeration *enumeration;
1098
1099 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
1100 ret = -1;
1101 goto end;
1102 }
1103
1104 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1105 parent);
1106 ret = (int) enumeration->entries->len;
1107end:
1108 return ret;
1109}
1110
1111static inline
1112struct enumeration_mapping *get_enumeration_mapping(
1113 struct bt_ctf_field_type *type, int index)
1114{
1115 struct enumeration_mapping *mapping = NULL;
1116 struct bt_ctf_field_type_enumeration *enumeration;
1117
1118 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1119 parent);
1120 if (index >= enumeration->entries->len) {
1121 goto end;
1122 }
1123
1124 mapping = g_ptr_array_index(enumeration->entries, index);
1125end:
1126 return mapping;
1127}
1128
5ad19bf0 1129BT_HIDDEN
1c822dfb
JG
1130int bt_ctf_field_type_enumeration_get_mapping(
1131 struct bt_ctf_field_type *type, int index,
1132 const char **string, int64_t *range_start, int64_t *range_end)
1133{
1134 struct enumeration_mapping *mapping;
1135 int ret = 0;
1136
1137 if (!type || index < 0 || !string || !range_start || !range_end ||
1138 (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
1139 ret = -1;
1140 goto end;
1141 }
1142
1143 mapping = get_enumeration_mapping(type, index);
1144 if (!mapping) {
1145 ret = -1;
1146 goto end;
1147 }
1148
1149 *string = g_quark_to_string(mapping->string);
1150 *range_start = mapping->range_start._signed;
1151 *range_end = mapping->range_end._signed;
1152end:
1153 return ret;
1154}
1155
5ad19bf0 1156BT_HIDDEN
1c822dfb
JG
1157int bt_ctf_field_type_enumeration_get_mapping_unsigned(
1158 struct bt_ctf_field_type *type, int index,
1159 const char **string, uint64_t *range_start, uint64_t *range_end)
1160{
1161 struct enumeration_mapping *mapping;
1162 int ret = 0;
1163
1164 if (!type || index < 0 || !string || !range_start || !range_end ||
1165 (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
1166 ret = -1;
1167 goto end;
1168 }
1169
1170 mapping = get_enumeration_mapping(type, index);
1171 if (!mapping) {
1172 ret = -1;
1173 goto end;
1174 }
1175
1176 *string = g_quark_to_string(mapping->string);
1177 *range_start = mapping->range_start._unsigned;
1178 *range_end = mapping->range_end._unsigned;
1179end:
1180 return ret;
1181}
1182
5ad19bf0 1183BT_HIDDEN
1c822dfb
JG
1184int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
1185 struct bt_ctf_field_type *type, const char *name)
1186{
1187 GQuark name_quark;
1188 struct bt_ctf_field_type_enumeration *enumeration;
1189 int i, ret = 0;
1190
1191 if (!type || !name ||
1192 (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
1193 ret = -1;
1194 goto end;
1195 }
1196
1197 name_quark = g_quark_try_string(name);
1198 if (!name_quark) {
1199 ret = -1;
1200 goto end;
1201 }
1202
1203 enumeration = container_of(type,
1204 struct bt_ctf_field_type_enumeration, parent);
1205 for (i = 0; i < enumeration->entries->len; i++) {
1206 struct enumeration_mapping *mapping =
1207 get_enumeration_mapping(type, i);
1208
1209 if (mapping->string == name_quark) {
1210 ret = i;
1211 goto end;
1212 }
1213 }
1214
1215 ret = -1;
1216end:
1217 return ret;
1218}
1219
5ad19bf0 1220BT_HIDDEN
1c822dfb
JG
1221int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
1222 struct bt_ctf_field_type *type, int64_t value)
1223{
1224 struct bt_ctf_field_type_enumeration *enumeration;
1225 int i, ret = 0;
1226
1227 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
1228 ret = -1;
1229 goto end;
1230 }
1231
1232 enumeration = container_of(type,
1233 struct bt_ctf_field_type_enumeration, parent);
1234 for (i = 0; i < enumeration->entries->len; i++) {
1235 struct enumeration_mapping *mapping =
1236 get_enumeration_mapping(type, i);
1237
1238 if (value >= mapping->range_start._signed &&
1239 value <= mapping->range_end._signed) {
1240 ret = i;
1241 goto end;
1242 }
1243 }
1244
1245 ret = -1;
1246end:
1247 return ret;
1248}
1249
5ad19bf0 1250BT_HIDDEN
1c822dfb
JG
1251int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
1252 struct bt_ctf_field_type *type, uint64_t value)
1253{
1254 struct bt_ctf_field_type_enumeration *enumeration;
1255 int i, ret = 0;
1256
1257 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
1258 ret = -1;
1259 goto end;
1260 }
1261
1262 enumeration = container_of(type,
1263 struct bt_ctf_field_type_enumeration, parent);
1264 for (i = 0; i < enumeration->entries->len; i++) {
1265 struct enumeration_mapping *mapping =
1266 get_enumeration_mapping(type, i);
1267
1268 if (value >= mapping->range_start._unsigned &&
1269 value <= mapping->range_end._unsigned) {
1270 ret = i;
1271 goto end;
1272 }
1273 }
1274
1275 ret = -1;
1276end:
1277 return ret;
1278}
1279
1280struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
1281{
1282 struct bt_ctf_field_type_floating_point *floating_point =
1283 g_new0(struct bt_ctf_field_type_floating_point, 1);
1284
1285 if (!floating_point) {
1286 goto end;
1287 }
1288
1289 floating_point->declaration.sign = &floating_point->sign;
1290 floating_point->declaration.mantissa = &floating_point->mantissa;
1291 floating_point->declaration.exp = &floating_point->exp;
1292 floating_point->sign.len = 1;
1293 floating_point->parent.declaration = &floating_point->declaration.p;
1294 floating_point->parent.declaration->id = BT_CTF_TYPE_ID_FLOAT;
1295 floating_point->declaration.exp->len =
1296 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
1297 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
1298 floating_point->sign.p.alignment = 1;
1299 floating_point->mantissa.p.alignment = 1;
1300 floating_point->exp.p.alignment = 1;
1301
1302 bt_ctf_field_type_init(&floating_point->parent, TRUE);
1303end:
1304 return floating_point ? &floating_point->parent : NULL;
1305}
1306
5ad19bf0 1307BT_HIDDEN
1c822dfb
JG
1308int bt_ctf_field_type_floating_point_get_exponent_digits(
1309 struct bt_ctf_field_type *type)
1310{
1311 int ret = 0;
1312 struct bt_ctf_field_type_floating_point *floating_point;
1313
1314 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
1315 ret = -1;
1316 goto end;
1317 }
1318
1319 floating_point = container_of(type,
1320 struct bt_ctf_field_type_floating_point, parent);
1321 ret = (int) floating_point->declaration.exp->len;
1322end:
1323 return ret;
1324}
1325
1326int bt_ctf_field_type_floating_point_set_exponent_digits(
1327 struct bt_ctf_field_type *type,
1328 unsigned int exponent_digits)
1329{
1330 int ret = 0;
1331 struct bt_ctf_field_type_floating_point *floating_point;
1332
1333 if (!type || type->frozen ||
1334 (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
1335 ret = -1;
1336 goto end;
1337 }
1338
1339 floating_point = container_of(type,
1340 struct bt_ctf_field_type_floating_point, parent);
1341 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1342 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1343 (exponent_digits !=
1344 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1345 ret = -1;
1346 goto end;
1347 }
1348
1349 floating_point->declaration.exp->len = exponent_digits;
1350end:
1351 return ret;
1352}
1353
5ad19bf0 1354BT_HIDDEN
1c822dfb
JG
1355int bt_ctf_field_type_floating_point_get_mantissa_digits(
1356 struct bt_ctf_field_type *type)
1357{
1358 int ret = 0;
1359 struct bt_ctf_field_type_floating_point *floating_point;
1360
1361 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
1362 ret = -1;
1363 goto end;
1364 }
1365
1366 floating_point = container_of(type,
1367 struct bt_ctf_field_type_floating_point, parent);
1368 ret = (int) floating_point->mantissa.len + 1;
1369end:
1370 return ret;
1371}
1372
1373int bt_ctf_field_type_floating_point_set_mantissa_digits(
1374 struct bt_ctf_field_type *type,
1375 unsigned int mantissa_digits)
1376{
1377 int ret = 0;
1378 struct bt_ctf_field_type_floating_point *floating_point;
1379
1380 if (!type || type->frozen ||
1381 (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
1382 ret = -1;
1383 goto end;
1384 }
1385
1386 floating_point = container_of(type,
1387 struct bt_ctf_field_type_floating_point, parent);
1388
1389 if ((mantissa_digits != FLT_MANT_DIG) &&
1390 (mantissa_digits != DBL_MANT_DIG) &&
1391 (mantissa_digits != LDBL_MANT_DIG)) {
1392 ret = -1;
1393 goto end;
1394 }
1395
1396 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1397end:
1398 return ret;
1399}
1400
1401struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1402{
1403 struct bt_ctf_field_type_structure *structure =
1404 g_new0(struct bt_ctf_field_type_structure, 1);
1405
1406 if (!structure) {
1407 goto error;
1408 }
1409
1410 structure->parent.declaration = &structure->declaration.p;
1411 structure->parent.declaration->id = BT_CTF_TYPE_ID_STRUCT;
1412 structure->fields = g_ptr_array_new_with_free_func(
1413 (GDestroyNotify)destroy_structure_field);
1414 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
1415 bt_ctf_field_type_init(&structure->parent, TRUE);
1416 return &structure->parent;
1417error:
1418 return NULL;
1419}
1420
1421int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1422 struct bt_ctf_field_type *field_type,
1423 const char *field_name)
1424{
1425 int ret = 0;
1426 struct bt_ctf_field_type_structure *structure;
1427
1428 if (!type || !field_type || type->frozen ||
1429 bt_ctf_validate_identifier(field_name) ||
1430 (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
1431 ret = -1;
1432 goto end;
1433 }
1434
1435 structure = container_of(type,
1436 struct bt_ctf_field_type_structure, parent);
1437 if (add_structure_field(structure->fields,
1438 structure->field_name_to_index, field_type, field_name)) {
1439 ret = -1;
1440 goto end;
1441 }
1442end:
1443 return ret;
1444}
1445
5ad19bf0 1446BT_HIDDEN
1c822dfb
JG
1447int bt_ctf_field_type_structure_get_field_count(
1448 struct bt_ctf_field_type *type)
1449{
1450 int ret = 0;
1451 struct bt_ctf_field_type_structure *structure;
1452
1453 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
1454 ret = -1;
1455 goto end;
1456 }
1457
1458 structure = container_of(type, struct bt_ctf_field_type_structure,
1459 parent);
1460 ret = (int) structure->fields->len;
1461end:
1462 return ret;
1463}
1464
1465int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1466 const char **field_name, struct bt_ctf_field_type **field_type,
1467 int index)
1468{
1469 struct bt_ctf_field_type_structure *structure;
1470 struct structure_field *field;
1471 int ret = 0;
1472
1473 if (!type || index < 0 ||
1474 (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
1475 ret = -1;
1476 goto end;
1477 }
1478
1479 structure = container_of(type, struct bt_ctf_field_type_structure,
1480 parent);
1481 if (index >= structure->fields->len) {
1482 ret = -1;
1483 goto end;
1484 }
1485
1486 field = g_ptr_array_index(structure->fields, index);
1487 if (field_type) {
1488 *field_type = field->type;
1489 bt_get(field->type);
1490 }
1491 if (field_name) {
1492 *field_name = g_quark_to_string(field->name);
1493 }
1494end:
1495 return ret;
1496}
1497
5ad19bf0 1498BT_HIDDEN
1c822dfb
JG
1499struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1500 struct bt_ctf_field_type *type,
1501 const char *name)
1502{
1503 size_t index;
1504 GQuark name_quark;
1505 struct structure_field *field;
1506 struct bt_ctf_field_type_structure *structure;
1507 struct bt_ctf_field_type *field_type = NULL;
1508
1509 if (!type || !name) {
1510 goto end;
1511 }
1512
1513 name_quark = g_quark_try_string(name);
1514 if (!name_quark) {
1515 goto end;
1516 }
1517
1518 structure = container_of(type, struct bt_ctf_field_type_structure,
1519 parent);
1520 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1521 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1522 goto end;
1523 }
1524
1525 field = structure->fields->pdata[index];
1526 field_type = field->type;
1527 bt_get(field_type);
1528end:
1529 return field_type;
1530}
1531
1532struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1533 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1534{
1535 struct bt_ctf_field_type_variant *variant = NULL;
1536
1537 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
1538 goto error;
1539 }
1540
1541 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1542 if (!variant) {
1543 goto error;
1544 }
1545
1546 variant->parent.declaration = &variant->declaration.p;
1547 variant->parent.declaration->id = BT_CTF_TYPE_ID_VARIANT;
1548 variant->tag_name = g_string_new(tag_name);
1549 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1550 variant->fields = g_ptr_array_new_with_free_func(
1551 (GDestroyNotify) destroy_structure_field);
1552 if (enum_tag) {
1553 bt_get(enum_tag);
1554 variant->tag = container_of(enum_tag,
1555 struct bt_ctf_field_type_enumeration, parent);
1556 }
1557
1558 bt_ctf_field_type_init(&variant->parent, TRUE);
1559 /* A variant's alignment is undefined */
1560 variant->parent.declaration->alignment = 0;
1561 return &variant->parent;
1562error:
1563 return NULL;
1564}
1565
5ad19bf0 1566BT_HIDDEN
1c822dfb
JG
1567struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1568 struct bt_ctf_field_type *type)
1569{
1570 struct bt_ctf_field_type_variant *variant;
1571 struct bt_ctf_field_type *tag_type = NULL;
1572
1573 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1574 goto end;
1575 }
1576
1577 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1578 if (!variant->tag) {
1579 goto end;
1580 }
1581
1582 tag_type = &variant->tag->parent;
1583 bt_get(tag_type);
1584end:
1585 return tag_type;
1586}
1587
5ad19bf0 1588BT_HIDDEN
1c822dfb
JG
1589const char *bt_ctf_field_type_variant_get_tag_name(
1590 struct bt_ctf_field_type *type)
1591{
1592 struct bt_ctf_field_type_variant *variant;
1593 const char *tag_name = NULL;
1594
1595 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1596 goto end;
1597 }
1598
1599 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1600 if (variant->tag_name->len == 0) {
1601 goto end;
1602 }
1603
1604 tag_name = variant->tag_name->str;
1605end:
1606 return tag_name;
1607}
1608
5ad19bf0 1609BT_HIDDEN
1c822dfb
JG
1610int bt_ctf_field_type_variant_set_tag_name(
1611 struct bt_ctf_field_type *type, const char *name)
1612{
1613 int ret = 0;
1614 struct bt_ctf_field_type_variant *variant;
1615
1616 if (!type || type->frozen ||
1617 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT) ||
1618 bt_ctf_validate_identifier(name)) {
1619 ret = -1;
1620 goto end;
1621 }
1622
1623 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1624 g_string_assign(variant->tag_name, name);
1625end:
1626 return ret;
1627}
1628
1629int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1630 struct bt_ctf_field_type *field_type,
1631 const char *field_name)
1632{
1633 size_t i;
1634 int ret = 0;
1635 struct bt_ctf_field_type_variant *variant;
1636 GQuark field_name_quark = g_quark_from_string(field_name);
1637
1638 if (!type || !field_type || type->frozen ||
1639 bt_ctf_validate_identifier(field_name) ||
1640 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1641 ret = -1;
1642 goto end;
1643 }
1644
1645 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1646
1647 /* The user has explicitly provided a tag; validate against it. */
1648 if (variant->tag) {
1649 int name_found = 0;
1650
1651 /* Make sure this name is present in the enum tag */
1652 for (i = 0; i < variant->tag->entries->len; i++) {
1653 struct enumeration_mapping *mapping =
1654 g_ptr_array_index(variant->tag->entries, i);
1655
1656 if (mapping->string == field_name_quark) {
1657 name_found = 1;
1658 break;
1659 }
1660 }
1661
1662 if (!name_found) {
1663 /* Validation failed */
1664 ret = -1;
1665 goto end;
1666 }
1667 }
1668
1669 if (add_structure_field(variant->fields, variant->field_name_to_index,
1670 field_type, field_name)) {
1671 ret = -1;
1672 goto end;
1673 }
1674end:
1675 return ret;
1676}
1677
5ad19bf0 1678BT_HIDDEN
1c822dfb
JG
1679struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1680 struct bt_ctf_field_type *type,
1681 const char *field_name)
1682{
1683 size_t index;
1684 GQuark name_quark;
1685 struct structure_field *field;
1686 struct bt_ctf_field_type_variant *variant;
1687 struct bt_ctf_field_type *field_type = NULL;
1688
1689 if (!type || !field_name) {
1690 goto end;
1691 }
1692
1693 name_quark = g_quark_try_string(field_name);
1694 if (!name_quark) {
1695 goto end;
1696 }
1697
1698 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1699 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1700 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1701 goto end;
1702 }
1703
1704 field = g_ptr_array_index(variant->fields, index);
1705 field_type = field->type;
1706 bt_get(field_type);
1707end:
1708 return field_type;
1709}
1710
5ad19bf0 1711BT_HIDDEN
1c822dfb
JG
1712struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1713 struct bt_ctf_field_type *type,
1714 struct bt_ctf_field *tag)
1715{
1716 const char *enum_value;
1717 struct bt_ctf_field_type *field_type = NULL;
1718
1719 if (!type || !tag || type->declaration->id != BT_CTF_TYPE_ID_VARIANT) {
1720 goto end;
1721 }
1722
1723 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1724 if (!enum_value) {
1725 goto end;
1726 }
1727
1728 /* Already increments field_type's reference count */
1729 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1730 type, enum_value);
1731end:
1732 return field_type;
1733}
1734
1735int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1736{
1737 int ret = 0;
1738 struct bt_ctf_field_type_variant *variant;
1739
1740 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1741 ret = -1;
1742 goto end;
1743 }
1744
1745 variant = container_of(type, struct bt_ctf_field_type_variant,
1746 parent);
1747 ret = (int) variant->fields->len;
1748end:
1749 return ret;
1750
1751}
1752
5ad19bf0 1753BT_HIDDEN
1c822dfb
JG
1754int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1755 const char **field_name, struct bt_ctf_field_type **field_type,
1756 int index)
1757{
1758 struct bt_ctf_field_type_variant *variant;
1759 struct structure_field *field;
1760 int ret = 0;
1761
1762 if (!type || index < 0 ||
1763 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1764 ret = -1;
1765 goto end;
1766 }
1767
1768 variant = container_of(type, struct bt_ctf_field_type_variant,
1769 parent);
1770 if (index >= variant->fields->len) {
1771 ret = -1;
1772 goto end;
1773 }
1774
1775 field = g_ptr_array_index(variant->fields, index);
1776 if (field_type) {
1777 *field_type = field->type;
1778 bt_get(field->type);
1779 }
1780 if (field_name) {
1781 *field_name = g_quark_to_string(field->name);
1782 }
1783end:
1784 return ret;
1785}
1786
1787struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1788 struct bt_ctf_field_type *element_type,
1789 unsigned int length)
1790{
1791 struct bt_ctf_field_type_array *array = NULL;
1792
1793 if (!element_type || length == 0) {
1794 goto error;
1795 }
1796
1797 array = g_new0(struct bt_ctf_field_type_array, 1);
1798 if (!array) {
1799 goto error;
1800 }
1801
1802 array->parent.declaration = &array->declaration.p;
1803 array->parent.declaration->id = BT_CTF_TYPE_ID_ARRAY;
1804
1805 bt_get(element_type);
1806 array->element_type = element_type;
1807 array->length = length;
1808 bt_ctf_field_type_init(&array->parent, FALSE);
1809 return &array->parent;
1810error:
1811 return NULL;
1812}
1813
5ad19bf0 1814BT_HIDDEN
1c822dfb
JG
1815struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1816 struct bt_ctf_field_type *type)
1817{
1818 struct bt_ctf_field_type *ret = NULL;
1819 struct bt_ctf_field_type_array *array;
1820
1821 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1822 goto end;
1823 }
1824
1825 array = container_of(type, struct bt_ctf_field_type_array, parent);
1826 ret = array->element_type;
1827 bt_get(ret);
1828end:
1829 return ret;
1830}
1831
1832BT_HIDDEN
1833int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
1834 struct bt_ctf_field_type *element_type)
1835{
1836 int ret = 0;
1837 struct bt_ctf_field_type_array *array;
1838
1839 if (!type || !element_type ||
1840 (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1841 ret = -1;
1842 goto end;
1843 }
1844
1845 array = container_of(type, struct bt_ctf_field_type_array, parent);
1846
1847 if (array->element_type) {
1848 BT_PUT(array->element_type);
1849 }
1850
1851 array->element_type = element_type;
1852 bt_get(array->element_type);
1853
1854end:
1855 return ret;
1856}
1857
5ad19bf0 1858BT_HIDDEN
1c822dfb
JG
1859int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1860{
1861 int64_t ret;
1862 struct bt_ctf_field_type_array *array;
1863
1864 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1865 ret = -1;
1866 goto end;
1867 }
1868
1869 array = container_of(type, struct bt_ctf_field_type_array, parent);
1870 ret = (int64_t) array->length;
1871end:
1872 return ret;
1873}
1874
1875struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1876 struct bt_ctf_field_type *element_type,
1877 const char *length_field_name)
1878{
1879 struct bt_ctf_field_type_sequence *sequence = NULL;
1880
1881 if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
1882 goto error;
1883 }
1884
1885 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1886 if (!sequence) {
1887 goto error;
1888 }
1889
1890 sequence->parent.declaration = &sequence->declaration.p;
1891 sequence->parent.declaration->id = BT_CTF_TYPE_ID_SEQUENCE;
1892 bt_get(element_type);
1893 sequence->element_type = element_type;
1894 sequence->length_field_name = g_string_new(length_field_name);
1895 bt_ctf_field_type_init(&sequence->parent, FALSE);
1896 return &sequence->parent;
1897error:
1898 return NULL;
1899}
1900
5ad19bf0 1901BT_HIDDEN
1c822dfb
JG
1902struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1903 struct bt_ctf_field_type *type)
1904{
1905 struct bt_ctf_field_type *ret = NULL;
1906 struct bt_ctf_field_type_sequence *sequence;
1907
1908 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
1909 goto end;
1910 }
1911
1912 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1913 parent);
1914 ret = sequence->element_type;
1915 bt_get(ret);
1916end:
1917 return ret;
1918}
1919
1920BT_HIDDEN
1921int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
1922 struct bt_ctf_field_type *element_type)
1923{
1924 int ret = 0;
1925 struct bt_ctf_field_type_sequence *sequence;
1926
1927 if (!type || !element_type ||
1928 (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
1929 ret = -1;
1930 goto end;
1931 }
1932
1933 sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
1934
1935 if (sequence->element_type) {
1936 BT_PUT(sequence->element_type);
1937 }
1938
1939 sequence->element_type = element_type;
1940 bt_get(sequence->element_type);
1941
1942end:
1943 return ret;
1944}
1945
5ad19bf0 1946BT_HIDDEN
1c822dfb
JG
1947const char *bt_ctf_field_type_sequence_get_length_field_name(
1948 struct bt_ctf_field_type *type)
1949{
1950 const char *ret = NULL;
1951 struct bt_ctf_field_type_sequence *sequence;
1952
1953 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
1954 goto end;
1955 }
1956
1957 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1958 parent);
1959 ret = sequence->length_field_name->str;
1960end:
1961 return ret;
1962}
1963
1964struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1965{
1966 struct bt_ctf_field_type_string *string =
1967 g_new0(struct bt_ctf_field_type_string, 1);
1968
1969 if (!string) {
1970 return NULL;
1971 }
1972
1973 string->parent.declaration = &string->declaration.p;
1974 string->parent.declaration->id = BT_CTF_TYPE_ID_STRING;
1975 bt_ctf_field_type_init(&string->parent, TRUE);
1976 string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
1977 string->parent.declaration->alignment = CHAR_BIT;
1978 return &string->parent;
1979}
1980
5ad19bf0 1981BT_HIDDEN
1c822dfb
JG
1982enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1983 struct bt_ctf_field_type *type)
1984{
1985 struct bt_ctf_field_type_string *string;
1986 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
1987
1988 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRING)) {
1989 goto end;
1990 }
1991
1992 string = container_of(type, struct bt_ctf_field_type_string,
1993 parent);
1994 ret = string->declaration.encoding;
1995end:
1996 return ret;
1997}
1998
1999int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
2000 enum bt_ctf_string_encoding encoding)
2001{
2002 int ret = 0;
2003 struct bt_ctf_field_type_string *string;
2004
2005 if (!type || type->declaration->id != BT_CTF_TYPE_ID_STRING ||
2006 (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
2007 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
2008 ret = -1;
2009 goto end;
2010 }
2011
2012 string = container_of(type, struct bt_ctf_field_type_string, parent);
2013 string->declaration.encoding = encoding;
2014end:
2015 return ret;
2016}
2017
5ad19bf0 2018BT_HIDDEN
1c822dfb
JG
2019int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
2020{
2021 int ret;
2022 enum bt_ctf_type_id type_id;
2023
2024 if (!type) {
2025 ret = -1;
2026 goto end;
2027 }
2028
2029 if (type->frozen) {
2030 ret = (int) type->declaration->alignment;
2031 goto end;
2032 }
2033
2034 type_id = bt_ctf_field_type_get_type_id(type);
2035 switch (type_id) {
2036 case BT_CTF_TYPE_ID_SEQUENCE:
2037 {
2038 struct bt_ctf_field_type *element =
2039 bt_ctf_field_type_sequence_get_element_type(type);
2040
2041 if (!element) {
2042 ret = -1;
2043 goto end;
2044 }
2045
2046 ret = bt_ctf_field_type_get_alignment(element);
2047 bt_put(element);
2048 break;
2049 }
2050 case BT_CTF_TYPE_ID_ARRAY:
2051 {
2052 struct bt_ctf_field_type *element =
2053 bt_ctf_field_type_array_get_element_type(type);
2054
2055 if (!element) {
2056 ret = -1;
2057 goto end;
2058 }
2059
2060 ret = bt_ctf_field_type_get_alignment(element);
2061 bt_put(element);
2062 break;
2063 }
2064 case BT_CTF_TYPE_ID_STRUCT:
2065 {
2066 int i, element_count;
2067
2068 element_count = bt_ctf_field_type_structure_get_field_count(
2069 type);
2070 if (element_count < 0) {
2071 ret = element_count;
2072 goto end;
2073 }
2074
2075 for (i = 0; i < element_count; i++) {
2076 struct bt_ctf_field_type *field;
2077 int field_alignment;
2078
2079 ret = bt_ctf_field_type_structure_get_field(type, NULL,
2080 &field, i);
2081 if (ret) {
2082 goto end;
2083 }
2084
2085 assert(field);
2086 field_alignment = bt_ctf_field_type_get_alignment(
2087 field);
2088 bt_put(field);
2089 if (field_alignment < 0) {
2090 ret = field_alignment;
2091 goto end;
2092 }
2093
2094 type->declaration->alignment = MAX(field_alignment,
2095 type->declaration->alignment);
2096 }
2097 ret = (int) type->declaration->alignment;
2098 break;
2099 }
2100 case BT_CTF_TYPE_ID_UNKNOWN:
2101 ret = -1;
2102 break;
2103 default:
2104 ret = (int) type->declaration->alignment;
2105 break;
2106 }
2107end:
2108 return ret;
2109}
2110
2111static inline
2112int is_power_of_two(unsigned int value)
2113{
2114 return ((value & (value - 1)) == 0) && value > 0;
2115}
2116
2117int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
2118 unsigned int alignment)
2119{
2120 int ret = 0;
2121 enum bt_ctf_type_id type_id;
2122
2123 /* Alignment must be a power of two */
2124 if (!type || type->frozen || !is_power_of_two(alignment)) {
2125 ret = -1;
2126 goto end;
2127 }
2128
2129 type_id = bt_ctf_field_type_get_type_id(type);
2130 if (type_id == BT_CTF_TYPE_ID_UNKNOWN) {
2131 ret = -1;
2132 goto end;
2133 }
2134
2135 if (type->declaration->id == BT_CTF_TYPE_ID_STRING &&
2136 alignment != CHAR_BIT) {
2137 ret = -1;
2138 goto end;
2139 }
2140
2141 if (type_id == BT_CTF_TYPE_ID_VARIANT ||
2142 type_id == BT_CTF_TYPE_ID_SEQUENCE ||
2143 type_id == BT_CTF_TYPE_ID_ARRAY) {
2144 /* Setting an alignment on these types makes no sense */
2145 ret = -1;
2146 goto end;
2147 }
2148
2149 type->declaration->alignment = alignment;
2150 ret = 0;
2151end:
2152 return ret;
2153}
2154
5ad19bf0 2155BT_HIDDEN
1c822dfb
JG
2156enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
2157 struct bt_ctf_field_type *type)
2158{
2159 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
2160
2161 if (!type) {
2162 goto end;
2163 }
2164
2165 switch (type->declaration->id) {
2166 case BT_CTF_TYPE_ID_INTEGER:
2167 {
2168 struct bt_ctf_field_type_integer *integer = container_of(
2169 type, struct bt_ctf_field_type_integer, parent);
2170 ret = integer->user_byte_order;
2171 break;
2172 }
2173 case BT_CTF_TYPE_ID_FLOAT:
2174 {
2175 struct bt_ctf_field_type_floating_point *floating_point =
2176 container_of(type,
2177 struct bt_ctf_field_type_floating_point,
2178 parent);
2179 ret = floating_point->user_byte_order;
2180 break;
2181 }
2182 default:
2183 goto end;
2184 }
2185
2186 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2187 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2188 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2189 ret == BT_CTF_BYTE_ORDER_NETWORK);
2190
2191end:
2192 return ret;
2193}
2194
2195int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2196 enum bt_ctf_byte_order byte_order)
2197{
2198 int ret = 0;
2199 int internal_byte_order;
2200 enum bt_ctf_type_id type_id;
2201
2202 if (!type || type->frozen) {
2203 ret = -1;
2204 goto end;
2205 }
2206
2207 switch (byte_order) {
2208 case BT_CTF_BYTE_ORDER_NATIVE:
2209 /* Leave unset. Will be initialized by parent. */
2210 internal_byte_order = 0;
2211 break;
2212 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2213 internal_byte_order = LITTLE_ENDIAN;
2214 break;
2215 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2216 case BT_CTF_BYTE_ORDER_NETWORK:
2217 internal_byte_order = BIG_ENDIAN;
2218 break;
2219 default:
2220 ret = -1;
2221 goto end;
2222 }
2223
2224 type_id = type->declaration->id;
2225 if (set_byte_order_funcs[type_id]) {
2226 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
2227 }
2228end:
2229 return ret;
2230}
2231
5ad19bf0 2232BT_HIDDEN
1c822dfb
JG
2233enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
2234 struct bt_ctf_field_type *type)
2235{
2236 if (!type) {
2237 return BT_CTF_TYPE_ID_UNKNOWN;
2238 }
2239
2240 return type->declaration->id;
2241}
2242
5ad19bf0 2243BT_HIDDEN
1c822dfb
JG
2244int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2245{
2246 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
2247}
2248
5ad19bf0 2249BT_HIDDEN
1c822dfb
JG
2250int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2251{
2252 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
2253}
2254
5ad19bf0 2255BT_HIDDEN
1c822dfb
JG
2256int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2257{
2258 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
2259}
2260
5ad19bf0 2261BT_HIDDEN
1c822dfb
JG
2262int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2263{
2264 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
2265}
2266
5ad19bf0 2267BT_HIDDEN
1c822dfb
JG
2268int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2269{
2270 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
2271}
2272
5ad19bf0 2273BT_HIDDEN
1c822dfb
JG
2274int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2275{
2276 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
2277}
2278
5ad19bf0 2279BT_HIDDEN
1c822dfb
JG
2280int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2281{
2282 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
2283}
2284
5ad19bf0 2285BT_HIDDEN
1c822dfb
JG
2286int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2287{
2288 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
2289}
2290
2291void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2292{
2293 bt_get(type);
2294}
2295
2296void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2297{
2298 bt_put(type);
2299}
2300
2301BT_HIDDEN
2302void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2303{
2304 if (!type) {
2305 return;
2306 }
2307
2308 type->freeze(type);
2309}
2310
2311BT_HIDDEN
2312struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2313 struct bt_ctf_field_type_variant *variant,
2314 int64_t tag_value)
2315{
2316 struct bt_ctf_field_type *type = NULL;
2317 GQuark field_name_quark;
2318 gpointer index;
2319 struct structure_field *field_entry;
2320 struct range_overlap_query query = {
2321 .range_start._signed = tag_value,
2322 .range_end._signed = tag_value,
2323 .mapping_name = 0, .overlaps = 0};
2324
2325 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2326 &query);
2327 if (!query.overlaps) {
2328 goto end;
2329 }
2330
2331 field_name_quark = query.mapping_name;
2332 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2333 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2334 goto end;
2335 }
2336
2337 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
2338 type = field_entry->type;
2339end:
2340 return type;
2341}
2342
2343BT_HIDDEN
2344struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
2345 struct bt_ctf_field_type_variant *variant,
2346 uint64_t tag_value)
2347{
2348 struct bt_ctf_field_type *type = NULL;
2349 GQuark field_name_quark;
2350 gpointer index;
2351 struct structure_field *field_entry;
2352 struct range_overlap_query query = {
2353 .range_start._unsigned = tag_value,
2354 .range_end._unsigned = tag_value,
2355 .mapping_name = 0, .overlaps = 0};
2356
2357 g_ptr_array_foreach(variant->tag->entries,
2358 check_ranges_overlap_unsigned,
2359 &query);
2360 if (!query.overlaps) {
2361 goto end;
2362 }
2363
2364 field_name_quark = query.mapping_name;
2365 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2366 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2367 goto end;
2368 }
2369
2370 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2371 type = field_entry->type;
2372end:
2373 return type;
2374}
2375
2376BT_HIDDEN
2377int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2378 struct metadata_context *context)
2379{
2380 int ret;
2381
2382 if (!type || !context) {
2383 ret = -1;
2384 goto end;
2385 }
2386
2387 /* Make sure field type is valid before serializing it */
2388 ret = bt_ctf_field_type_validate(type);
2389
2390 if (ret) {
2391 goto end;
2392 }
2393
2394 ret = type->serialize(type, context);
2395end:
2396 return ret;
2397}
2398
2399BT_HIDDEN
2400void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2401 int byte_order)
2402{
2403 if (!type) {
2404 return;
2405 }
2406
2407 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2408 if (set_byte_order_funcs[type->declaration->id]) {
2409 set_byte_order_funcs[type->declaration->id](type,
2410 byte_order, 1);
2411 }
2412}
2413
2414BT_HIDDEN
2415struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2416{
2417 struct bt_ctf_field_type *copy = NULL;
2418
2419 if (!type) {
2420 goto end;
2421 }
2422
2423 copy = type_copy_funcs[type->declaration->id](type);
2424end:
2425 return copy;
2426}
2427
2428BT_HIDDEN
2429int bt_ctf_field_type_structure_get_field_name_index(
2430 struct bt_ctf_field_type *type, const char *name)
2431{
2432 int ret;
2433 size_t index;
2434 GQuark name_quark;
2435 struct bt_ctf_field_type_structure *structure;
2436
2437 if (!type || !name ||
2438 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2439 ret = -1;
2440 goto end;
2441 }
2442
2443 name_quark = g_quark_try_string(name);
2444 if (!name_quark) {
2445 ret = -1;
2446 goto end;
2447 }
2448
2449 structure = container_of(type, struct bt_ctf_field_type_structure,
2450 parent);
2451 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2452 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2453 ret = -1;
2454 goto end;
2455 }
2456 ret = (int) index;
2457end:
2458 return ret;
2459}
2460
2461BT_HIDDEN
2462int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2463 struct bt_ctf_field_type *field, int index)
2464{
2465 int ret = 0;
2466 struct bt_ctf_field_type_structure *structure;
2467
2468 if (!type || !field ||
2469 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2470 ret = -1;
2471 goto end;
2472 }
2473
2474 structure = container_of(type, struct bt_ctf_field_type_structure,
2475 parent);
2476 if (index < 0 || index >= structure->fields->len) {
2477 ret = -1;
2478 goto end;
2479 }
2480
2481 bt_get(field);
2482 bt_put(((struct structure_field *)
2483 g_ptr_array_index(structure->fields, index))->type);
2484 ((struct structure_field *) structure->fields->pdata[index])->type =
2485 field;
2486end:
2487 return ret;
2488}
2489
2490BT_HIDDEN
2491int bt_ctf_field_type_variant_get_field_name_index(
2492 struct bt_ctf_field_type *type, const char *name)
2493{
2494 int ret;
2495 size_t index;
2496 GQuark name_quark;
2497 struct bt_ctf_field_type_variant *variant;
2498
2499 if (!type || !name ||
2500 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2501 ret = -1;
2502 goto end;
2503 }
2504
2505 name_quark = g_quark_try_string(name);
2506 if (!name_quark) {
2507 ret = -1;
2508 goto end;
2509 }
2510
2511 variant = container_of(type, struct bt_ctf_field_type_variant,
2512 parent);
2513 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2514 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2515 ret = -1;
2516 goto end;
2517 }
2518 ret = (int) index;
2519end:
2520 return ret;
2521}
2522
2523BT_HIDDEN
2524int bt_ctf_field_type_sequence_set_length_field_path(
2525 struct bt_ctf_field_type *type,
2526 struct bt_ctf_field_path *path)
2527{
2528 int ret = 0;
2529 struct bt_ctf_field_type_sequence *sequence;
2530
2531 if (!type || bt_ctf_field_type_get_type_id(type) !=
2532 BT_CTF_TYPE_ID_SEQUENCE) {
2533 ret = -1;
2534 goto end;
2535 }
2536
2537 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2538 parent);
2539 bt_get(path);
2540 BT_MOVE(sequence->length_field_path, path);
2541end:
2542 return ret;
2543}
2544
2545BT_HIDDEN
2546int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2547 struct bt_ctf_field_path *path)
2548{
2549 int ret = 0;
2550 struct bt_ctf_field_type_variant *variant;
2551
2552 if (!type || bt_ctf_field_type_get_type_id(type) !=
2553 BT_CTF_TYPE_ID_VARIANT) {
2554 ret = -1;
2555 goto end;
2556 }
2557
2558 variant = container_of(type, struct bt_ctf_field_type_variant,
2559 parent);
2560 bt_get(path);
2561 BT_MOVE(variant->tag_field_path, path);
2562end:
2563 return ret;
2564}
2565
2566BT_HIDDEN
2567int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
2568 struct bt_ctf_field_type *tag)
2569{
2570 int ret = 0;
2571 struct bt_ctf_field_type_variant *variant;
2572
2573 if (!type || !tag ||
2574 bt_ctf_field_type_get_type_id(tag) !=
2575 BT_CTF_TYPE_ID_ENUM) {
2576 ret = -1;
2577 goto end;
2578 }
2579
2580 variant = container_of(type, struct bt_ctf_field_type_variant,
2581 parent);
2582 bt_get(tag);
2583 if (variant->tag) {
2584 bt_put(&variant->tag->parent);
2585 }
2586 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2587 parent);
2588end:
2589 return ret;
2590}
2591
2592BT_HIDDEN
2593int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2594 struct bt_ctf_field_type *field, int index)
2595{
2596 int ret = 0;
2597 struct bt_ctf_field_type_variant *variant;
2598
2599 if (!type || !field ||
2600 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2601 ret = -1;
2602 goto end;
2603 }
2604
2605 variant = container_of(type, struct bt_ctf_field_type_variant,
2606 parent);
2607 if (index < 0 || index >= variant->fields->len) {
2608 ret = -1;
2609 goto end;
2610 }
2611
2612 bt_get(field);
2613 bt_put(((struct structure_field *)
2614 g_ptr_array_index(variant->fields, index))->type);
2615 ((struct structure_field *) variant->fields->pdata[index])->type =
2616 field;
2617end:
2618 return ret;
2619}
2620
2621static
2622void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
2623{
2624 struct bt_ctf_field_type_integer *integer =
2625 (struct bt_ctf_field_type_integer *) type;
2626
2627 if (!type) {
2628 return;
2629 }
2630
2631 bt_put(integer->mapped_clock);
2632 g_free(integer);
2633}
2634
2635static
2636void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
2637{
2638 struct bt_ctf_field_type_enumeration *enumeration =
2639 (struct bt_ctf_field_type_enumeration *) type;
2640
2641 if (!type) {
2642 return;
2643 }
2644
2645 g_ptr_array_free(enumeration->entries, TRUE);
2646 bt_put(enumeration->container);
2647 g_free(enumeration);
2648}
2649
2650static
2651void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
2652{
2653 struct bt_ctf_field_type_floating_point *floating_point =
2654 (struct bt_ctf_field_type_floating_point *) type;
2655
2656 if (!type) {
2657 return;
2658 }
2659
2660 g_free(floating_point);
2661}
2662
2663static
2664void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
2665{
2666 struct bt_ctf_field_type_structure *structure =
2667 (struct bt_ctf_field_type_structure *) type;
2668
2669 if (!type) {
2670 return;
2671 }
2672
2673 g_ptr_array_free(structure->fields, TRUE);
2674 g_hash_table_destroy(structure->field_name_to_index);
2675 g_free(structure);
2676}
2677
2678static
2679void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
2680{
2681 struct bt_ctf_field_type_variant *variant =
2682 (struct bt_ctf_field_type_variant *) type;
2683
2684 if (!type) {
2685 return;
2686 }
2687
2688 g_ptr_array_free(variant->fields, TRUE);
2689 g_hash_table_destroy(variant->field_name_to_index);
2690 g_string_free(variant->tag_name, TRUE);
2691 bt_put(&variant->tag->parent);
2692 BT_PUT(variant->tag_field_path);
2693 g_free(variant);
2694}
2695
2696static
2697void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
2698{
2699 struct bt_ctf_field_type_array *array =
2700 (struct bt_ctf_field_type_array *) type;
2701
2702 if (!type) {
2703 return;
2704 }
2705
2706 bt_put(array->element_type);
2707 g_free(array);
2708}
2709
2710static
2711void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
2712{
2713 struct bt_ctf_field_type_sequence *sequence =
2714 (struct bt_ctf_field_type_sequence *) type;
2715
2716 if (!type) {
2717 return;
2718 }
2719
2720 bt_put(sequence->element_type);
2721 g_string_free(sequence->length_field_name, TRUE);
2722 BT_PUT(sequence->length_field_path);
2723 g_free(sequence);
2724}
2725
2726static
2727void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
2728{
2729 struct bt_ctf_field_type_string *string =
2730 (struct bt_ctf_field_type_string *) type;
2731
2732 if (!type) {
2733 return;
2734 }
2735
2736 g_free(string);
2737}
2738
2739static
2740void generic_field_type_freeze(struct bt_ctf_field_type *type)
2741{
2742 type->frozen = 1;
2743}
2744
2745static
2746void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2747{
2748 struct bt_ctf_field_type_integer *integer_type = container_of(
2749 type, struct bt_ctf_field_type_integer, parent);
2750
2751 if (integer_type->mapped_clock) {
2752 bt_ctf_clock_freeze(integer_type->mapped_clock);
2753 }
2754
2755 generic_field_type_freeze(type);
2756}
2757
2758static
2759void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2760{
2761 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2762 type, struct bt_ctf_field_type_enumeration, parent);
2763
2764 generic_field_type_freeze(type);
2765 bt_ctf_field_type_freeze(enumeration_type->container);
2766}
2767
2768static
2769void freeze_structure_field(struct structure_field *field)
2770{
2771 bt_ctf_field_type_freeze(field->type);
2772}
2773
2774static
2775void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2776{
2777 struct bt_ctf_field_type_structure *structure_type = container_of(
2778 type, struct bt_ctf_field_type_structure, parent);
2779
2780 /* Cache the alignment */
2781 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2782 generic_field_type_freeze(type);
2783 g_ptr_array_foreach(structure_type->fields,
2784 (GFunc) freeze_structure_field, NULL);
2785}
2786
2787static
2788void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2789{
2790 struct bt_ctf_field_type_variant *variant_type = container_of(
2791 type, struct bt_ctf_field_type_variant, parent);
2792
2793 generic_field_type_freeze(type);
2794 g_ptr_array_foreach(variant_type->fields,
2795 (GFunc) freeze_structure_field, NULL);
2796}
2797
2798static
2799void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2800{
2801 struct bt_ctf_field_type_array *array_type = container_of(
2802 type, struct bt_ctf_field_type_array, parent);
2803
2804 /* Cache the alignment */
2805 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2806 generic_field_type_freeze(type);
2807 bt_ctf_field_type_freeze(array_type->element_type);
2808}
2809
2810static
2811void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2812{
2813 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2814 type, struct bt_ctf_field_type_sequence, parent);
2815
2816 /* Cache the alignment */
2817 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2818 generic_field_type_freeze(type);
2819 bt_ctf_field_type_freeze(sequence_type->element_type);
2820}
2821
2822static
2823const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
2824{
2825 const char *encoding_string;
2826
2827 switch (encoding) {
2828 case BT_CTF_STRING_ENCODING_NONE:
2829 encoding_string = "none";
2830 break;
2831 case BT_CTF_STRING_ENCODING_ASCII:
2832 encoding_string = "ASCII";
2833 break;
2834 case BT_CTF_STRING_ENCODING_UTF8:
2835 encoding_string = "UTF8";
2836 break;
2837 default:
2838 encoding_string = "unknown";
2839 break;
2840 }
2841
2842 return encoding_string;
2843}
2844
2845static
2846const char *get_integer_base_string(enum bt_ctf_integer_base base)
2847{
2848 const char *base_string;
2849
2850 switch (base) {
2851 case BT_CTF_INTEGER_BASE_DECIMAL:
2852 base_string = "decimal";
2853 break;
2854 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2855 base_string = "hexadecimal";
2856 break;
2857 case BT_CTF_INTEGER_BASE_OCTAL:
2858 base_string = "octal";
2859 break;
2860 case BT_CTF_INTEGER_BASE_BINARY:
2861 base_string = "binary";
2862 break;
2863 default:
2864 base_string = "unknown";
2865 break;
2866 }
2867
2868 return base_string;
2869}
2870
2871static
2872int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2873 struct metadata_context *context)
2874{
2875 struct bt_ctf_field_type_integer *integer = container_of(type,
2876 struct bt_ctf_field_type_integer, parent);
2877 int ret = 0;
2878
2879 g_string_append_printf(context->string,
2880 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2881 integer->declaration.len, type->declaration->alignment,
2882 (integer->declaration.signedness ? "true" : "false"),
2883 get_encoding_string(integer->declaration.encoding),
2884 get_integer_base_string(integer->declaration.base),
2885 get_byte_order_string(integer->declaration.byte_order));
2886 if (integer->mapped_clock) {
2887 const char *clock_name = bt_ctf_clock_get_name(
2888 integer->mapped_clock);
2889
2890 if (!clock_name) {
2891 ret = -1;
2892 goto end;
2893 }
2894
2895 g_string_append_printf(context->string,
2896 "; map = clock.%s.value", clock_name);
2897 }
2898
2899 g_string_append(context->string, "; }");
2900end:
2901 return ret;
2902}
2903
2904static
2905int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2906 struct metadata_context *context)
2907{
2908 size_t entry;
2909 int ret;
2910 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2911 struct bt_ctf_field_type_enumeration, parent);
2912 struct bt_ctf_field_type *container_type;
2913 int container_signed;
2914
2915 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2916 if (!container_type) {
2917 ret = -1;
2918 goto end;
2919 }
2920
2921 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2922 if (container_signed < 0) {
2923 ret = container_signed;
2924 goto error_put_container_type;
2925 }
2926
2927 g_string_append(context->string, "enum : ");
2928 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2929 if (ret) {
2930 goto error_put_container_type;
2931 }
2932
2933 g_string_append(context->string, " { ");
2934 for (entry = 0; entry < enumeration->entries->len; entry++) {
2935 struct enumeration_mapping *mapping =
2936 enumeration->entries->pdata[entry];
2937
2938 if (container_signed) {
2939 if (mapping->range_start._signed ==
2940 mapping->range_end._signed) {
2941 g_string_append_printf(context->string,
2942 "\"%s\" = %" PRId64,
2943 g_quark_to_string(mapping->string),
2944 mapping->range_start._signed);
2945 } else {
2946 g_string_append_printf(context->string,
2947 "\"%s\" = %" PRId64 " ... %" PRId64,
2948 g_quark_to_string(mapping->string),
2949 mapping->range_start._signed,
2950 mapping->range_end._signed);
2951 }
2952 } else {
2953 if (mapping->range_start._unsigned ==
2954 mapping->range_end._unsigned) {
2955 g_string_append_printf(context->string,
2956 "\"%s\" = %" PRIu64,
2957 g_quark_to_string(mapping->string),
2958 mapping->range_start._unsigned);
2959 } else {
2960 g_string_append_printf(context->string,
2961 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2962 g_quark_to_string(mapping->string),
2963 mapping->range_start._unsigned,
2964 mapping->range_end._unsigned);
2965 }
2966 }
2967
2968 g_string_append(context->string,
2969 ((entry != (enumeration->entries->len - 1)) ?
2970 ", " : " }"));
2971 }
2972
2973 if (context->field_name->len) {
2974 g_string_append_printf(context->string, " %s",
2975 context->field_name->str);
2976 g_string_assign(context->field_name, "");
2977 }
2978error_put_container_type:
2979 bt_put(container_type);
2980end:
2981 return ret;
2982}
2983
2984static
2985int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2986 struct metadata_context *context)
2987{
2988 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2989 type, struct bt_ctf_field_type_floating_point, parent);
2990
2991 g_string_append_printf(context->string,
2992 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2993 floating_point->declaration.exp->len,
2994 floating_point->declaration.mantissa->len + 1,
2995 get_byte_order_string(floating_point->declaration.byte_order),
2996 type->declaration->alignment);
2997 return 0;
2998}
2999
3000static
3001int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
3002 struct metadata_context *context)
3003{
3004 size_t i;
3005 unsigned int indent;
3006 int ret = 0;
3007 struct bt_ctf_field_type_structure *structure = container_of(type,
3008 struct bt_ctf_field_type_structure, parent);
3009 GString *structure_field_name = context->field_name;
3010
3011 context->field_name = g_string_new("");
3012
3013 context->current_indentation_level++;
3014 g_string_append(context->string, "struct {\n");
3015
3016 for (i = 0; i < structure->fields->len; i++) {
3017 struct structure_field *field;
3018
3019 for (indent = 0; indent < context->current_indentation_level;
3020 indent++) {
3021 g_string_append_c(context->string, '\t');
3022 }
3023
3024 field = structure->fields->pdata[i];
3025 g_string_assign(context->field_name,
3026 g_quark_to_string(field->name));
3027 ret = bt_ctf_field_type_serialize(field->type, context);
3028 if (ret) {
3029 goto end;
3030 }
3031
3032 if (context->field_name->len) {
3033 g_string_append_printf(context->string, " %s",
3034 context->field_name->str);
3035 }
3036 g_string_append(context->string, ";\n");
3037 }
3038
3039 context->current_indentation_level--;
3040 for (indent = 0; indent < context->current_indentation_level;
3041 indent++) {
3042 g_string_append_c(context->string, '\t');
3043 }
3044
3045 g_string_append_printf(context->string, "} align(%zu)",
3046 type->declaration->alignment);
3047end:
3048 g_string_free(context->field_name, TRUE);
3049 context->field_name = structure_field_name;
3050 return ret;
3051}
3052
3053static
3054int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3055 struct metadata_context *context)
3056{
3057 size_t i;
3058 unsigned int indent;
3059 int ret = 0;
3060 struct bt_ctf_field_type_variant *variant = container_of(
3061 type, struct bt_ctf_field_type_variant, parent);
3062 GString *variant_field_name = context->field_name;
3063
3064 context->field_name = g_string_new("");
3065 if (variant->tag_name->len > 0) {
3066 g_string_append_printf(context->string,
3067 "variant <%s> {\n", variant->tag_name->str);
3068 } else {
3069 g_string_append(context->string, "variant {\n");
3070 }
3071
3072 context->current_indentation_level++;
3073 for (i = 0; i < variant->fields->len; i++) {
3074 struct structure_field *field = variant->fields->pdata[i];
3075
3076 g_string_assign(context->field_name,
3077 g_quark_to_string(field->name));
3078 for (indent = 0; indent < context->current_indentation_level;
3079 indent++) {
3080 g_string_append_c(context->string, '\t');
3081 }
3082
3083 g_string_assign(context->field_name,
3084 g_quark_to_string(field->name));
3085 ret = bt_ctf_field_type_serialize(field->type, context);
3086 if (ret) {
3087 goto end;
3088 }
3089
3090 if (context->field_name->len) {
3091 g_string_append_printf(context->string, " %s;",
3092 context->field_name->str);
3093 }
3094
3095 g_string_append_c(context->string, '\n');
3096 }
3097
3098 context->current_indentation_level--;
3099 for (indent = 0; indent < context->current_indentation_level;
3100 indent++) {
3101 g_string_append_c(context->string, '\t');
3102 }
3103
3104 g_string_append(context->string, "}");
3105end:
3106 g_string_free(context->field_name, TRUE);
3107 context->field_name = variant_field_name;
3108 return ret;
3109}
3110
3111static
3112int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3113 struct metadata_context *context)
3114{
3115 int ret = 0;
3116 struct bt_ctf_field_type_array *array = container_of(type,
3117 struct bt_ctf_field_type_array, parent);
3118
3119 ret = bt_ctf_field_type_serialize(array->element_type, context);
3120 if (ret) {
3121 goto end;
3122 }
3123
3124 if (context->field_name->len) {
3125 g_string_append_printf(context->string, " %s[%u]",
3126 context->field_name->str, array->length);
3127 g_string_assign(context->field_name, "");
3128 } else {
3129 g_string_append_printf(context->string, "[%u]", array->length);
3130 }
3131end:
3132 return ret;
3133}
3134
3135static
3136int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3137 struct metadata_context *context)
3138{
3139 int ret = 0;
3140 struct bt_ctf_field_type_sequence *sequence = container_of(
3141 type, struct bt_ctf_field_type_sequence, parent);
3142
3143 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3144 if (ret) {
3145 goto end;
3146 }
3147
3148 if (context->field_name->len) {
3149 g_string_append_printf(context->string, " %s[%s]",
3150 context->field_name->str,
3151 sequence->length_field_name->str);
3152 g_string_assign(context->field_name, "");
3153 } else {
3154 g_string_append_printf(context->string, "[%s]",
3155 sequence->length_field_name->str);
3156 }
3157end:
3158 return ret;
3159}
3160
3161static
3162int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3163 struct metadata_context *context)
3164{
3165 struct bt_ctf_field_type_string *string = container_of(
3166 type, struct bt_ctf_field_type_string, parent);
3167
3168 g_string_append_printf(context->string,
3169 "string { encoding = %s; }",
3170 get_encoding_string(string->declaration.encoding));
3171 return 0;
3172}
3173
3174static
3175enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3176 enum bt_ctf_byte_order ret;
3177
3178 switch (byte_order) {
3179 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3180 case LITTLE_ENDIAN:
3181 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3182 break;
3183 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3184 case BIG_ENDIAN:
3185 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3186 break;
3187 case BT_CTF_BYTE_ORDER_NETWORK:
3188 ret = BT_CTF_BYTE_ORDER_NETWORK;
3189 break;
3190 case BT_CTF_BYTE_ORDER_NATIVE:
3191 ret = BT_CTF_BYTE_ORDER_NATIVE;
3192 break;
3193 default:
3194 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3195 break;
3196 }
3197
3198 return ret;
3199}
3200
3201static
3202void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
3203 int byte_order, int set_native)
3204{
3205 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3206 struct bt_ctf_field_type_integer, parent);
3207
3208 if (set_native) {
3209 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3210 /*
3211 * User byte order is native, so we can set
3212 * the real byte order.
3213 */
3214 integer_type->declaration.byte_order =
3215 byte_order;
3216 }
3217 } else {
3218 integer_type->user_byte_order =
3219 get_ctf_ir_byte_order(byte_order);
3220 integer_type->declaration.byte_order = byte_order;
3221 }
3222}
3223
3224static
3225void bt_ctf_field_type_enumeration_set_byte_order(
3226 struct bt_ctf_field_type *type, int byte_order, int set_native)
3227{
3228 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3229 struct bt_ctf_field_type_enumeration, parent);
3230
3231 /* Safe to assume that container is an integer */
3232 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3233 byte_order, set_native);
3234}
3235
3236static
3237void bt_ctf_field_type_floating_point_set_byte_order(
3238 struct bt_ctf_field_type *type, int byte_order, int set_native)
3239{
3240 struct bt_ctf_field_type_floating_point *floating_point_type =
3241 container_of(type, struct bt_ctf_field_type_floating_point,
3242 parent);
3243
3244 if (set_native) {
3245 if (floating_point_type->user_byte_order ==
3246 BT_CTF_BYTE_ORDER_NATIVE) {
3247 /*
3248 * User byte order is native, so we can set
3249 * the real byte order.
3250 */
3251 floating_point_type->declaration.byte_order =
3252 byte_order;
3253 floating_point_type->sign.byte_order =
3254 byte_order;
3255 floating_point_type->mantissa.byte_order =
3256 byte_order;
3257 floating_point_type->exp.byte_order =
3258 byte_order;
3259 }
3260 } else {
3261 floating_point_type->user_byte_order =
3262 get_ctf_ir_byte_order(byte_order);
3263 floating_point_type->declaration.byte_order = byte_order;
3264 floating_point_type->sign.byte_order = byte_order;
3265 floating_point_type->mantissa.byte_order = byte_order;
3266 floating_point_type->exp.byte_order = byte_order;
3267 }
3268}
3269
3270static
3271void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3272 int byte_order, int set_native)
3273{
3274 int i;
3275 struct bt_ctf_field_type_structure *structure_type =
3276 container_of(type, struct bt_ctf_field_type_structure,
3277 parent);
3278
3279 for (i = 0; i < structure_type->fields->len; i++) {
3280 struct structure_field *field = g_ptr_array_index(
3281 structure_type->fields, i);
3282 struct bt_ctf_field_type *field_type = field->type;
3283
3284 if (set_byte_order_funcs[field_type->declaration->id]) {
3285 set_byte_order_funcs[field_type->declaration->id](
3286 field_type, byte_order, set_native);
3287 }
3288 }
3289}
3290
3291static
3292void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3293 int byte_order, int set_native)
3294{
3295 int i;
3296 struct bt_ctf_field_type_variant *variant_type =
3297 container_of(type, struct bt_ctf_field_type_variant,
3298 parent);
3299
3300 for (i = 0; i < variant_type->fields->len; i++) {
3301 struct structure_field *field = g_ptr_array_index(
3302 variant_type->fields, i);
3303 struct bt_ctf_field_type *field_type = field->type;
3304
3305 if (set_byte_order_funcs[field_type->declaration->id]) {
3306 set_byte_order_funcs[field_type->declaration->id](
3307 field_type, byte_order, set_native);
3308 }
3309 }
3310}
3311
3312static
3313void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3314 int byte_order, int set_native)
3315{
3316 struct bt_ctf_field_type_array *array_type =
3317 container_of(type, struct bt_ctf_field_type_array,
3318 parent);
3319
3320 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3321 set_byte_order_funcs[array_type->element_type->declaration->id](
3322 array_type->element_type, byte_order, set_native);
3323 }
3324}
3325
3326static
3327void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3328 int byte_order, int set_native)
3329{
3330 struct bt_ctf_field_type_sequence *sequence_type =
3331 container_of(type, struct bt_ctf_field_type_sequence,
3332 parent);
3333
3334 if (set_byte_order_funcs[
3335 sequence_type->element_type->declaration->id]) {
3336 set_byte_order_funcs[
3337 sequence_type->element_type->declaration->id](
3338 sequence_type->element_type, byte_order, set_native);
3339 }
3340}
3341
3342static
3343struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3344 struct bt_ctf_field_type *type)
3345{
3346 struct bt_ctf_field_type *copy;
3347 struct bt_ctf_field_type_integer *integer, *copy_integer;
3348
3349 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3350 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3351 if (!copy) {
3352 goto end;
3353 }
3354
3355 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3356 parent);
3357 copy_integer->declaration = integer->declaration;
3358 if (integer->mapped_clock) {
3359 bt_get(integer->mapped_clock);
3360 copy_integer->mapped_clock = integer->mapped_clock;
3361 }
3362
3363 copy_integer->user_byte_order = integer->user_byte_order;
3364
3365end:
3366 return copy;
3367}
3368
3369static
3370struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3371 struct bt_ctf_field_type *type)
3372{
3373 size_t i;
3374 struct bt_ctf_field_type *copy = NULL, *copy_container;
3375 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3376
3377 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3378 parent);
3379
3380 /* Copy the source enumeration's container */
3381 copy_container = bt_ctf_field_type_copy(enumeration->container);
3382 if (!copy_container) {
3383 goto end;
3384 }
3385
3386 copy = bt_ctf_field_type_enumeration_create(copy_container);
3387 if (!copy) {
3388 goto end;
3389 }
3390 copy_enumeration = container_of(copy,
3391 struct bt_ctf_field_type_enumeration, parent);
3392
3393 /* Copy all enumaration entries */
3394 for (i = 0; i < enumeration->entries->len; i++) {
3395 struct enumeration_mapping *mapping = g_ptr_array_index(
3396 enumeration->entries, i);
3397 struct enumeration_mapping* copy_mapping = g_new0(
3398 struct enumeration_mapping, 1);
3399
3400 if (!copy_mapping) {
3401 goto error;
3402 }
3403
3404 *copy_mapping = *mapping;
3405 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3406 }
3407
3408 copy_enumeration->declaration = enumeration->declaration;
3409end:
3410 bt_put(copy_container);
3411 return copy;
3412error:
3413 bt_put(copy_container);
3414 BT_PUT(copy);
3415 return copy;
3416}
3417
3418static
3419struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3420 struct bt_ctf_field_type *type)
3421{
3422 struct bt_ctf_field_type *copy;
3423 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3424
3425 floating_point = container_of(type,
3426 struct bt_ctf_field_type_floating_point, parent);
3427 copy = bt_ctf_field_type_floating_point_create();
3428 if (!copy) {
3429 goto end;
3430 }
3431
3432 copy_float = container_of(copy,
3433 struct bt_ctf_field_type_floating_point, parent);
3434 copy_float->declaration = floating_point->declaration;
3435 copy_float->sign = floating_point->sign;
3436 copy_float->mantissa = floating_point->mantissa;
3437 copy_float->exp = floating_point->exp;
3438 copy_float->user_byte_order = floating_point->user_byte_order;
3439 copy_float->declaration.sign = &copy_float->sign;
3440 copy_float->declaration.mantissa = &copy_float->mantissa;
3441 copy_float->declaration.exp = &copy_float->exp;
3442end:
3443 return copy;
3444}
3445
3446static
3447struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3448 struct bt_ctf_field_type *type)
3449{
3450 int i;
3451 GHashTableIter iter;
3452 gpointer key, value;
3453 struct bt_ctf_field_type *copy;
3454 struct bt_ctf_field_type_structure *structure, *copy_structure;
3455
3456 structure = container_of(type, struct bt_ctf_field_type_structure,
3457 parent);
3458 copy = bt_ctf_field_type_structure_create();
3459 if (!copy) {
3460 goto end;
3461 }
3462
3463 copy_structure = container_of(copy,
3464 struct bt_ctf_field_type_structure, parent);
3465
3466 /* Copy field_name_to_index */
3467 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3468 while (g_hash_table_iter_next (&iter, &key, &value)) {
3469 g_hash_table_insert(copy_structure->field_name_to_index,
3470 key, value);
3471 }
3472
3473 for (i = 0; i < structure->fields->len; i++) {
3474 struct structure_field *entry, *copy_entry;
3475 struct bt_ctf_field_type *copy_field;
3476
3477 copy_entry = g_new0(struct structure_field, 1);
3478 if (!copy_entry) {
3479 goto error;
3480 }
3481
3482 entry = g_ptr_array_index(structure->fields, i);
3483 copy_field = bt_ctf_field_type_copy(entry->type);
3484 if (!copy_field) {
3485 g_free(copy_entry);
3486 goto error;
3487 }
3488
3489 copy_entry->name = entry->name;
3490 copy_entry->type = copy_field;
3491 g_ptr_array_add(copy_structure->fields, copy_entry);
3492 }
3493
3494 copy_structure->declaration = structure->declaration;
3495end:
3496 return copy;
3497error:
3498 BT_PUT(copy);
3499 return copy;
3500}
3501
3502static
3503struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3504 struct bt_ctf_field_type *type)
3505{
3506 int i;
3507 GHashTableIter iter;
3508 gpointer key, value;
3509 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3510 struct bt_ctf_field_type_variant *variant, *copy_variant;
3511
3512 variant = container_of(type, struct bt_ctf_field_type_variant,
3513 parent);
3514 if (variant->tag) {
3515 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3516 if (!copy_tag) {
3517 goto end;
3518 }
3519 }
3520
3521 copy = bt_ctf_field_type_variant_create(copy_tag,
3522 variant->tag_name->len ? variant->tag_name->str : NULL);
3523 if (!copy) {
3524 goto end;
3525 }
3526
3527 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3528 parent);
3529
3530 /* Copy field_name_to_index */
3531 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3532 while (g_hash_table_iter_next (&iter, &key, &value)) {
3533 g_hash_table_insert(copy_variant->field_name_to_index,
3534 key, value);
3535 }
3536
3537 for (i = 0; i < variant->fields->len; i++) {
3538 struct structure_field *entry, *copy_entry;
3539 struct bt_ctf_field_type *copy_field;
3540
3541 copy_entry = g_new0(struct structure_field, 1);
3542 if (!copy_entry) {
3543 goto error;
3544 }
3545
3546 entry = g_ptr_array_index(variant->fields, i);
3547 copy_field = bt_ctf_field_type_copy(entry->type);
3548 if (!copy_field) {
3549 g_free(copy_entry);
3550 goto error;
3551 }
3552
3553 copy_entry->name = entry->name;
3554 copy_entry->type = copy_field;
3555 g_ptr_array_add(copy_variant->fields, copy_entry);
3556 }
3557
3558 copy_variant->declaration = variant->declaration;
3559 if (variant->tag_field_path) {
3560 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3561 variant->tag_field_path);
3562 if (!copy_variant->tag_field_path) {
3563 goto error;
3564 }
3565 }
3566end:
3567 bt_put(copy_tag);
3568 return copy;
3569error:
3570 bt_put(copy_tag);
3571 BT_PUT(copy);
3572 return copy;
3573}
3574
3575static
3576struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3577 struct bt_ctf_field_type *type)
3578{
3579 struct bt_ctf_field_type *copy = NULL, *copy_element;
3580 struct bt_ctf_field_type_array *array, *copy_array;
3581
3582 array = container_of(type, struct bt_ctf_field_type_array,
3583 parent);
3584 copy_element = bt_ctf_field_type_copy(array->element_type);
3585 if (!copy_element) {
3586 goto end;
3587 }
3588
3589 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3590 if (!copy) {
3591 goto end;
3592 }
3593
3594 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3595 parent);
3596 copy_array->declaration = array->declaration;
3597end:
3598 bt_put(copy_element);
3599 return copy;
3600}
3601
3602static
3603struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3604 struct bt_ctf_field_type *type)
3605{
3606 struct bt_ctf_field_type *copy = NULL, *copy_element;
3607 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3608
3609 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3610 parent);
3611 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3612 if (!copy_element) {
3613 goto end;
3614 }
3615
3616 copy = bt_ctf_field_type_sequence_create(copy_element,
3617 sequence->length_field_name->len ?
3618 sequence->length_field_name->str : NULL);
3619 if (!copy) {
3620 goto end;
3621 }
3622
3623 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3624 parent);
3625 copy_sequence->declaration = sequence->declaration;
3626 if (sequence->length_field_path) {
3627 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3628 sequence->length_field_path);
3629 if (!copy_sequence->length_field_path) {
3630 goto error;
3631 }
3632 }
3633end:
3634 bt_put(copy_element);
3635 return copy;
3636error:
3637 BT_PUT(copy);
3638 goto end;
3639}
3640
3641static
3642struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3643 struct bt_ctf_field_type *type)
3644{
3645 struct bt_ctf_field_type *copy;
3646 struct bt_ctf_field_type_string *string, *copy_string;
3647
3648 copy = bt_ctf_field_type_string_create();
3649 if (!copy) {
3650 goto end;
3651 }
3652
3653 string = container_of(type, struct bt_ctf_field_type_string,
3654 parent);
3655 copy_string = container_of(type, struct bt_ctf_field_type_string,
3656 parent);
3657 copy_string->declaration = string->declaration;
3658end:
3659 return copy;
3660}
3661
3662static
3663int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3664 struct bt_ctf_field_type *type_b)
3665{
3666 int ret = 1;
3667 struct bt_ctf_field_type_integer *integer_a;
3668 struct bt_ctf_field_type_integer *integer_b;
3669 struct declaration_integer *decl_a;
3670 struct declaration_integer *decl_b;
3671
3672 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3673 parent);
3674 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3675 parent);
3676 decl_a = &integer_a->declaration;
3677 decl_b = &integer_b->declaration;
3678
3679 /* Length */
3680 if (decl_a->len != decl_b->len) {
3681 goto end;
3682 }
3683
3684 /*
3685 * Compare user byte orders only, not the cached,
3686 * real byte orders.
3687 */
3688 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3689 goto end;
3690 }
3691
3692 /* Signedness */
3693 if (decl_a->signedness != decl_b->signedness) {
3694 goto end;
3695 }
3696
3697 /* Base */
3698 if (decl_a->base != decl_b->base) {
3699 goto end;
3700 }
3701
3702 /* Encoding */
3703 if (decl_a->encoding != decl_b->encoding) {
3704 goto end;
3705 }
3706
3707 /* Mapped clock */
3708 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3709 goto end;
3710 }
3711
3712 /* Equal */
3713 ret = 0;
3714
3715end:
3716 return ret;
3717}
3718
3719static
3720int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3721 struct bt_ctf_field_type *type_b)
3722{
3723 int ret = 1;
3724 struct bt_ctf_field_type_floating_point *float_a;
3725 struct bt_ctf_field_type_floating_point *float_b;
3726
3727 float_a = container_of(type_a,
3728 struct bt_ctf_field_type_floating_point, parent);
3729 float_b = container_of(type_b,
3730 struct bt_ctf_field_type_floating_point, parent);
3731
3732 /* Sign length */
3733 if (float_a->sign.len != float_b->sign.len) {
3734 goto end;
3735 }
3736
3737 /* Exponent length */
3738 if (float_a->exp.len != float_b->exp.len) {
3739 goto end;
3740 }
3741
3742 /* Mantissa length */
3743 if (float_a->mantissa.len != float_b->mantissa.len) {
3744 goto end;
3745 }
3746
3747 /*
3748 * Compare user byte orders only, not the cached,
3749 * real byte orders.
3750 */
3751 if (float_a->user_byte_order != float_b->user_byte_order) {
3752 goto end;
3753 }
3754
3755 /* Equal */
3756 ret = 0;
3757
3758end:
3759 return ret;
3760}
3761
3762static
3763int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3764 struct enumeration_mapping *mapping_b)
3765{
3766 int ret = 1;
3767
3768 /* Label */
3769 if (mapping_a->string != mapping_b->string) {
3770 goto end;
3771 }
3772
3773 /* Range start */
3774 if (mapping_a->range_start._unsigned !=
3775 mapping_b->range_start._unsigned) {
3776 goto end;
3777 }
3778
3779 /* Range end */
3780 if (mapping_a->range_end._unsigned !=
3781 mapping_b->range_end._unsigned) {
3782 goto end;
3783 }
3784
3785 /* Equal */
3786 ret = 0;
3787
3788end:
3789 return ret;
3790}
3791
3792static
3793int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3794 struct bt_ctf_field_type *type_b)
3795{
3796 int ret = 1;
3797 int i;
3798 struct bt_ctf_field_type_enumeration *enum_a;
3799 struct bt_ctf_field_type_enumeration *enum_b;
3800
3801 enum_a = container_of(type_a,
3802 struct bt_ctf_field_type_enumeration, parent);
3803 enum_b = container_of(type_b,
3804 struct bt_ctf_field_type_enumeration, parent);
3805
3806 /* Container field type */
3807 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3808 if (ret) {
3809 goto end;
3810 }
3811
3812 ret = 1;
3813
3814 /* Entries */
3815 if (enum_a->entries->len != enum_b->entries->len) {
3816 goto end;
3817 }
3818
3819 for (i = 0; i < enum_a->entries->len; ++i) {
3820 struct enumeration_mapping *mapping_a =
3821 g_ptr_array_index(enum_a->entries, i);
3822 struct enumeration_mapping *mapping_b =
3823 g_ptr_array_index(enum_b->entries, i);
3824
3825 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3826 goto end;
3827 }
3828 }
3829
3830 /* Equal */
3831 ret = 0;
3832
3833end:
3834 return ret;
3835}
3836
3837static
3838int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3839 struct bt_ctf_field_type *type_b)
3840{
3841 int ret = 1;
3842 struct bt_ctf_field_type_string *string_a;
3843 struct bt_ctf_field_type_string *string_b;
3844
3845 string_a = container_of(type_a,
3846 struct bt_ctf_field_type_string, parent);
3847 string_b = container_of(type_b,
3848 struct bt_ctf_field_type_string, parent);
3849
3850 /* Encoding */
3851 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3852 goto end;
3853 }
3854
3855 /* Equal */
3856 ret = 0;
3857
3858end:
3859 return ret;
3860}
3861
3862static
3863int compare_structure_fields(struct structure_field *field_a,
3864 struct structure_field *field_b)
3865{
3866 int ret = 1;
3867
3868 /* Label */
3869 if (field_a->name != field_b->name) {
3870 goto end;
3871 }
3872
3873 /* Type */
3874 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3875
3876end:
3877 return ret;
3878}
3879
3880static
3881int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3882 struct bt_ctf_field_type *type_b)
3883{
3884 int ret = 1;
3885 int i;
3886 struct bt_ctf_field_type_structure *struct_a;
3887 struct bt_ctf_field_type_structure *struct_b;
3888
3889 struct_a = container_of(type_a,
3890 struct bt_ctf_field_type_structure, parent);
3891 struct_b = container_of(type_b,
3892 struct bt_ctf_field_type_structure, parent);
3893
3894 /* Alignment */
3895 if (bt_ctf_field_type_get_alignment(type_a) !=
3896 bt_ctf_field_type_get_alignment(type_b)) {
3897 goto end;
3898 }
3899
3900 /* Fields */
3901 if (struct_a->fields->len != struct_b->fields->len) {
3902 goto end;
3903 }
3904
3905 for (i = 0; i < struct_a->fields->len; ++i) {
3906 struct structure_field *field_a =
3907 g_ptr_array_index(struct_a->fields, i);
3908 struct structure_field *field_b =
3909 g_ptr_array_index(struct_b->fields, i);
3910
3911 ret = compare_structure_fields(field_a, field_b);
3912 if (ret) {
3913 goto end;
3914 }
3915 }
3916
3917 /* Equal */
3918 ret = 0;
3919
3920end:
3921 return ret;
3922}
3923
3924static
3925int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3926 struct bt_ctf_field_type *type_b)
3927{
3928 int ret = 1;
3929 int i;
3930 struct bt_ctf_field_type_variant *variant_a;
3931 struct bt_ctf_field_type_variant *variant_b;
3932
3933 variant_a = container_of(type_a,
3934 struct bt_ctf_field_type_variant, parent);
3935 variant_b = container_of(type_b,
3936 struct bt_ctf_field_type_variant, parent);
3937
3938 /* Tag name */
3939 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3940 goto end;
3941 }
3942
3943 /* Tag type */
3944 ret = bt_ctf_field_type_compare(
3945 (struct bt_ctf_field_type *) variant_a->tag,
3946 (struct bt_ctf_field_type *) variant_b->tag);
3947 if (ret) {
3948 goto end;
3949 }
3950
3951 ret = 1;
3952
3953 /* Fields */
3954 if (variant_a->fields->len != variant_b->fields->len) {
3955 goto end;
3956 }
3957
3958 for (i = 0; i < variant_a->fields->len; ++i) {
3959 struct structure_field *field_a =
3960 g_ptr_array_index(variant_a->fields, i);
3961 struct structure_field *field_b =
3962 g_ptr_array_index(variant_b->fields, i);
3963
3964 ret = compare_structure_fields(field_a, field_b);
3965 if (ret) {
3966 goto end;
3967 }
3968 }
3969
3970 /* Equal */
3971 ret = 0;
3972
3973end:
3974 return ret;
3975}
3976
3977static
3978int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3979 struct bt_ctf_field_type *type_b)
3980{
3981 int ret = 1;
3982 struct bt_ctf_field_type_array *array_a;
3983 struct bt_ctf_field_type_array *array_b;
3984
3985 array_a = container_of(type_a,
3986 struct bt_ctf_field_type_array, parent);
3987 array_b = container_of(type_b,
3988 struct bt_ctf_field_type_array, parent);
3989
3990 /* Length */
3991 if (array_a->length != array_b->length) {
3992 goto end;
3993 }
3994
3995 /* Element type */
3996 ret = bt_ctf_field_type_compare(array_a->element_type,
3997 array_b->element_type);
3998
3999end:
4000 return ret;
4001}
4002
4003static
4004int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
4005 struct bt_ctf_field_type *type_b)
4006{
4007 int ret = -1;
4008 struct bt_ctf_field_type_sequence *sequence_a;
4009 struct bt_ctf_field_type_sequence *sequence_b;
4010
4011 sequence_a = container_of(type_a,
4012 struct bt_ctf_field_type_sequence, parent);
4013 sequence_b = container_of(type_b,
4014 struct bt_ctf_field_type_sequence, parent);
4015
4016 /* Length name */
4017 if (strcmp(sequence_a->length_field_name->str,
4018 sequence_b->length_field_name->str)) {
4019 goto end;
4020 }
4021
4022 /* Element type */
4023 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4024 sequence_b->element_type);
4025
4026end:
4027 return ret;
4028}
4029
5ad19bf0 4030BT_HIDDEN
1c822dfb
JG
4031int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4032 struct bt_ctf_field_type *type_b)
4033{
4034 int ret = 1;
4035
4036 if (type_a == type_b) {
4037 /* Same reference: equal (even if both are NULL) */
4038 ret = 0;
4039 goto end;
4040 }
4041
4042 if (!type_a || !type_b) {
4043 ret = -1;
4044 goto end;
4045 }
4046
4047 if (type_a->declaration->id != type_b->declaration->id) {
4048 /* Different type IDs */
4049 goto end;
4050 }
4051
4052 if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
4053 /* Both have unknown type IDs */
4054 goto end;
4055 }
4056
4057 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4058
4059end:
4060 return ret;
4061}
4062
4063BT_HIDDEN
4064int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4065{
4066 int field_count = -1;
4067 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4068
4069 switch (type_id) {
4070 case CTF_TYPE_STRUCT:
4071 field_count =
4072 bt_ctf_field_type_structure_get_field_count(field_type);
4073 break;
4074 case CTF_TYPE_VARIANT:
4075 field_count =
4076 bt_ctf_field_type_variant_get_field_count(field_type);
4077 break;
4078 case CTF_TYPE_ARRAY:
4079 case CTF_TYPE_SEQUENCE:
4080 /*
4081 * Array and sequence types always contain a single member
4082 * (the element type).
4083 */
4084 field_count = 1;
4085 break;
4086 default:
4087 break;
4088 }
4089
4090 return field_count;
4091}
4092
4093BT_HIDDEN
4094struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4095 struct bt_ctf_field_type *field_type, int index)
4096{
4097 struct bt_ctf_field_type *field = NULL;
4098 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4099
4100 switch (type_id) {
4101 case CTF_TYPE_STRUCT:
4102 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4103 index);
4104 break;
4105 case CTF_TYPE_VARIANT:
4106 {
4107 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
4108 &field, index);
4109 if (ret) {
4110 field = NULL;
4111 goto end;
4112 }
4113 break;
4114 }
4115 case CTF_TYPE_ARRAY:
4116 field = bt_ctf_field_type_array_get_element_type(field_type);
4117 break;
4118 case CTF_TYPE_SEQUENCE:
4119 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4120 break;
4121 default:
4122 break;
4123 }
4124end:
4125 return field;
4126}
4127
4128BT_HIDDEN
4129int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4130 const char *name)
4131{
4132 int field_index = -1;
4133 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4134
4135 switch (type_id) {
4136 case CTF_TYPE_STRUCT:
4137 field_index = bt_ctf_field_type_structure_get_field_name_index(
4138 field_type, name);
4139 break;
4140 case CTF_TYPE_VARIANT:
4141 field_index = bt_ctf_field_type_variant_get_field_name_index(
4142 field_type, name);
4143 break;
4144 default:
4145 break;
4146 }
4147
4148 return field_index;
4149}
4150
5ad19bf0 4151BT_HIDDEN
1c822dfb
JG
4152struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4153 struct bt_ctf_field_type *type)
4154{
4155 struct bt_ctf_field_path *field_path = NULL;
4156 struct bt_ctf_field_type_variant *variant;
4157
4158 if (!type || !bt_ctf_field_type_is_variant(type)) {
4159 goto end;
4160 }
4161
4162 variant = container_of(type, struct bt_ctf_field_type_variant,
4163 parent);
4164 field_path = bt_get(variant->tag_field_path);
4165end:
4166 return field_path;
4167}
4168
5ad19bf0 4169BT_HIDDEN
1c822dfb
JG
4170struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
4171 struct bt_ctf_field_type *type)
4172{
4173 struct bt_ctf_field_path *field_path = NULL;
4174 struct bt_ctf_field_type_sequence *sequence;
4175
4176 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4177 goto end;
4178 }
4179
4180 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4181 parent);
4182 field_path = bt_get(sequence->length_field_path);
4183end:
4184 return field_path;
4185}
This page took 0.173115 seconds and 4 git commands to generate.