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