ir: consolidate reference counting functions
[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>
de3dd40e
PP
32#include <babeltrace/ctf-ir/ref.h>
33#include <babeltrace/ctf-ir/common-internal.h>
6cfb906f 34#include <babeltrace/ctf-ir/clock.h>
273b65be
JG
35#include <babeltrace/ctf-writer/writer-internal.h>
36#include <babeltrace/compiler.h>
37#include <babeltrace/endian.h>
38#include <float.h>
39#include <inttypes.h>
a39fa057 40#include <stdlib.h>
273b65be
JG
41
42struct range_overlap_query {
b92ddaaa
JG
43 union {
44 uint64_t _unsigned;
45 int64_t _signed;
46 } range_start;
47
48 union {
49 uint64_t _unsigned;
50 int64_t _signed;
51 } range_end;
273b65be
JG
52 int overlaps;
53 GQuark mapping_name;
54};
55
2f2d8e05 56static
de3dd40e 57void bt_ctf_field_type_destroy(struct bt_ref *);
273b65be 58static
de3dd40e 59void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
273b65be 60static
de3dd40e 61void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
273b65be 62static
de3dd40e 63void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
273b65be 64static
de3dd40e 65void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
273b65be 66static
de3dd40e 67void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
273b65be 68static
de3dd40e 69void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
273b65be 70static
de3dd40e 71void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
273b65be 72static
de3dd40e 73void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
273b65be
JG
74
75static
de3dd40e 76void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
273b65be
JG
77 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_destroy,
78 [CTF_TYPE_ENUM] =
79 bt_ctf_field_type_enumeration_destroy,
80 [CTF_TYPE_FLOAT] =
81 bt_ctf_field_type_floating_point_destroy,
82 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_destroy,
83 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_destroy,
84 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_destroy,
85 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
86 [CTF_TYPE_STRING] = bt_ctf_field_type_string_destroy,
87};
88
89static
90void generic_field_type_freeze(struct bt_ctf_field_type *);
91static
92void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
93static
94void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
95static
96void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
97static
98void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
99static
100void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
101
102static
103type_freeze_func const type_freeze_funcs[] = {
104 [CTF_TYPE_INTEGER] = generic_field_type_freeze,
105 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_freeze,
106 [CTF_TYPE_FLOAT] = generic_field_type_freeze,
107 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_freeze,
108 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_freeze,
109 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_freeze,
110 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
111 [CTF_TYPE_STRING] = generic_field_type_freeze,
112};
113
114static
115int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
116 struct metadata_context *);
117static
118int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
119 struct metadata_context *);
120static
121int bt_ctf_field_type_floating_point_serialize(
122 struct bt_ctf_field_type *, struct metadata_context *);
123static
124int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
125 struct metadata_context *);
126static
127int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
128 struct metadata_context *);
129static
130int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
131 struct metadata_context *);
132static
133int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
134 struct metadata_context *);
135static
136int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
137 struct metadata_context *);
138
139static
140type_serialize_func const type_serialize_funcs[] = {
141 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_serialize,
142 [CTF_TYPE_ENUM] =
143 bt_ctf_field_type_enumeration_serialize,
144 [CTF_TYPE_FLOAT] =
145 bt_ctf_field_type_floating_point_serialize,
146 [CTF_TYPE_STRUCT] =
147 bt_ctf_field_type_structure_serialize,
148 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_serialize,
149 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_serialize,
150 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
151 [CTF_TYPE_STRING] = bt_ctf_field_type_string_serialize,
152};
153
154static
155void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
c35a1669
JG
156 int byte_order, int set_native);
157static
158void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
159 int byte_order, int set_native);
273b65be
JG
160static
161void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669
JG
162 struct bt_ctf_field_type *, int byte_order, int set_native);
163static
164void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
165 int byte_order, int set_native);
166static
167void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
168 int byte_order, int set_native);
169static
170void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
171 int byte_order, int set_native);
172static
173void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
174 int byte_order, int set_native);
273b65be 175
c35a1669 176/* The set_native flag only set the byte order if it is set to native */
273b65be
JG
177static
178void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
c35a1669
JG
179 int byte_order, int set_native) = {
180 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
181 [CTF_TYPE_ENUM] =
182 bt_ctf_field_type_enumeration_set_byte_order,
273b65be
JG
183 [CTF_TYPE_FLOAT] =
184 bt_ctf_field_type_floating_point_set_byte_order,
c35a1669
JG
185 [CTF_TYPE_STRUCT] =
186 bt_ctf_field_type_structure_set_byte_order,
187 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
188 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_set_byte_order,
189 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
190 [CTF_TYPE_STRING] = NULL,
273b65be
JG
191};
192
24724933
JG
193static
194struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
195 struct bt_ctf_field_type *);
196static
197struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
198 struct bt_ctf_field_type *);
199static
200struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
201 struct bt_ctf_field_type *);
202static
203struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
204 struct bt_ctf_field_type *);
205static
206struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
207 struct bt_ctf_field_type *);
208static
209struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
210 struct bt_ctf_field_type *);
211static
212struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
213 struct bt_ctf_field_type *);
214static
215struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
216 struct bt_ctf_field_type *);
217
218static
219struct bt_ctf_field_type *(* const type_copy_funcs[])(
220 struct bt_ctf_field_type *) = {
221 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_copy,
222 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_copy,
223 [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_copy,
224 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_copy,
225 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_copy,
226 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_copy,
227 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_copy,
228 [CTF_TYPE_STRING] = bt_ctf_field_type_string_copy,
229};
230
273b65be
JG
231static
232void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
233{
234 g_free(mapping);
235}
236
237static
238void destroy_structure_field(struct structure_field *field)
239{
240 if (field->type) {
241 bt_ctf_field_type_put(field->type);
242 }
243
244 g_free(field);
245}
246
247static
248void check_ranges_overlap(gpointer element, gpointer query)
249{
250 struct enumeration_mapping *mapping = element;
251 struct range_overlap_query *overlap_query = query;
252
b92ddaaa
JG
253 if (mapping->range_start._signed <= overlap_query->range_end._signed
254 && overlap_query->range_start._signed <=
255 mapping->range_end._signed) {
256 overlap_query->overlaps = 1;
257 overlap_query->mapping_name = mapping->string;
258 }
259
260 overlap_query->overlaps |=
261 mapping->string == overlap_query->mapping_name;
262}
263
264static
265void check_ranges_overlap_unsigned(gpointer element, gpointer query)
266{
267 struct enumeration_mapping *mapping = element;
268 struct range_overlap_query *overlap_query = query;
269
270 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
271 && overlap_query->range_start._unsigned <=
272 mapping->range_end._unsigned) {
273b65be
JG
273 overlap_query->overlaps = 1;
274 overlap_query->mapping_name = mapping->string;
275 }
276
277 overlap_query->overlaps |=
278 mapping->string == overlap_query->mapping_name;
279}
280
b92ddaaa
JG
281static
282gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
283 struct enumeration_mapping **b)
284{
285 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
286}
287
288static
289gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
290 struct enumeration_mapping **b)
291{
292 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
293}
294
273b65be 295static
59acd4f5 296void bt_ctf_field_type_init(struct bt_ctf_field_type *type, int init_bo)
273b65be
JG
297{
298 enum ctf_type_id type_id = type->declaration->id;
299
300 assert(type && (type_id > CTF_TYPE_UNKNOWN) &&
301 (type_id < NR_CTF_TYPES));
302
de3dd40e 303 bt_ctf_base_init(type, bt_ctf_field_type_destroy);
273b65be
JG
304 type->freeze = type_freeze_funcs[type_id];
305 type->serialize = type_serialize_funcs[type_id];
59acd4f5
PP
306
307 if (init_bo) {
308 int ret = bt_ctf_field_type_set_byte_order(type,
309 BT_CTF_BYTE_ORDER_NATIVE);
310 assert(!ret);
311 }
312
273b65be
JG
313 type->declaration->alignment = 1;
314}
315
316static
317int add_structure_field(GPtrArray *fields,
318 GHashTable *field_name_to_index,
319 struct bt_ctf_field_type *field_type,
320 const char *field_name)
321{
322 int ret = 0;
323 GQuark name_quark = g_quark_from_string(field_name);
324 struct structure_field *field;
325
326 /* Make sure structure does not contain a field of the same name */
fe0fe95c
JG
327 if (g_hash_table_lookup_extended(field_name_to_index,
328 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
273b65be
JG
329 ret = -1;
330 goto end;
331 }
332
333 field = g_new0(struct structure_field, 1);
334 if (!field) {
335 ret = -1;
336 goto end;
337 }
338
339 bt_ctf_field_type_get(field_type);
340 field->name = name_quark;
341 field->type = field_type;
342 g_hash_table_insert(field_name_to_index,
343 (gpointer) (unsigned long) name_quark,
344 (gpointer) (unsigned long) fields->len);
345 g_ptr_array_add(fields, field);
273b65be
JG
346end:
347 return ret;
348}
349
2f2d8e05 350static
de3dd40e 351void bt_ctf_field_type_destroy(struct bt_ref *ref)
2f2d8e05
JG
352{
353 struct bt_ctf_field_type *type;
de3dd40e 354 struct bt_ctf_base *base;
2f2d8e05
JG
355 enum ctf_type_id type_id;
356
357 if (!ref) {
358 return;
359 }
360
de3dd40e
PP
361 base = container_of(ref, struct bt_ctf_base, ref_count);
362 type = container_of(base, struct bt_ctf_field_type, base);
2f2d8e05
JG
363 type_id = type->declaration->id;
364 if (type_id <= CTF_TYPE_UNKNOWN ||
365 type_id >= NR_CTF_TYPES) {
366 return;
367 }
368
de3dd40e 369 type_destroy_funcs[type_id](type);
2f2d8e05
JG
370}
371
9ce21c30
JG
372BT_HIDDEN
373int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
374{
375 int ret = 0;
376
377 if (!type) {
378 ret = -1;
379 goto end;
380 }
381
5d161ecc
JG
382 switch (type->declaration->id) {
383 case CTF_TYPE_ENUM:
384 {
9ce21c30
JG
385 struct bt_ctf_field_type_enumeration *enumeration =
386 container_of(type, struct bt_ctf_field_type_enumeration,
387 parent);
388
5d161ecc 389 /* Ensure enum has entries */
9ce21c30 390 ret = enumeration->entries->len ? 0 : -1;
5d161ecc
JG
391 break;
392 }
c6c0ca42
JG
393 case CTF_TYPE_SEQUENCE:
394 {
395 struct bt_ctf_field_type_sequence *sequence =
396 container_of(type, struct bt_ctf_field_type_sequence,
397 parent);
398
399 /* length field name should be set at this point */
400 ret = sequence->length_field_name->len ? 0 : -1;
401 break;
402 }
403 case CTF_TYPE_VARIANT:
404 {
405 struct bt_ctf_field_type_variant *variant =
406 container_of(type, struct bt_ctf_field_type_variant,
407 parent);
408
409 if (variant->tag_name->len == 0 || !variant->tag) {
410 ret = -1;
411 }
412 break;
413 }
5d161ecc
JG
414 default:
415 break;
9ce21c30
JG
416 }
417end:
418 return ret;
419}
420
273b65be
JG
421struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
422{
423 struct bt_ctf_field_type_integer *integer =
424 g_new0(struct bt_ctf_field_type_integer, 1);
425
1f02e293 426 if (!integer || size == 0 || size > 64) {
273b65be
JG
427 return NULL;
428 }
429
430 integer->parent.declaration = &integer->declaration.p;
431 integer->parent.declaration->id = CTF_TYPE_INTEGER;
432 integer->declaration.len = size;
433 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
434 integer->declaration.encoding = CTF_STRING_NONE;
59acd4f5 435 bt_ctf_field_type_init(&integer->parent, TRUE);
273b65be
JG
436 return &integer->parent;
437}
438
b92ddaaa
JG
439int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
440{
441 int ret = 0;
442 struct bt_ctf_field_type_integer *integer;
443
444 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
445 ret = -1;
446 goto end;
447 }
448
449 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
450 ret = (int) integer->declaration.len;
451end:
452 return ret;
453}
454
455int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
456{
457 int ret = 0;
458 struct bt_ctf_field_type_integer *integer;
459
460 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
461 ret = -1;
462 goto end;
463 }
464
465 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
466 ret = integer->declaration.signedness;
467end:
468 return ret;
469}
470
273b65be
JG
471int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
472 int is_signed)
473{
474 int ret = 0;
475 struct bt_ctf_field_type_integer *integer;
476
477 if (!type || type->frozen ||
478 type->declaration->id != CTF_TYPE_INTEGER) {
479 ret = -1;
480 goto end;
481 }
482
483 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
273b65be
JG
484 integer->declaration.signedness = !!is_signed;
485end:
486 return ret;
487}
488
b92ddaaa
JG
489enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
490 struct bt_ctf_field_type *type)
491{
492 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
493 struct bt_ctf_field_type_integer *integer;
494
495 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
496 goto end;
497 }
498
499 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
500 ret = integer->declaration.base;
501end:
502 return ret;
503}
504
273b65be
JG
505int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
506 enum bt_ctf_integer_base base)
507{
508 int ret = 0;
509
510 if (!type || type->frozen ||
511 type->declaration->id != CTF_TYPE_INTEGER) {
512 ret = -1;
513 goto end;
514 }
515
516 switch (base) {
517 case BT_CTF_INTEGER_BASE_BINARY:
518 case BT_CTF_INTEGER_BASE_OCTAL:
519 case BT_CTF_INTEGER_BASE_DECIMAL:
520 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
521 {
522 struct bt_ctf_field_type_integer *integer = container_of(type,
523 struct bt_ctf_field_type_integer, parent);
524 integer->declaration.base = base;
525 break;
526 }
527 default:
528 ret = -1;
529 }
530end:
531 return ret;
532}
533
b92ddaaa
JG
534enum ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
535 struct bt_ctf_field_type *type)
536{
537 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
538 struct bt_ctf_field_type_integer *integer;
539
540 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
541 goto end;
542 }
543
544 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
545 ret = integer->declaration.encoding;
546end:
547 return ret;
548}
549
273b65be
JG
550int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
551 enum ctf_string_encoding encoding)
552{
553 int ret = 0;
554 struct bt_ctf_field_type_integer *integer;
555
556 if (!type || type->frozen ||
557 (type->declaration->id != CTF_TYPE_INTEGER) ||
558 (encoding < CTF_STRING_NONE) ||
559 (encoding >= CTF_STRING_UNKNOWN)) {
560 ret = -1;
561 goto end;
562 }
563
564 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
565 integer->declaration.encoding = encoding;
566end:
567 return ret;
568}
569
6cfb906f
JG
570struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
571 struct bt_ctf_field_type *type)
572{
573 struct bt_ctf_field_type_integer *integer;
574 struct bt_ctf_clock *clock = NULL;
575
576 if (!type) {
577 goto end;
578 }
579
580 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
581 clock = integer->mapped_clock;
582 if (clock) {
583 bt_ctf_clock_get(clock);
584 }
585end:
586 return clock;
587}
588
589int bt_ctf_field_type_integer_set_mapped_clock(
590 struct bt_ctf_field_type *type,
591 struct bt_ctf_clock *clock)
592{
593 struct bt_ctf_field_type_integer *integer;
594 int ret = 0;
595
596 if (!type || type->frozen) {
597 ret = -1;
598 goto end;
599 }
600
601 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
602 if (integer->mapped_clock) {
603 bt_ctf_clock_put(integer->mapped_clock);
604 }
605
606 if (clock) {
607 bt_ctf_clock_get(clock);
608 }
609
610 integer->mapped_clock = clock;
611end:
612 return ret;
613}
614
273b65be
JG
615struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
616 struct bt_ctf_field_type *integer_container_type)
617{
618 struct bt_ctf_field_type_enumeration *enumeration = NULL;
619
620 if (!integer_container_type) {
621 goto error;
622 }
623
2a610bb7
JG
624 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
625 goto error;
626 }
627
273b65be
JG
628 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
629 if (!enumeration) {
630 goto error;
631 }
632
633 enumeration->parent.declaration = &enumeration->declaration.p;
634 enumeration->parent.declaration->id = CTF_TYPE_ENUM;
635 bt_ctf_field_type_get(integer_container_type);
636 enumeration->container = integer_container_type;
637 enumeration->entries = g_ptr_array_new_with_free_func(
638 (GDestroyNotify)destroy_enumeration_mapping);
59acd4f5 639 bt_ctf_field_type_init(&enumeration->parent, FALSE);
273b65be
JG
640 return &enumeration->parent;
641error:
642 g_free(enumeration);
643 return NULL;
644}
645
b92ddaaa
JG
646struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
647 struct bt_ctf_field_type *type)
648{
649 struct bt_ctf_field_type *container_type = NULL;
650 struct bt_ctf_field_type_enumeration *enumeration_type;
651
652 if (!type) {
653 goto end;
654 }
655
656 if (type->declaration->id != CTF_TYPE_ENUM) {
657 goto end;
658 }
659
660 enumeration_type = container_of(type,
661 struct bt_ctf_field_type_enumeration, parent);
662 container_type = enumeration_type->container;
663 bt_ctf_field_type_get(container_type);
664end:
665 return container_type;
666}
667
273b65be
JG
668int bt_ctf_field_type_enumeration_add_mapping(
669 struct bt_ctf_field_type *type, const char *string,
670 int64_t range_start, int64_t range_end)
671{
672 int ret = 0;
673 GQuark mapping_name;
674 struct enumeration_mapping *mapping;
675 struct bt_ctf_field_type_enumeration *enumeration;
676 struct range_overlap_query query;
a39fa057 677 char *escaped_string;
273b65be
JG
678
679 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
680 type->frozen ||
681 (range_end < range_start)) {
682 ret = -1;
683 goto end;
684 }
685
a39fa057 686 if (!string || strlen(string) == 0) {
273b65be
JG
687 ret = -1;
688 goto end;
689 }
690
a39fa057
JG
691 escaped_string = g_strescape(string, NULL);
692 if (!escaped_string) {
693 ret = -1;
694 goto end;
695 }
696
697 mapping_name = g_quark_from_string(escaped_string);
b92ddaaa
JG
698 query = (struct range_overlap_query) {
699 .range_start._signed = range_start,
700 .range_end._signed = range_end,
273b65be
JG
701 .mapping_name = mapping_name,
702 .overlaps = 0 };
703 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
704 parent);
705
706 /* Check that the range does not overlap with one already present */
707 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
708 if (query.overlaps) {
709 ret = -1;
a39fa057 710 goto error_free;
273b65be
JG
711 }
712
713 mapping = g_new(struct enumeration_mapping, 1);
714 if (!mapping) {
715 ret = -1;
a39fa057 716 goto error_free;
273b65be
JG
717 }
718
b92ddaaa
JG
719 *mapping = (struct enumeration_mapping) {
720 .range_start._signed = range_start,
721 .range_end._signed = range_end, .string = mapping_name};
273b65be 722 g_ptr_array_add(enumeration->entries, mapping);
b92ddaaa
JG
723 g_ptr_array_sort(enumeration->entries,
724 (GCompareFunc)compare_enumeration_mappings_signed);
725error_free:
726 free(escaped_string);
727end:
728 return ret;
729}
730
731int bt_ctf_field_type_enumeration_add_mapping_unsigned(
732 struct bt_ctf_field_type *type, const char *string,
733 uint64_t range_start, uint64_t range_end)
734{
735 int ret = 0;
736 GQuark mapping_name;
737 struct enumeration_mapping *mapping;
738 struct bt_ctf_field_type_enumeration *enumeration;
739 struct range_overlap_query query;
740 char *escaped_string;
741
742 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
743 type->frozen ||
744 (range_end < range_start)) {
745 ret = -1;
746 goto end;
747 }
748
749 if (!string || strlen(string) == 0) {
750 ret = -1;
751 goto end;
752 }
753
754 escaped_string = g_strescape(string, NULL);
755 if (!escaped_string) {
756 ret = -1;
757 goto end;
758 }
759
760 mapping_name = g_quark_from_string(escaped_string);
761 query = (struct range_overlap_query) {
762 .range_start._unsigned = range_start,
763 .range_end._unsigned = range_end,
764 .mapping_name = mapping_name,
765 .overlaps = 0 };
766 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
767 parent);
768
769 /* Check that the range does not overlap with one already present */
770 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned,
771 &query);
772 if (query.overlaps) {
773 ret = -1;
774 goto error_free;
775 }
776
777 mapping = g_new(struct enumeration_mapping, 1);
778 if (!mapping) {
779 ret = -1;
780 goto error_free;
781 }
782
783 *mapping = (struct enumeration_mapping) {
784 .range_start._unsigned = range_start,
785 .range_end._unsigned = range_end, .string = mapping_name};
786 g_ptr_array_add(enumeration->entries, mapping);
787 g_ptr_array_sort(enumeration->entries,
788 (GCompareFunc)compare_enumeration_mappings_unsigned);
a39fa057
JG
789error_free:
790 free(escaped_string);
273b65be
JG
791end:
792 return ret;
793}
794
e5958c30
JG
795const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
796 struct bt_ctf_field_type_enumeration *enumeration_type,
797 uint64_t value)
798{
799 const char *name = NULL;
800 struct range_overlap_query query =
801 (struct range_overlap_query) {
b92ddaaa
JG
802 .range_start._unsigned = value,
803 .range_end._unsigned = value,
e5958c30
JG
804 .overlaps = 0 };
805
b92ddaaa
JG
806 g_ptr_array_foreach(enumeration_type->entries,
807 check_ranges_overlap_unsigned,
e5958c30
JG
808 &query);
809 if (!query.overlaps) {
810 goto end;
811 }
812
813 name = g_quark_to_string(query.mapping_name);
814end:
815 return name;
816}
817
818const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
819 struct bt_ctf_field_type_enumeration *enumeration_type,
820 int64_t value)
821{
822 const char *name = NULL;
823 struct range_overlap_query query =
824 (struct range_overlap_query) {
b92ddaaa
JG
825 .range_start._signed = value,
826 .range_end._signed = value,
e5958c30
JG
827 .overlaps = 0 };
828
829 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
830 &query);
831 if (!query.overlaps) {
832 goto end;
833 }
834
835 name = g_quark_to_string(query.mapping_name);
836end:
837 return name;
838}
839
074ee56d 840int bt_ctf_field_type_enumeration_get_mapping_count(
b92ddaaa
JG
841 struct bt_ctf_field_type *type)
842{
074ee56d 843 int ret = 0;
b92ddaaa
JG
844 struct bt_ctf_field_type_enumeration *enumeration;
845
846 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
847 ret = -1;
848 goto end;
849 }
850
851 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
852 parent);
074ee56d 853 ret = (int) enumeration->entries->len;
b92ddaaa
JG
854end:
855 return ret;
856}
857
858static inline
859struct enumeration_mapping *get_enumeration_mapping(
074ee56d 860 struct bt_ctf_field_type *type, int index)
b92ddaaa
JG
861{
862 struct enumeration_mapping *mapping = NULL;
863 struct bt_ctf_field_type_enumeration *enumeration;
864
865 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
866 parent);
867 if (index >= enumeration->entries->len) {
868 goto end;
869 }
870
871 mapping = g_ptr_array_index(enumeration->entries, index);
872end:
873 return mapping;
874}
875
876int bt_ctf_field_type_enumeration_get_mapping(
074ee56d 877 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
878 const char **string, int64_t *range_start, int64_t *range_end)
879{
880 struct enumeration_mapping *mapping;
881 int ret = 0;
882
074ee56d 883 if (!type || index < 0 || !string || !range_start || !range_end ||
b92ddaaa
JG
884 (type->declaration->id != CTF_TYPE_ENUM)) {
885 ret = -1;
886 goto end;
887 }
888
889 mapping = get_enumeration_mapping(type, index);
890 if (!mapping) {
891 ret = -1;
892 goto end;
893 }
894
895 *string = g_quark_to_string(mapping->string);
896 *range_start = mapping->range_start._signed;
897 *range_end = mapping->range_end._signed;
898end:
899 return ret;
900}
901
902int bt_ctf_field_type_enumeration_get_mapping_unsigned(
074ee56d 903 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
904 const char **string, uint64_t *range_start, uint64_t *range_end)
905{
906 struct enumeration_mapping *mapping;
907 int ret = 0;
908
074ee56d 909 if (!type || index < 0 || !string || !range_start || !range_end ||
b92ddaaa
JG
910 (type->declaration->id != CTF_TYPE_ENUM)) {
911 ret = -1;
912 goto end;
913 }
914
915 mapping = get_enumeration_mapping(type, index);
916 if (!mapping) {
917 ret = -1;
918 goto end;
919 }
920
921 *string = g_quark_to_string(mapping->string);
922 *range_start = mapping->range_start._unsigned;
923 *range_end = mapping->range_end._unsigned;
924end:
925 return ret;
926}
927
928int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
074ee56d 929 struct bt_ctf_field_type *type, const char *name)
b92ddaaa 930{
b92ddaaa
JG
931 GQuark name_quark;
932 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 933 int i, ret = 0;
b92ddaaa 934
074ee56d 935 if (!type || !name ||
b92ddaaa
JG
936 (type->declaration->id != CTF_TYPE_ENUM)) {
937 ret = -1;
938 goto end;
939 }
940
941 name_quark = g_quark_try_string(name);
942 if (!name_quark) {
943 ret = -1;
944 goto end;
945 }
946
947 enumeration = container_of(type,
948 struct bt_ctf_field_type_enumeration, parent);
949 for (i = 0; i < enumeration->entries->len; i++) {
950 struct enumeration_mapping *mapping =
951 get_enumeration_mapping(type, i);
952
953 if (mapping->string == name_quark) {
074ee56d 954 ret = i;
b92ddaaa
JG
955 goto end;
956 }
957 }
958
959 ret = -1;
960end:
961 return ret;
962}
963
964int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
074ee56d 965 struct bt_ctf_field_type *type, int64_t value)
b92ddaaa
JG
966{
967 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 968 int i, ret = 0;
b92ddaaa 969
074ee56d 970 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
b92ddaaa
JG
971 ret = -1;
972 goto end;
973 }
974
975 enumeration = container_of(type,
976 struct bt_ctf_field_type_enumeration, parent);
977 for (i = 0; i < enumeration->entries->len; i++) {
978 struct enumeration_mapping *mapping =
979 get_enumeration_mapping(type, i);
980
981 if (value >= mapping->range_start._signed &&
982 value <= mapping->range_end._signed) {
074ee56d 983 ret = i;
b92ddaaa
JG
984 goto end;
985 }
986 }
987
988 ret = -1;
989end:
990 return ret;
991}
992
993int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
074ee56d 994 struct bt_ctf_field_type *type, uint64_t value)
b92ddaaa
JG
995{
996 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 997 int i, ret = 0;
b92ddaaa 998
074ee56d 999 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
b92ddaaa
JG
1000 ret = -1;
1001 goto end;
1002 }
1003
1004 enumeration = container_of(type,
1005 struct bt_ctf_field_type_enumeration, parent);
1006 for (i = 0; i < enumeration->entries->len; i++) {
1007 struct enumeration_mapping *mapping =
1008 get_enumeration_mapping(type, i);
1009
1010 if (value >= mapping->range_start._unsigned &&
1011 value <= mapping->range_end._unsigned) {
074ee56d 1012 ret = i;
b92ddaaa
JG
1013 goto end;
1014 }
1015 }
1016
1017 ret = -1;
1018end:
1019 return ret;
1020}
1021
273b65be
JG
1022struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
1023{
1024 struct bt_ctf_field_type_floating_point *floating_point =
1025 g_new0(struct bt_ctf_field_type_floating_point, 1);
1026
1027 if (!floating_point) {
1028 goto end;
1029 }
1030
1031 floating_point->declaration.sign = &floating_point->sign;
1032 floating_point->declaration.mantissa = &floating_point->mantissa;
1033 floating_point->declaration.exp = &floating_point->exp;
1034 floating_point->sign.len = 1;
1035 floating_point->parent.declaration = &floating_point->declaration.p;
1036 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
1037 floating_point->declaration.exp->len =
1038 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
1039 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
1040 floating_point->sign.p.alignment = 1;
1041 floating_point->mantissa.p.alignment = 1;
1042 floating_point->exp.p.alignment = 1;
1043
59acd4f5 1044 bt_ctf_field_type_init(&floating_point->parent, TRUE);
273b65be
JG
1045end:
1046 return floating_point ? &floating_point->parent : NULL;
1047}
1048
b92ddaaa
JG
1049int bt_ctf_field_type_floating_point_get_exponent_digits(
1050 struct bt_ctf_field_type *type)
1051{
1052 int ret = 0;
1053 struct bt_ctf_field_type_floating_point *floating_point;
1054
1055 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1056 ret = -1;
1057 goto end;
1058 }
1059
1060 floating_point = container_of(type,
1061 struct bt_ctf_field_type_floating_point, parent);
1062 ret = (int) floating_point->declaration.exp->len;
1063end:
1064 return ret;
1065}
1066
273b65be
JG
1067int bt_ctf_field_type_floating_point_set_exponent_digits(
1068 struct bt_ctf_field_type *type,
1069 unsigned int exponent_digits)
1070{
1071 int ret = 0;
1072 struct bt_ctf_field_type_floating_point *floating_point;
1073
1074 if (!type || type->frozen ||
1075 (type->declaration->id != CTF_TYPE_FLOAT)) {
1076 ret = -1;
1077 goto end;
1078 }
1079
1080 floating_point = container_of(type,
1081 struct bt_ctf_field_type_floating_point, parent);
1082 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1083 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1084 (exponent_digits !=
1085 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1086 ret = -1;
1087 goto end;
1088 }
1089
1090 floating_point->declaration.exp->len = exponent_digits;
1091end:
1092 return ret;
1093}
1094
b92ddaaa
JG
1095int bt_ctf_field_type_floating_point_get_mantissa_digits(
1096 struct bt_ctf_field_type *type)
1097{
1098 int ret = 0;
1099 struct bt_ctf_field_type_floating_point *floating_point;
1100
1101 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1102 ret = -1;
1103 goto end;
1104 }
1105
1106 floating_point = container_of(type,
1107 struct bt_ctf_field_type_floating_point, parent);
1108 ret = (int) floating_point->mantissa.len + 1;
1109end:
1110 return ret;
1111}
1112
273b65be
JG
1113int bt_ctf_field_type_floating_point_set_mantissa_digits(
1114 struct bt_ctf_field_type *type,
1115 unsigned int mantissa_digits)
1116{
1117 int ret = 0;
1118 struct bt_ctf_field_type_floating_point *floating_point;
1119
1120 if (!type || type->frozen ||
1121 (type->declaration->id != CTF_TYPE_FLOAT)) {
1122 ret = -1;
1123 goto end;
1124 }
1125
1126 floating_point = container_of(type,
1127 struct bt_ctf_field_type_floating_point, parent);
1128
1129 if ((mantissa_digits != FLT_MANT_DIG) &&
1130 (mantissa_digits != DBL_MANT_DIG) &&
1131 (mantissa_digits != LDBL_MANT_DIG)) {
1132 ret = -1;
1133 goto end;
1134 }
1135
1136 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1137end:
1138 return ret;
1139}
1140
1141struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1142{
1143 struct bt_ctf_field_type_structure *structure =
1144 g_new0(struct bt_ctf_field_type_structure, 1);
1145
1146 if (!structure) {
1147 goto error;
1148 }
1149
1150 structure->parent.declaration = &structure->declaration.p;
1151 structure->parent.declaration->id = CTF_TYPE_STRUCT;
273b65be
JG
1152 structure->fields = g_ptr_array_new_with_free_func(
1153 (GDestroyNotify)destroy_structure_field);
1154 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
59acd4f5 1155 bt_ctf_field_type_init(&structure->parent, TRUE);
273b65be
JG
1156 return &structure->parent;
1157error:
1158 return NULL;
1159}
1160
1161int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1162 struct bt_ctf_field_type *field_type,
1163 const char *field_name)
1164{
1165 int ret = 0;
1166 struct bt_ctf_field_type_structure *structure;
1167
1168 if (!type || !field_type || type->frozen ||
654c1444 1169 bt_ctf_validate_identifier(field_name) ||
9ce21c30
JG
1170 (type->declaration->id != CTF_TYPE_STRUCT) ||
1171 bt_ctf_field_type_validate(field_type)) {
e6235f1f 1172 ret = -1;
273b65be
JG
1173 goto end;
1174 }
1175
1176 structure = container_of(type,
1177 struct bt_ctf_field_type_structure, parent);
1178 if (add_structure_field(structure->fields,
1179 structure->field_name_to_index, field_type, field_name)) {
1180 ret = -1;
1181 goto end;
1182 }
b92ddaaa
JG
1183end:
1184 return ret;
1185}
1186
074ee56d 1187int bt_ctf_field_type_structure_get_field_count(
b92ddaaa
JG
1188 struct bt_ctf_field_type *type)
1189{
074ee56d 1190 int ret = 0;
b92ddaaa
JG
1191 struct bt_ctf_field_type_structure *structure;
1192
1193 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1194 ret = -1;
1195 goto end;
1196 }
1197
1198 structure = container_of(type, struct bt_ctf_field_type_structure,
1199 parent);
074ee56d 1200 ret = (int) structure->fields->len;
b92ddaaa
JG
1201end:
1202 return ret;
1203}
1204
1205int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1206 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 1207 int index)
b92ddaaa
JG
1208{
1209 struct bt_ctf_field_type_structure *structure;
1210 struct structure_field *field;
1211 int ret = 0;
1212
f9b799fc 1213 if (!type || index < 0 || (type->declaration->id != CTF_TYPE_STRUCT)) {
b92ddaaa
JG
1214 ret = -1;
1215 goto end;
1216 }
1217
1218 structure = container_of(type, struct bt_ctf_field_type_structure,
1219 parent);
1220 if (index >= structure->fields->len) {
1221 ret = -1;
1222 goto end;
1223 }
1224
1225 field = g_ptr_array_index(structure->fields, index);
f9b799fc
JG
1226 if (field_type) {
1227 *field_type = field->type;
1228 bt_ctf_field_type_get(field->type);
1229 }
1230 if (field_name) {
1231 *field_name = g_quark_to_string(field->name);
1232 }
b92ddaaa
JG
1233end:
1234 return ret;
1235}
1236
1237struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1238 struct bt_ctf_field_type *type,
1239 const char *name)
1240{
1241 size_t index;
1242 GQuark name_quark;
1243 struct structure_field *field;
1244 struct bt_ctf_field_type_structure *structure;
1245 struct bt_ctf_field_type *field_type = NULL;
1246
1247 if (!type || !name) {
1248 goto end;
1249 }
1250
1251 name_quark = g_quark_try_string(name);
1252 if (!name_quark) {
1253 goto end;
1254 }
1255
1256 structure = container_of(type, struct bt_ctf_field_type_structure,
1257 parent);
1258 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1259 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1260 goto end;
273b65be 1261 }
b92ddaaa
JG
1262
1263 field = structure->fields->pdata[index];
1264 field_type = field->type;
1265 bt_ctf_field_type_get(field_type);
273b65be 1266end:
b92ddaaa 1267 return field_type;
273b65be
JG
1268}
1269
1270struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1271 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1272{
1273 struct bt_ctf_field_type_variant *variant = NULL;
1274
6964b7fd 1275 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
273b65be
JG
1276 goto error;
1277 }
1278
1279 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1280 if (!variant) {
1281 goto error;
1282 }
1283
1284 variant->parent.declaration = &variant->declaration.p;
1285 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1286 variant->tag_name = g_string_new(tag_name);
273b65be
JG
1287 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1288 variant->fields = g_ptr_array_new_with_free_func(
1289 (GDestroyNotify)destroy_structure_field);
6964b7fd
JG
1290 if (enum_tag) {
1291 bt_ctf_field_type_get(enum_tag);
1292 variant->tag = container_of(enum_tag,
1293 struct bt_ctf_field_type_enumeration, parent);
1294 }
1295
59acd4f5 1296 bt_ctf_field_type_init(&variant->parent, TRUE);
46caf2cb
JG
1297 /* A variant's alignment is undefined */
1298 variant->parent.declaration->alignment = 0;
273b65be
JG
1299 return &variant->parent;
1300error:
1301 return NULL;
1302}
1303
b92ddaaa
JG
1304struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1305 struct bt_ctf_field_type *type)
1306{
1307 struct bt_ctf_field_type_variant *variant;
1308 struct bt_ctf_field_type *tag_type = NULL;
1309
1310 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1311 goto end;
1312 }
1313
1314 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd
JG
1315 if (!variant->tag) {
1316 goto end;
1317 }
1318
b92ddaaa
JG
1319 tag_type = &variant->tag->parent;
1320 bt_ctf_field_type_get(tag_type);
1321end:
1322 return tag_type;
1323}
1324
1325const char *bt_ctf_field_type_variant_get_tag_name(
1326 struct bt_ctf_field_type *type)
1327{
1328 struct bt_ctf_field_type_variant *variant;
1329 const char *tag_name = NULL;
1330
1331 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1332 goto end;
1333 }
1334
1335 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd
JG
1336 if (variant->tag_name->len == 0) {
1337 goto end;
1338 }
1339
b92ddaaa
JG
1340 tag_name = variant->tag_name->str;
1341end:
1342 return tag_name;
1343}
1344
d9b1ab6d
JG
1345int bt_ctf_field_type_variant_set_tag_name(
1346 struct bt_ctf_field_type *type, const char *name)
1347{
1348 int ret = 0;
1349 struct bt_ctf_field_type_variant *variant;
1350
1351 if (!type || type->frozen ||
1352 (type->declaration->id != CTF_TYPE_VARIANT) ||
1353 bt_ctf_validate_identifier(name)) {
1354 ret = -1;
1355 goto end;
1356 }
1357
1358 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1359 g_string_assign(variant->tag_name, name);
1360end:
1361 return ret;
1362}
1363
273b65be
JG
1364int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1365 struct bt_ctf_field_type *field_type,
1366 const char *field_name)
1367{
1368 size_t i;
1369 int ret = 0;
273b65be
JG
1370 struct bt_ctf_field_type_variant *variant;
1371 GQuark field_name_quark = g_quark_from_string(field_name);
1372
1373 if (!type || !field_type || type->frozen ||
654c1444 1374 bt_ctf_validate_identifier(field_name) ||
9ce21c30
JG
1375 (type->declaration->id != CTF_TYPE_VARIANT) ||
1376 bt_ctf_field_type_validate(field_type)) {
273b65be
JG
1377 ret = -1;
1378 goto end;
1379 }
1380
1381 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
273b65be 1382
6964b7fd
JG
1383 /* The user has explicitly provided a tag; validate against it. */
1384 if (variant->tag) {
1385 int name_found = 0;
1386
1387 /* Make sure this name is present in the enum tag */
1388 for (i = 0; i < variant->tag->entries->len; i++) {
1389 struct enumeration_mapping *mapping =
1390 g_ptr_array_index(variant->tag->entries, i);
1391
1392 if (mapping->string == field_name_quark) {
1393 name_found = 1;
1394 break;
1395 }
1396 }
1397
1398 if (!name_found) {
1399 /* Validation failed */
1400 ret = -1;
1401 goto end;
273b65be
JG
1402 }
1403 }
1404
6964b7fd
JG
1405 if (add_structure_field(variant->fields, variant->field_name_to_index,
1406 field_type, field_name)) {
273b65be
JG
1407 ret = -1;
1408 goto end;
1409 }
1410end:
1411 return ret;
1412}
1413
b92ddaaa
JG
1414struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1415 struct bt_ctf_field_type *type,
1416 const char *field_name)
1417{
1418 size_t index;
1419 GQuark name_quark;
1420 struct structure_field *field;
1421 struct bt_ctf_field_type_variant *variant;
1422 struct bt_ctf_field_type *field_type = NULL;
1423
1424 if (!type || !field_name) {
1425 goto end;
1426 }
1427
1428 name_quark = g_quark_try_string(field_name);
1429 if (!name_quark) {
1430 goto end;
1431 }
1432
1433 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1434 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1435 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1436 goto end;
1437 }
1438
1439 field = g_ptr_array_index(variant->fields, index);
1440 field_type = field->type;
1441 bt_ctf_field_type_get(field_type);
1442end:
1443 return field_type;
1444}
1445
1446struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1447 struct bt_ctf_field_type *type,
1448 struct bt_ctf_field *tag)
1449{
1450 const char *enum_value;
1451 struct bt_ctf_field_type *field_type = NULL;
1452
1453 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1454 goto end;
1455 }
1456
1457 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1458 if (!enum_value) {
1459 goto end;
1460 }
1461
1462 /* Already increments field_type's reference count */
1463 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1464 type, enum_value);
1465end:
1466 return field_type;
1467}
1468
074ee56d 1469int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
b92ddaaa 1470{
074ee56d 1471 int ret = 0;
b92ddaaa
JG
1472 struct bt_ctf_field_type_variant *variant;
1473
1474 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1475 ret = -1;
1476 goto end;
1477 }
1478
1479 variant = container_of(type, struct bt_ctf_field_type_variant,
1480 parent);
074ee56d 1481 ret = (int) variant->fields->len;
b92ddaaa
JG
1482end:
1483 return ret;
1484
1485}
1486
1487int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1488 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 1489 int index)
b92ddaaa
JG
1490{
1491 struct bt_ctf_field_type_variant *variant;
1492 struct structure_field *field;
1493 int ret = 0;
1494
647f3b93 1495 if (!type || index < 0 || (type->declaration->id != CTF_TYPE_VARIANT)) {
b92ddaaa
JG
1496 ret = -1;
1497 goto end;
1498 }
1499
1500 variant = container_of(type, struct bt_ctf_field_type_variant,
1501 parent);
1502 if (index >= variant->fields->len) {
1503 ret = -1;
1504 goto end;
1505 }
1506
1507 field = g_ptr_array_index(variant->fields, index);
647f3b93
JG
1508 if (field_type) {
1509 *field_type = field->type;
1510 bt_ctf_field_type_get(field->type);
1511 }
1512 if (field_name) {
1513 *field_name = g_quark_to_string(field->name);
1514 }
b92ddaaa
JG
1515end:
1516 return ret;
1517}
1518
273b65be
JG
1519struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1520 struct bt_ctf_field_type *element_type,
1521 unsigned int length)
1522{
1523 struct bt_ctf_field_type_array *array = NULL;
1524
9ce21c30
JG
1525 if (!element_type || length == 0 ||
1526 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1527 goto error;
1528 }
1529
1530 array = g_new0(struct bt_ctf_field_type_array, 1);
1531 if (!array) {
1532 goto error;
1533 }
1534
1535 array->parent.declaration = &array->declaration.p;
1536 array->parent.declaration->id = CTF_TYPE_ARRAY;
c35a1669 1537
273b65be
JG
1538 bt_ctf_field_type_get(element_type);
1539 array->element_type = element_type;
1540 array->length = length;
59acd4f5 1541 bt_ctf_field_type_init(&array->parent, FALSE);
273b65be
JG
1542 return &array->parent;
1543error:
1544 return NULL;
1545}
1546
b92ddaaa
JG
1547struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1548 struct bt_ctf_field_type *type)
1549{
1550 struct bt_ctf_field_type *ret = NULL;
1551 struct bt_ctf_field_type_array *array;
1552
1553 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1554 goto end;
1555 }
1556
1557 array = container_of(type, struct bt_ctf_field_type_array, parent);
1558 ret = array->element_type;
1559 bt_ctf_field_type_get(ret);
1560end:
1561 return ret;
1562}
1563
1564int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1565{
1566 int64_t ret;
1567 struct bt_ctf_field_type_array *array;
1568
1569 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1570 ret = -1;
1571 goto end;
1572 }
1573
1574 array = container_of(type, struct bt_ctf_field_type_array, parent);
1575 ret = (int64_t) array->length;
1576end:
1577 return ret;
1578}
1579
273b65be
JG
1580struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1581 struct bt_ctf_field_type *element_type,
1582 const char *length_field_name)
1583{
1584 struct bt_ctf_field_type_sequence *sequence = NULL;
1585
654c1444 1586 if (!element_type || bt_ctf_validate_identifier(length_field_name) ||
9ce21c30 1587 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
1588 goto error;
1589 }
1590
1591 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1592 if (!sequence) {
1593 goto error;
1594 }
1595
1596 sequence->parent.declaration = &sequence->declaration.p;
1597 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
273b65be
JG
1598 bt_ctf_field_type_get(element_type);
1599 sequence->element_type = element_type;
1600 sequence->length_field_name = g_string_new(length_field_name);
59acd4f5 1601 bt_ctf_field_type_init(&sequence->parent, FALSE);
273b65be
JG
1602 return &sequence->parent;
1603error:
1604 return NULL;
1605}
1606
b92ddaaa
JG
1607struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1608 struct bt_ctf_field_type *type)
1609{
1610 struct bt_ctf_field_type *ret = NULL;
1611 struct bt_ctf_field_type_sequence *sequence;
1612
1613 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1614 goto end;
1615 }
1616
1617 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1618 parent);
1619 ret = sequence->element_type;
1620 bt_ctf_field_type_get(ret);
1621end:
1622 return ret;
1623}
1624
1625const char *bt_ctf_field_type_sequence_get_length_field_name(
1626 struct bt_ctf_field_type *type)
1627{
1628 const char *ret = NULL;
1629 struct bt_ctf_field_type_sequence *sequence;
1630
1631 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1632 goto end;
1633 }
1634
1635 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1636 parent);
1637 ret = sequence->length_field_name->str;
1638end:
1639 return ret;
1640}
1641
273b65be
JG
1642struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1643{
1644 struct bt_ctf_field_type_string *string =
1645 g_new0(struct bt_ctf_field_type_string, 1);
1646
1647 if (!string) {
1648 return NULL;
1649 }
1650
1651 string->parent.declaration = &string->declaration.p;
1652 string->parent.declaration->id = CTF_TYPE_STRING;
59acd4f5 1653 bt_ctf_field_type_init(&string->parent, TRUE);
273b65be
JG
1654 string->declaration.encoding = CTF_STRING_UTF8;
1655 string->parent.declaration->alignment = CHAR_BIT;
1656 return &string->parent;
1657}
1658
b92ddaaa
JG
1659enum ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1660 struct bt_ctf_field_type *type)
1661{
1662 struct bt_ctf_field_type_string *string;
1663 enum ctf_string_encoding ret = CTF_STRING_UNKNOWN;
1664
1665 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1666 goto end;
1667 }
1668
1669 string = container_of(type, struct bt_ctf_field_type_string,
1670 parent);
1671 ret = string->declaration.encoding;
1672end:
1673 return ret;
1674}
1675
1676int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
273b65be
JG
1677 enum ctf_string_encoding encoding)
1678{
1679 int ret = 0;
1680 struct bt_ctf_field_type_string *string;
1681
1682 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1683 (encoding != CTF_STRING_UTF8 &&
1684 encoding != CTF_STRING_ASCII)) {
1685 ret = -1;
1686 goto end;
1687 }
1688
1689 string = container_of(type, struct bt_ctf_field_type_string, parent);
1690 string->declaration.encoding = encoding;
1691end:
1692 return ret;
1693}
1694
b92ddaaa
JG
1695int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1696{
1697 int ret;
3ffba961 1698 enum ctf_type_id type_id;
b92ddaaa
JG
1699
1700 if (!type) {
1701 ret = -1;
1702 goto end;
1703 }
1704
3ffba961
JG
1705 if (type->frozen) {
1706 ret = (int) type->declaration->alignment;
1707 goto end;
1708 }
1709
1710 type_id = bt_ctf_field_type_get_type_id(type);
1711 switch (type_id) {
1712 case CTF_TYPE_SEQUENCE:
1713 {
1714 struct bt_ctf_field_type *element =
1715 bt_ctf_field_type_sequence_get_element_type(type);
1716
1717 if (!element) {
1718 ret = -1;
1719 goto end;
1720 }
1721
1722 ret = bt_ctf_field_type_get_alignment(element);
1723 bt_ctf_field_type_put(element);
1724 break;
1725 }
1726 case CTF_TYPE_ARRAY:
1727 {
1728 struct bt_ctf_field_type *element =
1729 bt_ctf_field_type_array_get_element_type(type);
1730
1731 if (!element) {
1732 ret = -1;
1733 goto end;
1734 }
1735
1736 ret = bt_ctf_field_type_get_alignment(element);
1737 bt_ctf_field_type_put(element);
1738 break;
1739 }
1740 case CTF_TYPE_STRUCT:
1741 {
1742 int i, element_count;
1743
1744 element_count = bt_ctf_field_type_structure_get_field_count(
1745 type);
1746 if (element_count < 0) {
1747 ret = element_count;
1748 goto end;
1749 }
1750
1751 for (i = 0; i < element_count; i++) {
1752 struct bt_ctf_field_type *field;
1753 int field_alignment;
1754
1755 ret = bt_ctf_field_type_structure_get_field(type, NULL,
1756 &field, i);
1757 if (ret) {
1758 goto end;
1759 }
1760
1761 assert(field);
1762 field_alignment = bt_ctf_field_type_get_alignment(
1763 field);
1764 bt_ctf_field_type_put(field);
1765 if (field_alignment < 0) {
1766 ret = field_alignment;
1767 goto end;
1768 }
1769
1770 type->declaration->alignment = MAX(field_alignment,
1771 type->declaration->alignment);
1772 }
1773 ret = (int) type->declaration->alignment;
1774 break;
1775 }
1776 case CTF_TYPE_UNKNOWN:
1777 ret = -1;
1778 break;
1779 default:
1780 ret = (int) type->declaration->alignment;
1781 break;
1782 }
b92ddaaa
JG
1783end:
1784 return ret;
1785}
1786
9ad2f879
PP
1787static inline
1788int is_power_of_two(unsigned int value)
1789{
1790 return ((value & (value - 1)) == 0) && value > 0;
1791}
1792
273b65be
JG
1793int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
1794 unsigned int alignment)
1795{
1796 int ret = 0;
6a43d732 1797 enum ctf_type_id type_id;
273b65be 1798
9ad2f879
PP
1799 /* Alignment must be a power of two */
1800 if (!type || type->frozen || !is_power_of_two(alignment)) {
273b65be
JG
1801 ret = -1;
1802 goto end;
1803 }
1804
6a43d732
JG
1805 type_id = bt_ctf_field_type_get_type_id(type);
1806 if (type_id == CTF_TYPE_UNKNOWN) {
1807 ret = -1;
1808 goto end;
1809 }
1810
273b65be
JG
1811 if (type->declaration->id == CTF_TYPE_STRING &&
1812 alignment != CHAR_BIT) {
1813 ret = -1;
1814 goto end;
1815 }
1816
40e99cb3
PP
1817 if (type_id == CTF_TYPE_VARIANT || type_id == CTF_TYPE_SEQUENCE ||
1818 type_id == CTF_TYPE_ARRAY) {
6a43d732
JG
1819 /* Setting an alignment on these types makes no sense */
1820 ret = -1;
1821 goto end;
1822 }
1823
273b65be
JG
1824 type->declaration->alignment = alignment;
1825 ret = 0;
1826end:
1827 return ret;
1828}
1829
b92ddaaa
JG
1830enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1831 struct bt_ctf_field_type *type)
1832{
1833 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
c35a1669 1834 int internal_byte_order = -1;
b92ddaaa
JG
1835
1836 if (!type) {
1837 goto end;
1838 }
1839
1840 switch (type->declaration->id) {
1841 case CTF_TYPE_INTEGER:
1842 {
1843 struct bt_ctf_field_type_integer *integer = container_of(
1844 type, struct bt_ctf_field_type_integer, parent);
c35a1669 1845 internal_byte_order = integer->declaration.byte_order;
b92ddaaa
JG
1846 break;
1847 }
1848 case CTF_TYPE_FLOAT:
1849 {
1850 struct bt_ctf_field_type_floating_point *floating_point =
1851 container_of(type,
1852 struct bt_ctf_field_type_floating_point,
1853 parent);
c35a1669 1854 internal_byte_order = floating_point->declaration.byte_order;
b92ddaaa
JG
1855 break;
1856 }
1857 default:
c35a1669
JG
1858 goto end;
1859 }
1860
1861 switch (internal_byte_order) {
1862 case LITTLE_ENDIAN:
1863 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
b92ddaaa 1864 break;
c35a1669
JG
1865 case BIG_ENDIAN:
1866 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1867 break;
1868 case 0:
1869 ret = BT_CTF_BYTE_ORDER_NATIVE;
1870 break;
1871 default:
1872 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
b92ddaaa
JG
1873 }
1874end:
1875 return ret;
1876}
1877
273b65be
JG
1878int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
1879 enum bt_ctf_byte_order byte_order)
1880{
1881 int ret = 0;
1882 int internal_byte_order;
1883 enum ctf_type_id type_id;
1884
1885 if (!type || type->frozen) {
1886 ret = -1;
1887 goto end;
1888 }
1889
273b65be
JG
1890 switch (byte_order) {
1891 case BT_CTF_BYTE_ORDER_NATIVE:
c35a1669
JG
1892 /* Leave unset. Will be initialized by parent. */
1893 internal_byte_order = 0;
273b65be
JG
1894 break;
1895 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
1896 internal_byte_order = LITTLE_ENDIAN;
1897 break;
1898 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
1899 case BT_CTF_BYTE_ORDER_NETWORK:
1900 internal_byte_order = BIG_ENDIAN;
1901 break;
1902 default:
1903 ret = -1;
1904 goto end;
1905 }
1906
3fa759e9 1907 type_id = type->declaration->id;
273b65be 1908 if (set_byte_order_funcs[type_id]) {
c35a1669 1909 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
273b65be
JG
1910 }
1911end:
1912 return ret;
1913}
1914
b92ddaaa
JG
1915enum ctf_type_id bt_ctf_field_type_get_type_id(
1916 struct bt_ctf_field_type *type)
1917{
1918 if (!type) {
1919 return CTF_TYPE_UNKNOWN;
1920 }
1921
1922 return type->declaration->id;
1923}
2f2d8e05 1924
273b65be
JG
1925void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
1926{
de3dd40e 1927 bt_ctf_get(type);
273b65be
JG
1928}
1929
1930void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
1931{
de3dd40e 1932 bt_ctf_put(type);
273b65be
JG
1933}
1934
1935BT_HIDDEN
1936void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
1937{
1938 if (!type) {
1939 return;
1940 }
1941
1942 type->freeze(type);
1943}
1944
1945BT_HIDDEN
b92ddaaa
JG
1946struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
1947 struct bt_ctf_field_type_variant *variant,
1948 int64_t tag_value)
273b65be
JG
1949{
1950 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
1951 GQuark field_name_quark;
1952 gpointer index;
1953 struct structure_field *field_entry;
1954 struct range_overlap_query query = {
1955 .range_start._signed = tag_value,
1956 .range_end._signed = tag_value,
1957 .mapping_name = 0, .overlaps = 0};
273b65be 1958
b92ddaaa
JG
1959 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
1960 &query);
1961 if (!query.overlaps) {
273b65be
JG
1962 goto end;
1963 }
1964
b92ddaaa
JG
1965 field_name_quark = query.mapping_name;
1966 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1967 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
273b65be
JG
1968 goto end;
1969 }
1970
e54fab7e 1971 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
b92ddaaa 1972 type = field_entry->type;
273b65be
JG
1973end:
1974 return type;
1975}
1976
1977BT_HIDDEN
b92ddaaa 1978struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 1979 struct bt_ctf_field_type_variant *variant,
b92ddaaa 1980 uint64_t tag_value)
273b65be
JG
1981{
1982 struct bt_ctf_field_type *type = NULL;
1983 GQuark field_name_quark;
1984 gpointer index;
1985 struct structure_field *field_entry;
b92ddaaa
JG
1986 struct range_overlap_query query = {
1987 .range_start._unsigned = tag_value,
1988 .range_end._unsigned = tag_value,
1989 .mapping_name = 0, .overlaps = 0};
273b65be 1990
b92ddaaa
JG
1991 g_ptr_array_foreach(variant->tag->entries,
1992 check_ranges_overlap_unsigned,
273b65be
JG
1993 &query);
1994 if (!query.overlaps) {
1995 goto end;
1996 }
1997
1998 field_name_quark = query.mapping_name;
1999 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2000 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2001 goto end;
2002 }
2003
2004 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2005 type = field_entry->type;
2006end:
2007 return type;
2008}
2009
2010BT_HIDDEN
2011int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2012 struct metadata_context *context)
2013{
2014 int ret;
2015
2016 if (!type || !context) {
2017 ret = -1;
2018 goto end;
2019 }
2020
2021 ret = type->serialize(type, context);
2022end:
2023 return ret;
2024}
2025
c35a1669
JG
2026BT_HIDDEN
2027void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2028 int byte_order)
2029{
2030 if (!type) {
2031 return;
2032 }
2033
2034 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2035 if (set_byte_order_funcs[type->declaration->id]) {
2036 set_byte_order_funcs[type->declaration->id](type,
2037 byte_order, 1);
2038 }
2039}
2040
24724933
JG
2041BT_HIDDEN
2042struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2043{
2044 struct bt_ctf_field_type *copy = NULL;
2045
2046 if (!type) {
2047 goto end;
2048 }
2049
2050 copy = type_copy_funcs[type->declaration->id](type);
2051end:
2052 return copy;
2053}
2054
6b64f185
JG
2055BT_HIDDEN
2056struct bt_ctf_field_path *bt_ctf_field_path_create(void)
2057{
2058 struct bt_ctf_field_path *field_path = NULL;
2059
2060 field_path = g_new0(struct bt_ctf_field_path, 1);
2061 if (!field_path) {
2062 goto end;
2063 }
2064
2065 field_path->root = CTF_NODE_UNKNOWN;
2066 field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int));
2067 if (!field_path->path_indexes) {
2068 bt_ctf_field_path_destroy(field_path);
2069 field_path = NULL;
2070 }
2071end:
2072 return field_path;
2073}
2074
2075
2076BT_HIDDEN
2077struct bt_ctf_field_path *bt_ctf_field_path_copy(
2078 struct bt_ctf_field_path *path)
2079{
2080 struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
2081
2082 if (!new_path) {
2083 goto end;
2084 }
2085
2086 new_path->root = path->root;
2087 g_array_insert_vals(new_path->path_indexes, 0,
2088 path->path_indexes->data, path->path_indexes->len);
2089end:
2090 return new_path;
2091}
2092
2093BT_HIDDEN
2094void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
2095{
2096 if (!path) {
2097 return;
2098 }
2099
2100 if (path->path_indexes) {
2101 g_array_free(path->path_indexes, TRUE);
2102 }
2103 g_free(path);
2104}
39a5e0db
JG
2105
2106BT_HIDDEN
2107int bt_ctf_field_type_structure_get_field_name_index(
2108 struct bt_ctf_field_type *type, const char *name)
2109{
2110 int ret;
2111 size_t index;
2112 GQuark name_quark;
2113 struct bt_ctf_field_type_structure *structure;
2114
2115 if (!type || !name ||
2116 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2117 ret = -1;
2118 goto end;
2119 }
2120
2121 name_quark = g_quark_try_string(name);
2122 if (!name_quark) {
2123 ret = -1;
2124 goto end;
2125 }
2126
2127 structure = container_of(type, struct bt_ctf_field_type_structure,
2128 parent);
2129 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2130 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2131 ret = -1;
2132 goto end;
2133 }
2134 ret = (int) index;
2135end:
2136 return ret;
2137}
736133f1 2138
5cec03e4
JG
2139BT_HIDDEN
2140int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2141 struct bt_ctf_field_type *field, int index)
2142{
2143 int ret = 0;
2144 struct bt_ctf_field_type_structure *structure;
2145
6c827042 2146 if (!type || !field ||
5cec03e4
JG
2147 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2148 ret = -1;
2149 goto end;
2150 }
2151
2152 structure = container_of(type, struct bt_ctf_field_type_structure,
2153 parent);
2154 if (index < 0 || index >= structure->fields->len) {
2155 ret = -1;
2156 goto end;
2157 }
2158
2159 bt_ctf_field_type_get(field);
2160 bt_ctf_field_type_put(((struct structure_field *)
2161 g_ptr_array_index(structure->fields, index))->type);
2162 ((struct structure_field *) structure->fields->pdata[index])->type =
2163 field;
2164end:
2165 return ret;
2166}
2167
736133f1
JG
2168BT_HIDDEN
2169int bt_ctf_field_type_variant_get_field_name_index(
2170 struct bt_ctf_field_type *type, const char *name)
2171{
2172 int ret;
2173 size_t index;
2174 GQuark name_quark;
2175 struct bt_ctf_field_type_variant *variant;
2176
2177 if (!type || !name ||
2178 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2179 ret = -1;
2180 goto end;
2181 }
2182
2183 name_quark = g_quark_try_string(name);
2184 if (!name_quark) {
2185 ret = -1;
2186 goto end;
2187 }
2188
2189 variant = container_of(type, struct bt_ctf_field_type_variant,
2190 parent);
2191 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2192 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2193 ret = -1;
2194 goto end;
2195 }
2196 ret = (int) index;
2197end:
2198 return ret;
2199}
aa4e271c
JG
2200
2201BT_HIDDEN
2202int bt_ctf_field_type_sequence_set_length_field_path(
2203 struct bt_ctf_field_type *type,
2204 struct bt_ctf_field_path *path)
2205{
2206 int ret = 0;
2207 struct bt_ctf_field_type_sequence *sequence;
2208
2209 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) {
2210 ret = -1;
2211 goto end;
2212 }
2213
2214 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2215 parent);
2216 if (sequence->length_field_path) {
2217 bt_ctf_field_path_destroy(sequence->length_field_path);
2218 }
2219 sequence->length_field_path = path;
2220end:
2221 return ret;
2222}
4a1e8671
JG
2223
2224BT_HIDDEN
2225int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2226 struct bt_ctf_field_path *path)
2227{
2228 int ret = 0;
2229 struct bt_ctf_field_type_variant *variant;
2230
2231 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2232 ret = -1;
2233 goto end;
2234 }
2235
2236 variant = container_of(type, struct bt_ctf_field_type_variant,
2237 parent);
2238 if (variant->tag_path) {
2239 bt_ctf_field_path_destroy(variant->tag_path);
2240 }
2241 variant->tag_path = path;
2242end:
2243 return ret;
2244}
3f39933a
JG
2245
2246BT_HIDDEN
2247int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
2248 struct bt_ctf_field_type *tag)
2249{
2250 int ret = 0;
2251 struct bt_ctf_field_type_variant *variant;
2252
2253 if (!type || !tag || type->frozen ||
2254 bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
2255 ret = -1;
2256 goto end;
2257 }
2258
2259 variant = container_of(type, struct bt_ctf_field_type_variant,
2260 parent);
2261 bt_ctf_field_type_get(tag);
2262 if (variant->tag) {
2263 bt_ctf_field_type_put(&variant->tag->parent);
2264 }
2265 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2266 parent);
2267end:
2268 return ret;
2269}
2270
5cec03e4
JG
2271BT_HIDDEN
2272int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2273 struct bt_ctf_field_type *field, int index)
2274{
2275 int ret = 0;
2276 struct bt_ctf_field_type_variant *variant;
2277
6c827042 2278 if (!type || !field ||
5cec03e4
JG
2279 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2280 ret = -1;
2281 goto end;
2282 }
2283
2284 variant = container_of(type, struct bt_ctf_field_type_variant,
2285 parent);
2286 if (index < 0 || index >= variant->fields->len) {
2287 ret = -1;
2288 goto end;
2289 }
2290
2291 bt_ctf_field_type_get(field);
2292 bt_ctf_field_type_put(((struct structure_field *)
2293 g_ptr_array_index(variant->fields, index))->type);
2294 ((struct structure_field *) variant->fields->pdata[index])->type =
2295 field;
2296end:
2297 return ret;
2298}
2299
273b65be 2300static
de3dd40e 2301void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
273b65be 2302{
de3dd40e
PP
2303 struct bt_ctf_field_type_integer *integer =
2304 (struct bt_ctf_field_type_integer *) type;
273b65be 2305
de3dd40e 2306 if (!type) {
273b65be
JG
2307 return;
2308 }
2309
eee752e5
JG
2310 if (integer->mapped_clock) {
2311 bt_ctf_clock_put(integer->mapped_clock);
2312 }
273b65be
JG
2313 g_free(integer);
2314}
2315
2316static
de3dd40e 2317void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
273b65be 2318{
de3dd40e
PP
2319 struct bt_ctf_field_type_enumeration *enumeration =
2320 (struct bt_ctf_field_type_enumeration *) type;
273b65be 2321
de3dd40e 2322 if (!type) {
273b65be
JG
2323 return;
2324 }
2325
273b65be
JG
2326 g_ptr_array_free(enumeration->entries, TRUE);
2327 bt_ctf_field_type_put(enumeration->container);
2328 g_free(enumeration);
2329}
2330
2331static
de3dd40e 2332void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
273b65be 2333{
de3dd40e
PP
2334 struct bt_ctf_field_type_floating_point *floating_point =
2335 (struct bt_ctf_field_type_floating_point *) type;
273b65be 2336
de3dd40e 2337 if (!type) {
273b65be
JG
2338 return;
2339 }
2340
273b65be
JG
2341 g_free(floating_point);
2342}
2343
2344static
de3dd40e 2345void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
273b65be 2346{
de3dd40e
PP
2347 struct bt_ctf_field_type_structure *structure =
2348 (struct bt_ctf_field_type_structure *) type;
273b65be 2349
de3dd40e 2350 if (!type) {
273b65be
JG
2351 return;
2352 }
2353
273b65be
JG
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
de3dd40e 2360void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
273b65be 2361{
de3dd40e
PP
2362 struct bt_ctf_field_type_variant *variant =
2363 (struct bt_ctf_field_type_variant *) type;
273b65be 2364
de3dd40e 2365 if (!type) {
273b65be
JG
2366 return;
2367 }
2368
273b65be
JG
2369 g_ptr_array_free(variant->fields, TRUE);
2370 g_hash_table_destroy(variant->field_name_to_index);
2371 g_string_free(variant->tag_name, TRUE);
2372 bt_ctf_field_type_put(&variant->tag->parent);
4a1e8671 2373 bt_ctf_field_path_destroy(variant->tag_path);
273b65be
JG
2374 g_free(variant);
2375}
2376
2377static
de3dd40e 2378void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
273b65be 2379{
de3dd40e
PP
2380 struct bt_ctf_field_type_array *array =
2381 (struct bt_ctf_field_type_array *) type;
273b65be 2382
de3dd40e 2383 if (!type) {
273b65be
JG
2384 return;
2385 }
2386
273b65be
JG
2387 bt_ctf_field_type_put(array->element_type);
2388 g_free(array);
2389}
2390
2391static
de3dd40e 2392void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
273b65be 2393{
de3dd40e
PP
2394 struct bt_ctf_field_type_sequence *sequence =
2395 (struct bt_ctf_field_type_sequence *) type;
273b65be 2396
de3dd40e 2397 if (!type) {
273b65be
JG
2398 return;
2399 }
2400
273b65be
JG
2401 bt_ctf_field_type_put(sequence->element_type);
2402 g_string_free(sequence->length_field_name, TRUE);
aa4e271c 2403 bt_ctf_field_path_destroy(sequence->length_field_path);
273b65be
JG
2404 g_free(sequence);
2405}
2406
2407static
de3dd40e 2408void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
273b65be 2409{
de3dd40e
PP
2410 struct bt_ctf_field_type_string *string =
2411 (struct bt_ctf_field_type_string *) type;
273b65be 2412
de3dd40e 2413 if (!type) {
273b65be
JG
2414 return;
2415 }
2416
273b65be
JG
2417 g_free(string);
2418}
2419
2420static
2421void generic_field_type_freeze(struct bt_ctf_field_type *type)
2422{
2423 type->frozen = 1;
2424}
2425
2426static
2427void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2428{
2429 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2430 type, struct bt_ctf_field_type_enumeration, parent);
2431
2432 generic_field_type_freeze(type);
2433 bt_ctf_field_type_freeze(enumeration_type->container);
2434}
2435
2436static
2437void freeze_structure_field(struct structure_field *field)
2438{
2439 bt_ctf_field_type_freeze(field->type);
2440}
2441
2442static
2443void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2444{
2445 struct bt_ctf_field_type_structure *structure_type = container_of(
2446 type, struct bt_ctf_field_type_structure, parent);
2447
3ffba961
JG
2448 /* Cache the alignment */
2449 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2450 generic_field_type_freeze(type);
3ffba961
JG
2451 g_ptr_array_foreach(structure_type->fields,
2452 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2453}
2454
2455static
2456void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2457{
2458 struct bt_ctf_field_type_variant *variant_type = container_of(
2459 type, struct bt_ctf_field_type_variant, parent);
2460
3ffba961
JG
2461 /* Cache the alignment */
2462 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2463 generic_field_type_freeze(type);
3ffba961
JG
2464 g_ptr_array_foreach(variant_type->fields,
2465 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2466}
2467
2468static
2469void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2470{
2471 struct bt_ctf_field_type_array *array_type = container_of(
2472 type, struct bt_ctf_field_type_array, parent);
2473
3ffba961
JG
2474 /* Cache the alignment */
2475 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2476 generic_field_type_freeze(type);
2477 bt_ctf_field_type_freeze(array_type->element_type);
2478}
2479
2480static
2481void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2482{
2483 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2484 type, struct bt_ctf_field_type_sequence, parent);
2485
3ffba961
JG
2486 /* Cache the alignment */
2487 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2488 generic_field_type_freeze(type);
2489 bt_ctf_field_type_freeze(sequence_type->element_type);
2490}
2491
2492static
2493const char *get_encoding_string(enum ctf_string_encoding encoding)
2494{
2495 const char *encoding_string;
2496
2497 switch (encoding) {
2498 case CTF_STRING_NONE:
2499 encoding_string = "none";
2500 break;
2501 case CTF_STRING_ASCII:
2502 encoding_string = "ASCII";
2503 break;
2504 case CTF_STRING_UTF8:
2505 encoding_string = "UTF8";
2506 break;
2507 default:
2508 encoding_string = "unknown";
2509 break;
2510 }
2511
2512 return encoding_string;
2513}
2514
2515static
2516const char *get_integer_base_string(enum bt_ctf_integer_base base)
2517{
2518 const char *base_string;
2519
2520 switch (base) {
2521 case BT_CTF_INTEGER_BASE_DECIMAL:
2522 base_string = "decimal";
2523 break;
2524 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2525 base_string = "hexadecimal";
2526 break;
2527 case BT_CTF_INTEGER_BASE_OCTAL:
2528 base_string = "octal";
2529 break;
2530 case BT_CTF_INTEGER_BASE_BINARY:
2531 base_string = "binary";
2532 break;
2533 default:
2534 base_string = "unknown";
2535 break;
2536 }
2537
2538 return base_string;
2539}
2540
2541static
2542int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2543 struct metadata_context *context)
2544{
2545 struct bt_ctf_field_type_integer *integer = container_of(type,
2546 struct bt_ctf_field_type_integer, parent);
6cfb906f 2547 int ret = 0;
273b65be
JG
2548
2549 g_string_append_printf(context->string,
6cfb906f 2550 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
2551 integer->declaration.len, type->declaration->alignment,
2552 (integer->declaration.signedness ? "true" : "false"),
2553 get_encoding_string(integer->declaration.encoding),
2554 get_integer_base_string(integer->declaration.base),
2555 get_byte_order_string(integer->declaration.byte_order));
6cfb906f
JG
2556 if (integer->mapped_clock) {
2557 const char *clock_name = bt_ctf_clock_get_name(
2558 integer->mapped_clock);
2559
2560 if (!clock_name) {
2561 ret = -1;
2562 goto end;
2563 }
2564
2565 g_string_append_printf(context->string,
4ebdec03 2566 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2567 }
2568
2569 g_string_append(context->string, "; }");
2570end:
2571 return ret;
273b65be
JG
2572}
2573
2574static
2575int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2576 struct metadata_context *context)
2577{
2578 size_t entry;
9ce21c30 2579 int ret;
273b65be
JG
2580 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2581 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2582 struct bt_ctf_field_type *container_type;
2583 int container_signed;
273b65be 2584
9ce21c30
JG
2585 ret = bt_ctf_field_type_validate(type);
2586 if (ret) {
2587 goto end;
2588 }
2589
b92ddaaa
JG
2590 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2591 if (!container_type) {
2592 ret = -1;
2593 goto end;
2594 }
2595
2596 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2597 if (container_signed < 0) {
2598 ret = container_signed;
2599 goto error_put_container_type;
2600 }
2601
273b65be
JG
2602 g_string_append(context->string, "enum : ");
2603 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2604 if (ret) {
b92ddaaa 2605 goto error_put_container_type;
273b65be
JG
2606 }
2607
2608 g_string_append(context->string, " { ");
2609 for (entry = 0; entry < enumeration->entries->len; entry++) {
2610 struct enumeration_mapping *mapping =
2611 enumeration->entries->pdata[entry];
2612
b92ddaaa
JG
2613 if (container_signed) {
2614 if (mapping->range_start._signed ==
2615 mapping->range_end._signed) {
2616 g_string_append_printf(context->string,
2617 "\"%s\" = %" PRId64,
2618 g_quark_to_string(mapping->string),
2619 mapping->range_start._signed);
2620 } else {
2621 g_string_append_printf(context->string,
2622 "\"%s\" = %" PRId64 " ... %" PRId64,
2623 g_quark_to_string(mapping->string),
2624 mapping->range_start._signed,
2625 mapping->range_end._signed);
2626 }
273b65be 2627 } else {
b92ddaaa
JG
2628 if (mapping->range_start._unsigned ==
2629 mapping->range_end._unsigned) {
2630 g_string_append_printf(context->string,
2631 "\"%s\" = %" PRIu64,
2632 g_quark_to_string(mapping->string),
2633 mapping->range_start._unsigned);
2634 } else {
2635 g_string_append_printf(context->string,
2636 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2637 g_quark_to_string(mapping->string),
2638 mapping->range_start._unsigned,
2639 mapping->range_end._unsigned);
2640 }
273b65be
JG
2641 }
2642
2643 g_string_append(context->string,
2644 ((entry != (enumeration->entries->len - 1)) ?
2645 ", " : " }"));
2646 }
2647
2648 if (context->field_name->len) {
2649 g_string_append_printf(context->string, " %s",
2650 context->field_name->str);
2651 g_string_assign(context->field_name, "");
2652 }
b92ddaaa
JG
2653error_put_container_type:
2654 bt_ctf_field_type_put(container_type);
273b65be
JG
2655end:
2656 return ret;
2657}
2658
2659static
2660int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2661 struct metadata_context *context)
2662{
2663 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2664 type, struct bt_ctf_field_type_floating_point, parent);
2665
2666 g_string_append_printf(context->string,
2667 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2668 floating_point->declaration.exp->len,
2669 floating_point->declaration.mantissa->len + 1,
2670 get_byte_order_string(floating_point->declaration.byte_order),
2671 type->declaration->alignment);
2672 return 0;
2673}
2674
2675static
2676int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2677 struct metadata_context *context)
2678{
2679 size_t i;
2680 unsigned int indent;
2681 int ret = 0;
2682 struct bt_ctf_field_type_structure *structure = container_of(type,
2683 struct bt_ctf_field_type_structure, parent);
2684 GString *structure_field_name = context->field_name;
2685
2686 context->field_name = g_string_new("");
2687
2688 context->current_indentation_level++;
2689 g_string_append(context->string, "struct {\n");
2690
2691 for (i = 0; i < structure->fields->len; i++) {
2692 struct structure_field *field;
2693
2694 for (indent = 0; indent < context->current_indentation_level;
2695 indent++) {
2696 g_string_append_c(context->string, '\t');
2697 }
2698
2699 field = structure->fields->pdata[i];
2700 g_string_assign(context->field_name,
2701 g_quark_to_string(field->name));
2702 ret = bt_ctf_field_type_serialize(field->type, context);
2703 if (ret) {
2704 goto end;
2705 }
2706
2707 if (context->field_name->len) {
2708 g_string_append_printf(context->string, " %s",
2709 context->field_name->str);
2710 }
2711 g_string_append(context->string, ";\n");
2712 }
2713
2714 context->current_indentation_level--;
2715 for (indent = 0; indent < context->current_indentation_level;
2716 indent++) {
2717 g_string_append_c(context->string, '\t');
2718 }
2719
2720 g_string_append_printf(context->string, "} align(%zu)",
2721 type->declaration->alignment);
2722end:
2723 g_string_free(context->field_name, TRUE);
2724 context->field_name = structure_field_name;
2725 return ret;
2726}
2727
2728static
2729int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2730 struct metadata_context *context)
2731{
2732 size_t i;
2733 unsigned int indent;
2734 int ret = 0;
2735 struct bt_ctf_field_type_variant *variant = container_of(
2736 type, struct bt_ctf_field_type_variant, parent);
2737 GString *variant_field_name = context->field_name;
2738
2739 context->field_name = g_string_new("");
6964b7fd
JG
2740 if (variant->tag_name->len > 0) {
2741 g_string_append_printf(context->string,
2742 "variant <%s> {\n", variant->tag_name->str);
2743 } else {
2744 g_string_append(context->string, "variant {\n");
2745 }
2746
273b65be
JG
2747 context->current_indentation_level++;
2748 for (i = 0; i < variant->fields->len; i++) {
2749 struct structure_field *field = variant->fields->pdata[i];
2750
2751 g_string_assign(context->field_name,
2752 g_quark_to_string(field->name));
2753 for (indent = 0; indent < context->current_indentation_level;
2754 indent++) {
2755 g_string_append_c(context->string, '\t');
2756 }
2757
2758 g_string_assign(context->field_name,
2759 g_quark_to_string(field->name));
2760 ret = bt_ctf_field_type_serialize(field->type, context);
2761 if (ret) {
2762 goto end;
2763 }
2764
2765 if (context->field_name->len) {
2766 g_string_append_printf(context->string, " %s;",
2767 context->field_name->str);
2768 }
2769
2770 g_string_append_c(context->string, '\n');
2771 }
2772
2773 context->current_indentation_level--;
2774 for (indent = 0; indent < context->current_indentation_level;
2775 indent++) {
2776 g_string_append_c(context->string, '\t');
2777 }
2778
2779 g_string_append(context->string, "}");
2780end:
2781 g_string_free(context->field_name, TRUE);
2782 context->field_name = variant_field_name;
2783 return ret;
2784}
2785
2786static
2787int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2788 struct metadata_context *context)
2789{
2790 int ret = 0;
2791 struct bt_ctf_field_type_array *array = container_of(type,
2792 struct bt_ctf_field_type_array, parent);
2793
2794 ret = bt_ctf_field_type_serialize(array->element_type, context);
2795 if (ret) {
2796 goto end;
2797 }
2798
2799 if (context->field_name->len) {
2800 g_string_append_printf(context->string, " %s[%u]",
2801 context->field_name->str, array->length);
2802 g_string_assign(context->field_name, "");
2803 } else {
2804 g_string_append_printf(context->string, "[%u]", array->length);
2805 }
2806end:
2807 return ret;
2808}
2809
2810static
2811int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2812 struct metadata_context *context)
2813{
2814 int ret = 0;
2815 struct bt_ctf_field_type_sequence *sequence = container_of(
2816 type, struct bt_ctf_field_type_sequence, parent);
2817
2818 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2819 if (ret) {
2820 goto end;
2821 }
2822
2823 if (context->field_name->len) {
2824 g_string_append_printf(context->string, " %s[%s]",
2825 context->field_name->str,
2826 sequence->length_field_name->str);
2827 g_string_assign(context->field_name, "");
2828 } else {
2829 g_string_append_printf(context->string, "[%s]",
2830 sequence->length_field_name->str);
2831 }
2832end:
2833 return ret;
2834}
2835
2836static
2837int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2838 struct metadata_context *context)
2839{
2840 struct bt_ctf_field_type_string *string = container_of(
2841 type, struct bt_ctf_field_type_string, parent);
2842
2843 g_string_append_printf(context->string,
2844 "string { encoding = %s; }",
2845 get_encoding_string(string->declaration.encoding));
2846 return 0;
2847}
2848
2849static
2850void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 2851 int byte_order, int set_native)
273b65be
JG
2852{
2853 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2854 struct bt_ctf_field_type_integer, parent);
2855
c35a1669
JG
2856 if (set_native) {
2857 integer_type->declaration.byte_order =
2858 integer_type->declaration.byte_order == 0 ?
2859 byte_order : integer_type->declaration.byte_order;
2860 } else {
2861 integer_type->declaration.byte_order = byte_order;
2862 }
2863}
2864
2865static
2866void bt_ctf_field_type_enumeration_set_byte_order(
2867 struct bt_ctf_field_type *type, int byte_order, int set_native)
2868{
2869 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
2870 struct bt_ctf_field_type_enumeration, parent);
2871
2872 /* Safe to assume that container is an integer */
2873 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
2874 byte_order, set_native);
273b65be
JG
2875}
2876
2877static
2878void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 2879 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
2880{
2881 struct bt_ctf_field_type_floating_point *floating_point_type =
2882 container_of(type, struct bt_ctf_field_type_floating_point,
2883 parent);
2884
c35a1669
JG
2885 if (set_native) {
2886 floating_point_type->declaration.byte_order =
2887 floating_point_type->declaration.byte_order == 0 ?
2888 byte_order :
2889 floating_point_type->declaration.byte_order;
2890 floating_point_type->sign.byte_order =
2891 floating_point_type->sign.byte_order == 0 ?
2892 byte_order : floating_point_type->sign.byte_order;
2893 floating_point_type->mantissa.byte_order =
2894 floating_point_type->mantissa.byte_order == 0 ?
2895 byte_order : floating_point_type->mantissa.byte_order;
2896 floating_point_type->exp.byte_order =
2897 floating_point_type->exp.byte_order == 0 ?
2898 byte_order : floating_point_type->exp.byte_order;
2899 } else {
2900 floating_point_type->declaration.byte_order = byte_order;
2901 floating_point_type->sign.byte_order = byte_order;
2902 floating_point_type->mantissa.byte_order = byte_order;
2903 floating_point_type->exp.byte_order = byte_order;
2904 }
2905}
2906
2907static
2908void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
2909 int byte_order, int set_native)
2910{
2911 int i;
2912 struct bt_ctf_field_type_structure *structure_type =
2913 container_of(type, struct bt_ctf_field_type_structure,
2914 parent);
2915
2916 for (i = 0; i < structure_type->fields->len; i++) {
2917 struct structure_field *field = g_ptr_array_index(
2918 structure_type->fields, i);
2919 struct bt_ctf_field_type *field_type = field->type;
2920
2921 if (set_byte_order_funcs[field_type->declaration->id]) {
2922 set_byte_order_funcs[field_type->declaration->id](
2923 field_type, byte_order, set_native);
2924 }
2925 }
2926}
2927
2928static
2929void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
2930 int byte_order, int set_native)
2931{
2932 int i;
2933 struct bt_ctf_field_type_variant *variant_type =
2934 container_of(type, struct bt_ctf_field_type_variant,
2935 parent);
2936
2937 for (i = 0; i < variant_type->fields->len; i++) {
2938 struct structure_field *field = g_ptr_array_index(
2939 variant_type->fields, i);
2940 struct bt_ctf_field_type *field_type = field->type;
2941
2942 if (set_byte_order_funcs[field_type->declaration->id]) {
2943 set_byte_order_funcs[field_type->declaration->id](
2944 field_type, byte_order, set_native);
2945 }
2946 }
2947}
2948
2949static
2950void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
2951 int byte_order, int set_native)
2952{
2953 struct bt_ctf_field_type_array *array_type =
2954 container_of(type, struct bt_ctf_field_type_array,
2955 parent);
2956
2957 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
2958 set_byte_order_funcs[array_type->element_type->declaration->id](
2959 array_type->element_type, byte_order, set_native);
2960 }
2961}
2962
2963static
2964void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
2965 int byte_order, int set_native)
2966{
2967 struct bt_ctf_field_type_sequence *sequence_type =
2968 container_of(type, struct bt_ctf_field_type_sequence,
2969 parent);
2970
2971 if (set_byte_order_funcs[
2972 sequence_type->element_type->declaration->id]) {
2973 set_byte_order_funcs[
2974 sequence_type->element_type->declaration->id](
2975 sequence_type->element_type, byte_order, set_native);
2976 }
273b65be 2977}
24724933
JG
2978
2979static
2980struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
2981 struct bt_ctf_field_type *type)
2982{
2983 struct bt_ctf_field_type *copy;
2984 struct bt_ctf_field_type_integer *integer, *copy_integer;
2985
2986 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
2987 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
2988 if (!copy) {
2989 goto end;
2990 }
2991
2992 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
2993 parent);
2994 copy_integer->declaration = integer->declaration;
2995 if (integer->mapped_clock) {
2996 bt_ctf_clock_get(integer->mapped_clock);
2997 copy_integer->mapped_clock = integer->mapped_clock;
2998 }
2999end:
3000 return copy;
3001}
3002
3003static
3004struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3005 struct bt_ctf_field_type *type)
3006{
3007 size_t i;
3008 struct bt_ctf_field_type *copy = NULL, *copy_container;
3009 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3010
3011 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3012 parent);
3013
3014 /* Copy the source enumeration's container */
3015 copy_container = bt_ctf_field_type_copy(enumeration->container);
3016 if (!copy_container) {
3017 goto end;
3018 }
3019
3020 copy = bt_ctf_field_type_enumeration_create(copy_container);
3021 if (!copy) {
3022 goto end;
3023 }
3024 copy_enumeration = container_of(copy,
3025 struct bt_ctf_field_type_enumeration, parent);
3026
3027 /* Copy all enumaration entries */
3028 for (i = 0; i < enumeration->entries->len; i++) {
3029 struct enumeration_mapping *mapping = g_ptr_array_index(
3030 enumeration->entries, i);
3031 struct enumeration_mapping* copy_mapping = g_new0(
3032 struct enumeration_mapping, 1);
3033
3034 if (!copy_mapping) {
3035 goto error;
3036 }
3037
3038 *copy_mapping = *mapping;
3039 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3040 }
3041
3042 copy_enumeration->declaration = enumeration->declaration;
3043end:
3044 if (copy_container) {
3045 bt_ctf_field_type_put(copy_container);
3046 }
3047 return copy;
3048error:
3049 if (copy_container) {
3050 bt_ctf_field_type_put(copy_container);
3051 }
3052 bt_ctf_field_type_put(copy);
3053 return NULL;
3054}
3055
3056static
3057struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3058 struct bt_ctf_field_type *type)
3059{
3060 struct bt_ctf_field_type *copy;
3061 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3062
3063 floating_point = container_of(type,
3064 struct bt_ctf_field_type_floating_point, parent);
3065 copy = bt_ctf_field_type_floating_point_create();
3066 if (!copy) {
3067 goto end;
3068 }
3069
3070 copy_float = container_of(copy,
3071 struct bt_ctf_field_type_floating_point, parent);
3072 copy_float->declaration = floating_point->declaration;
3073 copy_float->sign = floating_point->sign;
3074 copy_float->mantissa = floating_point->mantissa;
3075 copy_float->exp = floating_point->exp;
3076end:
3077 return copy;
3078}
3079
3080static
3081struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3082 struct bt_ctf_field_type *type)
3083{
3084 int i;
3085 GHashTableIter iter;
3086 gpointer key, value;
3087 struct bt_ctf_field_type *copy;
3088 struct bt_ctf_field_type_structure *structure, *copy_structure;
3089
3090 structure = container_of(type, struct bt_ctf_field_type_structure,
3091 parent);
3092 copy = bt_ctf_field_type_structure_create();
3093 if (!copy) {
3094 goto end;
3095 }
3096
3097 copy_structure = container_of(copy,
3098 struct bt_ctf_field_type_structure, parent);
3099
3100 /* Copy field_name_to_index */
3101 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3102 while (g_hash_table_iter_next (&iter, &key, &value)) {
3103 g_hash_table_insert(copy_structure->field_name_to_index,
3104 key, value);
3105 }
3106
3107 for (i = 0; i < structure->fields->len; i++) {
3108 struct structure_field *entry, *copy_entry;
3109 struct bt_ctf_field_type *copy_field;
3110
3111 copy_entry = g_new0(struct structure_field, 1);
3112 if (!copy_entry) {
3113 goto error;
3114 }
3115
3116 entry = g_ptr_array_index(structure->fields, i);
3117 copy_field = bt_ctf_field_type_copy(entry->type);
3118 if (!copy_field) {
3119 g_free(copy_entry);
3120 goto error;
3121 }
3122
3123 copy_entry->name = entry->name;
3124 copy_entry->type = copy_field;
3125 g_ptr_array_add(copy_structure->fields, copy_entry);
3126 }
3127
3128 copy_structure->declaration = structure->declaration;
3129end:
3130 return copy;
3131error:
3132 bt_ctf_field_type_put(copy);
3133 return NULL;
3134}
3135
3136static
3137struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3138 struct bt_ctf_field_type *type)
3139{
3140 int i;
3141 GHashTableIter iter;
3142 gpointer key, value;
3143 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3144 struct bt_ctf_field_type_variant *variant, *copy_variant;
3145
3146 variant = container_of(type, struct bt_ctf_field_type_variant,
3147 parent);
3148 if (variant->tag) {
3149 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3150 if (!copy_tag) {
3151 goto end;
3152 }
3153 }
3154
3155 copy = bt_ctf_field_type_variant_create(copy_tag,
3156 variant->tag_name->len ? variant->tag_name->str : NULL);
3157 if (!copy) {
3158 goto end;
3159 }
3160
3161 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3162 parent);
3163
3164 /* Copy field_name_to_index */
3165 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3166 while (g_hash_table_iter_next (&iter, &key, &value)) {
3167 g_hash_table_insert(copy_variant->field_name_to_index,
3168 key, value);
3169 }
3170
3171 for (i = 0; i < variant->fields->len; i++) {
3172 struct structure_field *entry, *copy_entry;
3173 struct bt_ctf_field_type *copy_field;
3174
3175 copy_entry = g_new0(struct structure_field, 1);
3176 if (!copy_entry) {
3177 goto error;
3178 }
3179
3180 entry = g_ptr_array_index(variant->fields, i);
3181 copy_field = bt_ctf_field_type_copy(entry->type);
3182 if (!copy_field) {
3183 g_free(copy_entry);
3184 goto error;
3185 }
3186
3187 copy_entry->name = entry->name;
3188 copy_entry->type = copy_field;
3189 g_ptr_array_add(copy_variant->fields, copy_entry);
3190 }
3191
3192 copy_variant->declaration = variant->declaration;
4a1e8671
JG
3193 if (variant->tag_path) {
3194 copy_variant->tag_path = bt_ctf_field_path_copy(
3195 variant->tag_path);
3196 if (!copy_variant->tag_path) {
3197 goto error;
3198 }
3199 }
24724933
JG
3200end:
3201 if (copy_tag) {
3202 bt_ctf_field_type_put(copy_tag);
3203 }
3204
3205 return copy;
3206error:
3207 if (copy_tag) {
3208 bt_ctf_field_type_put(copy_tag);
3209 }
3210
3211 bt_ctf_field_type_put(copy);
3212 return NULL;
3213}
3214
3215static
3216struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3217 struct bt_ctf_field_type *type)
3218{
3219 struct bt_ctf_field_type *copy = NULL, *copy_element;
3220 struct bt_ctf_field_type_array *array, *copy_array;
3221
3222 array = container_of(type, struct bt_ctf_field_type_array,
3223 parent);
3224 copy_element = bt_ctf_field_type_copy(array->element_type);
3225 if (!copy_element) {
3226 goto end;
3227 }
3228
3229 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3230 if (!copy) {
3231 goto end;
3232 }
3233
3234 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3235 parent);
3236 copy_array->declaration = array->declaration;
3237end:
3238 if (copy_element) {
3239 bt_ctf_field_type_put(copy_element);
3240 }
3241
3242 return copy;
3243}
3244
3245static
3246struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3247 struct bt_ctf_field_type *type)
3248{
3249 struct bt_ctf_field_type *copy = NULL, *copy_element;
3250 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3251
3252 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3253 parent);
3254 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3255 if (!copy_element) {
3256 goto end;
3257 }
3258
3259 copy = bt_ctf_field_type_sequence_create(copy_element,
3260 sequence->length_field_name->len ?
3261 sequence->length_field_name->str : NULL);
3262 if (!copy) {
3263 goto end;
3264 }
3265
3266 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3267 parent);
3268 copy_sequence->declaration = sequence->declaration;
aa4e271c
JG
3269 if (sequence->length_field_path) {
3270 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3271 sequence->length_field_path);
3272 if (!copy_sequence->length_field_path) {
3273 goto error;
3274 }
3275 }
24724933
JG
3276end:
3277 if (copy_element) {
3278 bt_ctf_field_type_put(copy_element);
3279 }
3280
3281 return copy;
aa4e271c
JG
3282error:
3283 if (copy) {
3284 bt_ctf_field_type_put(copy);
3285 copy = NULL;
3286 }
3287 goto end;
24724933
JG
3288}
3289
3290static
3291struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3292 struct bt_ctf_field_type *type)
3293{
3294 struct bt_ctf_field_type *copy;
3295 struct bt_ctf_field_type_string *string, *copy_string;
3296
3297 copy = bt_ctf_field_type_string_create();
3298 if (!copy) {
3299 goto end;
3300 }
3301
3302 string = container_of(type, struct bt_ctf_field_type_string,
3303 parent);
3304 copy_string = container_of(type, struct bt_ctf_field_type_string,
3305 parent);
3306 copy_string->declaration = string->declaration;
3307end:
3308 return copy;
3309}
This page took 0.174263 seconds and 4 git commands to generate.