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