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