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