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