c03f0b7758f578b81e3c300118f94a9c7c96b34f
[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
1176 if (type->declaration->alignment < field_type->declaration->alignment) {
1177 type->declaration->alignment =
1178 field_type->declaration->alignment;
1179 }
1180 end:
1181 return ret;
1182 }
1183
1184 int bt_ctf_field_type_structure_get_field_count(
1185 struct bt_ctf_field_type *type)
1186 {
1187 int ret = 0;
1188 struct bt_ctf_field_type_structure *structure;
1189
1190 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1191 ret = -1;
1192 goto end;
1193 }
1194
1195 structure = container_of(type, struct bt_ctf_field_type_structure,
1196 parent);
1197 ret = (int) structure->fields->len;
1198 end:
1199 return ret;
1200 }
1201
1202 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1203 const char **field_name, struct bt_ctf_field_type **field_type,
1204 int index)
1205 {
1206 struct bt_ctf_field_type_structure *structure;
1207 struct structure_field *field;
1208 int ret = 0;
1209
1210 if (!type || index < 0 || (type->declaration->id != CTF_TYPE_STRUCT)) {
1211 ret = -1;
1212 goto end;
1213 }
1214
1215 structure = container_of(type, struct bt_ctf_field_type_structure,
1216 parent);
1217 if (index >= structure->fields->len) {
1218 ret = -1;
1219 goto end;
1220 }
1221
1222 field = g_ptr_array_index(structure->fields, index);
1223 if (field_type) {
1224 *field_type = field->type;
1225 bt_ctf_field_type_get(field->type);
1226 }
1227 if (field_name) {
1228 *field_name = g_quark_to_string(field->name);
1229 }
1230 end:
1231 return ret;
1232 }
1233
1234 struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1235 struct bt_ctf_field_type *type,
1236 const char *name)
1237 {
1238 size_t index;
1239 GQuark name_quark;
1240 struct structure_field *field;
1241 struct bt_ctf_field_type_structure *structure;
1242 struct bt_ctf_field_type *field_type = NULL;
1243
1244 if (!type || !name) {
1245 goto end;
1246 }
1247
1248 name_quark = g_quark_try_string(name);
1249 if (!name_quark) {
1250 goto end;
1251 }
1252
1253 structure = container_of(type, struct bt_ctf_field_type_structure,
1254 parent);
1255 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1256 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1257 goto end;
1258 }
1259
1260 field = structure->fields->pdata[index];
1261 field_type = field->type;
1262 bt_ctf_field_type_get(field_type);
1263 end:
1264 return field_type;
1265 }
1266
1267 struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1268 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1269 {
1270 struct bt_ctf_field_type_variant *variant = NULL;
1271
1272 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
1273 goto error;
1274 }
1275
1276 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1277 if (!variant) {
1278 goto error;
1279 }
1280
1281 variant->parent.declaration = &variant->declaration.p;
1282 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1283 variant->tag_name = g_string_new(tag_name);
1284 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1285 variant->fields = g_ptr_array_new_with_free_func(
1286 (GDestroyNotify)destroy_structure_field);
1287 if (enum_tag) {
1288 bt_ctf_field_type_get(enum_tag);
1289 variant->tag = container_of(enum_tag,
1290 struct bt_ctf_field_type_enumeration, parent);
1291 }
1292
1293 bt_ctf_field_type_init(&variant->parent);
1294 return &variant->parent;
1295 error:
1296 return NULL;
1297 }
1298
1299 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1300 struct bt_ctf_field_type *type)
1301 {
1302 struct bt_ctf_field_type_variant *variant;
1303 struct bt_ctf_field_type *tag_type = NULL;
1304
1305 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1306 goto end;
1307 }
1308
1309 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1310 if (!variant->tag) {
1311 goto end;
1312 }
1313
1314 tag_type = &variant->tag->parent;
1315 bt_ctf_field_type_get(tag_type);
1316 end:
1317 return tag_type;
1318 }
1319
1320 const char *bt_ctf_field_type_variant_get_tag_name(
1321 struct bt_ctf_field_type *type)
1322 {
1323 struct bt_ctf_field_type_variant *variant;
1324 const char *tag_name = NULL;
1325
1326 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1327 goto end;
1328 }
1329
1330 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1331 if (variant->tag_name->len == 0) {
1332 goto end;
1333 }
1334
1335 tag_name = variant->tag_name->str;
1336 end:
1337 return tag_name;
1338 }
1339
1340 int bt_ctf_field_type_variant_set_tag_name(
1341 struct bt_ctf_field_type *type, const char *name)
1342 {
1343 int ret = 0;
1344 struct bt_ctf_field_type_variant *variant;
1345
1346 if (!type || type->frozen ||
1347 (type->declaration->id != CTF_TYPE_VARIANT) ||
1348 bt_ctf_validate_identifier(name)) {
1349 ret = -1;
1350 goto end;
1351 }
1352
1353 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1354 g_string_assign(variant->tag_name, name);
1355 end:
1356 return ret;
1357 }
1358
1359 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1360 struct bt_ctf_field_type *field_type,
1361 const char *field_name)
1362 {
1363 size_t i;
1364 int ret = 0;
1365 struct bt_ctf_field_type_variant *variant;
1366 GQuark field_name_quark = g_quark_from_string(field_name);
1367
1368 if (!type || !field_type || type->frozen ||
1369 bt_ctf_validate_identifier(field_name) ||
1370 (type->declaration->id != CTF_TYPE_VARIANT) ||
1371 bt_ctf_field_type_validate(field_type)) {
1372 ret = -1;
1373 goto end;
1374 }
1375
1376 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1377
1378 /* The user has explicitly provided a tag; validate against it. */
1379 if (variant->tag) {
1380 int name_found = 0;
1381
1382 /* Make sure this name is present in the enum tag */
1383 for (i = 0; i < variant->tag->entries->len; i++) {
1384 struct enumeration_mapping *mapping =
1385 g_ptr_array_index(variant->tag->entries, i);
1386
1387 if (mapping->string == field_name_quark) {
1388 name_found = 1;
1389 break;
1390 }
1391 }
1392
1393 if (!name_found) {
1394 /* Validation failed */
1395 ret = -1;
1396 goto end;
1397 }
1398 }
1399
1400 if (add_structure_field(variant->fields, variant->field_name_to_index,
1401 field_type, field_name)) {
1402 ret = -1;
1403 goto end;
1404 }
1405 end:
1406 return ret;
1407 }
1408
1409 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1410 struct bt_ctf_field_type *type,
1411 const char *field_name)
1412 {
1413 size_t index;
1414 GQuark name_quark;
1415 struct structure_field *field;
1416 struct bt_ctf_field_type_variant *variant;
1417 struct bt_ctf_field_type *field_type = NULL;
1418
1419 if (!type || !field_name) {
1420 goto end;
1421 }
1422
1423 name_quark = g_quark_try_string(field_name);
1424 if (!name_quark) {
1425 goto end;
1426 }
1427
1428 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1429 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1430 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1431 goto end;
1432 }
1433
1434 field = g_ptr_array_index(variant->fields, index);
1435 field_type = field->type;
1436 bt_ctf_field_type_get(field_type);
1437 end:
1438 return field_type;
1439 }
1440
1441 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1442 struct bt_ctf_field_type *type,
1443 struct bt_ctf_field *tag)
1444 {
1445 const char *enum_value;
1446 struct bt_ctf_field_type *field_type = NULL;
1447
1448 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1449 goto end;
1450 }
1451
1452 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1453 if (!enum_value) {
1454 goto end;
1455 }
1456
1457 /* Already increments field_type's reference count */
1458 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1459 type, enum_value);
1460 end:
1461 return field_type;
1462 }
1463
1464 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1465 {
1466 int ret = 0;
1467 struct bt_ctf_field_type_variant *variant;
1468
1469 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1470 ret = -1;
1471 goto end;
1472 }
1473
1474 variant = container_of(type, struct bt_ctf_field_type_variant,
1475 parent);
1476 ret = (int) variant->fields->len;
1477 end:
1478 return ret;
1479
1480 }
1481
1482 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1483 const char **field_name, struct bt_ctf_field_type **field_type,
1484 int index)
1485 {
1486 struct bt_ctf_field_type_variant *variant;
1487 struct structure_field *field;
1488 int ret = 0;
1489
1490 if (!type || index < 0 || !field_name || !field_type ||
1491 (type->declaration->id != CTF_TYPE_VARIANT)) {
1492 ret = -1;
1493 goto end;
1494 }
1495
1496 variant = container_of(type, struct bt_ctf_field_type_variant,
1497 parent);
1498 if (index >= variant->fields->len) {
1499 ret = -1;
1500 goto end;
1501 }
1502
1503 field = g_ptr_array_index(variant->fields, index);
1504 *field_type = field->type;
1505 bt_ctf_field_type_get(field->type);
1506 *field_name = g_quark_to_string(field->name);
1507 end:
1508 return ret;
1509 }
1510
1511 struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1512 struct bt_ctf_field_type *element_type,
1513 unsigned int length)
1514 {
1515 struct bt_ctf_field_type_array *array = NULL;
1516
1517 if (!element_type || length == 0 ||
1518 bt_ctf_field_type_validate(element_type)) {
1519 goto error;
1520 }
1521
1522 array = g_new0(struct bt_ctf_field_type_array, 1);
1523 if (!array) {
1524 goto error;
1525 }
1526
1527 array->parent.declaration = &array->declaration.p;
1528 array->parent.declaration->id = CTF_TYPE_ARRAY;
1529
1530 bt_ctf_field_type_get(element_type);
1531 array->element_type = element_type;
1532 array->length = length;
1533 bt_ctf_field_type_init(&array->parent);
1534 array->parent.declaration->alignment =
1535 element_type->declaration->alignment;
1536 return &array->parent;
1537 error:
1538 return NULL;
1539 }
1540
1541 struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1542 struct bt_ctf_field_type *type)
1543 {
1544 struct bt_ctf_field_type *ret = NULL;
1545 struct bt_ctf_field_type_array *array;
1546
1547 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1548 goto end;
1549 }
1550
1551 array = container_of(type, struct bt_ctf_field_type_array, parent);
1552 ret = array->element_type;
1553 bt_ctf_field_type_get(ret);
1554 end:
1555 return ret;
1556 }
1557
1558 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1559 {
1560 int64_t ret;
1561 struct bt_ctf_field_type_array *array;
1562
1563 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1564 ret = -1;
1565 goto end;
1566 }
1567
1568 array = container_of(type, struct bt_ctf_field_type_array, parent);
1569 ret = (int64_t) array->length;
1570 end:
1571 return ret;
1572 }
1573
1574 struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1575 struct bt_ctf_field_type *element_type,
1576 const char *length_field_name)
1577 {
1578 struct bt_ctf_field_type_sequence *sequence = NULL;
1579
1580 if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
1581 bt_ctf_field_type_validate(element_type)) {
1582 goto error;
1583 }
1584
1585 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1586 if (!sequence) {
1587 goto error;
1588 }
1589
1590 sequence->parent.declaration = &sequence->declaration.p;
1591 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
1592 bt_ctf_field_type_get(element_type);
1593 sequence->element_type = element_type;
1594 sequence->length_field_name = g_string_new(length_field_name);
1595 bt_ctf_field_type_init(&sequence->parent);
1596 sequence->parent.declaration->alignment =
1597 element_type->declaration->alignment;
1598 return &sequence->parent;
1599 error:
1600 return NULL;
1601 }
1602
1603 struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1604 struct bt_ctf_field_type *type)
1605 {
1606 struct bt_ctf_field_type *ret = NULL;
1607 struct bt_ctf_field_type_sequence *sequence;
1608
1609 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1610 goto end;
1611 }
1612
1613 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1614 parent);
1615 ret = sequence->element_type;
1616 bt_ctf_field_type_get(ret);
1617 end:
1618 return ret;
1619 }
1620
1621 const char *bt_ctf_field_type_sequence_get_length_field_name(
1622 struct bt_ctf_field_type *type)
1623 {
1624 const char *ret = NULL;
1625 struct bt_ctf_field_type_sequence *sequence;
1626
1627 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1628 goto end;
1629 }
1630
1631 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1632 parent);
1633 ret = sequence->length_field_name->str;
1634 end:
1635 return ret;
1636 }
1637
1638 struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1639 {
1640 struct bt_ctf_field_type_string *string =
1641 g_new0(struct bt_ctf_field_type_string, 1);
1642
1643 if (!string) {
1644 return NULL;
1645 }
1646
1647 string->parent.declaration = &string->declaration.p;
1648 string->parent.declaration->id = CTF_TYPE_STRING;
1649 bt_ctf_field_type_init(&string->parent);
1650 string->declaration.encoding = CTF_STRING_UTF8;
1651 string->parent.declaration->alignment = CHAR_BIT;
1652 return &string->parent;
1653 }
1654
1655 enum ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1656 struct bt_ctf_field_type *type)
1657 {
1658 struct bt_ctf_field_type_string *string;
1659 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
1660
1661 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1662 goto end;
1663 }
1664
1665 string = container_of(type, struct bt_ctf_field_type_string,
1666 parent);
1667 ret = string->declaration.encoding;
1668 end:
1669 return ret;
1670 }
1671
1672 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
1673 enum ctf_string_encoding encoding)
1674 {
1675 int ret = 0;
1676 struct bt_ctf_field_type_string *string;
1677
1678 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1679 (encoding != CTF_STRING_UTF8 &&
1680 encoding != CTF_STRING_ASCII)) {
1681 ret = -1;
1682 goto end;
1683 }
1684
1685 string = container_of(type, struct bt_ctf_field_type_string, parent);
1686 string->declaration.encoding = encoding;
1687 end:
1688 return ret;
1689 }
1690
1691 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1692 {
1693 int ret;
1694
1695 if (!type) {
1696 ret = -1;
1697 goto end;
1698 }
1699
1700 ret = (int) type->declaration->alignment;
1701 end:
1702 return ret;
1703 }
1704
1705 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
1706 unsigned int alignment)
1707 {
1708 int ret = 0;
1709
1710 /* Alignment must be bit-aligned (1) or byte aligned */
1711 if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
1712 ret = -1;
1713 goto end;
1714 }
1715
1716 if (type->declaration->id == CTF_TYPE_STRING &&
1717 alignment != CHAR_BIT) {
1718 ret = -1;
1719 goto end;
1720 }
1721
1722 type->declaration->alignment = alignment;
1723 ret = 0;
1724 end:
1725 return ret;
1726 }
1727
1728 enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1729 struct bt_ctf_field_type *type)
1730 {
1731 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
1732 int internal_byte_order = -1;
1733
1734 if (!type) {
1735 goto end;
1736 }
1737
1738 switch (type->declaration->id) {
1739 case CTF_TYPE_INTEGER:
1740 {
1741 struct bt_ctf_field_type_integer *integer = container_of(
1742 type, struct bt_ctf_field_type_integer, parent);
1743 internal_byte_order = integer->declaration.byte_order;
1744 break;
1745 }
1746 case CTF_TYPE_FLOAT:
1747 {
1748 struct bt_ctf_field_type_floating_point *floating_point =
1749 container_of(type,
1750 struct bt_ctf_field_type_floating_point,
1751 parent);
1752 internal_byte_order = floating_point->declaration.byte_order;
1753 break;
1754 }
1755 default:
1756 goto end;
1757 }
1758
1759 switch (internal_byte_order) {
1760 case LITTLE_ENDIAN:
1761 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
1762 break;
1763 case BIG_ENDIAN:
1764 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1765 break;
1766 case 0:
1767 ret = BT_CTF_BYTE_ORDER_NATIVE;
1768 break;
1769 default:
1770 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
1771 }
1772 end:
1773 return ret;
1774 }
1775
1776 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
1777 enum bt_ctf_byte_order byte_order)
1778 {
1779 int ret = 0;
1780 int internal_byte_order;
1781 enum ctf_type_id type_id;
1782
1783 if (!type || type->frozen) {
1784 ret = -1;
1785 goto end;
1786 }
1787
1788 switch (byte_order) {
1789 case BT_CTF_BYTE_ORDER_NATIVE:
1790 /* Leave unset. Will be initialized by parent. */
1791 internal_byte_order = 0;
1792 break;
1793 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
1794 internal_byte_order = LITTLE_ENDIAN;
1795 break;
1796 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
1797 case BT_CTF_BYTE_ORDER_NETWORK:
1798 internal_byte_order = BIG_ENDIAN;
1799 break;
1800 default:
1801 ret = -1;
1802 goto end;
1803 }
1804
1805 type_id = type->declaration->id;
1806 if (set_byte_order_funcs[type_id]) {
1807 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
1808 }
1809 end:
1810 return ret;
1811 }
1812
1813 enum ctf_type_id bt_ctf_field_type_get_type_id(
1814 struct bt_ctf_field_type *type)
1815 {
1816 if (!type) {
1817 return CTF_TYPE_UNKNOWN;
1818 }
1819
1820 return type->declaration->id;
1821 }
1822
1823 void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
1824 {
1825 if (!type) {
1826 return;
1827 }
1828
1829 bt_ctf_ref_get(&type->ref_count);
1830 }
1831
1832 void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
1833 {
1834 if (!type) {
1835 return;
1836 }
1837
1838 bt_ctf_ref_put(&type->ref_count, bt_ctf_field_type_destroy);
1839 }
1840
1841 BT_HIDDEN
1842 void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
1843 {
1844 if (!type) {
1845 return;
1846 }
1847
1848 type->freeze(type);
1849 }
1850
1851 BT_HIDDEN
1852 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
1853 struct bt_ctf_field_type_variant *variant,
1854 int64_t tag_value)
1855 {
1856 struct bt_ctf_field_type *type = NULL;
1857 GQuark field_name_quark;
1858 gpointer index;
1859 struct structure_field *field_entry;
1860 struct range_overlap_query query = {
1861 .range_start._signed = tag_value,
1862 .range_end._signed = tag_value,
1863 .mapping_name = 0, .overlaps = 0};
1864
1865 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
1866 &query);
1867 if (!query.overlaps) {
1868 goto end;
1869 }
1870
1871 field_name_quark = query.mapping_name;
1872 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1873 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1874 goto end;
1875 }
1876
1877 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
1878 type = field_entry->type;
1879 end:
1880 return type;
1881 }
1882
1883 BT_HIDDEN
1884 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
1885 struct bt_ctf_field_type_variant *variant,
1886 uint64_t tag_value)
1887 {
1888 struct bt_ctf_field_type *type = NULL;
1889 GQuark field_name_quark;
1890 gpointer index;
1891 struct structure_field *field_entry;
1892 struct range_overlap_query query = {
1893 .range_start._unsigned = tag_value,
1894 .range_end._unsigned = tag_value,
1895 .mapping_name = 0, .overlaps = 0};
1896
1897 g_ptr_array_foreach(variant->tag->entries,
1898 check_ranges_overlap_unsigned,
1899 &query);
1900 if (!query.overlaps) {
1901 goto end;
1902 }
1903
1904 field_name_quark = query.mapping_name;
1905 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1906 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1907 goto end;
1908 }
1909
1910 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
1911 type = field_entry->type;
1912 end:
1913 return type;
1914 }
1915
1916 BT_HIDDEN
1917 int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
1918 struct metadata_context *context)
1919 {
1920 int ret;
1921
1922 if (!type || !context) {
1923 ret = -1;
1924 goto end;
1925 }
1926
1927 ret = type->serialize(type, context);
1928 end:
1929 return ret;
1930 }
1931
1932 BT_HIDDEN
1933 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
1934 int byte_order)
1935 {
1936 if (!type) {
1937 return;
1938 }
1939
1940 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
1941 if (set_byte_order_funcs[type->declaration->id]) {
1942 set_byte_order_funcs[type->declaration->id](type,
1943 byte_order, 1);
1944 }
1945 }
1946
1947 BT_HIDDEN
1948 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
1949 {
1950 struct bt_ctf_field_type *copy = NULL;
1951
1952 if (!type) {
1953 goto end;
1954 }
1955
1956 copy = type_copy_funcs[type->declaration->id](type);
1957 end:
1958 return copy;
1959 }
1960
1961 BT_HIDDEN
1962 struct bt_ctf_field_path *bt_ctf_field_path_create(void)
1963 {
1964 struct bt_ctf_field_path *field_path = NULL;
1965
1966 field_path = g_new0(struct bt_ctf_field_path, 1);
1967 if (!field_path) {
1968 goto end;
1969 }
1970
1971 field_path->root = CTF_NODE_UNKNOWN;
1972 field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int));
1973 if (!field_path->path_indexes) {
1974 bt_ctf_field_path_destroy(field_path);
1975 field_path = NULL;
1976 }
1977 end:
1978 return field_path;
1979 }
1980
1981
1982 BT_HIDDEN
1983 struct bt_ctf_field_path *bt_ctf_field_path_copy(
1984 struct bt_ctf_field_path *path)
1985 {
1986 struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
1987
1988 if (!new_path) {
1989 goto end;
1990 }
1991
1992 new_path->root = path->root;
1993 g_array_insert_vals(new_path->path_indexes, 0,
1994 path->path_indexes->data, path->path_indexes->len);
1995 end:
1996 return new_path;
1997 }
1998
1999 BT_HIDDEN
2000 void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
2001 {
2002 if (!path) {
2003 return;
2004 }
2005
2006 if (path->path_indexes) {
2007 g_array_free(path->path_indexes, TRUE);
2008 }
2009 g_free(path);
2010 }
2011
2012 BT_HIDDEN
2013 int bt_ctf_field_type_structure_get_field_name_index(
2014 struct bt_ctf_field_type *type, const char *name)
2015 {
2016 int ret;
2017 size_t index;
2018 GQuark name_quark;
2019 struct bt_ctf_field_type_structure *structure;
2020
2021 if (!type || !name ||
2022 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2023 ret = -1;
2024 goto end;
2025 }
2026
2027 name_quark = g_quark_try_string(name);
2028 if (!name_quark) {
2029 ret = -1;
2030 goto end;
2031 }
2032
2033 structure = container_of(type, struct bt_ctf_field_type_structure,
2034 parent);
2035 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2036 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2037 ret = -1;
2038 goto end;
2039 }
2040 ret = (int) index;
2041 end:
2042 return ret;
2043 }
2044
2045 BT_HIDDEN
2046 int bt_ctf_field_type_variant_get_field_name_index(
2047 struct bt_ctf_field_type *type, const char *name)
2048 {
2049 int ret;
2050 size_t index;
2051 GQuark name_quark;
2052 struct bt_ctf_field_type_variant *variant;
2053
2054 if (!type || !name ||
2055 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2056 ret = -1;
2057 goto end;
2058 }
2059
2060 name_quark = g_quark_try_string(name);
2061 if (!name_quark) {
2062 ret = -1;
2063 goto end;
2064 }
2065
2066 variant = container_of(type, struct bt_ctf_field_type_variant,
2067 parent);
2068 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2069 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2070 ret = -1;
2071 goto end;
2072 }
2073 ret = (int) index;
2074 end:
2075 return ret;
2076 }
2077
2078 BT_HIDDEN
2079 int bt_ctf_field_type_sequence_set_length_field_path(
2080 struct bt_ctf_field_type *type,
2081 struct bt_ctf_field_path *path)
2082 {
2083 int ret = 0;
2084 struct bt_ctf_field_type_sequence *sequence;
2085
2086 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) {
2087 ret = -1;
2088 goto end;
2089 }
2090
2091 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2092 parent);
2093 if (sequence->length_field_path) {
2094 bt_ctf_field_path_destroy(sequence->length_field_path);
2095 }
2096 sequence->length_field_path = path;
2097 end:
2098 return ret;
2099 }
2100
2101 BT_HIDDEN
2102 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2103 struct bt_ctf_field_path *path)
2104 {
2105 int ret = 0;
2106 struct bt_ctf_field_type_variant *variant;
2107
2108 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2109 ret = -1;
2110 goto end;
2111 }
2112
2113 variant = container_of(type, struct bt_ctf_field_type_variant,
2114 parent);
2115 if (variant->tag_path) {
2116 bt_ctf_field_path_destroy(variant->tag_path);
2117 }
2118 variant->tag_path = path;
2119 end:
2120 return ret;
2121 }
2122
2123 BT_HIDDEN
2124 int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
2125 struct bt_ctf_field_type *tag)
2126 {
2127 int ret = 0;
2128 struct bt_ctf_field_type_variant *variant;
2129
2130 if (!type || !tag || type->frozen ||
2131 bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
2132 ret = -1;
2133 goto end;
2134 }
2135
2136 variant = container_of(type, struct bt_ctf_field_type_variant,
2137 parent);
2138 bt_ctf_field_type_get(tag);
2139 if (variant->tag) {
2140 bt_ctf_field_type_put(&variant->tag->parent);
2141 }
2142 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2143 parent);
2144 end:
2145 return ret;
2146 }
2147
2148 static
2149 void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
2150 {
2151 struct bt_ctf_field_type_integer *integer;
2152
2153 if (!ref) {
2154 return;
2155 }
2156
2157 integer = container_of(
2158 container_of(ref, struct bt_ctf_field_type, ref_count),
2159 struct bt_ctf_field_type_integer, parent);
2160 if (integer->mapped_clock) {
2161 bt_ctf_clock_put(integer->mapped_clock);
2162 }
2163 g_free(integer);
2164 }
2165
2166 static
2167 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
2168 {
2169 struct bt_ctf_field_type_enumeration *enumeration;
2170
2171 if (!ref) {
2172 return;
2173 }
2174
2175 enumeration = container_of(
2176 container_of(ref, struct bt_ctf_field_type, ref_count),
2177 struct bt_ctf_field_type_enumeration, parent);
2178 g_ptr_array_free(enumeration->entries, TRUE);
2179 bt_ctf_field_type_put(enumeration->container);
2180 g_free(enumeration);
2181 }
2182
2183 static
2184 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
2185 {
2186 struct bt_ctf_field_type_floating_point *floating_point;
2187
2188 if (!ref) {
2189 return;
2190 }
2191
2192 floating_point = container_of(
2193 container_of(ref, struct bt_ctf_field_type, ref_count),
2194 struct bt_ctf_field_type_floating_point, parent);
2195 g_free(floating_point);
2196 }
2197
2198 static
2199 void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
2200 {
2201 struct bt_ctf_field_type_structure *structure;
2202
2203 if (!ref) {
2204 return;
2205 }
2206
2207 structure = container_of(
2208 container_of(ref, struct bt_ctf_field_type, ref_count),
2209 struct bt_ctf_field_type_structure, parent);
2210 g_ptr_array_free(structure->fields, TRUE);
2211 g_hash_table_destroy(structure->field_name_to_index);
2212 g_free(structure);
2213 }
2214
2215 static
2216 void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
2217 {
2218 struct bt_ctf_field_type_variant *variant;
2219
2220 if (!ref) {
2221 return;
2222 }
2223
2224 variant = container_of(
2225 container_of(ref, struct bt_ctf_field_type, ref_count),
2226 struct bt_ctf_field_type_variant, parent);
2227 g_ptr_array_free(variant->fields, TRUE);
2228 g_hash_table_destroy(variant->field_name_to_index);
2229 g_string_free(variant->tag_name, TRUE);
2230 bt_ctf_field_type_put(&variant->tag->parent);
2231 bt_ctf_field_path_destroy(variant->tag_path);
2232 g_free(variant);
2233 }
2234
2235 static
2236 void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
2237 {
2238 struct bt_ctf_field_type_array *array;
2239
2240 if (!ref) {
2241 return;
2242 }
2243
2244 array = container_of(
2245 container_of(ref, struct bt_ctf_field_type, ref_count),
2246 struct bt_ctf_field_type_array, parent);
2247 bt_ctf_field_type_put(array->element_type);
2248 g_free(array);
2249 }
2250
2251 static
2252 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
2253 {
2254 struct bt_ctf_field_type_sequence *sequence;
2255
2256 if (!ref) {
2257 return;
2258 }
2259
2260 sequence = container_of(
2261 container_of(ref, struct bt_ctf_field_type, ref_count),
2262 struct bt_ctf_field_type_sequence, parent);
2263 bt_ctf_field_type_put(sequence->element_type);
2264 g_string_free(sequence->length_field_name, TRUE);
2265 bt_ctf_field_path_destroy(sequence->length_field_path);
2266 g_free(sequence);
2267 }
2268
2269 static
2270 void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *ref)
2271 {
2272 struct bt_ctf_field_type_string *string;
2273
2274 if (!ref) {
2275 return;
2276 }
2277
2278 string = container_of(
2279 container_of(ref, struct bt_ctf_field_type, ref_count),
2280 struct bt_ctf_field_type_string, parent);
2281 g_free(string);
2282 }
2283
2284 static
2285 void generic_field_type_freeze(struct bt_ctf_field_type *type)
2286 {
2287 type->frozen = 1;
2288 }
2289
2290 static
2291 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2292 {
2293 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2294 type, struct bt_ctf_field_type_enumeration, parent);
2295
2296 generic_field_type_freeze(type);
2297 bt_ctf_field_type_freeze(enumeration_type->container);
2298 }
2299
2300 static
2301 void freeze_structure_field(struct structure_field *field)
2302 {
2303 bt_ctf_field_type_freeze(field->type);
2304 }
2305
2306 static
2307 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2308 {
2309 struct bt_ctf_field_type_structure *structure_type = container_of(
2310 type, struct bt_ctf_field_type_structure, parent);
2311
2312 generic_field_type_freeze(type);
2313 g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field,
2314 NULL);
2315 }
2316
2317 static
2318 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2319 {
2320 struct bt_ctf_field_type_variant *variant_type = container_of(
2321 type, struct bt_ctf_field_type_variant, parent);
2322
2323 generic_field_type_freeze(type);
2324 g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field,
2325 NULL);
2326 }
2327
2328 static
2329 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2330 {
2331 struct bt_ctf_field_type_array *array_type = container_of(
2332 type, struct bt_ctf_field_type_array, parent);
2333
2334 generic_field_type_freeze(type);
2335 bt_ctf_field_type_freeze(array_type->element_type);
2336 }
2337
2338 static
2339 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2340 {
2341 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2342 type, struct bt_ctf_field_type_sequence, parent);
2343
2344 generic_field_type_freeze(type);
2345 bt_ctf_field_type_freeze(sequence_type->element_type);
2346 }
2347
2348 static
2349 const char *get_encoding_string(enum ctf_string_encoding encoding)
2350 {
2351 const char *encoding_string;
2352
2353 switch (encoding) {
2354 case CTF_STRING_NONE:
2355 encoding_string = "none";
2356 break;
2357 case CTF_STRING_ASCII:
2358 encoding_string = "ASCII";
2359 break;
2360 case CTF_STRING_UTF8:
2361 encoding_string = "UTF8";
2362 break;
2363 default:
2364 encoding_string = "unknown";
2365 break;
2366 }
2367
2368 return encoding_string;
2369 }
2370
2371 static
2372 const char *get_integer_base_string(enum bt_ctf_integer_base base)
2373 {
2374 const char *base_string;
2375
2376 switch (base) {
2377 case BT_CTF_INTEGER_BASE_DECIMAL:
2378 base_string = "decimal";
2379 break;
2380 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2381 base_string = "hexadecimal";
2382 break;
2383 case BT_CTF_INTEGER_BASE_OCTAL:
2384 base_string = "octal";
2385 break;
2386 case BT_CTF_INTEGER_BASE_BINARY:
2387 base_string = "binary";
2388 break;
2389 default:
2390 base_string = "unknown";
2391 break;
2392 }
2393
2394 return base_string;
2395 }
2396
2397 static
2398 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2399 struct metadata_context *context)
2400 {
2401 struct bt_ctf_field_type_integer *integer = container_of(type,
2402 struct bt_ctf_field_type_integer, parent);
2403 int ret = 0;
2404
2405 g_string_append_printf(context->string,
2406 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2407 integer->declaration.len, type->declaration->alignment,
2408 (integer->declaration.signedness ? "true" : "false"),
2409 get_encoding_string(integer->declaration.encoding),
2410 get_integer_base_string(integer->declaration.base),
2411 get_byte_order_string(integer->declaration.byte_order));
2412 if (integer->mapped_clock) {
2413 const char *clock_name = bt_ctf_clock_get_name(
2414 integer->mapped_clock);
2415
2416 if (!clock_name) {
2417 ret = -1;
2418 goto end;
2419 }
2420
2421 g_string_append_printf(context->string,
2422 "; map = clock.%s.value", clock_name);
2423 }
2424
2425 g_string_append(context->string, "; }");
2426 end:
2427 return ret;
2428 }
2429
2430 static
2431 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2432 struct metadata_context *context)
2433 {
2434 size_t entry;
2435 int ret;
2436 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2437 struct bt_ctf_field_type_enumeration, parent);
2438 struct bt_ctf_field_type *container_type;
2439 int container_signed;
2440
2441 ret = bt_ctf_field_type_validate(type);
2442 if (ret) {
2443 goto end;
2444 }
2445
2446 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2447 if (!container_type) {
2448 ret = -1;
2449 goto end;
2450 }
2451
2452 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2453 if (container_signed < 0) {
2454 ret = container_signed;
2455 goto error_put_container_type;
2456 }
2457
2458 g_string_append(context->string, "enum : ");
2459 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2460 if (ret) {
2461 goto error_put_container_type;
2462 }
2463
2464 g_string_append(context->string, " { ");
2465 for (entry = 0; entry < enumeration->entries->len; entry++) {
2466 struct enumeration_mapping *mapping =
2467 enumeration->entries->pdata[entry];
2468
2469 if (container_signed) {
2470 if (mapping->range_start._signed ==
2471 mapping->range_end._signed) {
2472 g_string_append_printf(context->string,
2473 "\"%s\" = %" PRId64,
2474 g_quark_to_string(mapping->string),
2475 mapping->range_start._signed);
2476 } else {
2477 g_string_append_printf(context->string,
2478 "\"%s\" = %" PRId64 " ... %" PRId64,
2479 g_quark_to_string(mapping->string),
2480 mapping->range_start._signed,
2481 mapping->range_end._signed);
2482 }
2483 } else {
2484 if (mapping->range_start._unsigned ==
2485 mapping->range_end._unsigned) {
2486 g_string_append_printf(context->string,
2487 "\"%s\" = %" PRIu64,
2488 g_quark_to_string(mapping->string),
2489 mapping->range_start._unsigned);
2490 } else {
2491 g_string_append_printf(context->string,
2492 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2493 g_quark_to_string(mapping->string),
2494 mapping->range_start._unsigned,
2495 mapping->range_end._unsigned);
2496 }
2497 }
2498
2499 g_string_append(context->string,
2500 ((entry != (enumeration->entries->len - 1)) ?
2501 ", " : " }"));
2502 }
2503
2504 if (context->field_name->len) {
2505 g_string_append_printf(context->string, " %s",
2506 context->field_name->str);
2507 g_string_assign(context->field_name, "");
2508 }
2509 error_put_container_type:
2510 bt_ctf_field_type_put(container_type);
2511 end:
2512 return ret;
2513 }
2514
2515 static
2516 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2517 struct metadata_context *context)
2518 {
2519 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2520 type, struct bt_ctf_field_type_floating_point, parent);
2521
2522 g_string_append_printf(context->string,
2523 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2524 floating_point->declaration.exp->len,
2525 floating_point->declaration.mantissa->len + 1,
2526 get_byte_order_string(floating_point->declaration.byte_order),
2527 type->declaration->alignment);
2528 return 0;
2529 }
2530
2531 static
2532 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2533 struct metadata_context *context)
2534 {
2535 size_t i;
2536 unsigned int indent;
2537 int ret = 0;
2538 struct bt_ctf_field_type_structure *structure = container_of(type,
2539 struct bt_ctf_field_type_structure, parent);
2540 GString *structure_field_name = context->field_name;
2541
2542 context->field_name = g_string_new("");
2543
2544 context->current_indentation_level++;
2545 g_string_append(context->string, "struct {\n");
2546
2547 for (i = 0; i < structure->fields->len; i++) {
2548 struct structure_field *field;
2549
2550 for (indent = 0; indent < context->current_indentation_level;
2551 indent++) {
2552 g_string_append_c(context->string, '\t');
2553 }
2554
2555 field = structure->fields->pdata[i];
2556 g_string_assign(context->field_name,
2557 g_quark_to_string(field->name));
2558 ret = bt_ctf_field_type_serialize(field->type, context);
2559 if (ret) {
2560 goto end;
2561 }
2562
2563 if (context->field_name->len) {
2564 g_string_append_printf(context->string, " %s",
2565 context->field_name->str);
2566 }
2567 g_string_append(context->string, ";\n");
2568 }
2569
2570 context->current_indentation_level--;
2571 for (indent = 0; indent < context->current_indentation_level;
2572 indent++) {
2573 g_string_append_c(context->string, '\t');
2574 }
2575
2576 g_string_append_printf(context->string, "} align(%zu)",
2577 type->declaration->alignment);
2578 end:
2579 g_string_free(context->field_name, TRUE);
2580 context->field_name = structure_field_name;
2581 return ret;
2582 }
2583
2584 static
2585 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2586 struct metadata_context *context)
2587 {
2588 size_t i;
2589 unsigned int indent;
2590 int ret = 0;
2591 struct bt_ctf_field_type_variant *variant = container_of(
2592 type, struct bt_ctf_field_type_variant, parent);
2593 GString *variant_field_name = context->field_name;
2594
2595 context->field_name = g_string_new("");
2596 if (variant->tag_name->len > 0) {
2597 g_string_append_printf(context->string,
2598 "variant <%s> {\n", variant->tag_name->str);
2599 } else {
2600 g_string_append(context->string, "variant {\n");
2601 }
2602
2603 context->current_indentation_level++;
2604 for (i = 0; i < variant->fields->len; i++) {
2605 struct structure_field *field = variant->fields->pdata[i];
2606
2607 g_string_assign(context->field_name,
2608 g_quark_to_string(field->name));
2609 for (indent = 0; indent < context->current_indentation_level;
2610 indent++) {
2611 g_string_append_c(context->string, '\t');
2612 }
2613
2614 g_string_assign(context->field_name,
2615 g_quark_to_string(field->name));
2616 ret = bt_ctf_field_type_serialize(field->type, context);
2617 if (ret) {
2618 goto end;
2619 }
2620
2621 if (context->field_name->len) {
2622 g_string_append_printf(context->string, " %s;",
2623 context->field_name->str);
2624 }
2625
2626 g_string_append_c(context->string, '\n');
2627 }
2628
2629 context->current_indentation_level--;
2630 for (indent = 0; indent < context->current_indentation_level;
2631 indent++) {
2632 g_string_append_c(context->string, '\t');
2633 }
2634
2635 g_string_append(context->string, "}");
2636 end:
2637 g_string_free(context->field_name, TRUE);
2638 context->field_name = variant_field_name;
2639 return ret;
2640 }
2641
2642 static
2643 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2644 struct metadata_context *context)
2645 {
2646 int ret = 0;
2647 struct bt_ctf_field_type_array *array = container_of(type,
2648 struct bt_ctf_field_type_array, parent);
2649
2650 ret = bt_ctf_field_type_serialize(array->element_type, context);
2651 if (ret) {
2652 goto end;
2653 }
2654
2655 if (context->field_name->len) {
2656 g_string_append_printf(context->string, " %s[%u]",
2657 context->field_name->str, array->length);
2658 g_string_assign(context->field_name, "");
2659 } else {
2660 g_string_append_printf(context->string, "[%u]", array->length);
2661 }
2662 end:
2663 return ret;
2664 }
2665
2666 static
2667 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2668 struct metadata_context *context)
2669 {
2670 int ret = 0;
2671 struct bt_ctf_field_type_sequence *sequence = container_of(
2672 type, struct bt_ctf_field_type_sequence, parent);
2673
2674 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2675 if (ret) {
2676 goto end;
2677 }
2678
2679 if (context->field_name->len) {
2680 g_string_append_printf(context->string, " %s[%s]",
2681 context->field_name->str,
2682 sequence->length_field_name->str);
2683 g_string_assign(context->field_name, "");
2684 } else {
2685 g_string_append_printf(context->string, "[%s]",
2686 sequence->length_field_name->str);
2687 }
2688 end:
2689 return ret;
2690 }
2691
2692 static
2693 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2694 struct metadata_context *context)
2695 {
2696 struct bt_ctf_field_type_string *string = container_of(
2697 type, struct bt_ctf_field_type_string, parent);
2698
2699 g_string_append_printf(context->string,
2700 "string { encoding = %s; }",
2701 get_encoding_string(string->declaration.encoding));
2702 return 0;
2703 }
2704
2705 static
2706 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
2707 int byte_order, int set_native)
2708 {
2709 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2710 struct bt_ctf_field_type_integer, parent);
2711
2712 if (set_native) {
2713 integer_type->declaration.byte_order =
2714 integer_type->declaration.byte_order == 0 ?
2715 byte_order : integer_type->declaration.byte_order;
2716 } else {
2717 integer_type->declaration.byte_order = byte_order;
2718 }
2719 }
2720
2721 static
2722 void bt_ctf_field_type_enumeration_set_byte_order(
2723 struct bt_ctf_field_type *type, int byte_order, int set_native)
2724 {
2725 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
2726 struct bt_ctf_field_type_enumeration, parent);
2727
2728 /* Safe to assume that container is an integer */
2729 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
2730 byte_order, set_native);
2731 }
2732
2733 static
2734 void bt_ctf_field_type_floating_point_set_byte_order(
2735 struct bt_ctf_field_type *type, int byte_order, int set_native)
2736 {
2737 struct bt_ctf_field_type_floating_point *floating_point_type =
2738 container_of(type, struct bt_ctf_field_type_floating_point,
2739 parent);
2740
2741 if (set_native) {
2742 floating_point_type->declaration.byte_order =
2743 floating_point_type->declaration.byte_order == 0 ?
2744 byte_order :
2745 floating_point_type->declaration.byte_order;
2746 floating_point_type->sign.byte_order =
2747 floating_point_type->sign.byte_order == 0 ?
2748 byte_order : floating_point_type->sign.byte_order;
2749 floating_point_type->mantissa.byte_order =
2750 floating_point_type->mantissa.byte_order == 0 ?
2751 byte_order : floating_point_type->mantissa.byte_order;
2752 floating_point_type->exp.byte_order =
2753 floating_point_type->exp.byte_order == 0 ?
2754 byte_order : floating_point_type->exp.byte_order;
2755 } else {
2756 floating_point_type->declaration.byte_order = byte_order;
2757 floating_point_type->sign.byte_order = byte_order;
2758 floating_point_type->mantissa.byte_order = byte_order;
2759 floating_point_type->exp.byte_order = byte_order;
2760 }
2761 }
2762
2763 static
2764 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
2765 int byte_order, int set_native)
2766 {
2767 int i;
2768 struct bt_ctf_field_type_structure *structure_type =
2769 container_of(type, struct bt_ctf_field_type_structure,
2770 parent);
2771
2772 for (i = 0; i < structure_type->fields->len; i++) {
2773 struct structure_field *field = g_ptr_array_index(
2774 structure_type->fields, i);
2775 struct bt_ctf_field_type *field_type = field->type;
2776
2777 if (set_byte_order_funcs[field_type->declaration->id]) {
2778 set_byte_order_funcs[field_type->declaration->id](
2779 field_type, byte_order, set_native);
2780 }
2781 }
2782 }
2783
2784 static
2785 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
2786 int byte_order, int set_native)
2787 {
2788 int i;
2789 struct bt_ctf_field_type_variant *variant_type =
2790 container_of(type, struct bt_ctf_field_type_variant,
2791 parent);
2792
2793 for (i = 0; i < variant_type->fields->len; i++) {
2794 struct structure_field *field = g_ptr_array_index(
2795 variant_type->fields, i);
2796 struct bt_ctf_field_type *field_type = field->type;
2797
2798 if (set_byte_order_funcs[field_type->declaration->id]) {
2799 set_byte_order_funcs[field_type->declaration->id](
2800 field_type, byte_order, set_native);
2801 }
2802 }
2803 }
2804
2805 static
2806 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
2807 int byte_order, int set_native)
2808 {
2809 struct bt_ctf_field_type_array *array_type =
2810 container_of(type, struct bt_ctf_field_type_array,
2811 parent);
2812
2813 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
2814 set_byte_order_funcs[array_type->element_type->declaration->id](
2815 array_type->element_type, byte_order, set_native);
2816 }
2817 }
2818
2819 static
2820 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
2821 int byte_order, int set_native)
2822 {
2823 struct bt_ctf_field_type_sequence *sequence_type =
2824 container_of(type, struct bt_ctf_field_type_sequence,
2825 parent);
2826
2827 if (set_byte_order_funcs[
2828 sequence_type->element_type->declaration->id]) {
2829 set_byte_order_funcs[
2830 sequence_type->element_type->declaration->id](
2831 sequence_type->element_type, byte_order, set_native);
2832 }
2833 }
2834
2835 static
2836 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
2837 struct bt_ctf_field_type *type)
2838 {
2839 struct bt_ctf_field_type *copy;
2840 struct bt_ctf_field_type_integer *integer, *copy_integer;
2841
2842 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
2843 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
2844 if (!copy) {
2845 goto end;
2846 }
2847
2848 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
2849 parent);
2850 copy_integer->declaration = integer->declaration;
2851 if (integer->mapped_clock) {
2852 bt_ctf_clock_get(integer->mapped_clock);
2853 copy_integer->mapped_clock = integer->mapped_clock;
2854 }
2855 end:
2856 return copy;
2857 }
2858
2859 static
2860 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
2861 struct bt_ctf_field_type *type)
2862 {
2863 size_t i;
2864 struct bt_ctf_field_type *copy = NULL, *copy_container;
2865 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
2866
2867 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
2868 parent);
2869
2870 /* Copy the source enumeration's container */
2871 copy_container = bt_ctf_field_type_copy(enumeration->container);
2872 if (!copy_container) {
2873 goto end;
2874 }
2875
2876 copy = bt_ctf_field_type_enumeration_create(copy_container);
2877 if (!copy) {
2878 goto end;
2879 }
2880 copy_enumeration = container_of(copy,
2881 struct bt_ctf_field_type_enumeration, parent);
2882
2883 /* Copy all enumaration entries */
2884 for (i = 0; i < enumeration->entries->len; i++) {
2885 struct enumeration_mapping *mapping = g_ptr_array_index(
2886 enumeration->entries, i);
2887 struct enumeration_mapping* copy_mapping = g_new0(
2888 struct enumeration_mapping, 1);
2889
2890 if (!copy_mapping) {
2891 goto error;
2892 }
2893
2894 *copy_mapping = *mapping;
2895 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
2896 }
2897
2898 copy_enumeration->declaration = enumeration->declaration;
2899 end:
2900 if (copy_container) {
2901 bt_ctf_field_type_put(copy_container);
2902 }
2903 return copy;
2904 error:
2905 if (copy_container) {
2906 bt_ctf_field_type_put(copy_container);
2907 }
2908 bt_ctf_field_type_put(copy);
2909 return NULL;
2910 }
2911
2912 static
2913 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
2914 struct bt_ctf_field_type *type)
2915 {
2916 struct bt_ctf_field_type *copy;
2917 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
2918
2919 floating_point = container_of(type,
2920 struct bt_ctf_field_type_floating_point, parent);
2921 copy = bt_ctf_field_type_floating_point_create();
2922 if (!copy) {
2923 goto end;
2924 }
2925
2926 copy_float = container_of(copy,
2927 struct bt_ctf_field_type_floating_point, parent);
2928 copy_float->declaration = floating_point->declaration;
2929 copy_float->sign = floating_point->sign;
2930 copy_float->mantissa = floating_point->mantissa;
2931 copy_float->exp = floating_point->exp;
2932 end:
2933 return copy;
2934 }
2935
2936 static
2937 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
2938 struct bt_ctf_field_type *type)
2939 {
2940 int i;
2941 GHashTableIter iter;
2942 gpointer key, value;
2943 struct bt_ctf_field_type *copy;
2944 struct bt_ctf_field_type_structure *structure, *copy_structure;
2945
2946 structure = container_of(type, struct bt_ctf_field_type_structure,
2947 parent);
2948 copy = bt_ctf_field_type_structure_create();
2949 if (!copy) {
2950 goto end;
2951 }
2952
2953 copy_structure = container_of(copy,
2954 struct bt_ctf_field_type_structure, parent);
2955
2956 /* Copy field_name_to_index */
2957 g_hash_table_iter_init(&iter, structure->field_name_to_index);
2958 while (g_hash_table_iter_next (&iter, &key, &value)) {
2959 g_hash_table_insert(copy_structure->field_name_to_index,
2960 key, value);
2961 }
2962
2963 for (i = 0; i < structure->fields->len; i++) {
2964 struct structure_field *entry, *copy_entry;
2965 struct bt_ctf_field_type *copy_field;
2966
2967 copy_entry = g_new0(struct structure_field, 1);
2968 if (!copy_entry) {
2969 goto error;
2970 }
2971
2972 entry = g_ptr_array_index(structure->fields, i);
2973 copy_field = bt_ctf_field_type_copy(entry->type);
2974 if (!copy_field) {
2975 g_free(copy_entry);
2976 goto error;
2977 }
2978
2979 copy_entry->name = entry->name;
2980 copy_entry->type = copy_field;
2981 g_ptr_array_add(copy_structure->fields, copy_entry);
2982 }
2983
2984 copy_structure->declaration = structure->declaration;
2985 end:
2986 return copy;
2987 error:
2988 bt_ctf_field_type_put(copy);
2989 return NULL;
2990 }
2991
2992 static
2993 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
2994 struct bt_ctf_field_type *type)
2995 {
2996 int i;
2997 GHashTableIter iter;
2998 gpointer key, value;
2999 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3000 struct bt_ctf_field_type_variant *variant, *copy_variant;
3001
3002 variant = container_of(type, struct bt_ctf_field_type_variant,
3003 parent);
3004 if (variant->tag) {
3005 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3006 if (!copy_tag) {
3007 goto end;
3008 }
3009 }
3010
3011 copy = bt_ctf_field_type_variant_create(copy_tag,
3012 variant->tag_name->len ? variant->tag_name->str : NULL);
3013 if (!copy) {
3014 goto end;
3015 }
3016
3017 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3018 parent);
3019
3020 /* Copy field_name_to_index */
3021 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3022 while (g_hash_table_iter_next (&iter, &key, &value)) {
3023 g_hash_table_insert(copy_variant->field_name_to_index,
3024 key, value);
3025 }
3026
3027 for (i = 0; i < variant->fields->len; i++) {
3028 struct structure_field *entry, *copy_entry;
3029 struct bt_ctf_field_type *copy_field;
3030
3031 copy_entry = g_new0(struct structure_field, 1);
3032 if (!copy_entry) {
3033 goto error;
3034 }
3035
3036 entry = g_ptr_array_index(variant->fields, i);
3037 copy_field = bt_ctf_field_type_copy(entry->type);
3038 if (!copy_field) {
3039 g_free(copy_entry);
3040 goto error;
3041 }
3042
3043 copy_entry->name = entry->name;
3044 copy_entry->type = copy_field;
3045 g_ptr_array_add(copy_variant->fields, copy_entry);
3046 }
3047
3048 copy_variant->declaration = variant->declaration;
3049 if (variant->tag_path) {
3050 copy_variant->tag_path = bt_ctf_field_path_copy(
3051 variant->tag_path);
3052 if (!copy_variant->tag_path) {
3053 goto error;
3054 }
3055 }
3056 end:
3057 if (copy_tag) {
3058 bt_ctf_field_type_put(copy_tag);
3059 }
3060
3061 return copy;
3062 error:
3063 if (copy_tag) {
3064 bt_ctf_field_type_put(copy_tag);
3065 }
3066
3067 bt_ctf_field_type_put(copy);
3068 return NULL;
3069 }
3070
3071 static
3072 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3073 struct bt_ctf_field_type *type)
3074 {
3075 struct bt_ctf_field_type *copy = NULL, *copy_element;
3076 struct bt_ctf_field_type_array *array, *copy_array;
3077
3078 array = container_of(type, struct bt_ctf_field_type_array,
3079 parent);
3080 copy_element = bt_ctf_field_type_copy(array->element_type);
3081 if (!copy_element) {
3082 goto end;
3083 }
3084
3085 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3086 if (!copy) {
3087 goto end;
3088 }
3089
3090 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3091 parent);
3092 copy_array->declaration = array->declaration;
3093 end:
3094 if (copy_element) {
3095 bt_ctf_field_type_put(copy_element);
3096 }
3097
3098 return copy;
3099 }
3100
3101 static
3102 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3103 struct bt_ctf_field_type *type)
3104 {
3105 struct bt_ctf_field_type *copy = NULL, *copy_element;
3106 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3107
3108 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3109 parent);
3110 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3111 if (!copy_element) {
3112 goto end;
3113 }
3114
3115 copy = bt_ctf_field_type_sequence_create(copy_element,
3116 sequence->length_field_name->len ?
3117 sequence->length_field_name->str : NULL);
3118 if (!copy) {
3119 goto end;
3120 }
3121
3122 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3123 parent);
3124 copy_sequence->declaration = sequence->declaration;
3125 if (sequence->length_field_path) {
3126 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3127 sequence->length_field_path);
3128 if (!copy_sequence->length_field_path) {
3129 goto error;
3130 }
3131 }
3132 end:
3133 if (copy_element) {
3134 bt_ctf_field_type_put(copy_element);
3135 }
3136
3137 return copy;
3138 error:
3139 if (copy) {
3140 bt_ctf_field_type_put(copy);
3141 copy = NULL;
3142 }
3143 goto end;
3144 }
3145
3146 static
3147 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3148 struct bt_ctf_field_type *type)
3149 {
3150 struct bt_ctf_field_type *copy;
3151 struct bt_ctf_field_type_string *string, *copy_string;
3152
3153 copy = bt_ctf_field_type_string_create();
3154 if (!copy) {
3155 goto end;
3156 }
3157
3158 string = container_of(type, struct bt_ctf_field_type_string,
3159 parent);
3160 copy_string = container_of(type, struct bt_ctf_field_type_string,
3161 parent);
3162 copy_string->declaration = string->declaration;
3163 end:
3164 return copy;
3165 }
This page took 0.141362 seconds and 3 git commands to generate.