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