ir: validate field types on field creation
[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
2383
2384BT_HIDDEN
2385struct bt_ctf_field_path *bt_ctf_field_path_copy(
2386 struct bt_ctf_field_path *path)
2387{
2388 struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
2389
2390 if (!new_path) {
2391 goto end;
2392 }
2393
2394 new_path->root = path->root;
2395 g_array_insert_vals(new_path->path_indexes, 0,
2396 path->path_indexes->data, path->path_indexes->len);
2397end:
2398 return new_path;
2399}
2400
2401BT_HIDDEN
2402void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path)
2403{
2404 if (!path) {
2405 return;
2406 }
2407
2408 if (path->path_indexes) {
2409 g_array_free(path->path_indexes, TRUE);
2410 }
2411 g_free(path);
2412}
39a5e0db
JG
2413
2414BT_HIDDEN
2415int bt_ctf_field_type_structure_get_field_name_index(
2416 struct bt_ctf_field_type *type, const char *name)
2417{
2418 int ret;
2419 size_t index;
2420 GQuark name_quark;
2421 struct bt_ctf_field_type_structure *structure;
2422
2423 if (!type || !name ||
2424 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2425 ret = -1;
2426 goto end;
2427 }
2428
2429 name_quark = g_quark_try_string(name);
2430 if (!name_quark) {
2431 ret = -1;
2432 goto end;
2433 }
2434
2435 structure = container_of(type, struct bt_ctf_field_type_structure,
2436 parent);
2437 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2438 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2439 ret = -1;
2440 goto end;
2441 }
2442 ret = (int) index;
2443end:
2444 return ret;
2445}
736133f1 2446
5cec03e4
JG
2447BT_HIDDEN
2448int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2449 struct bt_ctf_field_type *field, int index)
2450{
2451 int ret = 0;
2452 struct bt_ctf_field_type_structure *structure;
2453
6c827042 2454 if (!type || !field ||
5cec03e4
JG
2455 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2456 ret = -1;
2457 goto end;
2458 }
2459
2460 structure = container_of(type, struct bt_ctf_field_type_structure,
2461 parent);
2462 if (index < 0 || index >= structure->fields->len) {
2463 ret = -1;
2464 goto end;
2465 }
2466
83509119
JG
2467 bt_get(field);
2468 bt_put(((struct structure_field *)
5cec03e4
JG
2469 g_ptr_array_index(structure->fields, index))->type);
2470 ((struct structure_field *) structure->fields->pdata[index])->type =
2471 field;
2472end:
2473 return ret;
2474}
2475
736133f1
JG
2476BT_HIDDEN
2477int bt_ctf_field_type_variant_get_field_name_index(
2478 struct bt_ctf_field_type *type, const char *name)
2479{
2480 int ret;
2481 size_t index;
2482 GQuark name_quark;
2483 struct bt_ctf_field_type_variant *variant;
2484
2485 if (!type || !name ||
2486 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2487 ret = -1;
2488 goto end;
2489 }
2490
2491 name_quark = g_quark_try_string(name);
2492 if (!name_quark) {
2493 ret = -1;
2494 goto end;
2495 }
2496
2497 variant = container_of(type, struct bt_ctf_field_type_variant,
2498 parent);
2499 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2500 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2501 ret = -1;
2502 goto end;
2503 }
2504 ret = (int) index;
2505end:
2506 return ret;
2507}
aa4e271c
JG
2508
2509BT_HIDDEN
2510int bt_ctf_field_type_sequence_set_length_field_path(
2511 struct bt_ctf_field_type *type,
2512 struct bt_ctf_field_path *path)
2513{
2514 int ret = 0;
2515 struct bt_ctf_field_type_sequence *sequence;
2516
2517 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_SEQUENCE) {
2518 ret = -1;
2519 goto end;
2520 }
2521
2522 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2523 parent);
2524 if (sequence->length_field_path) {
2525 bt_ctf_field_path_destroy(sequence->length_field_path);
2526 }
2527 sequence->length_field_path = path;
2528end:
2529 return ret;
2530}
4a1e8671 2531
32fe3f28
PP
2532BT_HIDDEN
2533struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
2534 struct bt_ctf_field_type *type)
2535{
2536 struct bt_ctf_field_type_sequence *sequence;
2537
2538 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2539 parent);
2540
2541 return sequence->length_field_path;
2542}
2543
4a1e8671
JG
2544BT_HIDDEN
2545int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2546 struct bt_ctf_field_path *path)
2547{
2548 int ret = 0;
2549 struct bt_ctf_field_type_variant *variant;
2550
2551 if (!type || bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2552 ret = -1;
2553 goto end;
2554 }
2555
2556 variant = container_of(type, struct bt_ctf_field_type_variant,
2557 parent);
2558 if (variant->tag_path) {
2559 bt_ctf_field_path_destroy(variant->tag_path);
2560 }
2561 variant->tag_path = path;
2562end:
2563 return ret;
2564}
3f39933a 2565
32fe3f28
PP
2566BT_HIDDEN
2567struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
2568 struct bt_ctf_field_type *type)
2569{
2570 struct bt_ctf_field_type_variant *variant;
2571
2572 variant = container_of(type, struct bt_ctf_field_type_variant,
2573 parent);
2574
2575 return variant->tag_path;
2576}
2577
3f39933a
JG
2578BT_HIDDEN
2579int bt_ctf_field_type_variant_set_tag(struct bt_ctf_field_type *type,
2580 struct bt_ctf_field_type *tag)
2581{
2582 int ret = 0;
2583 struct bt_ctf_field_type_variant *variant;
2584
2585 if (!type || !tag || type->frozen ||
2586 bt_ctf_field_type_get_type_id(tag) != CTF_TYPE_ENUM) {
2587 ret = -1;
2588 goto end;
2589 }
2590
2591 variant = container_of(type, struct bt_ctf_field_type_variant,
2592 parent);
83509119 2593 bt_get(tag);
3f39933a 2594 if (variant->tag) {
83509119 2595 bt_put(&variant->tag->parent);
3f39933a
JG
2596 }
2597 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2598 parent);
2599end:
2600 return ret;
2601}
2602
5cec03e4
JG
2603BT_HIDDEN
2604int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2605 struct bt_ctf_field_type *field, int index)
2606{
2607 int ret = 0;
2608 struct bt_ctf_field_type_variant *variant;
2609
6c827042 2610 if (!type || !field ||
5cec03e4
JG
2611 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2612 ret = -1;
2613 goto end;
2614 }
2615
2616 variant = container_of(type, struct bt_ctf_field_type_variant,
2617 parent);
2618 if (index < 0 || index >= variant->fields->len) {
2619 ret = -1;
2620 goto end;
2621 }
2622
83509119
JG
2623 bt_get(field);
2624 bt_put(((struct structure_field *)
5cec03e4
JG
2625 g_ptr_array_index(variant->fields, index))->type);
2626 ((struct structure_field *) variant->fields->pdata[index])->type =
2627 field;
2628end:
2629 return ret;
2630}
2631
273b65be 2632static
de3dd40e 2633void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
273b65be 2634{
de3dd40e
PP
2635 struct bt_ctf_field_type_integer *integer =
2636 (struct bt_ctf_field_type_integer *) type;
273b65be 2637
de3dd40e 2638 if (!type) {
273b65be
JG
2639 return;
2640 }
2641
83509119 2642 bt_put(integer->mapped_clock);
273b65be
JG
2643 g_free(integer);
2644}
2645
2646static
de3dd40e 2647void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
273b65be 2648{
de3dd40e
PP
2649 struct bt_ctf_field_type_enumeration *enumeration =
2650 (struct bt_ctf_field_type_enumeration *) type;
273b65be 2651
de3dd40e 2652 if (!type) {
273b65be
JG
2653 return;
2654 }
2655
273b65be 2656 g_ptr_array_free(enumeration->entries, TRUE);
83509119 2657 bt_put(enumeration->container);
273b65be
JG
2658 g_free(enumeration);
2659}
2660
2661static
de3dd40e 2662void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
273b65be 2663{
de3dd40e
PP
2664 struct bt_ctf_field_type_floating_point *floating_point =
2665 (struct bt_ctf_field_type_floating_point *) type;
273b65be 2666
de3dd40e 2667 if (!type) {
273b65be
JG
2668 return;
2669 }
2670
273b65be
JG
2671 g_free(floating_point);
2672}
2673
2674static
de3dd40e 2675void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
273b65be 2676{
de3dd40e
PP
2677 struct bt_ctf_field_type_structure *structure =
2678 (struct bt_ctf_field_type_structure *) type;
273b65be 2679
de3dd40e 2680 if (!type) {
273b65be
JG
2681 return;
2682 }
2683
273b65be
JG
2684 g_ptr_array_free(structure->fields, TRUE);
2685 g_hash_table_destroy(structure->field_name_to_index);
2686 g_free(structure);
2687}
2688
2689static
de3dd40e 2690void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
273b65be 2691{
de3dd40e
PP
2692 struct bt_ctf_field_type_variant *variant =
2693 (struct bt_ctf_field_type_variant *) type;
273b65be 2694
de3dd40e 2695 if (!type) {
273b65be
JG
2696 return;
2697 }
2698
273b65be
JG
2699 g_ptr_array_free(variant->fields, TRUE);
2700 g_hash_table_destroy(variant->field_name_to_index);
2701 g_string_free(variant->tag_name, TRUE);
83509119 2702 bt_put(&variant->tag->parent);
4a1e8671 2703 bt_ctf_field_path_destroy(variant->tag_path);
273b65be
JG
2704 g_free(variant);
2705}
2706
2707static
de3dd40e 2708void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
273b65be 2709{
de3dd40e
PP
2710 struct bt_ctf_field_type_array *array =
2711 (struct bt_ctf_field_type_array *) type;
273b65be 2712
de3dd40e 2713 if (!type) {
273b65be
JG
2714 return;
2715 }
2716
83509119 2717 bt_put(array->element_type);
273b65be
JG
2718 g_free(array);
2719}
2720
2721static
de3dd40e 2722void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
273b65be 2723{
de3dd40e
PP
2724 struct bt_ctf_field_type_sequence *sequence =
2725 (struct bt_ctf_field_type_sequence *) type;
273b65be 2726
de3dd40e 2727 if (!type) {
273b65be
JG
2728 return;
2729 }
2730
83509119 2731 bt_put(sequence->element_type);
273b65be 2732 g_string_free(sequence->length_field_name, TRUE);
aa4e271c 2733 bt_ctf_field_path_destroy(sequence->length_field_path);
273b65be
JG
2734 g_free(sequence);
2735}
2736
2737static
de3dd40e 2738void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
273b65be 2739{
de3dd40e
PP
2740 struct bt_ctf_field_type_string *string =
2741 (struct bt_ctf_field_type_string *) type;
273b65be 2742
de3dd40e 2743 if (!type) {
273b65be
JG
2744 return;
2745 }
2746
273b65be
JG
2747 g_free(string);
2748}
2749
2750static
2751void generic_field_type_freeze(struct bt_ctf_field_type *type)
2752{
2753 type->frozen = 1;
2754}
2755
2756static
2757void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2758{
2759 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2760 type, struct bt_ctf_field_type_enumeration, parent);
2761
2762 generic_field_type_freeze(type);
2763 bt_ctf_field_type_freeze(enumeration_type->container);
2764}
2765
2766static
2767void freeze_structure_field(struct structure_field *field)
2768{
2769 bt_ctf_field_type_freeze(field->type);
2770}
2771
2772static
2773void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2774{
2775 struct bt_ctf_field_type_structure *structure_type = container_of(
2776 type, struct bt_ctf_field_type_structure, parent);
2777
3ffba961
JG
2778 /* Cache the alignment */
2779 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2780 generic_field_type_freeze(type);
3ffba961
JG
2781 g_ptr_array_foreach(structure_type->fields,
2782 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2783}
2784
2785static
2786void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2787{
2788 struct bt_ctf_field_type_variant *variant_type = container_of(
2789 type, struct bt_ctf_field_type_variant, parent);
2790
2791 generic_field_type_freeze(type);
3ffba961
JG
2792 g_ptr_array_foreach(variant_type->fields,
2793 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2794}
2795
2796static
2797void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2798{
2799 struct bt_ctf_field_type_array *array_type = container_of(
2800 type, struct bt_ctf_field_type_array, parent);
2801
3ffba961
JG
2802 /* Cache the alignment */
2803 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2804 generic_field_type_freeze(type);
2805 bt_ctf_field_type_freeze(array_type->element_type);
2806}
2807
2808static
2809void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2810{
2811 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2812 type, struct bt_ctf_field_type_sequence, parent);
2813
3ffba961
JG
2814 /* Cache the alignment */
2815 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2816 generic_field_type_freeze(type);
2817 bt_ctf_field_type_freeze(sequence_type->element_type);
2818}
2819
2820static
2821const char *get_encoding_string(enum ctf_string_encoding encoding)
2822{
2823 const char *encoding_string;
2824
2825 switch (encoding) {
2826 case CTF_STRING_NONE:
2827 encoding_string = "none";
2828 break;
2829 case CTF_STRING_ASCII:
2830 encoding_string = "ASCII";
2831 break;
2832 case CTF_STRING_UTF8:
2833 encoding_string = "UTF8";
2834 break;
2835 default:
2836 encoding_string = "unknown";
2837 break;
2838 }
2839
2840 return encoding_string;
2841}
2842
2843static
2844const char *get_integer_base_string(enum bt_ctf_integer_base base)
2845{
2846 const char *base_string;
2847
2848 switch (base) {
2849 case BT_CTF_INTEGER_BASE_DECIMAL:
2850 base_string = "decimal";
2851 break;
2852 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2853 base_string = "hexadecimal";
2854 break;
2855 case BT_CTF_INTEGER_BASE_OCTAL:
2856 base_string = "octal";
2857 break;
2858 case BT_CTF_INTEGER_BASE_BINARY:
2859 base_string = "binary";
2860 break;
2861 default:
2862 base_string = "unknown";
2863 break;
2864 }
2865
2866 return base_string;
2867}
2868
2869static
2870int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2871 struct metadata_context *context)
2872{
2873 struct bt_ctf_field_type_integer *integer = container_of(type,
2874 struct bt_ctf_field_type_integer, parent);
6cfb906f 2875 int ret = 0;
273b65be
JG
2876
2877 g_string_append_printf(context->string,
6cfb906f 2878 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
2879 integer->declaration.len, type->declaration->alignment,
2880 (integer->declaration.signedness ? "true" : "false"),
2881 get_encoding_string(integer->declaration.encoding),
2882 get_integer_base_string(integer->declaration.base),
2883 get_byte_order_string(integer->declaration.byte_order));
6cfb906f
JG
2884 if (integer->mapped_clock) {
2885 const char *clock_name = bt_ctf_clock_get_name(
2886 integer->mapped_clock);
2887
2888 if (!clock_name) {
2889 ret = -1;
2890 goto end;
2891 }
2892
2893 g_string_append_printf(context->string,
4ebdec03 2894 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2895 }
2896
2897 g_string_append(context->string, "; }");
2898end:
2899 return ret;
273b65be
JG
2900}
2901
2902static
2903int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2904 struct metadata_context *context)
2905{
2906 size_t entry;
9ce21c30 2907 int ret;
273b65be
JG
2908 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2909 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2910 struct bt_ctf_field_type *container_type;
2911 int container_signed;
273b65be 2912
b92ddaaa
JG
2913 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2914 if (!container_type) {
2915 ret = -1;
2916 goto end;
2917 }
2918
2919 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2920 if (container_signed < 0) {
2921 ret = container_signed;
2922 goto error_put_container_type;
2923 }
2924
273b65be
JG
2925 g_string_append(context->string, "enum : ");
2926 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2927 if (ret) {
b92ddaaa 2928 goto error_put_container_type;
273b65be
JG
2929 }
2930
2931 g_string_append(context->string, " { ");
2932 for (entry = 0; entry < enumeration->entries->len; entry++) {
2933 struct enumeration_mapping *mapping =
2934 enumeration->entries->pdata[entry];
2935
b92ddaaa
JG
2936 if (container_signed) {
2937 if (mapping->range_start._signed ==
2938 mapping->range_end._signed) {
2939 g_string_append_printf(context->string,
2940 "\"%s\" = %" PRId64,
2941 g_quark_to_string(mapping->string),
2942 mapping->range_start._signed);
2943 } else {
2944 g_string_append_printf(context->string,
2945 "\"%s\" = %" PRId64 " ... %" PRId64,
2946 g_quark_to_string(mapping->string),
2947 mapping->range_start._signed,
2948 mapping->range_end._signed);
2949 }
273b65be 2950 } else {
b92ddaaa
JG
2951 if (mapping->range_start._unsigned ==
2952 mapping->range_end._unsigned) {
2953 g_string_append_printf(context->string,
2954 "\"%s\" = %" PRIu64,
2955 g_quark_to_string(mapping->string),
2956 mapping->range_start._unsigned);
2957 } else {
2958 g_string_append_printf(context->string,
2959 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2960 g_quark_to_string(mapping->string),
2961 mapping->range_start._unsigned,
2962 mapping->range_end._unsigned);
2963 }
273b65be
JG
2964 }
2965
2966 g_string_append(context->string,
2967 ((entry != (enumeration->entries->len - 1)) ?
2968 ", " : " }"));
2969 }
2970
2971 if (context->field_name->len) {
2972 g_string_append_printf(context->string, " %s",
2973 context->field_name->str);
2974 g_string_assign(context->field_name, "");
2975 }
b92ddaaa 2976error_put_container_type:
83509119 2977 bt_put(container_type);
273b65be
JG
2978end:
2979 return ret;
2980}
2981
2982static
2983int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2984 struct metadata_context *context)
2985{
2986 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2987 type, struct bt_ctf_field_type_floating_point, parent);
2988
2989 g_string_append_printf(context->string,
2990 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2991 floating_point->declaration.exp->len,
2992 floating_point->declaration.mantissa->len + 1,
2993 get_byte_order_string(floating_point->declaration.byte_order),
2994 type->declaration->alignment);
2995 return 0;
2996}
2997
2998static
2999int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
3000 struct metadata_context *context)
3001{
3002 size_t i;
3003 unsigned int indent;
3004 int ret = 0;
3005 struct bt_ctf_field_type_structure *structure = container_of(type,
3006 struct bt_ctf_field_type_structure, parent);
3007 GString *structure_field_name = context->field_name;
3008
3009 context->field_name = g_string_new("");
3010
3011 context->current_indentation_level++;
3012 g_string_append(context->string, "struct {\n");
3013
3014 for (i = 0; i < structure->fields->len; i++) {
3015 struct structure_field *field;
3016
3017 for (indent = 0; indent < context->current_indentation_level;
3018 indent++) {
3019 g_string_append_c(context->string, '\t');
3020 }
3021
3022 field = structure->fields->pdata[i];
3023 g_string_assign(context->field_name,
3024 g_quark_to_string(field->name));
3025 ret = bt_ctf_field_type_serialize(field->type, context);
3026 if (ret) {
3027 goto end;
3028 }
3029
3030 if (context->field_name->len) {
3031 g_string_append_printf(context->string, " %s",
3032 context->field_name->str);
3033 }
3034 g_string_append(context->string, ";\n");
3035 }
3036
3037 context->current_indentation_level--;
3038 for (indent = 0; indent < context->current_indentation_level;
3039 indent++) {
3040 g_string_append_c(context->string, '\t');
3041 }
3042
3043 g_string_append_printf(context->string, "} align(%zu)",
3044 type->declaration->alignment);
3045end:
3046 g_string_free(context->field_name, TRUE);
3047 context->field_name = structure_field_name;
3048 return ret;
3049}
3050
3051static
3052int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3053 struct metadata_context *context)
3054{
3055 size_t i;
3056 unsigned int indent;
3057 int ret = 0;
3058 struct bt_ctf_field_type_variant *variant = container_of(
3059 type, struct bt_ctf_field_type_variant, parent);
3060 GString *variant_field_name = context->field_name;
3061
3062 context->field_name = g_string_new("");
6964b7fd
JG
3063 if (variant->tag_name->len > 0) {
3064 g_string_append_printf(context->string,
3065 "variant <%s> {\n", variant->tag_name->str);
3066 } else {
3067 g_string_append(context->string, "variant {\n");
3068 }
3069
273b65be
JG
3070 context->current_indentation_level++;
3071 for (i = 0; i < variant->fields->len; i++) {
3072 struct structure_field *field = variant->fields->pdata[i];
3073
3074 g_string_assign(context->field_name,
3075 g_quark_to_string(field->name));
3076 for (indent = 0; indent < context->current_indentation_level;
3077 indent++) {
3078 g_string_append_c(context->string, '\t');
3079 }
3080
3081 g_string_assign(context->field_name,
3082 g_quark_to_string(field->name));
3083 ret = bt_ctf_field_type_serialize(field->type, context);
3084 if (ret) {
3085 goto end;
3086 }
3087
3088 if (context->field_name->len) {
3089 g_string_append_printf(context->string, " %s;",
3090 context->field_name->str);
3091 }
3092
3093 g_string_append_c(context->string, '\n');
3094 }
3095
3096 context->current_indentation_level--;
3097 for (indent = 0; indent < context->current_indentation_level;
3098 indent++) {
3099 g_string_append_c(context->string, '\t');
3100 }
3101
3102 g_string_append(context->string, "}");
3103end:
3104 g_string_free(context->field_name, TRUE);
3105 context->field_name = variant_field_name;
3106 return ret;
3107}
3108
3109static
3110int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3111 struct metadata_context *context)
3112{
3113 int ret = 0;
3114 struct bt_ctf_field_type_array *array = container_of(type,
3115 struct bt_ctf_field_type_array, parent);
3116
3117 ret = bt_ctf_field_type_serialize(array->element_type, context);
3118 if (ret) {
3119 goto end;
3120 }
3121
3122 if (context->field_name->len) {
3123 g_string_append_printf(context->string, " %s[%u]",
3124 context->field_name->str, array->length);
3125 g_string_assign(context->field_name, "");
3126 } else {
3127 g_string_append_printf(context->string, "[%u]", array->length);
3128 }
3129end:
3130 return ret;
3131}
3132
3133static
3134int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3135 struct metadata_context *context)
3136{
3137 int ret = 0;
3138 struct bt_ctf_field_type_sequence *sequence = container_of(
3139 type, struct bt_ctf_field_type_sequence, parent);
3140
3141 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3142 if (ret) {
3143 goto end;
3144 }
3145
3146 if (context->field_name->len) {
3147 g_string_append_printf(context->string, " %s[%s]",
3148 context->field_name->str,
3149 sequence->length_field_name->str);
3150 g_string_assign(context->field_name, "");
3151 } else {
3152 g_string_append_printf(context->string, "[%s]",
3153 sequence->length_field_name->str);
3154 }
3155end:
3156 return ret;
3157}
3158
3159static
3160int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3161 struct metadata_context *context)
3162{
3163 struct bt_ctf_field_type_string *string = container_of(
3164 type, struct bt_ctf_field_type_string, parent);
3165
3166 g_string_append_printf(context->string,
3167 "string { encoding = %s; }",
3168 get_encoding_string(string->declaration.encoding));
3169 return 0;
3170}
3171
445c3471
PP
3172static
3173enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3174 enum bt_ctf_byte_order ret;
3175
3176 switch (byte_order) {
3177 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3178 case LITTLE_ENDIAN:
3179 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3180 break;
3181 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3182 case BIG_ENDIAN:
3183 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3184 break;
3185 case BT_CTF_BYTE_ORDER_NETWORK:
3186 ret = BT_CTF_BYTE_ORDER_NETWORK;
3187 break;
3188 case BT_CTF_BYTE_ORDER_NATIVE:
3189 ret = BT_CTF_BYTE_ORDER_NATIVE;
3190 break;
3191 default:
3192 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3193 break;
3194 }
3195
3196 return ret;
3197}
3198
273b65be
JG
3199static
3200void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 3201 int byte_order, int set_native)
273b65be
JG
3202{
3203 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3204 struct bt_ctf_field_type_integer, parent);
3205
c35a1669 3206 if (set_native) {
445c3471
PP
3207 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3208 /*
3209 * User byte order is native, so we can set
3210 * the real byte order.
3211 */
3212 integer_type->declaration.byte_order =
3213 byte_order;
3214 }
c35a1669 3215 } else {
445c3471
PP
3216 integer_type->user_byte_order =
3217 get_ctf_ir_byte_order(byte_order);
c35a1669
JG
3218 integer_type->declaration.byte_order = byte_order;
3219 }
3220}
3221
3222static
3223void bt_ctf_field_type_enumeration_set_byte_order(
3224 struct bt_ctf_field_type *type, int byte_order, int set_native)
3225{
3226 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3227 struct bt_ctf_field_type_enumeration, parent);
3228
3229 /* Safe to assume that container is an integer */
3230 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3231 byte_order, set_native);
273b65be
JG
3232}
3233
3234static
3235void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 3236 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
3237{
3238 struct bt_ctf_field_type_floating_point *floating_point_type =
3239 container_of(type, struct bt_ctf_field_type_floating_point,
3240 parent);
3241
c35a1669 3242 if (set_native) {
445c3471
PP
3243 if (floating_point_type->user_byte_order ==
3244 BT_CTF_BYTE_ORDER_NATIVE) {
3245 /*
3246 * User byte order is native, so we can set
3247 * the real byte order.
3248 */
3249 floating_point_type->declaration.byte_order =
3250 byte_order;
3251 floating_point_type->sign.byte_order =
3252 byte_order;
3253 floating_point_type->mantissa.byte_order =
3254 byte_order;
3255 floating_point_type->exp.byte_order =
3256 byte_order;
3257 }
c35a1669 3258 } else {
445c3471
PP
3259 floating_point_type->user_byte_order =
3260 get_ctf_ir_byte_order(byte_order);
c35a1669
JG
3261 floating_point_type->declaration.byte_order = byte_order;
3262 floating_point_type->sign.byte_order = byte_order;
3263 floating_point_type->mantissa.byte_order = byte_order;
3264 floating_point_type->exp.byte_order = byte_order;
3265 }
3266}
3267
3268static
3269void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3270 int byte_order, int set_native)
3271{
3272 int i;
3273 struct bt_ctf_field_type_structure *structure_type =
3274 container_of(type, struct bt_ctf_field_type_structure,
3275 parent);
3276
3277 for (i = 0; i < structure_type->fields->len; i++) {
3278 struct structure_field *field = g_ptr_array_index(
3279 structure_type->fields, i);
3280 struct bt_ctf_field_type *field_type = field->type;
3281
3282 if (set_byte_order_funcs[field_type->declaration->id]) {
3283 set_byte_order_funcs[field_type->declaration->id](
3284 field_type, byte_order, set_native);
3285 }
3286 }
3287}
3288
3289static
3290void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3291 int byte_order, int set_native)
3292{
3293 int i;
3294 struct bt_ctf_field_type_variant *variant_type =
3295 container_of(type, struct bt_ctf_field_type_variant,
3296 parent);
3297
3298 for (i = 0; i < variant_type->fields->len; i++) {
3299 struct structure_field *field = g_ptr_array_index(
3300 variant_type->fields, i);
3301 struct bt_ctf_field_type *field_type = field->type;
3302
3303 if (set_byte_order_funcs[field_type->declaration->id]) {
3304 set_byte_order_funcs[field_type->declaration->id](
3305 field_type, byte_order, set_native);
3306 }
3307 }
3308}
3309
3310static
3311void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3312 int byte_order, int set_native)
3313{
3314 struct bt_ctf_field_type_array *array_type =
3315 container_of(type, struct bt_ctf_field_type_array,
3316 parent);
3317
3318 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3319 set_byte_order_funcs[array_type->element_type->declaration->id](
3320 array_type->element_type, byte_order, set_native);
3321 }
3322}
3323
3324static
3325void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3326 int byte_order, int set_native)
3327{
3328 struct bt_ctf_field_type_sequence *sequence_type =
3329 container_of(type, struct bt_ctf_field_type_sequence,
3330 parent);
3331
3332 if (set_byte_order_funcs[
3333 sequence_type->element_type->declaration->id]) {
3334 set_byte_order_funcs[
3335 sequence_type->element_type->declaration->id](
3336 sequence_type->element_type, byte_order, set_native);
3337 }
273b65be 3338}
24724933
JG
3339
3340static
3341struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3342 struct bt_ctf_field_type *type)
3343{
3344 struct bt_ctf_field_type *copy;
3345 struct bt_ctf_field_type_integer *integer, *copy_integer;
3346
3347 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3348 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3349 if (!copy) {
3350 goto end;
3351 }
3352
3353 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3354 parent);
3355 copy_integer->declaration = integer->declaration;
3356 if (integer->mapped_clock) {
83509119 3357 bt_get(integer->mapped_clock);
24724933
JG
3358 copy_integer->mapped_clock = integer->mapped_clock;
3359 }
445c3471
PP
3360
3361 copy_integer->user_byte_order = integer->user_byte_order;
3362
24724933
JG
3363end:
3364 return copy;
3365}
3366
3367static
3368struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3369 struct bt_ctf_field_type *type)
3370{
3371 size_t i;
3372 struct bt_ctf_field_type *copy = NULL, *copy_container;
3373 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3374
3375 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3376 parent);
3377
3378 /* Copy the source enumeration's container */
3379 copy_container = bt_ctf_field_type_copy(enumeration->container);
3380 if (!copy_container) {
3381 goto end;
3382 }
3383
3384 copy = bt_ctf_field_type_enumeration_create(copy_container);
3385 if (!copy) {
3386 goto end;
3387 }
3388 copy_enumeration = container_of(copy,
3389 struct bt_ctf_field_type_enumeration, parent);
3390
3391 /* Copy all enumaration entries */
3392 for (i = 0; i < enumeration->entries->len; i++) {
3393 struct enumeration_mapping *mapping = g_ptr_array_index(
3394 enumeration->entries, i);
3395 struct enumeration_mapping* copy_mapping = g_new0(
3396 struct enumeration_mapping, 1);
3397
3398 if (!copy_mapping) {
3399 goto error;
3400 }
3401
3402 *copy_mapping = *mapping;
3403 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3404 }
3405
3406 copy_enumeration->declaration = enumeration->declaration;
3407end:
83509119 3408 bt_put(copy_container);
24724933
JG
3409 return copy;
3410error:
83509119
JG
3411 bt_put(copy_container);
3412 BT_PUT(copy);
3413 return copy;
24724933
JG
3414}
3415
3416static
3417struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3418 struct bt_ctf_field_type *type)
3419{
3420 struct bt_ctf_field_type *copy;
3421 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3422
3423 floating_point = container_of(type,
3424 struct bt_ctf_field_type_floating_point, parent);
3425 copy = bt_ctf_field_type_floating_point_create();
3426 if (!copy) {
3427 goto end;
3428 }
3429
3430 copy_float = container_of(copy,
3431 struct bt_ctf_field_type_floating_point, parent);
3432 copy_float->declaration = floating_point->declaration;
3433 copy_float->sign = floating_point->sign;
3434 copy_float->mantissa = floating_point->mantissa;
3435 copy_float->exp = floating_point->exp;
445c3471 3436 copy_float->user_byte_order = floating_point->user_byte_order;
d480b699
PP
3437 copy_float->declaration.sign = &copy_float->sign;
3438 copy_float->declaration.mantissa = &copy_float->mantissa;
3439 copy_float->declaration.exp = &copy_float->exp;
24724933
JG
3440end:
3441 return copy;
3442}
3443
3444static
3445struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3446 struct bt_ctf_field_type *type)
3447{
3448 int i;
3449 GHashTableIter iter;
3450 gpointer key, value;
3451 struct bt_ctf_field_type *copy;
3452 struct bt_ctf_field_type_structure *structure, *copy_structure;
3453
3454 structure = container_of(type, struct bt_ctf_field_type_structure,
3455 parent);
3456 copy = bt_ctf_field_type_structure_create();
3457 if (!copy) {
3458 goto end;
3459 }
3460
3461 copy_structure = container_of(copy,
3462 struct bt_ctf_field_type_structure, parent);
3463
3464 /* Copy field_name_to_index */
3465 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3466 while (g_hash_table_iter_next (&iter, &key, &value)) {
3467 g_hash_table_insert(copy_structure->field_name_to_index,
3468 key, value);
3469 }
3470
3471 for (i = 0; i < structure->fields->len; i++) {
3472 struct structure_field *entry, *copy_entry;
3473 struct bt_ctf_field_type *copy_field;
3474
3475 copy_entry = g_new0(struct structure_field, 1);
3476 if (!copy_entry) {
3477 goto error;
3478 }
3479
3480 entry = g_ptr_array_index(structure->fields, i);
3481 copy_field = bt_ctf_field_type_copy(entry->type);
3482 if (!copy_field) {
3483 g_free(copy_entry);
3484 goto error;
3485 }
3486
3487 copy_entry->name = entry->name;
3488 copy_entry->type = copy_field;
3489 g_ptr_array_add(copy_structure->fields, copy_entry);
3490 }
3491
3492 copy_structure->declaration = structure->declaration;
3493end:
3494 return copy;
3495error:
83509119
JG
3496 BT_PUT(copy);
3497 return copy;
24724933
JG
3498}
3499
3500static
3501struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3502 struct bt_ctf_field_type *type)
3503{
3504 int i;
3505 GHashTableIter iter;
3506 gpointer key, value;
3507 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3508 struct bt_ctf_field_type_variant *variant, *copy_variant;
3509
3510 variant = container_of(type, struct bt_ctf_field_type_variant,
3511 parent);
3512 if (variant->tag) {
3513 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3514 if (!copy_tag) {
3515 goto end;
3516 }
3517 }
3518
3519 copy = bt_ctf_field_type_variant_create(copy_tag,
3520 variant->tag_name->len ? variant->tag_name->str : NULL);
3521 if (!copy) {
3522 goto end;
3523 }
3524
3525 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3526 parent);
3527
3528 /* Copy field_name_to_index */
3529 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3530 while (g_hash_table_iter_next (&iter, &key, &value)) {
3531 g_hash_table_insert(copy_variant->field_name_to_index,
3532 key, value);
3533 }
3534
3535 for (i = 0; i < variant->fields->len; i++) {
3536 struct structure_field *entry, *copy_entry;
3537 struct bt_ctf_field_type *copy_field;
3538
3539 copy_entry = g_new0(struct structure_field, 1);
3540 if (!copy_entry) {
3541 goto error;
3542 }
3543
3544 entry = g_ptr_array_index(variant->fields, i);
3545 copy_field = bt_ctf_field_type_copy(entry->type);
3546 if (!copy_field) {
3547 g_free(copy_entry);
3548 goto error;
3549 }
3550
3551 copy_entry->name = entry->name;
3552 copy_entry->type = copy_field;
3553 g_ptr_array_add(copy_variant->fields, copy_entry);
3554 }
3555
3556 copy_variant->declaration = variant->declaration;
4a1e8671
JG
3557 if (variant->tag_path) {
3558 copy_variant->tag_path = bt_ctf_field_path_copy(
3559 variant->tag_path);
3560 if (!copy_variant->tag_path) {
3561 goto error;
3562 }
3563 }
24724933 3564end:
83509119 3565 bt_put(copy_tag);
24724933
JG
3566 return copy;
3567error:
83509119
JG
3568 bt_put(copy_tag);
3569 BT_PUT(copy);
3570 return copy;
24724933
JG
3571}
3572
3573static
3574struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3575 struct bt_ctf_field_type *type)
3576{
3577 struct bt_ctf_field_type *copy = NULL, *copy_element;
3578 struct bt_ctf_field_type_array *array, *copy_array;
3579
3580 array = container_of(type, struct bt_ctf_field_type_array,
3581 parent);
3582 copy_element = bt_ctf_field_type_copy(array->element_type);
3583 if (!copy_element) {
3584 goto end;
3585 }
3586
3587 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3588 if (!copy) {
3589 goto end;
3590 }
3591
3592 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3593 parent);
3594 copy_array->declaration = array->declaration;
3595end:
83509119 3596 bt_put(copy_element);
24724933
JG
3597 return copy;
3598}
3599
3600static
3601struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3602 struct bt_ctf_field_type *type)
3603{
3604 struct bt_ctf_field_type *copy = NULL, *copy_element;
3605 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3606
3607 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3608 parent);
3609 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3610 if (!copy_element) {
3611 goto end;
3612 }
3613
3614 copy = bt_ctf_field_type_sequence_create(copy_element,
3615 sequence->length_field_name->len ?
3616 sequence->length_field_name->str : NULL);
3617 if (!copy) {
3618 goto end;
3619 }
3620
3621 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3622 parent);
3623 copy_sequence->declaration = sequence->declaration;
aa4e271c
JG
3624 if (sequence->length_field_path) {
3625 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3626 sequence->length_field_path);
3627 if (!copy_sequence->length_field_path) {
3628 goto error;
3629 }
3630 }
24724933 3631end:
83509119 3632 bt_put(copy_element);
24724933 3633 return copy;
aa4e271c 3634error:
83509119 3635 BT_PUT(copy);
aa4e271c 3636 goto end;
24724933
JG
3637}
3638
3639static
3640struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3641 struct bt_ctf_field_type *type)
3642{
3643 struct bt_ctf_field_type *copy;
3644 struct bt_ctf_field_type_string *string, *copy_string;
3645
3646 copy = bt_ctf_field_type_string_create();
3647 if (!copy) {
3648 goto end;
3649 }
3650
3651 string = container_of(type, struct bt_ctf_field_type_string,
3652 parent);
3653 copy_string = container_of(type, struct bt_ctf_field_type_string,
3654 parent);
3655 copy_string->declaration = string->declaration;
3656end:
3657 return copy;
3658}
265e809c
PP
3659
3660static
3661int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3662 struct bt_ctf_field_type *type_b)
3663{
3664 int ret = 1;
3665 struct bt_ctf_field_type_integer *integer_a;
3666 struct bt_ctf_field_type_integer *integer_b;
3667 struct declaration_integer *decl_a;
3668 struct declaration_integer *decl_b;
3669
3670 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3671 parent);
3672 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3673 parent);
3674 decl_a = &integer_a->declaration;
3675 decl_b = &integer_b->declaration;
3676
3677 /* Length */
3678 if (decl_a->len != decl_b->len) {
3679 goto end;
3680 }
3681
3682 /*
3683 * Compare user byte orders only, not the cached,
3684 * real byte orders.
3685 */
3686 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3687 goto end;
3688 }
3689
3690 /* Signedness */
3691 if (decl_a->signedness != decl_b->signedness) {
3692 goto end;
3693 }
3694
3695 /* Base */
3696 if (decl_a->base != decl_b->base) {
3697 goto end;
3698 }
3699
3700 /* Encoding */
3701 if (decl_a->encoding != decl_b->encoding) {
3702 goto end;
3703 }
3704
3705 /* Mapped clock */
3706 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3707 goto end;
3708 }
3709
3710 /* Equal */
3711 ret = 0;
3712
3713end:
3714 return ret;
3715}
3716
3717static
3718int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3719 struct bt_ctf_field_type *type_b)
3720{
3721 int ret = 1;
3722 struct bt_ctf_field_type_floating_point *float_a;
3723 struct bt_ctf_field_type_floating_point *float_b;
3724
3725 float_a = container_of(type_a,
3726 struct bt_ctf_field_type_floating_point, parent);
3727 float_b = container_of(type_b,
3728 struct bt_ctf_field_type_floating_point, parent);
3729
3730 /* Sign length */
3731 if (float_a->sign.len != float_b->sign.len) {
3732 goto end;
3733 }
3734
3735 /* Exponent length */
3736 if (float_a->exp.len != float_b->exp.len) {
3737 goto end;
3738 }
3739
3740 /* Mantissa length */
3741 if (float_a->mantissa.len != float_b->mantissa.len) {
3742 goto end;
3743 }
3744
3745 /*
3746 * Compare user byte orders only, not the cached,
3747 * real byte orders.
3748 */
3749 if (float_a->user_byte_order != float_b->user_byte_order) {
3750 goto end;
3751 }
3752
3753 /* Equal */
3754 ret = 0;
3755
3756end:
3757 return ret;
3758}
3759
3760static
3761int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3762 struct enumeration_mapping *mapping_b)
3763{
3764 int ret = 1;
3765
3766 /* Label */
3767 if (mapping_a->string != mapping_b->string) {
3768 goto end;
3769 }
3770
3771 /* Range start */
3772 if (mapping_a->range_start._unsigned !=
3773 mapping_b->range_start._unsigned) {
3774 goto end;
3775 }
3776
3777 /* Range end */
3778 if (mapping_a->range_end._unsigned !=
3779 mapping_b->range_end._unsigned) {
3780 goto end;
3781 }
3782
3783 /* Equal */
3784 ret = 0;
3785
3786end:
3787 return ret;
3788}
3789
3790static
3791int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3792 struct bt_ctf_field_type *type_b)
3793{
3794 int ret = 1;
3795 int i;
3796 struct bt_ctf_field_type_enumeration *enum_a;
3797 struct bt_ctf_field_type_enumeration *enum_b;
3798
3799 enum_a = container_of(type_a,
3800 struct bt_ctf_field_type_enumeration, parent);
3801 enum_b = container_of(type_b,
3802 struct bt_ctf_field_type_enumeration, parent);
3803
3804 /* Container field type */
3805 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3806 if (ret) {
3807 goto end;
3808 }
3809
3810 ret = 1;
3811
3812 /* Entries */
3813 if (enum_a->entries->len != enum_b->entries->len) {
3814 goto end;
3815 }
3816
3817 for (i = 0; i < enum_a->entries->len; ++i) {
3818 struct enumeration_mapping *mapping_a =
3819 g_ptr_array_index(enum_a->entries, i);
3820 struct enumeration_mapping *mapping_b =
3821 g_ptr_array_index(enum_b->entries, i);
3822
3823 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3824 goto end;
3825 }
3826 }
3827
3828 /* Equal */
3829 ret = 0;
3830
3831end:
3832 return ret;
3833}
3834
3835static
3836int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3837 struct bt_ctf_field_type *type_b)
3838{
3839 int ret = 1;
3840 struct bt_ctf_field_type_string *string_a;
3841 struct bt_ctf_field_type_string *string_b;
3842
3843 string_a = container_of(type_a,
3844 struct bt_ctf_field_type_string, parent);
3845 string_b = container_of(type_b,
3846 struct bt_ctf_field_type_string, parent);
3847
3848 /* Encoding */
3849 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3850 goto end;
3851 }
3852
3853 /* Equal */
3854 ret = 0;
3855
3856end:
3857 return ret;
3858}
3859
3860static
3861int compare_structure_fields(struct structure_field *field_a,
3862 struct structure_field *field_b)
3863{
3864 int ret = 1;
3865
3866 /* Label */
3867 if (field_a->name != field_b->name) {
3868 goto end;
3869 }
3870
3871 /* Type */
3872 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3873
3874end:
3875 return ret;
3876}
3877
3878static
3879int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3880 struct bt_ctf_field_type *type_b)
3881{
3882 int ret = 1;
3883 int i;
3884 struct bt_ctf_field_type_structure *struct_a;
3885 struct bt_ctf_field_type_structure *struct_b;
3886
3887 struct_a = container_of(type_a,
3888 struct bt_ctf_field_type_structure, parent);
3889 struct_b = container_of(type_b,
3890 struct bt_ctf_field_type_structure, parent);
3891
3892 /* Alignment */
3893 if (bt_ctf_field_type_get_alignment(type_a) !=
3894 bt_ctf_field_type_get_alignment(type_b)) {
3895 goto end;
3896 }
3897
3898 /* Fields */
3899 if (struct_a->fields->len != struct_b->fields->len) {
3900 goto end;
3901 }
3902
3903 for (i = 0; i < struct_a->fields->len; ++i) {
3904 struct structure_field *field_a =
3905 g_ptr_array_index(struct_a->fields, i);
3906 struct structure_field *field_b =
3907 g_ptr_array_index(struct_b->fields, i);
3908
3909 ret = compare_structure_fields(field_a, field_b);
3910 if (ret) {
3911 goto end;
3912 }
3913
3914 ret = 1;
3915 }
3916
3917 /* Equal */
3918 ret = 0;
3919
3920end:
3921 return ret;
3922}
3923
3924static
3925int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3926 struct bt_ctf_field_type *type_b)
3927{
3928 int ret = 1;
3929 int i;
3930 struct bt_ctf_field_type_variant *variant_a;
3931 struct bt_ctf_field_type_variant *variant_b;
3932
3933 variant_a = container_of(type_a,
3934 struct bt_ctf_field_type_variant, parent);
3935 variant_b = container_of(type_b,
3936 struct bt_ctf_field_type_variant, parent);
3937
3938 /* Tag name */
3939 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3940 goto end;
3941 }
3942
3943 /* Tag type */
3944 ret = bt_ctf_field_type_compare(
3945 (struct bt_ctf_field_type *) variant_a->tag,
3946 (struct bt_ctf_field_type *) variant_b->tag);
3947 if (ret) {
3948 goto end;
3949 }
3950
3951 ret = 1;
3952
3953 /* Fields */
3954 if (variant_a->fields->len != variant_b->fields->len) {
3955 goto end;
3956 }
3957
3958 for (i = 0; i < variant_a->fields->len; ++i) {
3959 struct structure_field *field_a =
3960 g_ptr_array_index(variant_a->fields, i);
3961 struct structure_field *field_b =
3962 g_ptr_array_index(variant_b->fields, i);
3963
3964 ret = compare_structure_fields(field_a, field_b);
3965 if (ret) {
3966 goto end;
3967 }
3968
3969 ret = 1;
3970 }
3971
3972 /* Equal */
3973 ret = 0;
3974
3975end:
3976 return ret;
3977}
3978
3979static
3980int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3981 struct bt_ctf_field_type *type_b)
3982{
3983 int ret = 1;
3984 struct bt_ctf_field_type_array *array_a;
3985 struct bt_ctf_field_type_array *array_b;
3986
3987 array_a = container_of(type_a,
3988 struct bt_ctf_field_type_array, parent);
3989 array_b = container_of(type_b,
3990 struct bt_ctf_field_type_array, parent);
3991
3992 /* Length */
3993 if (array_a->length != array_b->length) {
3994 goto end;
3995 }
3996
3997 /* Element type */
3998 ret = bt_ctf_field_type_compare(array_a->element_type,
3999 array_b->element_type);
4000
4001end:
4002 return ret;
4003}
4004
4005static
4006int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
4007 struct bt_ctf_field_type *type_b)
4008{
4009 int ret = -1;
4010 struct bt_ctf_field_type_sequence *sequence_a;
4011 struct bt_ctf_field_type_sequence *sequence_b;
4012
4013 sequence_a = container_of(type_a,
4014 struct bt_ctf_field_type_sequence, parent);
4015 sequence_b = container_of(type_b,
4016 struct bt_ctf_field_type_sequence, parent);
4017
4018 /* Length name */
4019 if (strcmp(sequence_a->length_field_name->str,
4020 sequence_b->length_field_name->str)) {
4021 goto end;
4022 }
4023
4024 /* Element type */
4025 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4026 sequence_b->element_type);
4027
4028end:
4029 return ret;
4030}
4031
4032int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4033 struct bt_ctf_field_type *type_b)
4034{
4035 int ret = 1;
4036
4037 if (type_a == type_b) {
4038 /* Same reference: equal (even if both are NULL) */
4039 ret = 0;
4040 goto end;
4041 }
4042
4043 if (!type_a || !type_b) {
4044 ret = -1;
4045 goto end;
4046 }
4047
4048 if (type_a->declaration->id != type_b->declaration->id) {
4049 /* Different type IDs */
4050 goto end;
4051 }
4052
4053 if (type_a->declaration->id == CTF_TYPE_UNKNOWN) {
4054 /* Both have unknown type IDs */
4055 goto end;
4056 }
4057
4058 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4059
4060end:
4061 return ret;
4062}
This page took 0.207346 seconds and 4 git commands to generate.