Tests: add tests for the new trace and trace clock accessors
[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
b92ddaaa
JG
706int64_t bt_ctf_field_type_enumeration_get_mapping_count(
707 struct bt_ctf_field_type *type)
708{
709 int64_t ret = 0;
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);
719 ret = enumeration->entries->len;
720end:
721 return ret;
722}
723
724static inline
725struct enumeration_mapping *get_enumeration_mapping(
726 struct bt_ctf_field_type *type, size_t index)
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(
743 struct bt_ctf_field_type *type, size_t index,
744 const char **string, int64_t *range_start, int64_t *range_end)
745{
746 struct enumeration_mapping *mapping;
747 int ret = 0;
748
749 if (!type || !string || !range_start || !range_end ||
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(
769 struct bt_ctf_field_type *type, size_t index,
770 const char **string, uint64_t *range_start, uint64_t *range_end)
771{
772 struct enumeration_mapping *mapping;
773 int ret = 0;
774
775 if (!type || !string || !range_start || !range_end ||
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(
795 struct bt_ctf_field_type *type, const char *name,
796 size_t *index)
797{
798 size_t i;
799 GQuark name_quark;
800 struct bt_ctf_field_type_enumeration *enumeration;
801 int ret = 0;
802
803 if (!type || !name || !index ||
804 (type->declaration->id != CTF_TYPE_ENUM)) {
805 ret = -1;
806 goto end;
807 }
808
809 name_quark = g_quark_try_string(name);
810 if (!name_quark) {
811 ret = -1;
812 goto end;
813 }
814
815 enumeration = container_of(type,
816 struct bt_ctf_field_type_enumeration, parent);
817 for (i = 0; i < enumeration->entries->len; i++) {
818 struct enumeration_mapping *mapping =
819 get_enumeration_mapping(type, i);
820
821 if (mapping->string == name_quark) {
822 *index = i;
823 goto end;
824 }
825 }
826
827 ret = -1;
828end:
829 return ret;
830}
831
832int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
833 struct bt_ctf_field_type *type, int64_t value,
834 size_t *index)
835{
836 struct bt_ctf_field_type_enumeration *enumeration;
837 size_t i;
838 int ret = 0;
839
840 if (!type || !index || (type->declaration->id != CTF_TYPE_ENUM)) {
841 ret = -1;
842 goto end;
843 }
844
845 enumeration = container_of(type,
846 struct bt_ctf_field_type_enumeration, parent);
847 for (i = 0; i < enumeration->entries->len; i++) {
848 struct enumeration_mapping *mapping =
849 get_enumeration_mapping(type, i);
850
851 if (value >= mapping->range_start._signed &&
852 value <= mapping->range_end._signed) {
853 *index = i;
854 goto end;
855 }
856 }
857
858 ret = -1;
859end:
860 return ret;
861}
862
863int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
864 struct bt_ctf_field_type *type, uint64_t value,
865 size_t *index)
866{
867 struct bt_ctf_field_type_enumeration *enumeration;
868 size_t i;
869 int ret = 0;
870
871 if (!type || !index || (type->declaration->id != CTF_TYPE_ENUM)) {
872 ret = -1;
873 goto end;
874 }
875
876 enumeration = container_of(type,
877 struct bt_ctf_field_type_enumeration, parent);
878 for (i = 0; i < enumeration->entries->len; i++) {
879 struct enumeration_mapping *mapping =
880 get_enumeration_mapping(type, i);
881
882 if (value >= mapping->range_start._unsigned &&
883 value <= mapping->range_end._unsigned) {
884 *index = i;
885 goto end;
886 }
887 }
888
889 ret = -1;
890end:
891 return ret;
892}
893
273b65be
JG
894struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
895{
896 struct bt_ctf_field_type_floating_point *floating_point =
897 g_new0(struct bt_ctf_field_type_floating_point, 1);
898
899 if (!floating_point) {
900 goto end;
901 }
902
903 floating_point->declaration.sign = &floating_point->sign;
904 floating_point->declaration.mantissa = &floating_point->mantissa;
905 floating_point->declaration.exp = &floating_point->exp;
906 floating_point->sign.len = 1;
907 floating_point->parent.declaration = &floating_point->declaration.p;
908 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
909 floating_point->declaration.exp->len =
910 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
911 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
912 floating_point->sign.p.alignment = 1;
913 floating_point->mantissa.p.alignment = 1;
914 floating_point->exp.p.alignment = 1;
915
916 bt_ctf_field_type_init(&floating_point->parent);
917end:
918 return floating_point ? &floating_point->parent : NULL;
919}
920
b92ddaaa
JG
921int bt_ctf_field_type_floating_point_get_exponent_digits(
922 struct bt_ctf_field_type *type)
923{
924 int ret = 0;
925 struct bt_ctf_field_type_floating_point *floating_point;
926
927 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
928 ret = -1;
929 goto end;
930 }
931
932 floating_point = container_of(type,
933 struct bt_ctf_field_type_floating_point, parent);
934 ret = (int) floating_point->declaration.exp->len;
935end:
936 return ret;
937}
938
273b65be
JG
939int bt_ctf_field_type_floating_point_set_exponent_digits(
940 struct bt_ctf_field_type *type,
941 unsigned int exponent_digits)
942{
943 int ret = 0;
944 struct bt_ctf_field_type_floating_point *floating_point;
945
946 if (!type || type->frozen ||
947 (type->declaration->id != CTF_TYPE_FLOAT)) {
948 ret = -1;
949 goto end;
950 }
951
952 floating_point = container_of(type,
953 struct bt_ctf_field_type_floating_point, parent);
954 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
955 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
956 (exponent_digits !=
957 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
958 ret = -1;
959 goto end;
960 }
961
962 floating_point->declaration.exp->len = exponent_digits;
963end:
964 return ret;
965}
966
b92ddaaa
JG
967int bt_ctf_field_type_floating_point_get_mantissa_digits(
968 struct bt_ctf_field_type *type)
969{
970 int ret = 0;
971 struct bt_ctf_field_type_floating_point *floating_point;
972
973 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
974 ret = -1;
975 goto end;
976 }
977
978 floating_point = container_of(type,
979 struct bt_ctf_field_type_floating_point, parent);
980 ret = (int) floating_point->mantissa.len + 1;
981end:
982 return ret;
983}
984
273b65be
JG
985int bt_ctf_field_type_floating_point_set_mantissa_digits(
986 struct bt_ctf_field_type *type,
987 unsigned int mantissa_digits)
988{
989 int ret = 0;
990 struct bt_ctf_field_type_floating_point *floating_point;
991
992 if (!type || type->frozen ||
993 (type->declaration->id != CTF_TYPE_FLOAT)) {
994 ret = -1;
995 goto end;
996 }
997
998 floating_point = container_of(type,
999 struct bt_ctf_field_type_floating_point, parent);
1000
1001 if ((mantissa_digits != FLT_MANT_DIG) &&
1002 (mantissa_digits != DBL_MANT_DIG) &&
1003 (mantissa_digits != LDBL_MANT_DIG)) {
1004 ret = -1;
1005 goto end;
1006 }
1007
1008 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1009end:
1010 return ret;
1011}
1012
1013struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1014{
1015 struct bt_ctf_field_type_structure *structure =
1016 g_new0(struct bt_ctf_field_type_structure, 1);
1017
1018 if (!structure) {
1019 goto error;
1020 }
1021
1022 structure->parent.declaration = &structure->declaration.p;
1023 structure->parent.declaration->id = CTF_TYPE_STRUCT;
1024 bt_ctf_field_type_init(&structure->parent);
1025 structure->fields = g_ptr_array_new_with_free_func(
1026 (GDestroyNotify)destroy_structure_field);
1027 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
1028 return &structure->parent;
1029error:
1030 return NULL;
1031}
1032
1033int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1034 struct bt_ctf_field_type *field_type,
1035 const char *field_name)
1036{
1037 int ret = 0;
1038 struct bt_ctf_field_type_structure *structure;
1039
1040 if (!type || !field_type || type->frozen ||
1041 validate_identifier(field_name) ||
9ce21c30
JG
1042 (type->declaration->id != CTF_TYPE_STRUCT) ||
1043 bt_ctf_field_type_validate(field_type)) {
e6235f1f 1044 ret = -1;
273b65be
JG
1045 goto end;
1046 }
1047
1048 structure = container_of(type,
1049 struct bt_ctf_field_type_structure, parent);
1050 if (add_structure_field(structure->fields,
1051 structure->field_name_to_index, field_type, field_name)) {
1052 ret = -1;
1053 goto end;
1054 }
1055
b92ddaaa
JG
1056 if (type->declaration->alignment < field_type->declaration->alignment) {
1057 type->declaration->alignment =
1058 field_type->declaration->alignment;
1059 }
1060end:
1061 return ret;
1062}
1063
1064int64_t bt_ctf_field_type_structure_get_field_count(
1065 struct bt_ctf_field_type *type)
1066{
1067 int64_t ret = 0;
1068 struct bt_ctf_field_type_structure *structure;
1069
1070 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1071 ret = -1;
1072 goto end;
1073 }
1074
1075 structure = container_of(type, struct bt_ctf_field_type_structure,
1076 parent);
1077 ret = structure->fields->len;
1078end:
1079 return ret;
1080}
1081
1082int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1083 const char **field_name, struct bt_ctf_field_type **field_type,
1084 size_t index)
1085{
1086 struct bt_ctf_field_type_structure *structure;
1087 struct structure_field *field;
1088 int ret = 0;
1089
1090 if (!type || !field_name || !field_type ||
1091 (type->declaration->id != CTF_TYPE_STRUCT)) {
1092 ret = -1;
1093 goto end;
1094 }
1095
1096 structure = container_of(type, struct bt_ctf_field_type_structure,
1097 parent);
1098 if (index >= structure->fields->len) {
1099 ret = -1;
1100 goto end;
1101 }
1102
1103 field = g_ptr_array_index(structure->fields, index);
1104 *field_type = field->type;
1105 bt_ctf_field_type_get(field->type);
1106 *field_name = g_quark_to_string(field->name);
1107end:
1108 return ret;
1109}
1110
1111struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1112 struct bt_ctf_field_type *type,
1113 const char *name)
1114{
1115 size_t index;
1116 GQuark name_quark;
1117 struct structure_field *field;
1118 struct bt_ctf_field_type_structure *structure;
1119 struct bt_ctf_field_type *field_type = NULL;
1120
1121 if (!type || !name) {
1122 goto end;
1123 }
1124
1125 name_quark = g_quark_try_string(name);
1126 if (!name_quark) {
1127 goto end;
1128 }
1129
1130 structure = container_of(type, struct bt_ctf_field_type_structure,
1131 parent);
1132 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1133 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1134 goto end;
273b65be 1135 }
b92ddaaa
JG
1136
1137 field = structure->fields->pdata[index];
1138 field_type = field->type;
1139 bt_ctf_field_type_get(field_type);
273b65be 1140end:
b92ddaaa 1141 return field_type;
273b65be
JG
1142}
1143
1144struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1145 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1146{
1147 struct bt_ctf_field_type_variant *variant = NULL;
1148
1149 if (!enum_tag || validate_identifier(tag_name) ||
1150 (enum_tag->declaration->id != CTF_TYPE_ENUM)) {
1151 goto error;
1152 }
1153
1154 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1155 if (!variant) {
1156 goto error;
1157 }
1158
1159 variant->parent.declaration = &variant->declaration.p;
1160 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1161 variant->tag_name = g_string_new(tag_name);
1162 bt_ctf_field_type_init(&variant->parent);
1163 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1164 variant->fields = g_ptr_array_new_with_free_func(
1165 (GDestroyNotify)destroy_structure_field);
1166 bt_ctf_field_type_get(enum_tag);
1167 variant->tag = container_of(enum_tag,
1168 struct bt_ctf_field_type_enumeration, parent);
1169 return &variant->parent;
1170error:
1171 return NULL;
1172}
1173
b92ddaaa
JG
1174struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1175 struct bt_ctf_field_type *type)
1176{
1177 struct bt_ctf_field_type_variant *variant;
1178 struct bt_ctf_field_type *tag_type = NULL;
1179
1180 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1181 goto end;
1182 }
1183
1184 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1185 tag_type = &variant->tag->parent;
1186 bt_ctf_field_type_get(tag_type);
1187end:
1188 return tag_type;
1189}
1190
1191const char *bt_ctf_field_type_variant_get_tag_name(
1192 struct bt_ctf_field_type *type)
1193{
1194 struct bt_ctf_field_type_variant *variant;
1195 const char *tag_name = 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_name = variant->tag_name->str;
1203end:
1204 return tag_name;
1205}
1206
273b65be
JG
1207int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1208 struct bt_ctf_field_type *field_type,
1209 const char *field_name)
1210{
1211 size_t i;
1212 int ret = 0;
1213 int name_found = 0;
1214 struct bt_ctf_field_type_variant *variant;
1215 GQuark field_name_quark = g_quark_from_string(field_name);
1216
1217 if (!type || !field_type || type->frozen ||
1218 validate_identifier(field_name) ||
9ce21c30
JG
1219 (type->declaration->id != CTF_TYPE_VARIANT) ||
1220 bt_ctf_field_type_validate(field_type)) {
273b65be
JG
1221 ret = -1;
1222 goto end;
1223 }
1224
1225 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1226 /* Make sure this name is present in the enum tag */
1227 for (i = 0; i < variant->tag->entries->len; i++) {
1228 struct enumeration_mapping *mapping =
1229 g_ptr_array_index(variant->tag->entries, i);
1230
1231 if (mapping->string == field_name_quark) {
1232 name_found = 1;
1233 break;
1234 }
1235 }
1236
1237 if (!name_found || add_structure_field(variant->fields,
1238 variant->field_name_to_index, field_type, field_name)) {
1239 ret = -1;
1240 goto end;
1241 }
1242end:
1243 return ret;
1244}
1245
b92ddaaa
JG
1246struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1247 struct bt_ctf_field_type *type,
1248 const char *field_name)
1249{
1250 size_t index;
1251 GQuark name_quark;
1252 struct structure_field *field;
1253 struct bt_ctf_field_type_variant *variant;
1254 struct bt_ctf_field_type *field_type = NULL;
1255
1256 if (!type || !field_name) {
1257 goto end;
1258 }
1259
1260 name_quark = g_quark_try_string(field_name);
1261 if (!name_quark) {
1262 goto end;
1263 }
1264
1265 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1266 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1267 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1268 goto end;
1269 }
1270
1271 field = g_ptr_array_index(variant->fields, index);
1272 field_type = field->type;
1273 bt_ctf_field_type_get(field_type);
1274end:
1275 return field_type;
1276}
1277
1278struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1279 struct bt_ctf_field_type *type,
1280 struct bt_ctf_field *tag)
1281{
1282 const char *enum_value;
1283 struct bt_ctf_field_type *field_type = NULL;
1284
1285 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1286 goto end;
1287 }
1288
1289 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1290 if (!enum_value) {
1291 goto end;
1292 }
1293
1294 /* Already increments field_type's reference count */
1295 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1296 type, enum_value);
1297end:
1298 return field_type;
1299}
1300
1301int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1302{
1303 int64_t ret = 0;
1304 struct bt_ctf_field_type_variant *variant;
1305
1306 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1307 ret = -1;
1308 goto end;
1309 }
1310
1311 variant = container_of(type, struct bt_ctf_field_type_variant,
1312 parent);
1313 ret = variant->fields->len;
1314end:
1315 return ret;
1316
1317}
1318
1319int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1320 const char **field_name, struct bt_ctf_field_type **field_type,
1321 size_t index)
1322{
1323 struct bt_ctf_field_type_variant *variant;
1324 struct structure_field *field;
1325 int ret = 0;
1326
1327 if (!type || !field_name || !field_type ||
1328 (type->declaration->id != CTF_TYPE_VARIANT)) {
1329 ret = -1;
1330 goto end;
1331 }
1332
1333 variant = container_of(type, struct bt_ctf_field_type_variant,
1334 parent);
1335 if (index >= variant->fields->len) {
1336 ret = -1;
1337 goto end;
1338 }
1339
1340 field = g_ptr_array_index(variant->fields, index);
1341 *field_type = field->type;
1342 bt_ctf_field_type_get(field->type);
1343 *field_name = g_quark_to_string(field->name);
1344end:
1345 return ret;
1346}
1347
273b65be
JG
1348struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1349 struct bt_ctf_field_type *element_type,
1350 unsigned int length)
1351{
1352 struct bt_ctf_field_type_array *array = NULL;
1353
9ce21c30
JG
1354 if (!element_type || length == 0 ||
1355 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1356 goto error;
1357 }
1358
1359 array = g_new0(struct bt_ctf_field_type_array, 1);
1360 if (!array) {
1361 goto error;
1362 }
1363
1364 array->parent.declaration = &array->declaration.p;
1365 array->parent.declaration->id = CTF_TYPE_ARRAY;
1366 bt_ctf_field_type_init(&array->parent);
1367 bt_ctf_field_type_get(element_type);
1368 array->element_type = element_type;
1369 array->length = length;
1370 array->parent.declaration->alignment =
1371 element_type->declaration->alignment;
1372 return &array->parent;
1373error:
1374 return NULL;
1375}
1376
b92ddaaa
JG
1377struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1378 struct bt_ctf_field_type *type)
1379{
1380 struct bt_ctf_field_type *ret = NULL;
1381 struct bt_ctf_field_type_array *array;
1382
1383 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1384 goto end;
1385 }
1386
1387 array = container_of(type, struct bt_ctf_field_type_array, parent);
1388 ret = array->element_type;
1389 bt_ctf_field_type_get(ret);
1390end:
1391 return ret;
1392}
1393
1394int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1395{
1396 int64_t ret;
1397 struct bt_ctf_field_type_array *array;
1398
1399 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1400 ret = -1;
1401 goto end;
1402 }
1403
1404 array = container_of(type, struct bt_ctf_field_type_array, parent);
1405 ret = (int64_t) array->length;
1406end:
1407 return ret;
1408}
1409
273b65be
JG
1410struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1411 struct bt_ctf_field_type *element_type,
1412 const char *length_field_name)
1413{
1414 struct bt_ctf_field_type_sequence *sequence = NULL;
1415
9ce21c30
JG
1416 if (!element_type || validate_identifier(length_field_name) ||
1417 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1418 goto error;
1419 }
1420
1421 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1422 if (!sequence) {
1423 goto error;
1424 }
1425
1426 sequence->parent.declaration = &sequence->declaration.p;
1427 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
1428 bt_ctf_field_type_init(&sequence->parent);
1429 bt_ctf_field_type_get(element_type);
1430 sequence->element_type = element_type;
1431 sequence->length_field_name = g_string_new(length_field_name);
1432 sequence->parent.declaration->alignment =
1433 element_type->declaration->alignment;
1434 return &sequence->parent;
1435error:
1436 return NULL;
1437}
1438
b92ddaaa
JG
1439struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1440 struct bt_ctf_field_type *type)
1441{
1442 struct bt_ctf_field_type *ret = NULL;
1443 struct bt_ctf_field_type_sequence *sequence;
1444
1445 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1446 goto end;
1447 }
1448
1449 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1450 parent);
1451 ret = sequence->element_type;
1452 bt_ctf_field_type_get(ret);
1453end:
1454 return ret;
1455}
1456
1457const char *bt_ctf_field_type_sequence_get_length_field_name(
1458 struct bt_ctf_field_type *type)
1459{
1460 const char *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->length_field_name->str;
1470end:
1471 return ret;
1472}
1473
273b65be
JG
1474struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1475{
1476 struct bt_ctf_field_type_string *string =
1477 g_new0(struct bt_ctf_field_type_string, 1);
1478
1479 if (!string) {
1480 return NULL;
1481 }
1482
1483 string->parent.declaration = &string->declaration.p;
1484 string->parent.declaration->id = CTF_TYPE_STRING;
1485 bt_ctf_field_type_init(&string->parent);
1486 string->declaration.encoding = CTF_STRING_UTF8;
1487 string->parent.declaration->alignment = CHAR_BIT;
1488 return &string->parent;
1489}
1490
b92ddaaa
JG
1491enum ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1492 struct bt_ctf_field_type *type)
1493{
1494 struct bt_ctf_field_type_string *string;
1495 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
1496
1497 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1498 goto end;
1499 }
1500
1501 string = container_of(type, struct bt_ctf_field_type_string,
1502 parent);
1503 ret = string->declaration.encoding;
1504end:
1505 return ret;
1506}
1507
1508int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
273b65be
JG
1509 enum ctf_string_encoding encoding)
1510{
1511 int ret = 0;
1512 struct bt_ctf_field_type_string *string;
1513
1514 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1515 (encoding != CTF_STRING_UTF8 &&
1516 encoding != CTF_STRING_ASCII)) {
1517 ret = -1;
1518 goto end;
1519 }
1520
1521 string = container_of(type, struct bt_ctf_field_type_string, parent);
1522 string->declaration.encoding = encoding;
1523end:
1524 return ret;
1525}
1526
b92ddaaa
JG
1527int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1528{
1529 int ret;
1530
1531 if (!type) {
1532 ret = -1;
1533 goto end;
1534 }
1535
1536 ret = (int) type->declaration->alignment;
1537end:
1538 return ret;
1539}
1540
273b65be
JG
1541int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
1542 unsigned int alignment)
1543{
1544 int ret = 0;
1545
1546 /* Alignment must be bit-aligned (1) or byte aligned */
1547 if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
1548 ret = -1;
1549 goto end;
1550 }
1551
1552 if (type->declaration->id == CTF_TYPE_STRING &&
1553 alignment != CHAR_BIT) {
1554 ret = -1;
1555 goto end;
1556 }
1557
1558 type->declaration->alignment = alignment;
1559 ret = 0;
1560end:
1561 return ret;
1562}
1563
b92ddaaa
JG
1564enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1565 struct bt_ctf_field_type *type)
1566{
1567 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
1568
1569 if (!type) {
1570 goto end;
1571 }
1572
1573 switch (type->declaration->id) {
1574 case CTF_TYPE_INTEGER:
1575 {
1576 struct bt_ctf_field_type_integer *integer = container_of(
1577 type, struct bt_ctf_field_type_integer, parent);
1578 ret = integer->declaration.byte_order == LITTLE_ENDIAN ?
1579 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN :
1580 BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1581 break;
1582 }
1583 case CTF_TYPE_FLOAT:
1584 {
1585 struct bt_ctf_field_type_floating_point *floating_point =
1586 container_of(type,
1587 struct bt_ctf_field_type_floating_point,
1588 parent);
1589 ret = floating_point->declaration.byte_order == LITTLE_ENDIAN ?
1590 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN :
1591 BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1592 break;
1593 }
1594 default:
1595 break;
1596 }
1597end:
1598 return ret;
1599}
1600
273b65be
JG
1601int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
1602 enum bt_ctf_byte_order byte_order)
1603{
1604 int ret = 0;
1605 int internal_byte_order;
1606 enum ctf_type_id type_id;
1607
1608 if (!type || type->frozen) {
1609 ret = -1;
1610 goto end;
1611 }
1612
1613 type_id = type->declaration->id;
1614 switch (byte_order) {
1615 case BT_CTF_BYTE_ORDER_NATIVE:
1616 internal_byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN ?
1617 LITTLE_ENDIAN : BIG_ENDIAN);
1618 break;
1619 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
1620 internal_byte_order = LITTLE_ENDIAN;
1621 break;
1622 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
1623 case BT_CTF_BYTE_ORDER_NETWORK:
1624 internal_byte_order = BIG_ENDIAN;
1625 break;
1626 default:
1627 ret = -1;
1628 goto end;
1629 }
1630
1631 if (set_byte_order_funcs[type_id]) {
1632 set_byte_order_funcs[type_id](type, internal_byte_order);
1633 }
1634end:
1635 return ret;
1636}
1637
b92ddaaa
JG
1638enum ctf_type_id bt_ctf_field_type_get_type_id(
1639 struct bt_ctf_field_type *type)
1640{
1641 if (!type) {
1642 return CTF_TYPE_UNKNOWN;
1643 }
1644
1645 return type->declaration->id;
1646}
1647
2f2d8e05
JG
1648const char *bt_ctf_field_type_get_alias_name(
1649 struct bt_ctf_field_type *type)
1650{
1651 const char *name = NULL;
1652
1653 if (!type || !type->alias_name) {
1654 goto end;
1655 }
1656
1657 name = type->alias_name->str;
1658end:
1659 return name;
1660}
1661
273b65be
JG
1662void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
1663{
1664 if (!type) {
1665 return;
1666 }
1667
1668 bt_ctf_ref_get(&type->ref_count);
1669}
1670
1671void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
1672{
273b65be
JG
1673 if (!type) {
1674 return;
1675 }
1676
2f2d8e05 1677 bt_ctf_ref_put(&type->ref_count, bt_ctf_field_type_destroy);
273b65be
JG
1678}
1679
1680BT_HIDDEN
1681void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
1682{
1683 if (!type) {
1684 return;
1685 }
1686
1687 type->freeze(type);
1688}
1689
1690BT_HIDDEN
b92ddaaa
JG
1691struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
1692 struct bt_ctf_field_type_variant *variant,
1693 int64_t tag_value)
273b65be
JG
1694{
1695 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
1696 GQuark field_name_quark;
1697 gpointer index;
1698 struct structure_field *field_entry;
1699 struct range_overlap_query query = {
1700 .range_start._signed = tag_value,
1701 .range_end._signed = tag_value,
1702 .mapping_name = 0, .overlaps = 0};
273b65be 1703
b92ddaaa
JG
1704 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
1705 &query);
1706 if (!query.overlaps) {
273b65be
JG
1707 goto end;
1708 }
1709
b92ddaaa
JG
1710 field_name_quark = query.mapping_name;
1711 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1712 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
273b65be
JG
1713 goto end;
1714 }
1715
b92ddaaa
JG
1716 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
1717 type = field_entry->type;
273b65be
JG
1718end:
1719 return type;
1720}
1721
1722BT_HIDDEN
b92ddaaa 1723struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 1724 struct bt_ctf_field_type_variant *variant,
b92ddaaa 1725 uint64_t tag_value)
273b65be
JG
1726{
1727 struct bt_ctf_field_type *type = NULL;
1728 GQuark field_name_quark;
1729 gpointer index;
1730 struct structure_field *field_entry;
b92ddaaa
JG
1731 struct range_overlap_query query = {
1732 .range_start._unsigned = tag_value,
1733 .range_end._unsigned = tag_value,
1734 .mapping_name = 0, .overlaps = 0};
273b65be 1735
b92ddaaa
JG
1736 g_ptr_array_foreach(variant->tag->entries,
1737 check_ranges_overlap_unsigned,
273b65be
JG
1738 &query);
1739 if (!query.overlaps) {
1740 goto end;
1741 }
1742
1743 field_name_quark = query.mapping_name;
1744 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1745 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1746 goto end;
1747 }
1748
1749 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
1750 type = field_entry->type;
1751end:
1752 return type;
1753}
1754
1755BT_HIDDEN
1756int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
1757 struct metadata_context *context)
1758{
1759 int ret;
1760
1761 if (!type || !context) {
1762 ret = -1;
1763 goto end;
1764 }
1765
1766 ret = type->serialize(type, context);
1767end:
1768 return ret;
1769}
1770
1771static
1772void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
1773{
1774 struct bt_ctf_field_type_integer *integer;
1775
1776 if (!ref) {
1777 return;
1778 }
1779
1780 integer = container_of(
1781 container_of(ref, struct bt_ctf_field_type, ref_count),
1782 struct bt_ctf_field_type_integer, parent);
1783 g_free(integer);
1784}
1785
1786static
1787void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
1788{
1789 struct bt_ctf_field_type_enumeration *enumeration;
1790
1791 if (!ref) {
1792 return;
1793 }
1794
1795 enumeration = container_of(
1796 container_of(ref, struct bt_ctf_field_type, ref_count),
1797 struct bt_ctf_field_type_enumeration, parent);
1798 g_ptr_array_free(enumeration->entries, TRUE);
1799 bt_ctf_field_type_put(enumeration->container);
1800 g_free(enumeration);
1801}
1802
1803static
1804void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
1805{
1806 struct bt_ctf_field_type_floating_point *floating_point;
1807
1808 if (!ref) {
1809 return;
1810 }
1811
1812 floating_point = container_of(
1813 container_of(ref, struct bt_ctf_field_type, ref_count),
1814 struct bt_ctf_field_type_floating_point, parent);
1815 g_free(floating_point);
1816}
1817
1818static
1819void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
1820{
1821 struct bt_ctf_field_type_structure *structure;
1822
1823 if (!ref) {
1824 return;
1825 }
1826
1827 structure = container_of(
1828 container_of(ref, struct bt_ctf_field_type, ref_count),
1829 struct bt_ctf_field_type_structure, parent);
1830 g_ptr_array_free(structure->fields, TRUE);
1831 g_hash_table_destroy(structure->field_name_to_index);
1832 g_free(structure);
1833}
1834
1835static
1836void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
1837{
1838 struct bt_ctf_field_type_variant *variant;
1839
1840 if (!ref) {
1841 return;
1842 }
1843
1844 variant = container_of(
1845 container_of(ref, struct bt_ctf_field_type, ref_count),
1846 struct bt_ctf_field_type_variant, parent);
1847 g_ptr_array_free(variant->fields, TRUE);
1848 g_hash_table_destroy(variant->field_name_to_index);
1849 g_string_free(variant->tag_name, TRUE);
1850 bt_ctf_field_type_put(&variant->tag->parent);
1851 g_free(variant);
1852}
1853
1854static
1855void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
1856{
1857 struct bt_ctf_field_type_array *array;
1858
1859 if (!ref) {
1860 return;
1861 }
1862
1863 array = container_of(
1864 container_of(ref, struct bt_ctf_field_type, ref_count),
1865 struct bt_ctf_field_type_array, parent);
1866 bt_ctf_field_type_put(array->element_type);
1867 g_free(array);
1868}
1869
1870static
1871void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
1872{
1873 struct bt_ctf_field_type_sequence *sequence;
1874
1875 if (!ref) {
1876 return;
1877 }
1878
1879 sequence = container_of(
1880 container_of(ref, struct bt_ctf_field_type, ref_count),
1881 struct bt_ctf_field_type_sequence, parent);
1882 bt_ctf_field_type_put(sequence->element_type);
1883 g_string_free(sequence->length_field_name, TRUE);
1884 g_free(sequence);
1885}
1886
1887static
1888void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *ref)
1889{
1890 struct bt_ctf_field_type_string *string;
1891
1892 if (!ref) {
1893 return;
1894 }
1895
1896 string = container_of(
1897 container_of(ref, struct bt_ctf_field_type, ref_count),
1898 struct bt_ctf_field_type_string, parent);
1899 g_free(string);
1900}
1901
1902static
1903void generic_field_type_freeze(struct bt_ctf_field_type *type)
1904{
1905 type->frozen = 1;
1906}
1907
1908static
1909void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
1910{
1911 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
1912 type, struct bt_ctf_field_type_enumeration, parent);
1913
1914 generic_field_type_freeze(type);
1915 bt_ctf_field_type_freeze(enumeration_type->container);
1916}
1917
1918static
1919void freeze_structure_field(struct structure_field *field)
1920{
1921 bt_ctf_field_type_freeze(field->type);
1922}
1923
1924static
1925void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
1926{
1927 struct bt_ctf_field_type_structure *structure_type = container_of(
1928 type, struct bt_ctf_field_type_structure, parent);
1929
1930 generic_field_type_freeze(type);
1931 g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field,
1932 NULL);
1933}
1934
1935static
1936void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
1937{
1938 struct bt_ctf_field_type_variant *variant_type = container_of(
1939 type, struct bt_ctf_field_type_variant, parent);
1940
1941 generic_field_type_freeze(type);
1942 g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field,
1943 NULL);
1944}
1945
1946static
1947void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
1948{
1949 struct bt_ctf_field_type_array *array_type = container_of(
1950 type, struct bt_ctf_field_type_array, parent);
1951
1952 generic_field_type_freeze(type);
1953 bt_ctf_field_type_freeze(array_type->element_type);
1954}
1955
1956static
1957void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
1958{
1959 struct bt_ctf_field_type_sequence *sequence_type = container_of(
1960 type, struct bt_ctf_field_type_sequence, parent);
1961
1962 generic_field_type_freeze(type);
1963 bt_ctf_field_type_freeze(sequence_type->element_type);
1964}
1965
1966static
1967const char *get_encoding_string(enum ctf_string_encoding encoding)
1968{
1969 const char *encoding_string;
1970
1971 switch (encoding) {
1972 case CTF_STRING_NONE:
1973 encoding_string = "none";
1974 break;
1975 case CTF_STRING_ASCII:
1976 encoding_string = "ASCII";
1977 break;
1978 case CTF_STRING_UTF8:
1979 encoding_string = "UTF8";
1980 break;
1981 default:
1982 encoding_string = "unknown";
1983 break;
1984 }
1985
1986 return encoding_string;
1987}
1988
1989static
1990const char *get_integer_base_string(enum bt_ctf_integer_base base)
1991{
1992 const char *base_string;
1993
1994 switch (base) {
1995 case BT_CTF_INTEGER_BASE_DECIMAL:
1996 base_string = "decimal";
1997 break;
1998 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
1999 base_string = "hexadecimal";
2000 break;
2001 case BT_CTF_INTEGER_BASE_OCTAL:
2002 base_string = "octal";
2003 break;
2004 case BT_CTF_INTEGER_BASE_BINARY:
2005 base_string = "binary";
2006 break;
2007 default:
2008 base_string = "unknown";
2009 break;
2010 }
2011
2012 return base_string;
2013}
2014
2015static
2016int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2017 struct metadata_context *context)
2018{
2019 struct bt_ctf_field_type_integer *integer = container_of(type,
2020 struct bt_ctf_field_type_integer, parent);
2021
2022 g_string_append_printf(context->string,
2023 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
2024 integer->declaration.len, type->declaration->alignment,
2025 (integer->declaration.signedness ? "true" : "false"),
2026 get_encoding_string(integer->declaration.encoding),
2027 get_integer_base_string(integer->declaration.base),
2028 get_byte_order_string(integer->declaration.byte_order));
2029 return 0;
2030}
2031
2032static
2033int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2034 struct metadata_context *context)
2035{
2036 size_t entry;
9ce21c30 2037 int ret;
273b65be
JG
2038 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2039 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2040 struct bt_ctf_field_type *container_type;
2041 int container_signed;
273b65be 2042
9ce21c30
JG
2043 ret = bt_ctf_field_type_validate(type);
2044 if (ret) {
2045 goto end;
2046 }
2047
b92ddaaa
JG
2048 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2049 if (!container_type) {
2050 ret = -1;
2051 goto end;
2052 }
2053
2054 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2055 if (container_signed < 0) {
2056 ret = container_signed;
2057 goto error_put_container_type;
2058 }
2059
273b65be
JG
2060 g_string_append(context->string, "enum : ");
2061 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2062 if (ret) {
b92ddaaa 2063 goto error_put_container_type;
273b65be
JG
2064 }
2065
2066 g_string_append(context->string, " { ");
2067 for (entry = 0; entry < enumeration->entries->len; entry++) {
2068 struct enumeration_mapping *mapping =
2069 enumeration->entries->pdata[entry];
2070
b92ddaaa
JG
2071 if (container_signed) {
2072 if (mapping->range_start._signed ==
2073 mapping->range_end._signed) {
2074 g_string_append_printf(context->string,
2075 "\"%s\" = %" PRId64,
2076 g_quark_to_string(mapping->string),
2077 mapping->range_start._signed);
2078 } else {
2079 g_string_append_printf(context->string,
2080 "\"%s\" = %" PRId64 " ... %" PRId64,
2081 g_quark_to_string(mapping->string),
2082 mapping->range_start._signed,
2083 mapping->range_end._signed);
2084 }
273b65be 2085 } else {
b92ddaaa
JG
2086 if (mapping->range_start._unsigned ==
2087 mapping->range_end._unsigned) {
2088 g_string_append_printf(context->string,
2089 "\"%s\" = %" PRIu64,
2090 g_quark_to_string(mapping->string),
2091 mapping->range_start._unsigned);
2092 } else {
2093 g_string_append_printf(context->string,
2094 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2095 g_quark_to_string(mapping->string),
2096 mapping->range_start._unsigned,
2097 mapping->range_end._unsigned);
2098 }
273b65be
JG
2099 }
2100
2101 g_string_append(context->string,
2102 ((entry != (enumeration->entries->len - 1)) ?
2103 ", " : " }"));
2104 }
2105
2106 if (context->field_name->len) {
2107 g_string_append_printf(context->string, " %s",
2108 context->field_name->str);
2109 g_string_assign(context->field_name, "");
2110 }
b92ddaaa
JG
2111error_put_container_type:
2112 bt_ctf_field_type_put(container_type);
273b65be
JG
2113end:
2114 return ret;
2115}
2116
2117static
2118int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2119 struct metadata_context *context)
2120{
2121 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2122 type, struct bt_ctf_field_type_floating_point, parent);
2123
2124 g_string_append_printf(context->string,
2125 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2126 floating_point->declaration.exp->len,
2127 floating_point->declaration.mantissa->len + 1,
2128 get_byte_order_string(floating_point->declaration.byte_order),
2129 type->declaration->alignment);
2130 return 0;
2131}
2132
2133static
2134int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2135 struct metadata_context *context)
2136{
2137 size_t i;
2138 unsigned int indent;
2139 int ret = 0;
2140 struct bt_ctf_field_type_structure *structure = container_of(type,
2141 struct bt_ctf_field_type_structure, parent);
2142 GString *structure_field_name = context->field_name;
2143
2144 context->field_name = g_string_new("");
2145
2146 context->current_indentation_level++;
2147 g_string_append(context->string, "struct {\n");
2148
2149 for (i = 0; i < structure->fields->len; i++) {
2150 struct structure_field *field;
2151
2152 for (indent = 0; indent < context->current_indentation_level;
2153 indent++) {
2154 g_string_append_c(context->string, '\t');
2155 }
2156
2157 field = structure->fields->pdata[i];
2158 g_string_assign(context->field_name,
2159 g_quark_to_string(field->name));
2160 ret = bt_ctf_field_type_serialize(field->type, context);
2161 if (ret) {
2162 goto end;
2163 }
2164
2165 if (context->field_name->len) {
2166 g_string_append_printf(context->string, " %s",
2167 context->field_name->str);
2168 }
2169 g_string_append(context->string, ";\n");
2170 }
2171
2172 context->current_indentation_level--;
2173 for (indent = 0; indent < context->current_indentation_level;
2174 indent++) {
2175 g_string_append_c(context->string, '\t');
2176 }
2177
2178 g_string_append_printf(context->string, "} align(%zu)",
2179 type->declaration->alignment);
2180end:
2181 g_string_free(context->field_name, TRUE);
2182 context->field_name = structure_field_name;
2183 return ret;
2184}
2185
2186static
2187int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2188 struct metadata_context *context)
2189{
2190 size_t i;
2191 unsigned int indent;
2192 int ret = 0;
2193 struct bt_ctf_field_type_variant *variant = container_of(
2194 type, struct bt_ctf_field_type_variant, parent);
2195 GString *variant_field_name = context->field_name;
2196
2197 context->field_name = g_string_new("");
2198 g_string_append_printf(context->string,
2199 "variant <%s> {\n", variant->tag_name->str);
2200 context->current_indentation_level++;
2201 for (i = 0; i < variant->fields->len; i++) {
2202 struct structure_field *field = variant->fields->pdata[i];
2203
2204 g_string_assign(context->field_name,
2205 g_quark_to_string(field->name));
2206 for (indent = 0; indent < context->current_indentation_level;
2207 indent++) {
2208 g_string_append_c(context->string, '\t');
2209 }
2210
2211 g_string_assign(context->field_name,
2212 g_quark_to_string(field->name));
2213 ret = bt_ctf_field_type_serialize(field->type, context);
2214 if (ret) {
2215 goto end;
2216 }
2217
2218 if (context->field_name->len) {
2219 g_string_append_printf(context->string, " %s;",
2220 context->field_name->str);
2221 }
2222
2223 g_string_append_c(context->string, '\n');
2224 }
2225
2226 context->current_indentation_level--;
2227 for (indent = 0; indent < context->current_indentation_level;
2228 indent++) {
2229 g_string_append_c(context->string, '\t');
2230 }
2231
2232 g_string_append(context->string, "}");
2233end:
2234 g_string_free(context->field_name, TRUE);
2235 context->field_name = variant_field_name;
2236 return ret;
2237}
2238
2239static
2240int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2241 struct metadata_context *context)
2242{
2243 int ret = 0;
2244 struct bt_ctf_field_type_array *array = container_of(type,
2245 struct bt_ctf_field_type_array, parent);
2246
2247 ret = bt_ctf_field_type_serialize(array->element_type, context);
2248 if (ret) {
2249 goto end;
2250 }
2251
2252 if (context->field_name->len) {
2253 g_string_append_printf(context->string, " %s[%u]",
2254 context->field_name->str, array->length);
2255 g_string_assign(context->field_name, "");
2256 } else {
2257 g_string_append_printf(context->string, "[%u]", array->length);
2258 }
2259end:
2260 return ret;
2261}
2262
2263static
2264int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2265 struct metadata_context *context)
2266{
2267 int ret = 0;
2268 struct bt_ctf_field_type_sequence *sequence = container_of(
2269 type, struct bt_ctf_field_type_sequence, parent);
2270
2271 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2272 if (ret) {
2273 goto end;
2274 }
2275
2276 if (context->field_name->len) {
2277 g_string_append_printf(context->string, " %s[%s]",
2278 context->field_name->str,
2279 sequence->length_field_name->str);
2280 g_string_assign(context->field_name, "");
2281 } else {
2282 g_string_append_printf(context->string, "[%s]",
2283 sequence->length_field_name->str);
2284 }
2285end:
2286 return ret;
2287}
2288
2289static
2290int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2291 struct metadata_context *context)
2292{
2293 struct bt_ctf_field_type_string *string = container_of(
2294 type, struct bt_ctf_field_type_string, parent);
2295
2296 g_string_append_printf(context->string,
2297 "string { encoding = %s; }",
2298 get_encoding_string(string->declaration.encoding));
2299 return 0;
2300}
2301
2302static
2303void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
2304 int byte_order)
2305{
2306 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2307 struct bt_ctf_field_type_integer, parent);
2308
2309 integer_type->declaration.byte_order = byte_order;
2310}
2311
2312static
2313void bt_ctf_field_type_floating_point_set_byte_order(
2314 struct bt_ctf_field_type *type, int byte_order)
2315{
2316 struct bt_ctf_field_type_floating_point *floating_point_type =
2317 container_of(type, struct bt_ctf_field_type_floating_point,
2318 parent);
2319
2320 floating_point_type->declaration.byte_order = byte_order;
2321 floating_point_type->sign.byte_order = byte_order;
2322 floating_point_type->mantissa.byte_order = byte_order;
2323 floating_point_type->exp.byte_order = byte_order;
2324}
This page took 0.162677 seconds and 4 git commands to generate.