ir: add internal field path getters
[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 2223
32fe3f28
PP
2224BT_HIDDEN
2225struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
2226 struct bt_ctf_field_type *type)
2227{
2228 struct bt_ctf_field_type_sequence *sequence;
2229
2230 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2231 parent);
2232
2233 return sequence->length_field_path;
2234}
2235
4a1e8671
JG
2236BT_HIDDEN
2237int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2238 struct bt_ctf_field_path *path)
2239{
2240 int ret = 0;
2241 struct bt_ctf_field_type_variant *variant;
2242
2243 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2244 ret = -1;
2245 goto end;
2246 }
2247
2248 variant = container_of(type, struct bt_ctf_field_type_variant,
2249 parent);
2250 if (variant->tag_path) {
2251 bt_ctf_field_path_destroy(variant->tag_path);
2252 }
2253 variant->tag_path = path;
2254end:
2255 return ret;
2256}
3f39933a 2257
32fe3f28
PP
2258BT_HIDDEN
2259struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
2260 struct bt_ctf_field_type *type)
2261{
2262 struct bt_ctf_field_type_variant *variant;
2263
2264 variant = container_of(type, struct bt_ctf_field_type_variant,
2265 parent);
2266
2267 return variant->tag_path;
2268}
2269
3f39933a
JG
2270BT_HIDDEN
2271int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
2272 struct bt_ctf_field_type *tag)
2273{
2274 int ret = 0;
2275 struct bt_ctf_field_type_variant *variant;
2276
2277 if (!type || !tag || type->frozen ||
2278 bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
2279 ret = -1;
2280 goto end;
2281 }
2282
2283 variant = container_of(type, struct bt_ctf_field_type_variant,
2284 parent);
2285 bt_ctf_field_type_get(tag);
2286 if (variant->tag) {
2287 bt_ctf_field_type_put(&variant->tag->parent);
2288 }
2289 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2290 parent);
2291end:
2292 return ret;
2293}
2294
5cec03e4
JG
2295BT_HIDDEN
2296int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2297 struct bt_ctf_field_type *field, int index)
2298{
2299 int ret = 0;
2300 struct bt_ctf_field_type_variant *variant;
2301
6c827042 2302 if (!type || !field ||
5cec03e4
JG
2303 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2304 ret = -1;
2305 goto end;
2306 }
2307
2308 variant = container_of(type, struct bt_ctf_field_type_variant,
2309 parent);
2310 if (index < 0 || index >= variant->fields->len) {
2311 ret = -1;
2312 goto end;
2313 }
2314
2315 bt_ctf_field_type_get(field);
2316 bt_ctf_field_type_put(((struct structure_field *)
2317 g_ptr_array_index(variant->fields, index))->type);
2318 ((struct structure_field *) variant->fields->pdata[index])->type =
2319 field;
2320end:
2321 return ret;
2322}
2323
273b65be 2324static
de3dd40e 2325void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
273b65be 2326{
de3dd40e
PP
2327 struct bt_ctf_field_type_integer *integer =
2328 (struct bt_ctf_field_type_integer *) type;
273b65be 2329
de3dd40e 2330 if (!type) {
273b65be
JG
2331 return;
2332 }
2333
eee752e5
JG
2334 if (integer->mapped_clock) {
2335 bt_ctf_clock_put(integer->mapped_clock);
2336 }
273b65be
JG
2337 g_free(integer);
2338}
2339
2340static
de3dd40e 2341void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
273b65be 2342{
de3dd40e
PP
2343 struct bt_ctf_field_type_enumeration *enumeration =
2344 (struct bt_ctf_field_type_enumeration *) type;
273b65be 2345
de3dd40e 2346 if (!type) {
273b65be
JG
2347 return;
2348 }
2349
273b65be
JG
2350 g_ptr_array_free(enumeration->entries, TRUE);
2351 bt_ctf_field_type_put(enumeration->container);
2352 g_free(enumeration);
2353}
2354
2355static
de3dd40e 2356void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
273b65be 2357{
de3dd40e
PP
2358 struct bt_ctf_field_type_floating_point *floating_point =
2359 (struct bt_ctf_field_type_floating_point *) type;
273b65be 2360
de3dd40e 2361 if (!type) {
273b65be
JG
2362 return;
2363 }
2364
273b65be
JG
2365 g_free(floating_point);
2366}
2367
2368static
de3dd40e 2369void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
273b65be 2370{
de3dd40e
PP
2371 struct bt_ctf_field_type_structure *structure =
2372 (struct bt_ctf_field_type_structure *) type;
273b65be 2373
de3dd40e 2374 if (!type) {
273b65be
JG
2375 return;
2376 }
2377
273b65be
JG
2378 g_ptr_array_free(structure->fields, TRUE);
2379 g_hash_table_destroy(structure->field_name_to_index);
2380 g_free(structure);
2381}
2382
2383static
de3dd40e 2384void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
273b65be 2385{
de3dd40e
PP
2386 struct bt_ctf_field_type_variant *variant =
2387 (struct bt_ctf_field_type_variant *) type;
273b65be 2388
de3dd40e 2389 if (!type) {
273b65be
JG
2390 return;
2391 }
2392
273b65be
JG
2393 g_ptr_array_free(variant->fields, TRUE);
2394 g_hash_table_destroy(variant->field_name_to_index);
2395 g_string_free(variant->tag_name, TRUE);
2396 bt_ctf_field_type_put(&variant->tag->parent);
4a1e8671 2397 bt_ctf_field_path_destroy(variant->tag_path);
273b65be
JG
2398 g_free(variant);
2399}
2400
2401static
de3dd40e 2402void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
273b65be 2403{
de3dd40e
PP
2404 struct bt_ctf_field_type_array *array =
2405 (struct bt_ctf_field_type_array *) type;
273b65be 2406
de3dd40e 2407 if (!type) {
273b65be
JG
2408 return;
2409 }
2410
273b65be
JG
2411 bt_ctf_field_type_put(array->element_type);
2412 g_free(array);
2413}
2414
2415static
de3dd40e 2416void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
273b65be 2417{
de3dd40e
PP
2418 struct bt_ctf_field_type_sequence *sequence =
2419 (struct bt_ctf_field_type_sequence *) type;
273b65be 2420
de3dd40e 2421 if (!type) {
273b65be
JG
2422 return;
2423 }
2424
273b65be
JG
2425 bt_ctf_field_type_put(sequence->element_type);
2426 g_string_free(sequence->length_field_name, TRUE);
aa4e271c 2427 bt_ctf_field_path_destroy(sequence->length_field_path);
273b65be
JG
2428 g_free(sequence);
2429}
2430
2431static
de3dd40e 2432void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
273b65be 2433{
de3dd40e
PP
2434 struct bt_ctf_field_type_string *string =
2435 (struct bt_ctf_field_type_string *) type;
273b65be 2436
de3dd40e 2437 if (!type) {
273b65be
JG
2438 return;
2439 }
2440
273b65be
JG
2441 g_free(string);
2442}
2443
2444static
2445void generic_field_type_freeze(struct bt_ctf_field_type *type)
2446{
2447 type->frozen = 1;
2448}
2449
2450static
2451void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2452{
2453 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2454 type, struct bt_ctf_field_type_enumeration, parent);
2455
2456 generic_field_type_freeze(type);
2457 bt_ctf_field_type_freeze(enumeration_type->container);
2458}
2459
2460static
2461void freeze_structure_field(struct structure_field *field)
2462{
2463 bt_ctf_field_type_freeze(field->type);
2464}
2465
2466static
2467void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2468{
2469 struct bt_ctf_field_type_structure *structure_type = container_of(
2470 type, struct bt_ctf_field_type_structure, parent);
2471
3ffba961
JG
2472 /* Cache the alignment */
2473 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2474 generic_field_type_freeze(type);
3ffba961
JG
2475 g_ptr_array_foreach(structure_type->fields,
2476 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2477}
2478
2479static
2480void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2481{
2482 struct bt_ctf_field_type_variant *variant_type = container_of(
2483 type, struct bt_ctf_field_type_variant, parent);
2484
3ffba961
JG
2485 /* Cache the alignment */
2486 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2487 generic_field_type_freeze(type);
3ffba961
JG
2488 g_ptr_array_foreach(variant_type->fields,
2489 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2490}
2491
2492static
2493void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2494{
2495 struct bt_ctf_field_type_array *array_type = container_of(
2496 type, struct bt_ctf_field_type_array, parent);
2497
3ffba961
JG
2498 /* Cache the alignment */
2499 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2500 generic_field_type_freeze(type);
2501 bt_ctf_field_type_freeze(array_type->element_type);
2502}
2503
2504static
2505void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2506{
2507 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2508 type, struct bt_ctf_field_type_sequence, parent);
2509
3ffba961
JG
2510 /* Cache the alignment */
2511 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2512 generic_field_type_freeze(type);
2513 bt_ctf_field_type_freeze(sequence_type->element_type);
2514}
2515
2516static
2517const char *get_encoding_string(enum ctf_string_encoding encoding)
2518{
2519 const char *encoding_string;
2520
2521 switch (encoding) {
2522 case CTF_STRING_NONE:
2523 encoding_string = "none";
2524 break;
2525 case CTF_STRING_ASCII:
2526 encoding_string = "ASCII";
2527 break;
2528 case CTF_STRING_UTF8:
2529 encoding_string = "UTF8";
2530 break;
2531 default:
2532 encoding_string = "unknown";
2533 break;
2534 }
2535
2536 return encoding_string;
2537}
2538
2539static
2540const char *get_integer_base_string(enum bt_ctf_integer_base base)
2541{
2542 const char *base_string;
2543
2544 switch (base) {
2545 case BT_CTF_INTEGER_BASE_DECIMAL:
2546 base_string = "decimal";
2547 break;
2548 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2549 base_string = "hexadecimal";
2550 break;
2551 case BT_CTF_INTEGER_BASE_OCTAL:
2552 base_string = "octal";
2553 break;
2554 case BT_CTF_INTEGER_BASE_BINARY:
2555 base_string = "binary";
2556 break;
2557 default:
2558 base_string = "unknown";
2559 break;
2560 }
2561
2562 return base_string;
2563}
2564
2565static
2566int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2567 struct metadata_context *context)
2568{
2569 struct bt_ctf_field_type_integer *integer = container_of(type,
2570 struct bt_ctf_field_type_integer, parent);
6cfb906f 2571 int ret = 0;
273b65be
JG
2572
2573 g_string_append_printf(context->string,
6cfb906f 2574 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
2575 integer->declaration.len, type->declaration->alignment,
2576 (integer->declaration.signedness ? "true" : "false"),
2577 get_encoding_string(integer->declaration.encoding),
2578 get_integer_base_string(integer->declaration.base),
2579 get_byte_order_string(integer->declaration.byte_order));
6cfb906f
JG
2580 if (integer->mapped_clock) {
2581 const char *clock_name = bt_ctf_clock_get_name(
2582 integer->mapped_clock);
2583
2584 if (!clock_name) {
2585 ret = -1;
2586 goto end;
2587 }
2588
2589 g_string_append_printf(context->string,
4ebdec03 2590 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2591 }
2592
2593 g_string_append(context->string, "; }");
2594end:
2595 return ret;
273b65be
JG
2596}
2597
2598static
2599int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2600 struct metadata_context *context)
2601{
2602 size_t entry;
9ce21c30 2603 int ret;
273b65be
JG
2604 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2605 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2606 struct bt_ctf_field_type *container_type;
2607 int container_signed;
273b65be 2608
9ce21c30
JG
2609 ret = bt_ctf_field_type_validate(type);
2610 if (ret) {
2611 goto end;
2612 }
2613
b92ddaaa
JG
2614 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2615 if (!container_type) {
2616 ret = -1;
2617 goto end;
2618 }
2619
2620 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2621 if (container_signed < 0) {
2622 ret = container_signed;
2623 goto error_put_container_type;
2624 }
2625
273b65be
JG
2626 g_string_append(context->string, "enum : ");
2627 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2628 if (ret) {
b92ddaaa 2629 goto error_put_container_type;
273b65be
JG
2630 }
2631
2632 g_string_append(context->string, " { ");
2633 for (entry = 0; entry < enumeration->entries->len; entry++) {
2634 struct enumeration_mapping *mapping =
2635 enumeration->entries->pdata[entry];
2636
b92ddaaa
JG
2637 if (container_signed) {
2638 if (mapping->range_start._signed ==
2639 mapping->range_end._signed) {
2640 g_string_append_printf(context->string,
2641 "\"%s\" = %" PRId64,
2642 g_quark_to_string(mapping->string),
2643 mapping->range_start._signed);
2644 } else {
2645 g_string_append_printf(context->string,
2646 "\"%s\" = %" PRId64 " ... %" PRId64,
2647 g_quark_to_string(mapping->string),
2648 mapping->range_start._signed,
2649 mapping->range_end._signed);
2650 }
273b65be 2651 } else {
b92ddaaa
JG
2652 if (mapping->range_start._unsigned ==
2653 mapping->range_end._unsigned) {
2654 g_string_append_printf(context->string,
2655 "\"%s\" = %" PRIu64,
2656 g_quark_to_string(mapping->string),
2657 mapping->range_start._unsigned);
2658 } else {
2659 g_string_append_printf(context->string,
2660 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2661 g_quark_to_string(mapping->string),
2662 mapping->range_start._unsigned,
2663 mapping->range_end._unsigned);
2664 }
273b65be
JG
2665 }
2666
2667 g_string_append(context->string,
2668 ((entry != (enumeration->entries->len - 1)) ?
2669 ", " : " }"));
2670 }
2671
2672 if (context->field_name->len) {
2673 g_string_append_printf(context->string, " %s",
2674 context->field_name->str);
2675 g_string_assign(context->field_name, "");
2676 }
b92ddaaa
JG
2677error_put_container_type:
2678 bt_ctf_field_type_put(container_type);
273b65be
JG
2679end:
2680 return ret;
2681}
2682
2683static
2684int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2685 struct metadata_context *context)
2686{
2687 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2688 type, struct bt_ctf_field_type_floating_point, parent);
2689
2690 g_string_append_printf(context->string,
2691 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2692 floating_point->declaration.exp->len,
2693 floating_point->declaration.mantissa->len + 1,
2694 get_byte_order_string(floating_point->declaration.byte_order),
2695 type->declaration->alignment);
2696 return 0;
2697}
2698
2699static
2700int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2701 struct metadata_context *context)
2702{
2703 size_t i;
2704 unsigned int indent;
2705 int ret = 0;
2706 struct bt_ctf_field_type_structure *structure = container_of(type,
2707 struct bt_ctf_field_type_structure, parent);
2708 GString *structure_field_name = context->field_name;
2709
2710 context->field_name = g_string_new("");
2711
2712 context->current_indentation_level++;
2713 g_string_append(context->string, "struct {\n");
2714
2715 for (i = 0; i < structure->fields->len; i++) {
2716 struct structure_field *field;
2717
2718 for (indent = 0; indent < context->current_indentation_level;
2719 indent++) {
2720 g_string_append_c(context->string, '\t');
2721 }
2722
2723 field = structure->fields->pdata[i];
2724 g_string_assign(context->field_name,
2725 g_quark_to_string(field->name));
2726 ret = bt_ctf_field_type_serialize(field->type, context);
2727 if (ret) {
2728 goto end;
2729 }
2730
2731 if (context->field_name->len) {
2732 g_string_append_printf(context->string, " %s",
2733 context->field_name->str);
2734 }
2735 g_string_append(context->string, ";\n");
2736 }
2737
2738 context->current_indentation_level--;
2739 for (indent = 0; indent < context->current_indentation_level;
2740 indent++) {
2741 g_string_append_c(context->string, '\t');
2742 }
2743
2744 g_string_append_printf(context->string, "} align(%zu)",
2745 type->declaration->alignment);
2746end:
2747 g_string_free(context->field_name, TRUE);
2748 context->field_name = structure_field_name;
2749 return ret;
2750}
2751
2752static
2753int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
2754 struct metadata_context *context)
2755{
2756 size_t i;
2757 unsigned int indent;
2758 int ret = 0;
2759 struct bt_ctf_field_type_variant *variant = container_of(
2760 type, struct bt_ctf_field_type_variant, parent);
2761 GString *variant_field_name = context->field_name;
2762
2763 context->field_name = g_string_new("");
6964b7fd
JG
2764 if (variant->tag_name->len > 0) {
2765 g_string_append_printf(context->string,
2766 "variant <%s> {\n", variant->tag_name->str);
2767 } else {
2768 g_string_append(context->string, "variant {\n");
2769 }
2770
273b65be
JG
2771 context->current_indentation_level++;
2772 for (i = 0; i < variant->fields->len; i++) {
2773 struct structure_field *field = variant->fields->pdata[i];
2774
2775 g_string_assign(context->field_name,
2776 g_quark_to_string(field->name));
2777 for (indent = 0; indent < context->current_indentation_level;
2778 indent++) {
2779 g_string_append_c(context->string, '\t');
2780 }
2781
2782 g_string_assign(context->field_name,
2783 g_quark_to_string(field->name));
2784 ret = bt_ctf_field_type_serialize(field->type, context);
2785 if (ret) {
2786 goto end;
2787 }
2788
2789 if (context->field_name->len) {
2790 g_string_append_printf(context->string, " %s;",
2791 context->field_name->str);
2792 }
2793
2794 g_string_append_c(context->string, '\n');
2795 }
2796
2797 context->current_indentation_level--;
2798 for (indent = 0; indent < context->current_indentation_level;
2799 indent++) {
2800 g_string_append_c(context->string, '\t');
2801 }
2802
2803 g_string_append(context->string, "}");
2804end:
2805 g_string_free(context->field_name, TRUE);
2806 context->field_name = variant_field_name;
2807 return ret;
2808}
2809
2810static
2811int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
2812 struct metadata_context *context)
2813{
2814 int ret = 0;
2815 struct bt_ctf_field_type_array *array = container_of(type,
2816 struct bt_ctf_field_type_array, parent);
2817
2818 ret = bt_ctf_field_type_serialize(array->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[%u]",
2825 context->field_name->str, array->length);
2826 g_string_assign(context->field_name, "");
2827 } else {
2828 g_string_append_printf(context->string, "[%u]", array->length);
2829 }
2830end:
2831 return ret;
2832}
2833
2834static
2835int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
2836 struct metadata_context *context)
2837{
2838 int ret = 0;
2839 struct bt_ctf_field_type_sequence *sequence = container_of(
2840 type, struct bt_ctf_field_type_sequence, parent);
2841
2842 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
2843 if (ret) {
2844 goto end;
2845 }
2846
2847 if (context->field_name->len) {
2848 g_string_append_printf(context->string, " %s[%s]",
2849 context->field_name->str,
2850 sequence->length_field_name->str);
2851 g_string_assign(context->field_name, "");
2852 } else {
2853 g_string_append_printf(context->string, "[%s]",
2854 sequence->length_field_name->str);
2855 }
2856end:
2857 return ret;
2858}
2859
2860static
2861int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
2862 struct metadata_context *context)
2863{
2864 struct bt_ctf_field_type_string *string = container_of(
2865 type, struct bt_ctf_field_type_string, parent);
2866
2867 g_string_append_printf(context->string,
2868 "string { encoding = %s; }",
2869 get_encoding_string(string->declaration.encoding));
2870 return 0;
2871}
2872
2873static
2874void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 2875 int byte_order, int set_native)
273b65be
JG
2876{
2877 struct bt_ctf_field_type_integer *integer_type = container_of(type,
2878 struct bt_ctf_field_type_integer, parent);
2879
c35a1669
JG
2880 if (set_native) {
2881 integer_type->declaration.byte_order =
2882 integer_type->declaration.byte_order == 0 ?
2883 byte_order : integer_type->declaration.byte_order;
2884 } else {
2885 integer_type->declaration.byte_order = byte_order;
2886 }
2887}
2888
2889static
2890void bt_ctf_field_type_enumeration_set_byte_order(
2891 struct bt_ctf_field_type *type, int byte_order, int set_native)
2892{
2893 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
2894 struct bt_ctf_field_type_enumeration, parent);
2895
2896 /* Safe to assume that container is an integer */
2897 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
2898 byte_order, set_native);
273b65be
JG
2899}
2900
2901static
2902void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 2903 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
2904{
2905 struct bt_ctf_field_type_floating_point *floating_point_type =
2906 container_of(type, struct bt_ctf_field_type_floating_point,
2907 parent);
2908
c35a1669
JG
2909 if (set_native) {
2910 floating_point_type->declaration.byte_order =
2911 floating_point_type->declaration.byte_order == 0 ?
2912 byte_order :
2913 floating_point_type->declaration.byte_order;
2914 floating_point_type->sign.byte_order =
2915 floating_point_type->sign.byte_order == 0 ?
2916 byte_order : floating_point_type->sign.byte_order;
2917 floating_point_type->mantissa.byte_order =
2918 floating_point_type->mantissa.byte_order == 0 ?
2919 byte_order : floating_point_type->mantissa.byte_order;
2920 floating_point_type->exp.byte_order =
2921 floating_point_type->exp.byte_order == 0 ?
2922 byte_order : floating_point_type->exp.byte_order;
2923 } else {
2924 floating_point_type->declaration.byte_order = byte_order;
2925 floating_point_type->sign.byte_order = byte_order;
2926 floating_point_type->mantissa.byte_order = byte_order;
2927 floating_point_type->exp.byte_order = byte_order;
2928 }
2929}
2930
2931static
2932void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
2933 int byte_order, int set_native)
2934{
2935 int i;
2936 struct bt_ctf_field_type_structure *structure_type =
2937 container_of(type, struct bt_ctf_field_type_structure,
2938 parent);
2939
2940 for (i = 0; i < structure_type->fields->len; i++) {
2941 struct structure_field *field = g_ptr_array_index(
2942 structure_type->fields, i);
2943 struct bt_ctf_field_type *field_type = field->type;
2944
2945 if (set_byte_order_funcs[field_type->declaration->id]) {
2946 set_byte_order_funcs[field_type->declaration->id](
2947 field_type, byte_order, set_native);
2948 }
2949 }
2950}
2951
2952static
2953void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
2954 int byte_order, int set_native)
2955{
2956 int i;
2957 struct bt_ctf_field_type_variant *variant_type =
2958 container_of(type, struct bt_ctf_field_type_variant,
2959 parent);
2960
2961 for (i = 0; i < variant_type->fields->len; i++) {
2962 struct structure_field *field = g_ptr_array_index(
2963 variant_type->fields, i);
2964 struct bt_ctf_field_type *field_type = field->type;
2965
2966 if (set_byte_order_funcs[field_type->declaration->id]) {
2967 set_byte_order_funcs[field_type->declaration->id](
2968 field_type, byte_order, set_native);
2969 }
2970 }
2971}
2972
2973static
2974void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
2975 int byte_order, int set_native)
2976{
2977 struct bt_ctf_field_type_array *array_type =
2978 container_of(type, struct bt_ctf_field_type_array,
2979 parent);
2980
2981 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
2982 set_byte_order_funcs[array_type->element_type->declaration->id](
2983 array_type->element_type, byte_order, set_native);
2984 }
2985}
2986
2987static
2988void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
2989 int byte_order, int set_native)
2990{
2991 struct bt_ctf_field_type_sequence *sequence_type =
2992 container_of(type, struct bt_ctf_field_type_sequence,
2993 parent);
2994
2995 if (set_byte_order_funcs[
2996 sequence_type->element_type->declaration->id]) {
2997 set_byte_order_funcs[
2998 sequence_type->element_type->declaration->id](
2999 sequence_type->element_type, byte_order, set_native);
3000 }
273b65be 3001}
24724933
JG
3002
3003static
3004struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3005 struct bt_ctf_field_type *type)
3006{
3007 struct bt_ctf_field_type *copy;
3008 struct bt_ctf_field_type_integer *integer, *copy_integer;
3009
3010 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3011 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3012 if (!copy) {
3013 goto end;
3014 }
3015
3016 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3017 parent);
3018 copy_integer->declaration = integer->declaration;
3019 if (integer->mapped_clock) {
3020 bt_ctf_clock_get(integer->mapped_clock);
3021 copy_integer->mapped_clock = integer->mapped_clock;
3022 }
3023end:
3024 return copy;
3025}
3026
3027static
3028struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3029 struct bt_ctf_field_type *type)
3030{
3031 size_t i;
3032 struct bt_ctf_field_type *copy = NULL, *copy_container;
3033 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3034
3035 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3036 parent);
3037
3038 /* Copy the source enumeration's container */
3039 copy_container = bt_ctf_field_type_copy(enumeration->container);
3040 if (!copy_container) {
3041 goto end;
3042 }
3043
3044 copy = bt_ctf_field_type_enumeration_create(copy_container);
3045 if (!copy) {
3046 goto end;
3047 }
3048 copy_enumeration = container_of(copy,
3049 struct bt_ctf_field_type_enumeration, parent);
3050
3051 /* Copy all enumaration entries */
3052 for (i = 0; i < enumeration->entries->len; i++) {
3053 struct enumeration_mapping *mapping = g_ptr_array_index(
3054 enumeration->entries, i);
3055 struct enumeration_mapping* copy_mapping = g_new0(
3056 struct enumeration_mapping, 1);
3057
3058 if (!copy_mapping) {
3059 goto error;
3060 }
3061
3062 *copy_mapping = *mapping;
3063 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3064 }
3065
3066 copy_enumeration->declaration = enumeration->declaration;
3067end:
3068 if (copy_container) {
3069 bt_ctf_field_type_put(copy_container);
3070 }
3071 return copy;
3072error:
3073 if (copy_container) {
3074 bt_ctf_field_type_put(copy_container);
3075 }
3076 bt_ctf_field_type_put(copy);
3077 return NULL;
3078}
3079
3080static
3081struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3082 struct bt_ctf_field_type *type)
3083{
3084 struct bt_ctf_field_type *copy;
3085 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3086
3087 floating_point = container_of(type,
3088 struct bt_ctf_field_type_floating_point, parent);
3089 copy = bt_ctf_field_type_floating_point_create();
3090 if (!copy) {
3091 goto end;
3092 }
3093
3094 copy_float = container_of(copy,
3095 struct bt_ctf_field_type_floating_point, parent);
3096 copy_float->declaration = floating_point->declaration;
3097 copy_float->sign = floating_point->sign;
3098 copy_float->mantissa = floating_point->mantissa;
3099 copy_float->exp = floating_point->exp;
3100end:
3101 return copy;
3102}
3103
3104static
3105struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3106 struct bt_ctf_field_type *type)
3107{
3108 int i;
3109 GHashTableIter iter;
3110 gpointer key, value;
3111 struct bt_ctf_field_type *copy;
3112 struct bt_ctf_field_type_structure *structure, *copy_structure;
3113
3114 structure = container_of(type, struct bt_ctf_field_type_structure,
3115 parent);
3116 copy = bt_ctf_field_type_structure_create();
3117 if (!copy) {
3118 goto end;
3119 }
3120
3121 copy_structure = container_of(copy,
3122 struct bt_ctf_field_type_structure, parent);
3123
3124 /* Copy field_name_to_index */
3125 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3126 while (g_hash_table_iter_next (&iter, &key, &value)) {
3127 g_hash_table_insert(copy_structure->field_name_to_index,
3128 key, value);
3129 }
3130
3131 for (i = 0; i < structure->fields->len; i++) {
3132 struct structure_field *entry, *copy_entry;
3133 struct bt_ctf_field_type *copy_field;
3134
3135 copy_entry = g_new0(struct structure_field, 1);
3136 if (!copy_entry) {
3137 goto error;
3138 }
3139
3140 entry = g_ptr_array_index(structure->fields, i);
3141 copy_field = bt_ctf_field_type_copy(entry->type);
3142 if (!copy_field) {
3143 g_free(copy_entry);
3144 goto error;
3145 }
3146
3147 copy_entry->name = entry->name;
3148 copy_entry->type = copy_field;
3149 g_ptr_array_add(copy_structure->fields, copy_entry);
3150 }
3151
3152 copy_structure->declaration = structure->declaration;
3153end:
3154 return copy;
3155error:
3156 bt_ctf_field_type_put(copy);
3157 return NULL;
3158}
3159
3160static
3161struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3162 struct bt_ctf_field_type *type)
3163{
3164 int i;
3165 GHashTableIter iter;
3166 gpointer key, value;
3167 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3168 struct bt_ctf_field_type_variant *variant, *copy_variant;
3169
3170 variant = container_of(type, struct bt_ctf_field_type_variant,
3171 parent);
3172 if (variant->tag) {
3173 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3174 if (!copy_tag) {
3175 goto end;
3176 }
3177 }
3178
3179 copy = bt_ctf_field_type_variant_create(copy_tag,
3180 variant->tag_name->len ? variant->tag_name->str : NULL);
3181 if (!copy) {
3182 goto end;
3183 }
3184
3185 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3186 parent);
3187
3188 /* Copy field_name_to_index */
3189 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3190 while (g_hash_table_iter_next (&iter, &key, &value)) {
3191 g_hash_table_insert(copy_variant->field_name_to_index,
3192 key, value);
3193 }
3194
3195 for (i = 0; i < variant->fields->len; i++) {
3196 struct structure_field *entry, *copy_entry;
3197 struct bt_ctf_field_type *copy_field;
3198
3199 copy_entry = g_new0(struct structure_field, 1);
3200 if (!copy_entry) {
3201 goto error;
3202 }
3203
3204 entry = g_ptr_array_index(variant->fields, i);
3205 copy_field = bt_ctf_field_type_copy(entry->type);
3206 if (!copy_field) {
3207 g_free(copy_entry);
3208 goto error;
3209 }
3210
3211 copy_entry->name = entry->name;
3212 copy_entry->type = copy_field;
3213 g_ptr_array_add(copy_variant->fields, copy_entry);
3214 }
3215
3216 copy_variant->declaration = variant->declaration;
4a1e8671
JG
3217 if (variant->tag_path) {
3218 copy_variant->tag_path = bt_ctf_field_path_copy(
3219 variant->tag_path);
3220 if (!copy_variant->tag_path) {
3221 goto error;
3222 }
3223 }
24724933
JG
3224end:
3225 if (copy_tag) {
3226 bt_ctf_field_type_put(copy_tag);
3227 }
3228
3229 return copy;
3230error:
3231 if (copy_tag) {
3232 bt_ctf_field_type_put(copy_tag);
3233 }
3234
3235 bt_ctf_field_type_put(copy);
3236 return NULL;
3237}
3238
3239static
3240struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3241 struct bt_ctf_field_type *type)
3242{
3243 struct bt_ctf_field_type *copy = NULL, *copy_element;
3244 struct bt_ctf_field_type_array *array, *copy_array;
3245
3246 array = container_of(type, struct bt_ctf_field_type_array,
3247 parent);
3248 copy_element = bt_ctf_field_type_copy(array->element_type);
3249 if (!copy_element) {
3250 goto end;
3251 }
3252
3253 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3254 if (!copy) {
3255 goto end;
3256 }
3257
3258 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3259 parent);
3260 copy_array->declaration = array->declaration;
3261end:
3262 if (copy_element) {
3263 bt_ctf_field_type_put(copy_element);
3264 }
3265
3266 return copy;
3267}
3268
3269static
3270struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3271 struct bt_ctf_field_type *type)
3272{
3273 struct bt_ctf_field_type *copy = NULL, *copy_element;
3274 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3275
3276 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3277 parent);
3278 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3279 if (!copy_element) {
3280 goto end;
3281 }
3282
3283 copy = bt_ctf_field_type_sequence_create(copy_element,
3284 sequence->length_field_name->len ?
3285 sequence->length_field_name->str : NULL);
3286 if (!copy) {
3287 goto end;
3288 }
3289
3290 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3291 parent);
3292 copy_sequence->declaration = sequence->declaration;
aa4e271c
JG
3293 if (sequence->length_field_path) {
3294 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3295 sequence->length_field_path);
3296 if (!copy_sequence->length_field_path) {
3297 goto error;
3298 }
3299 }
24724933
JG
3300end:
3301 if (copy_element) {
3302 bt_ctf_field_type_put(copy_element);
3303 }
3304
3305 return copy;
aa4e271c
JG
3306error:
3307 if (copy) {
3308 bt_ctf_field_type_put(copy);
3309 copy = NULL;
3310 }
3311 goto end;
24724933
JG
3312}
3313
3314static
3315struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3316 struct bt_ctf_field_type *type)
3317{
3318 struct bt_ctf_field_type *copy;
3319 struct bt_ctf_field_type_string *string, *copy_string;
3320
3321 copy = bt_ctf_field_type_string_create();
3322 if (!copy) {
3323 goto end;
3324 }
3325
3326 string = container_of(type, struct bt_ctf_field_type_string,
3327 parent);
3328 copy_string = container_of(type, struct bt_ctf_field_type_string,
3329 parent);
3330 copy_string->declaration = string->declaration;
3331end:
3332 return copy;
3333}
This page took 0.169052 seconds and 4 git commands to generate.