bt_ctf_field_type_get_byte_order(): support enum FT
[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_ENUM:
2154 {
2155 struct bt_ctf_field_type_enumeration *enum_ft = container_of(
2156 type, struct bt_ctf_field_type_enumeration, parent);
2157 ret = bt_ctf_field_type_get_byte_order(enum_ft->container);
2158 break;
2159 }
2160 case BT_CTF_TYPE_ID_FLOAT:
2161 {
2162 struct bt_ctf_field_type_floating_point *floating_point =
2163 container_of(type,
2164 struct bt_ctf_field_type_floating_point,
2165 parent);
2166 ret = floating_point->user_byte_order;
2167 break;
2168 }
2169 default:
2170 goto end;
2171 }
2172
2173 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2174 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2175 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2176 ret == BT_CTF_BYTE_ORDER_NETWORK);
2177
2178 end:
2179 return ret;
2180 }
2181
2182 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2183 enum bt_ctf_byte_order byte_order)
2184 {
2185 int ret = 0;
2186 int internal_byte_order;
2187 enum bt_ctf_type_id type_id;
2188
2189 if (!type || type->frozen) {
2190 ret = -1;
2191 goto end;
2192 }
2193
2194 switch (byte_order) {
2195 case BT_CTF_BYTE_ORDER_NATIVE:
2196 /* Leave unset. Will be initialized by parent. */
2197 internal_byte_order = 0;
2198 break;
2199 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2200 internal_byte_order = LITTLE_ENDIAN;
2201 break;
2202 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2203 case BT_CTF_BYTE_ORDER_NETWORK:
2204 internal_byte_order = BIG_ENDIAN;
2205 break;
2206 default:
2207 ret = -1;
2208 goto end;
2209 }
2210
2211 type_id = type->declaration->id;
2212 if (set_byte_order_funcs[type_id]) {
2213 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
2214 }
2215 end:
2216 return ret;
2217 }
2218
2219 enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
2220 struct bt_ctf_field_type *type)
2221 {
2222 if (!type) {
2223 return BT_CTF_TYPE_ID_UNKNOWN;
2224 }
2225
2226 return type->declaration->id;
2227 }
2228
2229 int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2230 {
2231 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
2232 }
2233
2234 int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2235 {
2236 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
2237 }
2238
2239 int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2240 {
2241 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
2242 }
2243
2244 int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2245 {
2246 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
2247 }
2248
2249 int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2250 {
2251 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
2252 }
2253
2254 int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2255 {
2256 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
2257 }
2258
2259 int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2260 {
2261 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
2262 }
2263
2264 int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2265 {
2266 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
2267 }
2268
2269 void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2270 {
2271 bt_get(type);
2272 }
2273
2274 void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2275 {
2276 bt_put(type);
2277 }
2278
2279 BT_HIDDEN
2280 void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2281 {
2282 if (!type) {
2283 return;
2284 }
2285
2286 type->freeze(type);
2287 }
2288
2289 BT_HIDDEN
2290 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2291 struct bt_ctf_field_type_variant *variant,
2292 int64_t tag_value)
2293 {
2294 struct bt_ctf_field_type *type = NULL;
2295 GQuark field_name_quark;
2296 gpointer index;
2297 struct structure_field *field_entry;
2298 struct range_overlap_query query = {
2299 .range_start._signed = tag_value,
2300 .range_end._signed = tag_value,
2301 .mapping_name = 0, .overlaps = 0};
2302
2303 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2304 &query);
2305 if (!query.overlaps) {
2306 goto end;
2307 }
2308
2309 field_name_quark = query.mapping_name;
2310 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2311 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2312 goto end;
2313 }
2314
2315 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
2316 type = field_entry->type;
2317 end:
2318 return type;
2319 }
2320
2321 BT_HIDDEN
2322 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
2323 struct bt_ctf_field_type_variant *variant,
2324 uint64_t tag_value)
2325 {
2326 struct bt_ctf_field_type *type = NULL;
2327 GQuark field_name_quark;
2328 gpointer index;
2329 struct structure_field *field_entry;
2330 struct range_overlap_query query = {
2331 .range_start._unsigned = tag_value,
2332 .range_end._unsigned = tag_value,
2333 .mapping_name = 0, .overlaps = 0};
2334
2335 g_ptr_array_foreach(variant->tag->entries,
2336 check_ranges_overlap_unsigned,
2337 &query);
2338 if (!query.overlaps) {
2339 goto end;
2340 }
2341
2342 field_name_quark = query.mapping_name;
2343 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2344 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2345 goto end;
2346 }
2347
2348 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2349 type = field_entry->type;
2350 end:
2351 return type;
2352 }
2353
2354 BT_HIDDEN
2355 int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2356 struct metadata_context *context)
2357 {
2358 int ret;
2359
2360 if (!type || !context) {
2361 ret = -1;
2362 goto end;
2363 }
2364
2365 /* Make sure field type is valid before serializing it */
2366 ret = bt_ctf_field_type_validate(type);
2367
2368 if (ret) {
2369 goto end;
2370 }
2371
2372 ret = type->serialize(type, context);
2373 end:
2374 return ret;
2375 }
2376
2377 BT_HIDDEN
2378 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2379 int byte_order)
2380 {
2381 if (!type) {
2382 return;
2383 }
2384
2385 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2386 if (set_byte_order_funcs[type->declaration->id]) {
2387 set_byte_order_funcs[type->declaration->id](type,
2388 byte_order, 1);
2389 }
2390 }
2391
2392 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2393 {
2394 struct bt_ctf_field_type *copy = NULL;
2395
2396 if (!type) {
2397 goto end;
2398 }
2399
2400 copy = type_copy_funcs[type->declaration->id](type);
2401 end:
2402 return copy;
2403 }
2404
2405 BT_HIDDEN
2406 int bt_ctf_field_type_structure_get_field_name_index(
2407 struct bt_ctf_field_type *type, const char *name)
2408 {
2409 int ret;
2410 size_t index;
2411 GQuark name_quark;
2412 struct bt_ctf_field_type_structure *structure;
2413
2414 if (!type || !name ||
2415 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2416 ret = -1;
2417 goto end;
2418 }
2419
2420 name_quark = g_quark_try_string(name);
2421 if (!name_quark) {
2422 ret = -1;
2423 goto end;
2424 }
2425
2426 structure = container_of(type, struct bt_ctf_field_type_structure,
2427 parent);
2428 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2429 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2430 ret = -1;
2431 goto end;
2432 }
2433 ret = (int) index;
2434 end:
2435 return ret;
2436 }
2437
2438 BT_HIDDEN
2439 int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2440 struct bt_ctf_field_type *field, int index)
2441 {
2442 int ret = 0;
2443 struct bt_ctf_field_type_structure *structure;
2444
2445 if (!type || !field ||
2446 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2447 ret = -1;
2448 goto end;
2449 }
2450
2451 structure = container_of(type, struct bt_ctf_field_type_structure,
2452 parent);
2453 if (index < 0 || index >= structure->fields->len) {
2454 ret = -1;
2455 goto end;
2456 }
2457
2458 bt_get(field);
2459 bt_put(((struct structure_field *)
2460 g_ptr_array_index(structure->fields, index))->type);
2461 ((struct structure_field *) structure->fields->pdata[index])->type =
2462 field;
2463 end:
2464 return ret;
2465 }
2466
2467 BT_HIDDEN
2468 int bt_ctf_field_type_variant_get_field_name_index(
2469 struct bt_ctf_field_type *type, const char *name)
2470 {
2471 int ret;
2472 size_t index;
2473 GQuark name_quark;
2474 struct bt_ctf_field_type_variant *variant;
2475
2476 if (!type || !name ||
2477 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2478 ret = -1;
2479 goto end;
2480 }
2481
2482 name_quark = g_quark_try_string(name);
2483 if (!name_quark) {
2484 ret = -1;
2485 goto end;
2486 }
2487
2488 variant = container_of(type, struct bt_ctf_field_type_variant,
2489 parent);
2490 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2491 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2492 ret = -1;
2493 goto end;
2494 }
2495 ret = (int) index;
2496 end:
2497 return ret;
2498 }
2499
2500 BT_HIDDEN
2501 int bt_ctf_field_type_sequence_set_length_field_path(
2502 struct bt_ctf_field_type *type,
2503 struct bt_ctf_field_path *path)
2504 {
2505 int ret = 0;
2506 struct bt_ctf_field_type_sequence *sequence;
2507
2508 if (!type || bt_ctf_field_type_get_type_id(type) !=
2509 BT_CTF_TYPE_ID_SEQUENCE) {
2510 ret = -1;
2511 goto end;
2512 }
2513
2514 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2515 parent);
2516 bt_get(path);
2517 BT_MOVE(sequence->length_field_path, path);
2518 end:
2519 return ret;
2520 }
2521
2522 BT_HIDDEN
2523 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2524 struct bt_ctf_field_path *path)
2525 {
2526 int ret = 0;
2527 struct bt_ctf_field_type_variant *variant;
2528
2529 if (!type || bt_ctf_field_type_get_type_id(type) !=
2530 BT_CTF_TYPE_ID_VARIANT) {
2531 ret = -1;
2532 goto end;
2533 }
2534
2535 variant = container_of(type, struct bt_ctf_field_type_variant,
2536 parent);
2537 bt_get(path);
2538 BT_MOVE(variant->tag_field_path, path);
2539 end:
2540 return ret;
2541 }
2542
2543 BT_HIDDEN
2544 int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
2545 struct bt_ctf_field_type *tag)
2546 {
2547 int ret = 0;
2548 struct bt_ctf_field_type_variant *variant;
2549
2550 if (!type || !tag ||
2551 bt_ctf_field_type_get_type_id(tag) !=
2552 BT_CTF_TYPE_ID_ENUM) {
2553 ret = -1;
2554 goto end;
2555 }
2556
2557 variant = container_of(type, struct bt_ctf_field_type_variant,
2558 parent);
2559 bt_get(tag);
2560 if (variant->tag) {
2561 bt_put(&variant->tag->parent);
2562 }
2563 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2564 parent);
2565 end:
2566 return ret;
2567 }
2568
2569 BT_HIDDEN
2570 int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2571 struct bt_ctf_field_type *field, int index)
2572 {
2573 int ret = 0;
2574 struct bt_ctf_field_type_variant *variant;
2575
2576 if (!type || !field ||
2577 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2578 ret = -1;
2579 goto end;
2580 }
2581
2582 variant = container_of(type, struct bt_ctf_field_type_variant,
2583 parent);
2584 if (index < 0 || index >= variant->fields->len) {
2585 ret = -1;
2586 goto end;
2587 }
2588
2589 bt_get(field);
2590 bt_put(((struct structure_field *)
2591 g_ptr_array_index(variant->fields, index))->type);
2592 ((struct structure_field *) variant->fields->pdata[index])->type =
2593 field;
2594 end:
2595 return ret;
2596 }
2597
2598 static
2599 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
2600 {
2601 struct bt_ctf_field_type_integer *integer =
2602 (struct bt_ctf_field_type_integer *) type;
2603
2604 if (!type) {
2605 return;
2606 }
2607
2608 bt_put(integer->mapped_clock);
2609 g_free(integer);
2610 }
2611
2612 static
2613 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
2614 {
2615 struct bt_ctf_field_type_enumeration *enumeration =
2616 (struct bt_ctf_field_type_enumeration *) type;
2617
2618 if (!type) {
2619 return;
2620 }
2621
2622 g_ptr_array_free(enumeration->entries, TRUE);
2623 bt_put(enumeration->container);
2624 g_free(enumeration);
2625 }
2626
2627 static
2628 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
2629 {
2630 struct bt_ctf_field_type_floating_point *floating_point =
2631 (struct bt_ctf_field_type_floating_point *) type;
2632
2633 if (!type) {
2634 return;
2635 }
2636
2637 g_free(floating_point);
2638 }
2639
2640 static
2641 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
2642 {
2643 struct bt_ctf_field_type_structure *structure =
2644 (struct bt_ctf_field_type_structure *) type;
2645
2646 if (!type) {
2647 return;
2648 }
2649
2650 g_ptr_array_free(structure->fields, TRUE);
2651 g_hash_table_destroy(structure->field_name_to_index);
2652 g_free(structure);
2653 }
2654
2655 static
2656 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
2657 {
2658 struct bt_ctf_field_type_variant *variant =
2659 (struct bt_ctf_field_type_variant *) type;
2660
2661 if (!type) {
2662 return;
2663 }
2664
2665 g_ptr_array_free(variant->fields, TRUE);
2666 g_hash_table_destroy(variant->field_name_to_index);
2667 g_string_free(variant->tag_name, TRUE);
2668 bt_put(&variant->tag->parent);
2669 BT_PUT(variant->tag_field_path);
2670 g_free(variant);
2671 }
2672
2673 static
2674 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
2675 {
2676 struct bt_ctf_field_type_array *array =
2677 (struct bt_ctf_field_type_array *) type;
2678
2679 if (!type) {
2680 return;
2681 }
2682
2683 bt_put(array->element_type);
2684 g_free(array);
2685 }
2686
2687 static
2688 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
2689 {
2690 struct bt_ctf_field_type_sequence *sequence =
2691 (struct bt_ctf_field_type_sequence *) type;
2692
2693 if (!type) {
2694 return;
2695 }
2696
2697 bt_put(sequence->element_type);
2698 g_string_free(sequence->length_field_name, TRUE);
2699 BT_PUT(sequence->length_field_path);
2700 g_free(sequence);
2701 }
2702
2703 static
2704 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
2705 {
2706 struct bt_ctf_field_type_string *string =
2707 (struct bt_ctf_field_type_string *) type;
2708
2709 if (!type) {
2710 return;
2711 }
2712
2713 g_free(string);
2714 }
2715
2716 static
2717 void generic_field_type_freeze(struct bt_ctf_field_type *type)
2718 {
2719 type->frozen = 1;
2720 }
2721
2722 static
2723 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2724 {
2725 struct bt_ctf_field_type_integer *integer_type = container_of(
2726 type, struct bt_ctf_field_type_integer, parent);
2727
2728 if (integer_type->mapped_clock) {
2729 bt_ctf_clock_freeze(integer_type->mapped_clock);
2730 }
2731
2732 generic_field_type_freeze(type);
2733 }
2734
2735 static
2736 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2737 {
2738 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2739 type, struct bt_ctf_field_type_enumeration, parent);
2740
2741 generic_field_type_freeze(type);
2742 bt_ctf_field_type_freeze(enumeration_type->container);
2743 }
2744
2745 static
2746 void freeze_structure_field(struct structure_field *field)
2747 {
2748 bt_ctf_field_type_freeze(field->type);
2749 }
2750
2751 static
2752 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2753 {
2754 struct bt_ctf_field_type_structure *structure_type = container_of(
2755 type, struct bt_ctf_field_type_structure, parent);
2756
2757 /* Cache the alignment */
2758 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2759 generic_field_type_freeze(type);
2760 g_ptr_array_foreach(structure_type->fields,
2761 (GFunc) freeze_structure_field, NULL);
2762 }
2763
2764 static
2765 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2766 {
2767 struct bt_ctf_field_type_variant *variant_type = container_of(
2768 type, struct bt_ctf_field_type_variant, parent);
2769
2770 generic_field_type_freeze(type);
2771 g_ptr_array_foreach(variant_type->fields,
2772 (GFunc) freeze_structure_field, NULL);
2773 }
2774
2775 static
2776 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2777 {
2778 struct bt_ctf_field_type_array *array_type = container_of(
2779 type, struct bt_ctf_field_type_array, parent);
2780
2781 /* Cache the alignment */
2782 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2783 generic_field_type_freeze(type);
2784 bt_ctf_field_type_freeze(array_type->element_type);
2785 }
2786
2787 static
2788 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2789 {
2790 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2791 type, struct bt_ctf_field_type_sequence, parent);
2792
2793 /* Cache the alignment */
2794 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2795 generic_field_type_freeze(type);
2796 bt_ctf_field_type_freeze(sequence_type->element_type);
2797 }
2798
2799 static
2800 const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
2801 {
2802 const char *encoding_string;
2803
2804 switch (encoding) {
2805 case BT_CTF_STRING_ENCODING_NONE:
2806 encoding_string = "none";
2807 break;
2808 case BT_CTF_STRING_ENCODING_ASCII:
2809 encoding_string = "ASCII";
2810 break;
2811 case BT_CTF_STRING_ENCODING_UTF8:
2812 encoding_string = "UTF8";
2813 break;
2814 default:
2815 encoding_string = "unknown";
2816 break;
2817 }
2818
2819 return encoding_string;
2820 }
2821
2822 static
2823 const char *get_integer_base_string(enum bt_ctf_integer_base base)
2824 {
2825 const char *base_string;
2826
2827 switch (base) {
2828 case BT_CTF_INTEGER_BASE_DECIMAL:
2829 base_string = "decimal";
2830 break;
2831 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2832 base_string = "hexadecimal";
2833 break;
2834 case BT_CTF_INTEGER_BASE_OCTAL:
2835 base_string = "octal";
2836 break;
2837 case BT_CTF_INTEGER_BASE_BINARY:
2838 base_string = "binary";
2839 break;
2840 default:
2841 base_string = "unknown";
2842 break;
2843 }
2844
2845 return base_string;
2846 }
2847
2848 static
2849 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2850 struct metadata_context *context)
2851 {
2852 struct bt_ctf_field_type_integer *integer = container_of(type,
2853 struct bt_ctf_field_type_integer, parent);
2854 int ret = 0;
2855
2856 g_string_append_printf(context->string,
2857 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2858 integer->declaration.len, type->declaration->alignment,
2859 (integer->declaration.signedness ? "true" : "false"),
2860 get_encoding_string(integer->declaration.encoding),
2861 get_integer_base_string(integer->declaration.base),
2862 get_byte_order_string(integer->declaration.byte_order));
2863 if (integer->mapped_clock) {
2864 const char *clock_name = bt_ctf_clock_get_name(
2865 integer->mapped_clock);
2866
2867 if (!clock_name) {
2868 ret = -1;
2869 goto end;
2870 }
2871
2872 g_string_append_printf(context->string,
2873 "; map = clock.%s.value", clock_name);
2874 }
2875
2876 g_string_append(context->string, "; }");
2877 end:
2878 return ret;
2879 }
2880
2881 static
2882 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2883 struct metadata_context *context)
2884 {
2885 size_t entry;
2886 int ret;
2887 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2888 struct bt_ctf_field_type_enumeration, parent);
2889 struct bt_ctf_field_type *container_type;
2890 int container_signed;
2891
2892 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2893 if (!container_type) {
2894 ret = -1;
2895 goto end;
2896 }
2897
2898 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2899 if (container_signed < 0) {
2900 ret = container_signed;
2901 goto error_put_container_type;
2902 }
2903
2904 g_string_append(context->string, "enum : ");
2905 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2906 if (ret) {
2907 goto error_put_container_type;
2908 }
2909
2910 g_string_append(context->string, " { ");
2911 for (entry = 0; entry < enumeration->entries->len; entry++) {
2912 struct enumeration_mapping *mapping =
2913 enumeration->entries->pdata[entry];
2914
2915 if (container_signed) {
2916 if (mapping->range_start._signed ==
2917 mapping->range_end._signed) {
2918 g_string_append_printf(context->string,
2919 "\"%s\" = %" PRId64,
2920 g_quark_to_string(mapping->string),
2921 mapping->range_start._signed);
2922 } else {
2923 g_string_append_printf(context->string,
2924 "\"%s\" = %" PRId64 " ... %" PRId64,
2925 g_quark_to_string(mapping->string),
2926 mapping->range_start._signed,
2927 mapping->range_end._signed);
2928 }
2929 } else {
2930 if (mapping->range_start._unsigned ==
2931 mapping->range_end._unsigned) {
2932 g_string_append_printf(context->string,
2933 "\"%s\" = %" PRIu64,
2934 g_quark_to_string(mapping->string),
2935 mapping->range_start._unsigned);
2936 } else {
2937 g_string_append_printf(context->string,
2938 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2939 g_quark_to_string(mapping->string),
2940 mapping->range_start._unsigned,
2941 mapping->range_end._unsigned);
2942 }
2943 }
2944
2945 g_string_append(context->string,
2946 ((entry != (enumeration->entries->len - 1)) ?
2947 ", " : " }"));
2948 }
2949
2950 if (context->field_name->len) {
2951 g_string_append_printf(context->string, " %s",
2952 context->field_name->str);
2953 g_string_assign(context->field_name, "");
2954 }
2955 error_put_container_type:
2956 bt_put(container_type);
2957 end:
2958 return ret;
2959 }
2960
2961 static
2962 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2963 struct metadata_context *context)
2964 {
2965 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2966 type, struct bt_ctf_field_type_floating_point, parent);
2967
2968 g_string_append_printf(context->string,
2969 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2970 floating_point->declaration.exp->len,
2971 floating_point->declaration.mantissa->len + 1,
2972 get_byte_order_string(floating_point->declaration.byte_order),
2973 type->declaration->alignment);
2974 return 0;
2975 }
2976
2977 static
2978 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2979 struct metadata_context *context)
2980 {
2981 size_t i;
2982 unsigned int indent;
2983 int ret = 0;
2984 struct bt_ctf_field_type_structure *structure = container_of(type,
2985 struct bt_ctf_field_type_structure, parent);
2986 GString *structure_field_name = context->field_name;
2987
2988 context->field_name = g_string_new("");
2989
2990 context->current_indentation_level++;
2991 g_string_append(context->string, "struct {\n");
2992
2993 for (i = 0; i < structure->fields->len; i++) {
2994 struct structure_field *field;
2995
2996 for (indent = 0; indent < context->current_indentation_level;
2997 indent++) {
2998 g_string_append_c(context->string, '\t');
2999 }
3000
3001 field = structure->fields->pdata[i];
3002 g_string_assign(context->field_name,
3003 g_quark_to_string(field->name));
3004 ret = bt_ctf_field_type_serialize(field->type, context);
3005 if (ret) {
3006 goto end;
3007 }
3008
3009 if (context->field_name->len) {
3010 g_string_append_printf(context->string, " %s",
3011 context->field_name->str);
3012 }
3013 g_string_append(context->string, ";\n");
3014 }
3015
3016 context->current_indentation_level--;
3017 for (indent = 0; indent < context->current_indentation_level;
3018 indent++) {
3019 g_string_append_c(context->string, '\t');
3020 }
3021
3022 g_string_append_printf(context->string, "} align(%zu)",
3023 type->declaration->alignment);
3024 end:
3025 g_string_free(context->field_name, TRUE);
3026 context->field_name = structure_field_name;
3027 return ret;
3028 }
3029
3030 static
3031 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3032 struct metadata_context *context)
3033 {
3034 size_t i;
3035 unsigned int indent;
3036 int ret = 0;
3037 struct bt_ctf_field_type_variant *variant = container_of(
3038 type, struct bt_ctf_field_type_variant, parent);
3039 GString *variant_field_name = context->field_name;
3040
3041 context->field_name = g_string_new("");
3042 if (variant->tag_name->len > 0) {
3043 g_string_append_printf(context->string,
3044 "variant <%s> {\n", variant->tag_name->str);
3045 } else {
3046 g_string_append(context->string, "variant {\n");
3047 }
3048
3049 context->current_indentation_level++;
3050 for (i = 0; i < variant->fields->len; i++) {
3051 struct structure_field *field = variant->fields->pdata[i];
3052
3053 g_string_assign(context->field_name,
3054 g_quark_to_string(field->name));
3055 for (indent = 0; indent < context->current_indentation_level;
3056 indent++) {
3057 g_string_append_c(context->string, '\t');
3058 }
3059
3060 g_string_assign(context->field_name,
3061 g_quark_to_string(field->name));
3062 ret = bt_ctf_field_type_serialize(field->type, context);
3063 if (ret) {
3064 goto end;
3065 }
3066
3067 if (context->field_name->len) {
3068 g_string_append_printf(context->string, " %s;",
3069 context->field_name->str);
3070 }
3071
3072 g_string_append_c(context->string, '\n');
3073 }
3074
3075 context->current_indentation_level--;
3076 for (indent = 0; indent < context->current_indentation_level;
3077 indent++) {
3078 g_string_append_c(context->string, '\t');
3079 }
3080
3081 g_string_append(context->string, "}");
3082 end:
3083 g_string_free(context->field_name, TRUE);
3084 context->field_name = variant_field_name;
3085 return ret;
3086 }
3087
3088 static
3089 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3090 struct metadata_context *context)
3091 {
3092 int ret = 0;
3093 struct bt_ctf_field_type_array *array = container_of(type,
3094 struct bt_ctf_field_type_array, parent);
3095
3096 ret = bt_ctf_field_type_serialize(array->element_type, context);
3097 if (ret) {
3098 goto end;
3099 }
3100
3101 if (context->field_name->len) {
3102 g_string_append_printf(context->string, " %s[%u]",
3103 context->field_name->str, array->length);
3104 g_string_assign(context->field_name, "");
3105 } else {
3106 g_string_append_printf(context->string, "[%u]", array->length);
3107 }
3108 end:
3109 return ret;
3110 }
3111
3112 static
3113 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3114 struct metadata_context *context)
3115 {
3116 int ret = 0;
3117 struct bt_ctf_field_type_sequence *sequence = container_of(
3118 type, struct bt_ctf_field_type_sequence, parent);
3119
3120 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3121 if (ret) {
3122 goto end;
3123 }
3124
3125 if (context->field_name->len) {
3126 g_string_append_printf(context->string, " %s[%s]",
3127 context->field_name->str,
3128 sequence->length_field_name->str);
3129 g_string_assign(context->field_name, "");
3130 } else {
3131 g_string_append_printf(context->string, "[%s]",
3132 sequence->length_field_name->str);
3133 }
3134 end:
3135 return ret;
3136 }
3137
3138 static
3139 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3140 struct metadata_context *context)
3141 {
3142 struct bt_ctf_field_type_string *string = container_of(
3143 type, struct bt_ctf_field_type_string, parent);
3144
3145 g_string_append_printf(context->string,
3146 "string { encoding = %s; }",
3147 get_encoding_string(string->declaration.encoding));
3148 return 0;
3149 }
3150
3151 static
3152 enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3153 enum bt_ctf_byte_order ret;
3154
3155 switch (byte_order) {
3156 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3157 case LITTLE_ENDIAN:
3158 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3159 break;
3160 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3161 case BIG_ENDIAN:
3162 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3163 break;
3164 case BT_CTF_BYTE_ORDER_NETWORK:
3165 ret = BT_CTF_BYTE_ORDER_NETWORK;
3166 break;
3167 case BT_CTF_BYTE_ORDER_NATIVE:
3168 ret = BT_CTF_BYTE_ORDER_NATIVE;
3169 break;
3170 default:
3171 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3172 break;
3173 }
3174
3175 return ret;
3176 }
3177
3178 static
3179 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
3180 int byte_order, int set_native)
3181 {
3182 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3183 struct bt_ctf_field_type_integer, parent);
3184
3185 if (set_native) {
3186 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3187 /*
3188 * User byte order is native, so we can set
3189 * the real byte order.
3190 */
3191 integer_type->declaration.byte_order =
3192 byte_order;
3193 }
3194 } else {
3195 integer_type->user_byte_order =
3196 get_ctf_ir_byte_order(byte_order);
3197 integer_type->declaration.byte_order = byte_order;
3198 }
3199 }
3200
3201 static
3202 void bt_ctf_field_type_enumeration_set_byte_order(
3203 struct bt_ctf_field_type *type, int byte_order, int set_native)
3204 {
3205 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3206 struct bt_ctf_field_type_enumeration, parent);
3207
3208 /* Safe to assume that container is an integer */
3209 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3210 byte_order, set_native);
3211 }
3212
3213 static
3214 void bt_ctf_field_type_floating_point_set_byte_order(
3215 struct bt_ctf_field_type *type, int byte_order, int set_native)
3216 {
3217 struct bt_ctf_field_type_floating_point *floating_point_type =
3218 container_of(type, struct bt_ctf_field_type_floating_point,
3219 parent);
3220
3221 if (set_native) {
3222 if (floating_point_type->user_byte_order ==
3223 BT_CTF_BYTE_ORDER_NATIVE) {
3224 /*
3225 * User byte order is native, so we can set
3226 * the real byte order.
3227 */
3228 floating_point_type->declaration.byte_order =
3229 byte_order;
3230 floating_point_type->sign.byte_order =
3231 byte_order;
3232 floating_point_type->mantissa.byte_order =
3233 byte_order;
3234 floating_point_type->exp.byte_order =
3235 byte_order;
3236 }
3237 } else {
3238 floating_point_type->user_byte_order =
3239 get_ctf_ir_byte_order(byte_order);
3240 floating_point_type->declaration.byte_order = byte_order;
3241 floating_point_type->sign.byte_order = byte_order;
3242 floating_point_type->mantissa.byte_order = byte_order;
3243 floating_point_type->exp.byte_order = byte_order;
3244 }
3245 }
3246
3247 static
3248 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3249 int byte_order, int set_native)
3250 {
3251 int i;
3252 struct bt_ctf_field_type_structure *structure_type =
3253 container_of(type, struct bt_ctf_field_type_structure,
3254 parent);
3255
3256 for (i = 0; i < structure_type->fields->len; i++) {
3257 struct structure_field *field = g_ptr_array_index(
3258 structure_type->fields, i);
3259 struct bt_ctf_field_type *field_type = field->type;
3260
3261 if (set_byte_order_funcs[field_type->declaration->id]) {
3262 set_byte_order_funcs[field_type->declaration->id](
3263 field_type, byte_order, set_native);
3264 }
3265 }
3266 }
3267
3268 static
3269 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3270 int byte_order, int set_native)
3271 {
3272 int i;
3273 struct bt_ctf_field_type_variant *variant_type =
3274 container_of(type, struct bt_ctf_field_type_variant,
3275 parent);
3276
3277 for (i = 0; i < variant_type->fields->len; i++) {
3278 struct structure_field *field = g_ptr_array_index(
3279 variant_type->fields, i);
3280 struct bt_ctf_field_type *field_type = field->type;
3281
3282 if (set_byte_order_funcs[field_type->declaration->id]) {
3283 set_byte_order_funcs[field_type->declaration->id](
3284 field_type, byte_order, set_native);
3285 }
3286 }
3287 }
3288
3289 static
3290 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3291 int byte_order, int set_native)
3292 {
3293 struct bt_ctf_field_type_array *array_type =
3294 container_of(type, struct bt_ctf_field_type_array,
3295 parent);
3296
3297 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3298 set_byte_order_funcs[array_type->element_type->declaration->id](
3299 array_type->element_type, byte_order, set_native);
3300 }
3301 }
3302
3303 static
3304 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3305 int byte_order, int set_native)
3306 {
3307 struct bt_ctf_field_type_sequence *sequence_type =
3308 container_of(type, struct bt_ctf_field_type_sequence,
3309 parent);
3310
3311 if (set_byte_order_funcs[
3312 sequence_type->element_type->declaration->id]) {
3313 set_byte_order_funcs[
3314 sequence_type->element_type->declaration->id](
3315 sequence_type->element_type, byte_order, set_native);
3316 }
3317 }
3318
3319 static
3320 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3321 struct bt_ctf_field_type *type)
3322 {
3323 struct bt_ctf_field_type *copy;
3324 struct bt_ctf_field_type_integer *integer, *copy_integer;
3325
3326 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3327 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3328 if (!copy) {
3329 goto end;
3330 }
3331
3332 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3333 parent);
3334 copy_integer->declaration = integer->declaration;
3335 if (integer->mapped_clock) {
3336 bt_get(integer->mapped_clock);
3337 copy_integer->mapped_clock = integer->mapped_clock;
3338 }
3339
3340 copy_integer->user_byte_order = integer->user_byte_order;
3341
3342 end:
3343 return copy;
3344 }
3345
3346 static
3347 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3348 struct bt_ctf_field_type *type)
3349 {
3350 size_t i;
3351 struct bt_ctf_field_type *copy = NULL, *copy_container;
3352 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3353
3354 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3355 parent);
3356
3357 /* Copy the source enumeration's container */
3358 copy_container = bt_ctf_field_type_copy(enumeration->container);
3359 if (!copy_container) {
3360 goto end;
3361 }
3362
3363 copy = bt_ctf_field_type_enumeration_create(copy_container);
3364 if (!copy) {
3365 goto end;
3366 }
3367 copy_enumeration = container_of(copy,
3368 struct bt_ctf_field_type_enumeration, parent);
3369
3370 /* Copy all enumaration entries */
3371 for (i = 0; i < enumeration->entries->len; i++) {
3372 struct enumeration_mapping *mapping = g_ptr_array_index(
3373 enumeration->entries, i);
3374 struct enumeration_mapping* copy_mapping = g_new0(
3375 struct enumeration_mapping, 1);
3376
3377 if (!copy_mapping) {
3378 goto error;
3379 }
3380
3381 *copy_mapping = *mapping;
3382 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3383 }
3384
3385 copy_enumeration->declaration = enumeration->declaration;
3386 end:
3387 bt_put(copy_container);
3388 return copy;
3389 error:
3390 bt_put(copy_container);
3391 BT_PUT(copy);
3392 return copy;
3393 }
3394
3395 static
3396 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3397 struct bt_ctf_field_type *type)
3398 {
3399 struct bt_ctf_field_type *copy;
3400 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3401
3402 floating_point = container_of(type,
3403 struct bt_ctf_field_type_floating_point, parent);
3404 copy = bt_ctf_field_type_floating_point_create();
3405 if (!copy) {
3406 goto end;
3407 }
3408
3409 copy_float = container_of(copy,
3410 struct bt_ctf_field_type_floating_point, parent);
3411 copy_float->declaration = floating_point->declaration;
3412 copy_float->sign = floating_point->sign;
3413 copy_float->mantissa = floating_point->mantissa;
3414 copy_float->exp = floating_point->exp;
3415 copy_float->user_byte_order = floating_point->user_byte_order;
3416 copy_float->declaration.sign = &copy_float->sign;
3417 copy_float->declaration.mantissa = &copy_float->mantissa;
3418 copy_float->declaration.exp = &copy_float->exp;
3419 end:
3420 return copy;
3421 }
3422
3423 static
3424 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3425 struct bt_ctf_field_type *type)
3426 {
3427 int i;
3428 GHashTableIter iter;
3429 gpointer key, value;
3430 struct bt_ctf_field_type *copy;
3431 struct bt_ctf_field_type_structure *structure, *copy_structure;
3432
3433 structure = container_of(type, struct bt_ctf_field_type_structure,
3434 parent);
3435 copy = bt_ctf_field_type_structure_create();
3436 if (!copy) {
3437 goto end;
3438 }
3439
3440 copy_structure = container_of(copy,
3441 struct bt_ctf_field_type_structure, parent);
3442
3443 /* Copy field_name_to_index */
3444 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3445 while (g_hash_table_iter_next (&iter, &key, &value)) {
3446 g_hash_table_insert(copy_structure->field_name_to_index,
3447 key, value);
3448 }
3449
3450 for (i = 0; i < structure->fields->len; i++) {
3451 struct structure_field *entry, *copy_entry;
3452 struct bt_ctf_field_type *copy_field;
3453
3454 copy_entry = g_new0(struct structure_field, 1);
3455 if (!copy_entry) {
3456 goto error;
3457 }
3458
3459 entry = g_ptr_array_index(structure->fields, i);
3460 copy_field = bt_ctf_field_type_copy(entry->type);
3461 if (!copy_field) {
3462 g_free(copy_entry);
3463 goto error;
3464 }
3465
3466 copy_entry->name = entry->name;
3467 copy_entry->type = copy_field;
3468 g_ptr_array_add(copy_structure->fields, copy_entry);
3469 }
3470
3471 copy_structure->declaration = structure->declaration;
3472 end:
3473 return copy;
3474 error:
3475 BT_PUT(copy);
3476 return copy;
3477 }
3478
3479 static
3480 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3481 struct bt_ctf_field_type *type)
3482 {
3483 int i;
3484 GHashTableIter iter;
3485 gpointer key, value;
3486 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3487 struct bt_ctf_field_type_variant *variant, *copy_variant;
3488
3489 variant = container_of(type, struct bt_ctf_field_type_variant,
3490 parent);
3491 if (variant->tag) {
3492 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3493 if (!copy_tag) {
3494 goto end;
3495 }
3496 }
3497
3498 copy = bt_ctf_field_type_variant_create(copy_tag,
3499 variant->tag_name->len ? variant->tag_name->str : NULL);
3500 if (!copy) {
3501 goto end;
3502 }
3503
3504 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3505 parent);
3506
3507 /* Copy field_name_to_index */
3508 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3509 while (g_hash_table_iter_next (&iter, &key, &value)) {
3510 g_hash_table_insert(copy_variant->field_name_to_index,
3511 key, value);
3512 }
3513
3514 for (i = 0; i < variant->fields->len; i++) {
3515 struct structure_field *entry, *copy_entry;
3516 struct bt_ctf_field_type *copy_field;
3517
3518 copy_entry = g_new0(struct structure_field, 1);
3519 if (!copy_entry) {
3520 goto error;
3521 }
3522
3523 entry = g_ptr_array_index(variant->fields, i);
3524 copy_field = bt_ctf_field_type_copy(entry->type);
3525 if (!copy_field) {
3526 g_free(copy_entry);
3527 goto error;
3528 }
3529
3530 copy_entry->name = entry->name;
3531 copy_entry->type = copy_field;
3532 g_ptr_array_add(copy_variant->fields, copy_entry);
3533 }
3534
3535 copy_variant->declaration = variant->declaration;
3536 if (variant->tag_field_path) {
3537 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3538 variant->tag_field_path);
3539 if (!copy_variant->tag_field_path) {
3540 goto error;
3541 }
3542 }
3543 end:
3544 bt_put(copy_tag);
3545 return copy;
3546 error:
3547 bt_put(copy_tag);
3548 BT_PUT(copy);
3549 return copy;
3550 }
3551
3552 static
3553 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3554 struct bt_ctf_field_type *type)
3555 {
3556 struct bt_ctf_field_type *copy = NULL, *copy_element;
3557 struct bt_ctf_field_type_array *array, *copy_array;
3558
3559 array = container_of(type, struct bt_ctf_field_type_array,
3560 parent);
3561 copy_element = bt_ctf_field_type_copy(array->element_type);
3562 if (!copy_element) {
3563 goto end;
3564 }
3565
3566 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3567 if (!copy) {
3568 goto end;
3569 }
3570
3571 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3572 parent);
3573 copy_array->declaration = array->declaration;
3574 end:
3575 bt_put(copy_element);
3576 return copy;
3577 }
3578
3579 static
3580 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3581 struct bt_ctf_field_type *type)
3582 {
3583 struct bt_ctf_field_type *copy = NULL, *copy_element;
3584 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3585
3586 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3587 parent);
3588 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3589 if (!copy_element) {
3590 goto end;
3591 }
3592
3593 copy = bt_ctf_field_type_sequence_create(copy_element,
3594 sequence->length_field_name->len ?
3595 sequence->length_field_name->str : NULL);
3596 if (!copy) {
3597 goto end;
3598 }
3599
3600 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3601 parent);
3602 copy_sequence->declaration = sequence->declaration;
3603 if (sequence->length_field_path) {
3604 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3605 sequence->length_field_path);
3606 if (!copy_sequence->length_field_path) {
3607 goto error;
3608 }
3609 }
3610 end:
3611 bt_put(copy_element);
3612 return copy;
3613 error:
3614 BT_PUT(copy);
3615 goto end;
3616 }
3617
3618 static
3619 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3620 struct bt_ctf_field_type *type)
3621 {
3622 struct bt_ctf_field_type *copy;
3623 struct bt_ctf_field_type_string *string, *copy_string;
3624
3625 copy = bt_ctf_field_type_string_create();
3626 if (!copy) {
3627 goto end;
3628 }
3629
3630 string = container_of(type, struct bt_ctf_field_type_string,
3631 parent);
3632 copy_string = container_of(type, struct bt_ctf_field_type_string,
3633 parent);
3634 copy_string->declaration = string->declaration;
3635 end:
3636 return copy;
3637 }
3638
3639 static
3640 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3641 struct bt_ctf_field_type *type_b)
3642 {
3643 int ret = 1;
3644 struct bt_ctf_field_type_integer *integer_a;
3645 struct bt_ctf_field_type_integer *integer_b;
3646 struct declaration_integer *decl_a;
3647 struct declaration_integer *decl_b;
3648
3649 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3650 parent);
3651 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3652 parent);
3653 decl_a = &integer_a->declaration;
3654 decl_b = &integer_b->declaration;
3655
3656 /* Length */
3657 if (decl_a->len != decl_b->len) {
3658 goto end;
3659 }
3660
3661 /*
3662 * Compare user byte orders only, not the cached,
3663 * real byte orders.
3664 */
3665 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3666 goto end;
3667 }
3668
3669 /* Signedness */
3670 if (decl_a->signedness != decl_b->signedness) {
3671 goto end;
3672 }
3673
3674 /* Base */
3675 if (decl_a->base != decl_b->base) {
3676 goto end;
3677 }
3678
3679 /* Encoding */
3680 if (decl_a->encoding != decl_b->encoding) {
3681 goto end;
3682 }
3683
3684 /* Mapped clock */
3685 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3686 goto end;
3687 }
3688
3689 /* Equal */
3690 ret = 0;
3691
3692 end:
3693 return ret;
3694 }
3695
3696 static
3697 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3698 struct bt_ctf_field_type *type_b)
3699 {
3700 int ret = 1;
3701 struct bt_ctf_field_type_floating_point *float_a;
3702 struct bt_ctf_field_type_floating_point *float_b;
3703
3704 float_a = container_of(type_a,
3705 struct bt_ctf_field_type_floating_point, parent);
3706 float_b = container_of(type_b,
3707 struct bt_ctf_field_type_floating_point, parent);
3708
3709 /* Sign length */
3710 if (float_a->sign.len != float_b->sign.len) {
3711 goto end;
3712 }
3713
3714 /* Exponent length */
3715 if (float_a->exp.len != float_b->exp.len) {
3716 goto end;
3717 }
3718
3719 /* Mantissa length */
3720 if (float_a->mantissa.len != float_b->mantissa.len) {
3721 goto end;
3722 }
3723
3724 /*
3725 * Compare user byte orders only, not the cached,
3726 * real byte orders.
3727 */
3728 if (float_a->user_byte_order != float_b->user_byte_order) {
3729 goto end;
3730 }
3731
3732 /* Equal */
3733 ret = 0;
3734
3735 end:
3736 return ret;
3737 }
3738
3739 static
3740 int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3741 struct enumeration_mapping *mapping_b)
3742 {
3743 int ret = 1;
3744
3745 /* Label */
3746 if (mapping_a->string != mapping_b->string) {
3747 goto end;
3748 }
3749
3750 /* Range start */
3751 if (mapping_a->range_start._unsigned !=
3752 mapping_b->range_start._unsigned) {
3753 goto end;
3754 }
3755
3756 /* Range end */
3757 if (mapping_a->range_end._unsigned !=
3758 mapping_b->range_end._unsigned) {
3759 goto end;
3760 }
3761
3762 /* Equal */
3763 ret = 0;
3764
3765 end:
3766 return ret;
3767 }
3768
3769 static
3770 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3771 struct bt_ctf_field_type *type_b)
3772 {
3773 int ret = 1;
3774 int i;
3775 struct bt_ctf_field_type_enumeration *enum_a;
3776 struct bt_ctf_field_type_enumeration *enum_b;
3777
3778 enum_a = container_of(type_a,
3779 struct bt_ctf_field_type_enumeration, parent);
3780 enum_b = container_of(type_b,
3781 struct bt_ctf_field_type_enumeration, parent);
3782
3783 /* Container field type */
3784 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3785 if (ret) {
3786 goto end;
3787 }
3788
3789 ret = 1;
3790
3791 /* Entries */
3792 if (enum_a->entries->len != enum_b->entries->len) {
3793 goto end;
3794 }
3795
3796 for (i = 0; i < enum_a->entries->len; ++i) {
3797 struct enumeration_mapping *mapping_a =
3798 g_ptr_array_index(enum_a->entries, i);
3799 struct enumeration_mapping *mapping_b =
3800 g_ptr_array_index(enum_b->entries, i);
3801
3802 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3803 goto end;
3804 }
3805 }
3806
3807 /* Equal */
3808 ret = 0;
3809
3810 end:
3811 return ret;
3812 }
3813
3814 static
3815 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3816 struct bt_ctf_field_type *type_b)
3817 {
3818 int ret = 1;
3819 struct bt_ctf_field_type_string *string_a;
3820 struct bt_ctf_field_type_string *string_b;
3821
3822 string_a = container_of(type_a,
3823 struct bt_ctf_field_type_string, parent);
3824 string_b = container_of(type_b,
3825 struct bt_ctf_field_type_string, parent);
3826
3827 /* Encoding */
3828 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3829 goto end;
3830 }
3831
3832 /* Equal */
3833 ret = 0;
3834
3835 end:
3836 return ret;
3837 }
3838
3839 static
3840 int compare_structure_fields(struct structure_field *field_a,
3841 struct structure_field *field_b)
3842 {
3843 int ret = 1;
3844
3845 /* Label */
3846 if (field_a->name != field_b->name) {
3847 goto end;
3848 }
3849
3850 /* Type */
3851 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3852
3853 end:
3854 return ret;
3855 }
3856
3857 static
3858 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3859 struct bt_ctf_field_type *type_b)
3860 {
3861 int ret = 1;
3862 int i;
3863 struct bt_ctf_field_type_structure *struct_a;
3864 struct bt_ctf_field_type_structure *struct_b;
3865
3866 struct_a = container_of(type_a,
3867 struct bt_ctf_field_type_structure, parent);
3868 struct_b = container_of(type_b,
3869 struct bt_ctf_field_type_structure, parent);
3870
3871 /* Alignment */
3872 if (bt_ctf_field_type_get_alignment(type_a) !=
3873 bt_ctf_field_type_get_alignment(type_b)) {
3874 goto end;
3875 }
3876
3877 /* Fields */
3878 if (struct_a->fields->len != struct_b->fields->len) {
3879 goto end;
3880 }
3881
3882 for (i = 0; i < struct_a->fields->len; ++i) {
3883 struct structure_field *field_a =
3884 g_ptr_array_index(struct_a->fields, i);
3885 struct structure_field *field_b =
3886 g_ptr_array_index(struct_b->fields, i);
3887
3888 ret = compare_structure_fields(field_a, field_b);
3889 if (ret) {
3890 goto end;
3891 }
3892 }
3893
3894 /* Equal */
3895 ret = 0;
3896
3897 end:
3898 return ret;
3899 }
3900
3901 static
3902 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3903 struct bt_ctf_field_type *type_b)
3904 {
3905 int ret = 1;
3906 int i;
3907 struct bt_ctf_field_type_variant *variant_a;
3908 struct bt_ctf_field_type_variant *variant_b;
3909
3910 variant_a = container_of(type_a,
3911 struct bt_ctf_field_type_variant, parent);
3912 variant_b = container_of(type_b,
3913 struct bt_ctf_field_type_variant, parent);
3914
3915 /* Tag name */
3916 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3917 goto end;
3918 }
3919
3920 /* Tag type */
3921 ret = bt_ctf_field_type_compare(
3922 (struct bt_ctf_field_type *) variant_a->tag,
3923 (struct bt_ctf_field_type *) variant_b->tag);
3924 if (ret) {
3925 goto end;
3926 }
3927
3928 ret = 1;
3929
3930 /* Fields */
3931 if (variant_a->fields->len != variant_b->fields->len) {
3932 goto end;
3933 }
3934
3935 for (i = 0; i < variant_a->fields->len; ++i) {
3936 struct structure_field *field_a =
3937 g_ptr_array_index(variant_a->fields, i);
3938 struct structure_field *field_b =
3939 g_ptr_array_index(variant_b->fields, i);
3940
3941 ret = compare_structure_fields(field_a, field_b);
3942 if (ret) {
3943 goto end;
3944 }
3945 }
3946
3947 /* Equal */
3948 ret = 0;
3949
3950 end:
3951 return ret;
3952 }
3953
3954 static
3955 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3956 struct bt_ctf_field_type *type_b)
3957 {
3958 int ret = 1;
3959 struct bt_ctf_field_type_array *array_a;
3960 struct bt_ctf_field_type_array *array_b;
3961
3962 array_a = container_of(type_a,
3963 struct bt_ctf_field_type_array, parent);
3964 array_b = container_of(type_b,
3965 struct bt_ctf_field_type_array, parent);
3966
3967 /* Length */
3968 if (array_a->length != array_b->length) {
3969 goto end;
3970 }
3971
3972 /* Element type */
3973 ret = bt_ctf_field_type_compare(array_a->element_type,
3974 array_b->element_type);
3975
3976 end:
3977 return ret;
3978 }
3979
3980 static
3981 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
3982 struct bt_ctf_field_type *type_b)
3983 {
3984 int ret = -1;
3985 struct bt_ctf_field_type_sequence *sequence_a;
3986 struct bt_ctf_field_type_sequence *sequence_b;
3987
3988 sequence_a = container_of(type_a,
3989 struct bt_ctf_field_type_sequence, parent);
3990 sequence_b = container_of(type_b,
3991 struct bt_ctf_field_type_sequence, parent);
3992
3993 /* Length name */
3994 if (strcmp(sequence_a->length_field_name->str,
3995 sequence_b->length_field_name->str)) {
3996 goto end;
3997 }
3998
3999 /* Element type */
4000 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4001 sequence_b->element_type);
4002
4003 end:
4004 return ret;
4005 }
4006
4007 int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4008 struct bt_ctf_field_type *type_b)
4009 {
4010 int ret = 1;
4011
4012 if (type_a == type_b) {
4013 /* Same reference: equal (even if both are NULL) */
4014 ret = 0;
4015 goto end;
4016 }
4017
4018 if (!type_a || !type_b) {
4019 ret = -1;
4020 goto end;
4021 }
4022
4023 if (type_a->declaration->id != type_b->declaration->id) {
4024 /* Different type IDs */
4025 goto end;
4026 }
4027
4028 if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
4029 /* Both have unknown type IDs */
4030 goto end;
4031 }
4032
4033 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4034
4035 end:
4036 return ret;
4037 }
4038
4039 BT_HIDDEN
4040 int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4041 {
4042 int field_count = -1;
4043 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4044
4045 switch (type_id) {
4046 case CTF_TYPE_STRUCT:
4047 field_count =
4048 bt_ctf_field_type_structure_get_field_count(field_type);
4049 break;
4050 case CTF_TYPE_VARIANT:
4051 field_count =
4052 bt_ctf_field_type_variant_get_field_count(field_type);
4053 break;
4054 case CTF_TYPE_ARRAY:
4055 case CTF_TYPE_SEQUENCE:
4056 /*
4057 * Array and sequence types always contain a single member
4058 * (the element type).
4059 */
4060 field_count = 1;
4061 break;
4062 default:
4063 break;
4064 }
4065
4066 return field_count;
4067 }
4068
4069 BT_HIDDEN
4070 struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4071 struct bt_ctf_field_type *field_type, int index)
4072 {
4073 struct bt_ctf_field_type *field = NULL;
4074 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4075
4076 switch (type_id) {
4077 case CTF_TYPE_STRUCT:
4078 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4079 index);
4080 break;
4081 case CTF_TYPE_VARIANT:
4082 {
4083 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
4084 &field, index);
4085 if (ret) {
4086 field = NULL;
4087 goto end;
4088 }
4089 break;
4090 }
4091 case CTF_TYPE_ARRAY:
4092 field = bt_ctf_field_type_array_get_element_type(field_type);
4093 break;
4094 case CTF_TYPE_SEQUENCE:
4095 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4096 break;
4097 default:
4098 break;
4099 }
4100 end:
4101 return field;
4102 }
4103
4104 BT_HIDDEN
4105 int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4106 const char *name)
4107 {
4108 int field_index = -1;
4109 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4110
4111 switch (type_id) {
4112 case CTF_TYPE_STRUCT:
4113 field_index = bt_ctf_field_type_structure_get_field_name_index(
4114 field_type, name);
4115 break;
4116 case CTF_TYPE_VARIANT:
4117 field_index = bt_ctf_field_type_variant_get_field_name_index(
4118 field_type, name);
4119 break;
4120 default:
4121 break;
4122 }
4123
4124 return field_index;
4125 }
4126
4127 struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4128 struct bt_ctf_field_type *type)
4129 {
4130 struct bt_ctf_field_path *field_path = NULL;
4131 struct bt_ctf_field_type_variant *variant;
4132
4133 if (!type || !bt_ctf_field_type_is_variant(type)) {
4134 goto end;
4135 }
4136
4137 variant = container_of(type, struct bt_ctf_field_type_variant,
4138 parent);
4139 field_path = bt_get(variant->tag_field_path);
4140 end:
4141 return field_path;
4142 }
4143
4144 struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
4145 struct bt_ctf_field_type *type)
4146 {
4147 struct bt_ctf_field_path *field_path = NULL;
4148 struct bt_ctf_field_type_sequence *sequence;
4149
4150 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4151 goto end;
4152 }
4153
4154 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4155 parent);
4156 field_path = bt_get(sequence->length_field_path);
4157 end:
4158 return field_path;
4159 }
This page took 0.159191 seconds and 4 git commands to generate.