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