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