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