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