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