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