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