Allow unset tags on variant field types
[babeltrace.git] / formats / ctf / ir / event-types.c
CommitLineData
273b65be
JG
1/*
2 * event-types.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Event Types
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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-writer/event-types.h>
adc315b8 30#include <babeltrace/ctf-ir/event-types-internal.h>
654c1444 31#include <babeltrace/ctf-ir/utils.h>
6cfb906f 32#include <babeltrace/ctf-ir/clock.h>
273b65be
JG
33#include <babeltrace/ctf-writer/writer-internal.h>
34#include <babeltrace/compiler.h>
35#include <babeltrace/endian.h>
36#include <float.h>
37#include <inttypes.h>
a39fa057 38#include <stdlib.h>
273b65be
JG
39
40struct range_overlap_query {
b92ddaaa
JG
41 union {
42 uint64_t _unsigned;
43 int64_t _signed;
44 } range_start;
45
46 union {
47 uint64_t _unsigned;
48 int64_t _signed;
49 } range_end;
273b65be
JG
50 int overlaps;
51 GQuark mapping_name;
52};
53
2f2d8e05
JG
54static
55void bt_ctf_field_type_destroy(struct bt_ctf_ref *);
273b65be
JG
56static
57void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *);
58static
59void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *);
60static
61void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *);
62static
63void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *);
64static
65void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *);
66static
67void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *);
68static
69void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *);
70static
71void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *);
72
73static
74void (* const type_destroy_funcs[])(struct bt_ctf_ref *) = {
75 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_destroy,
76 [CTF_TYPE_ENUM] =
77 bt_ctf_field_type_enumeration_destroy,
78 [CTF_TYPE_FLOAT] =
79 bt_ctf_field_type_floating_point_destroy,
80 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_destroy,
81 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_destroy,
82 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_destroy,
83 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
84 [CTF_TYPE_STRING] = bt_ctf_field_type_string_destroy,
85};
86
87static
88void generic_field_type_freeze(struct bt_ctf_field_type *);
89static
90void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
91static
92void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
93static
94void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
95static
96void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
97static
98void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
99
100static
101type_freeze_func const type_freeze_funcs[] = {
102 [CTF_TYPE_INTEGER] = generic_field_type_freeze,
103 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_freeze,
104 [CTF_TYPE_FLOAT] = generic_field_type_freeze,
105 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_freeze,
106 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_freeze,
107 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_freeze,
108 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
109 [CTF_TYPE_STRING] = generic_field_type_freeze,
110};
111
112static
113int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
114 struct metadata_context *);
115static
116int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
117 struct metadata_context *);
118static
119int bt_ctf_field_type_floating_point_serialize(
120 struct bt_ctf_field_type *, struct metadata_context *);
121static
122int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
123 struct metadata_context *);
124static
125int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
126 struct metadata_context *);
127static
128int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
129 struct metadata_context *);
130static
131int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
132 struct metadata_context *);
133static
134int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
135 struct metadata_context *);
136
137static
138type_serialize_func const type_serialize_funcs[] = {
139 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_serialize,
140 [CTF_TYPE_ENUM] =
141 bt_ctf_field_type_enumeration_serialize,
142 [CTF_TYPE_FLOAT] =
143 bt_ctf_field_type_floating_point_serialize,
144 [CTF_TYPE_STRUCT] =
145 bt_ctf_field_type_structure_serialize,
146 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_serialize,
147 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_serialize,
148 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
149 [CTF_TYPE_STRING] = bt_ctf_field_type_string_serialize,
150};
151
152static
153void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
c35a1669
JG
154 int byte_order, int set_native);
155static
156void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
157 int byte_order, int set_native);
273b65be
JG
158static
159void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669
JG
160 struct bt_ctf_field_type *, int byte_order, int set_native);
161static
162void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
163 int byte_order, int set_native);
164static
165void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
166 int byte_order, int set_native);
167static
168void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
169 int byte_order, int set_native);
170static
171void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
172 int byte_order, int set_native);
273b65be 173
c35a1669 174/* The set_native flag only set the byte order if it is set to native */
273b65be
JG
175static
176void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
c35a1669
JG
177 int byte_order, int set_native) = {
178 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
179 [CTF_TYPE_ENUM] =
180 bt_ctf_field_type_enumeration_set_byte_order,
273b65be
JG
181 [CTF_TYPE_FLOAT] =
182 bt_ctf_field_type_floating_point_set_byte_order,
c35a1669
JG
183 [CTF_TYPE_STRUCT] =
184 bt_ctf_field_type_structure_set_byte_order,
185 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
186 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_set_byte_order,
187 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
188 [CTF_TYPE_STRING] = NULL,
273b65be
JG
189};
190
273b65be
JG
191static
192void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
193{
194 g_free(mapping);
195}
196
197static
198void destroy_structure_field(struct structure_field *field)
199{
200 if (field->type) {
201 bt_ctf_field_type_put(field->type);
202 }
203
204 g_free(field);
205}
206
207static
208void check_ranges_overlap(gpointer element, gpointer query)
209{
210 struct enumeration_mapping *mapping = element;
211 struct range_overlap_query *overlap_query = query;
212
b92ddaaa
JG
213 if (mapping->range_start._signed <= overlap_query->range_end._signed
214 && overlap_query->range_start._signed <=
215 mapping->range_end._signed) {
216 overlap_query->overlaps = 1;
217 overlap_query->mapping_name = mapping->string;
218 }
219
220 overlap_query->overlaps |=
221 mapping->string == overlap_query->mapping_name;
222}
223
224static
225void check_ranges_overlap_unsigned(gpointer element, gpointer query)
226{
227 struct enumeration_mapping *mapping = element;
228 struct range_overlap_query *overlap_query = query;
229
230 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
231 && overlap_query->range_start._unsigned <=
232 mapping->range_end._unsigned) {
273b65be
JG
233 overlap_query->overlaps = 1;
234 overlap_query->mapping_name = mapping->string;
235 }
236
237 overlap_query->overlaps |=
238 mapping->string == overlap_query->mapping_name;
239}
240
b92ddaaa
JG
241static
242gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
243 struct enumeration_mapping **b)
244{
245 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
246}
247
248static
249gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
250 struct enumeration_mapping **b)
251{
252 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
253}
254
273b65be
JG
255static
256void bt_ctf_field_type_init(struct bt_ctf_field_type *type)
257{
258 enum ctf_type_id type_id = type->declaration->id;
c4e511df 259 int ret;
273b65be
JG
260
261 assert(type && (type_id > CTF_TYPE_UNKNOWN) &&
262 (type_id < NR_CTF_TYPES));
263
264 bt_ctf_ref_init(&type->ref_count);
265 type->freeze = type_freeze_funcs[type_id];
266 type->serialize = type_serialize_funcs[type_id];
c4e511df
MD
267 ret = bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_NATIVE);
268 assert(!ret);
273b65be
JG
269 type->declaration->alignment = 1;
270}
271
272static
273int add_structure_field(GPtrArray *fields,
274 GHashTable *field_name_to_index,
275 struct bt_ctf_field_type *field_type,
276 const char *field_name)
277{
278 int ret = 0;
279 GQuark name_quark = g_quark_from_string(field_name);
280 struct structure_field *field;
281
282 /* Make sure structure does not contain a field of the same name */
fe0fe95c
JG
283 if (g_hash_table_lookup_extended(field_name_to_index,
284 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
273b65be
JG
285 ret = -1;
286 goto end;
287 }
288
289 field = g_new0(struct structure_field, 1);
290 if (!field) {
291 ret = -1;
292 goto end;
293 }
294
295 bt_ctf_field_type_get(field_type);
296 field->name = name_quark;
297 field->type = field_type;
298 g_hash_table_insert(field_name_to_index,
299 (gpointer) (unsigned long) name_quark,
300 (gpointer) (unsigned long) fields->len);
301 g_ptr_array_add(fields, field);
273b65be
JG
302end:
303 return ret;
304}
305
2f2d8e05
JG
306static
307void bt_ctf_field_type_destroy(struct bt_ctf_ref *ref)
308{
309 struct bt_ctf_field_type *type;
310 enum ctf_type_id type_id;
311
312 if (!ref) {
313 return;
314 }
315
316 type = container_of(ref, struct bt_ctf_field_type, ref_count);
317 type_id = type->declaration->id;
318 if (type_id <= CTF_TYPE_UNKNOWN ||
319 type_id >= NR_CTF_TYPES) {
320 return;
321 }
322
323 if (type->alias_name) {
324 g_string_free(type->alias_name, TRUE);
325 }
326 type_destroy_funcs[type_id](ref);
327}
328
9ce21c30
JG
329BT_HIDDEN
330int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
331{
332 int ret = 0;
333
334 if (!type) {
335 ret = -1;
336 goto end;
337 }
338
5d161ecc
JG
339 switch (type->declaration->id) {
340 case CTF_TYPE_ENUM:
341 {
9ce21c30
JG
342 struct bt_ctf_field_type_enumeration *enumeration =
343 container_of(type, struct bt_ctf_field_type_enumeration,
344 parent);
345
5d161ecc 346 /* Ensure enum has entries */
9ce21c30 347 ret = enumeration->entries->len ? 0 : -1;
5d161ecc
JG
348 break;
349 }
350 default:
351 break;
9ce21c30
JG
352 }
353end:
354 return ret;
355}
356
273b65be
JG
357struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
358{
359 struct bt_ctf_field_type_integer *integer =
360 g_new0(struct bt_ctf_field_type_integer, 1);
361
1f02e293 362 if (!integer || size == 0 || size > 64) {
273b65be
JG
363 return NULL;
364 }
365
366 integer->parent.declaration = &integer->declaration.p;
367 integer->parent.declaration->id = CTF_TYPE_INTEGER;
368 integer->declaration.len = size;
369 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
370 integer->declaration.encoding = CTF_STRING_NONE;
371 bt_ctf_field_type_init(&integer->parent);
372 return &integer->parent;
373}
374
b92ddaaa
JG
375int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
376{
377 int ret = 0;
378 struct bt_ctf_field_type_integer *integer;
379
380 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
381 ret = -1;
382 goto end;
383 }
384
385 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
386 ret = (int) integer->declaration.len;
387end:
388 return ret;
389}
390
391int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
392{
393 int ret = 0;
394 struct bt_ctf_field_type_integer *integer;
395
396 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
397 ret = -1;
398 goto end;
399 }
400
401 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
402 ret = integer->declaration.signedness;
403end:
404 return ret;
405}
406
273b65be
JG
407int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
408 int is_signed)
409{
410 int ret = 0;
411 struct bt_ctf_field_type_integer *integer;
412
413 if (!type || type->frozen ||
414 type->declaration->id != CTF_TYPE_INTEGER) {
415 ret = -1;
416 goto end;
417 }
418
419 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
273b65be
JG
420 integer->declaration.signedness = !!is_signed;
421end:
422 return ret;
423}
424
b92ddaaa
JG
425enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
426 struct bt_ctf_field_type *type)
427{
428 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
429 struct bt_ctf_field_type_integer *integer;
430
431 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
432 goto end;
433 }
434
435 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
436 ret = integer->declaration.base;
437end:
438 return ret;
439}
440
273b65be
JG
441int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
442 enum bt_ctf_integer_base base)
443{
444 int ret = 0;
445
446 if (!type || type->frozen ||
447 type->declaration->id != CTF_TYPE_INTEGER) {
448 ret = -1;
449 goto end;
450 }
451
452 switch (base) {
453 case BT_CTF_INTEGER_BASE_BINARY:
454 case BT_CTF_INTEGER_BASE_OCTAL:
455 case BT_CTF_INTEGER_BASE_DECIMAL:
456 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
457 {
458 struct bt_ctf_field_type_integer *integer = container_of(type,
459 struct bt_ctf_field_type_integer, parent);
460 integer->declaration.base = base;
461 break;
462 }
463 default:
464 ret = -1;
465 }
466end:
467 return ret;
468}
469
b92ddaaa
JG
470enum ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
471 struct bt_ctf_field_type *type)
472{
473 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
474 struct bt_ctf_field_type_integer *integer;
475
476 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
477 goto end;
478 }
479
480 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
481 ret = integer->declaration.encoding;
482end:
483 return ret;
484}
485
273b65be
JG
486int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
487 enum ctf_string_encoding encoding)
488{
489 int ret = 0;
490 struct bt_ctf_field_type_integer *integer;
491
492 if (!type || type->frozen ||
493 (type->declaration->id != CTF_TYPE_INTEGER) ||
494 (encoding < CTF_STRING_NONE) ||
495 (encoding >= CTF_STRING_UNKNOWN)) {
496 ret = -1;
497 goto end;
498 }
499
500 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
501 integer->declaration.encoding = encoding;
502end:
503 return ret;
504}
505
6cfb906f
JG
506struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
507 struct bt_ctf_field_type *type)
508{
509 struct bt_ctf_field_type_integer *integer;
510 struct bt_ctf_clock *clock = NULL;
511
512 if (!type) {
513 goto end;
514 }
515
516 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
517 clock = integer->mapped_clock;
518 if (clock) {
519 bt_ctf_clock_get(clock);
520 }
521end:
522 return clock;
523}
524
525int bt_ctf_field_type_integer_set_mapped_clock(
526 struct bt_ctf_field_type *type,
527 struct bt_ctf_clock *clock)
528{
529 struct bt_ctf_field_type_integer *integer;
530 int ret = 0;
531
532 if (!type || type->frozen) {
533 ret = -1;
534 goto end;
535 }
536
537 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
538 if (integer->mapped_clock) {
539 bt_ctf_clock_put(integer->mapped_clock);
540 }
541
542 if (clock) {
543 bt_ctf_clock_get(clock);
544 }
545
546 integer->mapped_clock = clock;
547end:
548 return ret;
549}
550
273b65be
JG
551struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
552 struct bt_ctf_field_type *integer_container_type)
553{
554 struct bt_ctf_field_type_enumeration *enumeration = NULL;
555
556 if (!integer_container_type) {
557 goto error;
558 }
559
2a610bb7
JG
560 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
561 goto error;
562 }
563
273b65be
JG
564 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
565 if (!enumeration) {
566 goto error;
567 }
568
569 enumeration->parent.declaration = &enumeration->declaration.p;
570 enumeration->parent.declaration->id = CTF_TYPE_ENUM;
571 bt_ctf_field_type_get(integer_container_type);
572 enumeration->container = integer_container_type;
573 enumeration->entries = g_ptr_array_new_with_free_func(
574 (GDestroyNotify)destroy_enumeration_mapping);
575 bt_ctf_field_type_init(&enumeration->parent);
576 return &enumeration->parent;
577error:
578 g_free(enumeration);
579 return NULL;
580}
581
b92ddaaa
JG
582struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
583 struct bt_ctf_field_type *type)
584{
585 struct bt_ctf_field_type *container_type = NULL;
586 struct bt_ctf_field_type_enumeration *enumeration_type;
587
588 if (!type) {
589 goto end;
590 }
591
592 if (type->declaration->id != CTF_TYPE_ENUM) {
593 goto end;
594 }
595
596 enumeration_type = container_of(type,
597 struct bt_ctf_field_type_enumeration, parent);
598 container_type = enumeration_type->container;
599 bt_ctf_field_type_get(container_type);
600end:
601 return container_type;
602}
603
273b65be
JG
604int bt_ctf_field_type_enumeration_add_mapping(
605 struct bt_ctf_field_type *type, const char *string,
606 int64_t range_start, int64_t range_end)
607{
608 int ret = 0;
609 GQuark mapping_name;
610 struct enumeration_mapping *mapping;
611 struct bt_ctf_field_type_enumeration *enumeration;
612 struct range_overlap_query query;
a39fa057 613 char *escaped_string;
273b65be
JG
614
615 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
616 type->frozen ||
617 (range_end < range_start)) {
618 ret = -1;
619 goto end;
620 }
621
a39fa057 622 if (!string || strlen(string) == 0) {
273b65be
JG
623 ret = -1;
624 goto end;
625 }
626
a39fa057
JG
627 escaped_string = g_strescape(string, NULL);
628 if (!escaped_string) {
629 ret = -1;
630 goto end;
631 }
632
633 mapping_name = g_quark_from_string(escaped_string);
b92ddaaa
JG
634 query = (struct range_overlap_query) {
635 .range_start._signed = range_start,
636 .range_end._signed = range_end,
273b65be
JG
637 .mapping_name = mapping_name,
638 .overlaps = 0 };
639 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
640 parent);
641
642 /* Check that the range does not overlap with one already present */
643 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
644 if (query.overlaps) {
645 ret = -1;
a39fa057 646 goto error_free;
273b65be
JG
647 }
648
649 mapping = g_new(struct enumeration_mapping, 1);
650 if (!mapping) {
651 ret = -1;
a39fa057 652 goto error_free;
273b65be
JG
653 }
654
b92ddaaa
JG
655 *mapping = (struct enumeration_mapping) {
656 .range_start._signed = range_start,
657 .range_end._signed = range_end, .string = mapping_name};
273b65be 658 g_ptr_array_add(enumeration->entries, mapping);
b92ddaaa
JG
659 g_ptr_array_sort(enumeration->entries,
660 (GCompareFunc)compare_enumeration_mappings_signed);
661error_free:
662 free(escaped_string);
663end:
664 return ret;
665}
666
667int bt_ctf_field_type_enumeration_add_mapping_unsigned(
668 struct bt_ctf_field_type *type, const char *string,
669 uint64_t range_start, uint64_t range_end)
670{
671 int ret = 0;
672 GQuark mapping_name;
673 struct enumeration_mapping *mapping;
674 struct bt_ctf_field_type_enumeration *enumeration;
675 struct range_overlap_query query;
676 char *escaped_string;
677
678 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
679 type->frozen ||
680 (range_end < range_start)) {
681 ret = -1;
682 goto end;
683 }
684
685 if (!string || strlen(string) == 0) {
686 ret = -1;
687 goto end;
688 }
689
690 escaped_string = g_strescape(string, NULL);
691 if (!escaped_string) {
692 ret = -1;
693 goto end;
694 }
695
696 mapping_name = g_quark_from_string(escaped_string);
697 query = (struct range_overlap_query) {
698 .range_start._unsigned = range_start,
699 .range_end._unsigned = range_end,
700 .mapping_name = mapping_name,
701 .overlaps = 0 };
702 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
703 parent);
704
705 /* Check that the range does not overlap with one already present */
706 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned,
707 &query);
708 if (query.overlaps) {
709 ret = -1;
710 goto error_free;
711 }
712
713 mapping = g_new(struct enumeration_mapping, 1);
714 if (!mapping) {
715 ret = -1;
716 goto error_free;
717 }
718
719 *mapping = (struct enumeration_mapping) {
720 .range_start._unsigned = range_start,
721 .range_end._unsigned = range_end, .string = mapping_name};
722 g_ptr_array_add(enumeration->entries, mapping);
723 g_ptr_array_sort(enumeration->entries,
724 (GCompareFunc)compare_enumeration_mappings_unsigned);
a39fa057
JG
725error_free:
726 free(escaped_string);
273b65be
JG
727end:
728 return ret;
729}
730
e5958c30
JG
731const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
732 struct bt_ctf_field_type_enumeration *enumeration_type,
733 uint64_t value)
734{
735 const char *name = NULL;
736 struct range_overlap_query query =
737 (struct range_overlap_query) {
b92ddaaa
JG
738 .range_start._unsigned = value,
739 .range_end._unsigned = value,
e5958c30
JG
740 .overlaps = 0 };
741
b92ddaaa
JG
742 g_ptr_array_foreach(enumeration_type->entries,
743 check_ranges_overlap_unsigned,
e5958c30
JG
744 &query);
745 if (!query.overlaps) {
746 goto end;
747 }
748
749 name = g_quark_to_string(query.mapping_name);
750end:
751 return name;
752}
753
754const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
755 struct bt_ctf_field_type_enumeration *enumeration_type,
756 int64_t value)
757{
758 const char *name = NULL;
759 struct range_overlap_query query =
760 (struct range_overlap_query) {
b92ddaaa
JG
761 .range_start._signed = value,
762 .range_end._signed = value,
e5958c30
JG
763 .overlaps = 0 };
764
765 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
766 &query);
767 if (!query.overlaps) {
768 goto end;
769 }
770
771 name = g_quark_to_string(query.mapping_name);
772end:
773 return name;
774}
775
074ee56d 776int bt_ctf_field_type_enumeration_get_mapping_count(
b92ddaaa
JG
777 struct bt_ctf_field_type *type)
778{
074ee56d 779 int ret = 0;
b92ddaaa
JG
780 struct bt_ctf_field_type_enumeration *enumeration;
781
782 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
783 ret = -1;
784 goto end;
785 }
786
787 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
788 parent);
074ee56d 789 ret = (int) enumeration->entries->len;
b92ddaaa
JG
790end:
791 return ret;
792}
793
794static inline
795struct enumeration_mapping *get_enumeration_mapping(
074ee56d 796 struct bt_ctf_field_type *type, int index)
b92ddaaa
JG
797{
798 struct enumeration_mapping *mapping = NULL;
799 struct bt_ctf_field_type_enumeration *enumeration;
800
801 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
802 parent);
803 if (index >= enumeration->entries->len) {
804 goto end;
805 }
806
807 mapping = g_ptr_array_index(enumeration->entries, index);
808end:
809 return mapping;
810}
811
812int bt_ctf_field_type_enumeration_get_mapping(
074ee56d 813 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
814 const char **string, int64_t *range_start, int64_t *range_end)
815{
816 struct enumeration_mapping *mapping;
817 int ret = 0;
818
074ee56d 819 if (!type || index < 0 || !string || !range_start || !range_end ||
b92ddaaa
JG
820 (type->declaration->id != CTF_TYPE_ENUM)) {
821 ret = -1;
822 goto end;
823 }
824
825 mapping = get_enumeration_mapping(type, index);
826 if (!mapping) {
827 ret = -1;
828 goto end;
829 }
830
831 *string = g_quark_to_string(mapping->string);
832 *range_start = mapping->range_start._signed;
833 *range_end = mapping->range_end._signed;
834end:
835 return ret;
836}
837
838int bt_ctf_field_type_enumeration_get_mapping_unsigned(
074ee56d 839 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
840 const char **string, uint64_t *range_start, uint64_t *range_end)
841{
842 struct enumeration_mapping *mapping;
843 int ret = 0;
844
074ee56d 845 if (!type || index < 0 || !string || !range_start || !range_end ||
b92ddaaa
JG
846 (type->declaration->id != CTF_TYPE_ENUM)) {
847 ret = -1;
848 goto end;
849 }
850
851 mapping = get_enumeration_mapping(type, index);
852 if (!mapping) {
853 ret = -1;
854 goto end;
855 }
856
857 *string = g_quark_to_string(mapping->string);
858 *range_start = mapping->range_start._unsigned;
859 *range_end = mapping->range_end._unsigned;
860end:
861 return ret;
862}
863
864int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
074ee56d 865 struct bt_ctf_field_type *type, const char *name)
b92ddaaa 866{
b92ddaaa
JG
867 GQuark name_quark;
868 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 869 int i, ret = 0;
b92ddaaa 870
074ee56d 871 if (!type || !name ||
b92ddaaa
JG
872 (type->declaration->id != CTF_TYPE_ENUM)) {
873 ret = -1;
874 goto end;
875 }
876
877 name_quark = g_quark_try_string(name);
878 if (!name_quark) {
879 ret = -1;
880 goto end;
881 }
882
883 enumeration = container_of(type,
884 struct bt_ctf_field_type_enumeration, parent);
885 for (i = 0; i < enumeration->entries->len; i++) {
886 struct enumeration_mapping *mapping =
887 get_enumeration_mapping(type, i);
888
889 if (mapping->string == name_quark) {
074ee56d 890 ret = i;
b92ddaaa
JG
891 goto end;
892 }
893 }
894
895 ret = -1;
896end:
897 return ret;
898}
899
900int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
074ee56d 901 struct bt_ctf_field_type *type, int64_t value)
b92ddaaa
JG
902{
903 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 904 int i, ret = 0;
b92ddaaa 905
074ee56d 906 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
b92ddaaa
JG
907 ret = -1;
908 goto end;
909 }
910
911 enumeration = container_of(type,
912 struct bt_ctf_field_type_enumeration, parent);
913 for (i = 0; i < enumeration->entries->len; i++) {
914 struct enumeration_mapping *mapping =
915 get_enumeration_mapping(type, i);
916
917 if (value >= mapping->range_start._signed &&
918 value <= mapping->range_end._signed) {
074ee56d 919 ret = i;
b92ddaaa
JG
920 goto end;
921 }
922 }
923
924 ret = -1;
925end:
926 return ret;
927}
928
929int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
074ee56d 930 struct bt_ctf_field_type *type, uint64_t value)
b92ddaaa
JG
931{
932 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 933 int i, ret = 0;
b92ddaaa 934
074ee56d 935 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
b92ddaaa
JG
936 ret = -1;
937 goto end;
938 }
939
940 enumeration = container_of(type,
941 struct bt_ctf_field_type_enumeration, parent);
942 for (i = 0; i < enumeration->entries->len; i++) {
943 struct enumeration_mapping *mapping =
944 get_enumeration_mapping(type, i);
945
946 if (value >= mapping->range_start._unsigned &&
947 value <= mapping->range_end._unsigned) {
074ee56d 948 ret = i;
b92ddaaa
JG
949 goto end;
950 }
951 }
952
953 ret = -1;
954end:
955 return ret;
956}
957
273b65be
JG
958struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
959{
960 struct bt_ctf_field_type_floating_point *floating_point =
961 g_new0(struct bt_ctf_field_type_floating_point, 1);
962
963 if (!floating_point) {
964 goto end;
965 }
966
967 floating_point->declaration.sign = &floating_point->sign;
968 floating_point->declaration.mantissa = &floating_point->mantissa;
969 floating_point->declaration.exp = &floating_point->exp;
970 floating_point->sign.len = 1;
971 floating_point->parent.declaration = &floating_point->declaration.p;
972 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
973 floating_point->declaration.exp->len =
974 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
975 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
976 floating_point->sign.p.alignment = 1;
977 floating_point->mantissa.p.alignment = 1;
978 floating_point->exp.p.alignment = 1;
979
980 bt_ctf_field_type_init(&floating_point->parent);
981end:
982 return floating_point ? &floating_point->parent : NULL;
983}
984
b92ddaaa
JG
985int bt_ctf_field_type_floating_point_get_exponent_digits(
986 struct bt_ctf_field_type *type)
987{
988 int ret = 0;
989 struct bt_ctf_field_type_floating_point *floating_point;
990
991 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
992 ret = -1;
993 goto end;
994 }
995
996 floating_point = container_of(type,
997 struct bt_ctf_field_type_floating_point, parent);
998 ret = (int) floating_point->declaration.exp->len;
999end:
1000 return ret;
1001}
1002
273b65be
JG
1003int bt_ctf_field_type_floating_point_set_exponent_digits(
1004 struct bt_ctf_field_type *type,
1005 unsigned int exponent_digits)
1006{
1007 int ret = 0;
1008 struct bt_ctf_field_type_floating_point *floating_point;
1009
1010 if (!type || type->frozen ||
1011 (type->declaration->id != CTF_TYPE_FLOAT)) {
1012 ret = -1;
1013 goto end;
1014 }
1015
1016 floating_point = container_of(type,
1017 struct bt_ctf_field_type_floating_point, parent);
1018 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1019 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1020 (exponent_digits !=
1021 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1022 ret = -1;
1023 goto end;
1024 }
1025
1026 floating_point->declaration.exp->len = exponent_digits;
1027end:
1028 return ret;
1029}
1030
b92ddaaa
JG
1031int bt_ctf_field_type_floating_point_get_mantissa_digits(
1032 struct bt_ctf_field_type *type)
1033{
1034 int ret = 0;
1035 struct bt_ctf_field_type_floating_point *floating_point;
1036
1037 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1038 ret = -1;
1039 goto end;
1040 }
1041
1042 floating_point = container_of(type,
1043 struct bt_ctf_field_type_floating_point, parent);
1044 ret = (int) floating_point->mantissa.len + 1;
1045end:
1046 return ret;
1047}
1048
273b65be
JG
1049int bt_ctf_field_type_floating_point_set_mantissa_digits(
1050 struct bt_ctf_field_type *type,
1051 unsigned int mantissa_digits)
1052{
1053 int ret = 0;
1054 struct bt_ctf_field_type_floating_point *floating_point;
1055
1056 if (!type || type->frozen ||
1057 (type->declaration->id != CTF_TYPE_FLOAT)) {
1058 ret = -1;
1059 goto end;
1060 }
1061
1062 floating_point = container_of(type,
1063 struct bt_ctf_field_type_floating_point, parent);
1064
1065 if ((mantissa_digits != FLT_MANT_DIG) &&
1066 (mantissa_digits != DBL_MANT_DIG) &&
1067 (mantissa_digits != LDBL_MANT_DIG)) {
1068 ret = -1;
1069 goto end;
1070 }
1071
1072 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1073end:
1074 return ret;
1075}
1076
1077struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1078{
1079 struct bt_ctf_field_type_structure *structure =
1080 g_new0(struct bt_ctf_field_type_structure, 1);
1081
1082 if (!structure) {
1083 goto error;
1084 }
1085
1086 structure->parent.declaration = &structure->declaration.p;
1087 structure->parent.declaration->id = CTF_TYPE_STRUCT;
273b65be
JG
1088 structure->fields = g_ptr_array_new_with_free_func(
1089 (GDestroyNotify)destroy_structure_field);
1090 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
c35a1669 1091 bt_ctf_field_type_init(&structure->parent);
273b65be
JG
1092 return &structure->parent;
1093error:
1094 return NULL;
1095}
1096
1097int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1098 struct bt_ctf_field_type *field_type,
1099 const char *field_name)
1100{
1101 int ret = 0;
1102 struct bt_ctf_field_type_structure *structure;
1103
1104 if (!type || !field_type || type->frozen ||
654c1444 1105 bt_ctf_validate_identifier(field_name) ||
9ce21c30
JG
1106 (type->declaration->id != CTF_TYPE_STRUCT) ||
1107 bt_ctf_field_type_validate(field_type)) {
e6235f1f 1108 ret = -1;
273b65be
JG
1109 goto end;
1110 }
1111
1112 structure = container_of(type,
1113 struct bt_ctf_field_type_structure, parent);
1114 if (add_structure_field(structure->fields,
1115 structure->field_name_to_index, field_type, field_name)) {
1116 ret = -1;
1117 goto end;
1118 }
1119
b92ddaaa
JG
1120 if (type->declaration->alignment < field_type->declaration->alignment) {
1121 type->declaration->alignment =
1122 field_type->declaration->alignment;
1123 }
1124end:
1125 return ret;
1126}
1127
074ee56d 1128int bt_ctf_field_type_structure_get_field_count(
b92ddaaa
JG
1129 struct bt_ctf_field_type *type)
1130{
074ee56d 1131 int ret = 0;
b92ddaaa
JG
1132 struct bt_ctf_field_type_structure *structure;
1133
1134 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1135 ret = -1;
1136 goto end;
1137 }
1138
1139 structure = container_of(type, struct bt_ctf_field_type_structure,
1140 parent);
074ee56d 1141 ret = (int) structure->fields->len;
b92ddaaa
JG
1142end:
1143 return ret;
1144}
1145
1146int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1147 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 1148 int index)
b92ddaaa
JG
1149{
1150 struct bt_ctf_field_type_structure *structure;
1151 struct structure_field *field;
1152 int ret = 0;
1153
074ee56d 1154 if (!type || index < 0 || !field_name || !field_type ||
b92ddaaa
JG
1155 (type->declaration->id != CTF_TYPE_STRUCT)) {
1156 ret = -1;
1157 goto end;
1158 }
1159
1160 structure = container_of(type, struct bt_ctf_field_type_structure,
1161 parent);
1162 if (index >= structure->fields->len) {
1163 ret = -1;
1164 goto end;
1165 }
1166
1167 field = g_ptr_array_index(structure->fields, index);
1168 *field_type = field->type;
1169 bt_ctf_field_type_get(field->type);
1170 *field_name = g_quark_to_string(field->name);
1171end:
1172 return ret;
1173}
1174
1175struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1176 struct bt_ctf_field_type *type,
1177 const char *name)
1178{
1179 size_t index;
1180 GQuark name_quark;
1181 struct structure_field *field;
1182 struct bt_ctf_field_type_structure *structure;
1183 struct bt_ctf_field_type *field_type = NULL;
1184
1185 if (!type || !name) {
1186 goto end;
1187 }
1188
1189 name_quark = g_quark_try_string(name);
1190 if (!name_quark) {
1191 goto end;
1192 }
1193
1194 structure = container_of(type, struct bt_ctf_field_type_structure,
1195 parent);
1196 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1197 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1198 goto end;
273b65be 1199 }
b92ddaaa
JG
1200
1201 field = structure->fields->pdata[index];
1202 field_type = field->type;
1203 bt_ctf_field_type_get(field_type);
273b65be 1204end:
b92ddaaa 1205 return field_type;
273b65be
JG
1206}
1207
1208struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1209 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1210{
1211 struct bt_ctf_field_type_variant *variant = NULL;
1212
6964b7fd 1213 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
273b65be
JG
1214 goto error;
1215 }
1216
1217 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1218 if (!variant) {
1219 goto error;
1220 }
1221
1222 variant->parent.declaration = &variant->declaration.p;
1223 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1224 variant->tag_name = g_string_new(tag_name);
273b65be
JG
1225 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1226 variant->fields = g_ptr_array_new_with_free_func(
1227 (GDestroyNotify)destroy_structure_field);
6964b7fd
JG
1228 if (enum_tag) {
1229 bt_ctf_field_type_get(enum_tag);
1230 variant->tag = container_of(enum_tag,
1231 struct bt_ctf_field_type_enumeration, parent);
1232 }
1233
c35a1669 1234 bt_ctf_field_type_init(&variant->parent);
273b65be
JG
1235 return &variant->parent;
1236error:
1237 return NULL;
1238}
1239
b92ddaaa
JG
1240struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1241 struct bt_ctf_field_type *type)
1242{
1243 struct bt_ctf_field_type_variant *variant;
1244 struct bt_ctf_field_type *tag_type = NULL;
1245
1246 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1247 goto end;
1248 }
1249
1250 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd
JG
1251 if (!variant->tag) {
1252 goto end;
1253 }
1254
b92ddaaa
JG
1255 tag_type = &variant->tag->parent;
1256 bt_ctf_field_type_get(tag_type);
1257end:
1258 return tag_type;
1259}
1260
1261const char *bt_ctf_field_type_variant_get_tag_name(
1262 struct bt_ctf_field_type *type)
1263{
1264 struct bt_ctf_field_type_variant *variant;
1265 const char *tag_name = NULL;
1266
1267 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1268 goto end;
1269 }
1270
1271 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd
JG
1272 if (variant->tag_name->len == 0) {
1273 goto end;
1274 }
1275
b92ddaaa
JG
1276 tag_name = variant->tag_name->str;
1277end:
1278 return tag_name;
1279}
1280
273b65be
JG
1281int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1282 struct bt_ctf_field_type *field_type,
1283 const char *field_name)
1284{
1285 size_t i;
1286 int ret = 0;
273b65be
JG
1287 struct bt_ctf_field_type_variant *variant;
1288 GQuark field_name_quark = g_quark_from_string(field_name);
1289
1290 if (!type || !field_type || type->frozen ||
654c1444 1291 bt_ctf_validate_identifier(field_name) ||
9ce21c30
JG
1292 (type->declaration->id != CTF_TYPE_VARIANT) ||
1293 bt_ctf_field_type_validate(field_type)) {
273b65be
JG
1294 ret = -1;
1295 goto end;
1296 }
1297
1298 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
273b65be 1299
6964b7fd
JG
1300 /* The user has explicitly provided a tag; validate against it. */
1301 if (variant->tag) {
1302 int name_found = 0;
1303
1304 /* Make sure this name is present in the enum tag */
1305 for (i = 0; i < variant->tag->entries->len; i++) {
1306 struct enumeration_mapping *mapping =
1307 g_ptr_array_index(variant->tag->entries, i);
1308
1309 if (mapping->string == field_name_quark) {
1310 name_found = 1;
1311 break;
1312 }
1313 }
1314
1315 if (!name_found) {
1316 /* Validation failed */
1317 ret = -1;
1318 goto end;
273b65be
JG
1319 }
1320 }
1321
6964b7fd
JG
1322 if (add_structure_field(variant->fields, variant->field_name_to_index,
1323 field_type, field_name)) {
273b65be
JG
1324 ret = -1;
1325 goto end;
1326 }
1327end:
1328 return ret;
1329}
1330
b92ddaaa
JG
1331struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1332 struct bt_ctf_field_type *type,
1333 const char *field_name)
1334{
1335 size_t index;
1336 GQuark name_quark;
1337 struct structure_field *field;
1338 struct bt_ctf_field_type_variant *variant;
1339 struct bt_ctf_field_type *field_type = NULL;
1340
1341 if (!type || !field_name) {
1342 goto end;
1343 }
1344
1345 name_quark = g_quark_try_string(field_name);
1346 if (!name_quark) {
1347 goto end;
1348 }
1349
1350 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1351 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1352 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1353 goto end;
1354 }
1355
1356 field = g_ptr_array_index(variant->fields, index);
1357 field_type = field->type;
1358 bt_ctf_field_type_get(field_type);
1359end:
1360 return field_type;
1361}
1362
1363struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1364 struct bt_ctf_field_type *type,
1365 struct bt_ctf_field *tag)
1366{
1367 const char *enum_value;
1368 struct bt_ctf_field_type *field_type = NULL;
1369
1370 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1371 goto end;
1372 }
1373
1374 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1375 if (!enum_value) {
1376 goto end;
1377 }
1378
1379 /* Already increments field_type's reference count */
1380 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1381 type, enum_value);
1382end:
1383 return field_type;
1384}
1385
074ee56d 1386int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
b92ddaaa 1387{
074ee56d 1388 int ret = 0;
b92ddaaa
JG
1389 struct bt_ctf_field_type_variant *variant;
1390
1391 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1392 ret = -1;
1393 goto end;
1394 }
1395
1396 variant = container_of(type, struct bt_ctf_field_type_variant,
1397 parent);
074ee56d 1398 ret = (int) variant->fields->len;
b92ddaaa
JG
1399end:
1400 return ret;
1401
1402}
1403
1404int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1405 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 1406 int index)
b92ddaaa
JG
1407{
1408 struct bt_ctf_field_type_variant *variant;
1409 struct structure_field *field;
1410 int ret = 0;
1411
074ee56d 1412 if (!type || index < 0 || !field_name || !field_type ||
b92ddaaa
JG
1413 (type->declaration->id != CTF_TYPE_VARIANT)) {
1414 ret = -1;
1415 goto end;
1416 }
1417
1418 variant = container_of(type, struct bt_ctf_field_type_variant,
1419 parent);
1420 if (index >= variant->fields->len) {
1421 ret = -1;
1422 goto end;
1423 }
1424
1425 field = g_ptr_array_index(variant->fields, index);
1426 *field_type = field->type;
1427 bt_ctf_field_type_get(field->type);
1428 *field_name = g_quark_to_string(field->name);
1429end:
1430 return ret;
1431}
1432
273b65be
JG
1433struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1434 struct bt_ctf_field_type *element_type,
1435 unsigned int length)
1436{
1437 struct bt_ctf_field_type_array *array = NULL;
1438
9ce21c30
JG
1439 if (!element_type || length == 0 ||
1440 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1441 goto error;
1442 }
1443
1444 array = g_new0(struct bt_ctf_field_type_array, 1);
1445 if (!array) {
1446 goto error;
1447 }
1448
1449 array->parent.declaration = &array->declaration.p;
1450 array->parent.declaration->id = CTF_TYPE_ARRAY;
c35a1669 1451
273b65be
JG
1452 bt_ctf_field_type_get(element_type);
1453 array->element_type = element_type;
1454 array->length = length;
c35a1669 1455 bt_ctf_field_type_init(&array->parent);
273b65be
JG
1456 array->parent.declaration->alignment =
1457 element_type->declaration->alignment;
1458 return &array->parent;
1459error:
1460 return NULL;
1461}
1462
b92ddaaa
JG
1463struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1464 struct bt_ctf_field_type *type)
1465{
1466 struct bt_ctf_field_type *ret = NULL;
1467 struct bt_ctf_field_type_array *array;
1468
1469 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1470 goto end;
1471 }
1472
1473 array = container_of(type, struct bt_ctf_field_type_array, parent);
1474 ret = array->element_type;
1475 bt_ctf_field_type_get(ret);
1476end:
1477 return ret;
1478}
1479
1480int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1481{
1482 int64_t ret;
1483 struct bt_ctf_field_type_array *array;
1484
1485 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1486 ret = -1;
1487 goto end;
1488 }
1489
1490 array = container_of(type, struct bt_ctf_field_type_array, parent);
1491 ret = (int64_t) array->length;
1492end:
1493 return ret;
1494}
1495
273b65be
JG
1496struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1497 struct bt_ctf_field_type *element_type,
1498 const char *length_field_name)
1499{
1500 struct bt_ctf_field_type_sequence *sequence = NULL;
1501
654c1444 1502 if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
9ce21c30 1503 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1504 goto error;
1505 }
1506
1507 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1508 if (!sequence) {
1509 goto error;
1510 }
1511
1512 sequence->parent.declaration = &sequence->declaration.p;
1513 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
273b65be
JG
1514 bt_ctf_field_type_get(element_type);
1515 sequence->element_type = element_type;
1516 sequence->length_field_name = g_string_new(length_field_name);
c35a1669 1517 bt_ctf_field_type_init(&sequence->parent);
273b65be
JG
1518 sequence->parent.declaration->alignment =
1519 element_type->declaration->alignment;
1520 return &sequence->parent;
1521error:
1522 return NULL;
1523}
1524
b92ddaaa
JG
1525struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1526 struct bt_ctf_field_type *type)
1527{
1528 struct bt_ctf_field_type *ret = NULL;
1529 struct bt_ctf_field_type_sequence *sequence;
1530
1531 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1532 goto end;
1533 }
1534
1535 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1536 parent);
1537 ret = sequence->element_type;
1538 bt_ctf_field_type_get(ret);
1539end:
1540 return ret;
1541}
1542
1543const char *bt_ctf_field_type_sequence_get_length_field_name(
1544 struct bt_ctf_field_type *type)
1545{
1546 const char *ret = NULL;
1547 struct bt_ctf_field_type_sequence *sequence;
1548
1549 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1550 goto end;
1551 }
1552
1553 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1554 parent);
1555 ret = sequence->length_field_name->str;
1556end:
1557 return ret;
1558}
1559
273b65be
JG
1560struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1561{
1562 struct bt_ctf_field_type_string *string =
1563 g_new0(struct bt_ctf_field_type_string, 1);
1564
1565 if (!string) {
1566 return NULL;
1567 }
1568
1569 string->parent.declaration = &string->declaration.p;
1570 string->parent.declaration->id = CTF_TYPE_STRING;
1571 bt_ctf_field_type_init(&string->parent);
1572 string->declaration.encoding = CTF_STRING_UTF8;
1573 string->parent.declaration->alignment = CHAR_BIT;
1574 return &string->parent;
1575}
1576
b92ddaaa
JG
1577enum ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1578 struct bt_ctf_field_type *type)
1579{
1580 struct bt_ctf_field_type_string *string;
1581 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
1582
1583 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1584 goto end;
1585 }
1586
1587 string = container_of(type, struct bt_ctf_field_type_string,
1588 parent);
1589 ret = string->declaration.encoding;
1590end:
1591 return ret;
1592}
1593
1594int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
273b65be
JG
1595 enum ctf_string_encoding encoding)
1596{
1597 int ret = 0;
1598 struct bt_ctf_field_type_string *string;
1599
1600 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1601 (encoding != CTF_STRING_UTF8 &&
1602 encoding != CTF_STRING_ASCII)) {
1603 ret = -1;
1604 goto end;
1605 }
1606
1607 string = container_of(type, struct bt_ctf_field_type_string, parent);
1608 string->declaration.encoding = encoding;
1609end:
1610 return ret;
1611}
1612
b92ddaaa
JG
1613int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1614{
1615 int ret;
1616
1617 if (!type) {
1618 ret = -1;
1619 goto end;
1620 }
1621
1622 ret = (int) type->declaration->alignment;
1623end:
1624 return ret;
1625}
1626
273b65be
JG
1627int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
1628 unsigned int alignment)
1629{
1630 int ret = 0;
1631
1632 /* Alignment must be bit-aligned (1) or byte aligned */
1633 if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
1634 ret = -1;
1635 goto end;
1636 }
1637
1638 if (type->declaration->id == CTF_TYPE_STRING &&
1639 alignment != CHAR_BIT) {
1640 ret = -1;
1641 goto end;
1642 }
1643
1644 type->declaration->alignment = alignment;
1645 ret = 0;
1646end:
1647 return ret;
1648}
1649
b92ddaaa
JG
1650enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1651 struct bt_ctf_field_type *type)
1652{
1653 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
c35a1669 1654 int internal_byte_order = -1;
b92ddaaa
JG
1655
1656 if (!type) {
1657 goto end;
1658 }
1659
1660 switch (type->declaration->id) {
1661 case CTF_TYPE_INTEGER:
1662 {
1663 struct bt_ctf_field_type_integer *integer = container_of(
1664 type, struct bt_ctf_field_type_integer, parent);
c35a1669 1665 internal_byte_order = integer->declaration.byte_order;
b92ddaaa
JG
1666 break;
1667 }
1668 case CTF_TYPE_FLOAT:
1669 {
1670 struct bt_ctf_field_type_floating_point *floating_point =
1671 container_of(type,
1672 struct bt_ctf_field_type_floating_point,
1673 parent);
c35a1669 1674 internal_byte_order = floating_point->declaration.byte_order;
b92ddaaa
JG
1675 break;
1676 }
1677 default:
c35a1669
JG
1678 goto end;
1679 }
1680
1681 switch (internal_byte_order) {
1682 case LITTLE_ENDIAN:
1683 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
b92ddaaa 1684 break;
c35a1669
JG
1685 case BIG_ENDIAN:
1686 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1687 break;
1688 case 0:
1689 ret = BT_CTF_BYTE_ORDER_NATIVE;
1690 break;
1691 default:
1692 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
b92ddaaa
JG
1693 }
1694end:
1695 return ret;
1696}
1697
273b65be
JG
1698int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
1699 enum bt_ctf_byte_order byte_order)
1700{
1701 int ret = 0;
1702 int internal_byte_order;
1703 enum ctf_type_id type_id;
1704
1705 if (!type || type->frozen) {
1706 ret = -1;
1707 goto end;
1708 }
1709
1710 type_id = type->declaration->id;
1711 switch (byte_order) {
1712 case BT_CTF_BYTE_ORDER_NATIVE:
c35a1669
JG
1713 /* Leave unset. Will be initialized by parent. */
1714 internal_byte_order = 0;
273b65be
JG
1715 break;
1716 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
1717 internal_byte_order = LITTLE_ENDIAN;
1718 break;
1719 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
1720 case BT_CTF_BYTE_ORDER_NETWORK:
1721 internal_byte_order = BIG_ENDIAN;
1722 break;
1723 default:
1724 ret = -1;
1725 goto end;
1726 }
1727
1728 if (set_byte_order_funcs[type_id]) {
c35a1669 1729 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
273b65be
JG
1730 }
1731end:
1732 return ret;
1733}
1734
b92ddaaa
JG
1735enum ctf_type_id bt_ctf_field_type_get_type_id(
1736 struct bt_ctf_field_type *type)
1737{
1738 if (!type) {
1739 return CTF_TYPE_UNKNOWN;
1740 }
1741
1742 return type->declaration->id;
1743}
1744
2f2d8e05
JG
1745const char *bt_ctf_field_type_get_alias_name(
1746 struct bt_ctf_field_type *type)
1747{
1748 const char *name = NULL;
1749
1750 if (!type || !type->alias_name) {
1751 goto end;
1752 }
1753
1754 name = type->alias_name->str;
1755end:
1756 return name;
1757}
1758
273b65be
JG
1759void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
1760{
1761 if (!type) {
1762 return;
1763 }
1764
1765 bt_ctf_ref_get(&type->ref_count);
1766}
1767
1768void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
1769{
273b65be
JG
1770 if (!type) {
1771 return;
1772 }
1773
2f2d8e05 1774 bt_ctf_ref_put(&type->ref_count, bt_ctf_field_type_destroy);
273b65be
JG
1775}
1776
1777BT_HIDDEN
1778void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
1779{
1780 if (!type) {
1781 return;
1782 }
1783
1784 type->freeze(type);
1785}
1786
1787BT_HIDDEN
b92ddaaa
JG
1788struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
1789 struct bt_ctf_field_type_variant *variant,
1790 int64_t tag_value)
273b65be
JG
1791{
1792 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
1793 GQuark field_name_quark;
1794 gpointer index;
1795 struct structure_field *field_entry;
1796 struct range_overlap_query query = {
1797 .range_start._signed = tag_value,
1798 .range_end._signed = tag_value,
1799 .mapping_name = 0, .overlaps = 0};
273b65be 1800
b92ddaaa
JG
1801 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
1802 &query);
1803 if (!query.overlaps) {
273b65be
JG
1804 goto end;
1805 }
1806
b92ddaaa
JG
1807 field_name_quark = query.mapping_name;
1808 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1809 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
273b65be
JG
1810 goto end;
1811 }
1812
e54fab7e 1813 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
b92ddaaa 1814 type = field_entry->type;
273b65be
JG
1815end:
1816 return type;
1817}
1818
1819BT_HIDDEN
b92ddaaa 1820struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 1821 struct bt_ctf_field_type_variant *variant,
b92ddaaa 1822 uint64_t tag_value)
273b65be
JG
1823{
1824 struct bt_ctf_field_type *type = NULL;
1825 GQuark field_name_quark;
1826 gpointer index;
1827 struct structure_field *field_entry;
b92ddaaa
JG
1828 struct range_overlap_query query = {
1829 .range_start._unsigned = tag_value,
1830 .range_end._unsigned = tag_value,
1831 .mapping_name = 0, .overlaps = 0};
273b65be 1832
b92ddaaa
JG
1833 g_ptr_array_foreach(variant->tag->entries,
1834 check_ranges_overlap_unsigned,
273b65be
JG
1835 &query);
1836 if (!query.overlaps) {
1837 goto end;
1838 }
1839
1840 field_name_quark = query.mapping_name;
1841 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1842 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1843 goto end;
1844 }
1845
1846 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
1847 type = field_entry->type;
1848end:
1849 return type;
1850}
1851
1852BT_HIDDEN
1853int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
1854 struct metadata_context *context)
1855{
1856 int ret;
1857
1858 if (!type || !context) {
1859 ret = -1;
1860 goto end;
1861 }
1862
1863 ret = type->serialize(type, context);
1864end:
1865 return ret;
1866}
1867
c35a1669
JG
1868BT_HIDDEN
1869void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
1870 int byte_order)
1871{
1872 if (!type) {
1873 return;
1874 }
1875
1876 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
1877 if (set_byte_order_funcs[type->declaration->id]) {
1878 set_byte_order_funcs[type->declaration->id](type,
1879 byte_order, 1);
1880 }
1881}
1882
273b65be
JG
1883static
1884void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
1885{
1886 struct bt_ctf_field_type_integer *integer;
1887
1888 if (!ref) {
1889 return;
1890 }
1891
1892 integer = container_of(
1893 container_of(ref, struct bt_ctf_field_type, ref_count),
1894 struct bt_ctf_field_type_integer, parent);
eee752e5
JG
1895 if (integer->mapped_clock) {
1896 bt_ctf_clock_put(integer->mapped_clock);
1897 }
273b65be
JG
1898 g_free(integer);
1899}
1900
1901static
1902void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
1903{
1904 struct bt_ctf_field_type_enumeration *enumeration;
1905
1906 if (!ref) {
1907 return;
1908 }
1909
1910 enumeration = container_of(
1911 container_of(ref, struct bt_ctf_field_type, ref_count),
1912 struct bt_ctf_field_type_enumeration, parent);
1913 g_ptr_array_free(enumeration->entries, TRUE);
1914 bt_ctf_field_type_put(enumeration->container);
1915 g_free(enumeration);
1916}
1917
1918static
1919void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
1920{
1921 struct bt_ctf_field_type_floating_point *floating_point;
1922
1923 if (!ref) {
1924 return;
1925 }
1926
1927 floating_point = container_of(
1928 container_of(ref, struct bt_ctf_field_type, ref_count),
1929 struct bt_ctf_field_type_floating_point, parent);
1930 g_free(floating_point);
1931}
1932
1933static
1934void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
1935{
1936 struct bt_ctf_field_type_structure *structure;
1937
1938 if (!ref) {
1939 return;
1940 }
1941
1942 structure = container_of(
1943 container_of(ref, struct bt_ctf_field_type, ref_count),
1944 struct bt_ctf_field_type_structure, parent);
1945 g_ptr_array_free(structure->fields, TRUE);
1946 g_hash_table_destroy(structure->field_name_to_index);
1947 g_free(structure);
1948}
1949
1950static
1951void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
1952{
1953 struct bt_ctf_field_type_variant *variant;
1954
1955 if (!ref) {
1956 return;
1957 }
1958
1959 variant = container_of(
1960 container_of(ref, struct bt_ctf_field_type, ref_count),
1961 struct bt_ctf_field_type_variant, parent);
1962 g_ptr_array_free(variant->fields, TRUE);
1963 g_hash_table_destroy(variant->field_name_to_index);
1964 g_string_free(variant->tag_name, TRUE);
1965 bt_ctf_field_type_put(&variant->tag->parent);
1966 g_free(variant);
1967}
1968
1969static
1970void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
1971{
1972 struct bt_ctf_field_type_array *array;
1973
1974 if (!ref) {
1975 return;
1976 }
1977
1978 array = container_of(
1979 container_of(ref, struct bt_ctf_field_type, ref_count),
1980 struct bt_ctf_field_type_array, parent);
1981 bt_ctf_field_type_put(array->element_type);
1982 g_free(array);
1983}
1984
1985static
1986void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
1987{
1988 struct bt_ctf_field_type_sequence *sequence;
1989
1990 if (!ref) {
1991 return;
1992 }
1993
1994 sequence = container_of(
1995 container_of(ref, struct bt_ctf_field_type, ref_count),
1996 struct bt_ctf_field_type_sequence, parent);
1997 bt_ctf_field_type_put(sequence->element_type);
1998 g_string_free(sequence->length_field_name, TRUE);
1999 g_free(sequence);
2000}
2001
2002static
2003void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *ref)
2004{
2005 struct bt_ctf_field_type_string *string;
2006
2007 if (!ref) {
2008 return;
2009 }
2010
2011 string = container_of(
2012 container_of(ref, struct bt_ctf_field_type, ref_count),
2013 struct bt_ctf_field_type_string, parent);
2014 g_free(string);
2015}
2016
2017static
2018void generic_field_type_freeze(struct bt_ctf_field_type *type)
2019{
2020 type->frozen = 1;
2021}
2022
2023static
2024void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2025{
2026 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2027 type, struct bt_ctf_field_type_enumeration, parent);
2028
2029 generic_field_type_freeze(type);
2030 bt_ctf_field_type_freeze(enumeration_type->container);
2031}
2032
2033static
2034void freeze_structure_field(struct structure_field *field)
2035{
2036 bt_ctf_field_type_freeze(field->type);
2037}
2038
2039static
2040void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2041{
2042 struct bt_ctf_field_type_structure *structure_type = container_of(
2043 type, struct bt_ctf_field_type_structure, parent);
2044
2045 generic_field_type_freeze(type);
2046 g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field,
2047 NULL);
2048}
2049
2050static
2051void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2052{
2053 struct bt_ctf_field_type_variant *variant_type = container_of(
2054 type, struct bt_ctf_field_type_variant, parent);
2055
2056 generic_field_type_freeze(type);
2057 g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field,
2058 NULL);
2059}
2060
2061static
2062void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2063{
2064 struct bt_ctf_field_type_array *array_type = container_of(
2065 type, struct bt_ctf_field_type_array, parent);
2066
2067 generic_field_type_freeze(type);
2068 bt_ctf_field_type_freeze(array_type->element_type);
2069}
2070
2071static
2072void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2073{
2074 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2075 type, struct bt_ctf_field_type_sequence, parent);
2076
2077 generic_field_type_freeze(type);
2078 bt_ctf_field_type_freeze(sequence_type->element_type);
2079}
2080
2081static
2082const char *get_encoding_string(enum ctf_string_encoding encoding)
2083{
2084 const char *encoding_string;
2085
2086 switch (encoding) {
2087 case CTF_STRING_NONE:
2088 encoding_string = "none";
2089 break;
2090 case CTF_STRING_ASCII:
2091 encoding_string = "ASCII";
2092 break;
2093 case CTF_STRING_UTF8:
2094 encoding_string = "UTF8";
2095 break;
2096 default:
2097 encoding_string = "unknown";
2098 break;
2099 }
2100
2101 return encoding_string;
2102}
2103
2104static
2105const char *get_integer_base_string(enum bt_ctf_integer_base base)
2106{
2107 const char *base_string;
2108
2109 switch (base) {
2110 case BT_CTF_INTEGER_BASE_DECIMAL:
2111 base_string = "decimal";
2112 break;
2113 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2114 base_string = "hexadecimal";
2115 break;
2116 case BT_CTF_INTEGER_BASE_OCTAL:
2117 base_string = "octal";
2118 break;
2119 case BT_CTF_INTEGER_BASE_BINARY:
2120 base_string = "binary";
2121 break;
2122 default:
2123 base_string = "unknown";
2124 break;
2125 }
2126
2127 return base_string;
2128}
2129
2130static
2131int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2132 struct metadata_context *context)
2133{
2134 struct bt_ctf_field_type_integer *integer = container_of(type,
2135 struct bt_ctf_field_type_integer, parent);
6cfb906f 2136 int ret = 0;
273b65be
JG
2137
2138 g_string_append_printf(context->string,
6cfb906f 2139 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
2140 integer->declaration.len, type->declaration->alignment,
2141 (integer->declaration.signedness ? "true" : "false"),
2142 get_encoding_string(integer->declaration.encoding),
2143 get_integer_base_string(integer->declaration.base),
2144 get_byte_order_string(integer->declaration.byte_order));
6cfb906f
JG
2145 if (integer->mapped_clock) {
2146 const char *clock_name = bt_ctf_clock_get_name(
2147 integer->mapped_clock);
2148
2149 if (!clock_name) {
2150 ret = -1;
2151 goto end;
2152 }
2153
2154 g_string_append_printf(context->string,
4ebdec03 2155 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2156 }
2157
2158 g_string_append(context->string, "; }");
2159end:
2160 return ret;
273b65be
JG
2161}
2162
2163static
2164int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2165 struct metadata_context *context)
2166{
2167 size_t entry;
9ce21c30 2168 int ret;
273b65be
JG
2169 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2170 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2171 struct bt_ctf_field_type *container_type;
2172 int container_signed;
273b65be 2173
9ce21c30
JG
2174 ret = bt_ctf_field_type_validate(type);
2175 if (ret) {
2176 goto end;
2177 }
2178
b92ddaaa
JG
2179 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2180 if (!container_type) {
2181 ret = -1;
2182 goto end;
2183 }
2184
2185 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2186 if (container_signed < 0) {
2187 ret = container_signed;
2188 goto error_put_container_type;
2189 }
2190
273b65be
JG
2191 g_string_append(context->string, "enum : ");
2192 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2193 if (ret) {
b92ddaaa 2194 goto error_put_container_type;
273b65be
JG
2195 }
2196
2197 g_string_append(context->string, " { ");
2198 for (entry = 0; entry < enumeration->entries->len; entry++) {
2199 struct enumeration_mapping *mapping =
2200 enumeration->entries->pdata[entry];
2201
b92ddaaa
JG
2202 if (container_signed) {
2203 if (mapping->range_start._signed ==
2204 mapping->range_end._signed) {
2205 g_string_append_printf(context->string,
2206 "\"%s\" = %" PRId64,
2207 g_quark_to_string(mapping->string),
2208 mapping->range_start._signed);
2209 } else {
2210 g_string_append_printf(context->string,
2211 "\"%s\" = %" PRId64 " ... %" PRId64,
2212 g_quark_to_string(mapping->string),
2213 mapping->range_start._signed,
2214 mapping->range_end._signed);
2215 }
273b65be 2216 } else {
b92ddaaa
JG
2217 if (mapping->range_start._unsigned ==
2218 mapping->range_end._unsigned) {
2219 g_string_append_printf(context->string,
2220 "\"%s\" = %" PRIu64,
2221 g_quark_to_string(mapping->string),
2222 mapping->range_start._unsigned);
2223 } else {
2224 g_string_append_printf(context->string,
2225 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2226 g_quark_to_string(mapping->string),
2227 mapping->range_start._unsigned,
2228 mapping->range_end._unsigned);
2229 }
273b65be
JG
2230 }
2231
2232 g_string_append(context->string,
2233 ((entry != (enumeration->entries->len - 1)) ?
2234 ", " : " }"));
2235 }
2236
2237 if (context->field_name->len) {
2238 g_string_append_printf(context->string, " %s",
2239 context->field_name->str);
2240 g_string_assign(context->field_name, "");
2241 }
b92ddaaa
JG
2242error_put_container_type:
2243 bt_ctf_field_type_put(container_type);
273b65be
JG
2244end:
2245 return ret;
2246}
2247
2248static
2249int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2250 struct metadata_context *context)
2251{
2252 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2253 type, struct bt_ctf_field_type_floating_point, parent);
2254
2255 g_string_append_printf(context->string,
2256 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2257 floating_point->declaration.exp->len,
2258 floating_point->declaration.mantissa->len + 1,
2259 get_byte_order_string(floating_point->declaration.byte_order),
2260 type->declaration->alignment);
2261 return 0;
2262}
2263
2264static
2265int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2266 struct metadata_context *context)
2267{
2268 size_t i;
2269 unsigned int indent;
2270 int ret = 0;
2271 struct bt_ctf_field_type_structure *structure = container_of(type,
2272 struct bt_ctf_field_type_structure, parent);
2273 GString *structure_field_name = context->field_name;
2274
2275 context->field_name = g_string_new("");
2276
2277 context->current_indentation_level++;
2278 g_string_append(context->string, "struct {\n");
2279
2280 for (i = 0; i < structure->fields->len; i++) {
2281 struct structure_field *field;
2282
2283 for (indent = 0; indent < context->current_indentation_level;
2284 indent++) {
2285 g_string_append_c(context->string, '\t');
2286 }
2287
2288 field = structure->fields->pdata[i];
2289 g_string_assign(context->field_name,
2290 g_quark_to_string(field->name));
2291 ret = bt_ctf_field_type_serialize(field->type, context);
2292 if (ret) {
2293 goto end;
2294 }
2295
2296 if (context->field_name->len) {
2297 g_string_append_printf(context->string, " %s",
2298 context->field_name->str);
2299 }
2300 g_string_append(context->string, ";\n");
2301 }
2302
2303 context->current_indentation_level--;
2304 for (indent = 0; indent < context->current_indentation_level;
2305 indent++) {
2306 g_string_append_c(context->string, '\t');
2307 }
2308
2309 g_string_append_printf(context->string, "} align(%zu)",
2310 type->declaration->alignment);
2311end:
2312 g_string_free(context->field_name, TRUE);
2313 context->field_name = structure_field_name;
2314 return ret;
2315}
2316
2317static
2318int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2319 struct metadata_context *context)
2320{
2321 size_t i;
2322 unsigned int indent;
2323 int ret = 0;
2324 struct bt_ctf_field_type_variant *variant = container_of(
2325 type, struct bt_ctf_field_type_variant, parent);
2326 GString *variant_field_name = context->field_name;
2327
2328 context->field_name = g_string_new("");
6964b7fd
JG
2329 if (variant->tag_name->len > 0) {
2330 g_string_append_printf(context->string,
2331 "variant <%s> {\n", variant->tag_name->str);
2332 } else {
2333 g_string_append(context->string, "variant {\n");
2334 }
2335
273b65be
JG
2336 context->current_indentation_level++;
2337 for (i = 0; i < variant->fields->len; i++) {
2338 struct structure_field *field = variant->fields->pdata[i];
2339
2340 g_string_assign(context->field_name,
2341 g_quark_to_string(field->name));
2342 for (indent = 0; indent < context->current_indentation_level;
2343 indent++) {
2344 g_string_append_c(context->string, '\t');
2345 }
2346
2347 g_string_assign(context->field_name,
2348 g_quark_to_string(field->name));
2349 ret = bt_ctf_field_type_serialize(field->type, context);
2350 if (ret) {
2351 goto end;
2352 }
2353
2354 if (context->field_name->len) {
2355 g_string_append_printf(context->string, " %s;",
2356 context->field_name->str);
2357 }
2358
2359 g_string_append_c(context->string, '\n');
2360 }
2361
2362 context->current_indentation_level--;
2363 for (indent = 0; indent < context->current_indentation_level;
2364 indent++) {
2365 g_string_append_c(context->string, '\t');
2366 }
2367
2368 g_string_append(context->string, "}");
2369end:
2370 g_string_free(context->field_name, TRUE);
2371 context->field_name = variant_field_name;
2372 return ret;
2373}
2374
2375static
2376int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2377 struct metadata_context *context)
2378{
2379 int ret = 0;
2380 struct bt_ctf_field_type_array *array = container_of(type,
2381 struct bt_ctf_field_type_array, parent);
2382
2383 ret = bt_ctf_field_type_serialize(array->element_type, context);
2384 if (ret) {
2385 goto end;
2386 }
2387
2388 if (context->field_name->len) {
2389 g_string_append_printf(context->string, " %s[%u]",
2390 context->field_name->str, array->length);
2391 g_string_assign(context->field_name, "");
2392 } else {
2393 g_string_append_printf(context->string, "[%u]", array->length);
2394 }
2395end:
2396 return ret;
2397}
2398
2399static
2400int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2401 struct metadata_context *context)
2402{
2403 int ret = 0;
2404 struct bt_ctf_field_type_sequence *sequence = container_of(
2405 type, struct bt_ctf_field_type_sequence, parent);
2406
2407 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2408 if (ret) {
2409 goto end;
2410 }
2411
2412 if (context->field_name->len) {
2413 g_string_append_printf(context->string, " %s[%s]",
2414 context->field_name->str,
2415 sequence->length_field_name->str);
2416 g_string_assign(context->field_name, "");
2417 } else {
2418 g_string_append_printf(context->string, "[%s]",
2419 sequence->length_field_name->str);
2420 }
2421end:
2422 return ret;
2423}
2424
2425static
2426int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2427 struct metadata_context *context)
2428{
2429 struct bt_ctf_field_type_string *string = container_of(
2430 type, struct bt_ctf_field_type_string, parent);
2431
2432 g_string_append_printf(context->string,
2433 "string { encoding = %s; }",
2434 get_encoding_string(string->declaration.encoding));
2435 return 0;
2436}
2437
2438static
2439void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 2440 int byte_order, int set_native)
273b65be
JG
2441{
2442 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2443 struct bt_ctf_field_type_integer, parent);
2444
c35a1669
JG
2445 if (set_native) {
2446 integer_type->declaration.byte_order =
2447 integer_type->declaration.byte_order == 0 ?
2448 byte_order : integer_type->declaration.byte_order;
2449 } else {
2450 integer_type->declaration.byte_order = byte_order;
2451 }
2452}
2453
2454static
2455void bt_ctf_field_type_enumeration_set_byte_order(
2456 struct bt_ctf_field_type *type, int byte_order, int set_native)
2457{
2458 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
2459 struct bt_ctf_field_type_enumeration, parent);
2460
2461 /* Safe to assume that container is an integer */
2462 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
2463 byte_order, set_native);
273b65be
JG
2464}
2465
2466static
2467void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 2468 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
2469{
2470 struct bt_ctf_field_type_floating_point *floating_point_type =
2471 container_of(type, struct bt_ctf_field_type_floating_point,
2472 parent);
2473
c35a1669
JG
2474 if (set_native) {
2475 floating_point_type->declaration.byte_order =
2476 floating_point_type->declaration.byte_order == 0 ?
2477 byte_order :
2478 floating_point_type->declaration.byte_order;
2479 floating_point_type->sign.byte_order =
2480 floating_point_type->sign.byte_order == 0 ?
2481 byte_order : floating_point_type->sign.byte_order;
2482 floating_point_type->mantissa.byte_order =
2483 floating_point_type->mantissa.byte_order == 0 ?
2484 byte_order : floating_point_type->mantissa.byte_order;
2485 floating_point_type->exp.byte_order =
2486 floating_point_type->exp.byte_order == 0 ?
2487 byte_order : floating_point_type->exp.byte_order;
2488 } else {
2489 floating_point_type->declaration.byte_order = byte_order;
2490 floating_point_type->sign.byte_order = byte_order;
2491 floating_point_type->mantissa.byte_order = byte_order;
2492 floating_point_type->exp.byte_order = byte_order;
2493 }
2494}
2495
2496static
2497void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
2498 int byte_order, int set_native)
2499{
2500 int i;
2501 struct bt_ctf_field_type_structure *structure_type =
2502 container_of(type, struct bt_ctf_field_type_structure,
2503 parent);
2504
2505 for (i = 0; i < structure_type->fields->len; i++) {
2506 struct structure_field *field = g_ptr_array_index(
2507 structure_type->fields, i);
2508 struct bt_ctf_field_type *field_type = field->type;
2509
2510 if (set_byte_order_funcs[field_type->declaration->id]) {
2511 set_byte_order_funcs[field_type->declaration->id](
2512 field_type, byte_order, set_native);
2513 }
2514 }
2515}
2516
2517static
2518void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
2519 int byte_order, int set_native)
2520{
2521 int i;
2522 struct bt_ctf_field_type_variant *variant_type =
2523 container_of(type, struct bt_ctf_field_type_variant,
2524 parent);
2525
2526 for (i = 0; i < variant_type->fields->len; i++) {
2527 struct structure_field *field = g_ptr_array_index(
2528 variant_type->fields, i);
2529 struct bt_ctf_field_type *field_type = field->type;
2530
2531 if (set_byte_order_funcs[field_type->declaration->id]) {
2532 set_byte_order_funcs[field_type->declaration->id](
2533 field_type, byte_order, set_native);
2534 }
2535 }
2536}
2537
2538static
2539void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
2540 int byte_order, int set_native)
2541{
2542 struct bt_ctf_field_type_array *array_type =
2543 container_of(type, struct bt_ctf_field_type_array,
2544 parent);
2545
2546 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
2547 set_byte_order_funcs[array_type->element_type->declaration->id](
2548 array_type->element_type, byte_order, set_native);
2549 }
2550}
2551
2552static
2553void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
2554 int byte_order, int set_native)
2555{
2556 struct bt_ctf_field_type_sequence *sequence_type =
2557 container_of(type, struct bt_ctf_field_type_sequence,
2558 parent);
2559
2560 if (set_byte_order_funcs[
2561 sequence_type->element_type->declaration->id]) {
2562 set_byte_order_funcs[
2563 sequence_type->element_type->declaration->id](
2564 sequence_type->element_type, byte_order, set_native);
2565 }
273b65be 2566}
This page took 0.140602 seconds and 4 git commands to generate.