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