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