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