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