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