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