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