Fix enum rename warnings
[babeltrace.git] / formats / ctf / ir / field-types.c
CommitLineData
1c822dfb
JG
1/*
2 * field-types.c
3 *
4 * Babeltrace CTF IR - Event Types
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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-ir/field-types-internal.h>
30#include <babeltrace/ctf-ir/field-path-internal.h>
830017b0 31#include <babeltrace/ctf-ir/fields-internal.h>
1c822dfb
JG
32#include <babeltrace/ctf-ir/utils.h>
33#include <babeltrace/ref.h>
34#include <babeltrace/ctf-ir/clock.h>
35#include <babeltrace/ctf-ir/clock-internal.h>
36#include <babeltrace/ctf-writer/writer-internal.h>
37#include <babeltrace/object-internal.h>
38#include <babeltrace/ref.h>
39#include <babeltrace/compiler.h>
40#include <babeltrace/endian.h>
41#include <float.h>
42#include <inttypes.h>
43#include <stdlib.h>
44
45struct range_overlap_query {
46 union {
47 uint64_t _unsigned;
48 int64_t _signed;
49 } range_start;
50
51 union {
52 uint64_t _unsigned;
53 int64_t _signed;
54 } range_end;
55 int overlaps;
56 GQuark mapping_name;
57};
58
59static
60void bt_ctf_field_type_destroy(struct bt_object *);
61static
62void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
63static
64void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
65static
66void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
67static
68void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
69static
70void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
71static
72void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
73static
74void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
75static
76void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
77
78static
79void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
830017b0
JG
80 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_destroy,
81 [CTF_TYPE_ENUM] =
1c822dfb 82 bt_ctf_field_type_enumeration_destroy,
830017b0 83 [CTF_TYPE_FLOAT] =
1c822dfb 84 bt_ctf_field_type_floating_point_destroy,
830017b0
JG
85 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_destroy,
86 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_destroy,
87 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_destroy,
88 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
89 [CTF_TYPE_STRING] = bt_ctf_field_type_string_destroy,
1c822dfb
JG
90};
91
92static
93void generic_field_type_freeze(struct bt_ctf_field_type *);
94static
95void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
96static
97void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
98static
99void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
100static
101void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
102static
103void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
104static
105void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
106
107static
108type_freeze_func const type_freeze_funcs[] = {
830017b0
JG
109 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_freeze,
110 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_freeze,
111 [CTF_TYPE_FLOAT] = generic_field_type_freeze,
112 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_freeze,
113 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_freeze,
114 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_freeze,
115 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
116 [CTF_TYPE_STRING] = generic_field_type_freeze,
1c822dfb
JG
117};
118
119static
120int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
121 struct metadata_context *);
122static
123int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
124 struct metadata_context *);
125static
126int bt_ctf_field_type_floating_point_serialize(
127 struct bt_ctf_field_type *, struct metadata_context *);
128static
129int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
130 struct metadata_context *);
131static
132int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
133 struct metadata_context *);
134static
135int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
136 struct metadata_context *);
137static
138int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
139 struct metadata_context *);
140static
141int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
142 struct metadata_context *);
143
144static
145type_serialize_func const type_serialize_funcs[] = {
830017b0
JG
146 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_serialize,
147 [CTF_TYPE_ENUM] =
1c822dfb 148 bt_ctf_field_type_enumeration_serialize,
830017b0 149 [CTF_TYPE_FLOAT] =
1c822dfb 150 bt_ctf_field_type_floating_point_serialize,
830017b0 151 [CTF_TYPE_STRUCT] =
1c822dfb 152 bt_ctf_field_type_structure_serialize,
830017b0
JG
153 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_serialize,
154 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_serialize,
155 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
156 [CTF_TYPE_STRING] = bt_ctf_field_type_string_serialize,
1c822dfb
JG
157};
158
159static
160void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
161 int byte_order, int set_native);
162static
163void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
164 int byte_order, int set_native);
165static
166void bt_ctf_field_type_floating_point_set_byte_order(
167 struct bt_ctf_field_type *, int byte_order, int set_native);
168static
169void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
170 int byte_order, int set_native);
171static
172void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
173 int byte_order, int set_native);
174static
175void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
176 int byte_order, int set_native);
177static
178void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
179 int byte_order, int set_native);
180
181/* The set_native flag only set the byte order if it is set to native */
182static
183void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
184 int byte_order, int set_native) = {
830017b0
JG
185 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
186 [CTF_TYPE_ENUM] =
1c822dfb 187 bt_ctf_field_type_enumeration_set_byte_order,
830017b0 188 [CTF_TYPE_FLOAT] =
1c822dfb 189 bt_ctf_field_type_floating_point_set_byte_order,
830017b0 190 [CTF_TYPE_STRUCT] =
1c822dfb 191 bt_ctf_field_type_structure_set_byte_order,
830017b0
JG
192 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
193 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_set_byte_order,
194 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
195 [CTF_TYPE_STRING] = NULL,
1c822dfb
JG
196};
197
198static
199struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
200 struct bt_ctf_field_type *);
201static
202struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
203 struct bt_ctf_field_type *);
204static
205struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
206 struct bt_ctf_field_type *);
207static
208struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
209 struct bt_ctf_field_type *);
210static
211struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
212 struct bt_ctf_field_type *);
213static
214struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
215 struct bt_ctf_field_type *);
216static
217struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
218 struct bt_ctf_field_type *);
219static
220struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
221 struct bt_ctf_field_type *);
222
223static
224struct bt_ctf_field_type *(* const type_copy_funcs[])(
225 struct bt_ctf_field_type *) = {
830017b0
JG
226 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_copy,
227 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_copy,
228 [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_copy,
229 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_copy,
230 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_copy,
231 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_copy,
232 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_copy,
233 [CTF_TYPE_STRING] = bt_ctf_field_type_string_copy,
1c822dfb
JG
234};
235
236static
237int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
238 struct bt_ctf_field_type *);
239static
240int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
241 struct bt_ctf_field_type *);
242static
243int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
244 struct bt_ctf_field_type *);
245static
246int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
247 struct bt_ctf_field_type *);
248static
249int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
250 struct bt_ctf_field_type *);
251static
252int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
253 struct bt_ctf_field_type *);
254static
255int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
256 struct bt_ctf_field_type *);
257static
258int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
259 struct bt_ctf_field_type *);
260
261static
262int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
263 struct bt_ctf_field_type *) = {
830017b0
JG
264 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_compare,
265 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_compare,
266 [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_compare,
267 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_compare,
268 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_compare,
269 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_compare,
270 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_compare,
271 [CTF_TYPE_STRING] = bt_ctf_field_type_string_compare,
1c822dfb
JG
272};
273
274static
275int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *);
276static
277int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
278static
279int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
280static
281int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
282static
283int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
284static
285int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
286
287static
288int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
830017b0
JG
289 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_validate,
290 [CTF_TYPE_FLOAT] = NULL,
291 [CTF_TYPE_STRING] = NULL,
292 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_validate,
293 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_validate,
294 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_validate,
295 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_validate,
296 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_validate,
1c822dfb
JG
297};
298
299static
300void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
301{
302 g_free(mapping);
303}
304
305static
306void destroy_structure_field(struct structure_field *field)
307{
308 bt_put(field->type);
309 g_free(field);
310}
311
312static
313void check_ranges_overlap(gpointer element, gpointer query)
314{
315 struct enumeration_mapping *mapping = element;
316 struct range_overlap_query *overlap_query = query;
317
318 if (mapping->range_start._signed <= overlap_query->range_end._signed
319 && overlap_query->range_start._signed <=
320 mapping->range_end._signed) {
321 overlap_query->overlaps = 1;
322 overlap_query->mapping_name = mapping->string;
323 }
324
325 overlap_query->overlaps |=
326 mapping->string == overlap_query->mapping_name;
327}
328
329static
330void check_ranges_overlap_unsigned(gpointer element, gpointer query)
331{
332 struct enumeration_mapping *mapping = element;
333 struct range_overlap_query *overlap_query = query;
334
335 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
336 && overlap_query->range_start._unsigned <=
337 mapping->range_end._unsigned) {
338 overlap_query->overlaps = 1;
339 overlap_query->mapping_name = mapping->string;
340 }
341
342 overlap_query->overlaps |=
343 mapping->string == overlap_query->mapping_name;
344}
345
346static
347gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
348 struct enumeration_mapping **b)
349{
350 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
351}
352
353static
354gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
355 struct enumeration_mapping **b)
356{
357 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
358}
359
360static
361void bt_ctf_field_type_init(struct bt_ctf_field_type *type, int init_bo)
362{
830017b0 363 enum ctf_type_id type_id = type->declaration->id;
1c822dfb 364
830017b0
JG
365 assert(type && (type_id > CTF_TYPE_UNKNOWN) &&
366 (type_id < NR_CTF_TYPES));
1c822dfb
JG
367
368 bt_object_init(type, bt_ctf_field_type_destroy);
369 type->freeze = type_freeze_funcs[type_id];
370 type->serialize = type_serialize_funcs[type_id];
371
372 if (init_bo) {
373 int ret = bt_ctf_field_type_set_byte_order(type,
374 BT_CTF_BYTE_ORDER_NATIVE);
375 assert(!ret);
376 }
377
378 type->declaration->alignment = 1;
379}
380
381static
382int add_structure_field(GPtrArray *fields,
383 GHashTable *field_name_to_index,
384 struct bt_ctf_field_type *field_type,
385 const char *field_name)
386{
387 int ret = 0;
388 GQuark name_quark = g_quark_from_string(field_name);
389 struct structure_field *field;
390
391 /* Make sure structure does not contain a field of the same name */
392 if (g_hash_table_lookup_extended(field_name_to_index,
393 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
394 ret = -1;
395 goto end;
396 }
397
398 field = g_new0(struct structure_field, 1);
399 if (!field) {
400 ret = -1;
401 goto end;
402 }
403
404 bt_get(field_type);
405 field->name = name_quark;
406 field->type = field_type;
407 g_hash_table_insert(field_name_to_index,
408 (gpointer) (unsigned long) name_quark,
409 (gpointer) (unsigned long) fields->len);
410 g_ptr_array_add(fields, field);
411end:
412 return ret;
413}
414
415static
416void bt_ctf_field_type_destroy(struct bt_object *obj)
417{
418 struct bt_ctf_field_type *type;
830017b0 419 enum ctf_type_id type_id;
1c822dfb
JG
420
421 type = container_of(obj, struct bt_ctf_field_type, base);
422 type_id = type->declaration->id;
830017b0
JG
423 if (type_id <= CTF_TYPE_UNKNOWN ||
424 type_id >= NR_CTF_TYPES) {
1c822dfb
JG
425 return;
426 }
427
428 type_destroy_funcs[type_id](type);
429}
430
431static
432int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type)
433{
434 int ret = 0;
435
436 struct bt_ctf_field_type_integer *integer =
437 container_of(type, struct bt_ctf_field_type_integer,
438 parent);
439
440 if (integer->mapped_clock && integer->declaration.signedness) {
441 ret = -1;
442 goto end;
443 }
444
445end:
446 return ret;
447}
448
449static
450int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
451{
452 int ret = 0;
453
454 struct bt_ctf_field_type_enumeration *enumeration =
455 container_of(type, struct bt_ctf_field_type_enumeration,
456 parent);
457 struct bt_ctf_field_type *container_type =
458 bt_ctf_field_type_enumeration_get_container_type(type);
459
460 if (!container_type) {
461 ret = -1;
462 goto end;
463 }
464
465 ret = bt_ctf_field_type_validate(container_type);
466 if (ret) {
467 goto end;
468 }
469
470 /* Ensure enum has entries */
471 ret = enumeration->entries->len ? 0 : -1;
472
473end:
474 BT_PUT(container_type);
475 return ret;
476}
477
478static
479int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type)
480{
481 int ret = 0;
482 struct bt_ctf_field_type *element_type = NULL;
483 struct bt_ctf_field_type_sequence *sequence =
484 container_of(type, struct bt_ctf_field_type_sequence,
485 parent);
486
487 /* Length field name should be set at this point */
488 if (sequence->length_field_name->len == 0) {
489 ret = -1;
490 goto end;
491 }
492
493 element_type = bt_ctf_field_type_sequence_get_element_type(type);
494 if (!element_type) {
495 ret = -1;
496 goto end;
497 }
498
499 ret = bt_ctf_field_type_validate(element_type);
500
501end:
502 BT_PUT(element_type);
503
504 return ret;
505}
506
507static
508int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type)
509{
510 int ret = 0;
511 struct bt_ctf_field_type *element_type = NULL;
512
513 element_type = bt_ctf_field_type_array_get_element_type(type);
514 if (!element_type) {
515 ret = -1;
516 goto end;
517 }
518
519 ret = bt_ctf_field_type_validate(element_type);
520
521end:
522 BT_PUT(element_type);
523
524 return ret;
525}
526
527static
528int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type)
529{
530 int ret = 0;
531 struct bt_ctf_field_type *child_type = NULL;
532 int field_count = bt_ctf_field_type_structure_get_field_count(type);
533 int i;
534
535 if (field_count < 0) {
536 ret = -1;
537 goto end;
538 }
539
540 for (i = 0; i < field_count; ++i) {
541 ret = bt_ctf_field_type_structure_get_field(type,
542 NULL, &child_type, i);
543 if (ret) {
544 goto end;
545 }
546
547 ret = bt_ctf_field_type_validate(child_type);
548 if (ret) {
549 goto end;
550 }
551
552 BT_PUT(child_type);
553 }
554
555end:
556 BT_PUT(child_type);
557
558 return ret;
559}
560
561static
562int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type)
563{
564 int ret = 0;
565 int field_count;
566 struct bt_ctf_field_type *child_type = NULL;
567 struct bt_ctf_field_type_variant *variant =
568 container_of(type, struct bt_ctf_field_type_variant,
569 parent);
570 int i;
571 int tag_mappings_count;
572
573 if (variant->tag_name->len == 0 || !variant->tag) {
574 ret = -1;
575 goto end;
576 }
577
578 tag_mappings_count =
579 bt_ctf_field_type_enumeration_get_mapping_count(
580 (struct bt_ctf_field_type *) variant->tag);
581
582 if (tag_mappings_count != variant->fields->len) {
583 ret = -1;
584 goto end;
585 }
586
587 for (i = 0; i < tag_mappings_count; ++i) {
588 const char *label;
589 int64_t range_start, range_end;
590 struct bt_ctf_field_type *ft;
591
592 ret = bt_ctf_field_type_enumeration_get_mapping(
593 (struct bt_ctf_field_type *) variant->tag,
594 i, &label, &range_start, &range_end);
595 if (ret) {
596 goto end;
597 }
598 if (!label) {
599 ret = -1;
600 goto end;
601 }
602
603 ft = bt_ctf_field_type_variant_get_field_type_by_name(
604 type, label);
605 if (!ft) {
606 ret = -1;
607 goto end;
608 }
609
610 BT_PUT(ft);
611 }
612
613 field_count = bt_ctf_field_type_variant_get_field_count(type);
614 if (field_count < 0) {
615 ret = -1;
616 goto end;
617 }
618
619 for (i = 0; i < field_count; ++i) {
620 ret = bt_ctf_field_type_variant_get_field(type,
621 NULL, &child_type, i);
622 if (ret) {
623 goto end;
624 }
625
626 ret = bt_ctf_field_type_validate(child_type);
627 if (ret) {
628 goto end;
629 }
630
631 BT_PUT(child_type);
632 }
633
634end:
635 BT_PUT(child_type);
636
637 return ret;
638}
639
640/*
641 * This function validates a given field type without considering
642 * where this field type is located. It only validates the properties
643 * of the given field type and the properties of its children if
644 * applicable.
645 */
646BT_HIDDEN
647int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
648{
649 int ret = 0;
830017b0 650 enum ctf_type_id id = bt_ctf_field_type_get_type_id(type);
1c822dfb
JG
651
652 if (!type) {
653 ret = -1;
654 goto end;
655 }
656
657 if (type->valid) {
658 /* Already marked as valid */
659 goto end;
660 }
661
662 if (type_validate_funcs[id]) {
663 ret = type_validate_funcs[id](type);
664 }
665
666 if (!ret && type->frozen) {
667 /* Field type is valid */
668 type->valid = 1;
669 }
670
671end:
672 return ret;
673}
674
675struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
676{
677 struct bt_ctf_field_type_integer *integer =
678 g_new0(struct bt_ctf_field_type_integer, 1);
679
680 if (!integer || size == 0 || size > 64) {
681 return NULL;
682 }
683
684 integer->parent.declaration = &integer->declaration.p;
830017b0 685 integer->parent.declaration->id = CTF_TYPE_INTEGER;
1c822dfb
JG
686 integer->declaration.len = size;
687 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
688 integer->declaration.encoding = BT_CTF_STRING_ENCODING_NONE;
689 bt_ctf_field_type_init(&integer->parent, TRUE);
690 return &integer->parent;
691}
692
5ad19bf0 693BT_HIDDEN
1c822dfb
JG
694int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
695{
696 int ret = 0;
697 struct bt_ctf_field_type_integer *integer;
698
830017b0 699 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
700 ret = -1;
701 goto end;
702 }
703
704 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
705 ret = (int) integer->declaration.len;
706end:
707 return ret;
708}
709
710int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
711{
712 int ret = 0;
713 struct bt_ctf_field_type_integer *integer;
714
830017b0 715 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
716 ret = -1;
717 goto end;
718 }
719
720 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
721 ret = integer->declaration.signedness;
722end:
723 return ret;
724}
725
726int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
727 int is_signed)
728{
729 int ret = 0;
730 struct bt_ctf_field_type_integer *integer;
731
732 if (!type || type->frozen ||
830017b0 733 type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
734 ret = -1;
735 goto end;
736 }
737
738 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
739 integer->declaration.signedness = !!is_signed;
740end:
741 return ret;
742}
743
5ad19bf0 744BT_HIDDEN
1c822dfb
JG
745enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
746 struct bt_ctf_field_type *type)
747{
748 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
749 struct bt_ctf_field_type_integer *integer;
750
830017b0 751 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
752 goto end;
753 }
754
755 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
756 ret = integer->declaration.base;
757end:
758 return ret;
759}
760
761int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
762 enum bt_ctf_integer_base base)
763{
764 int ret = 0;
765
766 if (!type || type->frozen ||
830017b0 767 type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
768 ret = -1;
769 goto end;
770 }
771
772 switch (base) {
773 case BT_CTF_INTEGER_BASE_BINARY:
774 case BT_CTF_INTEGER_BASE_OCTAL:
775 case BT_CTF_INTEGER_BASE_DECIMAL:
776 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
777 {
778 struct bt_ctf_field_type_integer *integer = container_of(type,
779 struct bt_ctf_field_type_integer, parent);
780 integer->declaration.base = base;
781 break;
782 }
783 default:
784 ret = -1;
785 }
786end:
787 return ret;
788}
789
5ad19bf0 790BT_HIDDEN
1c822dfb
JG
791enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
792 struct bt_ctf_field_type *type)
793{
794 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
795 struct bt_ctf_field_type_integer *integer;
796
830017b0 797 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
798 goto end;
799 }
800
801 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
802 ret = integer->declaration.encoding;
803end:
804 return ret;
805}
806
807int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
808 enum bt_ctf_string_encoding encoding)
809{
810 int ret = 0;
811 struct bt_ctf_field_type_integer *integer;
812
813 if (!type || type->frozen ||
830017b0 814 (type->declaration->id != CTF_TYPE_INTEGER) ||
1c822dfb
JG
815 (encoding < BT_CTF_STRING_ENCODING_NONE) ||
816 (encoding >= BT_CTF_STRING_ENCODING_UNKNOWN)) {
817 ret = -1;
818 goto end;
819 }
820
821 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
822 integer->declaration.encoding = encoding;
823end:
824 return ret;
825}
826
5ad19bf0 827BT_HIDDEN
1c822dfb
JG
828struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
829 struct bt_ctf_field_type *type)
830{
831 struct bt_ctf_field_type_integer *integer;
832 struct bt_ctf_clock *clock = NULL;
833
834 if (!type) {
835 goto end;
836 }
837
838 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
839 clock = integer->mapped_clock;
840 bt_get(clock);
841end:
842 return clock;
843}
844
5ad19bf0 845BT_HIDDEN
1c822dfb
JG
846int bt_ctf_field_type_integer_set_mapped_clock(
847 struct bt_ctf_field_type *type,
848 struct bt_ctf_clock *clock)
849{
850 struct bt_ctf_field_type_integer *integer;
851 int ret = 0;
852
853 if (!type || type->frozen) {
854 ret = -1;
855 goto end;
856 }
857
858 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
859 bt_put(integer->mapped_clock);
860 bt_get(clock);
861 integer->mapped_clock = clock;
862end:
863 return ret;
864}
865
866struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
867 struct bt_ctf_field_type *integer_container_type)
868{
869 struct bt_ctf_field_type_enumeration *enumeration = NULL;
870
871 if (!integer_container_type) {
872 goto error;
873 }
874
830017b0 875 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
1c822dfb
JG
876 goto error;
877 }
878
879 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
880 if (!enumeration) {
881 goto error;
882 }
883
884 enumeration->parent.declaration = &enumeration->declaration.p;
830017b0 885 enumeration->parent.declaration->id = CTF_TYPE_ENUM;
1c822dfb
JG
886 bt_get(integer_container_type);
887 enumeration->container = integer_container_type;
888 enumeration->entries = g_ptr_array_new_with_free_func(
889 (GDestroyNotify)destroy_enumeration_mapping);
890 bt_ctf_field_type_init(&enumeration->parent, FALSE);
891 return &enumeration->parent;
892error:
893 g_free(enumeration);
894 return NULL;
895}
896
5ad19bf0 897BT_HIDDEN
1c822dfb
JG
898struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
899 struct bt_ctf_field_type *type)
900{
901 struct bt_ctf_field_type *container_type = NULL;
902 struct bt_ctf_field_type_enumeration *enumeration_type;
903
904 if (!type) {
905 goto end;
906 }
907
830017b0 908 if (type->declaration->id != CTF_TYPE_ENUM) {
1c822dfb
JG
909 goto end;
910 }
911
912 enumeration_type = container_of(type,
913 struct bt_ctf_field_type_enumeration, parent);
914 container_type = enumeration_type->container;
915 bt_get(container_type);
916end:
917 return container_type;
918}
919
920int bt_ctf_field_type_enumeration_add_mapping(
921 struct bt_ctf_field_type *type, const char *string,
922 int64_t range_start, int64_t range_end)
923{
924 int ret = 0;
925 GQuark mapping_name;
926 struct enumeration_mapping *mapping;
927 struct bt_ctf_field_type_enumeration *enumeration;
928 struct range_overlap_query query;
929 char *escaped_string;
930
830017b0 931 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
1c822dfb
JG
932 type->frozen ||
933 (range_end < range_start)) {
934 ret = -1;
935 goto end;
936 }
937
938 if (!string || strlen(string) == 0) {
939 ret = -1;
940 goto end;
941 }
942
943 escaped_string = g_strescape(string, NULL);
944 if (!escaped_string) {
945 ret = -1;
946 goto end;
947 }
948
949 mapping_name = g_quark_from_string(escaped_string);
950 query = (struct range_overlap_query) {
951 .range_start._signed = range_start,
952 .range_end._signed = range_end,
953 .mapping_name = mapping_name,
954 .overlaps = 0 };
955 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
956 parent);
957
958 /* Check that the range does not overlap with one already present */
959 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
960 if (query.overlaps) {
961 ret = -1;
962 goto error_free;
963 }
964
965 mapping = g_new(struct enumeration_mapping, 1);
966 if (!mapping) {
967 ret = -1;
968 goto error_free;
969 }
970
971 *mapping = (struct enumeration_mapping) {
972 .range_start._signed = range_start,
973 .range_end._signed = range_end, .string = mapping_name};
974 g_ptr_array_add(enumeration->entries, mapping);
975 g_ptr_array_sort(enumeration->entries,
976 (GCompareFunc)compare_enumeration_mappings_signed);
977error_free:
978 free(escaped_string);
979end:
980 return ret;
981}
982
5ad19bf0 983BT_HIDDEN
1c822dfb
JG
984int bt_ctf_field_type_enumeration_add_mapping_unsigned(
985 struct bt_ctf_field_type *type, const char *string,
986 uint64_t range_start, uint64_t range_end)
987{
988 int ret = 0;
989 GQuark mapping_name;
990 struct enumeration_mapping *mapping;
991 struct bt_ctf_field_type_enumeration *enumeration;
992 struct range_overlap_query query;
993 char *escaped_string;
994
830017b0 995 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
1c822dfb
JG
996 type->frozen ||
997 (range_end < range_start)) {
998 ret = -1;
999 goto end;
1000 }
1001
1002 if (!string || strlen(string) == 0) {
1003 ret = -1;
1004 goto end;
1005 }
1006
1007 escaped_string = g_strescape(string, NULL);
1008 if (!escaped_string) {
1009 ret = -1;
1010 goto end;
1011 }
1012
1013 mapping_name = g_quark_from_string(escaped_string);
1014 query = (struct range_overlap_query) {
1015 .range_start._unsigned = range_start,
1016 .range_end._unsigned = range_end,
1017 .mapping_name = mapping_name,
1018 .overlaps = 0 };
1019 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1020 parent);
1021
1022 /* Check that the range does not overlap with one already present */
1023 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned,
1024 &query);
1025 if (query.overlaps) {
1026 ret = -1;
1027 goto error_free;
1028 }
1029
1030 mapping = g_new(struct enumeration_mapping, 1);
1031 if (!mapping) {
1032 ret = -1;
1033 goto error_free;
1034 }
1035
1036 *mapping = (struct enumeration_mapping) {
1037 .range_start._unsigned = range_start,
1038 .range_end._unsigned = range_end, .string = mapping_name};
1039 g_ptr_array_add(enumeration->entries, mapping);
1040 g_ptr_array_sort(enumeration->entries,
1041 (GCompareFunc)compare_enumeration_mappings_unsigned);
1042error_free:
1043 free(escaped_string);
1044end:
1045 return ret;
1046}
1047
5ad19bf0 1048BT_HIDDEN
1c822dfb
JG
1049const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
1050 struct bt_ctf_field_type_enumeration *enumeration_type,
1051 uint64_t value)
1052{
1053 const char *name = NULL;
1054 struct range_overlap_query query =
1055 (struct range_overlap_query) {
1056 .range_start._unsigned = value,
1057 .range_end._unsigned = value,
1058 .overlaps = 0 };
1059
1060 g_ptr_array_foreach(enumeration_type->entries,
1061 check_ranges_overlap_unsigned,
1062 &query);
1063 if (!query.overlaps) {
1064 goto end;
1065 }
1066
1067 name = g_quark_to_string(query.mapping_name);
1068end:
1069 return name;
1070}
1071
1072const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
1073 struct bt_ctf_field_type_enumeration *enumeration_type,
1074 int64_t value)
1075{
1076 const char *name = NULL;
1077 struct range_overlap_query query =
1078 (struct range_overlap_query) {
1079 .range_start._signed = value,
1080 .range_end._signed = value,
1081 .overlaps = 0 };
1082
1083 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
1084 &query);
1085 if (!query.overlaps) {
1086 goto end;
1087 }
1088
1089 name = g_quark_to_string(query.mapping_name);
1090end:
1091 return name;
1092}
1093
1094int bt_ctf_field_type_enumeration_get_mapping_count(
1095 struct bt_ctf_field_type *type)
1096{
1097 int ret = 0;
1098 struct bt_ctf_field_type_enumeration *enumeration;
1099
830017b0 1100 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
1c822dfb
JG
1101 ret = -1;
1102 goto end;
1103 }
1104
1105 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1106 parent);
1107 ret = (int) enumeration->entries->len;
1108end:
1109 return ret;
1110}
1111
1112static inline
1113struct enumeration_mapping *get_enumeration_mapping(
1114 struct bt_ctf_field_type *type, int index)
1115{
1116 struct enumeration_mapping *mapping = NULL;
1117 struct bt_ctf_field_type_enumeration *enumeration;
1118
1119 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1120 parent);
1121 if (index >= enumeration->entries->len) {
1122 goto end;
1123 }
1124
1125 mapping = g_ptr_array_index(enumeration->entries, index);
1126end:
1127 return mapping;
1128}
1129
5ad19bf0 1130BT_HIDDEN
1c822dfb
JG
1131int bt_ctf_field_type_enumeration_get_mapping(
1132 struct bt_ctf_field_type *type, int index,
1133 const char **string, int64_t *range_start, int64_t *range_end)
1134{
1135 struct enumeration_mapping *mapping;
1136 int ret = 0;
1137
1138 if (!type || index < 0 || !string || !range_start || !range_end ||
830017b0 1139 (type->declaration->id != CTF_TYPE_ENUM)) {
1c822dfb
JG
1140 ret = -1;
1141 goto end;
1142 }
1143
1144 mapping = get_enumeration_mapping(type, index);
1145 if (!mapping) {
1146 ret = -1;
1147 goto end;
1148 }
1149
1150 *string = g_quark_to_string(mapping->string);
1151 *range_start = mapping->range_start._signed;
1152 *range_end = mapping->range_end._signed;
1153end:
1154 return ret;
1155}
1156
5ad19bf0 1157BT_HIDDEN
1c822dfb
JG
1158int bt_ctf_field_type_enumeration_get_mapping_unsigned(
1159 struct bt_ctf_field_type *type, int index,
1160 const char **string, uint64_t *range_start, uint64_t *range_end)
1161{
1162 struct enumeration_mapping *mapping;
1163 int ret = 0;
1164
1165 if (!type || index < 0 || !string || !range_start || !range_end ||
830017b0 1166 (type->declaration->id != CTF_TYPE_ENUM)) {
1c822dfb
JG
1167 ret = -1;
1168 goto end;
1169 }
1170
1171 mapping = get_enumeration_mapping(type, index);
1172 if (!mapping) {
1173 ret = -1;
1174 goto end;
1175 }
1176
1177 *string = g_quark_to_string(mapping->string);
1178 *range_start = mapping->range_start._unsigned;
1179 *range_end = mapping->range_end._unsigned;
1180end:
1181 return ret;
1182}
1183
5ad19bf0 1184BT_HIDDEN
1c822dfb
JG
1185int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
1186 struct bt_ctf_field_type *type, const char *name)
1187{
1188 GQuark name_quark;
1189 struct bt_ctf_field_type_enumeration *enumeration;
1190 int i, ret = 0;
1191
1192 if (!type || !name ||
830017b0 1193 (type->declaration->id != CTF_TYPE_ENUM)) {
1c822dfb
JG
1194 ret = -1;
1195 goto end;
1196 }
1197
1198 name_quark = g_quark_try_string(name);
1199 if (!name_quark) {
1200 ret = -1;
1201 goto end;
1202 }
1203
1204 enumeration = container_of(type,
1205 struct bt_ctf_field_type_enumeration, parent);
1206 for (i = 0; i < enumeration->entries->len; i++) {
1207 struct enumeration_mapping *mapping =
1208 get_enumeration_mapping(type, i);
1209
1210 if (mapping->string == name_quark) {
1211 ret = i;
1212 goto end;
1213 }
1214 }
1215
1216 ret = -1;
1217end:
1218 return ret;
1219}
1220
5ad19bf0 1221BT_HIDDEN
1c822dfb
JG
1222int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
1223 struct bt_ctf_field_type *type, int64_t value)
1224{
1225 struct bt_ctf_field_type_enumeration *enumeration;
1226 int i, ret = 0;
1227
830017b0 1228 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
1c822dfb
JG
1229 ret = -1;
1230 goto end;
1231 }
1232
1233 enumeration = container_of(type,
1234 struct bt_ctf_field_type_enumeration, parent);
1235 for (i = 0; i < enumeration->entries->len; i++) {
1236 struct enumeration_mapping *mapping =
1237 get_enumeration_mapping(type, i);
1238
1239 if (value >= mapping->range_start._signed &&
1240 value <= mapping->range_end._signed) {
1241 ret = i;
1242 goto end;
1243 }
1244 }
1245
1246 ret = -1;
1247end:
1248 return ret;
1249}
1250
5ad19bf0 1251BT_HIDDEN
1c822dfb
JG
1252int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
1253 struct bt_ctf_field_type *type, uint64_t value)
1254{
1255 struct bt_ctf_field_type_enumeration *enumeration;
1256 int i, ret = 0;
1257
830017b0 1258 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
1c822dfb
JG
1259 ret = -1;
1260 goto end;
1261 }
1262
1263 enumeration = container_of(type,
1264 struct bt_ctf_field_type_enumeration, parent);
1265 for (i = 0; i < enumeration->entries->len; i++) {
1266 struct enumeration_mapping *mapping =
1267 get_enumeration_mapping(type, i);
1268
1269 if (value >= mapping->range_start._unsigned &&
1270 value <= mapping->range_end._unsigned) {
1271 ret = i;
1272 goto end;
1273 }
1274 }
1275
1276 ret = -1;
1277end:
1278 return ret;
1279}
1280
1281struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
1282{
1283 struct bt_ctf_field_type_floating_point *floating_point =
1284 g_new0(struct bt_ctf_field_type_floating_point, 1);
1285
1286 if (!floating_point) {
1287 goto end;
1288 }
1289
1290 floating_point->declaration.sign = &floating_point->sign;
1291 floating_point->declaration.mantissa = &floating_point->mantissa;
1292 floating_point->declaration.exp = &floating_point->exp;
1293 floating_point->sign.len = 1;
1294 floating_point->parent.declaration = &floating_point->declaration.p;
830017b0 1295 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
1c822dfb
JG
1296 floating_point->declaration.exp->len =
1297 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
1298 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
1299 floating_point->sign.p.alignment = 1;
1300 floating_point->mantissa.p.alignment = 1;
1301 floating_point->exp.p.alignment = 1;
1302
1303 bt_ctf_field_type_init(&floating_point->parent, TRUE);
1304end:
1305 return floating_point ? &floating_point->parent : NULL;
1306}
1307
5ad19bf0 1308BT_HIDDEN
1c822dfb
JG
1309int bt_ctf_field_type_floating_point_get_exponent_digits(
1310 struct bt_ctf_field_type *type)
1311{
1312 int ret = 0;
1313 struct bt_ctf_field_type_floating_point *floating_point;
1314
830017b0 1315 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1c822dfb
JG
1316 ret = -1;
1317 goto end;
1318 }
1319
1320 floating_point = container_of(type,
1321 struct bt_ctf_field_type_floating_point, parent);
1322 ret = (int) floating_point->declaration.exp->len;
1323end:
1324 return ret;
1325}
1326
1327int bt_ctf_field_type_floating_point_set_exponent_digits(
1328 struct bt_ctf_field_type *type,
1329 unsigned int exponent_digits)
1330{
1331 int ret = 0;
1332 struct bt_ctf_field_type_floating_point *floating_point;
1333
1334 if (!type || type->frozen ||
830017b0 1335 (type->declaration->id != CTF_TYPE_FLOAT)) {
1c822dfb
JG
1336 ret = -1;
1337 goto end;
1338 }
1339
1340 floating_point = container_of(type,
1341 struct bt_ctf_field_type_floating_point, parent);
1342 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1343 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1344 (exponent_digits !=
1345 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1346 ret = -1;
1347 goto end;
1348 }
1349
1350 floating_point->declaration.exp->len = exponent_digits;
1351end:
1352 return ret;
1353}
1354
5ad19bf0 1355BT_HIDDEN
1c822dfb
JG
1356int bt_ctf_field_type_floating_point_get_mantissa_digits(
1357 struct bt_ctf_field_type *type)
1358{
1359 int ret = 0;
1360 struct bt_ctf_field_type_floating_point *floating_point;
1361
830017b0 1362 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1c822dfb
JG
1363 ret = -1;
1364 goto end;
1365 }
1366
1367 floating_point = container_of(type,
1368 struct bt_ctf_field_type_floating_point, parent);
1369 ret = (int) floating_point->mantissa.len + 1;
1370end:
1371 return ret;
1372}
1373
1374int bt_ctf_field_type_floating_point_set_mantissa_digits(
1375 struct bt_ctf_field_type *type,
1376 unsigned int mantissa_digits)
1377{
1378 int ret = 0;
1379 struct bt_ctf_field_type_floating_point *floating_point;
1380
1381 if (!type || type->frozen ||
830017b0 1382 (type->declaration->id != CTF_TYPE_FLOAT)) {
1c822dfb
JG
1383 ret = -1;
1384 goto end;
1385 }
1386
1387 floating_point = container_of(type,
1388 struct bt_ctf_field_type_floating_point, parent);
1389
1390 if ((mantissa_digits != FLT_MANT_DIG) &&
1391 (mantissa_digits != DBL_MANT_DIG) &&
1392 (mantissa_digits != LDBL_MANT_DIG)) {
1393 ret = -1;
1394 goto end;
1395 }
1396
1397 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1398end:
1399 return ret;
1400}
1401
1402struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1403{
1404 struct bt_ctf_field_type_structure *structure =
1405 g_new0(struct bt_ctf_field_type_structure, 1);
1406
1407 if (!structure) {
1408 goto error;
1409 }
1410
1411 structure->parent.declaration = &structure->declaration.p;
830017b0 1412 structure->parent.declaration->id = CTF_TYPE_STRUCT;
1c822dfb
JG
1413 structure->fields = g_ptr_array_new_with_free_func(
1414 (GDestroyNotify)destroy_structure_field);
1415 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
1416 bt_ctf_field_type_init(&structure->parent, TRUE);
1417 return &structure->parent;
1418error:
1419 return NULL;
1420}
1421
1422int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1423 struct bt_ctf_field_type *field_type,
1424 const char *field_name)
1425{
1426 int ret = 0;
1427 struct bt_ctf_field_type_structure *structure;
1428
1429 if (!type || !field_type || type->frozen ||
1430 bt_ctf_validate_identifier(field_name) ||
830017b0 1431 (type->declaration->id != CTF_TYPE_STRUCT)) {
1c822dfb
JG
1432 ret = -1;
1433 goto end;
1434 }
1435
1436 structure = container_of(type,
1437 struct bt_ctf_field_type_structure, parent);
1438 if (add_structure_field(structure->fields,
1439 structure->field_name_to_index, field_type, field_name)) {
1440 ret = -1;
1441 goto end;
1442 }
1443end:
1444 return ret;
1445}
1446
5ad19bf0 1447BT_HIDDEN
1c822dfb
JG
1448int bt_ctf_field_type_structure_get_field_count(
1449 struct bt_ctf_field_type *type)
1450{
1451 int ret = 0;
1452 struct bt_ctf_field_type_structure *structure;
1453
830017b0 1454 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1c822dfb
JG
1455 ret = -1;
1456 goto end;
1457 }
1458
1459 structure = container_of(type, struct bt_ctf_field_type_structure,
1460 parent);
1461 ret = (int) structure->fields->len;
1462end:
1463 return ret;
1464}
1465
1466int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1467 const char **field_name, struct bt_ctf_field_type **field_type,
1468 int index)
1469{
1470 struct bt_ctf_field_type_structure *structure;
1471 struct structure_field *field;
1472 int ret = 0;
1473
1474 if (!type || index < 0 ||
830017b0 1475 (type->declaration->id != CTF_TYPE_STRUCT)) {
1c822dfb
JG
1476 ret = -1;
1477 goto end;
1478 }
1479
1480 structure = container_of(type, struct bt_ctf_field_type_structure,
1481 parent);
1482 if (index >= structure->fields->len) {
1483 ret = -1;
1484 goto end;
1485 }
1486
1487 field = g_ptr_array_index(structure->fields, index);
1488 if (field_type) {
1489 *field_type = field->type;
1490 bt_get(field->type);
1491 }
1492 if (field_name) {
1493 *field_name = g_quark_to_string(field->name);
1494 }
1495end:
1496 return ret;
1497}
1498
5ad19bf0 1499BT_HIDDEN
1c822dfb
JG
1500struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1501 struct bt_ctf_field_type *type,
1502 const char *name)
1503{
1504 size_t index;
1505 GQuark name_quark;
1506 struct structure_field *field;
1507 struct bt_ctf_field_type_structure *structure;
1508 struct bt_ctf_field_type *field_type = NULL;
1509
1510 if (!type || !name) {
1511 goto end;
1512 }
1513
1514 name_quark = g_quark_try_string(name);
1515 if (!name_quark) {
1516 goto end;
1517 }
1518
1519 structure = container_of(type, struct bt_ctf_field_type_structure,
1520 parent);
1521 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1522 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1523 goto end;
1524 }
1525
1526 field = structure->fields->pdata[index];
1527 field_type = field->type;
1528 bt_get(field_type);
1529end:
1530 return field_type;
1531}
1532
1533struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1534 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1535{
1536 struct bt_ctf_field_type_variant *variant = NULL;
1537
1538 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
1539 goto error;
1540 }
1541
1542 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1543 if (!variant) {
1544 goto error;
1545 }
1546
1547 variant->parent.declaration = &variant->declaration.p;
830017b0 1548 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1c822dfb
JG
1549 variant->tag_name = g_string_new(tag_name);
1550 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1551 variant->fields = g_ptr_array_new_with_free_func(
1552 (GDestroyNotify) destroy_structure_field);
1553 if (enum_tag) {
1554 bt_get(enum_tag);
1555 variant->tag = container_of(enum_tag,
1556 struct bt_ctf_field_type_enumeration, parent);
1557 }
1558
1559 bt_ctf_field_type_init(&variant->parent, TRUE);
1560 /* A variant's alignment is undefined */
1561 variant->parent.declaration->alignment = 0;
1562 return &variant->parent;
1563error:
1564 return NULL;
1565}
1566
5ad19bf0 1567BT_HIDDEN
1c822dfb
JG
1568struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1569 struct bt_ctf_field_type *type)
1570{
1571 struct bt_ctf_field_type_variant *variant;
1572 struct bt_ctf_field_type *tag_type = NULL;
1573
830017b0 1574 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1c822dfb
JG
1575 goto end;
1576 }
1577
1578 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1579 if (!variant->tag) {
1580 goto end;
1581 }
1582
1583 tag_type = &variant->tag->parent;
1584 bt_get(tag_type);
1585end:
1586 return tag_type;
1587}
1588
5ad19bf0 1589BT_HIDDEN
1c822dfb
JG
1590const char *bt_ctf_field_type_variant_get_tag_name(
1591 struct bt_ctf_field_type *type)
1592{
1593 struct bt_ctf_field_type_variant *variant;
1594 const char *tag_name = NULL;
1595
830017b0 1596 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1c822dfb
JG
1597 goto end;
1598 }
1599
1600 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1601 if (variant->tag_name->len == 0) {
1602 goto end;
1603 }
1604
1605 tag_name = variant->tag_name->str;
1606end:
1607 return tag_name;
1608}
1609
5ad19bf0 1610BT_HIDDEN
1c822dfb
JG
1611int bt_ctf_field_type_variant_set_tag_name(
1612 struct bt_ctf_field_type *type, const char *name)
1613{
1614 int ret = 0;
1615 struct bt_ctf_field_type_variant *variant;
1616
1617 if (!type || type->frozen ||
830017b0 1618 (type->declaration->id != CTF_TYPE_VARIANT) ||
1c822dfb
JG
1619 bt_ctf_validate_identifier(name)) {
1620 ret = -1;
1621 goto end;
1622 }
1623
1624 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1625 g_string_assign(variant->tag_name, name);
1626end:
1627 return ret;
1628}
1629
1630int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1631 struct bt_ctf_field_type *field_type,
1632 const char *field_name)
1633{
1634 size_t i;
1635 int ret = 0;
1636 struct bt_ctf_field_type_variant *variant;
1637 GQuark field_name_quark = g_quark_from_string(field_name);
1638
1639 if (!type || !field_type || type->frozen ||
1640 bt_ctf_validate_identifier(field_name) ||
830017b0 1641 (type->declaration->id != CTF_TYPE_VARIANT)) {
1c822dfb
JG
1642 ret = -1;
1643 goto end;
1644 }
1645
1646 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1647
1648 /* The user has explicitly provided a tag; validate against it. */
1649 if (variant->tag) {
1650 int name_found = 0;
1651
1652 /* Make sure this name is present in the enum tag */
1653 for (i = 0; i < variant->tag->entries->len; i++) {
1654 struct enumeration_mapping *mapping =
1655 g_ptr_array_index(variant->tag->entries, i);
1656
1657 if (mapping->string == field_name_quark) {
1658 name_found = 1;
1659 break;
1660 }
1661 }
1662
1663 if (!name_found) {
1664 /* Validation failed */
1665 ret = -1;
1666 goto end;
1667 }
1668 }
1669
1670 if (add_structure_field(variant->fields, variant->field_name_to_index,
1671 field_type, field_name)) {
1672 ret = -1;
1673 goto end;
1674 }
1675end:
1676 return ret;
1677}
1678
5ad19bf0 1679BT_HIDDEN
1c822dfb
JG
1680struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1681 struct bt_ctf_field_type *type,
1682 const char *field_name)
1683{
1684 size_t index;
1685 GQuark name_quark;
1686 struct structure_field *field;
1687 struct bt_ctf_field_type_variant *variant;
1688 struct bt_ctf_field_type *field_type = NULL;
1689
1690 if (!type || !field_name) {
1691 goto end;
1692 }
1693
1694 name_quark = g_quark_try_string(field_name);
1695 if (!name_quark) {
1696 goto end;
1697 }
1698
1699 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1700 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1701 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1702 goto end;
1703 }
1704
1705 field = g_ptr_array_index(variant->fields, index);
1706 field_type = field->type;
1707 bt_get(field_type);
1708end:
1709 return field_type;
1710}
1711
5ad19bf0 1712BT_HIDDEN
1c822dfb
JG
1713struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1714 struct bt_ctf_field_type *type,
1715 struct bt_ctf_field *tag)
1716{
1717 const char *enum_value;
1718 struct bt_ctf_field_type *field_type = NULL;
1719
830017b0 1720 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1c822dfb
JG
1721 goto end;
1722 }
1723
1724 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1725 if (!enum_value) {
1726 goto end;
1727 }
1728
1729 /* Already increments field_type's reference count */
1730 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1731 type, enum_value);
1732end:
1733 return field_type;
1734}
1735
1736int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1737{
1738 int ret = 0;
1739 struct bt_ctf_field_type_variant *variant;
1740
830017b0 1741 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1c822dfb
JG
1742 ret = -1;
1743 goto end;
1744 }
1745
1746 variant = container_of(type, struct bt_ctf_field_type_variant,
1747 parent);
1748 ret = (int) variant->fields->len;
1749end:
1750 return ret;
1751
1752}
1753
5ad19bf0 1754BT_HIDDEN
1c822dfb
JG
1755int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1756 const char **field_name, struct bt_ctf_field_type **field_type,
1757 int index)
1758{
1759 struct bt_ctf_field_type_variant *variant;
1760 struct structure_field *field;
1761 int ret = 0;
1762
1763 if (!type || index < 0 ||
830017b0 1764 (type->declaration->id != CTF_TYPE_VARIANT)) {
1c822dfb
JG
1765 ret = -1;
1766 goto end;
1767 }
1768
1769 variant = container_of(type, struct bt_ctf_field_type_variant,
1770 parent);
1771 if (index >= variant->fields->len) {
1772 ret = -1;
1773 goto end;
1774 }
1775
1776 field = g_ptr_array_index(variant->fields, index);
1777 if (field_type) {
1778 *field_type = field->type;
1779 bt_get(field->type);
1780 }
1781 if (field_name) {
1782 *field_name = g_quark_to_string(field->name);
1783 }
1784end:
1785 return ret;
1786}
1787
1788struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1789 struct bt_ctf_field_type *element_type,
1790 unsigned int length)
1791{
1792 struct bt_ctf_field_type_array *array = NULL;
1793
1794 if (!element_type || length == 0) {
1795 goto error;
1796 }
1797
1798 array = g_new0(struct bt_ctf_field_type_array, 1);
1799 if (!array) {
1800 goto error;
1801 }
1802
1803 array->parent.declaration = &array->declaration.p;
830017b0 1804 array->parent.declaration->id = CTF_TYPE_ARRAY;
1c822dfb
JG
1805
1806 bt_get(element_type);
1807 array->element_type = element_type;
1808 array->length = length;
1809 bt_ctf_field_type_init(&array->parent, FALSE);
1810 return &array->parent;
1811error:
1812 return NULL;
1813}
1814
5ad19bf0 1815BT_HIDDEN
1c822dfb
JG
1816struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1817 struct bt_ctf_field_type *type)
1818{
1819 struct bt_ctf_field_type *ret = NULL;
1820 struct bt_ctf_field_type_array *array;
1821
830017b0 1822 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1c822dfb
JG
1823 goto end;
1824 }
1825
1826 array = container_of(type, struct bt_ctf_field_type_array, parent);
1827 ret = array->element_type;
1828 bt_get(ret);
1829end:
1830 return ret;
1831}
1832
1833BT_HIDDEN
1834int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
1835 struct bt_ctf_field_type *element_type)
1836{
1837 int ret = 0;
1838 struct bt_ctf_field_type_array *array;
1839
1840 if (!type || !element_type ||
830017b0 1841 (type->declaration->id != CTF_TYPE_ARRAY)) {
1c822dfb
JG
1842 ret = -1;
1843 goto end;
1844 }
1845
1846 array = container_of(type, struct bt_ctf_field_type_array, parent);
1847
1848 if (array->element_type) {
1849 BT_PUT(array->element_type);
1850 }
1851
1852 array->element_type = element_type;
1853 bt_get(array->element_type);
1854
1855end:
1856 return ret;
1857}
1858
5ad19bf0 1859BT_HIDDEN
1c822dfb
JG
1860int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1861{
1862 int64_t ret;
1863 struct bt_ctf_field_type_array *array;
1864
830017b0 1865 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1c822dfb
JG
1866 ret = -1;
1867 goto end;
1868 }
1869
1870 array = container_of(type, struct bt_ctf_field_type_array, parent);
1871 ret = (int64_t) array->length;
1872end:
1873 return ret;
1874}
1875
1876struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1877 struct bt_ctf_field_type *element_type,
1878 const char *length_field_name)
1879{
1880 struct bt_ctf_field_type_sequence *sequence = NULL;
1881
1882 if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
1883 goto error;
1884 }
1885
1886 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1887 if (!sequence) {
1888 goto error;
1889 }
1890
1891 sequence->parent.declaration = &sequence->declaration.p;
830017b0 1892 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
1c822dfb
JG
1893 bt_get(element_type);
1894 sequence->element_type = element_type;
1895 sequence->length_field_name = g_string_new(length_field_name);
1896 bt_ctf_field_type_init(&sequence->parent, FALSE);
1897 return &sequence->parent;
1898error:
1899 return NULL;
1900}
1901
5ad19bf0 1902BT_HIDDEN
1c822dfb
JG
1903struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1904 struct bt_ctf_field_type *type)
1905{
1906 struct bt_ctf_field_type *ret = NULL;
1907 struct bt_ctf_field_type_sequence *sequence;
1908
830017b0 1909 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1c822dfb
JG
1910 goto end;
1911 }
1912
1913 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1914 parent);
1915 ret = sequence->element_type;
1916 bt_get(ret);
1917end:
1918 return ret;
1919}
1920
1921BT_HIDDEN
1922int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
1923 struct bt_ctf_field_type *element_type)
1924{
1925 int ret = 0;
1926 struct bt_ctf_field_type_sequence *sequence;
1927
1928 if (!type || !element_type ||
830017b0 1929 (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1c822dfb
JG
1930 ret = -1;
1931 goto end;
1932 }
1933
1934 sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
1935
1936 if (sequence->element_type) {
1937 BT_PUT(sequence->element_type);
1938 }
1939
1940 sequence->element_type = element_type;
1941 bt_get(sequence->element_type);
1942
1943end:
1944 return ret;
1945}
1946
5ad19bf0 1947BT_HIDDEN
1c822dfb
JG
1948const char *bt_ctf_field_type_sequence_get_length_field_name(
1949 struct bt_ctf_field_type *type)
1950{
1951 const char *ret = NULL;
1952 struct bt_ctf_field_type_sequence *sequence;
1953
830017b0 1954 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1c822dfb
JG
1955 goto end;
1956 }
1957
1958 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1959 parent);
1960 ret = sequence->length_field_name->str;
1961end:
1962 return ret;
1963}
1964
1965struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1966{
1967 struct bt_ctf_field_type_string *string =
1968 g_new0(struct bt_ctf_field_type_string, 1);
1969
1970 if (!string) {
1971 return NULL;
1972 }
1973
1974 string->parent.declaration = &string->declaration.p;
830017b0 1975 string->parent.declaration->id = CTF_TYPE_STRING;
1c822dfb
JG
1976 bt_ctf_field_type_init(&string->parent, TRUE);
1977 string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
1978 string->parent.declaration->alignment = CHAR_BIT;
1979 return &string->parent;
1980}
1981
5ad19bf0 1982BT_HIDDEN
1c822dfb
JG
1983enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1984 struct bt_ctf_field_type *type)
1985{
1986 struct bt_ctf_field_type_string *string;
1987 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
1988
830017b0 1989 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1c822dfb
JG
1990 goto end;
1991 }
1992
1993 string = container_of(type, struct bt_ctf_field_type_string,
1994 parent);
1995 ret = string->declaration.encoding;
1996end:
1997 return ret;
1998}
1999
2000int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
2001 enum bt_ctf_string_encoding encoding)
2002{
2003 int ret = 0;
2004 struct bt_ctf_field_type_string *string;
2005
830017b0 2006 if (!type || type->declaration->id != CTF_TYPE_STRING ||
1c822dfb
JG
2007 (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
2008 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
2009 ret = -1;
2010 goto end;
2011 }
2012
2013 string = container_of(type, struct bt_ctf_field_type_string, parent);
2014 string->declaration.encoding = encoding;
2015end:
2016 return ret;
2017}
2018
5ad19bf0 2019BT_HIDDEN
1c822dfb
JG
2020int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
2021{
2022 int ret;
830017b0 2023 enum ctf_type_id type_id;
1c822dfb
JG
2024
2025 if (!type) {
2026 ret = -1;
2027 goto end;
2028 }
2029
2030 if (type->frozen) {
2031 ret = (int) type->declaration->alignment;
2032 goto end;
2033 }
2034
2035 type_id = bt_ctf_field_type_get_type_id(type);
2036 switch (type_id) {
830017b0 2037 case CTF_TYPE_SEQUENCE:
1c822dfb
JG
2038 {
2039 struct bt_ctf_field_type *element =
2040 bt_ctf_field_type_sequence_get_element_type(type);
2041
2042 if (!element) {
2043 ret = -1;
2044 goto end;
2045 }
2046
2047 ret = bt_ctf_field_type_get_alignment(element);
2048 bt_put(element);
2049 break;
2050 }
830017b0 2051 case CTF_TYPE_ARRAY:
1c822dfb
JG
2052 {
2053 struct bt_ctf_field_type *element =
2054 bt_ctf_field_type_array_get_element_type(type);
2055
2056 if (!element) {
2057 ret = -1;
2058 goto end;
2059 }
2060
2061 ret = bt_ctf_field_type_get_alignment(element);
2062 bt_put(element);
2063 break;
2064 }
830017b0 2065 case CTF_TYPE_STRUCT:
1c822dfb
JG
2066 {
2067 int i, element_count;
2068
2069 element_count = bt_ctf_field_type_structure_get_field_count(
2070 type);
2071 if (element_count < 0) {
2072 ret = element_count;
2073 goto end;
2074 }
2075
2076 for (i = 0; i < element_count; i++) {
2077 struct bt_ctf_field_type *field;
2078 int field_alignment;
2079
2080 ret = bt_ctf_field_type_structure_get_field(type, NULL,
2081 &field, i);
2082 if (ret) {
2083 goto end;
2084 }
2085
2086 assert(field);
2087 field_alignment = bt_ctf_field_type_get_alignment(
2088 field);
2089 bt_put(field);
2090 if (field_alignment < 0) {
2091 ret = field_alignment;
2092 goto end;
2093 }
2094
2095 type->declaration->alignment = MAX(field_alignment,
2096 type->declaration->alignment);
2097 }
2098 ret = (int) type->declaration->alignment;
2099 break;
2100 }
830017b0 2101 case CTF_TYPE_UNKNOWN:
1c822dfb
JG
2102 ret = -1;
2103 break;
2104 default:
2105 ret = (int) type->declaration->alignment;
2106 break;
2107 }
2108end:
2109 return ret;
2110}
2111
2112static inline
2113int is_power_of_two(unsigned int value)
2114{
2115 return ((value & (value - 1)) == 0) && value > 0;
2116}
2117
2118int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
2119 unsigned int alignment)
2120{
2121 int ret = 0;
830017b0 2122 enum ctf_type_id type_id;
1c822dfb
JG
2123
2124 /* Alignment must be a power of two */
2125 if (!type || type->frozen || !is_power_of_two(alignment)) {
2126 ret = -1;
2127 goto end;
2128 }
2129
2130 type_id = bt_ctf_field_type_get_type_id(type);
830017b0 2131 if (type_id == CTF_TYPE_UNKNOWN) {
1c822dfb
JG
2132 ret = -1;
2133 goto end;
2134 }
2135
830017b0 2136 if (type->declaration->id == CTF_TYPE_STRING &&
1c822dfb
JG
2137 alignment != CHAR_BIT) {
2138 ret = -1;
2139 goto end;
2140 }
2141
830017b0
JG
2142 if (type_id == CTF_TYPE_VARIANT ||
2143 type_id == CTF_TYPE_SEQUENCE ||
2144 type_id == CTF_TYPE_ARRAY) {
1c822dfb
JG
2145 /* Setting an alignment on these types makes no sense */
2146 ret = -1;
2147 goto end;
2148 }
2149
2150 type->declaration->alignment = alignment;
2151 ret = 0;
2152end:
2153 return ret;
2154}
2155
5ad19bf0 2156BT_HIDDEN
1c822dfb
JG
2157enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
2158 struct bt_ctf_field_type *type)
2159{
2160 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
2161
2162 if (!type) {
2163 goto end;
2164 }
2165
2166 switch (type->declaration->id) {
830017b0 2167 case CTF_TYPE_INTEGER:
1c822dfb
JG
2168 {
2169 struct bt_ctf_field_type_integer *integer = container_of(
2170 type, struct bt_ctf_field_type_integer, parent);
2171 ret = integer->user_byte_order;
2172 break;
2173 }
830017b0 2174 case CTF_TYPE_FLOAT:
1c822dfb
JG
2175 {
2176 struct bt_ctf_field_type_floating_point *floating_point =
2177 container_of(type,
2178 struct bt_ctf_field_type_floating_point,
2179 parent);
2180 ret = floating_point->user_byte_order;
2181 break;
2182 }
2183 default:
2184 goto end;
2185 }
2186
2187 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2188 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2189 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2190 ret == BT_CTF_BYTE_ORDER_NETWORK);
2191
2192end:
2193 return ret;
2194}
2195
2196int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2197 enum bt_ctf_byte_order byte_order)
2198{
2199 int ret = 0;
2200 int internal_byte_order;
830017b0 2201 enum ctf_type_id type_id;
1c822dfb
JG
2202
2203 if (!type || type->frozen) {
2204 ret = -1;
2205 goto end;
2206 }
2207
2208 switch (byte_order) {
2209 case BT_CTF_BYTE_ORDER_NATIVE:
2210 /* Leave unset. Will be initialized by parent. */
2211 internal_byte_order = 0;
2212 break;
2213 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2214 internal_byte_order = LITTLE_ENDIAN;
2215 break;
2216 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2217 case BT_CTF_BYTE_ORDER_NETWORK:
2218 internal_byte_order = BIG_ENDIAN;
2219 break;
2220 default:
2221 ret = -1;
2222 goto end;
2223 }
2224
2225 type_id = type->declaration->id;
2226 if (set_byte_order_funcs[type_id]) {
2227 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
2228 }
2229end:
2230 return ret;
2231}
2232
5ad19bf0 2233BT_HIDDEN
830017b0 2234enum ctf_type_id bt_ctf_field_type_get_type_id(
1c822dfb
JG
2235 struct bt_ctf_field_type *type)
2236{
2237 if (!type) {
830017b0 2238 return CTF_TYPE_UNKNOWN;
1c822dfb
JG
2239 }
2240
2241 return type->declaration->id;
2242}
2243
5ad19bf0 2244BT_HIDDEN
1c822dfb
JG
2245int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2246{
830017b0 2247 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_INTEGER;
1c822dfb
JG
2248}
2249
5ad19bf0 2250BT_HIDDEN
1c822dfb
JG
2251int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2252{
830017b0 2253 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_FLOAT;
1c822dfb
JG
2254}
2255
5ad19bf0 2256BT_HIDDEN
1c822dfb
JG
2257int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2258{
830017b0 2259 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_ENUM;
1c822dfb
JG
2260}
2261
5ad19bf0 2262BT_HIDDEN
1c822dfb
JG
2263int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2264{
830017b0 2265 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_STRING;
1c822dfb
JG
2266}
2267
5ad19bf0 2268BT_HIDDEN
1c822dfb
JG
2269int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2270{
830017b0 2271 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_STRUCT;
1c822dfb
JG
2272}
2273
5ad19bf0 2274BT_HIDDEN
1c822dfb
JG
2275int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2276{
830017b0 2277 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_ARRAY;
1c822dfb
JG
2278}
2279
5ad19bf0 2280BT_HIDDEN
1c822dfb
JG
2281int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2282{
830017b0 2283 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_SEQUENCE;
1c822dfb
JG
2284}
2285
5ad19bf0 2286BT_HIDDEN
1c822dfb
JG
2287int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2288{
830017b0 2289 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_VARIANT;
1c822dfb
JG
2290}
2291
2292void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2293{
2294 bt_get(type);
2295}
2296
2297void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2298{
2299 bt_put(type);
2300}
2301
2302BT_HIDDEN
2303void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2304{
2305 if (!type) {
2306 return;
2307 }
2308
2309 type->freeze(type);
2310}
2311
2312BT_HIDDEN
2313struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2314 struct bt_ctf_field_type_variant *variant,
2315 int64_t tag_value)
2316{
2317 struct bt_ctf_field_type *type = NULL;
2318 GQuark field_name_quark;
2319 gpointer index;
2320 struct structure_field *field_entry;
2321 struct range_overlap_query query = {
2322 .range_start._signed = tag_value,
2323 .range_end._signed = tag_value,
2324 .mapping_name = 0, .overlaps = 0};
2325
2326 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2327 &query);
2328 if (!query.overlaps) {
2329 goto end;
2330 }
2331
2332 field_name_quark = query.mapping_name;
2333 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2334 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2335 goto end;
2336 }
2337
2338 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
2339 type = field_entry->type;
2340end:
2341 return type;
2342}
2343
2344BT_HIDDEN
2345struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
2346 struct bt_ctf_field_type_variant *variant,
2347 uint64_t tag_value)
2348{
2349 struct bt_ctf_field_type *type = NULL;
2350 GQuark field_name_quark;
2351 gpointer index;
2352 struct structure_field *field_entry;
2353 struct range_overlap_query query = {
2354 .range_start._unsigned = tag_value,
2355 .range_end._unsigned = tag_value,
2356 .mapping_name = 0, .overlaps = 0};
2357
2358 g_ptr_array_foreach(variant->tag->entries,
2359 check_ranges_overlap_unsigned,
2360 &query);
2361 if (!query.overlaps) {
2362 goto end;
2363 }
2364
2365 field_name_quark = query.mapping_name;
2366 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2367 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2368 goto end;
2369 }
2370
2371 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2372 type = field_entry->type;
2373end:
2374 return type;
2375}
2376
2377BT_HIDDEN
2378int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2379 struct metadata_context *context)
2380{
2381 int ret;
2382
2383 if (!type || !context) {
2384 ret = -1;
2385 goto end;
2386 }
2387
2388 /* Make sure field type is valid before serializing it */
2389 ret = bt_ctf_field_type_validate(type);
2390
2391 if (ret) {
2392 goto end;
2393 }
2394
2395 ret = type->serialize(type, context);
2396end:
2397 return ret;
2398}
2399
2400BT_HIDDEN
2401void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2402 int byte_order)
2403{
2404 if (!type) {
2405 return;
2406 }
2407
2408 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2409 if (set_byte_order_funcs[type->declaration->id]) {
2410 set_byte_order_funcs[type->declaration->id](type,
2411 byte_order, 1);
2412 }
2413}
2414
2415BT_HIDDEN
2416struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2417{
2418 struct bt_ctf_field_type *copy = NULL;
2419
2420 if (!type) {
2421 goto end;
2422 }
2423
2424 copy = type_copy_funcs[type->declaration->id](type);
2425end:
2426 return copy;
2427}
2428
2429BT_HIDDEN
2430int bt_ctf_field_type_structure_get_field_name_index(
2431 struct bt_ctf_field_type *type, const char *name)
2432{
2433 int ret;
2434 size_t index;
2435 GQuark name_quark;
2436 struct bt_ctf_field_type_structure *structure;
2437
2438 if (!type || !name ||
830017b0 2439 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
1c822dfb
JG
2440 ret = -1;
2441 goto end;
2442 }
2443
2444 name_quark = g_quark_try_string(name);
2445 if (!name_quark) {
2446 ret = -1;
2447 goto end;
2448 }
2449
2450 structure = container_of(type, struct bt_ctf_field_type_structure,
2451 parent);
2452 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2453 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2454 ret = -1;
2455 goto end;
2456 }
2457 ret = (int) index;
2458end:
2459 return ret;
2460}
2461
2462BT_HIDDEN
2463int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2464 struct bt_ctf_field_type *field, int index)
2465{
2466 int ret = 0;
2467 struct bt_ctf_field_type_structure *structure;
2468
2469 if (!type || !field ||
830017b0 2470 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
1c822dfb
JG
2471 ret = -1;
2472 goto end;
2473 }
2474
2475 structure = container_of(type, struct bt_ctf_field_type_structure,
2476 parent);
2477 if (index < 0 || index >= structure->fields->len) {
2478 ret = -1;
2479 goto end;
2480 }
2481
2482 bt_get(field);
2483 bt_put(((struct structure_field *)
2484 g_ptr_array_index(structure->fields, index))->type);
2485 ((struct structure_field *) structure->fields->pdata[index])->type =
2486 field;
2487end:
2488 return ret;
2489}
2490
2491BT_HIDDEN
2492int bt_ctf_field_type_variant_get_field_name_index(
2493 struct bt_ctf_field_type *type, const char *name)
2494{
2495 int ret;
2496 size_t index;
2497 GQuark name_quark;
2498 struct bt_ctf_field_type_variant *variant;
2499
2500 if (!type || !name ||
830017b0 2501 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
1c822dfb
JG
2502 ret = -1;
2503 goto end;
2504 }
2505
2506 name_quark = g_quark_try_string(name);
2507 if (!name_quark) {
2508 ret = -1;
2509 goto end;
2510 }
2511
2512 variant = container_of(type, struct bt_ctf_field_type_variant,
2513 parent);
2514 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2515 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2516 ret = -1;
2517 goto end;
2518 }
2519 ret = (int) index;
2520end:
2521 return ret;
2522}
2523
2524BT_HIDDEN
2525int bt_ctf_field_type_sequence_set_length_field_path(
2526 struct bt_ctf_field_type *type,
2527 struct bt_ctf_field_path *path)
2528{
2529 int ret = 0;
2530 struct bt_ctf_field_type_sequence *sequence;
2531
2532 if (!type || bt_ctf_field_type_get_type_id(type) !=
830017b0 2533 CTF_TYPE_SEQUENCE) {
1c822dfb
JG
2534 ret = -1;
2535 goto end;
2536 }
2537
2538 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2539 parent);
2540 bt_get(path);
2541 BT_MOVE(sequence->length_field_path, path);
2542end:
2543 return ret;
2544}
2545
2546BT_HIDDEN
2547int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2548 struct bt_ctf_field_path *path)
2549{
2550 int ret = 0;
2551 struct bt_ctf_field_type_variant *variant;
2552
2553 if (!type || bt_ctf_field_type_get_type_id(type) !=
830017b0 2554 CTF_TYPE_VARIANT) {
1c822dfb
JG
2555 ret = -1;
2556 goto end;
2557 }
2558
2559 variant = container_of(type, struct bt_ctf_field_type_variant,
2560 parent);
2561 bt_get(path);
2562 BT_MOVE(variant->tag_field_path, path);
2563end:
2564 return ret;
2565}
2566
2567BT_HIDDEN
2568int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
2569 struct bt_ctf_field_type *tag)
2570{
2571 int ret = 0;
2572 struct bt_ctf_field_type_variant *variant;
2573
2574 if (!type || !tag ||
2575 bt_ctf_field_type_get_type_id(tag) !=
830017b0 2576 CTF_TYPE_ENUM) {
1c822dfb
JG
2577 ret = -1;
2578 goto end;
2579 }
2580
2581 variant = container_of(type, struct bt_ctf_field_type_variant,
2582 parent);
2583 bt_get(tag);
2584 if (variant->tag) {
2585 bt_put(&variant->tag->parent);
2586 }
2587 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2588 parent);
2589end:
2590 return ret;
2591}
2592
2593BT_HIDDEN
2594int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2595 struct bt_ctf_field_type *field, int index)
2596{
2597 int ret = 0;
2598 struct bt_ctf_field_type_variant *variant;
2599
2600 if (!type || !field ||
830017b0 2601 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
1c822dfb
JG
2602 ret = -1;
2603 goto end;
2604 }
2605
2606 variant = container_of(type, struct bt_ctf_field_type_variant,
2607 parent);
2608 if (index < 0 || index >= variant->fields->len) {
2609 ret = -1;
2610 goto end;
2611 }
2612
2613 bt_get(field);
2614 bt_put(((struct structure_field *)
2615 g_ptr_array_index(variant->fields, index))->type);
2616 ((struct structure_field *) variant->fields->pdata[index])->type =
2617 field;
2618end:
2619 return ret;
2620}
2621
2622static
2623void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
2624{
2625 struct bt_ctf_field_type_integer *integer =
2626 (struct bt_ctf_field_type_integer *) type;
2627
2628 if (!type) {
2629 return;
2630 }
2631
2632 bt_put(integer->mapped_clock);
2633 g_free(integer);
2634}
2635
2636static
2637void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
2638{
2639 struct bt_ctf_field_type_enumeration *enumeration =
2640 (struct bt_ctf_field_type_enumeration *) type;
2641
2642 if (!type) {
2643 return;
2644 }
2645
2646 g_ptr_array_free(enumeration->entries, TRUE);
2647 bt_put(enumeration->container);
2648 g_free(enumeration);
2649}
2650
2651static
2652void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
2653{
2654 struct bt_ctf_field_type_floating_point *floating_point =
2655 (struct bt_ctf_field_type_floating_point *) type;
2656
2657 if (!type) {
2658 return;
2659 }
2660
2661 g_free(floating_point);
2662}
2663
2664static
2665void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
2666{
2667 struct bt_ctf_field_type_structure *structure =
2668 (struct bt_ctf_field_type_structure *) type;
2669
2670 if (!type) {
2671 return;
2672 }
2673
2674 g_ptr_array_free(structure->fields, TRUE);
2675 g_hash_table_destroy(structure->field_name_to_index);
2676 g_free(structure);
2677}
2678
2679static
2680void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
2681{
2682 struct bt_ctf_field_type_variant *variant =
2683 (struct bt_ctf_field_type_variant *) type;
2684
2685 if (!type) {
2686 return;
2687 }
2688
2689 g_ptr_array_free(variant->fields, TRUE);
2690 g_hash_table_destroy(variant->field_name_to_index);
2691 g_string_free(variant->tag_name, TRUE);
2692 bt_put(&variant->tag->parent);
2693 BT_PUT(variant->tag_field_path);
2694 g_free(variant);
2695}
2696
2697static
2698void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
2699{
2700 struct bt_ctf_field_type_array *array =
2701 (struct bt_ctf_field_type_array *) type;
2702
2703 if (!type) {
2704 return;
2705 }
2706
2707 bt_put(array->element_type);
2708 g_free(array);
2709}
2710
2711static
2712void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
2713{
2714 struct bt_ctf_field_type_sequence *sequence =
2715 (struct bt_ctf_field_type_sequence *) type;
2716
2717 if (!type) {
2718 return;
2719 }
2720
2721 bt_put(sequence->element_type);
2722 g_string_free(sequence->length_field_name, TRUE);
2723 BT_PUT(sequence->length_field_path);
2724 g_free(sequence);
2725}
2726
2727static
2728void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
2729{
2730 struct bt_ctf_field_type_string *string =
2731 (struct bt_ctf_field_type_string *) type;
2732
2733 if (!type) {
2734 return;
2735 }
2736
2737 g_free(string);
2738}
2739
2740static
2741void generic_field_type_freeze(struct bt_ctf_field_type *type)
2742{
2743 type->frozen = 1;
2744}
2745
2746static
2747void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2748{
2749 struct bt_ctf_field_type_integer *integer_type = container_of(
2750 type, struct bt_ctf_field_type_integer, parent);
2751
2752 if (integer_type->mapped_clock) {
2753 bt_ctf_clock_freeze(integer_type->mapped_clock);
2754 }
2755
2756 generic_field_type_freeze(type);
2757}
2758
2759static
2760void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2761{
2762 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2763 type, struct bt_ctf_field_type_enumeration, parent);
2764
2765 generic_field_type_freeze(type);
2766 bt_ctf_field_type_freeze(enumeration_type->container);
2767}
2768
2769static
2770void freeze_structure_field(struct structure_field *field)
2771{
2772 bt_ctf_field_type_freeze(field->type);
2773}
2774
2775static
2776void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2777{
2778 struct bt_ctf_field_type_structure *structure_type = container_of(
2779 type, struct bt_ctf_field_type_structure, parent);
2780
2781 /* Cache the alignment */
2782 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2783 generic_field_type_freeze(type);
2784 g_ptr_array_foreach(structure_type->fields,
2785 (GFunc) freeze_structure_field, NULL);
2786}
2787
2788static
2789void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2790{
2791 struct bt_ctf_field_type_variant *variant_type = container_of(
2792 type, struct bt_ctf_field_type_variant, parent);
2793
2794 generic_field_type_freeze(type);
2795 g_ptr_array_foreach(variant_type->fields,
2796 (GFunc) freeze_structure_field, NULL);
2797}
2798
2799static
2800void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2801{
2802 struct bt_ctf_field_type_array *array_type = container_of(
2803 type, struct bt_ctf_field_type_array, parent);
2804
2805 /* Cache the alignment */
2806 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2807 generic_field_type_freeze(type);
2808 bt_ctf_field_type_freeze(array_type->element_type);
2809}
2810
2811static
2812void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2813{
2814 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2815 type, struct bt_ctf_field_type_sequence, parent);
2816
2817 /* Cache the alignment */
2818 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2819 generic_field_type_freeze(type);
2820 bt_ctf_field_type_freeze(sequence_type->element_type);
2821}
2822
2823static
2824const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
2825{
2826 const char *encoding_string;
2827
2828 switch (encoding) {
2829 case BT_CTF_STRING_ENCODING_NONE:
2830 encoding_string = "none";
2831 break;
2832 case BT_CTF_STRING_ENCODING_ASCII:
2833 encoding_string = "ASCII";
2834 break;
2835 case BT_CTF_STRING_ENCODING_UTF8:
2836 encoding_string = "UTF8";
2837 break;
2838 default:
2839 encoding_string = "unknown";
2840 break;
2841 }
2842
2843 return encoding_string;
2844}
2845
2846static
2847const char *get_integer_base_string(enum bt_ctf_integer_base base)
2848{
2849 const char *base_string;
2850
2851 switch (base) {
2852 case BT_CTF_INTEGER_BASE_DECIMAL:
2853 base_string = "decimal";
2854 break;
2855 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2856 base_string = "hexadecimal";
2857 break;
2858 case BT_CTF_INTEGER_BASE_OCTAL:
2859 base_string = "octal";
2860 break;
2861 case BT_CTF_INTEGER_BASE_BINARY:
2862 base_string = "binary";
2863 break;
2864 default:
2865 base_string = "unknown";
2866 break;
2867 }
2868
2869 return base_string;
2870}
2871
2872static
2873int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2874 struct metadata_context *context)
2875{
2876 struct bt_ctf_field_type_integer *integer = container_of(type,
2877 struct bt_ctf_field_type_integer, parent);
2878 int ret = 0;
2879
2880 g_string_append_printf(context->string,
2881 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2882 integer->declaration.len, type->declaration->alignment,
2883 (integer->declaration.signedness ? "true" : "false"),
2884 get_encoding_string(integer->declaration.encoding),
2885 get_integer_base_string(integer->declaration.base),
2886 get_byte_order_string(integer->declaration.byte_order));
2887 if (integer->mapped_clock) {
2888 const char *clock_name = bt_ctf_clock_get_name(
2889 integer->mapped_clock);
2890
2891 if (!clock_name) {
2892 ret = -1;
2893 goto end;
2894 }
2895
2896 g_string_append_printf(context->string,
2897 "; map = clock.%s.value", clock_name);
2898 }
2899
2900 g_string_append(context->string, "; }");
2901end:
2902 return ret;
2903}
2904
2905static
2906int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2907 struct metadata_context *context)
2908{
2909 size_t entry;
2910 int ret;
2911 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2912 struct bt_ctf_field_type_enumeration, parent);
2913 struct bt_ctf_field_type *container_type;
2914 int container_signed;
2915
2916 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2917 if (!container_type) {
2918 ret = -1;
2919 goto end;
2920 }
2921
2922 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2923 if (container_signed < 0) {
2924 ret = container_signed;
2925 goto error_put_container_type;
2926 }
2927
2928 g_string_append(context->string, "enum : ");
2929 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2930 if (ret) {
2931 goto error_put_container_type;
2932 }
2933
2934 g_string_append(context->string, " { ");
2935 for (entry = 0; entry < enumeration->entries->len; entry++) {
2936 struct enumeration_mapping *mapping =
2937 enumeration->entries->pdata[entry];
2938
2939 if (container_signed) {
2940 if (mapping->range_start._signed ==
2941 mapping->range_end._signed) {
2942 g_string_append_printf(context->string,
2943 "\"%s\" = %" PRId64,
2944 g_quark_to_string(mapping->string),
2945 mapping->range_start._signed);
2946 } else {
2947 g_string_append_printf(context->string,
2948 "\"%s\" = %" PRId64 " ... %" PRId64,
2949 g_quark_to_string(mapping->string),
2950 mapping->range_start._signed,
2951 mapping->range_end._signed);
2952 }
2953 } else {
2954 if (mapping->range_start._unsigned ==
2955 mapping->range_end._unsigned) {
2956 g_string_append_printf(context->string,
2957 "\"%s\" = %" PRIu64,
2958 g_quark_to_string(mapping->string),
2959 mapping->range_start._unsigned);
2960 } else {
2961 g_string_append_printf(context->string,
2962 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2963 g_quark_to_string(mapping->string),
2964 mapping->range_start._unsigned,
2965 mapping->range_end._unsigned);
2966 }
2967 }
2968
2969 g_string_append(context->string,
2970 ((entry != (enumeration->entries->len - 1)) ?
2971 ", " : " }"));
2972 }
2973
2974 if (context->field_name->len) {
2975 g_string_append_printf(context->string, " %s",
2976 context->field_name->str);
2977 g_string_assign(context->field_name, "");
2978 }
2979error_put_container_type:
2980 bt_put(container_type);
2981end:
2982 return ret;
2983}
2984
2985static
2986int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2987 struct metadata_context *context)
2988{
2989 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2990 type, struct bt_ctf_field_type_floating_point, parent);
2991
2992 g_string_append_printf(context->string,
2993 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2994 floating_point->declaration.exp->len,
2995 floating_point->declaration.mantissa->len + 1,
2996 get_byte_order_string(floating_point->declaration.byte_order),
2997 type->declaration->alignment);
2998 return 0;
2999}
3000
3001static
3002int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
3003 struct metadata_context *context)
3004{
3005 size_t i;
3006 unsigned int indent;
3007 int ret = 0;
3008 struct bt_ctf_field_type_structure *structure = container_of(type,
3009 struct bt_ctf_field_type_structure, parent);
3010 GString *structure_field_name = context->field_name;
3011
3012 context->field_name = g_string_new("");
3013
3014 context->current_indentation_level++;
3015 g_string_append(context->string, "struct {\n");
3016
3017 for (i = 0; i < structure->fields->len; i++) {
3018 struct structure_field *field;
3019
3020 for (indent = 0; indent < context->current_indentation_level;
3021 indent++) {
3022 g_string_append_c(context->string, '\t');
3023 }
3024
3025 field = structure->fields->pdata[i];
3026 g_string_assign(context->field_name,
3027 g_quark_to_string(field->name));
3028 ret = bt_ctf_field_type_serialize(field->type, context);
3029 if (ret) {
3030 goto end;
3031 }
3032
3033 if (context->field_name->len) {
3034 g_string_append_printf(context->string, " %s",
3035 context->field_name->str);
3036 }
3037 g_string_append(context->string, ";\n");
3038 }
3039
3040 context->current_indentation_level--;
3041 for (indent = 0; indent < context->current_indentation_level;
3042 indent++) {
3043 g_string_append_c(context->string, '\t');
3044 }
3045
3046 g_string_append_printf(context->string, "} align(%zu)",
3047 type->declaration->alignment);
3048end:
3049 g_string_free(context->field_name, TRUE);
3050 context->field_name = structure_field_name;
3051 return ret;
3052}
3053
3054static
3055int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3056 struct metadata_context *context)
3057{
3058 size_t i;
3059 unsigned int indent;
3060 int ret = 0;
3061 struct bt_ctf_field_type_variant *variant = container_of(
3062 type, struct bt_ctf_field_type_variant, parent);
3063 GString *variant_field_name = context->field_name;
3064
3065 context->field_name = g_string_new("");
3066 if (variant->tag_name->len > 0) {
3067 g_string_append_printf(context->string,
3068 "variant <%s> {\n", variant->tag_name->str);
3069 } else {
3070 g_string_append(context->string, "variant {\n");
3071 }
3072
3073 context->current_indentation_level++;
3074 for (i = 0; i < variant->fields->len; i++) {
3075 struct structure_field *field = variant->fields->pdata[i];
3076
3077 g_string_assign(context->field_name,
3078 g_quark_to_string(field->name));
3079 for (indent = 0; indent < context->current_indentation_level;
3080 indent++) {
3081 g_string_append_c(context->string, '\t');
3082 }
3083
3084 g_string_assign(context->field_name,
3085 g_quark_to_string(field->name));
3086 ret = bt_ctf_field_type_serialize(field->type, context);
3087 if (ret) {
3088 goto end;
3089 }
3090
3091 if (context->field_name->len) {
3092 g_string_append_printf(context->string, " %s;",
3093 context->field_name->str);
3094 }
3095
3096 g_string_append_c(context->string, '\n');
3097 }
3098
3099 context->current_indentation_level--;
3100 for (indent = 0; indent < context->current_indentation_level;
3101 indent++) {
3102 g_string_append_c(context->string, '\t');
3103 }
3104
3105 g_string_append(context->string, "}");
3106end:
3107 g_string_free(context->field_name, TRUE);
3108 context->field_name = variant_field_name;
3109 return ret;
3110}
3111
3112static
3113int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3114 struct metadata_context *context)
3115{
3116 int ret = 0;
3117 struct bt_ctf_field_type_array *array = container_of(type,
3118 struct bt_ctf_field_type_array, parent);
3119
3120 ret = bt_ctf_field_type_serialize(array->element_type, context);
3121 if (ret) {
3122 goto end;
3123 }
3124
3125 if (context->field_name->len) {
3126 g_string_append_printf(context->string, " %s[%u]",
3127 context->field_name->str, array->length);
3128 g_string_assign(context->field_name, "");
3129 } else {
3130 g_string_append_printf(context->string, "[%u]", array->length);
3131 }
3132end:
3133 return ret;
3134}
3135
3136static
3137int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3138 struct metadata_context *context)
3139{
3140 int ret = 0;
3141 struct bt_ctf_field_type_sequence *sequence = container_of(
3142 type, struct bt_ctf_field_type_sequence, parent);
3143
3144 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3145 if (ret) {
3146 goto end;
3147 }
3148
3149 if (context->field_name->len) {
3150 g_string_append_printf(context->string, " %s[%s]",
3151 context->field_name->str,
3152 sequence->length_field_name->str);
3153 g_string_assign(context->field_name, "");
3154 } else {
3155 g_string_append_printf(context->string, "[%s]",
3156 sequence->length_field_name->str);
3157 }
3158end:
3159 return ret;
3160}
3161
3162static
3163int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3164 struct metadata_context *context)
3165{
3166 struct bt_ctf_field_type_string *string = container_of(
3167 type, struct bt_ctf_field_type_string, parent);
3168
3169 g_string_append_printf(context->string,
3170 "string { encoding = %s; }",
3171 get_encoding_string(string->declaration.encoding));
3172 return 0;
3173}
3174
3175static
3176enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3177 enum bt_ctf_byte_order ret;
3178
3179 switch (byte_order) {
3180 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3181 case LITTLE_ENDIAN:
3182 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3183 break;
3184 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3185 case BIG_ENDIAN:
3186 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3187 break;
3188 case BT_CTF_BYTE_ORDER_NETWORK:
3189 ret = BT_CTF_BYTE_ORDER_NETWORK;
3190 break;
3191 case BT_CTF_BYTE_ORDER_NATIVE:
3192 ret = BT_CTF_BYTE_ORDER_NATIVE;
3193 break;
3194 default:
3195 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3196 break;
3197 }
3198
3199 return ret;
3200}
3201
3202static
3203void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
3204 int byte_order, int set_native)
3205{
3206 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3207 struct bt_ctf_field_type_integer, parent);
3208
3209 if (set_native) {
3210 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3211 /*
3212 * User byte order is native, so we can set
3213 * the real byte order.
3214 */
3215 integer_type->declaration.byte_order =
3216 byte_order;
3217 }
3218 } else {
3219 integer_type->user_byte_order =
3220 get_ctf_ir_byte_order(byte_order);
3221 integer_type->declaration.byte_order = byte_order;
3222 }
3223}
3224
3225static
3226void bt_ctf_field_type_enumeration_set_byte_order(
3227 struct bt_ctf_field_type *type, int byte_order, int set_native)
3228{
3229 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3230 struct bt_ctf_field_type_enumeration, parent);
3231
3232 /* Safe to assume that container is an integer */
3233 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3234 byte_order, set_native);
3235}
3236
3237static
3238void bt_ctf_field_type_floating_point_set_byte_order(
3239 struct bt_ctf_field_type *type, int byte_order, int set_native)
3240{
3241 struct bt_ctf_field_type_floating_point *floating_point_type =
3242 container_of(type, struct bt_ctf_field_type_floating_point,
3243 parent);
3244
3245 if (set_native) {
3246 if (floating_point_type->user_byte_order ==
3247 BT_CTF_BYTE_ORDER_NATIVE) {
3248 /*
3249 * User byte order is native, so we can set
3250 * the real byte order.
3251 */
3252 floating_point_type->declaration.byte_order =
3253 byte_order;
3254 floating_point_type->sign.byte_order =
3255 byte_order;
3256 floating_point_type->mantissa.byte_order =
3257 byte_order;
3258 floating_point_type->exp.byte_order =
3259 byte_order;
3260 }
3261 } else {
3262 floating_point_type->user_byte_order =
3263 get_ctf_ir_byte_order(byte_order);
3264 floating_point_type->declaration.byte_order = byte_order;
3265 floating_point_type->sign.byte_order = byte_order;
3266 floating_point_type->mantissa.byte_order = byte_order;
3267 floating_point_type->exp.byte_order = byte_order;
3268 }
3269}
3270
3271static
3272void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3273 int byte_order, int set_native)
3274{
3275 int i;
3276 struct bt_ctf_field_type_structure *structure_type =
3277 container_of(type, struct bt_ctf_field_type_structure,
3278 parent);
3279
3280 for (i = 0; i < structure_type->fields->len; i++) {
3281 struct structure_field *field = g_ptr_array_index(
3282 structure_type->fields, i);
3283 struct bt_ctf_field_type *field_type = field->type;
3284
3285 if (set_byte_order_funcs[field_type->declaration->id]) {
3286 set_byte_order_funcs[field_type->declaration->id](
3287 field_type, byte_order, set_native);
3288 }
3289 }
3290}
3291
3292static
3293void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3294 int byte_order, int set_native)
3295{
3296 int i;
3297 struct bt_ctf_field_type_variant *variant_type =
3298 container_of(type, struct bt_ctf_field_type_variant,
3299 parent);
3300
3301 for (i = 0; i < variant_type->fields->len; i++) {
3302 struct structure_field *field = g_ptr_array_index(
3303 variant_type->fields, i);
3304 struct bt_ctf_field_type *field_type = field->type;
3305
3306 if (set_byte_order_funcs[field_type->declaration->id]) {
3307 set_byte_order_funcs[field_type->declaration->id](
3308 field_type, byte_order, set_native);
3309 }
3310 }
3311}
3312
3313static
3314void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3315 int byte_order, int set_native)
3316{
3317 struct bt_ctf_field_type_array *array_type =
3318 container_of(type, struct bt_ctf_field_type_array,
3319 parent);
3320
3321 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3322 set_byte_order_funcs[array_type->element_type->declaration->id](
3323 array_type->element_type, byte_order, set_native);
3324 }
3325}
3326
3327static
3328void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3329 int byte_order, int set_native)
3330{
3331 struct bt_ctf_field_type_sequence *sequence_type =
3332 container_of(type, struct bt_ctf_field_type_sequence,
3333 parent);
3334
3335 if (set_byte_order_funcs[
3336 sequence_type->element_type->declaration->id]) {
3337 set_byte_order_funcs[
3338 sequence_type->element_type->declaration->id](
3339 sequence_type->element_type, byte_order, set_native);
3340 }
3341}
3342
3343static
3344struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3345 struct bt_ctf_field_type *type)
3346{
3347 struct bt_ctf_field_type *copy;
3348 struct bt_ctf_field_type_integer *integer, *copy_integer;
3349
3350 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3351 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3352 if (!copy) {
3353 goto end;
3354 }
3355
3356 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3357 parent);
3358 copy_integer->declaration = integer->declaration;
3359 if (integer->mapped_clock) {
3360 bt_get(integer->mapped_clock);
3361 copy_integer->mapped_clock = integer->mapped_clock;
3362 }
3363
3364 copy_integer->user_byte_order = integer->user_byte_order;
3365
3366end:
3367 return copy;
3368}
3369
3370static
3371struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3372 struct bt_ctf_field_type *type)
3373{
3374 size_t i;
3375 struct bt_ctf_field_type *copy = NULL, *copy_container;
3376 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3377
3378 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3379 parent);
3380
3381 /* Copy the source enumeration's container */
3382 copy_container = bt_ctf_field_type_copy(enumeration->container);
3383 if (!copy_container) {
3384 goto end;
3385 }
3386
3387 copy = bt_ctf_field_type_enumeration_create(copy_container);
3388 if (!copy) {
3389 goto end;
3390 }
3391 copy_enumeration = container_of(copy,
3392 struct bt_ctf_field_type_enumeration, parent);
3393
3394 /* Copy all enumaration entries */
3395 for (i = 0; i < enumeration->entries->len; i++) {
3396 struct enumeration_mapping *mapping = g_ptr_array_index(
3397 enumeration->entries, i);
3398 struct enumeration_mapping* copy_mapping = g_new0(
3399 struct enumeration_mapping, 1);
3400
3401 if (!copy_mapping) {
3402 goto error;
3403 }
3404
3405 *copy_mapping = *mapping;
3406 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3407 }
3408
3409 copy_enumeration->declaration = enumeration->declaration;
3410end:
3411 bt_put(copy_container);
3412 return copy;
3413error:
3414 bt_put(copy_container);
3415 BT_PUT(copy);
3416 return copy;
3417}
3418
3419static
3420struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3421 struct bt_ctf_field_type *type)
3422{
3423 struct bt_ctf_field_type *copy;
3424 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3425
3426 floating_point = container_of(type,
3427 struct bt_ctf_field_type_floating_point, parent);
3428 copy = bt_ctf_field_type_floating_point_create();
3429 if (!copy) {
3430 goto end;
3431 }
3432
3433 copy_float = container_of(copy,
3434 struct bt_ctf_field_type_floating_point, parent);
3435 copy_float->declaration = floating_point->declaration;
3436 copy_float->sign = floating_point->sign;
3437 copy_float->mantissa = floating_point->mantissa;
3438 copy_float->exp = floating_point->exp;
3439 copy_float->user_byte_order = floating_point->user_byte_order;
3440 copy_float->declaration.sign = &copy_float->sign;
3441 copy_float->declaration.mantissa = &copy_float->mantissa;
3442 copy_float->declaration.exp = &copy_float->exp;
3443end:
3444 return copy;
3445}
3446
3447static
3448struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3449 struct bt_ctf_field_type *type)
3450{
3451 int i;
3452 GHashTableIter iter;
3453 gpointer key, value;
3454 struct bt_ctf_field_type *copy;
3455 struct bt_ctf_field_type_structure *structure, *copy_structure;
3456
3457 structure = container_of(type, struct bt_ctf_field_type_structure,
3458 parent);
3459 copy = bt_ctf_field_type_structure_create();
3460 if (!copy) {
3461 goto end;
3462 }
3463
3464 copy_structure = container_of(copy,
3465 struct bt_ctf_field_type_structure, parent);
3466
3467 /* Copy field_name_to_index */
3468 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3469 while (g_hash_table_iter_next (&iter, &key, &value)) {
3470 g_hash_table_insert(copy_structure->field_name_to_index,
3471 key, value);
3472 }
3473
3474 for (i = 0; i < structure->fields->len; i++) {
3475 struct structure_field *entry, *copy_entry;
3476 struct bt_ctf_field_type *copy_field;
3477
3478 copy_entry = g_new0(struct structure_field, 1);
3479 if (!copy_entry) {
3480 goto error;
3481 }
3482
3483 entry = g_ptr_array_index(structure->fields, i);
3484 copy_field = bt_ctf_field_type_copy(entry->type);
3485 if (!copy_field) {
3486 g_free(copy_entry);
3487 goto error;
3488 }
3489
3490 copy_entry->name = entry->name;
3491 copy_entry->type = copy_field;
3492 g_ptr_array_add(copy_structure->fields, copy_entry);
3493 }
3494
3495 copy_structure->declaration = structure->declaration;
3496end:
3497 return copy;
3498error:
3499 BT_PUT(copy);
3500 return copy;
3501}
3502
3503static
3504struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3505 struct bt_ctf_field_type *type)
3506{
3507 int i;
3508 GHashTableIter iter;
3509 gpointer key, value;
3510 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3511 struct bt_ctf_field_type_variant *variant, *copy_variant;
3512
3513 variant = container_of(type, struct bt_ctf_field_type_variant,
3514 parent);
3515 if (variant->tag) {
3516 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3517 if (!copy_tag) {
3518 goto end;
3519 }
3520 }
3521
3522 copy = bt_ctf_field_type_variant_create(copy_tag,
3523 variant->tag_name->len ? variant->tag_name->str : NULL);
3524 if (!copy) {
3525 goto end;
3526 }
3527
3528 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3529 parent);
3530
3531 /* Copy field_name_to_index */
3532 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3533 while (g_hash_table_iter_next (&iter, &key, &value)) {
3534 g_hash_table_insert(copy_variant->field_name_to_index,
3535 key, value);
3536 }
3537
3538 for (i = 0; i < variant->fields->len; i++) {
3539 struct structure_field *entry, *copy_entry;
3540 struct bt_ctf_field_type *copy_field;
3541
3542 copy_entry = g_new0(struct structure_field, 1);
3543 if (!copy_entry) {
3544 goto error;
3545 }
3546
3547 entry = g_ptr_array_index(variant->fields, i);
3548 copy_field = bt_ctf_field_type_copy(entry->type);
3549 if (!copy_field) {
3550 g_free(copy_entry);
3551 goto error;
3552 }
3553
3554 copy_entry->name = entry->name;
3555 copy_entry->type = copy_field;
3556 g_ptr_array_add(copy_variant->fields, copy_entry);
3557 }
3558
3559 copy_variant->declaration = variant->declaration;
3560 if (variant->tag_field_path) {
3561 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3562 variant->tag_field_path);
3563 if (!copy_variant->tag_field_path) {
3564 goto error;
3565 }
3566 }
3567end:
3568 bt_put(copy_tag);
3569 return copy;
3570error:
3571 bt_put(copy_tag);
3572 BT_PUT(copy);
3573 return copy;
3574}
3575
3576static
3577struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3578 struct bt_ctf_field_type *type)
3579{
3580 struct bt_ctf_field_type *copy = NULL, *copy_element;
3581 struct bt_ctf_field_type_array *array, *copy_array;
3582
3583 array = container_of(type, struct bt_ctf_field_type_array,
3584 parent);
3585 copy_element = bt_ctf_field_type_copy(array->element_type);
3586 if (!copy_element) {
3587 goto end;
3588 }
3589
3590 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3591 if (!copy) {
3592 goto end;
3593 }
3594
3595 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3596 parent);
3597 copy_array->declaration = array->declaration;
3598end:
3599 bt_put(copy_element);
3600 return copy;
3601}
3602
3603static
3604struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3605 struct bt_ctf_field_type *type)
3606{
3607 struct bt_ctf_field_type *copy = NULL, *copy_element;
3608 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3609
3610 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3611 parent);
3612 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3613 if (!copy_element) {
3614 goto end;
3615 }
3616
3617 copy = bt_ctf_field_type_sequence_create(copy_element,
3618 sequence->length_field_name->len ?
3619 sequence->length_field_name->str : NULL);
3620 if (!copy) {
3621 goto end;
3622 }
3623
3624 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3625 parent);
3626 copy_sequence->declaration = sequence->declaration;
3627 if (sequence->length_field_path) {
3628 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3629 sequence->length_field_path);
3630 if (!copy_sequence->length_field_path) {
3631 goto error;
3632 }
3633 }
3634end:
3635 bt_put(copy_element);
3636 return copy;
3637error:
3638 BT_PUT(copy);
3639 goto end;
3640}
3641
3642static
3643struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3644 struct bt_ctf_field_type *type)
3645{
3646 struct bt_ctf_field_type *copy;
3647 struct bt_ctf_field_type_string *string, *copy_string;
3648
3649 copy = bt_ctf_field_type_string_create();
3650 if (!copy) {
3651 goto end;
3652 }
3653
3654 string = container_of(type, struct bt_ctf_field_type_string,
3655 parent);
3656 copy_string = container_of(type, struct bt_ctf_field_type_string,
3657 parent);
3658 copy_string->declaration = string->declaration;
3659end:
3660 return copy;
3661}
3662
3663static
3664int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3665 struct bt_ctf_field_type *type_b)
3666{
3667 int ret = 1;
3668 struct bt_ctf_field_type_integer *integer_a;
3669 struct bt_ctf_field_type_integer *integer_b;
3670 struct declaration_integer *decl_a;
3671 struct declaration_integer *decl_b;
3672
3673 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3674 parent);
3675 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3676 parent);
3677 decl_a = &integer_a->declaration;
3678 decl_b = &integer_b->declaration;
3679
3680 /* Length */
3681 if (decl_a->len != decl_b->len) {
3682 goto end;
3683 }
3684
3685 /*
3686 * Compare user byte orders only, not the cached,
3687 * real byte orders.
3688 */
3689 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3690 goto end;
3691 }
3692
3693 /* Signedness */
3694 if (decl_a->signedness != decl_b->signedness) {
3695 goto end;
3696 }
3697
3698 /* Base */
3699 if (decl_a->base != decl_b->base) {
3700 goto end;
3701 }
3702
3703 /* Encoding */
3704 if (decl_a->encoding != decl_b->encoding) {
3705 goto end;
3706 }
3707
3708 /* Mapped clock */
3709 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3710 goto end;
3711 }
3712
3713 /* Equal */
3714 ret = 0;
3715
3716end:
3717 return ret;
3718}
3719
3720static
3721int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3722 struct bt_ctf_field_type *type_b)
3723{
3724 int ret = 1;
3725 struct bt_ctf_field_type_floating_point *float_a;
3726 struct bt_ctf_field_type_floating_point *float_b;
3727
3728 float_a = container_of(type_a,
3729 struct bt_ctf_field_type_floating_point, parent);
3730 float_b = container_of(type_b,
3731 struct bt_ctf_field_type_floating_point, parent);
3732
3733 /* Sign length */
3734 if (float_a->sign.len != float_b->sign.len) {
3735 goto end;
3736 }
3737
3738 /* Exponent length */
3739 if (float_a->exp.len != float_b->exp.len) {
3740 goto end;
3741 }
3742
3743 /* Mantissa length */
3744 if (float_a->mantissa.len != float_b->mantissa.len) {
3745 goto end;
3746 }
3747
3748 /*
3749 * Compare user byte orders only, not the cached,
3750 * real byte orders.
3751 */
3752 if (float_a->user_byte_order != float_b->user_byte_order) {
3753 goto end;
3754 }
3755
3756 /* Equal */
3757 ret = 0;
3758
3759end:
3760 return ret;
3761}
3762
3763static
3764int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3765 struct enumeration_mapping *mapping_b)
3766{
3767 int ret = 1;
3768
3769 /* Label */
3770 if (mapping_a->string != mapping_b->string) {
3771 goto end;
3772 }
3773
3774 /* Range start */
3775 if (mapping_a->range_start._unsigned !=
3776 mapping_b->range_start._unsigned) {
3777 goto end;
3778 }
3779
3780 /* Range end */
3781 if (mapping_a->range_end._unsigned !=
3782 mapping_b->range_end._unsigned) {
3783 goto end;
3784 }
3785
3786 /* Equal */
3787 ret = 0;
3788
3789end:
3790 return ret;
3791}
3792
3793static
3794int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3795 struct bt_ctf_field_type *type_b)
3796{
3797 int ret = 1;
3798 int i;
3799 struct bt_ctf_field_type_enumeration *enum_a;
3800 struct bt_ctf_field_type_enumeration *enum_b;
3801
3802 enum_a = container_of(type_a,
3803 struct bt_ctf_field_type_enumeration, parent);
3804 enum_b = container_of(type_b,
3805 struct bt_ctf_field_type_enumeration, parent);
3806
3807 /* Container field type */
3808 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3809 if (ret) {
3810 goto end;
3811 }
3812
3813 ret = 1;
3814
3815 /* Entries */
3816 if (enum_a->entries->len != enum_b->entries->len) {
3817 goto end;
3818 }
3819
3820 for (i = 0; i < enum_a->entries->len; ++i) {
3821 struct enumeration_mapping *mapping_a =
3822 g_ptr_array_index(enum_a->entries, i);
3823 struct enumeration_mapping *mapping_b =
3824 g_ptr_array_index(enum_b->entries, i);
3825
3826 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3827 goto end;
3828 }
3829 }
3830
3831 /* Equal */
3832 ret = 0;
3833
3834end:
3835 return ret;
3836}
3837
3838static
3839int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3840 struct bt_ctf_field_type *type_b)
3841{
3842 int ret = 1;
3843 struct bt_ctf_field_type_string *string_a;
3844 struct bt_ctf_field_type_string *string_b;
3845
3846 string_a = container_of(type_a,
3847 struct bt_ctf_field_type_string, parent);
3848 string_b = container_of(type_b,
3849 struct bt_ctf_field_type_string, parent);
3850
3851 /* Encoding */
3852 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3853 goto end;
3854 }
3855
3856 /* Equal */
3857 ret = 0;
3858
3859end:
3860 return ret;
3861}
3862
3863static
3864int compare_structure_fields(struct structure_field *field_a,
3865 struct structure_field *field_b)
3866{
3867 int ret = 1;
3868
3869 /* Label */
3870 if (field_a->name != field_b->name) {
3871 goto end;
3872 }
3873
3874 /* Type */
3875 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3876
3877end:
3878 return ret;
3879}
3880
3881static
3882int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3883 struct bt_ctf_field_type *type_b)
3884{
3885 int ret = 1;
3886 int i;
3887 struct bt_ctf_field_type_structure *struct_a;
3888 struct bt_ctf_field_type_structure *struct_b;
3889
3890 struct_a = container_of(type_a,
3891 struct bt_ctf_field_type_structure, parent);
3892 struct_b = container_of(type_b,
3893 struct bt_ctf_field_type_structure, parent);
3894
3895 /* Alignment */
3896 if (bt_ctf_field_type_get_alignment(type_a) !=
3897 bt_ctf_field_type_get_alignment(type_b)) {
3898 goto end;
3899 }
3900
3901 /* Fields */
3902 if (struct_a->fields->len != struct_b->fields->len) {
3903 goto end;
3904 }
3905
3906 for (i = 0; i < struct_a->fields->len; ++i) {
3907 struct structure_field *field_a =
3908 g_ptr_array_index(struct_a->fields, i);
3909 struct structure_field *field_b =
3910 g_ptr_array_index(struct_b->fields, i);
3911
3912 ret = compare_structure_fields(field_a, field_b);
3913 if (ret) {
3914 goto end;
3915 }
3916 }
3917
3918 /* Equal */
3919 ret = 0;
3920
3921end:
3922 return ret;
3923}
3924
3925static
3926int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3927 struct bt_ctf_field_type *type_b)
3928{
3929 int ret = 1;
3930 int i;
3931 struct bt_ctf_field_type_variant *variant_a;
3932 struct bt_ctf_field_type_variant *variant_b;
3933
3934 variant_a = container_of(type_a,
3935 struct bt_ctf_field_type_variant, parent);
3936 variant_b = container_of(type_b,
3937 struct bt_ctf_field_type_variant, parent);
3938
3939 /* Tag name */
3940 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3941 goto end;
3942 }
3943
3944 /* Tag type */
3945 ret = bt_ctf_field_type_compare(
3946 (struct bt_ctf_field_type *) variant_a->tag,
3947 (struct bt_ctf_field_type *) variant_b->tag);
3948 if (ret) {
3949 goto end;
3950 }
3951
3952 ret = 1;
3953
3954 /* Fields */
3955 if (variant_a->fields->len != variant_b->fields->len) {
3956 goto end;
3957 }
3958
3959 for (i = 0; i < variant_a->fields->len; ++i) {
3960 struct structure_field *field_a =
3961 g_ptr_array_index(variant_a->fields, i);
3962 struct structure_field *field_b =
3963 g_ptr_array_index(variant_b->fields, i);
3964
3965 ret = compare_structure_fields(field_a, field_b);
3966 if (ret) {
3967 goto end;
3968 }
3969 }
3970
3971 /* Equal */
3972 ret = 0;
3973
3974end:
3975 return ret;
3976}
3977
3978static
3979int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3980 struct bt_ctf_field_type *type_b)
3981{
3982 int ret = 1;
3983 struct bt_ctf_field_type_array *array_a;
3984 struct bt_ctf_field_type_array *array_b;
3985
3986 array_a = container_of(type_a,
3987 struct bt_ctf_field_type_array, parent);
3988 array_b = container_of(type_b,
3989 struct bt_ctf_field_type_array, parent);
3990
3991 /* Length */
3992 if (array_a->length != array_b->length) {
3993 goto end;
3994 }
3995
3996 /* Element type */
3997 ret = bt_ctf_field_type_compare(array_a->element_type,
3998 array_b->element_type);
3999
4000end:
4001 return ret;
4002}
4003
4004static
4005int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
4006 struct bt_ctf_field_type *type_b)
4007{
4008 int ret = -1;
4009 struct bt_ctf_field_type_sequence *sequence_a;
4010 struct bt_ctf_field_type_sequence *sequence_b;
4011
4012 sequence_a = container_of(type_a,
4013 struct bt_ctf_field_type_sequence, parent);
4014 sequence_b = container_of(type_b,
4015 struct bt_ctf_field_type_sequence, parent);
4016
4017 /* Length name */
4018 if (strcmp(sequence_a->length_field_name->str,
4019 sequence_b->length_field_name->str)) {
4020 goto end;
4021 }
4022
4023 /* Element type */
4024 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4025 sequence_b->element_type);
4026
4027end:
4028 return ret;
4029}
4030
5ad19bf0 4031BT_HIDDEN
1c822dfb
JG
4032int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4033 struct bt_ctf_field_type *type_b)
4034{
4035 int ret = 1;
4036
4037 if (type_a == type_b) {
4038 /* Same reference: equal (even if both are NULL) */
4039 ret = 0;
4040 goto end;
4041 }
4042
4043 if (!type_a || !type_b) {
4044 ret = -1;
4045 goto end;
4046 }
4047
4048 if (type_a->declaration->id != type_b->declaration->id) {
4049 /* Different type IDs */
4050 goto end;
4051 }
4052
830017b0 4053 if (type_a->declaration->id == CTF_TYPE_UNKNOWN) {
1c822dfb
JG
4054 /* Both have unknown type IDs */
4055 goto end;
4056 }
4057
4058 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4059
4060end:
4061 return ret;
4062}
4063
4064BT_HIDDEN
4065int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4066{
4067 int field_count = -1;
4068 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4069
4070 switch (type_id) {
4071 case CTF_TYPE_STRUCT:
4072 field_count =
4073 bt_ctf_field_type_structure_get_field_count(field_type);
4074 break;
4075 case CTF_TYPE_VARIANT:
4076 field_count =
4077 bt_ctf_field_type_variant_get_field_count(field_type);
4078 break;
4079 case CTF_TYPE_ARRAY:
4080 case CTF_TYPE_SEQUENCE:
4081 /*
4082 * Array and sequence types always contain a single member
4083 * (the element type).
4084 */
4085 field_count = 1;
4086 break;
4087 default:
4088 break;
4089 }
4090
4091 return field_count;
4092}
4093
4094BT_HIDDEN
4095struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4096 struct bt_ctf_field_type *field_type, int index)
4097{
4098 struct bt_ctf_field_type *field = NULL;
4099 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4100
4101 switch (type_id) {
4102 case CTF_TYPE_STRUCT:
4103 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4104 index);
4105 break;
4106 case CTF_TYPE_VARIANT:
4107 {
4108 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
4109 &field, index);
4110 if (ret) {
4111 field = NULL;
4112 goto end;
4113 }
4114 break;
4115 }
4116 case CTF_TYPE_ARRAY:
4117 field = bt_ctf_field_type_array_get_element_type(field_type);
4118 break;
4119 case CTF_TYPE_SEQUENCE:
4120 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4121 break;
4122 default:
4123 break;
4124 }
4125end:
4126 return field;
4127}
4128
4129BT_HIDDEN
4130int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4131 const char *name)
4132{
4133 int field_index = -1;
4134 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4135
4136 switch (type_id) {
4137 case CTF_TYPE_STRUCT:
4138 field_index = bt_ctf_field_type_structure_get_field_name_index(
4139 field_type, name);
4140 break;
4141 case CTF_TYPE_VARIANT:
4142 field_index = bt_ctf_field_type_variant_get_field_name_index(
4143 field_type, name);
4144 break;
4145 default:
4146 break;
4147 }
4148
4149 return field_index;
4150}
4151
5ad19bf0 4152BT_HIDDEN
1c822dfb
JG
4153struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4154 struct bt_ctf_field_type *type)
4155{
4156 struct bt_ctf_field_path *field_path = NULL;
4157 struct bt_ctf_field_type_variant *variant;
4158
4159 if (!type || !bt_ctf_field_type_is_variant(type)) {
4160 goto end;
4161 }
4162
4163 variant = container_of(type, struct bt_ctf_field_type_variant,
4164 parent);
4165 field_path = bt_get(variant->tag_field_path);
4166end:
4167 return field_path;
4168}
4169
5ad19bf0 4170BT_HIDDEN
1c822dfb
JG
4171struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
4172 struct bt_ctf_field_type *type)
4173{
4174 struct bt_ctf_field_path *field_path = NULL;
4175 struct bt_ctf_field_type_sequence *sequence;
4176
4177 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4178 goto end;
4179 }
4180
4181 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4182 parent);
4183 field_path = bt_get(sequence->length_field_path);
4184end:
4185 return field_path;
4186}
This page took 0.195882 seconds and 4 git commands to generate.