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