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