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