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