Fix enum rename warnings
[babeltrace.git] / formats / ctf / ir / field-types.c
1 /*
2 * field-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-ir/field-types-internal.h>
30 #include <babeltrace/ctf-ir/field-path-internal.h>
31 #include <babeltrace/ctf-ir/fields-internal.h>
32 #include <babeltrace/ctf-ir/utils.h>
33 #include <babeltrace/ref.h>
34 #include <babeltrace/ctf-ir/clock.h>
35 #include <babeltrace/ctf-ir/clock-internal.h>
36 #include <babeltrace/ctf-writer/writer-internal.h>
37 #include <babeltrace/object-internal.h>
38 #include <babeltrace/ref.h>
39 #include <babeltrace/compiler.h>
40 #include <babeltrace/endian.h>
41 #include <float.h>
42 #include <inttypes.h>
43 #include <stdlib.h>
44
45 struct range_overlap_query {
46 union {
47 uint64_t _unsigned;
48 int64_t _signed;
49 } range_start;
50
51 union {
52 uint64_t _unsigned;
53 int64_t _signed;
54 } range_end;
55 int overlaps;
56 GQuark mapping_name;
57 };
58
59 static
60 void bt_ctf_field_type_destroy(struct bt_object *);
61 static
62 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
63 static
64 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
65 static
66 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
67 static
68 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
69 static
70 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
71 static
72 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
73 static
74 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
75 static
76 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
77
78 static
79 void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
80 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_destroy,
81 [CTF_TYPE_ENUM] =
82 bt_ctf_field_type_enumeration_destroy,
83 [CTF_TYPE_FLOAT] =
84 bt_ctf_field_type_floating_point_destroy,
85 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_destroy,
86 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_destroy,
87 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_destroy,
88 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
89 [CTF_TYPE_STRING] = bt_ctf_field_type_string_destroy,
90 };
91
92 static
93 void generic_field_type_freeze(struct bt_ctf_field_type *);
94 static
95 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
96 static
97 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
98 static
99 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
100 static
101 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
102 static
103 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
104 static
105 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
106
107 static
108 type_freeze_func const type_freeze_funcs[] = {
109 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_freeze,
110 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_freeze,
111 [CTF_TYPE_FLOAT] = generic_field_type_freeze,
112 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_freeze,
113 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_freeze,
114 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_freeze,
115 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
116 [CTF_TYPE_STRING] = generic_field_type_freeze,
117 };
118
119 static
120 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
121 struct metadata_context *);
122 static
123 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
124 struct metadata_context *);
125 static
126 int bt_ctf_field_type_floating_point_serialize(
127 struct bt_ctf_field_type *, struct metadata_context *);
128 static
129 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
130 struct metadata_context *);
131 static
132 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
133 struct metadata_context *);
134 static
135 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
136 struct metadata_context *);
137 static
138 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
139 struct metadata_context *);
140 static
141 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
142 struct metadata_context *);
143
144 static
145 type_serialize_func const type_serialize_funcs[] = {
146 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_serialize,
147 [CTF_TYPE_ENUM] =
148 bt_ctf_field_type_enumeration_serialize,
149 [CTF_TYPE_FLOAT] =
150 bt_ctf_field_type_floating_point_serialize,
151 [CTF_TYPE_STRUCT] =
152 bt_ctf_field_type_structure_serialize,
153 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_serialize,
154 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_serialize,
155 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
156 [CTF_TYPE_STRING] = bt_ctf_field_type_string_serialize,
157 };
158
159 static
160 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
161 int byte_order, int set_native);
162 static
163 void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
164 int byte_order, int set_native);
165 static
166 void bt_ctf_field_type_floating_point_set_byte_order(
167 struct bt_ctf_field_type *, int byte_order, int set_native);
168 static
169 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
170 int byte_order, int set_native);
171 static
172 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
173 int byte_order, int set_native);
174 static
175 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
176 int byte_order, int set_native);
177 static
178 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
179 int byte_order, int set_native);
180
181 /* The set_native flag only set the byte order if it is set to native */
182 static
183 void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
184 int byte_order, int set_native) = {
185 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
186 [CTF_TYPE_ENUM] =
187 bt_ctf_field_type_enumeration_set_byte_order,
188 [CTF_TYPE_FLOAT] =
189 bt_ctf_field_type_floating_point_set_byte_order,
190 [CTF_TYPE_STRUCT] =
191 bt_ctf_field_type_structure_set_byte_order,
192 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
193 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_set_byte_order,
194 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
195 [CTF_TYPE_STRING] = NULL,
196 };
197
198 static
199 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
200 struct bt_ctf_field_type *);
201 static
202 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
203 struct bt_ctf_field_type *);
204 static
205 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
206 struct bt_ctf_field_type *);
207 static
208 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
209 struct bt_ctf_field_type *);
210 static
211 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
212 struct bt_ctf_field_type *);
213 static
214 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
215 struct bt_ctf_field_type *);
216 static
217 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
218 struct bt_ctf_field_type *);
219 static
220 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
221 struct bt_ctf_field_type *);
222
223 static
224 struct bt_ctf_field_type *(* const type_copy_funcs[])(
225 struct bt_ctf_field_type *) = {
226 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_copy,
227 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_copy,
228 [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_copy,
229 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_copy,
230 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_copy,
231 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_copy,
232 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_copy,
233 [CTF_TYPE_STRING] = bt_ctf_field_type_string_copy,
234 };
235
236 static
237 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
238 struct bt_ctf_field_type *);
239 static
240 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
241 struct bt_ctf_field_type *);
242 static
243 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
244 struct bt_ctf_field_type *);
245 static
246 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
247 struct bt_ctf_field_type *);
248 static
249 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
250 struct bt_ctf_field_type *);
251 static
252 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
253 struct bt_ctf_field_type *);
254 static
255 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
256 struct bt_ctf_field_type *);
257 static
258 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
259 struct bt_ctf_field_type *);
260
261 static
262 int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
263 struct bt_ctf_field_type *) = {
264 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_compare,
265 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_compare,
266 [CTF_TYPE_FLOAT] = bt_ctf_field_type_floating_point_compare,
267 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_compare,
268 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_compare,
269 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_compare,
270 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_compare,
271 [CTF_TYPE_STRING] = bt_ctf_field_type_string_compare,
272 };
273
274 static
275 int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *);
276 static
277 int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
278 static
279 int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
280 static
281 int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
282 static
283 int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
284 static
285 int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
286
287 static
288 int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
289 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_validate,
290 [CTF_TYPE_FLOAT] = NULL,
291 [CTF_TYPE_STRING] = NULL,
292 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_validate,
293 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_validate,
294 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_validate,
295 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_validate,
296 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_validate,
297 };
298
299 static
300 void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
301 {
302 g_free(mapping);
303 }
304
305 static
306 void destroy_structure_field(struct structure_field *field)
307 {
308 bt_put(field->type);
309 g_free(field);
310 }
311
312 static
313 void check_ranges_overlap(gpointer element, gpointer query)
314 {
315 struct enumeration_mapping *mapping = element;
316 struct range_overlap_query *overlap_query = query;
317
318 if (mapping->range_start._signed <= overlap_query->range_end._signed
319 && overlap_query->range_start._signed <=
320 mapping->range_end._signed) {
321 overlap_query->overlaps = 1;
322 overlap_query->mapping_name = mapping->string;
323 }
324
325 overlap_query->overlaps |=
326 mapping->string == overlap_query->mapping_name;
327 }
328
329 static
330 void check_ranges_overlap_unsigned(gpointer element, gpointer query)
331 {
332 struct enumeration_mapping *mapping = element;
333 struct range_overlap_query *overlap_query = query;
334
335 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
336 && overlap_query->range_start._unsigned <=
337 mapping->range_end._unsigned) {
338 overlap_query->overlaps = 1;
339 overlap_query->mapping_name = mapping->string;
340 }
341
342 overlap_query->overlaps |=
343 mapping->string == overlap_query->mapping_name;
344 }
345
346 static
347 gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
348 struct enumeration_mapping **b)
349 {
350 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
351 }
352
353 static
354 gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
355 struct enumeration_mapping **b)
356 {
357 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
358 }
359
360 static
361 void bt_ctf_field_type_init(struct bt_ctf_field_type *type, int init_bo)
362 {
363 enum ctf_type_id type_id = type->declaration->id;
364
365 assert(type && (type_id > CTF_TYPE_UNKNOWN) &&
366 (type_id < NR_CTF_TYPES));
367
368 bt_object_init(type, bt_ctf_field_type_destroy);
369 type->freeze = type_freeze_funcs[type_id];
370 type->serialize = type_serialize_funcs[type_id];
371
372 if (init_bo) {
373 int ret = bt_ctf_field_type_set_byte_order(type,
374 BT_CTF_BYTE_ORDER_NATIVE);
375 assert(!ret);
376 }
377
378 type->declaration->alignment = 1;
379 }
380
381 static
382 int add_structure_field(GPtrArray *fields,
383 GHashTable *field_name_to_index,
384 struct bt_ctf_field_type *field_type,
385 const char *field_name)
386 {
387 int ret = 0;
388 GQuark name_quark = g_quark_from_string(field_name);
389 struct structure_field *field;
390
391 /* Make sure structure does not contain a field of the same name */
392 if (g_hash_table_lookup_extended(field_name_to_index,
393 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
394 ret = -1;
395 goto end;
396 }
397
398 field = g_new0(struct structure_field, 1);
399 if (!field) {
400 ret = -1;
401 goto end;
402 }
403
404 bt_get(field_type);
405 field->name = name_quark;
406 field->type = field_type;
407 g_hash_table_insert(field_name_to_index,
408 (gpointer) (unsigned long) name_quark,
409 (gpointer) (unsigned long) fields->len);
410 g_ptr_array_add(fields, field);
411 end:
412 return ret;
413 }
414
415 static
416 void bt_ctf_field_type_destroy(struct bt_object *obj)
417 {
418 struct bt_ctf_field_type *type;
419 enum ctf_type_id type_id;
420
421 type = container_of(obj, struct bt_ctf_field_type, base);
422 type_id = type->declaration->id;
423 if (type_id <= CTF_TYPE_UNKNOWN ||
424 type_id >= NR_CTF_TYPES) {
425 return;
426 }
427
428 type_destroy_funcs[type_id](type);
429 }
430
431 static
432 int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type)
433 {
434 int ret = 0;
435
436 struct bt_ctf_field_type_integer *integer =
437 container_of(type, struct bt_ctf_field_type_integer,
438 parent);
439
440 if (integer->mapped_clock && integer->declaration.signedness) {
441 ret = -1;
442 goto end;
443 }
444
445 end:
446 return ret;
447 }
448
449 static
450 int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
451 {
452 int ret = 0;
453
454 struct bt_ctf_field_type_enumeration *enumeration =
455 container_of(type, struct bt_ctf_field_type_enumeration,
456 parent);
457 struct bt_ctf_field_type *container_type =
458 bt_ctf_field_type_enumeration_get_container_type(type);
459
460 if (!container_type) {
461 ret = -1;
462 goto end;
463 }
464
465 ret = bt_ctf_field_type_validate(container_type);
466 if (ret) {
467 goto end;
468 }
469
470 /* Ensure enum has entries */
471 ret = enumeration->entries->len ? 0 : -1;
472
473 end:
474 BT_PUT(container_type);
475 return ret;
476 }
477
478 static
479 int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type)
480 {
481 int ret = 0;
482 struct bt_ctf_field_type *element_type = NULL;
483 struct bt_ctf_field_type_sequence *sequence =
484 container_of(type, struct bt_ctf_field_type_sequence,
485 parent);
486
487 /* Length field name should be set at this point */
488 if (sequence->length_field_name->len == 0) {
489 ret = -1;
490 goto end;
491 }
492
493 element_type = bt_ctf_field_type_sequence_get_element_type(type);
494 if (!element_type) {
495 ret = -1;
496 goto end;
497 }
498
499 ret = bt_ctf_field_type_validate(element_type);
500
501 end:
502 BT_PUT(element_type);
503
504 return ret;
505 }
506
507 static
508 int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type)
509 {
510 int ret = 0;
511 struct bt_ctf_field_type *element_type = NULL;
512
513 element_type = bt_ctf_field_type_array_get_element_type(type);
514 if (!element_type) {
515 ret = -1;
516 goto end;
517 }
518
519 ret = bt_ctf_field_type_validate(element_type);
520
521 end:
522 BT_PUT(element_type);
523
524 return ret;
525 }
526
527 static
528 int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type)
529 {
530 int ret = 0;
531 struct bt_ctf_field_type *child_type = NULL;
532 int field_count = bt_ctf_field_type_structure_get_field_count(type);
533 int i;
534
535 if (field_count < 0) {
536 ret = -1;
537 goto end;
538 }
539
540 for (i = 0; i < field_count; ++i) {
541 ret = bt_ctf_field_type_structure_get_field(type,
542 NULL, &child_type, i);
543 if (ret) {
544 goto end;
545 }
546
547 ret = bt_ctf_field_type_validate(child_type);
548 if (ret) {
549 goto end;
550 }
551
552 BT_PUT(child_type);
553 }
554
555 end:
556 BT_PUT(child_type);
557
558 return ret;
559 }
560
561 static
562 int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type)
563 {
564 int ret = 0;
565 int field_count;
566 struct bt_ctf_field_type *child_type = NULL;
567 struct bt_ctf_field_type_variant *variant =
568 container_of(type, struct bt_ctf_field_type_variant,
569 parent);
570 int i;
571 int tag_mappings_count;
572
573 if (variant->tag_name->len == 0 || !variant->tag) {
574 ret = -1;
575 goto end;
576 }
577
578 tag_mappings_count =
579 bt_ctf_field_type_enumeration_get_mapping_count(
580 (struct bt_ctf_field_type *) variant->tag);
581
582 if (tag_mappings_count != variant->fields->len) {
583 ret = -1;
584 goto end;
585 }
586
587 for (i = 0; i < tag_mappings_count; ++i) {
588 const char *label;
589 int64_t range_start, range_end;
590 struct bt_ctf_field_type *ft;
591
592 ret = bt_ctf_field_type_enumeration_get_mapping(
593 (struct bt_ctf_field_type *) variant->tag,
594 i, &label, &range_start, &range_end);
595 if (ret) {
596 goto end;
597 }
598 if (!label) {
599 ret = -1;
600 goto end;
601 }
602
603 ft = bt_ctf_field_type_variant_get_field_type_by_name(
604 type, label);
605 if (!ft) {
606 ret = -1;
607 goto end;
608 }
609
610 BT_PUT(ft);
611 }
612
613 field_count = bt_ctf_field_type_variant_get_field_count(type);
614 if (field_count < 0) {
615 ret = -1;
616 goto end;
617 }
618
619 for (i = 0; i < field_count; ++i) {
620 ret = bt_ctf_field_type_variant_get_field(type,
621 NULL, &child_type, i);
622 if (ret) {
623 goto end;
624 }
625
626 ret = bt_ctf_field_type_validate(child_type);
627 if (ret) {
628 goto end;
629 }
630
631 BT_PUT(child_type);
632 }
633
634 end:
635 BT_PUT(child_type);
636
637 return ret;
638 }
639
640 /*
641 * This function validates a given field type without considering
642 * where this field type is located. It only validates the properties
643 * of the given field type and the properties of its children if
644 * applicable.
645 */
646 BT_HIDDEN
647 int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
648 {
649 int ret = 0;
650 enum ctf_type_id id = bt_ctf_field_type_get_type_id(type);
651
652 if (!type) {
653 ret = -1;
654 goto end;
655 }
656
657 if (type->valid) {
658 /* Already marked as valid */
659 goto end;
660 }
661
662 if (type_validate_funcs[id]) {
663 ret = type_validate_funcs[id](type);
664 }
665
666 if (!ret && type->frozen) {
667 /* Field type is valid */
668 type->valid = 1;
669 }
670
671 end:
672 return ret;
673 }
674
675 struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
676 {
677 struct bt_ctf_field_type_integer *integer =
678 g_new0(struct bt_ctf_field_type_integer, 1);
679
680 if (!integer || size == 0 || size > 64) {
681 return NULL;
682 }
683
684 integer->parent.declaration = &integer->declaration.p;
685 integer->parent.declaration->id = CTF_TYPE_INTEGER;
686 integer->declaration.len = size;
687 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
688 integer->declaration.encoding = BT_CTF_STRING_ENCODING_NONE;
689 bt_ctf_field_type_init(&integer->parent, TRUE);
690 return &integer->parent;
691 }
692
693 BT_HIDDEN
694 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
695 {
696 int ret = 0;
697 struct bt_ctf_field_type_integer *integer;
698
699 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
700 ret = -1;
701 goto end;
702 }
703
704 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
705 ret = (int) integer->declaration.len;
706 end:
707 return ret;
708 }
709
710 int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
711 {
712 int ret = 0;
713 struct bt_ctf_field_type_integer *integer;
714
715 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
716 ret = -1;
717 goto end;
718 }
719
720 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
721 ret = integer->declaration.signedness;
722 end:
723 return ret;
724 }
725
726 int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
727 int is_signed)
728 {
729 int ret = 0;
730 struct bt_ctf_field_type_integer *integer;
731
732 if (!type || type->frozen ||
733 type->declaration->id != CTF_TYPE_INTEGER) {
734 ret = -1;
735 goto end;
736 }
737
738 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
739 integer->declaration.signedness = !!is_signed;
740 end:
741 return ret;
742 }
743
744 BT_HIDDEN
745 enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
746 struct bt_ctf_field_type *type)
747 {
748 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
749 struct bt_ctf_field_type_integer *integer;
750
751 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
752 goto end;
753 }
754
755 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
756 ret = integer->declaration.base;
757 end:
758 return ret;
759 }
760
761 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
762 enum bt_ctf_integer_base base)
763 {
764 int ret = 0;
765
766 if (!type || type->frozen ||
767 type->declaration->id != CTF_TYPE_INTEGER) {
768 ret = -1;
769 goto end;
770 }
771
772 switch (base) {
773 case BT_CTF_INTEGER_BASE_BINARY:
774 case BT_CTF_INTEGER_BASE_OCTAL:
775 case BT_CTF_INTEGER_BASE_DECIMAL:
776 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
777 {
778 struct bt_ctf_field_type_integer *integer = container_of(type,
779 struct bt_ctf_field_type_integer, parent);
780 integer->declaration.base = base;
781 break;
782 }
783 default:
784 ret = -1;
785 }
786 end:
787 return ret;
788 }
789
790 BT_HIDDEN
791 enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
792 struct bt_ctf_field_type *type)
793 {
794 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
795 struct bt_ctf_field_type_integer *integer;
796
797 if (!type || type->declaration->id != CTF_TYPE_INTEGER) {
798 goto end;
799 }
800
801 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
802 ret = integer->declaration.encoding;
803 end:
804 return ret;
805 }
806
807 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
808 enum bt_ctf_string_encoding encoding)
809 {
810 int ret = 0;
811 struct bt_ctf_field_type_integer *integer;
812
813 if (!type || type->frozen ||
814 (type->declaration->id != CTF_TYPE_INTEGER) ||
815 (encoding < BT_CTF_STRING_ENCODING_NONE) ||
816 (encoding >= BT_CTF_STRING_ENCODING_UNKNOWN)) {
817 ret = -1;
818 goto end;
819 }
820
821 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
822 integer->declaration.encoding = encoding;
823 end:
824 return ret;
825 }
826
827 BT_HIDDEN
828 struct bt_ctf_clock *bt_ctf_field_type_integer_get_mapped_clock(
829 struct bt_ctf_field_type *type)
830 {
831 struct bt_ctf_field_type_integer *integer;
832 struct bt_ctf_clock *clock = NULL;
833
834 if (!type) {
835 goto end;
836 }
837
838 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
839 clock = integer->mapped_clock;
840 bt_get(clock);
841 end:
842 return clock;
843 }
844
845 BT_HIDDEN
846 int bt_ctf_field_type_integer_set_mapped_clock(
847 struct bt_ctf_field_type *type,
848 struct bt_ctf_clock *clock)
849 {
850 struct bt_ctf_field_type_integer *integer;
851 int ret = 0;
852
853 if (!type || type->frozen) {
854 ret = -1;
855 goto end;
856 }
857
858 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
859 bt_put(integer->mapped_clock);
860 bt_get(clock);
861 integer->mapped_clock = clock;
862 end:
863 return ret;
864 }
865
866 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
867 struct bt_ctf_field_type *integer_container_type)
868 {
869 struct bt_ctf_field_type_enumeration *enumeration = NULL;
870
871 if (!integer_container_type) {
872 goto error;
873 }
874
875 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
876 goto error;
877 }
878
879 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
880 if (!enumeration) {
881 goto error;
882 }
883
884 enumeration->parent.declaration = &enumeration->declaration.p;
885 enumeration->parent.declaration->id = CTF_TYPE_ENUM;
886 bt_get(integer_container_type);
887 enumeration->container = integer_container_type;
888 enumeration->entries = g_ptr_array_new_with_free_func(
889 (GDestroyNotify)destroy_enumeration_mapping);
890 bt_ctf_field_type_init(&enumeration->parent, FALSE);
891 return &enumeration->parent;
892 error:
893 g_free(enumeration);
894 return NULL;
895 }
896
897 BT_HIDDEN
898 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
899 struct bt_ctf_field_type *type)
900 {
901 struct bt_ctf_field_type *container_type = NULL;
902 struct bt_ctf_field_type_enumeration *enumeration_type;
903
904 if (!type) {
905 goto end;
906 }
907
908 if (type->declaration->id != CTF_TYPE_ENUM) {
909 goto end;
910 }
911
912 enumeration_type = container_of(type,
913 struct bt_ctf_field_type_enumeration, parent);
914 container_type = enumeration_type->container;
915 bt_get(container_type);
916 end:
917 return container_type;
918 }
919
920 int bt_ctf_field_type_enumeration_add_mapping(
921 struct bt_ctf_field_type *type, const char *string,
922 int64_t range_start, int64_t range_end)
923 {
924 int ret = 0;
925 GQuark mapping_name;
926 struct enumeration_mapping *mapping;
927 struct bt_ctf_field_type_enumeration *enumeration;
928 struct range_overlap_query query;
929 char *escaped_string;
930
931 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
932 type->frozen ||
933 (range_end < range_start)) {
934 ret = -1;
935 goto end;
936 }
937
938 if (!string || strlen(string) == 0) {
939 ret = -1;
940 goto end;
941 }
942
943 escaped_string = g_strescape(string, NULL);
944 if (!escaped_string) {
945 ret = -1;
946 goto end;
947 }
948
949 mapping_name = g_quark_from_string(escaped_string);
950 query = (struct range_overlap_query) {
951 .range_start._signed = range_start,
952 .range_end._signed = range_end,
953 .mapping_name = mapping_name,
954 .overlaps = 0 };
955 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
956 parent);
957
958 /* Check that the range does not overlap with one already present */
959 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
960 if (query.overlaps) {
961 ret = -1;
962 goto error_free;
963 }
964
965 mapping = g_new(struct enumeration_mapping, 1);
966 if (!mapping) {
967 ret = -1;
968 goto error_free;
969 }
970
971 *mapping = (struct enumeration_mapping) {
972 .range_start._signed = range_start,
973 .range_end._signed = range_end, .string = mapping_name};
974 g_ptr_array_add(enumeration->entries, mapping);
975 g_ptr_array_sort(enumeration->entries,
976 (GCompareFunc)compare_enumeration_mappings_signed);
977 error_free:
978 free(escaped_string);
979 end:
980 return ret;
981 }
982
983 BT_HIDDEN
984 int bt_ctf_field_type_enumeration_add_mapping_unsigned(
985 struct bt_ctf_field_type *type, const char *string,
986 uint64_t range_start, uint64_t range_end)
987 {
988 int ret = 0;
989 GQuark mapping_name;
990 struct enumeration_mapping *mapping;
991 struct bt_ctf_field_type_enumeration *enumeration;
992 struct range_overlap_query query;
993 char *escaped_string;
994
995 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
996 type->frozen ||
997 (range_end < range_start)) {
998 ret = -1;
999 goto end;
1000 }
1001
1002 if (!string || strlen(string) == 0) {
1003 ret = -1;
1004 goto end;
1005 }
1006
1007 escaped_string = g_strescape(string, NULL);
1008 if (!escaped_string) {
1009 ret = -1;
1010 goto end;
1011 }
1012
1013 mapping_name = g_quark_from_string(escaped_string);
1014 query = (struct range_overlap_query) {
1015 .range_start._unsigned = range_start,
1016 .range_end._unsigned = range_end,
1017 .mapping_name = mapping_name,
1018 .overlaps = 0 };
1019 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1020 parent);
1021
1022 /* Check that the range does not overlap with one already present */
1023 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap_unsigned,
1024 &query);
1025 if (query.overlaps) {
1026 ret = -1;
1027 goto error_free;
1028 }
1029
1030 mapping = g_new(struct enumeration_mapping, 1);
1031 if (!mapping) {
1032 ret = -1;
1033 goto error_free;
1034 }
1035
1036 *mapping = (struct enumeration_mapping) {
1037 .range_start._unsigned = range_start,
1038 .range_end._unsigned = range_end, .string = mapping_name};
1039 g_ptr_array_add(enumeration->entries, mapping);
1040 g_ptr_array_sort(enumeration->entries,
1041 (GCompareFunc)compare_enumeration_mappings_unsigned);
1042 error_free:
1043 free(escaped_string);
1044 end:
1045 return ret;
1046 }
1047
1048 BT_HIDDEN
1049 const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
1050 struct bt_ctf_field_type_enumeration *enumeration_type,
1051 uint64_t value)
1052 {
1053 const char *name = NULL;
1054 struct range_overlap_query query =
1055 (struct range_overlap_query) {
1056 .range_start._unsigned = value,
1057 .range_end._unsigned = value,
1058 .overlaps = 0 };
1059
1060 g_ptr_array_foreach(enumeration_type->entries,
1061 check_ranges_overlap_unsigned,
1062 &query);
1063 if (!query.overlaps) {
1064 goto end;
1065 }
1066
1067 name = g_quark_to_string(query.mapping_name);
1068 end:
1069 return name;
1070 }
1071
1072 const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
1073 struct bt_ctf_field_type_enumeration *enumeration_type,
1074 int64_t value)
1075 {
1076 const char *name = NULL;
1077 struct range_overlap_query query =
1078 (struct range_overlap_query) {
1079 .range_start._signed = value,
1080 .range_end._signed = value,
1081 .overlaps = 0 };
1082
1083 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
1084 &query);
1085 if (!query.overlaps) {
1086 goto end;
1087 }
1088
1089 name = g_quark_to_string(query.mapping_name);
1090 end:
1091 return name;
1092 }
1093
1094 int bt_ctf_field_type_enumeration_get_mapping_count(
1095 struct bt_ctf_field_type *type)
1096 {
1097 int ret = 0;
1098 struct bt_ctf_field_type_enumeration *enumeration;
1099
1100 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
1101 ret = -1;
1102 goto end;
1103 }
1104
1105 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1106 parent);
1107 ret = (int) enumeration->entries->len;
1108 end:
1109 return ret;
1110 }
1111
1112 static inline
1113 struct enumeration_mapping *get_enumeration_mapping(
1114 struct bt_ctf_field_type *type, int index)
1115 {
1116 struct enumeration_mapping *mapping = NULL;
1117 struct bt_ctf_field_type_enumeration *enumeration;
1118
1119 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1120 parent);
1121 if (index >= enumeration->entries->len) {
1122 goto end;
1123 }
1124
1125 mapping = g_ptr_array_index(enumeration->entries, index);
1126 end:
1127 return mapping;
1128 }
1129
1130 BT_HIDDEN
1131 int bt_ctf_field_type_enumeration_get_mapping(
1132 struct bt_ctf_field_type *type, int index,
1133 const char **string, int64_t *range_start, int64_t *range_end)
1134 {
1135 struct enumeration_mapping *mapping;
1136 int ret = 0;
1137
1138 if (!type || index < 0 || !string || !range_start || !range_end ||
1139 (type->declaration->id != CTF_TYPE_ENUM)) {
1140 ret = -1;
1141 goto end;
1142 }
1143
1144 mapping = get_enumeration_mapping(type, index);
1145 if (!mapping) {
1146 ret = -1;
1147 goto end;
1148 }
1149
1150 *string = g_quark_to_string(mapping->string);
1151 *range_start = mapping->range_start._signed;
1152 *range_end = mapping->range_end._signed;
1153 end:
1154 return ret;
1155 }
1156
1157 BT_HIDDEN
1158 int bt_ctf_field_type_enumeration_get_mapping_unsigned(
1159 struct bt_ctf_field_type *type, int index,
1160 const char **string, uint64_t *range_start, uint64_t *range_end)
1161 {
1162 struct enumeration_mapping *mapping;
1163 int ret = 0;
1164
1165 if (!type || index < 0 || !string || !range_start || !range_end ||
1166 (type->declaration->id != CTF_TYPE_ENUM)) {
1167 ret = -1;
1168 goto end;
1169 }
1170
1171 mapping = get_enumeration_mapping(type, index);
1172 if (!mapping) {
1173 ret = -1;
1174 goto end;
1175 }
1176
1177 *string = g_quark_to_string(mapping->string);
1178 *range_start = mapping->range_start._unsigned;
1179 *range_end = mapping->range_end._unsigned;
1180 end:
1181 return ret;
1182 }
1183
1184 BT_HIDDEN
1185 int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
1186 struct bt_ctf_field_type *type, const char *name)
1187 {
1188 GQuark name_quark;
1189 struct bt_ctf_field_type_enumeration *enumeration;
1190 int i, ret = 0;
1191
1192 if (!type || !name ||
1193 (type->declaration->id != CTF_TYPE_ENUM)) {
1194 ret = -1;
1195 goto end;
1196 }
1197
1198 name_quark = g_quark_try_string(name);
1199 if (!name_quark) {
1200 ret = -1;
1201 goto end;
1202 }
1203
1204 enumeration = container_of(type,
1205 struct bt_ctf_field_type_enumeration, parent);
1206 for (i = 0; i < enumeration->entries->len; i++) {
1207 struct enumeration_mapping *mapping =
1208 get_enumeration_mapping(type, i);
1209
1210 if (mapping->string == name_quark) {
1211 ret = i;
1212 goto end;
1213 }
1214 }
1215
1216 ret = -1;
1217 end:
1218 return ret;
1219 }
1220
1221 BT_HIDDEN
1222 int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
1223 struct bt_ctf_field_type *type, int64_t value)
1224 {
1225 struct bt_ctf_field_type_enumeration *enumeration;
1226 int i, ret = 0;
1227
1228 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
1229 ret = -1;
1230 goto end;
1231 }
1232
1233 enumeration = container_of(type,
1234 struct bt_ctf_field_type_enumeration, parent);
1235 for (i = 0; i < enumeration->entries->len; i++) {
1236 struct enumeration_mapping *mapping =
1237 get_enumeration_mapping(type, i);
1238
1239 if (value >= mapping->range_start._signed &&
1240 value <= mapping->range_end._signed) {
1241 ret = i;
1242 goto end;
1243 }
1244 }
1245
1246 ret = -1;
1247 end:
1248 return ret;
1249 }
1250
1251 BT_HIDDEN
1252 int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
1253 struct bt_ctf_field_type *type, uint64_t value)
1254 {
1255 struct bt_ctf_field_type_enumeration *enumeration;
1256 int i, ret = 0;
1257
1258 if (!type || (type->declaration->id != CTF_TYPE_ENUM)) {
1259 ret = -1;
1260 goto end;
1261 }
1262
1263 enumeration = container_of(type,
1264 struct bt_ctf_field_type_enumeration, parent);
1265 for (i = 0; i < enumeration->entries->len; i++) {
1266 struct enumeration_mapping *mapping =
1267 get_enumeration_mapping(type, i);
1268
1269 if (value >= mapping->range_start._unsigned &&
1270 value <= mapping->range_end._unsigned) {
1271 ret = i;
1272 goto end;
1273 }
1274 }
1275
1276 ret = -1;
1277 end:
1278 return ret;
1279 }
1280
1281 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
1282 {
1283 struct bt_ctf_field_type_floating_point *floating_point =
1284 g_new0(struct bt_ctf_field_type_floating_point, 1);
1285
1286 if (!floating_point) {
1287 goto end;
1288 }
1289
1290 floating_point->declaration.sign = &floating_point->sign;
1291 floating_point->declaration.mantissa = &floating_point->mantissa;
1292 floating_point->declaration.exp = &floating_point->exp;
1293 floating_point->sign.len = 1;
1294 floating_point->parent.declaration = &floating_point->declaration.p;
1295 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
1296 floating_point->declaration.exp->len =
1297 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
1298 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
1299 floating_point->sign.p.alignment = 1;
1300 floating_point->mantissa.p.alignment = 1;
1301 floating_point->exp.p.alignment = 1;
1302
1303 bt_ctf_field_type_init(&floating_point->parent, TRUE);
1304 end:
1305 return floating_point ? &floating_point->parent : NULL;
1306 }
1307
1308 BT_HIDDEN
1309 int bt_ctf_field_type_floating_point_get_exponent_digits(
1310 struct bt_ctf_field_type *type)
1311 {
1312 int ret = 0;
1313 struct bt_ctf_field_type_floating_point *floating_point;
1314
1315 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1316 ret = -1;
1317 goto end;
1318 }
1319
1320 floating_point = container_of(type,
1321 struct bt_ctf_field_type_floating_point, parent);
1322 ret = (int) floating_point->declaration.exp->len;
1323 end:
1324 return ret;
1325 }
1326
1327 int bt_ctf_field_type_floating_point_set_exponent_digits(
1328 struct bt_ctf_field_type *type,
1329 unsigned int exponent_digits)
1330 {
1331 int ret = 0;
1332 struct bt_ctf_field_type_floating_point *floating_point;
1333
1334 if (!type || type->frozen ||
1335 (type->declaration->id != CTF_TYPE_FLOAT)) {
1336 ret = -1;
1337 goto end;
1338 }
1339
1340 floating_point = container_of(type,
1341 struct bt_ctf_field_type_floating_point, parent);
1342 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1343 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1344 (exponent_digits !=
1345 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
1346 ret = -1;
1347 goto end;
1348 }
1349
1350 floating_point->declaration.exp->len = exponent_digits;
1351 end:
1352 return ret;
1353 }
1354
1355 BT_HIDDEN
1356 int bt_ctf_field_type_floating_point_get_mantissa_digits(
1357 struct bt_ctf_field_type *type)
1358 {
1359 int ret = 0;
1360 struct bt_ctf_field_type_floating_point *floating_point;
1361
1362 if (!type || (type->declaration->id != CTF_TYPE_FLOAT)) {
1363 ret = -1;
1364 goto end;
1365 }
1366
1367 floating_point = container_of(type,
1368 struct bt_ctf_field_type_floating_point, parent);
1369 ret = (int) floating_point->mantissa.len + 1;
1370 end:
1371 return ret;
1372 }
1373
1374 int bt_ctf_field_type_floating_point_set_mantissa_digits(
1375 struct bt_ctf_field_type *type,
1376 unsigned int mantissa_digits)
1377 {
1378 int ret = 0;
1379 struct bt_ctf_field_type_floating_point *floating_point;
1380
1381 if (!type || type->frozen ||
1382 (type->declaration->id != CTF_TYPE_FLOAT)) {
1383 ret = -1;
1384 goto end;
1385 }
1386
1387 floating_point = container_of(type,
1388 struct bt_ctf_field_type_floating_point, parent);
1389
1390 if ((mantissa_digits != FLT_MANT_DIG) &&
1391 (mantissa_digits != DBL_MANT_DIG) &&
1392 (mantissa_digits != LDBL_MANT_DIG)) {
1393 ret = -1;
1394 goto end;
1395 }
1396
1397 floating_point->declaration.mantissa->len = mantissa_digits - 1;
1398 end:
1399 return ret;
1400 }
1401
1402 struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1403 {
1404 struct bt_ctf_field_type_structure *structure =
1405 g_new0(struct bt_ctf_field_type_structure, 1);
1406
1407 if (!structure) {
1408 goto error;
1409 }
1410
1411 structure->parent.declaration = &structure->declaration.p;
1412 structure->parent.declaration->id = CTF_TYPE_STRUCT;
1413 structure->fields = g_ptr_array_new_with_free_func(
1414 (GDestroyNotify)destroy_structure_field);
1415 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
1416 bt_ctf_field_type_init(&structure->parent, TRUE);
1417 return &structure->parent;
1418 error:
1419 return NULL;
1420 }
1421
1422 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
1423 struct bt_ctf_field_type *field_type,
1424 const char *field_name)
1425 {
1426 int ret = 0;
1427 struct bt_ctf_field_type_structure *structure;
1428
1429 if (!type || !field_type || type->frozen ||
1430 bt_ctf_validate_identifier(field_name) ||
1431 (type->declaration->id != CTF_TYPE_STRUCT)) {
1432 ret = -1;
1433 goto end;
1434 }
1435
1436 structure = container_of(type,
1437 struct bt_ctf_field_type_structure, parent);
1438 if (add_structure_field(structure->fields,
1439 structure->field_name_to_index, field_type, field_name)) {
1440 ret = -1;
1441 goto end;
1442 }
1443 end:
1444 return ret;
1445 }
1446
1447 BT_HIDDEN
1448 int bt_ctf_field_type_structure_get_field_count(
1449 struct bt_ctf_field_type *type)
1450 {
1451 int ret = 0;
1452 struct bt_ctf_field_type_structure *structure;
1453
1454 if (!type || (type->declaration->id != CTF_TYPE_STRUCT)) {
1455 ret = -1;
1456 goto end;
1457 }
1458
1459 structure = container_of(type, struct bt_ctf_field_type_structure,
1460 parent);
1461 ret = (int) structure->fields->len;
1462 end:
1463 return ret;
1464 }
1465
1466 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1467 const char **field_name, struct bt_ctf_field_type **field_type,
1468 int index)
1469 {
1470 struct bt_ctf_field_type_structure *structure;
1471 struct structure_field *field;
1472 int ret = 0;
1473
1474 if (!type || index < 0 ||
1475 (type->declaration->id != CTF_TYPE_STRUCT)) {
1476 ret = -1;
1477 goto end;
1478 }
1479
1480 structure = container_of(type, struct bt_ctf_field_type_structure,
1481 parent);
1482 if (index >= structure->fields->len) {
1483 ret = -1;
1484 goto end;
1485 }
1486
1487 field = g_ptr_array_index(structure->fields, index);
1488 if (field_type) {
1489 *field_type = field->type;
1490 bt_get(field->type);
1491 }
1492 if (field_name) {
1493 *field_name = g_quark_to_string(field->name);
1494 }
1495 end:
1496 return ret;
1497 }
1498
1499 BT_HIDDEN
1500 struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1501 struct bt_ctf_field_type *type,
1502 const char *name)
1503 {
1504 size_t index;
1505 GQuark name_quark;
1506 struct structure_field *field;
1507 struct bt_ctf_field_type_structure *structure;
1508 struct bt_ctf_field_type *field_type = NULL;
1509
1510 if (!type || !name) {
1511 goto end;
1512 }
1513
1514 name_quark = g_quark_try_string(name);
1515 if (!name_quark) {
1516 goto end;
1517 }
1518
1519 structure = container_of(type, struct bt_ctf_field_type_structure,
1520 parent);
1521 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1522 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1523 goto end;
1524 }
1525
1526 field = structure->fields->pdata[index];
1527 field_type = field->type;
1528 bt_get(field_type);
1529 end:
1530 return field_type;
1531 }
1532
1533 struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1534 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1535 {
1536 struct bt_ctf_field_type_variant *variant = NULL;
1537
1538 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
1539 goto error;
1540 }
1541
1542 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1543 if (!variant) {
1544 goto error;
1545 }
1546
1547 variant->parent.declaration = &variant->declaration.p;
1548 variant->parent.declaration->id = CTF_TYPE_VARIANT;
1549 variant->tag_name = g_string_new(tag_name);
1550 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1551 variant->fields = g_ptr_array_new_with_free_func(
1552 (GDestroyNotify) destroy_structure_field);
1553 if (enum_tag) {
1554 bt_get(enum_tag);
1555 variant->tag = container_of(enum_tag,
1556 struct bt_ctf_field_type_enumeration, parent);
1557 }
1558
1559 bt_ctf_field_type_init(&variant->parent, TRUE);
1560 /* A variant's alignment is undefined */
1561 variant->parent.declaration->alignment = 0;
1562 return &variant->parent;
1563 error:
1564 return NULL;
1565 }
1566
1567 BT_HIDDEN
1568 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1569 struct bt_ctf_field_type *type)
1570 {
1571 struct bt_ctf_field_type_variant *variant;
1572 struct bt_ctf_field_type *tag_type = NULL;
1573
1574 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1575 goto end;
1576 }
1577
1578 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1579 if (!variant->tag) {
1580 goto end;
1581 }
1582
1583 tag_type = &variant->tag->parent;
1584 bt_get(tag_type);
1585 end:
1586 return tag_type;
1587 }
1588
1589 BT_HIDDEN
1590 const char *bt_ctf_field_type_variant_get_tag_name(
1591 struct bt_ctf_field_type *type)
1592 {
1593 struct bt_ctf_field_type_variant *variant;
1594 const char *tag_name = NULL;
1595
1596 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1597 goto end;
1598 }
1599
1600 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1601 if (variant->tag_name->len == 0) {
1602 goto end;
1603 }
1604
1605 tag_name = variant->tag_name->str;
1606 end:
1607 return tag_name;
1608 }
1609
1610 BT_HIDDEN
1611 int bt_ctf_field_type_variant_set_tag_name(
1612 struct bt_ctf_field_type *type, const char *name)
1613 {
1614 int ret = 0;
1615 struct bt_ctf_field_type_variant *variant;
1616
1617 if (!type || type->frozen ||
1618 (type->declaration->id != CTF_TYPE_VARIANT) ||
1619 bt_ctf_validate_identifier(name)) {
1620 ret = -1;
1621 goto end;
1622 }
1623
1624 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1625 g_string_assign(variant->tag_name, name);
1626 end:
1627 return ret;
1628 }
1629
1630 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1631 struct bt_ctf_field_type *field_type,
1632 const char *field_name)
1633 {
1634 size_t i;
1635 int ret = 0;
1636 struct bt_ctf_field_type_variant *variant;
1637 GQuark field_name_quark = g_quark_from_string(field_name);
1638
1639 if (!type || !field_type || type->frozen ||
1640 bt_ctf_validate_identifier(field_name) ||
1641 (type->declaration->id != CTF_TYPE_VARIANT)) {
1642 ret = -1;
1643 goto end;
1644 }
1645
1646 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1647
1648 /* The user has explicitly provided a tag; validate against it. */
1649 if (variant->tag) {
1650 int name_found = 0;
1651
1652 /* Make sure this name is present in the enum tag */
1653 for (i = 0; i < variant->tag->entries->len; i++) {
1654 struct enumeration_mapping *mapping =
1655 g_ptr_array_index(variant->tag->entries, i);
1656
1657 if (mapping->string == field_name_quark) {
1658 name_found = 1;
1659 break;
1660 }
1661 }
1662
1663 if (!name_found) {
1664 /* Validation failed */
1665 ret = -1;
1666 goto end;
1667 }
1668 }
1669
1670 if (add_structure_field(variant->fields, variant->field_name_to_index,
1671 field_type, field_name)) {
1672 ret = -1;
1673 goto end;
1674 }
1675 end:
1676 return ret;
1677 }
1678
1679 BT_HIDDEN
1680 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1681 struct bt_ctf_field_type *type,
1682 const char *field_name)
1683 {
1684 size_t index;
1685 GQuark name_quark;
1686 struct structure_field *field;
1687 struct bt_ctf_field_type_variant *variant;
1688 struct bt_ctf_field_type *field_type = NULL;
1689
1690 if (!type || !field_name) {
1691 goto end;
1692 }
1693
1694 name_quark = g_quark_try_string(field_name);
1695 if (!name_quark) {
1696 goto end;
1697 }
1698
1699 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1700 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1701 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1702 goto end;
1703 }
1704
1705 field = g_ptr_array_index(variant->fields, index);
1706 field_type = field->type;
1707 bt_get(field_type);
1708 end:
1709 return field_type;
1710 }
1711
1712 BT_HIDDEN
1713 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1714 struct bt_ctf_field_type *type,
1715 struct bt_ctf_field *tag)
1716 {
1717 const char *enum_value;
1718 struct bt_ctf_field_type *field_type = NULL;
1719
1720 if (!type || !tag || type->declaration->id != CTF_TYPE_VARIANT) {
1721 goto end;
1722 }
1723
1724 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1725 if (!enum_value) {
1726 goto end;
1727 }
1728
1729 /* Already increments field_type's reference count */
1730 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1731 type, enum_value);
1732 end:
1733 return field_type;
1734 }
1735
1736 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1737 {
1738 int ret = 0;
1739 struct bt_ctf_field_type_variant *variant;
1740
1741 if (!type || (type->declaration->id != CTF_TYPE_VARIANT)) {
1742 ret = -1;
1743 goto end;
1744 }
1745
1746 variant = container_of(type, struct bt_ctf_field_type_variant,
1747 parent);
1748 ret = (int) variant->fields->len;
1749 end:
1750 return ret;
1751
1752 }
1753
1754 BT_HIDDEN
1755 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1756 const char **field_name, struct bt_ctf_field_type **field_type,
1757 int index)
1758 {
1759 struct bt_ctf_field_type_variant *variant;
1760 struct structure_field *field;
1761 int ret = 0;
1762
1763 if (!type || index < 0 ||
1764 (type->declaration->id != CTF_TYPE_VARIANT)) {
1765 ret = -1;
1766 goto end;
1767 }
1768
1769 variant = container_of(type, struct bt_ctf_field_type_variant,
1770 parent);
1771 if (index >= variant->fields->len) {
1772 ret = -1;
1773 goto end;
1774 }
1775
1776 field = g_ptr_array_index(variant->fields, index);
1777 if (field_type) {
1778 *field_type = field->type;
1779 bt_get(field->type);
1780 }
1781 if (field_name) {
1782 *field_name = g_quark_to_string(field->name);
1783 }
1784 end:
1785 return ret;
1786 }
1787
1788 struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1789 struct bt_ctf_field_type *element_type,
1790 unsigned int length)
1791 {
1792 struct bt_ctf_field_type_array *array = NULL;
1793
1794 if (!element_type || length == 0) {
1795 goto error;
1796 }
1797
1798 array = g_new0(struct bt_ctf_field_type_array, 1);
1799 if (!array) {
1800 goto error;
1801 }
1802
1803 array->parent.declaration = &array->declaration.p;
1804 array->parent.declaration->id = CTF_TYPE_ARRAY;
1805
1806 bt_get(element_type);
1807 array->element_type = element_type;
1808 array->length = length;
1809 bt_ctf_field_type_init(&array->parent, FALSE);
1810 return &array->parent;
1811 error:
1812 return NULL;
1813 }
1814
1815 BT_HIDDEN
1816 struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1817 struct bt_ctf_field_type *type)
1818 {
1819 struct bt_ctf_field_type *ret = NULL;
1820 struct bt_ctf_field_type_array *array;
1821
1822 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1823 goto end;
1824 }
1825
1826 array = container_of(type, struct bt_ctf_field_type_array, parent);
1827 ret = array->element_type;
1828 bt_get(ret);
1829 end:
1830 return ret;
1831 }
1832
1833 BT_HIDDEN
1834 int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
1835 struct bt_ctf_field_type *element_type)
1836 {
1837 int ret = 0;
1838 struct bt_ctf_field_type_array *array;
1839
1840 if (!type || !element_type ||
1841 (type->declaration->id != CTF_TYPE_ARRAY)) {
1842 ret = -1;
1843 goto end;
1844 }
1845
1846 array = container_of(type, struct bt_ctf_field_type_array, parent);
1847
1848 if (array->element_type) {
1849 BT_PUT(array->element_type);
1850 }
1851
1852 array->element_type = element_type;
1853 bt_get(array->element_type);
1854
1855 end:
1856 return ret;
1857 }
1858
1859 BT_HIDDEN
1860 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1861 {
1862 int64_t ret;
1863 struct bt_ctf_field_type_array *array;
1864
1865 if (!type || (type->declaration->id != CTF_TYPE_ARRAY)) {
1866 ret = -1;
1867 goto end;
1868 }
1869
1870 array = container_of(type, struct bt_ctf_field_type_array, parent);
1871 ret = (int64_t) array->length;
1872 end:
1873 return ret;
1874 }
1875
1876 struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1877 struct bt_ctf_field_type *element_type,
1878 const char *length_field_name)
1879 {
1880 struct bt_ctf_field_type_sequence *sequence = NULL;
1881
1882 if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
1883 goto error;
1884 }
1885
1886 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1887 if (!sequence) {
1888 goto error;
1889 }
1890
1891 sequence->parent.declaration = &sequence->declaration.p;
1892 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
1893 bt_get(element_type);
1894 sequence->element_type = element_type;
1895 sequence->length_field_name = g_string_new(length_field_name);
1896 bt_ctf_field_type_init(&sequence->parent, FALSE);
1897 return &sequence->parent;
1898 error:
1899 return NULL;
1900 }
1901
1902 BT_HIDDEN
1903 struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1904 struct bt_ctf_field_type *type)
1905 {
1906 struct bt_ctf_field_type *ret = NULL;
1907 struct bt_ctf_field_type_sequence *sequence;
1908
1909 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1910 goto end;
1911 }
1912
1913 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1914 parent);
1915 ret = sequence->element_type;
1916 bt_get(ret);
1917 end:
1918 return ret;
1919 }
1920
1921 BT_HIDDEN
1922 int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
1923 struct bt_ctf_field_type *element_type)
1924 {
1925 int ret = 0;
1926 struct bt_ctf_field_type_sequence *sequence;
1927
1928 if (!type || !element_type ||
1929 (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1930 ret = -1;
1931 goto end;
1932 }
1933
1934 sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
1935
1936 if (sequence->element_type) {
1937 BT_PUT(sequence->element_type);
1938 }
1939
1940 sequence->element_type = element_type;
1941 bt_get(sequence->element_type);
1942
1943 end:
1944 return ret;
1945 }
1946
1947 BT_HIDDEN
1948 const char *bt_ctf_field_type_sequence_get_length_field_name(
1949 struct bt_ctf_field_type *type)
1950 {
1951 const char *ret = NULL;
1952 struct bt_ctf_field_type_sequence *sequence;
1953
1954 if (!type || (type->declaration->id != CTF_TYPE_SEQUENCE)) {
1955 goto end;
1956 }
1957
1958 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1959 parent);
1960 ret = sequence->length_field_name->str;
1961 end:
1962 return ret;
1963 }
1964
1965 struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1966 {
1967 struct bt_ctf_field_type_string *string =
1968 g_new0(struct bt_ctf_field_type_string, 1);
1969
1970 if (!string) {
1971 return NULL;
1972 }
1973
1974 string->parent.declaration = &string->declaration.p;
1975 string->parent.declaration->id = CTF_TYPE_STRING;
1976 bt_ctf_field_type_init(&string->parent, TRUE);
1977 string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
1978 string->parent.declaration->alignment = CHAR_BIT;
1979 return &string->parent;
1980 }
1981
1982 BT_HIDDEN
1983 enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1984 struct bt_ctf_field_type *type)
1985 {
1986 struct bt_ctf_field_type_string *string;
1987 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
1988
1989 if (!type || (type->declaration->id != CTF_TYPE_STRING)) {
1990 goto end;
1991 }
1992
1993 string = container_of(type, struct bt_ctf_field_type_string,
1994 parent);
1995 ret = string->declaration.encoding;
1996 end:
1997 return ret;
1998 }
1999
2000 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
2001 enum bt_ctf_string_encoding encoding)
2002 {
2003 int ret = 0;
2004 struct bt_ctf_field_type_string *string;
2005
2006 if (!type || type->declaration->id != CTF_TYPE_STRING ||
2007 (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
2008 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
2009 ret = -1;
2010 goto end;
2011 }
2012
2013 string = container_of(type, struct bt_ctf_field_type_string, parent);
2014 string->declaration.encoding = encoding;
2015 end:
2016 return ret;
2017 }
2018
2019 BT_HIDDEN
2020 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
2021 {
2022 int ret;
2023 enum ctf_type_id type_id;
2024
2025 if (!type) {
2026 ret = -1;
2027 goto end;
2028 }
2029
2030 if (type->frozen) {
2031 ret = (int) type->declaration->alignment;
2032 goto end;
2033 }
2034
2035 type_id = bt_ctf_field_type_get_type_id(type);
2036 switch (type_id) {
2037 case CTF_TYPE_SEQUENCE:
2038 {
2039 struct bt_ctf_field_type *element =
2040 bt_ctf_field_type_sequence_get_element_type(type);
2041
2042 if (!element) {
2043 ret = -1;
2044 goto end;
2045 }
2046
2047 ret = bt_ctf_field_type_get_alignment(element);
2048 bt_put(element);
2049 break;
2050 }
2051 case CTF_TYPE_ARRAY:
2052 {
2053 struct bt_ctf_field_type *element =
2054 bt_ctf_field_type_array_get_element_type(type);
2055
2056 if (!element) {
2057 ret = -1;
2058 goto end;
2059 }
2060
2061 ret = bt_ctf_field_type_get_alignment(element);
2062 bt_put(element);
2063 break;
2064 }
2065 case CTF_TYPE_STRUCT:
2066 {
2067 int i, element_count;
2068
2069 element_count = bt_ctf_field_type_structure_get_field_count(
2070 type);
2071 if (element_count < 0) {
2072 ret = element_count;
2073 goto end;
2074 }
2075
2076 for (i = 0; i < element_count; i++) {
2077 struct bt_ctf_field_type *field;
2078 int field_alignment;
2079
2080 ret = bt_ctf_field_type_structure_get_field(type, NULL,
2081 &field, i);
2082 if (ret) {
2083 goto end;
2084 }
2085
2086 assert(field);
2087 field_alignment = bt_ctf_field_type_get_alignment(
2088 field);
2089 bt_put(field);
2090 if (field_alignment < 0) {
2091 ret = field_alignment;
2092 goto end;
2093 }
2094
2095 type->declaration->alignment = MAX(field_alignment,
2096 type->declaration->alignment);
2097 }
2098 ret = (int) type->declaration->alignment;
2099 break;
2100 }
2101 case CTF_TYPE_UNKNOWN:
2102 ret = -1;
2103 break;
2104 default:
2105 ret = (int) type->declaration->alignment;
2106 break;
2107 }
2108 end:
2109 return ret;
2110 }
2111
2112 static inline
2113 int is_power_of_two(unsigned int value)
2114 {
2115 return ((value & (value - 1)) == 0) && value > 0;
2116 }
2117
2118 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
2119 unsigned int alignment)
2120 {
2121 int ret = 0;
2122 enum ctf_type_id type_id;
2123
2124 /* Alignment must be a power of two */
2125 if (!type || type->frozen || !is_power_of_two(alignment)) {
2126 ret = -1;
2127 goto end;
2128 }
2129
2130 type_id = bt_ctf_field_type_get_type_id(type);
2131 if (type_id == CTF_TYPE_UNKNOWN) {
2132 ret = -1;
2133 goto end;
2134 }
2135
2136 if (type->declaration->id == CTF_TYPE_STRING &&
2137 alignment != CHAR_BIT) {
2138 ret = -1;
2139 goto end;
2140 }
2141
2142 if (type_id == CTF_TYPE_VARIANT ||
2143 type_id == CTF_TYPE_SEQUENCE ||
2144 type_id == CTF_TYPE_ARRAY) {
2145 /* Setting an alignment on these types makes no sense */
2146 ret = -1;
2147 goto end;
2148 }
2149
2150 type->declaration->alignment = alignment;
2151 ret = 0;
2152 end:
2153 return ret;
2154 }
2155
2156 BT_HIDDEN
2157 enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
2158 struct bt_ctf_field_type *type)
2159 {
2160 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
2161
2162 if (!type) {
2163 goto end;
2164 }
2165
2166 switch (type->declaration->id) {
2167 case CTF_TYPE_INTEGER:
2168 {
2169 struct bt_ctf_field_type_integer *integer = container_of(
2170 type, struct bt_ctf_field_type_integer, parent);
2171 ret = integer->user_byte_order;
2172 break;
2173 }
2174 case CTF_TYPE_FLOAT:
2175 {
2176 struct bt_ctf_field_type_floating_point *floating_point =
2177 container_of(type,
2178 struct bt_ctf_field_type_floating_point,
2179 parent);
2180 ret = floating_point->user_byte_order;
2181 break;
2182 }
2183 default:
2184 goto end;
2185 }
2186
2187 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2188 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2189 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2190 ret == BT_CTF_BYTE_ORDER_NETWORK);
2191
2192 end:
2193 return ret;
2194 }
2195
2196 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2197 enum bt_ctf_byte_order byte_order)
2198 {
2199 int ret = 0;
2200 int internal_byte_order;
2201 enum ctf_type_id type_id;
2202
2203 if (!type || type->frozen) {
2204 ret = -1;
2205 goto end;
2206 }
2207
2208 switch (byte_order) {
2209 case BT_CTF_BYTE_ORDER_NATIVE:
2210 /* Leave unset. Will be initialized by parent. */
2211 internal_byte_order = 0;
2212 break;
2213 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2214 internal_byte_order = LITTLE_ENDIAN;
2215 break;
2216 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2217 case BT_CTF_BYTE_ORDER_NETWORK:
2218 internal_byte_order = BIG_ENDIAN;
2219 break;
2220 default:
2221 ret = -1;
2222 goto end;
2223 }
2224
2225 type_id = type->declaration->id;
2226 if (set_byte_order_funcs[type_id]) {
2227 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
2228 }
2229 end:
2230 return ret;
2231 }
2232
2233 BT_HIDDEN
2234 enum ctf_type_id bt_ctf_field_type_get_type_id(
2235 struct bt_ctf_field_type *type)
2236 {
2237 if (!type) {
2238 return CTF_TYPE_UNKNOWN;
2239 }
2240
2241 return type->declaration->id;
2242 }
2243
2244 BT_HIDDEN
2245 int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2246 {
2247 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_INTEGER;
2248 }
2249
2250 BT_HIDDEN
2251 int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2252 {
2253 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_FLOAT;
2254 }
2255
2256 BT_HIDDEN
2257 int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2258 {
2259 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_ENUM;
2260 }
2261
2262 BT_HIDDEN
2263 int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2264 {
2265 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_STRING;
2266 }
2267
2268 BT_HIDDEN
2269 int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2270 {
2271 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_STRUCT;
2272 }
2273
2274 BT_HIDDEN
2275 int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2276 {
2277 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_ARRAY;
2278 }
2279
2280 BT_HIDDEN
2281 int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2282 {
2283 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_SEQUENCE;
2284 }
2285
2286 BT_HIDDEN
2287 int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2288 {
2289 return bt_ctf_field_type_get_type_id(type) == CTF_TYPE_VARIANT;
2290 }
2291
2292 void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2293 {
2294 bt_get(type);
2295 }
2296
2297 void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2298 {
2299 bt_put(type);
2300 }
2301
2302 BT_HIDDEN
2303 void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2304 {
2305 if (!type) {
2306 return;
2307 }
2308
2309 type->freeze(type);
2310 }
2311
2312 BT_HIDDEN
2313 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2314 struct bt_ctf_field_type_variant *variant,
2315 int64_t tag_value)
2316 {
2317 struct bt_ctf_field_type *type = NULL;
2318 GQuark field_name_quark;
2319 gpointer index;
2320 struct structure_field *field_entry;
2321 struct range_overlap_query query = {
2322 .range_start._signed = tag_value,
2323 .range_end._signed = tag_value,
2324 .mapping_name = 0, .overlaps = 0};
2325
2326 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2327 &query);
2328 if (!query.overlaps) {
2329 goto end;
2330 }
2331
2332 field_name_quark = query.mapping_name;
2333 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2334 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2335 goto end;
2336 }
2337
2338 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
2339 type = field_entry->type;
2340 end:
2341 return type;
2342 }
2343
2344 BT_HIDDEN
2345 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
2346 struct bt_ctf_field_type_variant *variant,
2347 uint64_t tag_value)
2348 {
2349 struct bt_ctf_field_type *type = NULL;
2350 GQuark field_name_quark;
2351 gpointer index;
2352 struct structure_field *field_entry;
2353 struct range_overlap_query query = {
2354 .range_start._unsigned = tag_value,
2355 .range_end._unsigned = tag_value,
2356 .mapping_name = 0, .overlaps = 0};
2357
2358 g_ptr_array_foreach(variant->tag->entries,
2359 check_ranges_overlap_unsigned,
2360 &query);
2361 if (!query.overlaps) {
2362 goto end;
2363 }
2364
2365 field_name_quark = query.mapping_name;
2366 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2367 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2368 goto end;
2369 }
2370
2371 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2372 type = field_entry->type;
2373 end:
2374 return type;
2375 }
2376
2377 BT_HIDDEN
2378 int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2379 struct metadata_context *context)
2380 {
2381 int ret;
2382
2383 if (!type || !context) {
2384 ret = -1;
2385 goto end;
2386 }
2387
2388 /* Make sure field type is valid before serializing it */
2389 ret = bt_ctf_field_type_validate(type);
2390
2391 if (ret) {
2392 goto end;
2393 }
2394
2395 ret = type->serialize(type, context);
2396 end:
2397 return ret;
2398 }
2399
2400 BT_HIDDEN
2401 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2402 int byte_order)
2403 {
2404 if (!type) {
2405 return;
2406 }
2407
2408 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2409 if (set_byte_order_funcs[type->declaration->id]) {
2410 set_byte_order_funcs[type->declaration->id](type,
2411 byte_order, 1);
2412 }
2413 }
2414
2415 BT_HIDDEN
2416 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2417 {
2418 struct bt_ctf_field_type *copy = NULL;
2419
2420 if (!type) {
2421 goto end;
2422 }
2423
2424 copy = type_copy_funcs[type->declaration->id](type);
2425 end:
2426 return copy;
2427 }
2428
2429 BT_HIDDEN
2430 int bt_ctf_field_type_structure_get_field_name_index(
2431 struct bt_ctf_field_type *type, const char *name)
2432 {
2433 int ret;
2434 size_t index;
2435 GQuark name_quark;
2436 struct bt_ctf_field_type_structure *structure;
2437
2438 if (!type || !name ||
2439 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2440 ret = -1;
2441 goto end;
2442 }
2443
2444 name_quark = g_quark_try_string(name);
2445 if (!name_quark) {
2446 ret = -1;
2447 goto end;
2448 }
2449
2450 structure = container_of(type, struct bt_ctf_field_type_structure,
2451 parent);
2452 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2453 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2454 ret = -1;
2455 goto end;
2456 }
2457 ret = (int) index;
2458 end:
2459 return ret;
2460 }
2461
2462 BT_HIDDEN
2463 int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2464 struct bt_ctf_field_type *field, int index)
2465 {
2466 int ret = 0;
2467 struct bt_ctf_field_type_structure *structure;
2468
2469 if (!type || !field ||
2470 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_STRUCT) {
2471 ret = -1;
2472 goto end;
2473 }
2474
2475 structure = container_of(type, struct bt_ctf_field_type_structure,
2476 parent);
2477 if (index < 0 || index >= structure->fields->len) {
2478 ret = -1;
2479 goto end;
2480 }
2481
2482 bt_get(field);
2483 bt_put(((struct structure_field *)
2484 g_ptr_array_index(structure->fields, index))->type);
2485 ((struct structure_field *) structure->fields->pdata[index])->type =
2486 field;
2487 end:
2488 return ret;
2489 }
2490
2491 BT_HIDDEN
2492 int bt_ctf_field_type_variant_get_field_name_index(
2493 struct bt_ctf_field_type *type, const char *name)
2494 {
2495 int ret;
2496 size_t index;
2497 GQuark name_quark;
2498 struct bt_ctf_field_type_variant *variant;
2499
2500 if (!type || !name ||
2501 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2502 ret = -1;
2503 goto end;
2504 }
2505
2506 name_quark = g_quark_try_string(name);
2507 if (!name_quark) {
2508 ret = -1;
2509 goto end;
2510 }
2511
2512 variant = container_of(type, struct bt_ctf_field_type_variant,
2513 parent);
2514 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2515 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2516 ret = -1;
2517 goto end;
2518 }
2519 ret = (int) index;
2520 end:
2521 return ret;
2522 }
2523
2524 BT_HIDDEN
2525 int bt_ctf_field_type_sequence_set_length_field_path(
2526 struct bt_ctf_field_type *type,
2527 struct bt_ctf_field_path *path)
2528 {
2529 int ret = 0;
2530 struct bt_ctf_field_type_sequence *sequence;
2531
2532 if (!type || bt_ctf_field_type_get_type_id(type) !=
2533 CTF_TYPE_SEQUENCE) {
2534 ret = -1;
2535 goto end;
2536 }
2537
2538 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2539 parent);
2540 bt_get(path);
2541 BT_MOVE(sequence->length_field_path, path);
2542 end:
2543 return ret;
2544 }
2545
2546 BT_HIDDEN
2547 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2548 struct bt_ctf_field_path *path)
2549 {
2550 int ret = 0;
2551 struct bt_ctf_field_type_variant *variant;
2552
2553 if (!type || bt_ctf_field_type_get_type_id(type) !=
2554 CTF_TYPE_VARIANT) {
2555 ret = -1;
2556 goto end;
2557 }
2558
2559 variant = container_of(type, struct bt_ctf_field_type_variant,
2560 parent);
2561 bt_get(path);
2562 BT_MOVE(variant->tag_field_path, path);
2563 end:
2564 return ret;
2565 }
2566
2567 BT_HIDDEN
2568 int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
2569 struct bt_ctf_field_type *tag)
2570 {
2571 int ret = 0;
2572 struct bt_ctf_field_type_variant *variant;
2573
2574 if (!type || !tag ||
2575 bt_ctf_field_type_get_type_id(tag) !=
2576 CTF_TYPE_ENUM) {
2577 ret = -1;
2578 goto end;
2579 }
2580
2581 variant = container_of(type, struct bt_ctf_field_type_variant,
2582 parent);
2583 bt_get(tag);
2584 if (variant->tag) {
2585 bt_put(&variant->tag->parent);
2586 }
2587 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2588 parent);
2589 end:
2590 return ret;
2591 }
2592
2593 BT_HIDDEN
2594 int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2595 struct bt_ctf_field_type *field, int index)
2596 {
2597 int ret = 0;
2598 struct bt_ctf_field_type_variant *variant;
2599
2600 if (!type || !field ||
2601 bt_ctf_field_type_get_type_id(type) != CTF_TYPE_VARIANT) {
2602 ret = -1;
2603 goto end;
2604 }
2605
2606 variant = container_of(type, struct bt_ctf_field_type_variant,
2607 parent);
2608 if (index < 0 || index >= variant->fields->len) {
2609 ret = -1;
2610 goto end;
2611 }
2612
2613 bt_get(field);
2614 bt_put(((struct structure_field *)
2615 g_ptr_array_index(variant->fields, index))->type);
2616 ((struct structure_field *) variant->fields->pdata[index])->type =
2617 field;
2618 end:
2619 return ret;
2620 }
2621
2622 static
2623 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
2624 {
2625 struct bt_ctf_field_type_integer *integer =
2626 (struct bt_ctf_field_type_integer *) type;
2627
2628 if (!type) {
2629 return;
2630 }
2631
2632 bt_put(integer->mapped_clock);
2633 g_free(integer);
2634 }
2635
2636 static
2637 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
2638 {
2639 struct bt_ctf_field_type_enumeration *enumeration =
2640 (struct bt_ctf_field_type_enumeration *) type;
2641
2642 if (!type) {
2643 return;
2644 }
2645
2646 g_ptr_array_free(enumeration->entries, TRUE);
2647 bt_put(enumeration->container);
2648 g_free(enumeration);
2649 }
2650
2651 static
2652 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
2653 {
2654 struct bt_ctf_field_type_floating_point *floating_point =
2655 (struct bt_ctf_field_type_floating_point *) type;
2656
2657 if (!type) {
2658 return;
2659 }
2660
2661 g_free(floating_point);
2662 }
2663
2664 static
2665 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
2666 {
2667 struct bt_ctf_field_type_structure *structure =
2668 (struct bt_ctf_field_type_structure *) type;
2669
2670 if (!type) {
2671 return;
2672 }
2673
2674 g_ptr_array_free(structure->fields, TRUE);
2675 g_hash_table_destroy(structure->field_name_to_index);
2676 g_free(structure);
2677 }
2678
2679 static
2680 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
2681 {
2682 struct bt_ctf_field_type_variant *variant =
2683 (struct bt_ctf_field_type_variant *) type;
2684
2685 if (!type) {
2686 return;
2687 }
2688
2689 g_ptr_array_free(variant->fields, TRUE);
2690 g_hash_table_destroy(variant->field_name_to_index);
2691 g_string_free(variant->tag_name, TRUE);
2692 bt_put(&variant->tag->parent);
2693 BT_PUT(variant->tag_field_path);
2694 g_free(variant);
2695 }
2696
2697 static
2698 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
2699 {
2700 struct bt_ctf_field_type_array *array =
2701 (struct bt_ctf_field_type_array *) type;
2702
2703 if (!type) {
2704 return;
2705 }
2706
2707 bt_put(array->element_type);
2708 g_free(array);
2709 }
2710
2711 static
2712 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
2713 {
2714 struct bt_ctf_field_type_sequence *sequence =
2715 (struct bt_ctf_field_type_sequence *) type;
2716
2717 if (!type) {
2718 return;
2719 }
2720
2721 bt_put(sequence->element_type);
2722 g_string_free(sequence->length_field_name, TRUE);
2723 BT_PUT(sequence->length_field_path);
2724 g_free(sequence);
2725 }
2726
2727 static
2728 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
2729 {
2730 struct bt_ctf_field_type_string *string =
2731 (struct bt_ctf_field_type_string *) type;
2732
2733 if (!type) {
2734 return;
2735 }
2736
2737 g_free(string);
2738 }
2739
2740 static
2741 void generic_field_type_freeze(struct bt_ctf_field_type *type)
2742 {
2743 type->frozen = 1;
2744 }
2745
2746 static
2747 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2748 {
2749 struct bt_ctf_field_type_integer *integer_type = container_of(
2750 type, struct bt_ctf_field_type_integer, parent);
2751
2752 if (integer_type->mapped_clock) {
2753 bt_ctf_clock_freeze(integer_type->mapped_clock);
2754 }
2755
2756 generic_field_type_freeze(type);
2757 }
2758
2759 static
2760 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2761 {
2762 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2763 type, struct bt_ctf_field_type_enumeration, parent);
2764
2765 generic_field_type_freeze(type);
2766 bt_ctf_field_type_freeze(enumeration_type->container);
2767 }
2768
2769 static
2770 void freeze_structure_field(struct structure_field *field)
2771 {
2772 bt_ctf_field_type_freeze(field->type);
2773 }
2774
2775 static
2776 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2777 {
2778 struct bt_ctf_field_type_structure *structure_type = container_of(
2779 type, struct bt_ctf_field_type_structure, parent);
2780
2781 /* Cache the alignment */
2782 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2783 generic_field_type_freeze(type);
2784 g_ptr_array_foreach(structure_type->fields,
2785 (GFunc) freeze_structure_field, NULL);
2786 }
2787
2788 static
2789 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2790 {
2791 struct bt_ctf_field_type_variant *variant_type = container_of(
2792 type, struct bt_ctf_field_type_variant, parent);
2793
2794 generic_field_type_freeze(type);
2795 g_ptr_array_foreach(variant_type->fields,
2796 (GFunc) freeze_structure_field, NULL);
2797 }
2798
2799 static
2800 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2801 {
2802 struct bt_ctf_field_type_array *array_type = container_of(
2803 type, struct bt_ctf_field_type_array, parent);
2804
2805 /* Cache the alignment */
2806 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2807 generic_field_type_freeze(type);
2808 bt_ctf_field_type_freeze(array_type->element_type);
2809 }
2810
2811 static
2812 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2813 {
2814 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2815 type, struct bt_ctf_field_type_sequence, parent);
2816
2817 /* Cache the alignment */
2818 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2819 generic_field_type_freeze(type);
2820 bt_ctf_field_type_freeze(sequence_type->element_type);
2821 }
2822
2823 static
2824 const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
2825 {
2826 const char *encoding_string;
2827
2828 switch (encoding) {
2829 case BT_CTF_STRING_ENCODING_NONE:
2830 encoding_string = "none";
2831 break;
2832 case BT_CTF_STRING_ENCODING_ASCII:
2833 encoding_string = "ASCII";
2834 break;
2835 case BT_CTF_STRING_ENCODING_UTF8:
2836 encoding_string = "UTF8";
2837 break;
2838 default:
2839 encoding_string = "unknown";
2840 break;
2841 }
2842
2843 return encoding_string;
2844 }
2845
2846 static
2847 const char *get_integer_base_string(enum bt_ctf_integer_base base)
2848 {
2849 const char *base_string;
2850
2851 switch (base) {
2852 case BT_CTF_INTEGER_BASE_DECIMAL:
2853 base_string = "decimal";
2854 break;
2855 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2856 base_string = "hexadecimal";
2857 break;
2858 case BT_CTF_INTEGER_BASE_OCTAL:
2859 base_string = "octal";
2860 break;
2861 case BT_CTF_INTEGER_BASE_BINARY:
2862 base_string = "binary";
2863 break;
2864 default:
2865 base_string = "unknown";
2866 break;
2867 }
2868
2869 return base_string;
2870 }
2871
2872 static
2873 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2874 struct metadata_context *context)
2875 {
2876 struct bt_ctf_field_type_integer *integer = container_of(type,
2877 struct bt_ctf_field_type_integer, parent);
2878 int ret = 0;
2879
2880 g_string_append_printf(context->string,
2881 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2882 integer->declaration.len, type->declaration->alignment,
2883 (integer->declaration.signedness ? "true" : "false"),
2884 get_encoding_string(integer->declaration.encoding),
2885 get_integer_base_string(integer->declaration.base),
2886 get_byte_order_string(integer->declaration.byte_order));
2887 if (integer->mapped_clock) {
2888 const char *clock_name = bt_ctf_clock_get_name(
2889 integer->mapped_clock);
2890
2891 if (!clock_name) {
2892 ret = -1;
2893 goto end;
2894 }
2895
2896 g_string_append_printf(context->string,
2897 "; map = clock.%s.value", clock_name);
2898 }
2899
2900 g_string_append(context->string, "; }");
2901 end:
2902 return ret;
2903 }
2904
2905 static
2906 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2907 struct metadata_context *context)
2908 {
2909 size_t entry;
2910 int ret;
2911 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2912 struct bt_ctf_field_type_enumeration, parent);
2913 struct bt_ctf_field_type *container_type;
2914 int container_signed;
2915
2916 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2917 if (!container_type) {
2918 ret = -1;
2919 goto end;
2920 }
2921
2922 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2923 if (container_signed < 0) {
2924 ret = container_signed;
2925 goto error_put_container_type;
2926 }
2927
2928 g_string_append(context->string, "enum : ");
2929 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2930 if (ret) {
2931 goto error_put_container_type;
2932 }
2933
2934 g_string_append(context->string, " { ");
2935 for (entry = 0; entry < enumeration->entries->len; entry++) {
2936 struct enumeration_mapping *mapping =
2937 enumeration->entries->pdata[entry];
2938
2939 if (container_signed) {
2940 if (mapping->range_start._signed ==
2941 mapping->range_end._signed) {
2942 g_string_append_printf(context->string,
2943 "\"%s\" = %" PRId64,
2944 g_quark_to_string(mapping->string),
2945 mapping->range_start._signed);
2946 } else {
2947 g_string_append_printf(context->string,
2948 "\"%s\" = %" PRId64 " ... %" PRId64,
2949 g_quark_to_string(mapping->string),
2950 mapping->range_start._signed,
2951 mapping->range_end._signed);
2952 }
2953 } else {
2954 if (mapping->range_start._unsigned ==
2955 mapping->range_end._unsigned) {
2956 g_string_append_printf(context->string,
2957 "\"%s\" = %" PRIu64,
2958 g_quark_to_string(mapping->string),
2959 mapping->range_start._unsigned);
2960 } else {
2961 g_string_append_printf(context->string,
2962 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2963 g_quark_to_string(mapping->string),
2964 mapping->range_start._unsigned,
2965 mapping->range_end._unsigned);
2966 }
2967 }
2968
2969 g_string_append(context->string,
2970 ((entry != (enumeration->entries->len - 1)) ?
2971 ", " : " }"));
2972 }
2973
2974 if (context->field_name->len) {
2975 g_string_append_printf(context->string, " %s",
2976 context->field_name->str);
2977 g_string_assign(context->field_name, "");
2978 }
2979 error_put_container_type:
2980 bt_put(container_type);
2981 end:
2982 return ret;
2983 }
2984
2985 static
2986 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2987 struct metadata_context *context)
2988 {
2989 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2990 type, struct bt_ctf_field_type_floating_point, parent);
2991
2992 g_string_append_printf(context->string,
2993 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2994 floating_point->declaration.exp->len,
2995 floating_point->declaration.mantissa->len + 1,
2996 get_byte_order_string(floating_point->declaration.byte_order),
2997 type->declaration->alignment);
2998 return 0;
2999 }
3000
3001 static
3002 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
3003 struct metadata_context *context)
3004 {
3005 size_t i;
3006 unsigned int indent;
3007 int ret = 0;
3008 struct bt_ctf_field_type_structure *structure = container_of(type,
3009 struct bt_ctf_field_type_structure, parent);
3010 GString *structure_field_name = context->field_name;
3011
3012 context->field_name = g_string_new("");
3013
3014 context->current_indentation_level++;
3015 g_string_append(context->string, "struct {\n");
3016
3017 for (i = 0; i < structure->fields->len; i++) {
3018 struct structure_field *field;
3019
3020 for (indent = 0; indent < context->current_indentation_level;
3021 indent++) {
3022 g_string_append_c(context->string, '\t');
3023 }
3024
3025 field = structure->fields->pdata[i];
3026 g_string_assign(context->field_name,
3027 g_quark_to_string(field->name));
3028 ret = bt_ctf_field_type_serialize(field->type, context);
3029 if (ret) {
3030 goto end;
3031 }
3032
3033 if (context->field_name->len) {
3034 g_string_append_printf(context->string, " %s",
3035 context->field_name->str);
3036 }
3037 g_string_append(context->string, ";\n");
3038 }
3039
3040 context->current_indentation_level--;
3041 for (indent = 0; indent < context->current_indentation_level;
3042 indent++) {
3043 g_string_append_c(context->string, '\t');
3044 }
3045
3046 g_string_append_printf(context->string, "} align(%zu)",
3047 type->declaration->alignment);
3048 end:
3049 g_string_free(context->field_name, TRUE);
3050 context->field_name = structure_field_name;
3051 return ret;
3052 }
3053
3054 static
3055 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3056 struct metadata_context *context)
3057 {
3058 size_t i;
3059 unsigned int indent;
3060 int ret = 0;
3061 struct bt_ctf_field_type_variant *variant = container_of(
3062 type, struct bt_ctf_field_type_variant, parent);
3063 GString *variant_field_name = context->field_name;
3064
3065 context->field_name = g_string_new("");
3066 if (variant->tag_name->len > 0) {
3067 g_string_append_printf(context->string,
3068 "variant <%s> {\n", variant->tag_name->str);
3069 } else {
3070 g_string_append(context->string, "variant {\n");
3071 }
3072
3073 context->current_indentation_level++;
3074 for (i = 0; i < variant->fields->len; i++) {
3075 struct structure_field *field = variant->fields->pdata[i];
3076
3077 g_string_assign(context->field_name,
3078 g_quark_to_string(field->name));
3079 for (indent = 0; indent < context->current_indentation_level;
3080 indent++) {
3081 g_string_append_c(context->string, '\t');
3082 }
3083
3084 g_string_assign(context->field_name,
3085 g_quark_to_string(field->name));
3086 ret = bt_ctf_field_type_serialize(field->type, context);
3087 if (ret) {
3088 goto end;
3089 }
3090
3091 if (context->field_name->len) {
3092 g_string_append_printf(context->string, " %s;",
3093 context->field_name->str);
3094 }
3095
3096 g_string_append_c(context->string, '\n');
3097 }
3098
3099 context->current_indentation_level--;
3100 for (indent = 0; indent < context->current_indentation_level;
3101 indent++) {
3102 g_string_append_c(context->string, '\t');
3103 }
3104
3105 g_string_append(context->string, "}");
3106 end:
3107 g_string_free(context->field_name, TRUE);
3108 context->field_name = variant_field_name;
3109 return ret;
3110 }
3111
3112 static
3113 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3114 struct metadata_context *context)
3115 {
3116 int ret = 0;
3117 struct bt_ctf_field_type_array *array = container_of(type,
3118 struct bt_ctf_field_type_array, parent);
3119
3120 ret = bt_ctf_field_type_serialize(array->element_type, context);
3121 if (ret) {
3122 goto end;
3123 }
3124
3125 if (context->field_name->len) {
3126 g_string_append_printf(context->string, " %s[%u]",
3127 context->field_name->str, array->length);
3128 g_string_assign(context->field_name, "");
3129 } else {
3130 g_string_append_printf(context->string, "[%u]", array->length);
3131 }
3132 end:
3133 return ret;
3134 }
3135
3136 static
3137 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3138 struct metadata_context *context)
3139 {
3140 int ret = 0;
3141 struct bt_ctf_field_type_sequence *sequence = container_of(
3142 type, struct bt_ctf_field_type_sequence, parent);
3143
3144 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3145 if (ret) {
3146 goto end;
3147 }
3148
3149 if (context->field_name->len) {
3150 g_string_append_printf(context->string, " %s[%s]",
3151 context->field_name->str,
3152 sequence->length_field_name->str);
3153 g_string_assign(context->field_name, "");
3154 } else {
3155 g_string_append_printf(context->string, "[%s]",
3156 sequence->length_field_name->str);
3157 }
3158 end:
3159 return ret;
3160 }
3161
3162 static
3163 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3164 struct metadata_context *context)
3165 {
3166 struct bt_ctf_field_type_string *string = container_of(
3167 type, struct bt_ctf_field_type_string, parent);
3168
3169 g_string_append_printf(context->string,
3170 "string { encoding = %s; }",
3171 get_encoding_string(string->declaration.encoding));
3172 return 0;
3173 }
3174
3175 static
3176 enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3177 enum bt_ctf_byte_order ret;
3178
3179 switch (byte_order) {
3180 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3181 case LITTLE_ENDIAN:
3182 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3183 break;
3184 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3185 case BIG_ENDIAN:
3186 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3187 break;
3188 case BT_CTF_BYTE_ORDER_NETWORK:
3189 ret = BT_CTF_BYTE_ORDER_NETWORK;
3190 break;
3191 case BT_CTF_BYTE_ORDER_NATIVE:
3192 ret = BT_CTF_BYTE_ORDER_NATIVE;
3193 break;
3194 default:
3195 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3196 break;
3197 }
3198
3199 return ret;
3200 }
3201
3202 static
3203 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
3204 int byte_order, int set_native)
3205 {
3206 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3207 struct bt_ctf_field_type_integer, parent);
3208
3209 if (set_native) {
3210 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3211 /*
3212 * User byte order is native, so we can set
3213 * the real byte order.
3214 */
3215 integer_type->declaration.byte_order =
3216 byte_order;
3217 }
3218 } else {
3219 integer_type->user_byte_order =
3220 get_ctf_ir_byte_order(byte_order);
3221 integer_type->declaration.byte_order = byte_order;
3222 }
3223 }
3224
3225 static
3226 void bt_ctf_field_type_enumeration_set_byte_order(
3227 struct bt_ctf_field_type *type, int byte_order, int set_native)
3228 {
3229 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3230 struct bt_ctf_field_type_enumeration, parent);
3231
3232 /* Safe to assume that container is an integer */
3233 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3234 byte_order, set_native);
3235 }
3236
3237 static
3238 void bt_ctf_field_type_floating_point_set_byte_order(
3239 struct bt_ctf_field_type *type, int byte_order, int set_native)
3240 {
3241 struct bt_ctf_field_type_floating_point *floating_point_type =
3242 container_of(type, struct bt_ctf_field_type_floating_point,
3243 parent);
3244
3245 if (set_native) {
3246 if (floating_point_type->user_byte_order ==
3247 BT_CTF_BYTE_ORDER_NATIVE) {
3248 /*
3249 * User byte order is native, so we can set
3250 * the real byte order.
3251 */
3252 floating_point_type->declaration.byte_order =
3253 byte_order;
3254 floating_point_type->sign.byte_order =
3255 byte_order;
3256 floating_point_type->mantissa.byte_order =
3257 byte_order;
3258 floating_point_type->exp.byte_order =
3259 byte_order;
3260 }
3261 } else {
3262 floating_point_type->user_byte_order =
3263 get_ctf_ir_byte_order(byte_order);
3264 floating_point_type->declaration.byte_order = byte_order;
3265 floating_point_type->sign.byte_order = byte_order;
3266 floating_point_type->mantissa.byte_order = byte_order;
3267 floating_point_type->exp.byte_order = byte_order;
3268 }
3269 }
3270
3271 static
3272 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3273 int byte_order, int set_native)
3274 {
3275 int i;
3276 struct bt_ctf_field_type_structure *structure_type =
3277 container_of(type, struct bt_ctf_field_type_structure,
3278 parent);
3279
3280 for (i = 0; i < structure_type->fields->len; i++) {
3281 struct structure_field *field = g_ptr_array_index(
3282 structure_type->fields, i);
3283 struct bt_ctf_field_type *field_type = field->type;
3284
3285 if (set_byte_order_funcs[field_type->declaration->id]) {
3286 set_byte_order_funcs[field_type->declaration->id](
3287 field_type, byte_order, set_native);
3288 }
3289 }
3290 }
3291
3292 static
3293 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3294 int byte_order, int set_native)
3295 {
3296 int i;
3297 struct bt_ctf_field_type_variant *variant_type =
3298 container_of(type, struct bt_ctf_field_type_variant,
3299 parent);
3300
3301 for (i = 0; i < variant_type->fields->len; i++) {
3302 struct structure_field *field = g_ptr_array_index(
3303 variant_type->fields, i);
3304 struct bt_ctf_field_type *field_type = field->type;
3305
3306 if (set_byte_order_funcs[field_type->declaration->id]) {
3307 set_byte_order_funcs[field_type->declaration->id](
3308 field_type, byte_order, set_native);
3309 }
3310 }
3311 }
3312
3313 static
3314 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3315 int byte_order, int set_native)
3316 {
3317 struct bt_ctf_field_type_array *array_type =
3318 container_of(type, struct bt_ctf_field_type_array,
3319 parent);
3320
3321 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3322 set_byte_order_funcs[array_type->element_type->declaration->id](
3323 array_type->element_type, byte_order, set_native);
3324 }
3325 }
3326
3327 static
3328 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3329 int byte_order, int set_native)
3330 {
3331 struct bt_ctf_field_type_sequence *sequence_type =
3332 container_of(type, struct bt_ctf_field_type_sequence,
3333 parent);
3334
3335 if (set_byte_order_funcs[
3336 sequence_type->element_type->declaration->id]) {
3337 set_byte_order_funcs[
3338 sequence_type->element_type->declaration->id](
3339 sequence_type->element_type, byte_order, set_native);
3340 }
3341 }
3342
3343 static
3344 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3345 struct bt_ctf_field_type *type)
3346 {
3347 struct bt_ctf_field_type *copy;
3348 struct bt_ctf_field_type_integer *integer, *copy_integer;
3349
3350 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3351 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3352 if (!copy) {
3353 goto end;
3354 }
3355
3356 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3357 parent);
3358 copy_integer->declaration = integer->declaration;
3359 if (integer->mapped_clock) {
3360 bt_get(integer->mapped_clock);
3361 copy_integer->mapped_clock = integer->mapped_clock;
3362 }
3363
3364 copy_integer->user_byte_order = integer->user_byte_order;
3365
3366 end:
3367 return copy;
3368 }
3369
3370 static
3371 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3372 struct bt_ctf_field_type *type)
3373 {
3374 size_t i;
3375 struct bt_ctf_field_type *copy = NULL, *copy_container;
3376 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3377
3378 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3379 parent);
3380
3381 /* Copy the source enumeration's container */
3382 copy_container = bt_ctf_field_type_copy(enumeration->container);
3383 if (!copy_container) {
3384 goto end;
3385 }
3386
3387 copy = bt_ctf_field_type_enumeration_create(copy_container);
3388 if (!copy) {
3389 goto end;
3390 }
3391 copy_enumeration = container_of(copy,
3392 struct bt_ctf_field_type_enumeration, parent);
3393
3394 /* Copy all enumaration entries */
3395 for (i = 0; i < enumeration->entries->len; i++) {
3396 struct enumeration_mapping *mapping = g_ptr_array_index(
3397 enumeration->entries, i);
3398 struct enumeration_mapping* copy_mapping = g_new0(
3399 struct enumeration_mapping, 1);
3400
3401 if (!copy_mapping) {
3402 goto error;
3403 }
3404
3405 *copy_mapping = *mapping;
3406 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3407 }
3408
3409 copy_enumeration->declaration = enumeration->declaration;
3410 end:
3411 bt_put(copy_container);
3412 return copy;
3413 error:
3414 bt_put(copy_container);
3415 BT_PUT(copy);
3416 return copy;
3417 }
3418
3419 static
3420 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3421 struct bt_ctf_field_type *type)
3422 {
3423 struct bt_ctf_field_type *copy;
3424 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3425
3426 floating_point = container_of(type,
3427 struct bt_ctf_field_type_floating_point, parent);
3428 copy = bt_ctf_field_type_floating_point_create();
3429 if (!copy) {
3430 goto end;
3431 }
3432
3433 copy_float = container_of(copy,
3434 struct bt_ctf_field_type_floating_point, parent);
3435 copy_float->declaration = floating_point->declaration;
3436 copy_float->sign = floating_point->sign;
3437 copy_float->mantissa = floating_point->mantissa;
3438 copy_float->exp = floating_point->exp;
3439 copy_float->user_byte_order = floating_point->user_byte_order;
3440 copy_float->declaration.sign = &copy_float->sign;
3441 copy_float->declaration.mantissa = &copy_float->mantissa;
3442 copy_float->declaration.exp = &copy_float->exp;
3443 end:
3444 return copy;
3445 }
3446
3447 static
3448 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3449 struct bt_ctf_field_type *type)
3450 {
3451 int i;
3452 GHashTableIter iter;
3453 gpointer key, value;
3454 struct bt_ctf_field_type *copy;
3455 struct bt_ctf_field_type_structure *structure, *copy_structure;
3456
3457 structure = container_of(type, struct bt_ctf_field_type_structure,
3458 parent);
3459 copy = bt_ctf_field_type_structure_create();
3460 if (!copy) {
3461 goto end;
3462 }
3463
3464 copy_structure = container_of(copy,
3465 struct bt_ctf_field_type_structure, parent);
3466
3467 /* Copy field_name_to_index */
3468 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3469 while (g_hash_table_iter_next (&iter, &key, &value)) {
3470 g_hash_table_insert(copy_structure->field_name_to_index,
3471 key, value);
3472 }
3473
3474 for (i = 0; i < structure->fields->len; i++) {
3475 struct structure_field *entry, *copy_entry;
3476 struct bt_ctf_field_type *copy_field;
3477
3478 copy_entry = g_new0(struct structure_field, 1);
3479 if (!copy_entry) {
3480 goto error;
3481 }
3482
3483 entry = g_ptr_array_index(structure->fields, i);
3484 copy_field = bt_ctf_field_type_copy(entry->type);
3485 if (!copy_field) {
3486 g_free(copy_entry);
3487 goto error;
3488 }
3489
3490 copy_entry->name = entry->name;
3491 copy_entry->type = copy_field;
3492 g_ptr_array_add(copy_structure->fields, copy_entry);
3493 }
3494
3495 copy_structure->declaration = structure->declaration;
3496 end:
3497 return copy;
3498 error:
3499 BT_PUT(copy);
3500 return copy;
3501 }
3502
3503 static
3504 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3505 struct bt_ctf_field_type *type)
3506 {
3507 int i;
3508 GHashTableIter iter;
3509 gpointer key, value;
3510 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3511 struct bt_ctf_field_type_variant *variant, *copy_variant;
3512
3513 variant = container_of(type, struct bt_ctf_field_type_variant,
3514 parent);
3515 if (variant->tag) {
3516 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3517 if (!copy_tag) {
3518 goto end;
3519 }
3520 }
3521
3522 copy = bt_ctf_field_type_variant_create(copy_tag,
3523 variant->tag_name->len ? variant->tag_name->str : NULL);
3524 if (!copy) {
3525 goto end;
3526 }
3527
3528 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3529 parent);
3530
3531 /* Copy field_name_to_index */
3532 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3533 while (g_hash_table_iter_next (&iter, &key, &value)) {
3534 g_hash_table_insert(copy_variant->field_name_to_index,
3535 key, value);
3536 }
3537
3538 for (i = 0; i < variant->fields->len; i++) {
3539 struct structure_field *entry, *copy_entry;
3540 struct bt_ctf_field_type *copy_field;
3541
3542 copy_entry = g_new0(struct structure_field, 1);
3543 if (!copy_entry) {
3544 goto error;
3545 }
3546
3547 entry = g_ptr_array_index(variant->fields, i);
3548 copy_field = bt_ctf_field_type_copy(entry->type);
3549 if (!copy_field) {
3550 g_free(copy_entry);
3551 goto error;
3552 }
3553
3554 copy_entry->name = entry->name;
3555 copy_entry->type = copy_field;
3556 g_ptr_array_add(copy_variant->fields, copy_entry);
3557 }
3558
3559 copy_variant->declaration = variant->declaration;
3560 if (variant->tag_field_path) {
3561 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3562 variant->tag_field_path);
3563 if (!copy_variant->tag_field_path) {
3564 goto error;
3565 }
3566 }
3567 end:
3568 bt_put(copy_tag);
3569 return copy;
3570 error:
3571 bt_put(copy_tag);
3572 BT_PUT(copy);
3573 return copy;
3574 }
3575
3576 static
3577 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3578 struct bt_ctf_field_type *type)
3579 {
3580 struct bt_ctf_field_type *copy = NULL, *copy_element;
3581 struct bt_ctf_field_type_array *array, *copy_array;
3582
3583 array = container_of(type, struct bt_ctf_field_type_array,
3584 parent);
3585 copy_element = bt_ctf_field_type_copy(array->element_type);
3586 if (!copy_element) {
3587 goto end;
3588 }
3589
3590 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3591 if (!copy) {
3592 goto end;
3593 }
3594
3595 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3596 parent);
3597 copy_array->declaration = array->declaration;
3598 end:
3599 bt_put(copy_element);
3600 return copy;
3601 }
3602
3603 static
3604 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3605 struct bt_ctf_field_type *type)
3606 {
3607 struct bt_ctf_field_type *copy = NULL, *copy_element;
3608 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3609
3610 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3611 parent);
3612 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3613 if (!copy_element) {
3614 goto end;
3615 }
3616
3617 copy = bt_ctf_field_type_sequence_create(copy_element,
3618 sequence->length_field_name->len ?
3619 sequence->length_field_name->str : NULL);
3620 if (!copy) {
3621 goto end;
3622 }
3623
3624 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3625 parent);
3626 copy_sequence->declaration = sequence->declaration;
3627 if (sequence->length_field_path) {
3628 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3629 sequence->length_field_path);
3630 if (!copy_sequence->length_field_path) {
3631 goto error;
3632 }
3633 }
3634 end:
3635 bt_put(copy_element);
3636 return copy;
3637 error:
3638 BT_PUT(copy);
3639 goto end;
3640 }
3641
3642 static
3643 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3644 struct bt_ctf_field_type *type)
3645 {
3646 struct bt_ctf_field_type *copy;
3647 struct bt_ctf_field_type_string *string, *copy_string;
3648
3649 copy = bt_ctf_field_type_string_create();
3650 if (!copy) {
3651 goto end;
3652 }
3653
3654 string = container_of(type, struct bt_ctf_field_type_string,
3655 parent);
3656 copy_string = container_of(type, struct bt_ctf_field_type_string,
3657 parent);
3658 copy_string->declaration = string->declaration;
3659 end:
3660 return copy;
3661 }
3662
3663 static
3664 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3665 struct bt_ctf_field_type *type_b)
3666 {
3667 int ret = 1;
3668 struct bt_ctf_field_type_integer *integer_a;
3669 struct bt_ctf_field_type_integer *integer_b;
3670 struct declaration_integer *decl_a;
3671 struct declaration_integer *decl_b;
3672
3673 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3674 parent);
3675 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3676 parent);
3677 decl_a = &integer_a->declaration;
3678 decl_b = &integer_b->declaration;
3679
3680 /* Length */
3681 if (decl_a->len != decl_b->len) {
3682 goto end;
3683 }
3684
3685 /*
3686 * Compare user byte orders only, not the cached,
3687 * real byte orders.
3688 */
3689 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3690 goto end;
3691 }
3692
3693 /* Signedness */
3694 if (decl_a->signedness != decl_b->signedness) {
3695 goto end;
3696 }
3697
3698 /* Base */
3699 if (decl_a->base != decl_b->base) {
3700 goto end;
3701 }
3702
3703 /* Encoding */
3704 if (decl_a->encoding != decl_b->encoding) {
3705 goto end;
3706 }
3707
3708 /* Mapped clock */
3709 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3710 goto end;
3711 }
3712
3713 /* Equal */
3714 ret = 0;
3715
3716 end:
3717 return ret;
3718 }
3719
3720 static
3721 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3722 struct bt_ctf_field_type *type_b)
3723 {
3724 int ret = 1;
3725 struct bt_ctf_field_type_floating_point *float_a;
3726 struct bt_ctf_field_type_floating_point *float_b;
3727
3728 float_a = container_of(type_a,
3729 struct bt_ctf_field_type_floating_point, parent);
3730 float_b = container_of(type_b,
3731 struct bt_ctf_field_type_floating_point, parent);
3732
3733 /* Sign length */
3734 if (float_a->sign.len != float_b->sign.len) {
3735 goto end;
3736 }
3737
3738 /* Exponent length */
3739 if (float_a->exp.len != float_b->exp.len) {
3740 goto end;
3741 }
3742
3743 /* Mantissa length */
3744 if (float_a->mantissa.len != float_b->mantissa.len) {
3745 goto end;
3746 }
3747
3748 /*
3749 * Compare user byte orders only, not the cached,
3750 * real byte orders.
3751 */
3752 if (float_a->user_byte_order != float_b->user_byte_order) {
3753 goto end;
3754 }
3755
3756 /* Equal */
3757 ret = 0;
3758
3759 end:
3760 return ret;
3761 }
3762
3763 static
3764 int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3765 struct enumeration_mapping *mapping_b)
3766 {
3767 int ret = 1;
3768
3769 /* Label */
3770 if (mapping_a->string != mapping_b->string) {
3771 goto end;
3772 }
3773
3774 /* Range start */
3775 if (mapping_a->range_start._unsigned !=
3776 mapping_b->range_start._unsigned) {
3777 goto end;
3778 }
3779
3780 /* Range end */
3781 if (mapping_a->range_end._unsigned !=
3782 mapping_b->range_end._unsigned) {
3783 goto end;
3784 }
3785
3786 /* Equal */
3787 ret = 0;
3788
3789 end:
3790 return ret;
3791 }
3792
3793 static
3794 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3795 struct bt_ctf_field_type *type_b)
3796 {
3797 int ret = 1;
3798 int i;
3799 struct bt_ctf_field_type_enumeration *enum_a;
3800 struct bt_ctf_field_type_enumeration *enum_b;
3801
3802 enum_a = container_of(type_a,
3803 struct bt_ctf_field_type_enumeration, parent);
3804 enum_b = container_of(type_b,
3805 struct bt_ctf_field_type_enumeration, parent);
3806
3807 /* Container field type */
3808 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3809 if (ret) {
3810 goto end;
3811 }
3812
3813 ret = 1;
3814
3815 /* Entries */
3816 if (enum_a->entries->len != enum_b->entries->len) {
3817 goto end;
3818 }
3819
3820 for (i = 0; i < enum_a->entries->len; ++i) {
3821 struct enumeration_mapping *mapping_a =
3822 g_ptr_array_index(enum_a->entries, i);
3823 struct enumeration_mapping *mapping_b =
3824 g_ptr_array_index(enum_b->entries, i);
3825
3826 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3827 goto end;
3828 }
3829 }
3830
3831 /* Equal */
3832 ret = 0;
3833
3834 end:
3835 return ret;
3836 }
3837
3838 static
3839 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3840 struct bt_ctf_field_type *type_b)
3841 {
3842 int ret = 1;
3843 struct bt_ctf_field_type_string *string_a;
3844 struct bt_ctf_field_type_string *string_b;
3845
3846 string_a = container_of(type_a,
3847 struct bt_ctf_field_type_string, parent);
3848 string_b = container_of(type_b,
3849 struct bt_ctf_field_type_string, parent);
3850
3851 /* Encoding */
3852 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3853 goto end;
3854 }
3855
3856 /* Equal */
3857 ret = 0;
3858
3859 end:
3860 return ret;
3861 }
3862
3863 static
3864 int compare_structure_fields(struct structure_field *field_a,
3865 struct structure_field *field_b)
3866 {
3867 int ret = 1;
3868
3869 /* Label */
3870 if (field_a->name != field_b->name) {
3871 goto end;
3872 }
3873
3874 /* Type */
3875 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3876
3877 end:
3878 return ret;
3879 }
3880
3881 static
3882 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3883 struct bt_ctf_field_type *type_b)
3884 {
3885 int ret = 1;
3886 int i;
3887 struct bt_ctf_field_type_structure *struct_a;
3888 struct bt_ctf_field_type_structure *struct_b;
3889
3890 struct_a = container_of(type_a,
3891 struct bt_ctf_field_type_structure, parent);
3892 struct_b = container_of(type_b,
3893 struct bt_ctf_field_type_structure, parent);
3894
3895 /* Alignment */
3896 if (bt_ctf_field_type_get_alignment(type_a) !=
3897 bt_ctf_field_type_get_alignment(type_b)) {
3898 goto end;
3899 }
3900
3901 /* Fields */
3902 if (struct_a->fields->len != struct_b->fields->len) {
3903 goto end;
3904 }
3905
3906 for (i = 0; i < struct_a->fields->len; ++i) {
3907 struct structure_field *field_a =
3908 g_ptr_array_index(struct_a->fields, i);
3909 struct structure_field *field_b =
3910 g_ptr_array_index(struct_b->fields, i);
3911
3912 ret = compare_structure_fields(field_a, field_b);
3913 if (ret) {
3914 goto end;
3915 }
3916 }
3917
3918 /* Equal */
3919 ret = 0;
3920
3921 end:
3922 return ret;
3923 }
3924
3925 static
3926 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3927 struct bt_ctf_field_type *type_b)
3928 {
3929 int ret = 1;
3930 int i;
3931 struct bt_ctf_field_type_variant *variant_a;
3932 struct bt_ctf_field_type_variant *variant_b;
3933
3934 variant_a = container_of(type_a,
3935 struct bt_ctf_field_type_variant, parent);
3936 variant_b = container_of(type_b,
3937 struct bt_ctf_field_type_variant, parent);
3938
3939 /* Tag name */
3940 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3941 goto end;
3942 }
3943
3944 /* Tag type */
3945 ret = bt_ctf_field_type_compare(
3946 (struct bt_ctf_field_type *) variant_a->tag,
3947 (struct bt_ctf_field_type *) variant_b->tag);
3948 if (ret) {
3949 goto end;
3950 }
3951
3952 ret = 1;
3953
3954 /* Fields */
3955 if (variant_a->fields->len != variant_b->fields->len) {
3956 goto end;
3957 }
3958
3959 for (i = 0; i < variant_a->fields->len; ++i) {
3960 struct structure_field *field_a =
3961 g_ptr_array_index(variant_a->fields, i);
3962 struct structure_field *field_b =
3963 g_ptr_array_index(variant_b->fields, i);
3964
3965 ret = compare_structure_fields(field_a, field_b);
3966 if (ret) {
3967 goto end;
3968 }
3969 }
3970
3971 /* Equal */
3972 ret = 0;
3973
3974 end:
3975 return ret;
3976 }
3977
3978 static
3979 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3980 struct bt_ctf_field_type *type_b)
3981 {
3982 int ret = 1;
3983 struct bt_ctf_field_type_array *array_a;
3984 struct bt_ctf_field_type_array *array_b;
3985
3986 array_a = container_of(type_a,
3987 struct bt_ctf_field_type_array, parent);
3988 array_b = container_of(type_b,
3989 struct bt_ctf_field_type_array, parent);
3990
3991 /* Length */
3992 if (array_a->length != array_b->length) {
3993 goto end;
3994 }
3995
3996 /* Element type */
3997 ret = bt_ctf_field_type_compare(array_a->element_type,
3998 array_b->element_type);
3999
4000 end:
4001 return ret;
4002 }
4003
4004 static
4005 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
4006 struct bt_ctf_field_type *type_b)
4007 {
4008 int ret = -1;
4009 struct bt_ctf_field_type_sequence *sequence_a;
4010 struct bt_ctf_field_type_sequence *sequence_b;
4011
4012 sequence_a = container_of(type_a,
4013 struct bt_ctf_field_type_sequence, parent);
4014 sequence_b = container_of(type_b,
4015 struct bt_ctf_field_type_sequence, parent);
4016
4017 /* Length name */
4018 if (strcmp(sequence_a->length_field_name->str,
4019 sequence_b->length_field_name->str)) {
4020 goto end;
4021 }
4022
4023 /* Element type */
4024 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4025 sequence_b->element_type);
4026
4027 end:
4028 return ret;
4029 }
4030
4031 BT_HIDDEN
4032 int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4033 struct bt_ctf_field_type *type_b)
4034 {
4035 int ret = 1;
4036
4037 if (type_a == type_b) {
4038 /* Same reference: equal (even if both are NULL) */
4039 ret = 0;
4040 goto end;
4041 }
4042
4043 if (!type_a || !type_b) {
4044 ret = -1;
4045 goto end;
4046 }
4047
4048 if (type_a->declaration->id != type_b->declaration->id) {
4049 /* Different type IDs */
4050 goto end;
4051 }
4052
4053 if (type_a->declaration->id == CTF_TYPE_UNKNOWN) {
4054 /* Both have unknown type IDs */
4055 goto end;
4056 }
4057
4058 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4059
4060 end:
4061 return ret;
4062 }
4063
4064 BT_HIDDEN
4065 int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4066 {
4067 int field_count = -1;
4068 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4069
4070 switch (type_id) {
4071 case CTF_TYPE_STRUCT:
4072 field_count =
4073 bt_ctf_field_type_structure_get_field_count(field_type);
4074 break;
4075 case CTF_TYPE_VARIANT:
4076 field_count =
4077 bt_ctf_field_type_variant_get_field_count(field_type);
4078 break;
4079 case CTF_TYPE_ARRAY:
4080 case CTF_TYPE_SEQUENCE:
4081 /*
4082 * Array and sequence types always contain a single member
4083 * (the element type).
4084 */
4085 field_count = 1;
4086 break;
4087 default:
4088 break;
4089 }
4090
4091 return field_count;
4092 }
4093
4094 BT_HIDDEN
4095 struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4096 struct bt_ctf_field_type *field_type, int index)
4097 {
4098 struct bt_ctf_field_type *field = NULL;
4099 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4100
4101 switch (type_id) {
4102 case CTF_TYPE_STRUCT:
4103 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4104 index);
4105 break;
4106 case CTF_TYPE_VARIANT:
4107 {
4108 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
4109 &field, index);
4110 if (ret) {
4111 field = NULL;
4112 goto end;
4113 }
4114 break;
4115 }
4116 case CTF_TYPE_ARRAY:
4117 field = bt_ctf_field_type_array_get_element_type(field_type);
4118 break;
4119 case CTF_TYPE_SEQUENCE:
4120 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4121 break;
4122 default:
4123 break;
4124 }
4125 end:
4126 return field;
4127 }
4128
4129 BT_HIDDEN
4130 int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4131 const char *name)
4132 {
4133 int field_index = -1;
4134 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4135
4136 switch (type_id) {
4137 case CTF_TYPE_STRUCT:
4138 field_index = bt_ctf_field_type_structure_get_field_name_index(
4139 field_type, name);
4140 break;
4141 case CTF_TYPE_VARIANT:
4142 field_index = bt_ctf_field_type_variant_get_field_name_index(
4143 field_type, name);
4144 break;
4145 default:
4146 break;
4147 }
4148
4149 return field_index;
4150 }
4151
4152 BT_HIDDEN
4153 struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4154 struct bt_ctf_field_type *type)
4155 {
4156 struct bt_ctf_field_path *field_path = NULL;
4157 struct bt_ctf_field_type_variant *variant;
4158
4159 if (!type || !bt_ctf_field_type_is_variant(type)) {
4160 goto end;
4161 }
4162
4163 variant = container_of(type, struct bt_ctf_field_type_variant,
4164 parent);
4165 field_path = bt_get(variant->tag_field_path);
4166 end:
4167 return field_path;
4168 }
4169
4170 BT_HIDDEN
4171 struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
4172 struct bt_ctf_field_type *type)
4173 {
4174 struct bt_ctf_field_path *field_path = NULL;
4175 struct bt_ctf_field_type_sequence *sequence;
4176
4177 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4178 goto end;
4179 }
4180
4181 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4182 parent);
4183 field_path = bt_get(sequence->length_field_path);
4184 end:
4185 return field_path;
4186 }
This page took 0.122103 seconds and 4 git commands to generate.