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