12172e5df1002ee7228b6d50b0d00cd63c84f5cf
[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 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
193 struct bt_ctf_field_type *);
194 static
195 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
196 struct bt_ctf_field_type *);
197 static
198 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
199 struct bt_ctf_field_type *);
200 static
201 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
202 struct bt_ctf_field_type *);
203 static
204 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
205 struct bt_ctf_field_type *);
206 static
207 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
208 struct bt_ctf_field_type *);
209 static
210 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
211 struct bt_ctf_field_type *);
212 static
213 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
214 struct bt_ctf_field_type *);
215
216 static
217 struct bt_ctf_field_type *(* const type_copy_funcs[])(
218 struct bt_ctf_field_type *) = {
219 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_copy,
220 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_copy,
221 [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_copy,
222 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_copy,
223 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_copy,
224 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_copy,
225 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_copy,
226 [CTF_TYPE_STRING] = bt_ctf_field_type_string_copy,
227 };
228
229 static
230 void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
231 {
232 g_free(mapping);
233 }
234
235 static
236 void destroy_structure_field(struct structure_field *field)
237 {
238 if (field->type) {
239 bt_ctf_field_type_put(field->type);
240 }
241
242 g_free(field);
243 }
244
245 static
246 void check_ranges_overlap(gpointer element, gpointer query)
247 {
248 struct enumeration_mapping *mapping = element;
249 struct range_overlap_query *overlap_query = query;
250
251 if (mapping->range_start._signed <= overlap_query->range_end._signed
252 && overlap_query->range_start._signed <=
253 mapping->range_end._signed) {
254 overlap_query->overlaps = 1;
255 overlap_query->mapping_name = mapping->string;
256 }
257
258 overlap_query->overlaps |=
259 mapping->string == overlap_query->mapping_name;
260 }
261
262 static
263 void check_ranges_overlap_unsigned(gpointer element, gpointer query)
264 {
265 struct enumeration_mapping *mapping = element;
266 struct range_overlap_query *overlap_query = query;
267
268 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
269 && overlap_query->range_start._unsigned <=
270 mapping->range_end._unsigned) {
271 overlap_query->overlaps = 1;
272 overlap_query->mapping_name = mapping->string;
273 }
274
275 overlap_query->overlaps |=
276 mapping->string == overlap_query->mapping_name;
277 }
278
279 static
280 gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
281 struct enumeration_mapping **b)
282 {
283 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
284 }
285
286 static
287 gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
288 struct enumeration_mapping **b)
289 {
290 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
291 }
292
293 static
294 void bt_ctf_field_type_init(struct bt_ctf_field_type *type)
295 {
296 enum ctf_type_id type_id = type->declaration->id;
297 int ret;
298
299 assert(type && (type_id > CTF_TYPE_UNKNOWN) &&
300 (type_id < NR_CTF_TYPES));
301
302 bt_ctf_ref_init(&type->ref_count);
303 type->freeze = type_freeze_funcs[type_id];
304 type->serialize = type_serialize_funcs[type_id];
305 ret = bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_NATIVE);
306 assert(!ret);
307 type->declaration->alignment = 1;
308 }
309
310 static
311 int add_structure_field(GPtrArray *fields,
312 GHashTable *field_name_to_index,
313 struct bt_ctf_field_type *field_type,
314 const char *field_name)
315 {
316 int ret = 0;
317 GQuark name_quark = g_quark_from_string(field_name);
318 struct structure_field *field;
319
320 /* Make sure structure does not contain a field of the same name */
321 if (g_hash_table_lookup_extended(field_name_to_index,
322 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
323 ret = -1;
324 goto end;
325 }
326
327 field = g_new0(struct structure_field, 1);
328 if (!field) {
329 ret = -1;
330 goto end;
331 }
332
333 bt_ctf_field_type_get(field_type);
334 field->name = name_quark;
335 field->type = field_type;
336 g_hash_table_insert(field_name_to_index,
337 (gpointer) (unsigned long) name_quark,
338 (gpointer) (unsigned long) fields->len);
339 g_ptr_array_add(fields, field);
340 end:
341 return ret;
342 }
343
344 static
345 void bt_ctf_field_type_destroy(struct bt_ctf_ref *ref)
346 {
347 struct bt_ctf_field_type *type;
348 enum ctf_type_id type_id;
349
350 if (!ref) {
351 return;
352 }
353
354 type = container_of(ref, struct bt_ctf_field_type, ref_count);
355 type_id = type->declaration->id;
356 if (type_id <= CTF_TYPE_UNKNOWN ||
357 type_id >= NR_CTF_TYPES) {
358 return;
359 }
360
361 type_destroy_funcs[type_id](ref);
362 }
363
364 BT_HIDDEN
365 int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
366 {
367 int ret = 0;
368
369 if (!type) {
370 ret = -1;
371 goto end;
372 }
373
374 switch (type->declaration->id) {
375 case CTF_TYPE_ENUM:
376 {
377 struct bt_ctf_field_type_enumeration *enumeration =
378 container_of(type, struct bt_ctf_field_type_enumeration,
379 parent);
380
381 /* Ensure enum has entries */
382 ret = enumeration->entries->len ? 0 : -1;
383 break;
384 }
385 case CTF_TYPE_SEQUENCE:
386 {
387 struct bt_ctf_field_type_sequence *sequence =
388 container_of(type, struct bt_ctf_field_type_sequence,
389 parent);
390
391 /* length field name should be set at this point */
392 ret = sequence->length_field_name->len ? 0 : -1;
393 break;
394 }
395 case CTF_TYPE_VARIANT:
396 {
397 struct bt_ctf_field_type_variant *variant =
398 container_of(type, struct bt_ctf_field_type_variant,
399 parent);
400
401 if (variant->tag_name->len == 0 || !variant->tag) {
402 ret = -1;
403 }
404 break;
405 }
406 default:
407 break;
408 }
409 end:
410 return ret;
411 }
412
413 struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
414 {
415 struct bt_ctf_field_type_integer *integer =
416 g_new0(struct bt_ctf_field_type_integer, 1);
417
418 if (!integer || size == 0 || size > 64) {
419 return NULL;
420 }
421
422 integer->parent.declaration = &integer->declaration.p;
423 integer->parent.declaration->id = CTF_TYPE_INTEGER;
424 integer->declaration.len = size;
425 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
426 integer->declaration.encoding = CTF_STRING_NONE;
427 bt_ctf_field_type_init(&integer->parent);
428 return &integer->parent;
429 }
430
431 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
432 {
433 int ret = 0;
434 struct bt_ctf_field_type_integer *integer;
435
436 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
437 ret = -1;
438 goto end;
439 }
440
441 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
442 ret = (int) integer->declaration.len;
443 end:
444 return ret;
445 }
446
447 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
448 {
449 int ret = 0;
450 struct bt_ctf_field_type_integer *integer;
451
452 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
453 ret = -1;
454 goto end;
455 }
456
457 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
458 ret = integer->declaration.signedness;
459 end:
460 return ret;
461 }
462
463 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
464 int is_signed)
465 {
466 int ret = 0;
467 struct bt_ctf_field_type_integer *integer;
468
469 if (!type || type->frozen ||
470 type->declaration->id != CTF_TYPE_INTEGER) {
471 ret = -1;
472 goto end;
473 }
474
475 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
476 integer->declaration.signedness = !!is_signed;
477 end:
478 return ret;
479 }
480
481 enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
482 struct bt_ctf_field_type *type)
483 {
484 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
485 struct bt_ctf_field_type_integer *integer;
486
487 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
488 goto end;
489 }
490
491 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
492 ret = integer->declaration.base;
493 end:
494 return ret;
495 }
496
497 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
498 enum bt_ctf_integer_base base)
499 {
500 int ret = 0;
501
502 if (!type || type->frozen ||
503 type->declaration->id != CTF_TYPE_INTEGER) {
504 ret = -1;
505 goto end;
506 }
507
508 switch (base) {
509 case BT_CTF_INTEGER_BASE_BINARY:
510 case BT_CTF_INTEGER_BASE_OCTAL:
511 case BT_CTF_INTEGER_BASE_DECIMAL:
512 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
513 {
514 struct bt_ctf_field_type_integer *integer = container_of(type,
515 struct bt_ctf_field_type_integer, parent);
516 integer->declaration.base = base;
517 break;
518 }
519 default:
520 ret = -1;
521 }
522 end:
523 return ret;
524 }
525
526 enum ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
527 struct bt_ctf_field_type *type)
528 {
529 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
530 struct bt_ctf_field_type_integer *integer;
531
532 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
533 goto end;
534 }
535
536 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
537 ret = integer->declaration.encoding;
538 end:
539 return ret;
540 }
541
542 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
543 enum ctf_string_encoding encoding)
544 {
545 int ret = 0;
546 struct bt_ctf_field_type_integer *integer;
547
548 if (!type || type->frozen ||
549 (type->declaration->id != CTF_TYPE_INTEGER) ||
550 (encoding < CTF_STRING_NONE) ||
551 (encoding >= CTF_STRING_UNKNOWN)) {
552 ret = -1;
553 goto end;
554 }
555
556 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
557 integer->declaration.encoding = encoding;
558 end:
559 return ret;
560 }
561
562 struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
563 struct bt_ctf_field_type *type)
564 {
565 struct bt_ctf_field_type_integer *integer;
566 struct bt_ctf_clock *clock = NULL;
567
568 if (!type) {
569 goto end;
570 }
571
572 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
573 clock = integer->mapped_clock;
574 if (clock) {
575 bt_ctf_clock_get(clock);
576 }
577 end:
578 return clock;
579 }
580
581 int bt_ctf_field_type_integer_set_mapped_clock(
582 struct bt_ctf_field_type *type,
583 struct bt_ctf_clock *clock)
584 {
585 struct bt_ctf_field_type_integer *integer;
586 int ret = 0;
587
588 if (!type || type->frozen) {
589 ret = -1;
590 goto end;
591 }
592
593 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
594 if (integer->mapped_clock) {
595 bt_ctf_clock_put(integer->mapped_clock);
596 }
597
598 if (clock) {
599 bt_ctf_clock_get(clock);
600 }
601
602 integer->mapped_clock = clock;
603 end:
604 return ret;
605 }
606
607 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
608 struct bt_ctf_field_type *integer_container_type)
609 {
610 struct bt_ctf_field_type_enumeration *enumeration = NULL;
611
612 if (!integer_container_type) {
613 goto error;
614 }
615
616 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
617 goto error;
618 }
619
620 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
621 if (!enumeration) {
622 goto error;
623 }
624
625 enumeration->parent.declaration = &enumeration->declaration.p;
626 enumeration->parent.declaration->id = CTF_TYPE_ENUM;
627 bt_ctf_field_type_get(integer_container_type);
628 enumeration->container = integer_container_type;
629 enumeration->entries = g_ptr_array_new_with_free_func(
630 (GDestroyNotify)destroy_enumeration_mapping);
631 bt_ctf_field_type_init(&enumeration->parent);
632 return &enumeration->parent;
633 error:
634 g_free(enumeration);
635 return NULL;
636 }
637
638 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
639 struct bt_ctf_field_type *type)
640 {
641 struct bt_ctf_field_type *container_type = NULL;
642 struct bt_ctf_field_type_enumeration *enumeration_type;
643
644 if (!type) {
645 goto end;
646 }
647
648 if (type->declaration->id != CTF_TYPE_ENUM) {
649 goto end;
650 }
651
652 enumeration_type = container_of(type,
653 struct bt_ctf_field_type_enumeration, parent);
654 container_type = enumeration_type->container;
655 bt_ctf_field_type_get(container_type);
656 end:
657 return container_type;
658 }
659
660 int bt_ctf_field_type_enumeration_add_mapping(
661 struct bt_ctf_field_type *type, const char *string,
662 int64_t range_start, int64_t range_end)
663 {
664 int ret = 0;
665 GQuark mapping_name;
666 struct enumeration_mapping *mapping;
667 struct bt_ctf_field_type_enumeration *enumeration;
668 struct range_overlap_query query;
669 char *escaped_string;
670
671 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
672 type->frozen ||
673 (range_end < range_start)) {
674 ret = -1;
675 goto end;
676 }
677
678 if (!string || strlen(string) == 0) {
679 ret = -1;
680 goto end;
681 }
682
683 escaped_string = g_strescape(string, NULL);
684 if (!escaped_string) {
685 ret = -1;
686 goto end;
687 }
688
689 mapping_name = g_quark_from_string(escaped_string);
690 query = (struct range_overlap_query) {
691 .range_start._signed = range_start,
692 .range_end._signed = range_end,
693 .mapping_name = mapping_name,
694 .overlaps = 0 };
695 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
696 parent);
697
698 /* Check that the range does not overlap with one already present */
699 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
700 if (query.overlaps) {
701 ret = -1;
702 goto error_free;
703 }
704
705 mapping = g_new(struct enumeration_mapping, 1);
706 if (!mapping) {
707 ret = -1;
708 goto error_free;
709 }
710
711 *mapping = (struct enumeration_mapping) {
712 .range_start._signed = range_start,
713 .range_end._signed = range_end, .string = mapping_name};
714 g_ptr_array_add(enumeration->entries, mapping);
715 g_ptr_array_sort(enumeration->entries,
716 (GCompareFunc)compare_enumeration_mappings_signed);
717 error_free:
718 free(escaped_string);
719 end:
720 return ret;
721 }
722
723 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
724 struct bt_ctf_field_type *type, const char *string,
725 uint64_t range_start, uint64_t range_end)
726 {
727 int ret = 0;
728 GQuark mapping_name;
729 struct enumeration_mapping *mapping;
730 struct bt_ctf_field_type_enumeration *enumeration;
731 struct range_overlap_query query;
732 char *escaped_string;
733
734 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
735 type->frozen ||
736 (range_end < range_start)) {
737 ret = -1;
738 goto end;
739 }
740
741 if (!string || strlen(string) == 0) {
742 ret = -1;
743 goto end;
744 }
745
746 escaped_string = g_strescape(string, NULL);
747 if (!escaped_string) {
748 ret = -1;
749 goto end;
750 }
751
752 mapping_name = g_quark_from_string(escaped_string);
753 query = (struct range_overlap_query) {
754 .range_start._unsigned = range_start,
755 .range_end._unsigned = range_end,
756 .mapping_name = mapping_name,
757 .overlaps = 0 };
758 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
759 parent);
760
761 /* Check that the range does not overlap with one already present */
762 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned,
763 &query);
764 if (query.overlaps) {
765 ret = -1;
766 goto error_free;
767 }
768
769 mapping = g_new(struct enumeration_mapping, 1);
770 if (!mapping) {
771 ret = -1;
772 goto error_free;
773 }
774
775 *mapping = (struct enumeration_mapping) {
776 .range_start._unsigned = range_start,
777 .range_end._unsigned = range_end, .string = mapping_name};
778 g_ptr_array_add(enumeration->entries, mapping);
779 g_ptr_array_sort(enumeration->entries,
780 (GCompareFunc)compare_enumeration_mappings_unsigned);
781 error_free:
782 free(escaped_string);
783 end:
784 return ret;
785 }
786
787 const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
788 struct bt_ctf_field_type_enumeration *enumeration_type,
789 uint64_t value)
790 {
791 const char *name = NULL;
792 struct range_overlap_query query =
793 (struct range_overlap_query) {
794 .range_start._unsigned = value,
795 .range_end._unsigned = value,
796 .overlaps = 0 };
797
798 g_ptr_array_foreach(enumeration_type->entries,
799 check_ranges_overlap_unsigned,
800 &query);
801 if (!query.overlaps) {
802 goto end;
803 }
804
805 name = g_quark_to_string(query.mapping_name);
806 end:
807 return name;
808 }
809
810 const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
811 struct bt_ctf_field_type_enumeration *enumeration_type,
812 int64_t value)
813 {
814 const char *name = NULL;
815 struct range_overlap_query query =
816 (struct range_overlap_query) {
817 .range_start._signed = value,
818 .range_end._signed = value,
819 .overlaps = 0 };
820
821 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
822 &query);
823 if (!query.overlaps) {
824 goto end;
825 }
826
827 name = g_quark_to_string(query.mapping_name);
828 end:
829 return name;
830 }
831
832 int bt_ctf_field_type_enumeration_get_mapping_count(
833 struct bt_ctf_field_type *type)
834 {
835 int ret = 0;
836 struct bt_ctf_field_type_enumeration *enumeration;
837
838 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
839 ret = -1;
840 goto end;
841 }
842
843 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
844 parent);
845 ret = (int) enumeration->entries->len;
846 end:
847 return ret;
848 }
849
850 static inline
851 struct enumeration_mapping *get_enumeration_mapping(
852 struct bt_ctf_field_type *type, int index)
853 {
854 struct enumeration_mapping *mapping = NULL;
855 struct bt_ctf_field_type_enumeration *enumeration;
856
857 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
858 parent);
859 if (index >= enumeration->entries->len) {
860 goto end;
861 }
862
863 mapping = g_ptr_array_index(enumeration->entries, index);
864 end:
865 return mapping;
866 }
867
868 int bt_ctf_field_type_enumeration_get_mapping(
869 struct bt_ctf_field_type *type, int index,
870 const char **string, int64_t *range_start, int64_t *range_end)
871 {
872 struct enumeration_mapping *mapping;
873 int ret = 0;
874
875 if (!type || index < 0 || !string || !range_start || !range_end ||
876 (type->declaration->id != CTF_TYPE_ENUM)) {
877 ret = -1;
878 goto end;
879 }
880
881 mapping = get_enumeration_mapping(type, index);
882 if (!mapping) {
883 ret = -1;
884 goto end;
885 }
886
887 *string = g_quark_to_string(mapping->string);
888 *range_start = mapping->range_start._signed;
889 *range_end = mapping->range_end._signed;
890 end:
891 return ret;
892 }
893
894 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
895 struct bt_ctf_field_type *type, int index,
896 const char **string, uint64_t *range_start, uint64_t *range_end)
897 {
898 struct enumeration_mapping *mapping;
899 int ret = 0;
900
901 if (!type || index < 0 || !string || !range_start || !range_end ||
902 (type->declaration->id != CTF_TYPE_ENUM)) {
903 ret = -1;
904 goto end;
905 }
906
907 mapping = get_enumeration_mapping(type, index);
908 if (!mapping) {
909 ret = -1;
910 goto end;
911 }
912
913 *string = g_quark_to_string(mapping->string);
914 *range_start = mapping->range_start._unsigned;
915 *range_end = mapping->range_end._unsigned;
916 end:
917 return ret;
918 }
919
920 int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
921 struct bt_ctf_field_type *type, const char *name)
922 {
923 GQuark name_quark;
924 struct bt_ctf_field_type_enumeration *enumeration;
925 int i, ret = 0;
926
927 if (!type || !name ||
928 (type->declaration->id != CTF_TYPE_ENUM)) {
929 ret = -1;
930 goto end;
931 }
932
933 name_quark = g_quark_try_string(name);
934 if (!name_quark) {
935 ret = -1;
936 goto end;
937 }
938
939 enumeration = container_of(type,
940 struct bt_ctf_field_type_enumeration, parent);
941 for (i = 0; i < enumeration->entries->len; i++) {
942 struct enumeration_mapping *mapping =
943 get_enumeration_mapping(type, i);
944
945 if (mapping->string == name_quark) {
946 ret = i;
947 goto end;
948 }
949 }
950
951 ret = -1;
952 end:
953 return ret;
954 }
955
956 int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
957 struct bt_ctf_field_type *type, int64_t value)
958 {
959 struct bt_ctf_field_type_enumeration *enumeration;
960 int i, ret = 0;
961
962 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
963 ret = -1;
964 goto end;
965 }
966
967 enumeration = container_of(type,
968 struct bt_ctf_field_type_enumeration, parent);
969 for (i = 0; i < enumeration->entries->len; i++) {
970 struct enumeration_mapping *mapping =
971 get_enumeration_mapping(type, i);
972
973 if (value >= mapping->range_start._signed &&
974 value <= mapping->range_end._signed) {
975 ret = i;
976 goto end;
977 }
978 }
979
980 ret = -1;
981 end:
982 return ret;
983 }
984
985 int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
986 struct bt_ctf_field_type *type, uint64_t value)
987 {
988 struct bt_ctf_field_type_enumeration *enumeration;
989 int i, ret = 0;
990
991 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
992 ret = -1;
993 goto end;
994 }
995
996 enumeration = container_of(type,
997 struct bt_ctf_field_type_enumeration, parent);
998 for (i = 0; i < enumeration->entries->len; i++) {
999 struct enumeration_mapping *mapping =
1000 get_enumeration_mapping(type, i);
1001
1002 if (value >= mapping->range_start._unsigned &&
1003 value <= mapping->range_end._unsigned) {
1004 ret = i;
1005 goto end;
1006 }
1007 }
1008
1009 ret = -1;
1010 end:
1011 return ret;
1012 }
1013
1014 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
1015 {
1016 struct bt_ctf_field_type_floating_point *floating_point =
1017 g_new0(struct bt_ctf_field_type_floating_point, 1);
1018
1019 if (!floating_point) {
1020 goto end;
1021 }
1022
1023 floating_point->declaration.sign = &floating_point->sign;
1024 floating_point->declaration.mantissa = &floating_point->mantissa;
1025 floating_point->declaration.exp = &floating_point->exp;
1026 floating_point->sign.len = 1;
1027 floating_point->parent.declaration = &floating_point->declaration.p;
1028 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
1029 floating_point->declaration.exp->len =
1030 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
1031 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
1032 floating_point->sign.p.alignment = 1;
1033 floating_point->mantissa.p.alignment = 1;
1034 floating_point->exp.p.alignment = 1;
1035
1036 bt_ctf_field_type_init(&floating_point->parent);
1037 end:
1038 return floating_point ? &floating_point->parent : NULL;
1039 }
1040
1041 int bt_ctf_field_type_floating_point_get_exponent_digits(
1042 struct bt_ctf_field_type *type)
1043 {
1044 int ret = 0;
1045 struct bt_ctf_field_type_floating_point *floating_point;
1046
1047 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1048 ret = -1;
1049 goto end;
1050 }
1051
1052 floating_point = container_of(type,
1053 struct bt_ctf_field_type_floating_point, parent);
1054 ret = (int) floating_point->declaration.exp->len;
1055 end:
1056 return ret;
1057 }
1058
1059 int bt_ctf_field_type_floating_point_set_exponent_digits(
1060 struct bt_ctf_field_type *type,
1061 unsigned int exponent_digits)
1062 {
1063 int ret = 0;
1064 struct bt_ctf_field_type_floating_point *floating_point;
1065
1066 if (!type || type->frozen ||
1067 (type->declaration->id != CTF_TYPE_FLOAT)) {
1068 ret = -1;
1069 goto end;
1070 }
1071
1072 floating_point = container_of(type,
1073 struct bt_ctf_field_type_floating_point, parent);
1074 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1075 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1076 (exponent_digits !=
1077 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1078 ret = -1;
1079 goto end;
1080 }
1081
1082 floating_point->declaration.exp->len = exponent_digits;
1083 end:
1084 return ret;
1085 }
1086
1087 int bt_ctf_field_type_floating_point_get_mantissa_digits(
1088 struct bt_ctf_field_type *type)
1089 {
1090 int ret = 0;
1091 struct bt_ctf_field_type_floating_point *floating_point;
1092
1093 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1094 ret = -1;
1095 goto end;
1096 }
1097
1098 floating_point = container_of(type,
1099 struct bt_ctf_field_type_floating_point, parent);
1100 ret = (int) floating_point->mantissa.len + 1;
1101 end:
1102 return ret;
1103 }
1104
1105 int bt_ctf_field_type_floating_point_set_mantissa_digits(
1106 struct bt_ctf_field_type *type,
1107 unsigned int mantissa_digits)
1108 {
1109 int ret = 0;
1110 struct bt_ctf_field_type_floating_point *floating_point;
1111
1112 if (!type || type->frozen ||
1113 (type->declaration->id != CTF_TYPE_FLOAT)) {
1114 ret = -1;
1115 goto end;
1116 }
1117
1118 floating_point = container_of(type,
1119 struct bt_ctf_field_type_floating_point, parent);
1120
1121 if ((mantissa_digits != FLT_MANT_DIG) &&
1122 (mantissa_digits != DBL_MANT_DIG) &&
1123 (mantissa_digits != LDBL_MANT_DIG)) {
1124 ret = -1;
1125 goto end;
1126 }
1127
1128 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1129 end:
1130 return ret;
1131 }
1132
1133 struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1134 {
1135 struct bt_ctf_field_type_structure *structure =
1136 g_new0(struct bt_ctf_field_type_structure, 1);
1137
1138 if (!structure) {
1139 goto error;
1140 }
1141
1142 structure->parent.declaration = &structure->declaration.p;
1143 structure->parent.declaration->id = CTF_TYPE_STRUCT;
1144 structure->fields = g_ptr_array_new_with_free_func(
1145 (GDestroyNotify)destroy_structure_field);
1146 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
1147 bt_ctf_field_type_init(&structure->parent);
1148 return &structure->parent;
1149 error:
1150 return NULL;
1151 }
1152
1153 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1154 struct bt_ctf_field_type *field_type,
1155 const char *field_name)
1156 {
1157 int ret = 0;
1158 struct bt_ctf_field_type_structure *structure;
1159
1160 if (!type || !field_type || type->frozen ||
1161 bt_ctf_validate_identifier(field_name) ||
1162 (type->declaration->id != CTF_TYPE_STRUCT) ||
1163 bt_ctf_field_type_validate(field_type)) {
1164 ret = -1;
1165 goto end;
1166 }
1167
1168 structure = container_of(type,
1169 struct bt_ctf_field_type_structure, parent);
1170 if (add_structure_field(structure->fields,
1171 structure->field_name_to_index, field_type, field_name)) {
1172 ret = -1;
1173 goto end;
1174 }
1175 end:
1176 return ret;
1177 }
1178
1179 int bt_ctf_field_type_structure_get_field_count(
1180 struct bt_ctf_field_type *type)
1181 {
1182 int ret = 0;
1183 struct bt_ctf_field_type_structure *structure;
1184
1185 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1186 ret = -1;
1187 goto end;
1188 }
1189
1190 structure = container_of(type, struct bt_ctf_field_type_structure,
1191 parent);
1192 ret = (int) structure->fields->len;
1193 end:
1194 return ret;
1195 }
1196
1197 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1198 const char **field_name, struct bt_ctf_field_type **field_type,
1199 int index)
1200 {
1201 struct bt_ctf_field_type_structure *structure;
1202 struct structure_field *field;
1203 int ret = 0;
1204
1205 if (!type || index < 0 || (type->declaration->id != CTF_TYPE_STRUCT)) {
1206 ret = -1;
1207 goto end;
1208 }
1209
1210 structure = container_of(type, struct bt_ctf_field_type_structure,
1211 parent);
1212 if (index >= structure->fields->len) {
1213 ret = -1;
1214 goto end;
1215 }
1216
1217 field = g_ptr_array_index(structure->fields, index);
1218 if (field_type) {
1219 *field_type = field->type;
1220 bt_ctf_field_type_get(field->type);
1221 }
1222 if (field_name) {
1223 *field_name = g_quark_to_string(field->name);
1224 }
1225 end:
1226 return ret;
1227 }
1228
1229 struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1230 struct bt_ctf_field_type *type,
1231 const char *name)
1232 {
1233 size_t index;
1234 GQuark name_quark;
1235 struct structure_field *field;
1236 struct bt_ctf_field_type_structure *structure;
1237 struct bt_ctf_field_type *field_type = NULL;
1238
1239 if (!type || !name) {
1240 goto end;
1241 }
1242
1243 name_quark = g_quark_try_string(name);
1244 if (!name_quark) {
1245 goto end;
1246 }
1247
1248 structure = container_of(type, struct bt_ctf_field_type_structure,
1249 parent);
1250 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1251 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1252 goto end;
1253 }
1254
1255 field = structure->fields->pdata[index];
1256 field_type = field->type;
1257 bt_ctf_field_type_get(field_type);
1258 end:
1259 return field_type;
1260 }
1261
1262 struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1263 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1264 {
1265 struct bt_ctf_field_type_variant *variant = NULL;
1266
1267 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
1268 goto error;
1269 }
1270
1271 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1272 if (!variant) {
1273 goto error;
1274 }
1275
1276 variant->parent.declaration = &variant->declaration.p;
1277 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1278 variant->tag_name = g_string_new(tag_name);
1279 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1280 variant->fields = g_ptr_array_new_with_free_func(
1281 (GDestroyNotify)destroy_structure_field);
1282 if (enum_tag) {
1283 bt_ctf_field_type_get(enum_tag);
1284 variant->tag = container_of(enum_tag,
1285 struct bt_ctf_field_type_enumeration, parent);
1286 }
1287
1288 bt_ctf_field_type_init(&variant->parent);
1289 return &variant->parent;
1290 error:
1291 return NULL;
1292 }
1293
1294 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1295 struct bt_ctf_field_type *type)
1296 {
1297 struct bt_ctf_field_type_variant *variant;
1298 struct bt_ctf_field_type *tag_type = NULL;
1299
1300 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1301 goto end;
1302 }
1303
1304 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1305 if (!variant->tag) {
1306 goto end;
1307 }
1308
1309 tag_type = &variant->tag->parent;
1310 bt_ctf_field_type_get(tag_type);
1311 end:
1312 return tag_type;
1313 }
1314
1315 const char *bt_ctf_field_type_variant_get_tag_name(
1316 struct bt_ctf_field_type *type)
1317 {
1318 struct bt_ctf_field_type_variant *variant;
1319 const char *tag_name = NULL;
1320
1321 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1322 goto end;
1323 }
1324
1325 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1326 if (variant->tag_name->len == 0) {
1327 goto end;
1328 }
1329
1330 tag_name = variant->tag_name->str;
1331 end:
1332 return tag_name;
1333 }
1334
1335 int bt_ctf_field_type_variant_set_tag_name(
1336 struct bt_ctf_field_type *type, const char *name)
1337 {
1338 int ret = 0;
1339 struct bt_ctf_field_type_variant *variant;
1340
1341 if (!type || type->frozen ||
1342 (type->declaration->id != CTF_TYPE_VARIANT) ||
1343 bt_ctf_validate_identifier(name)) {
1344 ret = -1;
1345 goto end;
1346 }
1347
1348 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1349 g_string_assign(variant->tag_name, name);
1350 end:
1351 return ret;
1352 }
1353
1354 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1355 struct bt_ctf_field_type *field_type,
1356 const char *field_name)
1357 {
1358 size_t i;
1359 int ret = 0;
1360 struct bt_ctf_field_type_variant *variant;
1361 GQuark field_name_quark = g_quark_from_string(field_name);
1362
1363 if (!type || !field_type || type->frozen ||
1364 bt_ctf_validate_identifier(field_name) ||
1365 (type->declaration->id != CTF_TYPE_VARIANT) ||
1366 bt_ctf_field_type_validate(field_type)) {
1367 ret = -1;
1368 goto end;
1369 }
1370
1371 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1372
1373 /* The user has explicitly provided a tag; validate against it. */
1374 if (variant->tag) {
1375 int name_found = 0;
1376
1377 /* Make sure this name is present in the enum tag */
1378 for (i = 0; i < variant->tag->entries->len; i++) {
1379 struct enumeration_mapping *mapping =
1380 g_ptr_array_index(variant->tag->entries, i);
1381
1382 if (mapping->string == field_name_quark) {
1383 name_found = 1;
1384 break;
1385 }
1386 }
1387
1388 if (!name_found) {
1389 /* Validation failed */
1390 ret = -1;
1391 goto end;
1392 }
1393 }
1394
1395 if (add_structure_field(variant->fields, variant->field_name_to_index,
1396 field_type, field_name)) {
1397 ret = -1;
1398 goto end;
1399 }
1400 end:
1401 return ret;
1402 }
1403
1404 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1405 struct bt_ctf_field_type *type,
1406 const char *field_name)
1407 {
1408 size_t index;
1409 GQuark name_quark;
1410 struct structure_field *field;
1411 struct bt_ctf_field_type_variant *variant;
1412 struct bt_ctf_field_type *field_type = NULL;
1413
1414 if (!type || !field_name) {
1415 goto end;
1416 }
1417
1418 name_quark = g_quark_try_string(field_name);
1419 if (!name_quark) {
1420 goto end;
1421 }
1422
1423 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1424 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1425 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1426 goto end;
1427 }
1428
1429 field = g_ptr_array_index(variant->fields, index);
1430 field_type = field->type;
1431 bt_ctf_field_type_get(field_type);
1432 end:
1433 return field_type;
1434 }
1435
1436 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1437 struct bt_ctf_field_type *type,
1438 struct bt_ctf_field *tag)
1439 {
1440 const char *enum_value;
1441 struct bt_ctf_field_type *field_type = NULL;
1442
1443 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1444 goto end;
1445 }
1446
1447 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1448 if (!enum_value) {
1449 goto end;
1450 }
1451
1452 /* Already increments field_type's reference count */
1453 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1454 type, enum_value);
1455 end:
1456 return field_type;
1457 }
1458
1459 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1460 {
1461 int ret = 0;
1462 struct bt_ctf_field_type_variant *variant;
1463
1464 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1465 ret = -1;
1466 goto end;
1467 }
1468
1469 variant = container_of(type, struct bt_ctf_field_type_variant,
1470 parent);
1471 ret = (int) variant->fields->len;
1472 end:
1473 return ret;
1474
1475 }
1476
1477 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1478 const char **field_name, struct bt_ctf_field_type **field_type,
1479 int index)
1480 {
1481 struct bt_ctf_field_type_variant *variant;
1482 struct structure_field *field;
1483 int ret = 0;
1484
1485 if (!type || index < 0 || (type->declaration->id != CTF_TYPE_VARIANT)) {
1486 ret = -1;
1487 goto end;
1488 }
1489
1490 variant = container_of(type, struct bt_ctf_field_type_variant,
1491 parent);
1492 if (index >= variant->fields->len) {
1493 ret = -1;
1494 goto end;
1495 }
1496
1497 field = g_ptr_array_index(variant->fields, index);
1498 if (field_type) {
1499 *field_type = field->type;
1500 bt_ctf_field_type_get(field->type);
1501 }
1502 if (field_name) {
1503 *field_name = g_quark_to_string(field->name);
1504 }
1505 end:
1506 return ret;
1507 }
1508
1509 struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1510 struct bt_ctf_field_type *element_type,
1511 unsigned int length)
1512 {
1513 struct bt_ctf_field_type_array *array = NULL;
1514
1515 if (!element_type || length == 0 ||
1516 bt_ctf_field_type_validate(element_type)) {
1517 goto error;
1518 }
1519
1520 array = g_new0(struct bt_ctf_field_type_array, 1);
1521 if (!array) {
1522 goto error;
1523 }
1524
1525 array->parent.declaration = &array->declaration.p;
1526 array->parent.declaration->id = CTF_TYPE_ARRAY;
1527
1528 bt_ctf_field_type_get(element_type);
1529 array->element_type = element_type;
1530 array->length = length;
1531 bt_ctf_field_type_init(&array->parent);
1532 return &array->parent;
1533 error:
1534 return NULL;
1535 }
1536
1537 struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1538 struct bt_ctf_field_type *type)
1539 {
1540 struct bt_ctf_field_type *ret = NULL;
1541 struct bt_ctf_field_type_array *array;
1542
1543 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1544 goto end;
1545 }
1546
1547 array = container_of(type, struct bt_ctf_field_type_array, parent);
1548 ret = array->element_type;
1549 bt_ctf_field_type_get(ret);
1550 end:
1551 return ret;
1552 }
1553
1554 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1555 {
1556 int64_t ret;
1557 struct bt_ctf_field_type_array *array;
1558
1559 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1560 ret = -1;
1561 goto end;
1562 }
1563
1564 array = container_of(type, struct bt_ctf_field_type_array, parent);
1565 ret = (int64_t) array->length;
1566 end:
1567 return ret;
1568 }
1569
1570 struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1571 struct bt_ctf_field_type *element_type,
1572 const char *length_field_name)
1573 {
1574 struct bt_ctf_field_type_sequence *sequence = NULL;
1575
1576 if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
1577 bt_ctf_field_type_validate(element_type)) {
1578 goto error;
1579 }
1580
1581 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1582 if (!sequence) {
1583 goto error;
1584 }
1585
1586 sequence->parent.declaration = &sequence->declaration.p;
1587 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
1588 bt_ctf_field_type_get(element_type);
1589 sequence->element_type = element_type;
1590 sequence->length_field_name = g_string_new(length_field_name);
1591 bt_ctf_field_type_init(&sequence->parent);
1592 return &sequence->parent;
1593 error:
1594 return NULL;
1595 }
1596
1597 struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1598 struct bt_ctf_field_type *type)
1599 {
1600 struct bt_ctf_field_type *ret = NULL;
1601 struct bt_ctf_field_type_sequence *sequence;
1602
1603 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1604 goto end;
1605 }
1606
1607 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1608 parent);
1609 ret = sequence->element_type;
1610 bt_ctf_field_type_get(ret);
1611 end:
1612 return ret;
1613 }
1614
1615 const char *bt_ctf_field_type_sequence_get_length_field_name(
1616 struct bt_ctf_field_type *type)
1617 {
1618 const char *ret = NULL;
1619 struct bt_ctf_field_type_sequence *sequence;
1620
1621 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1622 goto end;
1623 }
1624
1625 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1626 parent);
1627 ret = sequence->length_field_name->str;
1628 end:
1629 return ret;
1630 }
1631
1632 struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1633 {
1634 struct bt_ctf_field_type_string *string =
1635 g_new0(struct bt_ctf_field_type_string, 1);
1636
1637 if (!string) {
1638 return NULL;
1639 }
1640
1641 string->parent.declaration = &string->declaration.p;
1642 string->parent.declaration->id = CTF_TYPE_STRING;
1643 bt_ctf_field_type_init(&string->parent);
1644 string->declaration.encoding = CTF_STRING_UTF8;
1645 string->parent.declaration->alignment = CHAR_BIT;
1646 return &string->parent;
1647 }
1648
1649 enum ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1650 struct bt_ctf_field_type *type)
1651 {
1652 struct bt_ctf_field_type_string *string;
1653 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
1654
1655 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1656 goto end;
1657 }
1658
1659 string = container_of(type, struct bt_ctf_field_type_string,
1660 parent);
1661 ret = string->declaration.encoding;
1662 end:
1663 return ret;
1664 }
1665
1666 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
1667 enum ctf_string_encoding encoding)
1668 {
1669 int ret = 0;
1670 struct bt_ctf_field_type_string *string;
1671
1672 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1673 (encoding != CTF_STRING_UTF8 &&
1674 encoding != CTF_STRING_ASCII)) {
1675 ret = -1;
1676 goto end;
1677 }
1678
1679 string = container_of(type, struct bt_ctf_field_type_string, parent);
1680 string->declaration.encoding = encoding;
1681 end:
1682 return ret;
1683 }
1684
1685 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1686 {
1687 int ret;
1688 enum ctf_type_id type_id;
1689
1690 if (!type) {
1691 ret = -1;
1692 goto end;
1693 }
1694
1695 if (type->frozen) {
1696 ret = (int) type->declaration->alignment;
1697 goto end;
1698 }
1699
1700 type_id = bt_ctf_field_type_get_type_id(type);
1701 switch (type_id) {
1702 case CTF_TYPE_SEQUENCE:
1703 {
1704 struct bt_ctf_field_type *element =
1705 bt_ctf_field_type_sequence_get_element_type(type);
1706
1707 if (!element) {
1708 ret = -1;
1709 goto end;
1710 }
1711
1712 ret = bt_ctf_field_type_get_alignment(element);
1713 bt_ctf_field_type_put(element);
1714 break;
1715 }
1716 case CTF_TYPE_ARRAY:
1717 {
1718 struct bt_ctf_field_type *element =
1719 bt_ctf_field_type_array_get_element_type(type);
1720
1721 if (!element) {
1722 ret = -1;
1723 goto end;
1724 }
1725
1726 ret = bt_ctf_field_type_get_alignment(element);
1727 bt_ctf_field_type_put(element);
1728 break;
1729 }
1730 case CTF_TYPE_STRUCT:
1731 {
1732 int i, element_count;
1733
1734 element_count = bt_ctf_field_type_structure_get_field_count(
1735 type);
1736 if (element_count < 0) {
1737 ret = element_count;
1738 goto end;
1739 }
1740
1741 for (i = 0; i < element_count; i++) {
1742 struct bt_ctf_field_type *field;
1743 int field_alignment;
1744
1745 ret = bt_ctf_field_type_structure_get_field(type, NULL,
1746 &field, i);
1747 if (ret) {
1748 goto end;
1749 }
1750
1751 assert(field);
1752 field_alignment = bt_ctf_field_type_get_alignment(
1753 field);
1754 bt_ctf_field_type_put(field);
1755 if (field_alignment < 0) {
1756 ret = field_alignment;
1757 goto end;
1758 }
1759
1760 type->declaration->alignment = MAX(field_alignment,
1761 type->declaration->alignment);
1762 }
1763 ret = (int) type->declaration->alignment;
1764 break;
1765 }
1766 case CTF_TYPE_UNKNOWN:
1767 ret = -1;
1768 break;
1769 default:
1770 ret = (int) type->declaration->alignment;
1771 break;
1772 }
1773 end:
1774 return ret;
1775 }
1776
1777 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
1778 unsigned int alignment)
1779 {
1780 int ret = 0;
1781
1782 /* Alignment must be bit-aligned (1) or byte aligned */
1783 if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
1784 ret = -1;
1785 goto end;
1786 }
1787
1788 if (type->declaration->id == CTF_TYPE_STRING &&
1789 alignment != CHAR_BIT) {
1790 ret = -1;
1791 goto end;
1792 }
1793
1794 type->declaration->alignment = alignment;
1795 ret = 0;
1796 end:
1797 return ret;
1798 }
1799
1800 enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1801 struct bt_ctf_field_type *type)
1802 {
1803 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
1804 int internal_byte_order = -1;
1805
1806 if (!type) {
1807 goto end;
1808 }
1809
1810 switch (type->declaration->id) {
1811 case CTF_TYPE_INTEGER:
1812 {
1813 struct bt_ctf_field_type_integer *integer = container_of(
1814 type, struct bt_ctf_field_type_integer, parent);
1815 internal_byte_order = integer->declaration.byte_order;
1816 break;
1817 }
1818 case CTF_TYPE_FLOAT:
1819 {
1820 struct bt_ctf_field_type_floating_point *floating_point =
1821 container_of(type,
1822 struct bt_ctf_field_type_floating_point,
1823 parent);
1824 internal_byte_order = floating_point->declaration.byte_order;
1825 break;
1826 }
1827 default:
1828 goto end;
1829 }
1830
1831 switch (internal_byte_order) {
1832 case LITTLE_ENDIAN:
1833 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
1834 break;
1835 case BIG_ENDIAN:
1836 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1837 break;
1838 case 0:
1839 ret = BT_CTF_BYTE_ORDER_NATIVE;
1840 break;
1841 default:
1842 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
1843 }
1844 end:
1845 return ret;
1846 }
1847
1848 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
1849 enum bt_ctf_byte_order byte_order)
1850 {
1851 int ret = 0;
1852 int internal_byte_order;
1853 enum ctf_type_id type_id;
1854
1855 if (!type || type->frozen) {
1856 ret = -1;
1857 goto end;
1858 }
1859
1860 switch (byte_order) {
1861 case BT_CTF_BYTE_ORDER_NATIVE:
1862 /* Leave unset. Will be initialized by parent. */
1863 internal_byte_order = 0;
1864 break;
1865 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
1866 internal_byte_order = LITTLE_ENDIAN;
1867 break;
1868 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
1869 case BT_CTF_BYTE_ORDER_NETWORK:
1870 internal_byte_order = BIG_ENDIAN;
1871 break;
1872 default:
1873 ret = -1;
1874 goto end;
1875 }
1876
1877 type_id = type->declaration->id;
1878 if (set_byte_order_funcs[type_id]) {
1879 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
1880 }
1881 end:
1882 return ret;
1883 }
1884
1885 enum ctf_type_id bt_ctf_field_type_get_type_id(
1886 struct bt_ctf_field_type *type)
1887 {
1888 if (!type) {
1889 return CTF_TYPE_UNKNOWN;
1890 }
1891
1892 return type->declaration->id;
1893 }
1894
1895 void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
1896 {
1897 if (!type) {
1898 return;
1899 }
1900
1901 bt_ctf_ref_get(&type->ref_count);
1902 }
1903
1904 void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
1905 {
1906 if (!type) {
1907 return;
1908 }
1909
1910 bt_ctf_ref_put(&type->ref_count, bt_ctf_field_type_destroy);
1911 }
1912
1913 BT_HIDDEN
1914 void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
1915 {
1916 if (!type) {
1917 return;
1918 }
1919
1920 type->freeze(type);
1921 }
1922
1923 BT_HIDDEN
1924 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
1925 struct bt_ctf_field_type_variant *variant,
1926 int64_t tag_value)
1927 {
1928 struct bt_ctf_field_type *type = NULL;
1929 GQuark field_name_quark;
1930 gpointer index;
1931 struct structure_field *field_entry;
1932 struct range_overlap_query query = {
1933 .range_start._signed = tag_value,
1934 .range_end._signed = tag_value,
1935 .mapping_name = 0, .overlaps = 0};
1936
1937 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
1938 &query);
1939 if (!query.overlaps) {
1940 goto end;
1941 }
1942
1943 field_name_quark = query.mapping_name;
1944 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1945 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1946 goto end;
1947 }
1948
1949 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
1950 type = field_entry->type;
1951 end:
1952 return type;
1953 }
1954
1955 BT_HIDDEN
1956 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
1957 struct bt_ctf_field_type_variant *variant,
1958 uint64_t tag_value)
1959 {
1960 struct bt_ctf_field_type *type = NULL;
1961 GQuark field_name_quark;
1962 gpointer index;
1963 struct structure_field *field_entry;
1964 struct range_overlap_query query = {
1965 .range_start._unsigned = tag_value,
1966 .range_end._unsigned = tag_value,
1967 .mapping_name = 0, .overlaps = 0};
1968
1969 g_ptr_array_foreach(variant->tag->entries,
1970 check_ranges_overlap_unsigned,
1971 &query);
1972 if (!query.overlaps) {
1973 goto end;
1974 }
1975
1976 field_name_quark = query.mapping_name;
1977 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1978 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1979 goto end;
1980 }
1981
1982 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
1983 type = field_entry->type;
1984 end:
1985 return type;
1986 }
1987
1988 BT_HIDDEN
1989 int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
1990 struct metadata_context *context)
1991 {
1992 int ret;
1993
1994 if (!type || !context) {
1995 ret = -1;
1996 goto end;
1997 }
1998
1999 ret = type->serialize(type, context);
2000 end:
2001 return ret;
2002 }
2003
2004 BT_HIDDEN
2005 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2006 int byte_order)
2007 {
2008 if (!type) {
2009 return;
2010 }
2011
2012 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2013 if (set_byte_order_funcs[type->declaration->id]) {
2014 set_byte_order_funcs[type->declaration->id](type,
2015 byte_order, 1);
2016 }
2017 }
2018
2019 BT_HIDDEN
2020 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2021 {
2022 struct bt_ctf_field_type *copy = NULL;
2023
2024 if (!type) {
2025 goto end;
2026 }
2027
2028 copy = type_copy_funcs[type->declaration->id](type);
2029 end:
2030 return copy;
2031 }
2032
2033 BT_HIDDEN
2034 struct bt_ctf_field_path *bt_ctf_field_path_create(void)
2035 {
2036 struct bt_ctf_field_path *field_path = NULL;
2037
2038 field_path = g_new0(struct bt_ctf_field_path, 1);
2039 if (!field_path) {
2040 goto end;
2041 }
2042
2043 field_path->root = CTF_NODE_UNKNOWN;
2044 field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int));
2045 if (!field_path->path_indexes) {
2046 bt_ctf_field_path_destroy(field_path);
2047 field_path = NULL;
2048 }
2049 end:
2050 return field_path;
2051 }
2052
2053
2054 BT_HIDDEN
2055 struct bt_ctf_field_path *bt_ctf_field_path_copy(
2056 struct bt_ctf_field_path *path)
2057 {
2058 struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
2059
2060 if (!new_path) {
2061 goto end;
2062 }
2063
2064 new_path->root = path->root;
2065 g_array_insert_vals(new_path->path_indexes, 0,
2066 path->path_indexes->data, path->path_indexes->len);
2067 end:
2068 return new_path;
2069 }
2070
2071 BT_HIDDEN
2072 void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
2073 {
2074 if (!path) {
2075 return;
2076 }
2077
2078 if (path->path_indexes) {
2079 g_array_free(path->path_indexes, TRUE);
2080 }
2081 g_free(path);
2082 }
2083
2084 BT_HIDDEN
2085 int bt_ctf_field_type_structure_get_field_name_index(
2086 struct bt_ctf_field_type *type, const char *name)
2087 {
2088 int ret;
2089 size_t index;
2090 GQuark name_quark;
2091 struct bt_ctf_field_type_structure *structure;
2092
2093 if (!type || !name ||
2094 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2095 ret = -1;
2096 goto end;
2097 }
2098
2099 name_quark = g_quark_try_string(name);
2100 if (!name_quark) {
2101 ret = -1;
2102 goto end;
2103 }
2104
2105 structure = container_of(type, struct bt_ctf_field_type_structure,
2106 parent);
2107 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2108 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2109 ret = -1;
2110 goto end;
2111 }
2112 ret = (int) index;
2113 end:
2114 return ret;
2115 }
2116
2117 BT_HIDDEN
2118 int bt_ctf_field_type_variant_get_field_name_index(
2119 struct bt_ctf_field_type *type, const char *name)
2120 {
2121 int ret;
2122 size_t index;
2123 GQuark name_quark;
2124 struct bt_ctf_field_type_variant *variant;
2125
2126 if (!type || !name ||
2127 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2128 ret = -1;
2129 goto end;
2130 }
2131
2132 name_quark = g_quark_try_string(name);
2133 if (!name_quark) {
2134 ret = -1;
2135 goto end;
2136 }
2137
2138 variant = container_of(type, struct bt_ctf_field_type_variant,
2139 parent);
2140 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2141 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2142 ret = -1;
2143 goto end;
2144 }
2145 ret = (int) index;
2146 end:
2147 return ret;
2148 }
2149
2150 BT_HIDDEN
2151 int bt_ctf_field_type_sequence_set_length_field_path(
2152 struct bt_ctf_field_type *type,
2153 struct bt_ctf_field_path *path)
2154 {
2155 int ret = 0;
2156 struct bt_ctf_field_type_sequence *sequence;
2157
2158 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) {
2159 ret = -1;
2160 goto end;
2161 }
2162
2163 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2164 parent);
2165 if (sequence->length_field_path) {
2166 bt_ctf_field_path_destroy(sequence->length_field_path);
2167 }
2168 sequence->length_field_path = path;
2169 end:
2170 return ret;
2171 }
2172
2173 BT_HIDDEN
2174 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2175 struct bt_ctf_field_path *path)
2176 {
2177 int ret = 0;
2178 struct bt_ctf_field_type_variant *variant;
2179
2180 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2181 ret = -1;
2182 goto end;
2183 }
2184
2185 variant = container_of(type, struct bt_ctf_field_type_variant,
2186 parent);
2187 if (variant->tag_path) {
2188 bt_ctf_field_path_destroy(variant->tag_path);
2189 }
2190 variant->tag_path = path;
2191 end:
2192 return ret;
2193 }
2194
2195 BT_HIDDEN
2196 int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
2197 struct bt_ctf_field_type *tag)
2198 {
2199 int ret = 0;
2200 struct bt_ctf_field_type_variant *variant;
2201
2202 if (!type || !tag || type->frozen ||
2203 bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
2204 ret = -1;
2205 goto end;
2206 }
2207
2208 variant = container_of(type, struct bt_ctf_field_type_variant,
2209 parent);
2210 bt_ctf_field_type_get(tag);
2211 if (variant->tag) {
2212 bt_ctf_field_type_put(&variant->tag->parent);
2213 }
2214 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2215 parent);
2216 end:
2217 return ret;
2218 }
2219
2220 static
2221 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
2222 {
2223 struct bt_ctf_field_type_integer *integer;
2224
2225 if (!ref) {
2226 return;
2227 }
2228
2229 integer = container_of(
2230 container_of(ref, struct bt_ctf_field_type, ref_count),
2231 struct bt_ctf_field_type_integer, parent);
2232 if (integer->mapped_clock) {
2233 bt_ctf_clock_put(integer->mapped_clock);
2234 }
2235 g_free(integer);
2236 }
2237
2238 static
2239 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
2240 {
2241 struct bt_ctf_field_type_enumeration *enumeration;
2242
2243 if (!ref) {
2244 return;
2245 }
2246
2247 enumeration = container_of(
2248 container_of(ref, struct bt_ctf_field_type, ref_count),
2249 struct bt_ctf_field_type_enumeration, parent);
2250 g_ptr_array_free(enumeration->entries, TRUE);
2251 bt_ctf_field_type_put(enumeration->container);
2252 g_free(enumeration);
2253 }
2254
2255 static
2256 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
2257 {
2258 struct bt_ctf_field_type_floating_point *floating_point;
2259
2260 if (!ref) {
2261 return;
2262 }
2263
2264 floating_point = container_of(
2265 container_of(ref, struct bt_ctf_field_type, ref_count),
2266 struct bt_ctf_field_type_floating_point, parent);
2267 g_free(floating_point);
2268 }
2269
2270 static
2271 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
2272 {
2273 struct bt_ctf_field_type_structure *structure;
2274
2275 if (!ref) {
2276 return;
2277 }
2278
2279 structure = container_of(
2280 container_of(ref, struct bt_ctf_field_type, ref_count),
2281 struct bt_ctf_field_type_structure, parent);
2282 g_ptr_array_free(structure->fields, TRUE);
2283 g_hash_table_destroy(structure->field_name_to_index);
2284 g_free(structure);
2285 }
2286
2287 static
2288 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
2289 {
2290 struct bt_ctf_field_type_variant *variant;
2291
2292 if (!ref) {
2293 return;
2294 }
2295
2296 variant = container_of(
2297 container_of(ref, struct bt_ctf_field_type, ref_count),
2298 struct bt_ctf_field_type_variant, parent);
2299 g_ptr_array_free(variant->fields, TRUE);
2300 g_hash_table_destroy(variant->field_name_to_index);
2301 g_string_free(variant->tag_name, TRUE);
2302 bt_ctf_field_type_put(&variant->tag->parent);
2303 bt_ctf_field_path_destroy(variant->tag_path);
2304 g_free(variant);
2305 }
2306
2307 static
2308 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
2309 {
2310 struct bt_ctf_field_type_array *array;
2311
2312 if (!ref) {
2313 return;
2314 }
2315
2316 array = container_of(
2317 container_of(ref, struct bt_ctf_field_type, ref_count),
2318 struct bt_ctf_field_type_array, parent);
2319 bt_ctf_field_type_put(array->element_type);
2320 g_free(array);
2321 }
2322
2323 static
2324 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
2325 {
2326 struct bt_ctf_field_type_sequence *sequence;
2327
2328 if (!ref) {
2329 return;
2330 }
2331
2332 sequence = container_of(
2333 container_of(ref, struct bt_ctf_field_type, ref_count),
2334 struct bt_ctf_field_type_sequence, parent);
2335 bt_ctf_field_type_put(sequence->element_type);
2336 g_string_free(sequence->length_field_name, TRUE);
2337 bt_ctf_field_path_destroy(sequence->length_field_path);
2338 g_free(sequence);
2339 }
2340
2341 static
2342 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *ref)
2343 {
2344 struct bt_ctf_field_type_string *string;
2345
2346 if (!ref) {
2347 return;
2348 }
2349
2350 string = container_of(
2351 container_of(ref, struct bt_ctf_field_type, ref_count),
2352 struct bt_ctf_field_type_string, parent);
2353 g_free(string);
2354 }
2355
2356 static
2357 void generic_field_type_freeze(struct bt_ctf_field_type *type)
2358 {
2359 type->frozen = 1;
2360 }
2361
2362 static
2363 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2364 {
2365 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2366 type, struct bt_ctf_field_type_enumeration, parent);
2367
2368 generic_field_type_freeze(type);
2369 bt_ctf_field_type_freeze(enumeration_type->container);
2370 }
2371
2372 static
2373 void freeze_structure_field(struct structure_field *field)
2374 {
2375 bt_ctf_field_type_freeze(field->type);
2376 }
2377
2378 static
2379 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2380 {
2381 struct bt_ctf_field_type_structure *structure_type = container_of(
2382 type, struct bt_ctf_field_type_structure, parent);
2383
2384 /* Cache the alignment */
2385 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2386 generic_field_type_freeze(type);
2387 g_ptr_array_foreach(structure_type->fields,
2388 (GFunc) freeze_structure_field, NULL);
2389 }
2390
2391 static
2392 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2393 {
2394 struct bt_ctf_field_type_variant *variant_type = container_of(
2395 type, struct bt_ctf_field_type_variant, parent);
2396
2397 /* Cache the alignment */
2398 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2399 generic_field_type_freeze(type);
2400 g_ptr_array_foreach(variant_type->fields,
2401 (GFunc) freeze_structure_field, NULL);
2402 }
2403
2404 static
2405 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2406 {
2407 struct bt_ctf_field_type_array *array_type = container_of(
2408 type, struct bt_ctf_field_type_array, parent);
2409
2410 /* Cache the alignment */
2411 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2412 generic_field_type_freeze(type);
2413 bt_ctf_field_type_freeze(array_type->element_type);
2414 }
2415
2416 static
2417 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2418 {
2419 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2420 type, struct bt_ctf_field_type_sequence, parent);
2421
2422 /* Cache the alignment */
2423 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2424 generic_field_type_freeze(type);
2425 bt_ctf_field_type_freeze(sequence_type->element_type);
2426 }
2427
2428 static
2429 const char *get_encoding_string(enum ctf_string_encoding encoding)
2430 {
2431 const char *encoding_string;
2432
2433 switch (encoding) {
2434 case CTF_STRING_NONE:
2435 encoding_string = "none";
2436 break;
2437 case CTF_STRING_ASCII:
2438 encoding_string = "ASCII";
2439 break;
2440 case CTF_STRING_UTF8:
2441 encoding_string = "UTF8";
2442 break;
2443 default:
2444 encoding_string = "unknown";
2445 break;
2446 }
2447
2448 return encoding_string;
2449 }
2450
2451 static
2452 const char *get_integer_base_string(enum bt_ctf_integer_base base)
2453 {
2454 const char *base_string;
2455
2456 switch (base) {
2457 case BT_CTF_INTEGER_BASE_DECIMAL:
2458 base_string = "decimal";
2459 break;
2460 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2461 base_string = "hexadecimal";
2462 break;
2463 case BT_CTF_INTEGER_BASE_OCTAL:
2464 base_string = "octal";
2465 break;
2466 case BT_CTF_INTEGER_BASE_BINARY:
2467 base_string = "binary";
2468 break;
2469 default:
2470 base_string = "unknown";
2471 break;
2472 }
2473
2474 return base_string;
2475 }
2476
2477 static
2478 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2479 struct metadata_context *context)
2480 {
2481 struct bt_ctf_field_type_integer *integer = container_of(type,
2482 struct bt_ctf_field_type_integer, parent);
2483 int ret = 0;
2484
2485 g_string_append_printf(context->string,
2486 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2487 integer->declaration.len, type->declaration->alignment,
2488 (integer->declaration.signedness ? "true" : "false"),
2489 get_encoding_string(integer->declaration.encoding),
2490 get_integer_base_string(integer->declaration.base),
2491 get_byte_order_string(integer->declaration.byte_order));
2492 if (integer->mapped_clock) {
2493 const char *clock_name = bt_ctf_clock_get_name(
2494 integer->mapped_clock);
2495
2496 if (!clock_name) {
2497 ret = -1;
2498 goto end;
2499 }
2500
2501 g_string_append_printf(context->string,
2502 "; map = clock.%s.value", clock_name);
2503 }
2504
2505 g_string_append(context->string, "; }");
2506 end:
2507 return ret;
2508 }
2509
2510 static
2511 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2512 struct metadata_context *context)
2513 {
2514 size_t entry;
2515 int ret;
2516 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2517 struct bt_ctf_field_type_enumeration, parent);
2518 struct bt_ctf_field_type *container_type;
2519 int container_signed;
2520
2521 ret = bt_ctf_field_type_validate(type);
2522 if (ret) {
2523 goto end;
2524 }
2525
2526 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2527 if (!container_type) {
2528 ret = -1;
2529 goto end;
2530 }
2531
2532 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2533 if (container_signed < 0) {
2534 ret = container_signed;
2535 goto error_put_container_type;
2536 }
2537
2538 g_string_append(context->string, "enum : ");
2539 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2540 if (ret) {
2541 goto error_put_container_type;
2542 }
2543
2544 g_string_append(context->string, " { ");
2545 for (entry = 0; entry < enumeration->entries->len; entry++) {
2546 struct enumeration_mapping *mapping =
2547 enumeration->entries->pdata[entry];
2548
2549 if (container_signed) {
2550 if (mapping->range_start._signed ==
2551 mapping->range_end._signed) {
2552 g_string_append_printf(context->string,
2553 "\"%s\" = %" PRId64,
2554 g_quark_to_string(mapping->string),
2555 mapping->range_start._signed);
2556 } else {
2557 g_string_append_printf(context->string,
2558 "\"%s\" = %" PRId64 " ... %" PRId64,
2559 g_quark_to_string(mapping->string),
2560 mapping->range_start._signed,
2561 mapping->range_end._signed);
2562 }
2563 } else {
2564 if (mapping->range_start._unsigned ==
2565 mapping->range_end._unsigned) {
2566 g_string_append_printf(context->string,
2567 "\"%s\" = %" PRIu64,
2568 g_quark_to_string(mapping->string),
2569 mapping->range_start._unsigned);
2570 } else {
2571 g_string_append_printf(context->string,
2572 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2573 g_quark_to_string(mapping->string),
2574 mapping->range_start._unsigned,
2575 mapping->range_end._unsigned);
2576 }
2577 }
2578
2579 g_string_append(context->string,
2580 ((entry != (enumeration->entries->len - 1)) ?
2581 ", " : " }"));
2582 }
2583
2584 if (context->field_name->len) {
2585 g_string_append_printf(context->string, " %s",
2586 context->field_name->str);
2587 g_string_assign(context->field_name, "");
2588 }
2589 error_put_container_type:
2590 bt_ctf_field_type_put(container_type);
2591 end:
2592 return ret;
2593 }
2594
2595 static
2596 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2597 struct metadata_context *context)
2598 {
2599 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2600 type, struct bt_ctf_field_type_floating_point, parent);
2601
2602 g_string_append_printf(context->string,
2603 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2604 floating_point->declaration.exp->len,
2605 floating_point->declaration.mantissa->len + 1,
2606 get_byte_order_string(floating_point->declaration.byte_order),
2607 type->declaration->alignment);
2608 return 0;
2609 }
2610
2611 static
2612 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2613 struct metadata_context *context)
2614 {
2615 size_t i;
2616 unsigned int indent;
2617 int ret = 0;
2618 struct bt_ctf_field_type_structure *structure = container_of(type,
2619 struct bt_ctf_field_type_structure, parent);
2620 GString *structure_field_name = context->field_name;
2621
2622 context->field_name = g_string_new("");
2623
2624 context->current_indentation_level++;
2625 g_string_append(context->string, "struct {\n");
2626
2627 for (i = 0; i < structure->fields->len; i++) {
2628 struct structure_field *field;
2629
2630 for (indent = 0; indent < context->current_indentation_level;
2631 indent++) {
2632 g_string_append_c(context->string, '\t');
2633 }
2634
2635 field = structure->fields->pdata[i];
2636 g_string_assign(context->field_name,
2637 g_quark_to_string(field->name));
2638 ret = bt_ctf_field_type_serialize(field->type, context);
2639 if (ret) {
2640 goto end;
2641 }
2642
2643 if (context->field_name->len) {
2644 g_string_append_printf(context->string, " %s",
2645 context->field_name->str);
2646 }
2647 g_string_append(context->string, ";\n");
2648 }
2649
2650 context->current_indentation_level--;
2651 for (indent = 0; indent < context->current_indentation_level;
2652 indent++) {
2653 g_string_append_c(context->string, '\t');
2654 }
2655
2656 g_string_append_printf(context->string, "} align(%zu)",
2657 type->declaration->alignment);
2658 end:
2659 g_string_free(context->field_name, TRUE);
2660 context->field_name = structure_field_name;
2661 return ret;
2662 }
2663
2664 static
2665 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2666 struct metadata_context *context)
2667 {
2668 size_t i;
2669 unsigned int indent;
2670 int ret = 0;
2671 struct bt_ctf_field_type_variant *variant = container_of(
2672 type, struct bt_ctf_field_type_variant, parent);
2673 GString *variant_field_name = context->field_name;
2674
2675 context->field_name = g_string_new("");
2676 if (variant->tag_name->len > 0) {
2677 g_string_append_printf(context->string,
2678 "variant <%s> {\n", variant->tag_name->str);
2679 } else {
2680 g_string_append(context->string, "variant {\n");
2681 }
2682
2683 context->current_indentation_level++;
2684 for (i = 0; i < variant->fields->len; i++) {
2685 struct structure_field *field = variant->fields->pdata[i];
2686
2687 g_string_assign(context->field_name,
2688 g_quark_to_string(field->name));
2689 for (indent = 0; indent < context->current_indentation_level;
2690 indent++) {
2691 g_string_append_c(context->string, '\t');
2692 }
2693
2694 g_string_assign(context->field_name,
2695 g_quark_to_string(field->name));
2696 ret = bt_ctf_field_type_serialize(field->type, context);
2697 if (ret) {
2698 goto end;
2699 }
2700
2701 if (context->field_name->len) {
2702 g_string_append_printf(context->string, " %s;",
2703 context->field_name->str);
2704 }
2705
2706 g_string_append_c(context->string, '\n');
2707 }
2708
2709 context->current_indentation_level--;
2710 for (indent = 0; indent < context->current_indentation_level;
2711 indent++) {
2712 g_string_append_c(context->string, '\t');
2713 }
2714
2715 g_string_append(context->string, "}");
2716 end:
2717 g_string_free(context->field_name, TRUE);
2718 context->field_name = variant_field_name;
2719 return ret;
2720 }
2721
2722 static
2723 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2724 struct metadata_context *context)
2725 {
2726 int ret = 0;
2727 struct bt_ctf_field_type_array *array = container_of(type,
2728 struct bt_ctf_field_type_array, parent);
2729
2730 ret = bt_ctf_field_type_serialize(array->element_type, context);
2731 if (ret) {
2732 goto end;
2733 }
2734
2735 if (context->field_name->len) {
2736 g_string_append_printf(context->string, " %s[%u]",
2737 context->field_name->str, array->length);
2738 g_string_assign(context->field_name, "");
2739 } else {
2740 g_string_append_printf(context->string, "[%u]", array->length);
2741 }
2742 end:
2743 return ret;
2744 }
2745
2746 static
2747 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2748 struct metadata_context *context)
2749 {
2750 int ret = 0;
2751 struct bt_ctf_field_type_sequence *sequence = container_of(
2752 type, struct bt_ctf_field_type_sequence, parent);
2753
2754 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2755 if (ret) {
2756 goto end;
2757 }
2758
2759 if (context->field_name->len) {
2760 g_string_append_printf(context->string, " %s[%s]",
2761 context->field_name->str,
2762 sequence->length_field_name->str);
2763 g_string_assign(context->field_name, "");
2764 } else {
2765 g_string_append_printf(context->string, "[%s]",
2766 sequence->length_field_name->str);
2767 }
2768 end:
2769 return ret;
2770 }
2771
2772 static
2773 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2774 struct metadata_context *context)
2775 {
2776 struct bt_ctf_field_type_string *string = container_of(
2777 type, struct bt_ctf_field_type_string, parent);
2778
2779 g_string_append_printf(context->string,
2780 "string { encoding = %s; }",
2781 get_encoding_string(string->declaration.encoding));
2782 return 0;
2783 }
2784
2785 static
2786 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
2787 int byte_order, int set_native)
2788 {
2789 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2790 struct bt_ctf_field_type_integer, parent);
2791
2792 if (set_native) {
2793 integer_type->declaration.byte_order =
2794 integer_type->declaration.byte_order == 0 ?
2795 byte_order : integer_type->declaration.byte_order;
2796 } else {
2797 integer_type->declaration.byte_order = byte_order;
2798 }
2799 }
2800
2801 static
2802 void bt_ctf_field_type_enumeration_set_byte_order(
2803 struct bt_ctf_field_type *type, int byte_order, int set_native)
2804 {
2805 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
2806 struct bt_ctf_field_type_enumeration, parent);
2807
2808 /* Safe to assume that container is an integer */
2809 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
2810 byte_order, set_native);
2811 }
2812
2813 static
2814 void bt_ctf_field_type_floating_point_set_byte_order(
2815 struct bt_ctf_field_type *type, int byte_order, int set_native)
2816 {
2817 struct bt_ctf_field_type_floating_point *floating_point_type =
2818 container_of(type, struct bt_ctf_field_type_floating_point,
2819 parent);
2820
2821 if (set_native) {
2822 floating_point_type->declaration.byte_order =
2823 floating_point_type->declaration.byte_order == 0 ?
2824 byte_order :
2825 floating_point_type->declaration.byte_order;
2826 floating_point_type->sign.byte_order =
2827 floating_point_type->sign.byte_order == 0 ?
2828 byte_order : floating_point_type->sign.byte_order;
2829 floating_point_type->mantissa.byte_order =
2830 floating_point_type->mantissa.byte_order == 0 ?
2831 byte_order : floating_point_type->mantissa.byte_order;
2832 floating_point_type->exp.byte_order =
2833 floating_point_type->exp.byte_order == 0 ?
2834 byte_order : floating_point_type->exp.byte_order;
2835 } else {
2836 floating_point_type->declaration.byte_order = byte_order;
2837 floating_point_type->sign.byte_order = byte_order;
2838 floating_point_type->mantissa.byte_order = byte_order;
2839 floating_point_type->exp.byte_order = byte_order;
2840 }
2841 }
2842
2843 static
2844 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
2845 int byte_order, int set_native)
2846 {
2847 int i;
2848 struct bt_ctf_field_type_structure *structure_type =
2849 container_of(type, struct bt_ctf_field_type_structure,
2850 parent);
2851
2852 for (i = 0; i < structure_type->fields->len; i++) {
2853 struct structure_field *field = g_ptr_array_index(
2854 structure_type->fields, i);
2855 struct bt_ctf_field_type *field_type = field->type;
2856
2857 if (set_byte_order_funcs[field_type->declaration->id]) {
2858 set_byte_order_funcs[field_type->declaration->id](
2859 field_type, byte_order, set_native);
2860 }
2861 }
2862 }
2863
2864 static
2865 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
2866 int byte_order, int set_native)
2867 {
2868 int i;
2869 struct bt_ctf_field_type_variant *variant_type =
2870 container_of(type, struct bt_ctf_field_type_variant,
2871 parent);
2872
2873 for (i = 0; i < variant_type->fields->len; i++) {
2874 struct structure_field *field = g_ptr_array_index(
2875 variant_type->fields, i);
2876 struct bt_ctf_field_type *field_type = field->type;
2877
2878 if (set_byte_order_funcs[field_type->declaration->id]) {
2879 set_byte_order_funcs[field_type->declaration->id](
2880 field_type, byte_order, set_native);
2881 }
2882 }
2883 }
2884
2885 static
2886 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
2887 int byte_order, int set_native)
2888 {
2889 struct bt_ctf_field_type_array *array_type =
2890 container_of(type, struct bt_ctf_field_type_array,
2891 parent);
2892
2893 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
2894 set_byte_order_funcs[array_type->element_type->declaration->id](
2895 array_type->element_type, byte_order, set_native);
2896 }
2897 }
2898
2899 static
2900 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
2901 int byte_order, int set_native)
2902 {
2903 struct bt_ctf_field_type_sequence *sequence_type =
2904 container_of(type, struct bt_ctf_field_type_sequence,
2905 parent);
2906
2907 if (set_byte_order_funcs[
2908 sequence_type->element_type->declaration->id]) {
2909 set_byte_order_funcs[
2910 sequence_type->element_type->declaration->id](
2911 sequence_type->element_type, byte_order, set_native);
2912 }
2913 }
2914
2915 static
2916 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
2917 struct bt_ctf_field_type *type)
2918 {
2919 struct bt_ctf_field_type *copy;
2920 struct bt_ctf_field_type_integer *integer, *copy_integer;
2921
2922 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
2923 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
2924 if (!copy) {
2925 goto end;
2926 }
2927
2928 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
2929 parent);
2930 copy_integer->declaration = integer->declaration;
2931 if (integer->mapped_clock) {
2932 bt_ctf_clock_get(integer->mapped_clock);
2933 copy_integer->mapped_clock = integer->mapped_clock;
2934 }
2935 end:
2936 return copy;
2937 }
2938
2939 static
2940 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
2941 struct bt_ctf_field_type *type)
2942 {
2943 size_t i;
2944 struct bt_ctf_field_type *copy = NULL, *copy_container;
2945 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
2946
2947 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
2948 parent);
2949
2950 /* Copy the source enumeration's container */
2951 copy_container = bt_ctf_field_type_copy(enumeration->container);
2952 if (!copy_container) {
2953 goto end;
2954 }
2955
2956 copy = bt_ctf_field_type_enumeration_create(copy_container);
2957 if (!copy) {
2958 goto end;
2959 }
2960 copy_enumeration = container_of(copy,
2961 struct bt_ctf_field_type_enumeration, parent);
2962
2963 /* Copy all enumaration entries */
2964 for (i = 0; i < enumeration->entries->len; i++) {
2965 struct enumeration_mapping *mapping = g_ptr_array_index(
2966 enumeration->entries, i);
2967 struct enumeration_mapping* copy_mapping = g_new0(
2968 struct enumeration_mapping, 1);
2969
2970 if (!copy_mapping) {
2971 goto error;
2972 }
2973
2974 *copy_mapping = *mapping;
2975 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
2976 }
2977
2978 copy_enumeration->declaration = enumeration->declaration;
2979 end:
2980 if (copy_container) {
2981 bt_ctf_field_type_put(copy_container);
2982 }
2983 return copy;
2984 error:
2985 if (copy_container) {
2986 bt_ctf_field_type_put(copy_container);
2987 }
2988 bt_ctf_field_type_put(copy);
2989 return NULL;
2990 }
2991
2992 static
2993 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
2994 struct bt_ctf_field_type *type)
2995 {
2996 struct bt_ctf_field_type *copy;
2997 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
2998
2999 floating_point = container_of(type,
3000 struct bt_ctf_field_type_floating_point, parent);
3001 copy = bt_ctf_field_type_floating_point_create();
3002 if (!copy) {
3003 goto end;
3004 }
3005
3006 copy_float = container_of(copy,
3007 struct bt_ctf_field_type_floating_point, parent);
3008 copy_float->declaration = floating_point->declaration;
3009 copy_float->sign = floating_point->sign;
3010 copy_float->mantissa = floating_point->mantissa;
3011 copy_float->exp = floating_point->exp;
3012 end:
3013 return copy;
3014 }
3015
3016 static
3017 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3018 struct bt_ctf_field_type *type)
3019 {
3020 int i;
3021 GHashTableIter iter;
3022 gpointer key, value;
3023 struct bt_ctf_field_type *copy;
3024 struct bt_ctf_field_type_structure *structure, *copy_structure;
3025
3026 structure = container_of(type, struct bt_ctf_field_type_structure,
3027 parent);
3028 copy = bt_ctf_field_type_structure_create();
3029 if (!copy) {
3030 goto end;
3031 }
3032
3033 copy_structure = container_of(copy,
3034 struct bt_ctf_field_type_structure, parent);
3035
3036 /* Copy field_name_to_index */
3037 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3038 while (g_hash_table_iter_next (&iter, &key, &value)) {
3039 g_hash_table_insert(copy_structure->field_name_to_index,
3040 key, value);
3041 }
3042
3043 for (i = 0; i < structure->fields->len; i++) {
3044 struct structure_field *entry, *copy_entry;
3045 struct bt_ctf_field_type *copy_field;
3046
3047 copy_entry = g_new0(struct structure_field, 1);
3048 if (!copy_entry) {
3049 goto error;
3050 }
3051
3052 entry = g_ptr_array_index(structure->fields, i);
3053 copy_field = bt_ctf_field_type_copy(entry->type);
3054 if (!copy_field) {
3055 g_free(copy_entry);
3056 goto error;
3057 }
3058
3059 copy_entry->name = entry->name;
3060 copy_entry->type = copy_field;
3061 g_ptr_array_add(copy_structure->fields, copy_entry);
3062 }
3063
3064 copy_structure->declaration = structure->declaration;
3065 end:
3066 return copy;
3067 error:
3068 bt_ctf_field_type_put(copy);
3069 return NULL;
3070 }
3071
3072 static
3073 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3074 struct bt_ctf_field_type *type)
3075 {
3076 int i;
3077 GHashTableIter iter;
3078 gpointer key, value;
3079 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3080 struct bt_ctf_field_type_variant *variant, *copy_variant;
3081
3082 variant = container_of(type, struct bt_ctf_field_type_variant,
3083 parent);
3084 if (variant->tag) {
3085 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3086 if (!copy_tag) {
3087 goto end;
3088 }
3089 }
3090
3091 copy = bt_ctf_field_type_variant_create(copy_tag,
3092 variant->tag_name->len ? variant->tag_name->str : NULL);
3093 if (!copy) {
3094 goto end;
3095 }
3096
3097 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3098 parent);
3099
3100 /* Copy field_name_to_index */
3101 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3102 while (g_hash_table_iter_next (&iter, &key, &value)) {
3103 g_hash_table_insert(copy_variant->field_name_to_index,
3104 key, value);
3105 }
3106
3107 for (i = 0; i < variant->fields->len; i++) {
3108 struct structure_field *entry, *copy_entry;
3109 struct bt_ctf_field_type *copy_field;
3110
3111 copy_entry = g_new0(struct structure_field, 1);
3112 if (!copy_entry) {
3113 goto error;
3114 }
3115
3116 entry = g_ptr_array_index(variant->fields, i);
3117 copy_field = bt_ctf_field_type_copy(entry->type);
3118 if (!copy_field) {
3119 g_free(copy_entry);
3120 goto error;
3121 }
3122
3123 copy_entry->name = entry->name;
3124 copy_entry->type = copy_field;
3125 g_ptr_array_add(copy_variant->fields, copy_entry);
3126 }
3127
3128 copy_variant->declaration = variant->declaration;
3129 if (variant->tag_path) {
3130 copy_variant->tag_path = bt_ctf_field_path_copy(
3131 variant->tag_path);
3132 if (!copy_variant->tag_path) {
3133 goto error;
3134 }
3135 }
3136 end:
3137 if (copy_tag) {
3138 bt_ctf_field_type_put(copy_tag);
3139 }
3140
3141 return copy;
3142 error:
3143 if (copy_tag) {
3144 bt_ctf_field_type_put(copy_tag);
3145 }
3146
3147 bt_ctf_field_type_put(copy);
3148 return NULL;
3149 }
3150
3151 static
3152 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3153 struct bt_ctf_field_type *type)
3154 {
3155 struct bt_ctf_field_type *copy = NULL, *copy_element;
3156 struct bt_ctf_field_type_array *array, *copy_array;
3157
3158 array = container_of(type, struct bt_ctf_field_type_array,
3159 parent);
3160 copy_element = bt_ctf_field_type_copy(array->element_type);
3161 if (!copy_element) {
3162 goto end;
3163 }
3164
3165 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3166 if (!copy) {
3167 goto end;
3168 }
3169
3170 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3171 parent);
3172 copy_array->declaration = array->declaration;
3173 end:
3174 if (copy_element) {
3175 bt_ctf_field_type_put(copy_element);
3176 }
3177
3178 return copy;
3179 }
3180
3181 static
3182 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3183 struct bt_ctf_field_type *type)
3184 {
3185 struct bt_ctf_field_type *copy = NULL, *copy_element;
3186 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3187
3188 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3189 parent);
3190 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3191 if (!copy_element) {
3192 goto end;
3193 }
3194
3195 copy = bt_ctf_field_type_sequence_create(copy_element,
3196 sequence->length_field_name->len ?
3197 sequence->length_field_name->str : NULL);
3198 if (!copy) {
3199 goto end;
3200 }
3201
3202 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3203 parent);
3204 copy_sequence->declaration = sequence->declaration;
3205 if (sequence->length_field_path) {
3206 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3207 sequence->length_field_path);
3208 if (!copy_sequence->length_field_path) {
3209 goto error;
3210 }
3211 }
3212 end:
3213 if (copy_element) {
3214 bt_ctf_field_type_put(copy_element);
3215 }
3216
3217 return copy;
3218 error:
3219 if (copy) {
3220 bt_ctf_field_type_put(copy);
3221 copy = NULL;
3222 }
3223 goto end;
3224 }
3225
3226 static
3227 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3228 struct bt_ctf_field_type *type)
3229 {
3230 struct bt_ctf_field_type *copy;
3231 struct bt_ctf_field_type_string *string, *copy_string;
3232
3233 copy = bt_ctf_field_type_string_create();
3234 if (!copy) {
3235 goto end;
3236 }
3237
3238 string = container_of(type, struct bt_ctf_field_type_string,
3239 parent);
3240 copy_string = container_of(type, struct bt_ctf_field_type_string,
3241 parent);
3242 copy_string->declaration = string->declaration;
3243 end:
3244 return copy;
3245 }
This page took 0.143286 seconds and 3 git commands to generate.