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