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