Add Variant and Sequence IR type validation checks
[babeltrace.git] / formats / ctf / ir / event-types.c
CommitLineData
273b65be
JG
1/*
2 * event-types.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Event Types
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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>
adc315b8 30#include <babeltrace/ctf-ir/event-types-internal.h>
654c1444 31#include <babeltrace/ctf-ir/utils.h>
6cfb906f 32#include <babeltrace/ctf-ir/clock.h>
273b65be
JG
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>
a39fa057 38#include <stdlib.h>
273b65be
JG
39
40struct range_overlap_query {
b92ddaaa
JG
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;
273b65be
JG
50 int overlaps;
51 GQuark mapping_name;
52};
53
2f2d8e05
JG
54static
55void bt_ctf_field_type_destroy(struct bt_ctf_ref *);
273b65be
JG
56static
57void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *);
58static
59void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *);
60static
61void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *);
62static
63void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *);
64static
65void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *);
66static
67void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *);
68static
69void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *);
70static
71void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *);
72
73static
74void (* 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
87static
88void generic_field_type_freeze(struct bt_ctf_field_type *);
89static
90void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
91static
92void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
93static
94void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
95static
96void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
97static
98void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
99
100static
101type_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
112static
113int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
114 struct metadata_context *);
115static
116int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
117 struct metadata_context *);
118static
119int bt_ctf_field_type_floating_point_serialize(
120 struct bt_ctf_field_type *, struct metadata_context *);
121static
122int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
123 struct metadata_context *);
124static
125int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
126 struct metadata_context *);
127static
128int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
129 struct metadata_context *);
130static
131int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
132 struct metadata_context *);
133static
134int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
135 struct metadata_context *);
136
137static
138type_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
152static
153void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
c35a1669
JG
154 int byte_order, int set_native);
155static
156void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
157 int byte_order, int set_native);
273b65be
JG
158static
159void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669
JG
160 struct bt_ctf_field_type *, int byte_order, int set_native);
161static
162void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
163 int byte_order, int set_native);
164static
165void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
166 int byte_order, int set_native);
167static
168void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
169 int byte_order, int set_native);
170static
171void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
172 int byte_order, int set_native);
273b65be 173
c35a1669 174/* The set_native flag only set the byte order if it is set to native */
273b65be
JG
175static
176void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
c35a1669
JG
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,
273b65be
JG
181 [CTF_TYPE_FLOAT] =
182 bt_ctf_field_type_floating_point_set_byte_order,
c35a1669
JG
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,
273b65be
JG
189};
190
24724933
JG
191static
192struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
193 struct bt_ctf_field_type *);
194static
195struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
196 struct bt_ctf_field_type *);
197static
198struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
199 struct bt_ctf_field_type *);
200static
201struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
202 struct bt_ctf_field_type *);
203static
204struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
205 struct bt_ctf_field_type *);
206static
207struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
208 struct bt_ctf_field_type *);
209static
210struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
211 struct bt_ctf_field_type *);
212static
213struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
214 struct bt_ctf_field_type *);
215
216static
217struct 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
273b65be
JG
229static
230void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
231{
232 g_free(mapping);
233}
234
235static
236void 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
245static
246void check_ranges_overlap(gpointer element, gpointer query)
247{
248 struct enumeration_mapping *mapping = element;
249 struct range_overlap_query *overlap_query = query;
250
b92ddaaa
JG
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
262static
263void 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) {
273b65be
JG
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
b92ddaaa
JG
279static
280gint 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
286static
287gint 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
273b65be
JG
293static
294void bt_ctf_field_type_init(struct bt_ctf_field_type *type)
295{
296 enum ctf_type_id type_id = type->declaration->id;
c4e511df 297 int ret;
273b65be
JG
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];
c4e511df
MD
305 ret = bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_NATIVE);
306 assert(!ret);
273b65be
JG
307 type->declaration->alignment = 1;
308}
309
310static
311int 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 */
fe0fe95c
JG
321 if (g_hash_table_lookup_extended(field_name_to_index,
322 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
273b65be
JG
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);
273b65be
JG
340end:
341 return ret;
342}
343
2f2d8e05
JG
344static
345void 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
2f2d8e05
JG
361 type_destroy_funcs[type_id](ref);
362}
363
9ce21c30
JG
364BT_HIDDEN
365int 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
5d161ecc
JG
374 switch (type->declaration->id) {
375 case CTF_TYPE_ENUM:
376 {
9ce21c30
JG
377 struct bt_ctf_field_type_enumeration *enumeration =
378 container_of(type, struct bt_ctf_field_type_enumeration,
379 parent);
380
5d161ecc 381 /* Ensure enum has entries */
9ce21c30 382 ret = enumeration->entries->len ? 0 : -1;
5d161ecc
JG
383 break;
384 }
c6c0ca42
JG
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 }
5d161ecc
JG
406 default:
407 break;
9ce21c30
JG
408 }
409end:
410 return ret;
411}
412
273b65be
JG
413struct 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
1f02e293 418 if (!integer || size == 0 || size > 64) {
273b65be
JG
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
b92ddaaa
JG
431int 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;
443end:
444 return ret;
445}
446
447int 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;
459end:
460 return ret;
461}
462
273b65be
JG
463int 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);
273b65be
JG
476 integer->declaration.signedness = !!is_signed;
477end:
478 return ret;
479}
480
b92ddaaa
JG
481enum 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;
493end:
494 return ret;
495}
496
273b65be
JG
497int 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 }
522end:
523 return ret;
524}
525
b92ddaaa
JG
526enum 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;
538end:
539 return ret;
540}
541
273b65be
JG
542int 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;
558end:
559 return ret;
560}
561
6cfb906f
JG
562struct 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 }
577end:
578 return clock;
579}
580
581int 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;
603end:
604 return ret;
605}
606
273b65be
JG
607struct 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
2a610bb7
JG
616 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
617 goto error;
618 }
619
273b65be
JG
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;
633error:
634 g_free(enumeration);
635 return NULL;
636}
637
b92ddaaa
JG
638struct 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);
656end:
657 return container_type;
658}
659
273b65be
JG
660int 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;
a39fa057 669 char *escaped_string;
273b65be
JG
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
a39fa057 678 if (!string || strlen(string) == 0) {
273b65be
JG
679 ret = -1;
680 goto end;
681 }
682
a39fa057
JG
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);
b92ddaaa
JG
690 query = (struct range_overlap_query) {
691 .range_start._signed = range_start,
692 .range_end._signed = range_end,
273b65be
JG
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;
a39fa057 702 goto error_free;
273b65be
JG
703 }
704
705 mapping = g_new(struct enumeration_mapping, 1);
706 if (!mapping) {
707 ret = -1;
a39fa057 708 goto error_free;
273b65be
JG
709 }
710
b92ddaaa
JG
711 *mapping = (struct enumeration_mapping) {
712 .range_start._signed = range_start,
713 .range_end._signed = range_end, .string = mapping_name};
273b65be 714 g_ptr_array_add(enumeration->entries, mapping);
b92ddaaa
JG
715 g_ptr_array_sort(enumeration->entries,
716 (GCompareFunc)compare_enumeration_mappings_signed);
717error_free:
718 free(escaped_string);
719end:
720 return ret;
721}
722
723int 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);
a39fa057
JG
781error_free:
782 free(escaped_string);
273b65be
JG
783end:
784 return ret;
785}
786
e5958c30
JG
787const 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) {
b92ddaaa
JG
794 .range_start._unsigned = value,
795 .range_end._unsigned = value,
e5958c30
JG
796 .overlaps = 0 };
797
b92ddaaa
JG
798 g_ptr_array_foreach(enumeration_type->entries,
799 check_ranges_overlap_unsigned,
e5958c30
JG
800 &query);
801 if (!query.overlaps) {
802 goto end;
803 }
804
805 name = g_quark_to_string(query.mapping_name);
806end:
807 return name;
808}
809
810const 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) {
b92ddaaa
JG
817 .range_start._signed = value,
818 .range_end._signed = value,
e5958c30
JG
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);
828end:
829 return name;
830}
831
074ee56d 832int bt_ctf_field_type_enumeration_get_mapping_count(
b92ddaaa
JG
833 struct bt_ctf_field_type *type)
834{
074ee56d 835 int ret = 0;
b92ddaaa
JG
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);
074ee56d 845 ret = (int) enumeration->entries->len;
b92ddaaa
JG
846end:
847 return ret;
848}
849
850static inline
851struct enumeration_mapping *get_enumeration_mapping(
074ee56d 852 struct bt_ctf_field_type *type, int index)
b92ddaaa
JG
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);
864end:
865 return mapping;
866}
867
868int bt_ctf_field_type_enumeration_get_mapping(
074ee56d 869 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
870 const char **string, int64_t *range_start, int64_t *range_end)
871{
872 struct enumeration_mapping *mapping;
873 int ret = 0;
874
074ee56d 875 if (!type || index < 0 || !string || !range_start || !range_end ||
b92ddaaa
JG
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;
890end:
891 return ret;
892}
893
894int bt_ctf_field_type_enumeration_get_mapping_unsigned(
074ee56d 895 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
896 const char **string, uint64_t *range_start, uint64_t *range_end)
897{
898 struct enumeration_mapping *mapping;
899 int ret = 0;
900
074ee56d 901 if (!type || index < 0 || !string || !range_start || !range_end ||
b92ddaaa
JG
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;
916end:
917 return ret;
918}
919
920int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
074ee56d 921 struct bt_ctf_field_type *type, const char *name)
b92ddaaa 922{
b92ddaaa
JG
923 GQuark name_quark;
924 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 925 int i, ret = 0;
b92ddaaa 926
074ee56d 927 if (!type || !name ||
b92ddaaa
JG
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) {
074ee56d 946 ret = i;
b92ddaaa
JG
947 goto end;
948 }
949 }
950
951 ret = -1;
952end:
953 return ret;
954}
955
956int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
074ee56d 957 struct bt_ctf_field_type *type, int64_t value)
b92ddaaa
JG
958{
959 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 960 int i, ret = 0;
b92ddaaa 961
074ee56d 962 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
b92ddaaa
JG
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) {
074ee56d 975 ret = i;
b92ddaaa
JG
976 goto end;
977 }
978 }
979
980 ret = -1;
981end:
982 return ret;
983}
984
985int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
074ee56d 986 struct bt_ctf_field_type *type, uint64_t value)
b92ddaaa
JG
987{
988 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 989 int i, ret = 0;
b92ddaaa 990
074ee56d 991 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
b92ddaaa
JG
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) {
074ee56d 1004 ret = i;
b92ddaaa
JG
1005 goto end;
1006 }
1007 }
1008
1009 ret = -1;
1010end:
1011 return ret;
1012}
1013
273b65be
JG
1014struct 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);
1037end:
1038 return floating_point ? &floating_point->parent : NULL;
1039}
1040
b92ddaaa
JG
1041int 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;
1055end:
1056 return ret;
1057}
1058
273b65be
JG
1059int 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;
1083end:
1084 return ret;
1085}
1086
b92ddaaa
JG
1087int 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;
1101end:
1102 return ret;
1103}
1104
273b65be
JG
1105int 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;
1129end:
1130 return ret;
1131}
1132
1133struct 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;
273b65be
JG
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);
c35a1669 1147 bt_ctf_field_type_init(&structure->parent);
273b65be
JG
1148 return &structure->parent;
1149error:
1150 return NULL;
1151}
1152
1153int 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 ||
654c1444 1161 bt_ctf_validate_identifier(field_name) ||
9ce21c30
JG
1162 (type->declaration->id != CTF_TYPE_STRUCT) ||
1163 bt_ctf_field_type_validate(field_type)) {
e6235f1f 1164 ret = -1;
273b65be
JG
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
b92ddaaa
JG
1176 if (type->declaration->alignment < field_type->declaration->alignment) {
1177 type->declaration->alignment =
1178 field_type->declaration->alignment;
1179 }
1180end:
1181 return ret;
1182}
1183
074ee56d 1184int bt_ctf_field_type_structure_get_field_count(
b92ddaaa
JG
1185 struct bt_ctf_field_type *type)
1186{
074ee56d 1187 int ret = 0;
b92ddaaa
JG
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);
074ee56d 1197 ret = (int) structure->fields->len;
b92ddaaa
JG
1198end:
1199 return ret;
1200}
1201
1202int 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,
074ee56d 1204 int index)
b92ddaaa
JG
1205{
1206 struct bt_ctf_field_type_structure *structure;
1207 struct structure_field *field;
1208 int ret = 0;
1209
074ee56d 1210 if (!type || index < 0 || !field_name || !field_type ||
b92ddaaa
JG
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);
1227end:
1228 return ret;
1229}
1230
1231struct 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;
273b65be 1255 }
b92ddaaa
JG
1256
1257 field = structure->fields->pdata[index];
1258 field_type = field->type;
1259 bt_ctf_field_type_get(field_type);
273b65be 1260end:
b92ddaaa 1261 return field_type;
273b65be
JG
1262}
1263
1264struct 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
6964b7fd 1269 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
273b65be
JG
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);
273b65be
JG
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);
6964b7fd
JG
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
c35a1669 1290 bt_ctf_field_type_init(&variant->parent);
273b65be
JG
1291 return &variant->parent;
1292error:
1293 return NULL;
1294}
1295
b92ddaaa
JG
1296struct 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);
6964b7fd
JG
1307 if (!variant->tag) {
1308 goto end;
1309 }
1310
b92ddaaa
JG
1311 tag_type = &variant->tag->parent;
1312 bt_ctf_field_type_get(tag_type);
1313end:
1314 return tag_type;
1315}
1316
1317const 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);
6964b7fd
JG
1328 if (variant->tag_name->len == 0) {
1329 goto end;
1330 }
1331
b92ddaaa
JG
1332 tag_name = variant->tag_name->str;
1333end:
1334 return tag_name;
1335}
1336
273b65be
JG
1337int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1338 struct bt_ctf_field_type *field_type,
1339 const char *field_name)
1340{
1341 size_t i;
1342 int ret = 0;
273b65be
JG
1343 struct bt_ctf_field_type_variant *variant;
1344 GQuark field_name_quark = g_quark_from_string(field_name);
1345
1346 if (!type || !field_type || type->frozen ||
654c1444 1347 bt_ctf_validate_identifier(field_name) ||
9ce21c30
JG
1348 (type->declaration->id != CTF_TYPE_VARIANT) ||
1349 bt_ctf_field_type_validate(field_type)) {
273b65be
JG
1350 ret = -1;
1351 goto end;
1352 }
1353
1354 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
273b65be 1355
6964b7fd
JG
1356 /* The user has explicitly provided a tag; validate against it. */
1357 if (variant->tag) {
1358 int name_found = 0;
1359
1360 /* Make sure this name is present in the enum tag */
1361 for (i = 0; i < variant->tag->entries->len; i++) {
1362 struct enumeration_mapping *mapping =
1363 g_ptr_array_index(variant->tag->entries, i);
1364
1365 if (mapping->string == field_name_quark) {
1366 name_found = 1;
1367 break;
1368 }
1369 }
1370
1371 if (!name_found) {
1372 /* Validation failed */
1373 ret = -1;
1374 goto end;
273b65be
JG
1375 }
1376 }
1377
6964b7fd
JG
1378 if (add_structure_field(variant->fields, variant->field_name_to_index,
1379 field_type, field_name)) {
273b65be
JG
1380 ret = -1;
1381 goto end;
1382 }
1383end:
1384 return ret;
1385}
1386
b92ddaaa
JG
1387struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1388 struct bt_ctf_field_type *type,
1389 const char *field_name)
1390{
1391 size_t index;
1392 GQuark name_quark;
1393 struct structure_field *field;
1394 struct bt_ctf_field_type_variant *variant;
1395 struct bt_ctf_field_type *field_type = NULL;
1396
1397 if (!type || !field_name) {
1398 goto end;
1399 }
1400
1401 name_quark = g_quark_try_string(field_name);
1402 if (!name_quark) {
1403 goto end;
1404 }
1405
1406 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1407 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1408 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1409 goto end;
1410 }
1411
1412 field = g_ptr_array_index(variant->fields, index);
1413 field_type = field->type;
1414 bt_ctf_field_type_get(field_type);
1415end:
1416 return field_type;
1417}
1418
1419struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1420 struct bt_ctf_field_type *type,
1421 struct bt_ctf_field *tag)
1422{
1423 const char *enum_value;
1424 struct bt_ctf_field_type *field_type = NULL;
1425
1426 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1427 goto end;
1428 }
1429
1430 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1431 if (!enum_value) {
1432 goto end;
1433 }
1434
1435 /* Already increments field_type's reference count */
1436 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1437 type, enum_value);
1438end:
1439 return field_type;
1440}
1441
074ee56d 1442int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
b92ddaaa 1443{
074ee56d 1444 int ret = 0;
b92ddaaa
JG
1445 struct bt_ctf_field_type_variant *variant;
1446
1447 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1448 ret = -1;
1449 goto end;
1450 }
1451
1452 variant = container_of(type, struct bt_ctf_field_type_variant,
1453 parent);
074ee56d 1454 ret = (int) variant->fields->len;
b92ddaaa
JG
1455end:
1456 return ret;
1457
1458}
1459
1460int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1461 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 1462 int index)
b92ddaaa
JG
1463{
1464 struct bt_ctf_field_type_variant *variant;
1465 struct structure_field *field;
1466 int ret = 0;
1467
074ee56d 1468 if (!type || index < 0 || !field_name || !field_type ||
b92ddaaa
JG
1469 (type->declaration->id != CTF_TYPE_VARIANT)) {
1470 ret = -1;
1471 goto end;
1472 }
1473
1474 variant = container_of(type, struct bt_ctf_field_type_variant,
1475 parent);
1476 if (index >= variant->fields->len) {
1477 ret = -1;
1478 goto end;
1479 }
1480
1481 field = g_ptr_array_index(variant->fields, index);
1482 *field_type = field->type;
1483 bt_ctf_field_type_get(field->type);
1484 *field_name = g_quark_to_string(field->name);
1485end:
1486 return ret;
1487}
1488
273b65be
JG
1489struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1490 struct bt_ctf_field_type *element_type,
1491 unsigned int length)
1492{
1493 struct bt_ctf_field_type_array *array = NULL;
1494
9ce21c30
JG
1495 if (!element_type || length == 0 ||
1496 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1497 goto error;
1498 }
1499
1500 array = g_new0(struct bt_ctf_field_type_array, 1);
1501 if (!array) {
1502 goto error;
1503 }
1504
1505 array->parent.declaration = &array->declaration.p;
1506 array->parent.declaration->id = CTF_TYPE_ARRAY;
c35a1669 1507
273b65be
JG
1508 bt_ctf_field_type_get(element_type);
1509 array->element_type = element_type;
1510 array->length = length;
c35a1669 1511 bt_ctf_field_type_init(&array->parent);
273b65be
JG
1512 array->parent.declaration->alignment =
1513 element_type->declaration->alignment;
1514 return &array->parent;
1515error:
1516 return NULL;
1517}
1518
b92ddaaa
JG
1519struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1520 struct bt_ctf_field_type *type)
1521{
1522 struct bt_ctf_field_type *ret = NULL;
1523 struct bt_ctf_field_type_array *array;
1524
1525 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1526 goto end;
1527 }
1528
1529 array = container_of(type, struct bt_ctf_field_type_array, parent);
1530 ret = array->element_type;
1531 bt_ctf_field_type_get(ret);
1532end:
1533 return ret;
1534}
1535
1536int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1537{
1538 int64_t ret;
1539 struct bt_ctf_field_type_array *array;
1540
1541 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1542 ret = -1;
1543 goto end;
1544 }
1545
1546 array = container_of(type, struct bt_ctf_field_type_array, parent);
1547 ret = (int64_t) array->length;
1548end:
1549 return ret;
1550}
1551
273b65be
JG
1552struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1553 struct bt_ctf_field_type *element_type,
1554 const char *length_field_name)
1555{
1556 struct bt_ctf_field_type_sequence *sequence = NULL;
1557
654c1444 1558 if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
9ce21c30 1559 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1560 goto error;
1561 }
1562
1563 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1564 if (!sequence) {
1565 goto error;
1566 }
1567
1568 sequence->parent.declaration = &sequence->declaration.p;
1569 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
273b65be
JG
1570 bt_ctf_field_type_get(element_type);
1571 sequence->element_type = element_type;
1572 sequence->length_field_name = g_string_new(length_field_name);
c35a1669 1573 bt_ctf_field_type_init(&sequence->parent);
273b65be
JG
1574 sequence->parent.declaration->alignment =
1575 element_type->declaration->alignment;
1576 return &sequence->parent;
1577error:
1578 return NULL;
1579}
1580
b92ddaaa
JG
1581struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1582 struct bt_ctf_field_type *type)
1583{
1584 struct bt_ctf_field_type *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->element_type;
1594 bt_ctf_field_type_get(ret);
1595end:
1596 return ret;
1597}
1598
1599const char *bt_ctf_field_type_sequence_get_length_field_name(
1600 struct bt_ctf_field_type *type)
1601{
1602 const char *ret = NULL;
1603 struct bt_ctf_field_type_sequence *sequence;
1604
1605 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1606 goto end;
1607 }
1608
1609 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1610 parent);
1611 ret = sequence->length_field_name->str;
1612end:
1613 return ret;
1614}
1615
273b65be
JG
1616struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1617{
1618 struct bt_ctf_field_type_string *string =
1619 g_new0(struct bt_ctf_field_type_string, 1);
1620
1621 if (!string) {
1622 return NULL;
1623 }
1624
1625 string->parent.declaration = &string->declaration.p;
1626 string->parent.declaration->id = CTF_TYPE_STRING;
1627 bt_ctf_field_type_init(&string->parent);
1628 string->declaration.encoding = CTF_STRING_UTF8;
1629 string->parent.declaration->alignment = CHAR_BIT;
1630 return &string->parent;
1631}
1632
b92ddaaa
JG
1633enum ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1634 struct bt_ctf_field_type *type)
1635{
1636 struct bt_ctf_field_type_string *string;
1637 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
1638
1639 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1640 goto end;
1641 }
1642
1643 string = container_of(type, struct bt_ctf_field_type_string,
1644 parent);
1645 ret = string->declaration.encoding;
1646end:
1647 return ret;
1648}
1649
1650int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
273b65be
JG
1651 enum ctf_string_encoding encoding)
1652{
1653 int ret = 0;
1654 struct bt_ctf_field_type_string *string;
1655
1656 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1657 (encoding != CTF_STRING_UTF8 &&
1658 encoding != CTF_STRING_ASCII)) {
1659 ret = -1;
1660 goto end;
1661 }
1662
1663 string = container_of(type, struct bt_ctf_field_type_string, parent);
1664 string->declaration.encoding = encoding;
1665end:
1666 return ret;
1667}
1668
b92ddaaa
JG
1669int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1670{
1671 int ret;
1672
1673 if (!type) {
1674 ret = -1;
1675 goto end;
1676 }
1677
1678 ret = (int) type->declaration->alignment;
1679end:
1680 return ret;
1681}
1682
273b65be
JG
1683int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
1684 unsigned int alignment)
1685{
1686 int ret = 0;
1687
1688 /* Alignment must be bit-aligned (1) or byte aligned */
1689 if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
1690 ret = -1;
1691 goto end;
1692 }
1693
1694 if (type->declaration->id == CTF_TYPE_STRING &&
1695 alignment != CHAR_BIT) {
1696 ret = -1;
1697 goto end;
1698 }
1699
1700 type->declaration->alignment = alignment;
1701 ret = 0;
1702end:
1703 return ret;
1704}
1705
b92ddaaa
JG
1706enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1707 struct bt_ctf_field_type *type)
1708{
1709 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
c35a1669 1710 int internal_byte_order = -1;
b92ddaaa
JG
1711
1712 if (!type) {
1713 goto end;
1714 }
1715
1716 switch (type->declaration->id) {
1717 case CTF_TYPE_INTEGER:
1718 {
1719 struct bt_ctf_field_type_integer *integer = container_of(
1720 type, struct bt_ctf_field_type_integer, parent);
c35a1669 1721 internal_byte_order = integer->declaration.byte_order;
b92ddaaa
JG
1722 break;
1723 }
1724 case CTF_TYPE_FLOAT:
1725 {
1726 struct bt_ctf_field_type_floating_point *floating_point =
1727 container_of(type,
1728 struct bt_ctf_field_type_floating_point,
1729 parent);
c35a1669 1730 internal_byte_order = floating_point->declaration.byte_order;
b92ddaaa
JG
1731 break;
1732 }
1733 default:
c35a1669
JG
1734 goto end;
1735 }
1736
1737 switch (internal_byte_order) {
1738 case LITTLE_ENDIAN:
1739 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
b92ddaaa 1740 break;
c35a1669
JG
1741 case BIG_ENDIAN:
1742 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1743 break;
1744 case 0:
1745 ret = BT_CTF_BYTE_ORDER_NATIVE;
1746 break;
1747 default:
1748 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
b92ddaaa
JG
1749 }
1750end:
1751 return ret;
1752}
1753
273b65be
JG
1754int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
1755 enum bt_ctf_byte_order byte_order)
1756{
1757 int ret = 0;
1758 int internal_byte_order;
1759 enum ctf_type_id type_id;
1760
1761 if (!type || type->frozen) {
1762 ret = -1;
1763 goto end;
1764 }
1765
1766 type_id = type->declaration->id;
1767 switch (byte_order) {
1768 case BT_CTF_BYTE_ORDER_NATIVE:
c35a1669
JG
1769 /* Leave unset. Will be initialized by parent. */
1770 internal_byte_order = 0;
273b65be
JG
1771 break;
1772 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
1773 internal_byte_order = LITTLE_ENDIAN;
1774 break;
1775 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
1776 case BT_CTF_BYTE_ORDER_NETWORK:
1777 internal_byte_order = BIG_ENDIAN;
1778 break;
1779 default:
1780 ret = -1;
1781 goto end;
1782 }
1783
1784 if (set_byte_order_funcs[type_id]) {
c35a1669 1785 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
273b65be
JG
1786 }
1787end:
1788 return ret;
1789}
1790
b92ddaaa
JG
1791enum ctf_type_id bt_ctf_field_type_get_type_id(
1792 struct bt_ctf_field_type *type)
1793{
1794 if (!type) {
1795 return CTF_TYPE_UNKNOWN;
1796 }
1797
1798 return type->declaration->id;
1799}
2f2d8e05 1800
273b65be
JG
1801void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
1802{
1803 if (!type) {
1804 return;
1805 }
1806
1807 bt_ctf_ref_get(&type->ref_count);
1808}
1809
1810void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
1811{
273b65be
JG
1812 if (!type) {
1813 return;
1814 }
1815
2f2d8e05 1816 bt_ctf_ref_put(&type->ref_count, bt_ctf_field_type_destroy);
273b65be
JG
1817}
1818
1819BT_HIDDEN
1820void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
1821{
1822 if (!type) {
1823 return;
1824 }
1825
1826 type->freeze(type);
1827}
1828
1829BT_HIDDEN
b92ddaaa
JG
1830struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
1831 struct bt_ctf_field_type_variant *variant,
1832 int64_t tag_value)
273b65be
JG
1833{
1834 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
1835 GQuark field_name_quark;
1836 gpointer index;
1837 struct structure_field *field_entry;
1838 struct range_overlap_query query = {
1839 .range_start._signed = tag_value,
1840 .range_end._signed = tag_value,
1841 .mapping_name = 0, .overlaps = 0};
273b65be 1842
b92ddaaa
JG
1843 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
1844 &query);
1845 if (!query.overlaps) {
273b65be
JG
1846 goto end;
1847 }
1848
b92ddaaa
JG
1849 field_name_quark = query.mapping_name;
1850 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1851 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
273b65be
JG
1852 goto end;
1853 }
1854
e54fab7e 1855 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
b92ddaaa 1856 type = field_entry->type;
273b65be
JG
1857end:
1858 return type;
1859}
1860
1861BT_HIDDEN
b92ddaaa 1862struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 1863 struct bt_ctf_field_type_variant *variant,
b92ddaaa 1864 uint64_t tag_value)
273b65be
JG
1865{
1866 struct bt_ctf_field_type *type = NULL;
1867 GQuark field_name_quark;
1868 gpointer index;
1869 struct structure_field *field_entry;
b92ddaaa
JG
1870 struct range_overlap_query query = {
1871 .range_start._unsigned = tag_value,
1872 .range_end._unsigned = tag_value,
1873 .mapping_name = 0, .overlaps = 0};
273b65be 1874
b92ddaaa
JG
1875 g_ptr_array_foreach(variant->tag->entries,
1876 check_ranges_overlap_unsigned,
273b65be
JG
1877 &query);
1878 if (!query.overlaps) {
1879 goto end;
1880 }
1881
1882 field_name_quark = query.mapping_name;
1883 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1884 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
1885 goto end;
1886 }
1887
1888 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
1889 type = field_entry->type;
1890end:
1891 return type;
1892}
1893
1894BT_HIDDEN
1895int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
1896 struct metadata_context *context)
1897{
1898 int ret;
1899
1900 if (!type || !context) {
1901 ret = -1;
1902 goto end;
1903 }
1904
1905 ret = type->serialize(type, context);
1906end:
1907 return ret;
1908}
1909
c35a1669
JG
1910BT_HIDDEN
1911void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
1912 int byte_order)
1913{
1914 if (!type) {
1915 return;
1916 }
1917
1918 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
1919 if (set_byte_order_funcs[type->declaration->id]) {
1920 set_byte_order_funcs[type->declaration->id](type,
1921 byte_order, 1);
1922 }
1923}
1924
24724933
JG
1925BT_HIDDEN
1926struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
1927{
1928 struct bt_ctf_field_type *copy = NULL;
1929
1930 if (!type) {
1931 goto end;
1932 }
1933
1934 copy = type_copy_funcs[type->declaration->id](type);
1935end:
1936 return copy;
1937}
1938
273b65be
JG
1939static
1940void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
1941{
1942 struct bt_ctf_field_type_integer *integer;
1943
1944 if (!ref) {
1945 return;
1946 }
1947
1948 integer = container_of(
1949 container_of(ref, struct bt_ctf_field_type, ref_count),
1950 struct bt_ctf_field_type_integer, parent);
eee752e5
JG
1951 if (integer->mapped_clock) {
1952 bt_ctf_clock_put(integer->mapped_clock);
1953 }
273b65be
JG
1954 g_free(integer);
1955}
1956
1957static
1958void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
1959{
1960 struct bt_ctf_field_type_enumeration *enumeration;
1961
1962 if (!ref) {
1963 return;
1964 }
1965
1966 enumeration = container_of(
1967 container_of(ref, struct bt_ctf_field_type, ref_count),
1968 struct bt_ctf_field_type_enumeration, parent);
1969 g_ptr_array_free(enumeration->entries, TRUE);
1970 bt_ctf_field_type_put(enumeration->container);
1971 g_free(enumeration);
1972}
1973
1974static
1975void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
1976{
1977 struct bt_ctf_field_type_floating_point *floating_point;
1978
1979 if (!ref) {
1980 return;
1981 }
1982
1983 floating_point = container_of(
1984 container_of(ref, struct bt_ctf_field_type, ref_count),
1985 struct bt_ctf_field_type_floating_point, parent);
1986 g_free(floating_point);
1987}
1988
1989static
1990void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
1991{
1992 struct bt_ctf_field_type_structure *structure;
1993
1994 if (!ref) {
1995 return;
1996 }
1997
1998 structure = container_of(
1999 container_of(ref, struct bt_ctf_field_type, ref_count),
2000 struct bt_ctf_field_type_structure, parent);
2001 g_ptr_array_free(structure->fields, TRUE);
2002 g_hash_table_destroy(structure->field_name_to_index);
2003 g_free(structure);
2004}
2005
2006static
2007void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
2008{
2009 struct bt_ctf_field_type_variant *variant;
2010
2011 if (!ref) {
2012 return;
2013 }
2014
2015 variant = container_of(
2016 container_of(ref, struct bt_ctf_field_type, ref_count),
2017 struct bt_ctf_field_type_variant, parent);
2018 g_ptr_array_free(variant->fields, TRUE);
2019 g_hash_table_destroy(variant->field_name_to_index);
2020 g_string_free(variant->tag_name, TRUE);
2021 bt_ctf_field_type_put(&variant->tag->parent);
2022 g_free(variant);
2023}
2024
2025static
2026void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
2027{
2028 struct bt_ctf_field_type_array *array;
2029
2030 if (!ref) {
2031 return;
2032 }
2033
2034 array = container_of(
2035 container_of(ref, struct bt_ctf_field_type, ref_count),
2036 struct bt_ctf_field_type_array, parent);
2037 bt_ctf_field_type_put(array->element_type);
2038 g_free(array);
2039}
2040
2041static
2042void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
2043{
2044 struct bt_ctf_field_type_sequence *sequence;
2045
2046 if (!ref) {
2047 return;
2048 }
2049
2050 sequence = container_of(
2051 container_of(ref, struct bt_ctf_field_type, ref_count),
2052 struct bt_ctf_field_type_sequence, parent);
2053 bt_ctf_field_type_put(sequence->element_type);
2054 g_string_free(sequence->length_field_name, TRUE);
2055 g_free(sequence);
2056}
2057
2058static
2059void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *ref)
2060{
2061 struct bt_ctf_field_type_string *string;
2062
2063 if (!ref) {
2064 return;
2065 }
2066
2067 string = container_of(
2068 container_of(ref, struct bt_ctf_field_type, ref_count),
2069 struct bt_ctf_field_type_string, parent);
2070 g_free(string);
2071}
2072
2073static
2074void generic_field_type_freeze(struct bt_ctf_field_type *type)
2075{
2076 type->frozen = 1;
2077}
2078
2079static
2080void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2081{
2082 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2083 type, struct bt_ctf_field_type_enumeration, parent);
2084
2085 generic_field_type_freeze(type);
2086 bt_ctf_field_type_freeze(enumeration_type->container);
2087}
2088
2089static
2090void freeze_structure_field(struct structure_field *field)
2091{
2092 bt_ctf_field_type_freeze(field->type);
2093}
2094
2095static
2096void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2097{
2098 struct bt_ctf_field_type_structure *structure_type = container_of(
2099 type, struct bt_ctf_field_type_structure, parent);
2100
2101 generic_field_type_freeze(type);
2102 g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field,
2103 NULL);
2104}
2105
2106static
2107void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2108{
2109 struct bt_ctf_field_type_variant *variant_type = container_of(
2110 type, struct bt_ctf_field_type_variant, parent);
2111
2112 generic_field_type_freeze(type);
2113 g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field,
2114 NULL);
2115}
2116
2117static
2118void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2119{
2120 struct bt_ctf_field_type_array *array_type = container_of(
2121 type, struct bt_ctf_field_type_array, parent);
2122
2123 generic_field_type_freeze(type);
2124 bt_ctf_field_type_freeze(array_type->element_type);
2125}
2126
2127static
2128void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2129{
2130 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2131 type, struct bt_ctf_field_type_sequence, parent);
2132
2133 generic_field_type_freeze(type);
2134 bt_ctf_field_type_freeze(sequence_type->element_type);
2135}
2136
2137static
2138const char *get_encoding_string(enum ctf_string_encoding encoding)
2139{
2140 const char *encoding_string;
2141
2142 switch (encoding) {
2143 case CTF_STRING_NONE:
2144 encoding_string = "none";
2145 break;
2146 case CTF_STRING_ASCII:
2147 encoding_string = "ASCII";
2148 break;
2149 case CTF_STRING_UTF8:
2150 encoding_string = "UTF8";
2151 break;
2152 default:
2153 encoding_string = "unknown";
2154 break;
2155 }
2156
2157 return encoding_string;
2158}
2159
2160static
2161const char *get_integer_base_string(enum bt_ctf_integer_base base)
2162{
2163 const char *base_string;
2164
2165 switch (base) {
2166 case BT_CTF_INTEGER_BASE_DECIMAL:
2167 base_string = "decimal";
2168 break;
2169 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2170 base_string = "hexadecimal";
2171 break;
2172 case BT_CTF_INTEGER_BASE_OCTAL:
2173 base_string = "octal";
2174 break;
2175 case BT_CTF_INTEGER_BASE_BINARY:
2176 base_string = "binary";
2177 break;
2178 default:
2179 base_string = "unknown";
2180 break;
2181 }
2182
2183 return base_string;
2184}
2185
2186static
2187int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2188 struct metadata_context *context)
2189{
2190 struct bt_ctf_field_type_integer *integer = container_of(type,
2191 struct bt_ctf_field_type_integer, parent);
6cfb906f 2192 int ret = 0;
273b65be
JG
2193
2194 g_string_append_printf(context->string,
6cfb906f 2195 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
2196 integer->declaration.len, type->declaration->alignment,
2197 (integer->declaration.signedness ? "true" : "false"),
2198 get_encoding_string(integer->declaration.encoding),
2199 get_integer_base_string(integer->declaration.base),
2200 get_byte_order_string(integer->declaration.byte_order));
6cfb906f
JG
2201 if (integer->mapped_clock) {
2202 const char *clock_name = bt_ctf_clock_get_name(
2203 integer->mapped_clock);
2204
2205 if (!clock_name) {
2206 ret = -1;
2207 goto end;
2208 }
2209
2210 g_string_append_printf(context->string,
4ebdec03 2211 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2212 }
2213
2214 g_string_append(context->string, "; }");
2215end:
2216 return ret;
273b65be
JG
2217}
2218
2219static
2220int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2221 struct metadata_context *context)
2222{
2223 size_t entry;
9ce21c30 2224 int ret;
273b65be
JG
2225 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2226 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2227 struct bt_ctf_field_type *container_type;
2228 int container_signed;
273b65be 2229
9ce21c30
JG
2230 ret = bt_ctf_field_type_validate(type);
2231 if (ret) {
2232 goto end;
2233 }
2234
b92ddaaa
JG
2235 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2236 if (!container_type) {
2237 ret = -1;
2238 goto end;
2239 }
2240
2241 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2242 if (container_signed < 0) {
2243 ret = container_signed;
2244 goto error_put_container_type;
2245 }
2246
273b65be
JG
2247 g_string_append(context->string, "enum : ");
2248 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2249 if (ret) {
b92ddaaa 2250 goto error_put_container_type;
273b65be
JG
2251 }
2252
2253 g_string_append(context->string, " { ");
2254 for (entry = 0; entry < enumeration->entries->len; entry++) {
2255 struct enumeration_mapping *mapping =
2256 enumeration->entries->pdata[entry];
2257
b92ddaaa
JG
2258 if (container_signed) {
2259 if (mapping->range_start._signed ==
2260 mapping->range_end._signed) {
2261 g_string_append_printf(context->string,
2262 "\"%s\" = %" PRId64,
2263 g_quark_to_string(mapping->string),
2264 mapping->range_start._signed);
2265 } else {
2266 g_string_append_printf(context->string,
2267 "\"%s\" = %" PRId64 " ... %" PRId64,
2268 g_quark_to_string(mapping->string),
2269 mapping->range_start._signed,
2270 mapping->range_end._signed);
2271 }
273b65be 2272 } else {
b92ddaaa
JG
2273 if (mapping->range_start._unsigned ==
2274 mapping->range_end._unsigned) {
2275 g_string_append_printf(context->string,
2276 "\"%s\" = %" PRIu64,
2277 g_quark_to_string(mapping->string),
2278 mapping->range_start._unsigned);
2279 } else {
2280 g_string_append_printf(context->string,
2281 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2282 g_quark_to_string(mapping->string),
2283 mapping->range_start._unsigned,
2284 mapping->range_end._unsigned);
2285 }
273b65be
JG
2286 }
2287
2288 g_string_append(context->string,
2289 ((entry != (enumeration->entries->len - 1)) ?
2290 ", " : " }"));
2291 }
2292
2293 if (context->field_name->len) {
2294 g_string_append_printf(context->string, " %s",
2295 context->field_name->str);
2296 g_string_assign(context->field_name, "");
2297 }
b92ddaaa
JG
2298error_put_container_type:
2299 bt_ctf_field_type_put(container_type);
273b65be
JG
2300end:
2301 return ret;
2302}
2303
2304static
2305int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2306 struct metadata_context *context)
2307{
2308 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2309 type, struct bt_ctf_field_type_floating_point, parent);
2310
2311 g_string_append_printf(context->string,
2312 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2313 floating_point->declaration.exp->len,
2314 floating_point->declaration.mantissa->len + 1,
2315 get_byte_order_string(floating_point->declaration.byte_order),
2316 type->declaration->alignment);
2317 return 0;
2318}
2319
2320static
2321int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2322 struct metadata_context *context)
2323{
2324 size_t i;
2325 unsigned int indent;
2326 int ret = 0;
2327 struct bt_ctf_field_type_structure *structure = container_of(type,
2328 struct bt_ctf_field_type_structure, parent);
2329 GString *structure_field_name = context->field_name;
2330
2331 context->field_name = g_string_new("");
2332
2333 context->current_indentation_level++;
2334 g_string_append(context->string, "struct {\n");
2335
2336 for (i = 0; i < structure->fields->len; i++) {
2337 struct structure_field *field;
2338
2339 for (indent = 0; indent < context->current_indentation_level;
2340 indent++) {
2341 g_string_append_c(context->string, '\t');
2342 }
2343
2344 field = structure->fields->pdata[i];
2345 g_string_assign(context->field_name,
2346 g_quark_to_string(field->name));
2347 ret = bt_ctf_field_type_serialize(field->type, context);
2348 if (ret) {
2349 goto end;
2350 }
2351
2352 if (context->field_name->len) {
2353 g_string_append_printf(context->string, " %s",
2354 context->field_name->str);
2355 }
2356 g_string_append(context->string, ";\n");
2357 }
2358
2359 context->current_indentation_level--;
2360 for (indent = 0; indent < context->current_indentation_level;
2361 indent++) {
2362 g_string_append_c(context->string, '\t');
2363 }
2364
2365 g_string_append_printf(context->string, "} align(%zu)",
2366 type->declaration->alignment);
2367end:
2368 g_string_free(context->field_name, TRUE);
2369 context->field_name = structure_field_name;
2370 return ret;
2371}
2372
2373static
2374int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2375 struct metadata_context *context)
2376{
2377 size_t i;
2378 unsigned int indent;
2379 int ret = 0;
2380 struct bt_ctf_field_type_variant *variant = container_of(
2381 type, struct bt_ctf_field_type_variant, parent);
2382 GString *variant_field_name = context->field_name;
2383
2384 context->field_name = g_string_new("");
6964b7fd
JG
2385 if (variant->tag_name->len > 0) {
2386 g_string_append_printf(context->string,
2387 "variant <%s> {\n", variant->tag_name->str);
2388 } else {
2389 g_string_append(context->string, "variant {\n");
2390 }
2391
273b65be
JG
2392 context->current_indentation_level++;
2393 for (i = 0; i < variant->fields->len; i++) {
2394 struct structure_field *field = variant->fields->pdata[i];
2395
2396 g_string_assign(context->field_name,
2397 g_quark_to_string(field->name));
2398 for (indent = 0; indent < context->current_indentation_level;
2399 indent++) {
2400 g_string_append_c(context->string, '\t');
2401 }
2402
2403 g_string_assign(context->field_name,
2404 g_quark_to_string(field->name));
2405 ret = bt_ctf_field_type_serialize(field->type, context);
2406 if (ret) {
2407 goto end;
2408 }
2409
2410 if (context->field_name->len) {
2411 g_string_append_printf(context->string, " %s;",
2412 context->field_name->str);
2413 }
2414
2415 g_string_append_c(context->string, '\n');
2416 }
2417
2418 context->current_indentation_level--;
2419 for (indent = 0; indent < context->current_indentation_level;
2420 indent++) {
2421 g_string_append_c(context->string, '\t');
2422 }
2423
2424 g_string_append(context->string, "}");
2425end:
2426 g_string_free(context->field_name, TRUE);
2427 context->field_name = variant_field_name;
2428 return ret;
2429}
2430
2431static
2432int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2433 struct metadata_context *context)
2434{
2435 int ret = 0;
2436 struct bt_ctf_field_type_array *array = container_of(type,
2437 struct bt_ctf_field_type_array, parent);
2438
2439 ret = bt_ctf_field_type_serialize(array->element_type, context);
2440 if (ret) {
2441 goto end;
2442 }
2443
2444 if (context->field_name->len) {
2445 g_string_append_printf(context->string, " %s[%u]",
2446 context->field_name->str, array->length);
2447 g_string_assign(context->field_name, "");
2448 } else {
2449 g_string_append_printf(context->string, "[%u]", array->length);
2450 }
2451end:
2452 return ret;
2453}
2454
2455static
2456int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2457 struct metadata_context *context)
2458{
2459 int ret = 0;
2460 struct bt_ctf_field_type_sequence *sequence = container_of(
2461 type, struct bt_ctf_field_type_sequence, parent);
2462
2463 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2464 if (ret) {
2465 goto end;
2466 }
2467
2468 if (context->field_name->len) {
2469 g_string_append_printf(context->string, " %s[%s]",
2470 context->field_name->str,
2471 sequence->length_field_name->str);
2472 g_string_assign(context->field_name, "");
2473 } else {
2474 g_string_append_printf(context->string, "[%s]",
2475 sequence->length_field_name->str);
2476 }
2477end:
2478 return ret;
2479}
2480
2481static
2482int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2483 struct metadata_context *context)
2484{
2485 struct bt_ctf_field_type_string *string = container_of(
2486 type, struct bt_ctf_field_type_string, parent);
2487
2488 g_string_append_printf(context->string,
2489 "string { encoding = %s; }",
2490 get_encoding_string(string->declaration.encoding));
2491 return 0;
2492}
2493
2494static
2495void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 2496 int byte_order, int set_native)
273b65be
JG
2497{
2498 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2499 struct bt_ctf_field_type_integer, parent);
2500
c35a1669
JG
2501 if (set_native) {
2502 integer_type->declaration.byte_order =
2503 integer_type->declaration.byte_order == 0 ?
2504 byte_order : integer_type->declaration.byte_order;
2505 } else {
2506 integer_type->declaration.byte_order = byte_order;
2507 }
2508}
2509
2510static
2511void bt_ctf_field_type_enumeration_set_byte_order(
2512 struct bt_ctf_field_type *type, int byte_order, int set_native)
2513{
2514 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
2515 struct bt_ctf_field_type_enumeration, parent);
2516
2517 /* Safe to assume that container is an integer */
2518 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
2519 byte_order, set_native);
273b65be
JG
2520}
2521
2522static
2523void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 2524 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
2525{
2526 struct bt_ctf_field_type_floating_point *floating_point_type =
2527 container_of(type, struct bt_ctf_field_type_floating_point,
2528 parent);
2529
c35a1669
JG
2530 if (set_native) {
2531 floating_point_type->declaration.byte_order =
2532 floating_point_type->declaration.byte_order == 0 ?
2533 byte_order :
2534 floating_point_type->declaration.byte_order;
2535 floating_point_type->sign.byte_order =
2536 floating_point_type->sign.byte_order == 0 ?
2537 byte_order : floating_point_type->sign.byte_order;
2538 floating_point_type->mantissa.byte_order =
2539 floating_point_type->mantissa.byte_order == 0 ?
2540 byte_order : floating_point_type->mantissa.byte_order;
2541 floating_point_type->exp.byte_order =
2542 floating_point_type->exp.byte_order == 0 ?
2543 byte_order : floating_point_type->exp.byte_order;
2544 } else {
2545 floating_point_type->declaration.byte_order = byte_order;
2546 floating_point_type->sign.byte_order = byte_order;
2547 floating_point_type->mantissa.byte_order = byte_order;
2548 floating_point_type->exp.byte_order = byte_order;
2549 }
2550}
2551
2552static
2553void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
2554 int byte_order, int set_native)
2555{
2556 int i;
2557 struct bt_ctf_field_type_structure *structure_type =
2558 container_of(type, struct bt_ctf_field_type_structure,
2559 parent);
2560
2561 for (i = 0; i < structure_type->fields->len; i++) {
2562 struct structure_field *field = g_ptr_array_index(
2563 structure_type->fields, i);
2564 struct bt_ctf_field_type *field_type = field->type;
2565
2566 if (set_byte_order_funcs[field_type->declaration->id]) {
2567 set_byte_order_funcs[field_type->declaration->id](
2568 field_type, byte_order, set_native);
2569 }
2570 }
2571}
2572
2573static
2574void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
2575 int byte_order, int set_native)
2576{
2577 int i;
2578 struct bt_ctf_field_type_variant *variant_type =
2579 container_of(type, struct bt_ctf_field_type_variant,
2580 parent);
2581
2582 for (i = 0; i < variant_type->fields->len; i++) {
2583 struct structure_field *field = g_ptr_array_index(
2584 variant_type->fields, i);
2585 struct bt_ctf_field_type *field_type = field->type;
2586
2587 if (set_byte_order_funcs[field_type->declaration->id]) {
2588 set_byte_order_funcs[field_type->declaration->id](
2589 field_type, byte_order, set_native);
2590 }
2591 }
2592}
2593
2594static
2595void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
2596 int byte_order, int set_native)
2597{
2598 struct bt_ctf_field_type_array *array_type =
2599 container_of(type, struct bt_ctf_field_type_array,
2600 parent);
2601
2602 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
2603 set_byte_order_funcs[array_type->element_type->declaration->id](
2604 array_type->element_type, byte_order, set_native);
2605 }
2606}
2607
2608static
2609void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
2610 int byte_order, int set_native)
2611{
2612 struct bt_ctf_field_type_sequence *sequence_type =
2613 container_of(type, struct bt_ctf_field_type_sequence,
2614 parent);
2615
2616 if (set_byte_order_funcs[
2617 sequence_type->element_type->declaration->id]) {
2618 set_byte_order_funcs[
2619 sequence_type->element_type->declaration->id](
2620 sequence_type->element_type, byte_order, set_native);
2621 }
273b65be 2622}
24724933
JG
2623
2624static
2625struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
2626 struct bt_ctf_field_type *type)
2627{
2628 struct bt_ctf_field_type *copy;
2629 struct bt_ctf_field_type_integer *integer, *copy_integer;
2630
2631 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
2632 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
2633 if (!copy) {
2634 goto end;
2635 }
2636
2637 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
2638 parent);
2639 copy_integer->declaration = integer->declaration;
2640 if (integer->mapped_clock) {
2641 bt_ctf_clock_get(integer->mapped_clock);
2642 copy_integer->mapped_clock = integer->mapped_clock;
2643 }
2644end:
2645 return copy;
2646}
2647
2648static
2649struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
2650 struct bt_ctf_field_type *type)
2651{
2652 size_t i;
2653 struct bt_ctf_field_type *copy = NULL, *copy_container;
2654 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
2655
2656 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
2657 parent);
2658
2659 /* Copy the source enumeration's container */
2660 copy_container = bt_ctf_field_type_copy(enumeration->container);
2661 if (!copy_container) {
2662 goto end;
2663 }
2664
2665 copy = bt_ctf_field_type_enumeration_create(copy_container);
2666 if (!copy) {
2667 goto end;
2668 }
2669 copy_enumeration = container_of(copy,
2670 struct bt_ctf_field_type_enumeration, parent);
2671
2672 /* Copy all enumaration entries */
2673 for (i = 0; i < enumeration->entries->len; i++) {
2674 struct enumeration_mapping *mapping = g_ptr_array_index(
2675 enumeration->entries, i);
2676 struct enumeration_mapping* copy_mapping = g_new0(
2677 struct enumeration_mapping, 1);
2678
2679 if (!copy_mapping) {
2680 goto error;
2681 }
2682
2683 *copy_mapping = *mapping;
2684 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
2685 }
2686
2687 copy_enumeration->declaration = enumeration->declaration;
2688end:
2689 if (copy_container) {
2690 bt_ctf_field_type_put(copy_container);
2691 }
2692 return copy;
2693error:
2694 if (copy_container) {
2695 bt_ctf_field_type_put(copy_container);
2696 }
2697 bt_ctf_field_type_put(copy);
2698 return NULL;
2699}
2700
2701static
2702struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
2703 struct bt_ctf_field_type *type)
2704{
2705 struct bt_ctf_field_type *copy;
2706 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
2707
2708 floating_point = container_of(type,
2709 struct bt_ctf_field_type_floating_point, parent);
2710 copy = bt_ctf_field_type_floating_point_create();
2711 if (!copy) {
2712 goto end;
2713 }
2714
2715 copy_float = container_of(copy,
2716 struct bt_ctf_field_type_floating_point, parent);
2717 copy_float->declaration = floating_point->declaration;
2718 copy_float->sign = floating_point->sign;
2719 copy_float->mantissa = floating_point->mantissa;
2720 copy_float->exp = floating_point->exp;
2721end:
2722 return copy;
2723}
2724
2725static
2726struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
2727 struct bt_ctf_field_type *type)
2728{
2729 int i;
2730 GHashTableIter iter;
2731 gpointer key, value;
2732 struct bt_ctf_field_type *copy;
2733 struct bt_ctf_field_type_structure *structure, *copy_structure;
2734
2735 structure = container_of(type, struct bt_ctf_field_type_structure,
2736 parent);
2737 copy = bt_ctf_field_type_structure_create();
2738 if (!copy) {
2739 goto end;
2740 }
2741
2742 copy_structure = container_of(copy,
2743 struct bt_ctf_field_type_structure, parent);
2744
2745 /* Copy field_name_to_index */
2746 g_hash_table_iter_init(&iter, structure->field_name_to_index);
2747 while (g_hash_table_iter_next (&iter, &key, &value)) {
2748 g_hash_table_insert(copy_structure->field_name_to_index,
2749 key, value);
2750 }
2751
2752 for (i = 0; i < structure->fields->len; i++) {
2753 struct structure_field *entry, *copy_entry;
2754 struct bt_ctf_field_type *copy_field;
2755
2756 copy_entry = g_new0(struct structure_field, 1);
2757 if (!copy_entry) {
2758 goto error;
2759 }
2760
2761 entry = g_ptr_array_index(structure->fields, i);
2762 copy_field = bt_ctf_field_type_copy(entry->type);
2763 if (!copy_field) {
2764 g_free(copy_entry);
2765 goto error;
2766 }
2767
2768 copy_entry->name = entry->name;
2769 copy_entry->type = copy_field;
2770 g_ptr_array_add(copy_structure->fields, copy_entry);
2771 }
2772
2773 copy_structure->declaration = structure->declaration;
2774end:
2775 return copy;
2776error:
2777 bt_ctf_field_type_put(copy);
2778 return NULL;
2779}
2780
2781static
2782struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
2783 struct bt_ctf_field_type *type)
2784{
2785 int i;
2786 GHashTableIter iter;
2787 gpointer key, value;
2788 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
2789 struct bt_ctf_field_type_variant *variant, *copy_variant;
2790
2791 variant = container_of(type, struct bt_ctf_field_type_variant,
2792 parent);
2793 if (variant->tag) {
2794 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
2795 if (!copy_tag) {
2796 goto end;
2797 }
2798 }
2799
2800 copy = bt_ctf_field_type_variant_create(copy_tag,
2801 variant->tag_name->len ? variant->tag_name->str : NULL);
2802 if (!copy) {
2803 goto end;
2804 }
2805
2806 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
2807 parent);
2808
2809 /* Copy field_name_to_index */
2810 g_hash_table_iter_init(&iter, variant->field_name_to_index);
2811 while (g_hash_table_iter_next (&iter, &key, &value)) {
2812 g_hash_table_insert(copy_variant->field_name_to_index,
2813 key, value);
2814 }
2815
2816 for (i = 0; i < variant->fields->len; i++) {
2817 struct structure_field *entry, *copy_entry;
2818 struct bt_ctf_field_type *copy_field;
2819
2820 copy_entry = g_new0(struct structure_field, 1);
2821 if (!copy_entry) {
2822 goto error;
2823 }
2824
2825 entry = g_ptr_array_index(variant->fields, i);
2826 copy_field = bt_ctf_field_type_copy(entry->type);
2827 if (!copy_field) {
2828 g_free(copy_entry);
2829 goto error;
2830 }
2831
2832 copy_entry->name = entry->name;
2833 copy_entry->type = copy_field;
2834 g_ptr_array_add(copy_variant->fields, copy_entry);
2835 }
2836
2837 copy_variant->declaration = variant->declaration;
2838end:
2839 if (copy_tag) {
2840 bt_ctf_field_type_put(copy_tag);
2841 }
2842
2843 return copy;
2844error:
2845 if (copy_tag) {
2846 bt_ctf_field_type_put(copy_tag);
2847 }
2848
2849 bt_ctf_field_type_put(copy);
2850 return NULL;
2851}
2852
2853static
2854struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
2855 struct bt_ctf_field_type *type)
2856{
2857 struct bt_ctf_field_type *copy = NULL, *copy_element;
2858 struct bt_ctf_field_type_array *array, *copy_array;
2859
2860 array = container_of(type, struct bt_ctf_field_type_array,
2861 parent);
2862 copy_element = bt_ctf_field_type_copy(array->element_type);
2863 if (!copy_element) {
2864 goto end;
2865 }
2866
2867 copy = bt_ctf_field_type_array_create(copy_element, array->length);
2868 if (!copy) {
2869 goto end;
2870 }
2871
2872 copy_array = container_of(copy, struct bt_ctf_field_type_array,
2873 parent);
2874 copy_array->declaration = array->declaration;
2875end:
2876 if (copy_element) {
2877 bt_ctf_field_type_put(copy_element);
2878 }
2879
2880 return copy;
2881}
2882
2883static
2884struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
2885 struct bt_ctf_field_type *type)
2886{
2887 struct bt_ctf_field_type *copy = NULL, *copy_element;
2888 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
2889
2890 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2891 parent);
2892 copy_element = bt_ctf_field_type_copy(sequence->element_type);
2893 if (!copy_element) {
2894 goto end;
2895 }
2896
2897 copy = bt_ctf_field_type_sequence_create(copy_element,
2898 sequence->length_field_name->len ?
2899 sequence->length_field_name->str : NULL);
2900 if (!copy) {
2901 goto end;
2902 }
2903
2904 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
2905 parent);
2906 copy_sequence->declaration = sequence->declaration;
2907end:
2908 if (copy_element) {
2909 bt_ctf_field_type_put(copy_element);
2910 }
2911
2912 return copy;
2913}
2914
2915static
2916struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
2917 struct bt_ctf_field_type *type)
2918{
2919 struct bt_ctf_field_type *copy;
2920 struct bt_ctf_field_type_string *string, *copy_string;
2921
2922 copy = bt_ctf_field_type_string_create();
2923 if (!copy) {
2924 goto end;
2925 }
2926
2927 string = container_of(type, struct bt_ctf_field_type_string,
2928 parent);
2929 copy_string = container_of(type, struct bt_ctf_field_type_string,
2930 parent);
2931 copy_string->declaration = string->declaration;
2932end:
2933 return copy;
2934}
This page took 0.183445 seconds and 4 git commands to generate.