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