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