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