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