ir: make bt_ctf_field_type_copy() public
[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 if (!type || !field_type || type->frozen ||
1414 bt_ctf_validate_identifier(field_name) ||
1415 (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
1416 ret = -1;
1417 goto end;
1418 }
1419
1420 structure = container_of(type,
1421 struct bt_ctf_field_type_structure, parent);
1422 if (add_structure_field(structure->fields,
1423 structure->field_name_to_index, field_type, field_name)) {
1424 ret = -1;
1425 goto end;
1426 }
1427 end:
1428 return ret;
1429 }
1430
1431 int bt_ctf_field_type_structure_get_field_count(
1432 struct bt_ctf_field_type *type)
1433 {
1434 int ret = 0;
1435 struct bt_ctf_field_type_structure *structure;
1436
1437 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
1438 ret = -1;
1439 goto end;
1440 }
1441
1442 structure = container_of(type, struct bt_ctf_field_type_structure,
1443 parent);
1444 ret = (int) structure->fields->len;
1445 end:
1446 return ret;
1447 }
1448
1449 int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
1450 const char **field_name, struct bt_ctf_field_type **field_type,
1451 int index)
1452 {
1453 struct bt_ctf_field_type_structure *structure;
1454 struct structure_field *field;
1455 int ret = 0;
1456
1457 if (!type || index < 0 ||
1458 (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
1459 ret = -1;
1460 goto end;
1461 }
1462
1463 structure = container_of(type, struct bt_ctf_field_type_structure,
1464 parent);
1465 if (index >= structure->fields->len) {
1466 ret = -1;
1467 goto end;
1468 }
1469
1470 field = g_ptr_array_index(structure->fields, index);
1471 if (field_type) {
1472 *field_type = field->type;
1473 bt_get(field->type);
1474 }
1475 if (field_name) {
1476 *field_name = g_quark_to_string(field->name);
1477 }
1478 end:
1479 return ret;
1480 }
1481
1482 struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
1483 struct bt_ctf_field_type *type,
1484 const char *name)
1485 {
1486 size_t index;
1487 GQuark name_quark;
1488 struct structure_field *field;
1489 struct bt_ctf_field_type_structure *structure;
1490 struct bt_ctf_field_type *field_type = NULL;
1491
1492 if (!type || !name) {
1493 goto end;
1494 }
1495
1496 name_quark = g_quark_try_string(name);
1497 if (!name_quark) {
1498 goto end;
1499 }
1500
1501 structure = container_of(type, struct bt_ctf_field_type_structure,
1502 parent);
1503 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
1504 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1505 goto end;
1506 }
1507
1508 field = structure->fields->pdata[index];
1509 field_type = field->type;
1510 bt_get(field_type);
1511 end:
1512 return field_type;
1513 }
1514
1515 struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
1516 struct bt_ctf_field_type *enum_tag, const char *tag_name)
1517 {
1518 struct bt_ctf_field_type_variant *variant = NULL;
1519
1520 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
1521 goto error;
1522 }
1523
1524 variant = g_new0(struct bt_ctf_field_type_variant, 1);
1525 if (!variant) {
1526 goto error;
1527 }
1528
1529 variant->parent.declaration = &variant->declaration.p;
1530 variant->parent.declaration->id = BT_CTF_TYPE_ID_VARIANT;
1531 variant->tag_name = g_string_new(tag_name);
1532 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1533 variant->fields = g_ptr_array_new_with_free_func(
1534 (GDestroyNotify) destroy_structure_field);
1535 if (enum_tag) {
1536 bt_get(enum_tag);
1537 variant->tag = container_of(enum_tag,
1538 struct bt_ctf_field_type_enumeration, parent);
1539 }
1540
1541 bt_ctf_field_type_init(&variant->parent, TRUE);
1542 /* A variant's alignment is undefined */
1543 variant->parent.declaration->alignment = 0;
1544 return &variant->parent;
1545 error:
1546 return NULL;
1547 }
1548
1549 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
1550 struct bt_ctf_field_type *type)
1551 {
1552 struct bt_ctf_field_type_variant *variant;
1553 struct bt_ctf_field_type *tag_type = NULL;
1554
1555 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1556 goto end;
1557 }
1558
1559 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1560 if (!variant->tag) {
1561 goto end;
1562 }
1563
1564 tag_type = &variant->tag->parent;
1565 bt_get(tag_type);
1566 end:
1567 return tag_type;
1568 }
1569
1570 const char *bt_ctf_field_type_variant_get_tag_name(
1571 struct bt_ctf_field_type *type)
1572 {
1573 struct bt_ctf_field_type_variant *variant;
1574 const char *tag_name = NULL;
1575
1576 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1577 goto end;
1578 }
1579
1580 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1581 if (variant->tag_name->len == 0) {
1582 goto end;
1583 }
1584
1585 tag_name = variant->tag_name->str;
1586 end:
1587 return tag_name;
1588 }
1589
1590 int bt_ctf_field_type_variant_set_tag_name(
1591 struct bt_ctf_field_type *type, const char *name)
1592 {
1593 int ret = 0;
1594 struct bt_ctf_field_type_variant *variant;
1595
1596 if (!type || type->frozen ||
1597 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT) ||
1598 bt_ctf_validate_identifier(name)) {
1599 ret = -1;
1600 goto end;
1601 }
1602
1603 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1604 g_string_assign(variant->tag_name, name);
1605 end:
1606 return ret;
1607 }
1608
1609 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
1610 struct bt_ctf_field_type *field_type,
1611 const char *field_name)
1612 {
1613 size_t i;
1614 int ret = 0;
1615 struct bt_ctf_field_type_variant *variant;
1616 GQuark field_name_quark = g_quark_from_string(field_name);
1617
1618 if (!type || !field_type || type->frozen ||
1619 bt_ctf_validate_identifier(field_name) ||
1620 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1621 ret = -1;
1622 goto end;
1623 }
1624
1625 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1626
1627 /* The user has explicitly provided a tag; validate against it. */
1628 if (variant->tag) {
1629 int name_found = 0;
1630
1631 /* Make sure this name is present in the enum tag */
1632 for (i = 0; i < variant->tag->entries->len; i++) {
1633 struct enumeration_mapping *mapping =
1634 g_ptr_array_index(variant->tag->entries, i);
1635
1636 if (mapping->string == field_name_quark) {
1637 name_found = 1;
1638 break;
1639 }
1640 }
1641
1642 if (!name_found) {
1643 /* Validation failed */
1644 ret = -1;
1645 goto end;
1646 }
1647 }
1648
1649 if (add_structure_field(variant->fields, variant->field_name_to_index,
1650 field_type, field_name)) {
1651 ret = -1;
1652 goto end;
1653 }
1654 end:
1655 return ret;
1656 }
1657
1658 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
1659 struct bt_ctf_field_type *type,
1660 const char *field_name)
1661 {
1662 size_t index;
1663 GQuark name_quark;
1664 struct structure_field *field;
1665 struct bt_ctf_field_type_variant *variant;
1666 struct bt_ctf_field_type *field_type = NULL;
1667
1668 if (!type || !field_name) {
1669 goto end;
1670 }
1671
1672 name_quark = g_quark_try_string(field_name);
1673 if (!name_quark) {
1674 goto end;
1675 }
1676
1677 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
1678 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
1679 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
1680 goto end;
1681 }
1682
1683 field = g_ptr_array_index(variant->fields, index);
1684 field_type = field->type;
1685 bt_get(field_type);
1686 end:
1687 return field_type;
1688 }
1689
1690 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
1691 struct bt_ctf_field_type *type,
1692 struct bt_ctf_field *tag)
1693 {
1694 const char *enum_value;
1695 struct bt_ctf_field_type *field_type = NULL;
1696
1697 if (!type || !tag || type->declaration->id != BT_CTF_TYPE_ID_VARIANT) {
1698 goto end;
1699 }
1700
1701 enum_value = bt_ctf_field_enumeration_get_mapping_name(tag);
1702 if (!enum_value) {
1703 goto end;
1704 }
1705
1706 /* Already increments field_type's reference count */
1707 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1708 type, enum_value);
1709 end:
1710 return field_type;
1711 }
1712
1713 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1714 {
1715 int ret = 0;
1716 struct bt_ctf_field_type_variant *variant;
1717
1718 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1719 ret = -1;
1720 goto end;
1721 }
1722
1723 variant = container_of(type, struct bt_ctf_field_type_variant,
1724 parent);
1725 ret = (int) variant->fields->len;
1726 end:
1727 return ret;
1728
1729 }
1730
1731 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1732 const char **field_name, struct bt_ctf_field_type **field_type,
1733 int index)
1734 {
1735 struct bt_ctf_field_type_variant *variant;
1736 struct structure_field *field;
1737 int ret = 0;
1738
1739 if (!type || index < 0 ||
1740 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1741 ret = -1;
1742 goto end;
1743 }
1744
1745 variant = container_of(type, struct bt_ctf_field_type_variant,
1746 parent);
1747 if (index >= variant->fields->len) {
1748 ret = -1;
1749 goto end;
1750 }
1751
1752 field = g_ptr_array_index(variant->fields, index);
1753 if (field_type) {
1754 *field_type = field->type;
1755 bt_get(field->type);
1756 }
1757 if (field_name) {
1758 *field_name = g_quark_to_string(field->name);
1759 }
1760 end:
1761 return ret;
1762 }
1763
1764 struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1765 struct bt_ctf_field_type *element_type,
1766 unsigned int length)
1767 {
1768 struct bt_ctf_field_type_array *array = NULL;
1769
1770 if (!element_type || length == 0) {
1771 goto error;
1772 }
1773
1774 array = g_new0(struct bt_ctf_field_type_array, 1);
1775 if (!array) {
1776 goto error;
1777 }
1778
1779 array->parent.declaration = &array->declaration.p;
1780 array->parent.declaration->id = BT_CTF_TYPE_ID_ARRAY;
1781
1782 bt_get(element_type);
1783 array->element_type = element_type;
1784 array->length = length;
1785 bt_ctf_field_type_init(&array->parent, FALSE);
1786 return &array->parent;
1787 error:
1788 return NULL;
1789 }
1790
1791 struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1792 struct bt_ctf_field_type *type)
1793 {
1794 struct bt_ctf_field_type *ret = NULL;
1795 struct bt_ctf_field_type_array *array;
1796
1797 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1798 goto end;
1799 }
1800
1801 array = container_of(type, struct bt_ctf_field_type_array, parent);
1802 ret = array->element_type;
1803 bt_get(ret);
1804 end:
1805 return ret;
1806 }
1807
1808 BT_HIDDEN
1809 int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
1810 struct bt_ctf_field_type *element_type)
1811 {
1812 int ret = 0;
1813 struct bt_ctf_field_type_array *array;
1814
1815 if (!type || !element_type ||
1816 (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1817 ret = -1;
1818 goto end;
1819 }
1820
1821 array = container_of(type, struct bt_ctf_field_type_array, parent);
1822
1823 if (array->element_type) {
1824 BT_PUT(array->element_type);
1825 }
1826
1827 array->element_type = element_type;
1828 bt_get(array->element_type);
1829
1830 end:
1831 return ret;
1832 }
1833
1834 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
1835 {
1836 int64_t ret;
1837 struct bt_ctf_field_type_array *array;
1838
1839 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1840 ret = -1;
1841 goto end;
1842 }
1843
1844 array = container_of(type, struct bt_ctf_field_type_array, parent);
1845 ret = (int64_t) array->length;
1846 end:
1847 return ret;
1848 }
1849
1850 struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1851 struct bt_ctf_field_type *element_type,
1852 const char *length_field_name)
1853 {
1854 struct bt_ctf_field_type_sequence *sequence = NULL;
1855
1856 if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
1857 goto error;
1858 }
1859
1860 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
1861 if (!sequence) {
1862 goto error;
1863 }
1864
1865 sequence->parent.declaration = &sequence->declaration.p;
1866 sequence->parent.declaration->id = BT_CTF_TYPE_ID_SEQUENCE;
1867 bt_get(element_type);
1868 sequence->element_type = element_type;
1869 sequence->length_field_name = g_string_new(length_field_name);
1870 bt_ctf_field_type_init(&sequence->parent, FALSE);
1871 return &sequence->parent;
1872 error:
1873 return NULL;
1874 }
1875
1876 struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
1877 struct bt_ctf_field_type *type)
1878 {
1879 struct bt_ctf_field_type *ret = NULL;
1880 struct bt_ctf_field_type_sequence *sequence;
1881
1882 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
1883 goto end;
1884 }
1885
1886 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1887 parent);
1888 ret = sequence->element_type;
1889 bt_get(ret);
1890 end:
1891 return ret;
1892 }
1893
1894 BT_HIDDEN
1895 int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
1896 struct bt_ctf_field_type *element_type)
1897 {
1898 int ret = 0;
1899 struct bt_ctf_field_type_sequence *sequence;
1900
1901 if (!type || !element_type ||
1902 (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
1903 ret = -1;
1904 goto end;
1905 }
1906
1907 sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
1908
1909 if (sequence->element_type) {
1910 BT_PUT(sequence->element_type);
1911 }
1912
1913 sequence->element_type = element_type;
1914 bt_get(sequence->element_type);
1915
1916 end:
1917 return ret;
1918 }
1919
1920 const char *bt_ctf_field_type_sequence_get_length_field_name(
1921 struct bt_ctf_field_type *type)
1922 {
1923 const char *ret = NULL;
1924 struct bt_ctf_field_type_sequence *sequence;
1925
1926 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
1927 goto end;
1928 }
1929
1930 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1931 parent);
1932 ret = sequence->length_field_name->str;
1933 end:
1934 return ret;
1935 }
1936
1937 struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1938 {
1939 struct bt_ctf_field_type_string *string =
1940 g_new0(struct bt_ctf_field_type_string, 1);
1941
1942 if (!string) {
1943 return NULL;
1944 }
1945
1946 string->parent.declaration = &string->declaration.p;
1947 string->parent.declaration->id = BT_CTF_TYPE_ID_STRING;
1948 bt_ctf_field_type_init(&string->parent, TRUE);
1949 string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
1950 string->parent.declaration->alignment = CHAR_BIT;
1951 return &string->parent;
1952 }
1953
1954 enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1955 struct bt_ctf_field_type *type)
1956 {
1957 struct bt_ctf_field_type_string *string;
1958 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
1959
1960 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRING)) {
1961 goto end;
1962 }
1963
1964 string = container_of(type, struct bt_ctf_field_type_string,
1965 parent);
1966 ret = string->declaration.encoding;
1967 end:
1968 return ret;
1969 }
1970
1971 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
1972 enum bt_ctf_string_encoding encoding)
1973 {
1974 int ret = 0;
1975 struct bt_ctf_field_type_string *string;
1976
1977 if (!type || type->declaration->id != BT_CTF_TYPE_ID_STRING ||
1978 (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
1979 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
1980 ret = -1;
1981 goto end;
1982 }
1983
1984 string = container_of(type, struct bt_ctf_field_type_string, parent);
1985 string->declaration.encoding = encoding;
1986 end:
1987 return ret;
1988 }
1989
1990 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1991 {
1992 int ret;
1993 enum bt_ctf_type_id type_id;
1994
1995 if (!type) {
1996 ret = -1;
1997 goto end;
1998 }
1999
2000 if (type->frozen) {
2001 ret = (int) type->declaration->alignment;
2002 goto end;
2003 }
2004
2005 type_id = bt_ctf_field_type_get_type_id(type);
2006 switch (type_id) {
2007 case BT_CTF_TYPE_ID_SEQUENCE:
2008 {
2009 struct bt_ctf_field_type *element =
2010 bt_ctf_field_type_sequence_get_element_type(type);
2011
2012 if (!element) {
2013 ret = -1;
2014 goto end;
2015 }
2016
2017 ret = bt_ctf_field_type_get_alignment(element);
2018 bt_put(element);
2019 break;
2020 }
2021 case BT_CTF_TYPE_ID_ARRAY:
2022 {
2023 struct bt_ctf_field_type *element =
2024 bt_ctf_field_type_array_get_element_type(type);
2025
2026 if (!element) {
2027 ret = -1;
2028 goto end;
2029 }
2030
2031 ret = bt_ctf_field_type_get_alignment(element);
2032 bt_put(element);
2033 break;
2034 }
2035 case BT_CTF_TYPE_ID_STRUCT:
2036 {
2037 int i, element_count;
2038
2039 element_count = bt_ctf_field_type_structure_get_field_count(
2040 type);
2041 if (element_count < 0) {
2042 ret = element_count;
2043 goto end;
2044 }
2045
2046 for (i = 0; i < element_count; i++) {
2047 struct bt_ctf_field_type *field;
2048 int field_alignment;
2049
2050 ret = bt_ctf_field_type_structure_get_field(type, NULL,
2051 &field, i);
2052 if (ret) {
2053 goto end;
2054 }
2055
2056 assert(field);
2057 field_alignment = bt_ctf_field_type_get_alignment(
2058 field);
2059 bt_put(field);
2060 if (field_alignment < 0) {
2061 ret = field_alignment;
2062 goto end;
2063 }
2064
2065 type->declaration->alignment = MAX(field_alignment,
2066 type->declaration->alignment);
2067 }
2068 ret = (int) type->declaration->alignment;
2069 break;
2070 }
2071 case BT_CTF_TYPE_ID_UNKNOWN:
2072 ret = -1;
2073 break;
2074 default:
2075 ret = (int) type->declaration->alignment;
2076 break;
2077 }
2078 end:
2079 return ret;
2080 }
2081
2082 static inline
2083 int is_power_of_two(unsigned int value)
2084 {
2085 return ((value & (value - 1)) == 0) && value > 0;
2086 }
2087
2088 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
2089 unsigned int alignment)
2090 {
2091 int ret = 0;
2092 enum bt_ctf_type_id type_id;
2093
2094 /* Alignment must be a power of two */
2095 if (!type || type->frozen || !is_power_of_two(alignment)) {
2096 ret = -1;
2097 goto end;
2098 }
2099
2100 type_id = bt_ctf_field_type_get_type_id(type);
2101 if (type_id == BT_CTF_TYPE_ID_UNKNOWN) {
2102 ret = -1;
2103 goto end;
2104 }
2105
2106 if (type->declaration->id == BT_CTF_TYPE_ID_STRING &&
2107 alignment != CHAR_BIT) {
2108 ret = -1;
2109 goto end;
2110 }
2111
2112 if (type_id == BT_CTF_TYPE_ID_VARIANT ||
2113 type_id == BT_CTF_TYPE_ID_SEQUENCE ||
2114 type_id == BT_CTF_TYPE_ID_ARRAY) {
2115 /* Setting an alignment on these types makes no sense */
2116 ret = -1;
2117 goto end;
2118 }
2119
2120 type->declaration->alignment = alignment;
2121 ret = 0;
2122 end:
2123 return ret;
2124 }
2125
2126 enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
2127 struct bt_ctf_field_type *type)
2128 {
2129 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
2130
2131 if (!type) {
2132 goto end;
2133 }
2134
2135 switch (type->declaration->id) {
2136 case BT_CTF_TYPE_ID_INTEGER:
2137 {
2138 struct bt_ctf_field_type_integer *integer = container_of(
2139 type, struct bt_ctf_field_type_integer, parent);
2140 ret = integer->user_byte_order;
2141 break;
2142 }
2143 case BT_CTF_TYPE_ID_FLOAT:
2144 {
2145 struct bt_ctf_field_type_floating_point *floating_point =
2146 container_of(type,
2147 struct bt_ctf_field_type_floating_point,
2148 parent);
2149 ret = floating_point->user_byte_order;
2150 break;
2151 }
2152 default:
2153 goto end;
2154 }
2155
2156 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2157 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2158 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2159 ret == BT_CTF_BYTE_ORDER_NETWORK);
2160
2161 end:
2162 return ret;
2163 }
2164
2165 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2166 enum bt_ctf_byte_order byte_order)
2167 {
2168 int ret = 0;
2169 int internal_byte_order;
2170 enum bt_ctf_type_id type_id;
2171
2172 if (!type || type->frozen) {
2173 ret = -1;
2174 goto end;
2175 }
2176
2177 switch (byte_order) {
2178 case BT_CTF_BYTE_ORDER_NATIVE:
2179 /* Leave unset. Will be initialized by parent. */
2180 internal_byte_order = 0;
2181 break;
2182 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2183 internal_byte_order = LITTLE_ENDIAN;
2184 break;
2185 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2186 case BT_CTF_BYTE_ORDER_NETWORK:
2187 internal_byte_order = BIG_ENDIAN;
2188 break;
2189 default:
2190 ret = -1;
2191 goto end;
2192 }
2193
2194 type_id = type->declaration->id;
2195 if (set_byte_order_funcs[type_id]) {
2196 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
2197 }
2198 end:
2199 return ret;
2200 }
2201
2202 enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
2203 struct bt_ctf_field_type *type)
2204 {
2205 if (!type) {
2206 return BT_CTF_TYPE_ID_UNKNOWN;
2207 }
2208
2209 return type->declaration->id;
2210 }
2211
2212 int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2213 {
2214 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
2215 }
2216
2217 int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2218 {
2219 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
2220 }
2221
2222 int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2223 {
2224 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
2225 }
2226
2227 int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2228 {
2229 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
2230 }
2231
2232 int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2233 {
2234 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
2235 }
2236
2237 int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2238 {
2239 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
2240 }
2241
2242 int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2243 {
2244 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
2245 }
2246
2247 int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2248 {
2249 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
2250 }
2251
2252 void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2253 {
2254 bt_get(type);
2255 }
2256
2257 void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2258 {
2259 bt_put(type);
2260 }
2261
2262 BT_HIDDEN
2263 void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2264 {
2265 if (!type) {
2266 return;
2267 }
2268
2269 type->freeze(type);
2270 }
2271
2272 BT_HIDDEN
2273 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2274 struct bt_ctf_field_type_variant *variant,
2275 int64_t tag_value)
2276 {
2277 struct bt_ctf_field_type *type = NULL;
2278 GQuark field_name_quark;
2279 gpointer index;
2280 struct structure_field *field_entry;
2281 struct range_overlap_query query = {
2282 .range_start._signed = tag_value,
2283 .range_end._signed = tag_value,
2284 .mapping_name = 0, .overlaps = 0};
2285
2286 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2287 &query);
2288 if (!query.overlaps) {
2289 goto end;
2290 }
2291
2292 field_name_quark = query.mapping_name;
2293 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2294 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2295 goto end;
2296 }
2297
2298 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
2299 type = field_entry->type;
2300 end:
2301 return type;
2302 }
2303
2304 BT_HIDDEN
2305 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
2306 struct bt_ctf_field_type_variant *variant,
2307 uint64_t tag_value)
2308 {
2309 struct bt_ctf_field_type *type = NULL;
2310 GQuark field_name_quark;
2311 gpointer index;
2312 struct structure_field *field_entry;
2313 struct range_overlap_query query = {
2314 .range_start._unsigned = tag_value,
2315 .range_end._unsigned = tag_value,
2316 .mapping_name = 0, .overlaps = 0};
2317
2318 g_ptr_array_foreach(variant->tag->entries,
2319 check_ranges_overlap_unsigned,
2320 &query);
2321 if (!query.overlaps) {
2322 goto end;
2323 }
2324
2325 field_name_quark = query.mapping_name;
2326 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2327 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2328 goto end;
2329 }
2330
2331 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2332 type = field_entry->type;
2333 end:
2334 return type;
2335 }
2336
2337 BT_HIDDEN
2338 int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2339 struct metadata_context *context)
2340 {
2341 int ret;
2342
2343 if (!type || !context) {
2344 ret = -1;
2345 goto end;
2346 }
2347
2348 /* Make sure field type is valid before serializing it */
2349 ret = bt_ctf_field_type_validate(type);
2350
2351 if (ret) {
2352 goto end;
2353 }
2354
2355 ret = type->serialize(type, context);
2356 end:
2357 return ret;
2358 }
2359
2360 BT_HIDDEN
2361 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2362 int byte_order)
2363 {
2364 if (!type) {
2365 return;
2366 }
2367
2368 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2369 if (set_byte_order_funcs[type->declaration->id]) {
2370 set_byte_order_funcs[type->declaration->id](type,
2371 byte_order, 1);
2372 }
2373 }
2374
2375 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2376 {
2377 struct bt_ctf_field_type *copy = NULL;
2378
2379 if (!type) {
2380 goto end;
2381 }
2382
2383 copy = type_copy_funcs[type->declaration->id](type);
2384 end:
2385 return copy;
2386 }
2387
2388 BT_HIDDEN
2389 int bt_ctf_field_type_structure_get_field_name_index(
2390 struct bt_ctf_field_type *type, const char *name)
2391 {
2392 int ret;
2393 size_t index;
2394 GQuark name_quark;
2395 struct bt_ctf_field_type_structure *structure;
2396
2397 if (!type || !name ||
2398 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2399 ret = -1;
2400 goto end;
2401 }
2402
2403 name_quark = g_quark_try_string(name);
2404 if (!name_quark) {
2405 ret = -1;
2406 goto end;
2407 }
2408
2409 structure = container_of(type, struct bt_ctf_field_type_structure,
2410 parent);
2411 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2412 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2413 ret = -1;
2414 goto end;
2415 }
2416 ret = (int) index;
2417 end:
2418 return ret;
2419 }
2420
2421 BT_HIDDEN
2422 int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2423 struct bt_ctf_field_type *field, int index)
2424 {
2425 int ret = 0;
2426 struct bt_ctf_field_type_structure *structure;
2427
2428 if (!type || !field ||
2429 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2430 ret = -1;
2431 goto end;
2432 }
2433
2434 structure = container_of(type, struct bt_ctf_field_type_structure,
2435 parent);
2436 if (index < 0 || index >= structure->fields->len) {
2437 ret = -1;
2438 goto end;
2439 }
2440
2441 bt_get(field);
2442 bt_put(((struct structure_field *)
2443 g_ptr_array_index(structure->fields, index))->type);
2444 ((struct structure_field *) structure->fields->pdata[index])->type =
2445 field;
2446 end:
2447 return ret;
2448 }
2449
2450 BT_HIDDEN
2451 int bt_ctf_field_type_variant_get_field_name_index(
2452 struct bt_ctf_field_type *type, const char *name)
2453 {
2454 int ret;
2455 size_t index;
2456 GQuark name_quark;
2457 struct bt_ctf_field_type_variant *variant;
2458
2459 if (!type || !name ||
2460 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2461 ret = -1;
2462 goto end;
2463 }
2464
2465 name_quark = g_quark_try_string(name);
2466 if (!name_quark) {
2467 ret = -1;
2468 goto end;
2469 }
2470
2471 variant = container_of(type, struct bt_ctf_field_type_variant,
2472 parent);
2473 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2474 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2475 ret = -1;
2476 goto end;
2477 }
2478 ret = (int) index;
2479 end:
2480 return ret;
2481 }
2482
2483 BT_HIDDEN
2484 int bt_ctf_field_type_sequence_set_length_field_path(
2485 struct bt_ctf_field_type *type,
2486 struct bt_ctf_field_path *path)
2487 {
2488 int ret = 0;
2489 struct bt_ctf_field_type_sequence *sequence;
2490
2491 if (!type || bt_ctf_field_type_get_type_id(type) !=
2492 BT_CTF_TYPE_ID_SEQUENCE) {
2493 ret = -1;
2494 goto end;
2495 }
2496
2497 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2498 parent);
2499 bt_get(path);
2500 BT_MOVE(sequence->length_field_path, path);
2501 end:
2502 return ret;
2503 }
2504
2505 BT_HIDDEN
2506 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2507 struct bt_ctf_field_path *path)
2508 {
2509 int ret = 0;
2510 struct bt_ctf_field_type_variant *variant;
2511
2512 if (!type || bt_ctf_field_type_get_type_id(type) !=
2513 BT_CTF_TYPE_ID_VARIANT) {
2514 ret = -1;
2515 goto end;
2516 }
2517
2518 variant = container_of(type, struct bt_ctf_field_type_variant,
2519 parent);
2520 bt_get(path);
2521 BT_MOVE(variant->tag_field_path, path);
2522 end:
2523 return ret;
2524 }
2525
2526 BT_HIDDEN
2527 int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
2528 struct bt_ctf_field_type *tag)
2529 {
2530 int ret = 0;
2531 struct bt_ctf_field_type_variant *variant;
2532
2533 if (!type || !tag ||
2534 bt_ctf_field_type_get_type_id(tag) !=
2535 BT_CTF_TYPE_ID_ENUM) {
2536 ret = -1;
2537 goto end;
2538 }
2539
2540 variant = container_of(type, struct bt_ctf_field_type_variant,
2541 parent);
2542 bt_get(tag);
2543 if (variant->tag) {
2544 bt_put(&variant->tag->parent);
2545 }
2546 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2547 parent);
2548 end:
2549 return ret;
2550 }
2551
2552 BT_HIDDEN
2553 int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2554 struct bt_ctf_field_type *field, int index)
2555 {
2556 int ret = 0;
2557 struct bt_ctf_field_type_variant *variant;
2558
2559 if (!type || !field ||
2560 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2561 ret = -1;
2562 goto end;
2563 }
2564
2565 variant = container_of(type, struct bt_ctf_field_type_variant,
2566 parent);
2567 if (index < 0 || index >= variant->fields->len) {
2568 ret = -1;
2569 goto end;
2570 }
2571
2572 bt_get(field);
2573 bt_put(((struct structure_field *)
2574 g_ptr_array_index(variant->fields, index))->type);
2575 ((struct structure_field *) variant->fields->pdata[index])->type =
2576 field;
2577 end:
2578 return ret;
2579 }
2580
2581 static
2582 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
2583 {
2584 struct bt_ctf_field_type_integer *integer =
2585 (struct bt_ctf_field_type_integer *) type;
2586
2587 if (!type) {
2588 return;
2589 }
2590
2591 bt_put(integer->mapped_clock);
2592 g_free(integer);
2593 }
2594
2595 static
2596 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
2597 {
2598 struct bt_ctf_field_type_enumeration *enumeration =
2599 (struct bt_ctf_field_type_enumeration *) type;
2600
2601 if (!type) {
2602 return;
2603 }
2604
2605 g_ptr_array_free(enumeration->entries, TRUE);
2606 bt_put(enumeration->container);
2607 g_free(enumeration);
2608 }
2609
2610 static
2611 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
2612 {
2613 struct bt_ctf_field_type_floating_point *floating_point =
2614 (struct bt_ctf_field_type_floating_point *) type;
2615
2616 if (!type) {
2617 return;
2618 }
2619
2620 g_free(floating_point);
2621 }
2622
2623 static
2624 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
2625 {
2626 struct bt_ctf_field_type_structure *structure =
2627 (struct bt_ctf_field_type_structure *) type;
2628
2629 if (!type) {
2630 return;
2631 }
2632
2633 g_ptr_array_free(structure->fields, TRUE);
2634 g_hash_table_destroy(structure->field_name_to_index);
2635 g_free(structure);
2636 }
2637
2638 static
2639 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
2640 {
2641 struct bt_ctf_field_type_variant *variant =
2642 (struct bt_ctf_field_type_variant *) type;
2643
2644 if (!type) {
2645 return;
2646 }
2647
2648 g_ptr_array_free(variant->fields, TRUE);
2649 g_hash_table_destroy(variant->field_name_to_index);
2650 g_string_free(variant->tag_name, TRUE);
2651 bt_put(&variant->tag->parent);
2652 BT_PUT(variant->tag_field_path);
2653 g_free(variant);
2654 }
2655
2656 static
2657 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
2658 {
2659 struct bt_ctf_field_type_array *array =
2660 (struct bt_ctf_field_type_array *) type;
2661
2662 if (!type) {
2663 return;
2664 }
2665
2666 bt_put(array->element_type);
2667 g_free(array);
2668 }
2669
2670 static
2671 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
2672 {
2673 struct bt_ctf_field_type_sequence *sequence =
2674 (struct bt_ctf_field_type_sequence *) type;
2675
2676 if (!type) {
2677 return;
2678 }
2679
2680 bt_put(sequence->element_type);
2681 g_string_free(sequence->length_field_name, TRUE);
2682 BT_PUT(sequence->length_field_path);
2683 g_free(sequence);
2684 }
2685
2686 static
2687 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
2688 {
2689 struct bt_ctf_field_type_string *string =
2690 (struct bt_ctf_field_type_string *) type;
2691
2692 if (!type) {
2693 return;
2694 }
2695
2696 g_free(string);
2697 }
2698
2699 static
2700 void generic_field_type_freeze(struct bt_ctf_field_type *type)
2701 {
2702 type->frozen = 1;
2703 }
2704
2705 static
2706 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2707 {
2708 struct bt_ctf_field_type_integer *integer_type = container_of(
2709 type, struct bt_ctf_field_type_integer, parent);
2710
2711 if (integer_type->mapped_clock) {
2712 bt_ctf_clock_freeze(integer_type->mapped_clock);
2713 }
2714
2715 generic_field_type_freeze(type);
2716 }
2717
2718 static
2719 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2720 {
2721 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2722 type, struct bt_ctf_field_type_enumeration, parent);
2723
2724 generic_field_type_freeze(type);
2725 bt_ctf_field_type_freeze(enumeration_type->container);
2726 }
2727
2728 static
2729 void freeze_structure_field(struct structure_field *field)
2730 {
2731 bt_ctf_field_type_freeze(field->type);
2732 }
2733
2734 static
2735 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2736 {
2737 struct bt_ctf_field_type_structure *structure_type = container_of(
2738 type, struct bt_ctf_field_type_structure, parent);
2739
2740 /* Cache the alignment */
2741 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2742 generic_field_type_freeze(type);
2743 g_ptr_array_foreach(structure_type->fields,
2744 (GFunc) freeze_structure_field, NULL);
2745 }
2746
2747 static
2748 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2749 {
2750 struct bt_ctf_field_type_variant *variant_type = container_of(
2751 type, struct bt_ctf_field_type_variant, parent);
2752
2753 generic_field_type_freeze(type);
2754 g_ptr_array_foreach(variant_type->fields,
2755 (GFunc) freeze_structure_field, NULL);
2756 }
2757
2758 static
2759 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2760 {
2761 struct bt_ctf_field_type_array *array_type = container_of(
2762 type, struct bt_ctf_field_type_array, parent);
2763
2764 /* Cache the alignment */
2765 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2766 generic_field_type_freeze(type);
2767 bt_ctf_field_type_freeze(array_type->element_type);
2768 }
2769
2770 static
2771 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2772 {
2773 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2774 type, struct bt_ctf_field_type_sequence, parent);
2775
2776 /* Cache the alignment */
2777 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2778 generic_field_type_freeze(type);
2779 bt_ctf_field_type_freeze(sequence_type->element_type);
2780 }
2781
2782 static
2783 const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
2784 {
2785 const char *encoding_string;
2786
2787 switch (encoding) {
2788 case BT_CTF_STRING_ENCODING_NONE:
2789 encoding_string = "none";
2790 break;
2791 case BT_CTF_STRING_ENCODING_ASCII:
2792 encoding_string = "ASCII";
2793 break;
2794 case BT_CTF_STRING_ENCODING_UTF8:
2795 encoding_string = "UTF8";
2796 break;
2797 default:
2798 encoding_string = "unknown";
2799 break;
2800 }
2801
2802 return encoding_string;
2803 }
2804
2805 static
2806 const char *get_integer_base_string(enum bt_ctf_integer_base base)
2807 {
2808 const char *base_string;
2809
2810 switch (base) {
2811 case BT_CTF_INTEGER_BASE_DECIMAL:
2812 base_string = "decimal";
2813 break;
2814 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2815 base_string = "hexadecimal";
2816 break;
2817 case BT_CTF_INTEGER_BASE_OCTAL:
2818 base_string = "octal";
2819 break;
2820 case BT_CTF_INTEGER_BASE_BINARY:
2821 base_string = "binary";
2822 break;
2823 default:
2824 base_string = "unknown";
2825 break;
2826 }
2827
2828 return base_string;
2829 }
2830
2831 static
2832 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2833 struct metadata_context *context)
2834 {
2835 struct bt_ctf_field_type_integer *integer = container_of(type,
2836 struct bt_ctf_field_type_integer, parent);
2837 int ret = 0;
2838
2839 g_string_append_printf(context->string,
2840 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
2841 integer->declaration.len, type->declaration->alignment,
2842 (integer->declaration.signedness ? "true" : "false"),
2843 get_encoding_string(integer->declaration.encoding),
2844 get_integer_base_string(integer->declaration.base),
2845 get_byte_order_string(integer->declaration.byte_order));
2846 if (integer->mapped_clock) {
2847 const char *clock_name = bt_ctf_clock_get_name(
2848 integer->mapped_clock);
2849
2850 if (!clock_name) {
2851 ret = -1;
2852 goto end;
2853 }
2854
2855 g_string_append_printf(context->string,
2856 "; map = clock.%s.value", clock_name);
2857 }
2858
2859 g_string_append(context->string, "; }");
2860 end:
2861 return ret;
2862 }
2863
2864 static
2865 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2866 struct metadata_context *context)
2867 {
2868 size_t entry;
2869 int ret;
2870 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2871 struct bt_ctf_field_type_enumeration, parent);
2872 struct bt_ctf_field_type *container_type;
2873 int container_signed;
2874
2875 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2876 if (!container_type) {
2877 ret = -1;
2878 goto end;
2879 }
2880
2881 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2882 if (container_signed < 0) {
2883 ret = container_signed;
2884 goto error_put_container_type;
2885 }
2886
2887 g_string_append(context->string, "enum : ");
2888 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2889 if (ret) {
2890 goto error_put_container_type;
2891 }
2892
2893 g_string_append(context->string, " { ");
2894 for (entry = 0; entry < enumeration->entries->len; entry++) {
2895 struct enumeration_mapping *mapping =
2896 enumeration->entries->pdata[entry];
2897
2898 if (container_signed) {
2899 if (mapping->range_start._signed ==
2900 mapping->range_end._signed) {
2901 g_string_append_printf(context->string,
2902 "\"%s\" = %" PRId64,
2903 g_quark_to_string(mapping->string),
2904 mapping->range_start._signed);
2905 } else {
2906 g_string_append_printf(context->string,
2907 "\"%s\" = %" PRId64 " ... %" PRId64,
2908 g_quark_to_string(mapping->string),
2909 mapping->range_start._signed,
2910 mapping->range_end._signed);
2911 }
2912 } else {
2913 if (mapping->range_start._unsigned ==
2914 mapping->range_end._unsigned) {
2915 g_string_append_printf(context->string,
2916 "\"%s\" = %" PRIu64,
2917 g_quark_to_string(mapping->string),
2918 mapping->range_start._unsigned);
2919 } else {
2920 g_string_append_printf(context->string,
2921 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2922 g_quark_to_string(mapping->string),
2923 mapping->range_start._unsigned,
2924 mapping->range_end._unsigned);
2925 }
2926 }
2927
2928 g_string_append(context->string,
2929 ((entry != (enumeration->entries->len - 1)) ?
2930 ", " : " }"));
2931 }
2932
2933 if (context->field_name->len) {
2934 g_string_append_printf(context->string, " %s",
2935 context->field_name->str);
2936 g_string_assign(context->field_name, "");
2937 }
2938 error_put_container_type:
2939 bt_put(container_type);
2940 end:
2941 return ret;
2942 }
2943
2944 static
2945 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2946 struct metadata_context *context)
2947 {
2948 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2949 type, struct bt_ctf_field_type_floating_point, parent);
2950
2951 g_string_append_printf(context->string,
2952 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2953 floating_point->declaration.exp->len,
2954 floating_point->declaration.mantissa->len + 1,
2955 get_byte_order_string(floating_point->declaration.byte_order),
2956 type->declaration->alignment);
2957 return 0;
2958 }
2959
2960 static
2961 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2962 struct metadata_context *context)
2963 {
2964 size_t i;
2965 unsigned int indent;
2966 int ret = 0;
2967 struct bt_ctf_field_type_structure *structure = container_of(type,
2968 struct bt_ctf_field_type_structure, parent);
2969 GString *structure_field_name = context->field_name;
2970
2971 context->field_name = g_string_new("");
2972
2973 context->current_indentation_level++;
2974 g_string_append(context->string, "struct {\n");
2975
2976 for (i = 0; i < structure->fields->len; i++) {
2977 struct structure_field *field;
2978
2979 for (indent = 0; indent < context->current_indentation_level;
2980 indent++) {
2981 g_string_append_c(context->string, '\t');
2982 }
2983
2984 field = structure->fields->pdata[i];
2985 g_string_assign(context->field_name,
2986 g_quark_to_string(field->name));
2987 ret = bt_ctf_field_type_serialize(field->type, context);
2988 if (ret) {
2989 goto end;
2990 }
2991
2992 if (context->field_name->len) {
2993 g_string_append_printf(context->string, " %s",
2994 context->field_name->str);
2995 }
2996 g_string_append(context->string, ";\n");
2997 }
2998
2999 context->current_indentation_level--;
3000 for (indent = 0; indent < context->current_indentation_level;
3001 indent++) {
3002 g_string_append_c(context->string, '\t');
3003 }
3004
3005 g_string_append_printf(context->string, "} align(%zu)",
3006 type->declaration->alignment);
3007 end:
3008 g_string_free(context->field_name, TRUE);
3009 context->field_name = structure_field_name;
3010 return ret;
3011 }
3012
3013 static
3014 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3015 struct metadata_context *context)
3016 {
3017 size_t i;
3018 unsigned int indent;
3019 int ret = 0;
3020 struct bt_ctf_field_type_variant *variant = container_of(
3021 type, struct bt_ctf_field_type_variant, parent);
3022 GString *variant_field_name = context->field_name;
3023
3024 context->field_name = g_string_new("");
3025 if (variant->tag_name->len > 0) {
3026 g_string_append_printf(context->string,
3027 "variant <%s> {\n", variant->tag_name->str);
3028 } else {
3029 g_string_append(context->string, "variant {\n");
3030 }
3031
3032 context->current_indentation_level++;
3033 for (i = 0; i < variant->fields->len; i++) {
3034 struct structure_field *field = variant->fields->pdata[i];
3035
3036 g_string_assign(context->field_name,
3037 g_quark_to_string(field->name));
3038 for (indent = 0; indent < context->current_indentation_level;
3039 indent++) {
3040 g_string_append_c(context->string, '\t');
3041 }
3042
3043 g_string_assign(context->field_name,
3044 g_quark_to_string(field->name));
3045 ret = bt_ctf_field_type_serialize(field->type, context);
3046 if (ret) {
3047 goto end;
3048 }
3049
3050 if (context->field_name->len) {
3051 g_string_append_printf(context->string, " %s;",
3052 context->field_name->str);
3053 }
3054
3055 g_string_append_c(context->string, '\n');
3056 }
3057
3058 context->current_indentation_level--;
3059 for (indent = 0; indent < context->current_indentation_level;
3060 indent++) {
3061 g_string_append_c(context->string, '\t');
3062 }
3063
3064 g_string_append(context->string, "}");
3065 end:
3066 g_string_free(context->field_name, TRUE);
3067 context->field_name = variant_field_name;
3068 return ret;
3069 }
3070
3071 static
3072 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3073 struct metadata_context *context)
3074 {
3075 int ret = 0;
3076 struct bt_ctf_field_type_array *array = container_of(type,
3077 struct bt_ctf_field_type_array, parent);
3078
3079 ret = bt_ctf_field_type_serialize(array->element_type, context);
3080 if (ret) {
3081 goto end;
3082 }
3083
3084 if (context->field_name->len) {
3085 g_string_append_printf(context->string, " %s[%u]",
3086 context->field_name->str, array->length);
3087 g_string_assign(context->field_name, "");
3088 } else {
3089 g_string_append_printf(context->string, "[%u]", array->length);
3090 }
3091 end:
3092 return ret;
3093 }
3094
3095 static
3096 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3097 struct metadata_context *context)
3098 {
3099 int ret = 0;
3100 struct bt_ctf_field_type_sequence *sequence = container_of(
3101 type, struct bt_ctf_field_type_sequence, parent);
3102
3103 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3104 if (ret) {
3105 goto end;
3106 }
3107
3108 if (context->field_name->len) {
3109 g_string_append_printf(context->string, " %s[%s]",
3110 context->field_name->str,
3111 sequence->length_field_name->str);
3112 g_string_assign(context->field_name, "");
3113 } else {
3114 g_string_append_printf(context->string, "[%s]",
3115 sequence->length_field_name->str);
3116 }
3117 end:
3118 return ret;
3119 }
3120
3121 static
3122 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3123 struct metadata_context *context)
3124 {
3125 struct bt_ctf_field_type_string *string = container_of(
3126 type, struct bt_ctf_field_type_string, parent);
3127
3128 g_string_append_printf(context->string,
3129 "string { encoding = %s; }",
3130 get_encoding_string(string->declaration.encoding));
3131 return 0;
3132 }
3133
3134 static
3135 enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3136 enum bt_ctf_byte_order ret;
3137
3138 switch (byte_order) {
3139 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3140 case LITTLE_ENDIAN:
3141 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3142 break;
3143 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3144 case BIG_ENDIAN:
3145 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3146 break;
3147 case BT_CTF_BYTE_ORDER_NETWORK:
3148 ret = BT_CTF_BYTE_ORDER_NETWORK;
3149 break;
3150 case BT_CTF_BYTE_ORDER_NATIVE:
3151 ret = BT_CTF_BYTE_ORDER_NATIVE;
3152 break;
3153 default:
3154 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3155 break;
3156 }
3157
3158 return ret;
3159 }
3160
3161 static
3162 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
3163 int byte_order, int set_native)
3164 {
3165 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3166 struct bt_ctf_field_type_integer, parent);
3167
3168 if (set_native) {
3169 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3170 /*
3171 * User byte order is native, so we can set
3172 * the real byte order.
3173 */
3174 integer_type->declaration.byte_order =
3175 byte_order;
3176 }
3177 } else {
3178 integer_type->user_byte_order =
3179 get_ctf_ir_byte_order(byte_order);
3180 integer_type->declaration.byte_order = byte_order;
3181 }
3182 }
3183
3184 static
3185 void bt_ctf_field_type_enumeration_set_byte_order(
3186 struct bt_ctf_field_type *type, int byte_order, int set_native)
3187 {
3188 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3189 struct bt_ctf_field_type_enumeration, parent);
3190
3191 /* Safe to assume that container is an integer */
3192 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3193 byte_order, set_native);
3194 }
3195
3196 static
3197 void bt_ctf_field_type_floating_point_set_byte_order(
3198 struct bt_ctf_field_type *type, int byte_order, int set_native)
3199 {
3200 struct bt_ctf_field_type_floating_point *floating_point_type =
3201 container_of(type, struct bt_ctf_field_type_floating_point,
3202 parent);
3203
3204 if (set_native) {
3205 if (floating_point_type->user_byte_order ==
3206 BT_CTF_BYTE_ORDER_NATIVE) {
3207 /*
3208 * User byte order is native, so we can set
3209 * the real byte order.
3210 */
3211 floating_point_type->declaration.byte_order =
3212 byte_order;
3213 floating_point_type->sign.byte_order =
3214 byte_order;
3215 floating_point_type->mantissa.byte_order =
3216 byte_order;
3217 floating_point_type->exp.byte_order =
3218 byte_order;
3219 }
3220 } else {
3221 floating_point_type->user_byte_order =
3222 get_ctf_ir_byte_order(byte_order);
3223 floating_point_type->declaration.byte_order = byte_order;
3224 floating_point_type->sign.byte_order = byte_order;
3225 floating_point_type->mantissa.byte_order = byte_order;
3226 floating_point_type->exp.byte_order = byte_order;
3227 }
3228 }
3229
3230 static
3231 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3232 int byte_order, int set_native)
3233 {
3234 int i;
3235 struct bt_ctf_field_type_structure *structure_type =
3236 container_of(type, struct bt_ctf_field_type_structure,
3237 parent);
3238
3239 for (i = 0; i < structure_type->fields->len; i++) {
3240 struct structure_field *field = g_ptr_array_index(
3241 structure_type->fields, i);
3242 struct bt_ctf_field_type *field_type = field->type;
3243
3244 if (set_byte_order_funcs[field_type->declaration->id]) {
3245 set_byte_order_funcs[field_type->declaration->id](
3246 field_type, byte_order, set_native);
3247 }
3248 }
3249 }
3250
3251 static
3252 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3253 int byte_order, int set_native)
3254 {
3255 int i;
3256 struct bt_ctf_field_type_variant *variant_type =
3257 container_of(type, struct bt_ctf_field_type_variant,
3258 parent);
3259
3260 for (i = 0; i < variant_type->fields->len; i++) {
3261 struct structure_field *field = g_ptr_array_index(
3262 variant_type->fields, i);
3263 struct bt_ctf_field_type *field_type = field->type;
3264
3265 if (set_byte_order_funcs[field_type->declaration->id]) {
3266 set_byte_order_funcs[field_type->declaration->id](
3267 field_type, byte_order, set_native);
3268 }
3269 }
3270 }
3271
3272 static
3273 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3274 int byte_order, int set_native)
3275 {
3276 struct bt_ctf_field_type_array *array_type =
3277 container_of(type, struct bt_ctf_field_type_array,
3278 parent);
3279
3280 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3281 set_byte_order_funcs[array_type->element_type->declaration->id](
3282 array_type->element_type, byte_order, set_native);
3283 }
3284 }
3285
3286 static
3287 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3288 int byte_order, int set_native)
3289 {
3290 struct bt_ctf_field_type_sequence *sequence_type =
3291 container_of(type, struct bt_ctf_field_type_sequence,
3292 parent);
3293
3294 if (set_byte_order_funcs[
3295 sequence_type->element_type->declaration->id]) {
3296 set_byte_order_funcs[
3297 sequence_type->element_type->declaration->id](
3298 sequence_type->element_type, byte_order, set_native);
3299 }
3300 }
3301
3302 static
3303 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3304 struct bt_ctf_field_type *type)
3305 {
3306 struct bt_ctf_field_type *copy;
3307 struct bt_ctf_field_type_integer *integer, *copy_integer;
3308
3309 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3310 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3311 if (!copy) {
3312 goto end;
3313 }
3314
3315 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3316 parent);
3317 copy_integer->declaration = integer->declaration;
3318 if (integer->mapped_clock) {
3319 bt_get(integer->mapped_clock);
3320 copy_integer->mapped_clock = integer->mapped_clock;
3321 }
3322
3323 copy_integer->user_byte_order = integer->user_byte_order;
3324
3325 end:
3326 return copy;
3327 }
3328
3329 static
3330 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3331 struct bt_ctf_field_type *type)
3332 {
3333 size_t i;
3334 struct bt_ctf_field_type *copy = NULL, *copy_container;
3335 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3336
3337 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3338 parent);
3339
3340 /* Copy the source enumeration's container */
3341 copy_container = bt_ctf_field_type_copy(enumeration->container);
3342 if (!copy_container) {
3343 goto end;
3344 }
3345
3346 copy = bt_ctf_field_type_enumeration_create(copy_container);
3347 if (!copy) {
3348 goto end;
3349 }
3350 copy_enumeration = container_of(copy,
3351 struct bt_ctf_field_type_enumeration, parent);
3352
3353 /* Copy all enumaration entries */
3354 for (i = 0; i < enumeration->entries->len; i++) {
3355 struct enumeration_mapping *mapping = g_ptr_array_index(
3356 enumeration->entries, i);
3357 struct enumeration_mapping* copy_mapping = g_new0(
3358 struct enumeration_mapping, 1);
3359
3360 if (!copy_mapping) {
3361 goto error;
3362 }
3363
3364 *copy_mapping = *mapping;
3365 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3366 }
3367
3368 copy_enumeration->declaration = enumeration->declaration;
3369 end:
3370 bt_put(copy_container);
3371 return copy;
3372 error:
3373 bt_put(copy_container);
3374 BT_PUT(copy);
3375 return copy;
3376 }
3377
3378 static
3379 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3380 struct bt_ctf_field_type *type)
3381 {
3382 struct bt_ctf_field_type *copy;
3383 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3384
3385 floating_point = container_of(type,
3386 struct bt_ctf_field_type_floating_point, parent);
3387 copy = bt_ctf_field_type_floating_point_create();
3388 if (!copy) {
3389 goto end;
3390 }
3391
3392 copy_float = container_of(copy,
3393 struct bt_ctf_field_type_floating_point, parent);
3394 copy_float->declaration = floating_point->declaration;
3395 copy_float->sign = floating_point->sign;
3396 copy_float->mantissa = floating_point->mantissa;
3397 copy_float->exp = floating_point->exp;
3398 copy_float->user_byte_order = floating_point->user_byte_order;
3399 copy_float->declaration.sign = &copy_float->sign;
3400 copy_float->declaration.mantissa = &copy_float->mantissa;
3401 copy_float->declaration.exp = &copy_float->exp;
3402 end:
3403 return copy;
3404 }
3405
3406 static
3407 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3408 struct bt_ctf_field_type *type)
3409 {
3410 int i;
3411 GHashTableIter iter;
3412 gpointer key, value;
3413 struct bt_ctf_field_type *copy;
3414 struct bt_ctf_field_type_structure *structure, *copy_structure;
3415
3416 structure = container_of(type, struct bt_ctf_field_type_structure,
3417 parent);
3418 copy = bt_ctf_field_type_structure_create();
3419 if (!copy) {
3420 goto end;
3421 }
3422
3423 copy_structure = container_of(copy,
3424 struct bt_ctf_field_type_structure, parent);
3425
3426 /* Copy field_name_to_index */
3427 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3428 while (g_hash_table_iter_next (&iter, &key, &value)) {
3429 g_hash_table_insert(copy_structure->field_name_to_index,
3430 key, value);
3431 }
3432
3433 for (i = 0; i < structure->fields->len; i++) {
3434 struct structure_field *entry, *copy_entry;
3435 struct bt_ctf_field_type *copy_field;
3436
3437 copy_entry = g_new0(struct structure_field, 1);
3438 if (!copy_entry) {
3439 goto error;
3440 }
3441
3442 entry = g_ptr_array_index(structure->fields, i);
3443 copy_field = bt_ctf_field_type_copy(entry->type);
3444 if (!copy_field) {
3445 g_free(copy_entry);
3446 goto error;
3447 }
3448
3449 copy_entry->name = entry->name;
3450 copy_entry->type = copy_field;
3451 g_ptr_array_add(copy_structure->fields, copy_entry);
3452 }
3453
3454 copy_structure->declaration = structure->declaration;
3455 end:
3456 return copy;
3457 error:
3458 BT_PUT(copy);
3459 return copy;
3460 }
3461
3462 static
3463 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3464 struct bt_ctf_field_type *type)
3465 {
3466 int i;
3467 GHashTableIter iter;
3468 gpointer key, value;
3469 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3470 struct bt_ctf_field_type_variant *variant, *copy_variant;
3471
3472 variant = container_of(type, struct bt_ctf_field_type_variant,
3473 parent);
3474 if (variant->tag) {
3475 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3476 if (!copy_tag) {
3477 goto end;
3478 }
3479 }
3480
3481 copy = bt_ctf_field_type_variant_create(copy_tag,
3482 variant->tag_name->len ? variant->tag_name->str : NULL);
3483 if (!copy) {
3484 goto end;
3485 }
3486
3487 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3488 parent);
3489
3490 /* Copy field_name_to_index */
3491 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3492 while (g_hash_table_iter_next (&iter, &key, &value)) {
3493 g_hash_table_insert(copy_variant->field_name_to_index,
3494 key, value);
3495 }
3496
3497 for (i = 0; i < variant->fields->len; i++) {
3498 struct structure_field *entry, *copy_entry;
3499 struct bt_ctf_field_type *copy_field;
3500
3501 copy_entry = g_new0(struct structure_field, 1);
3502 if (!copy_entry) {
3503 goto error;
3504 }
3505
3506 entry = g_ptr_array_index(variant->fields, i);
3507 copy_field = bt_ctf_field_type_copy(entry->type);
3508 if (!copy_field) {
3509 g_free(copy_entry);
3510 goto error;
3511 }
3512
3513 copy_entry->name = entry->name;
3514 copy_entry->type = copy_field;
3515 g_ptr_array_add(copy_variant->fields, copy_entry);
3516 }
3517
3518 copy_variant->declaration = variant->declaration;
3519 if (variant->tag_field_path) {
3520 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3521 variant->tag_field_path);
3522 if (!copy_variant->tag_field_path) {
3523 goto error;
3524 }
3525 }
3526 end:
3527 bt_put(copy_tag);
3528 return copy;
3529 error:
3530 bt_put(copy_tag);
3531 BT_PUT(copy);
3532 return copy;
3533 }
3534
3535 static
3536 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3537 struct bt_ctf_field_type *type)
3538 {
3539 struct bt_ctf_field_type *copy = NULL, *copy_element;
3540 struct bt_ctf_field_type_array *array, *copy_array;
3541
3542 array = container_of(type, struct bt_ctf_field_type_array,
3543 parent);
3544 copy_element = bt_ctf_field_type_copy(array->element_type);
3545 if (!copy_element) {
3546 goto end;
3547 }
3548
3549 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3550 if (!copy) {
3551 goto end;
3552 }
3553
3554 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3555 parent);
3556 copy_array->declaration = array->declaration;
3557 end:
3558 bt_put(copy_element);
3559 return copy;
3560 }
3561
3562 static
3563 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3564 struct bt_ctf_field_type *type)
3565 {
3566 struct bt_ctf_field_type *copy = NULL, *copy_element;
3567 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3568
3569 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3570 parent);
3571 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3572 if (!copy_element) {
3573 goto end;
3574 }
3575
3576 copy = bt_ctf_field_type_sequence_create(copy_element,
3577 sequence->length_field_name->len ?
3578 sequence->length_field_name->str : NULL);
3579 if (!copy) {
3580 goto end;
3581 }
3582
3583 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3584 parent);
3585 copy_sequence->declaration = sequence->declaration;
3586 if (sequence->length_field_path) {
3587 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3588 sequence->length_field_path);
3589 if (!copy_sequence->length_field_path) {
3590 goto error;
3591 }
3592 }
3593 end:
3594 bt_put(copy_element);
3595 return copy;
3596 error:
3597 BT_PUT(copy);
3598 goto end;
3599 }
3600
3601 static
3602 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3603 struct bt_ctf_field_type *type)
3604 {
3605 struct bt_ctf_field_type *copy;
3606 struct bt_ctf_field_type_string *string, *copy_string;
3607
3608 copy = bt_ctf_field_type_string_create();
3609 if (!copy) {
3610 goto end;
3611 }
3612
3613 string = container_of(type, struct bt_ctf_field_type_string,
3614 parent);
3615 copy_string = container_of(type, struct bt_ctf_field_type_string,
3616 parent);
3617 copy_string->declaration = string->declaration;
3618 end:
3619 return copy;
3620 }
3621
3622 static
3623 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3624 struct bt_ctf_field_type *type_b)
3625 {
3626 int ret = 1;
3627 struct bt_ctf_field_type_integer *integer_a;
3628 struct bt_ctf_field_type_integer *integer_b;
3629 struct declaration_integer *decl_a;
3630 struct declaration_integer *decl_b;
3631
3632 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3633 parent);
3634 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3635 parent);
3636 decl_a = &integer_a->declaration;
3637 decl_b = &integer_b->declaration;
3638
3639 /* Length */
3640 if (decl_a->len != decl_b->len) {
3641 goto end;
3642 }
3643
3644 /*
3645 * Compare user byte orders only, not the cached,
3646 * real byte orders.
3647 */
3648 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3649 goto end;
3650 }
3651
3652 /* Signedness */
3653 if (decl_a->signedness != decl_b->signedness) {
3654 goto end;
3655 }
3656
3657 /* Base */
3658 if (decl_a->base != decl_b->base) {
3659 goto end;
3660 }
3661
3662 /* Encoding */
3663 if (decl_a->encoding != decl_b->encoding) {
3664 goto end;
3665 }
3666
3667 /* Mapped clock */
3668 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3669 goto end;
3670 }
3671
3672 /* Equal */
3673 ret = 0;
3674
3675 end:
3676 return ret;
3677 }
3678
3679 static
3680 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3681 struct bt_ctf_field_type *type_b)
3682 {
3683 int ret = 1;
3684 struct bt_ctf_field_type_floating_point *float_a;
3685 struct bt_ctf_field_type_floating_point *float_b;
3686
3687 float_a = container_of(type_a,
3688 struct bt_ctf_field_type_floating_point, parent);
3689 float_b = container_of(type_b,
3690 struct bt_ctf_field_type_floating_point, parent);
3691
3692 /* Sign length */
3693 if (float_a->sign.len != float_b->sign.len) {
3694 goto end;
3695 }
3696
3697 /* Exponent length */
3698 if (float_a->exp.len != float_b->exp.len) {
3699 goto end;
3700 }
3701
3702 /* Mantissa length */
3703 if (float_a->mantissa.len != float_b->mantissa.len) {
3704 goto end;
3705 }
3706
3707 /*
3708 * Compare user byte orders only, not the cached,
3709 * real byte orders.
3710 */
3711 if (float_a->user_byte_order != float_b->user_byte_order) {
3712 goto end;
3713 }
3714
3715 /* Equal */
3716 ret = 0;
3717
3718 end:
3719 return ret;
3720 }
3721
3722 static
3723 int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3724 struct enumeration_mapping *mapping_b)
3725 {
3726 int ret = 1;
3727
3728 /* Label */
3729 if (mapping_a->string != mapping_b->string) {
3730 goto end;
3731 }
3732
3733 /* Range start */
3734 if (mapping_a->range_start._unsigned !=
3735 mapping_b->range_start._unsigned) {
3736 goto end;
3737 }
3738
3739 /* Range end */
3740 if (mapping_a->range_end._unsigned !=
3741 mapping_b->range_end._unsigned) {
3742 goto end;
3743 }
3744
3745 /* Equal */
3746 ret = 0;
3747
3748 end:
3749 return ret;
3750 }
3751
3752 static
3753 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3754 struct bt_ctf_field_type *type_b)
3755 {
3756 int ret = 1;
3757 int i;
3758 struct bt_ctf_field_type_enumeration *enum_a;
3759 struct bt_ctf_field_type_enumeration *enum_b;
3760
3761 enum_a = container_of(type_a,
3762 struct bt_ctf_field_type_enumeration, parent);
3763 enum_b = container_of(type_b,
3764 struct bt_ctf_field_type_enumeration, parent);
3765
3766 /* Container field type */
3767 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3768 if (ret) {
3769 goto end;
3770 }
3771
3772 ret = 1;
3773
3774 /* Entries */
3775 if (enum_a->entries->len != enum_b->entries->len) {
3776 goto end;
3777 }
3778
3779 for (i = 0; i < enum_a->entries->len; ++i) {
3780 struct enumeration_mapping *mapping_a =
3781 g_ptr_array_index(enum_a->entries, i);
3782 struct enumeration_mapping *mapping_b =
3783 g_ptr_array_index(enum_b->entries, i);
3784
3785 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3786 goto end;
3787 }
3788 }
3789
3790 /* Equal */
3791 ret = 0;
3792
3793 end:
3794 return ret;
3795 }
3796
3797 static
3798 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3799 struct bt_ctf_field_type *type_b)
3800 {
3801 int ret = 1;
3802 struct bt_ctf_field_type_string *string_a;
3803 struct bt_ctf_field_type_string *string_b;
3804
3805 string_a = container_of(type_a,
3806 struct bt_ctf_field_type_string, parent);
3807 string_b = container_of(type_b,
3808 struct bt_ctf_field_type_string, parent);
3809
3810 /* Encoding */
3811 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3812 goto end;
3813 }
3814
3815 /* Equal */
3816 ret = 0;
3817
3818 end:
3819 return ret;
3820 }
3821
3822 static
3823 int compare_structure_fields(struct structure_field *field_a,
3824 struct structure_field *field_b)
3825 {
3826 int ret = 1;
3827
3828 /* Label */
3829 if (field_a->name != field_b->name) {
3830 goto end;
3831 }
3832
3833 /* Type */
3834 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3835
3836 end:
3837 return ret;
3838 }
3839
3840 static
3841 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3842 struct bt_ctf_field_type *type_b)
3843 {
3844 int ret = 1;
3845 int i;
3846 struct bt_ctf_field_type_structure *struct_a;
3847 struct bt_ctf_field_type_structure *struct_b;
3848
3849 struct_a = container_of(type_a,
3850 struct bt_ctf_field_type_structure, parent);
3851 struct_b = container_of(type_b,
3852 struct bt_ctf_field_type_structure, parent);
3853
3854 /* Alignment */
3855 if (bt_ctf_field_type_get_alignment(type_a) !=
3856 bt_ctf_field_type_get_alignment(type_b)) {
3857 goto end;
3858 }
3859
3860 /* Fields */
3861 if (struct_a->fields->len != struct_b->fields->len) {
3862 goto end;
3863 }
3864
3865 for (i = 0; i < struct_a->fields->len; ++i) {
3866 struct structure_field *field_a =
3867 g_ptr_array_index(struct_a->fields, i);
3868 struct structure_field *field_b =
3869 g_ptr_array_index(struct_b->fields, i);
3870
3871 ret = compare_structure_fields(field_a, field_b);
3872 if (ret) {
3873 goto end;
3874 }
3875 }
3876
3877 /* Equal */
3878 ret = 0;
3879
3880 end:
3881 return ret;
3882 }
3883
3884 static
3885 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3886 struct bt_ctf_field_type *type_b)
3887 {
3888 int ret = 1;
3889 int i;
3890 struct bt_ctf_field_type_variant *variant_a;
3891 struct bt_ctf_field_type_variant *variant_b;
3892
3893 variant_a = container_of(type_a,
3894 struct bt_ctf_field_type_variant, parent);
3895 variant_b = container_of(type_b,
3896 struct bt_ctf_field_type_variant, parent);
3897
3898 /* Tag name */
3899 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3900 goto end;
3901 }
3902
3903 /* Tag type */
3904 ret = bt_ctf_field_type_compare(
3905 (struct bt_ctf_field_type *) variant_a->tag,
3906 (struct bt_ctf_field_type *) variant_b->tag);
3907 if (ret) {
3908 goto end;
3909 }
3910
3911 ret = 1;
3912
3913 /* Fields */
3914 if (variant_a->fields->len != variant_b->fields->len) {
3915 goto end;
3916 }
3917
3918 for (i = 0; i < variant_a->fields->len; ++i) {
3919 struct structure_field *field_a =
3920 g_ptr_array_index(variant_a->fields, i);
3921 struct structure_field *field_b =
3922 g_ptr_array_index(variant_b->fields, i);
3923
3924 ret = compare_structure_fields(field_a, field_b);
3925 if (ret) {
3926 goto end;
3927 }
3928 }
3929
3930 /* Equal */
3931 ret = 0;
3932
3933 end:
3934 return ret;
3935 }
3936
3937 static
3938 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3939 struct bt_ctf_field_type *type_b)
3940 {
3941 int ret = 1;
3942 struct bt_ctf_field_type_array *array_a;
3943 struct bt_ctf_field_type_array *array_b;
3944
3945 array_a = container_of(type_a,
3946 struct bt_ctf_field_type_array, parent);
3947 array_b = container_of(type_b,
3948 struct bt_ctf_field_type_array, parent);
3949
3950 /* Length */
3951 if (array_a->length != array_b->length) {
3952 goto end;
3953 }
3954
3955 /* Element type */
3956 ret = bt_ctf_field_type_compare(array_a->element_type,
3957 array_b->element_type);
3958
3959 end:
3960 return ret;
3961 }
3962
3963 static
3964 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
3965 struct bt_ctf_field_type *type_b)
3966 {
3967 int ret = -1;
3968 struct bt_ctf_field_type_sequence *sequence_a;
3969 struct bt_ctf_field_type_sequence *sequence_b;
3970
3971 sequence_a = container_of(type_a,
3972 struct bt_ctf_field_type_sequence, parent);
3973 sequence_b = container_of(type_b,
3974 struct bt_ctf_field_type_sequence, parent);
3975
3976 /* Length name */
3977 if (strcmp(sequence_a->length_field_name->str,
3978 sequence_b->length_field_name->str)) {
3979 goto end;
3980 }
3981
3982 /* Element type */
3983 ret = bt_ctf_field_type_compare(sequence_a->element_type,
3984 sequence_b->element_type);
3985
3986 end:
3987 return ret;
3988 }
3989
3990 int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
3991 struct bt_ctf_field_type *type_b)
3992 {
3993 int ret = 1;
3994
3995 if (type_a == type_b) {
3996 /* Same reference: equal (even if both are NULL) */
3997 ret = 0;
3998 goto end;
3999 }
4000
4001 if (!type_a || !type_b) {
4002 ret = -1;
4003 goto end;
4004 }
4005
4006 if (type_a->declaration->id != type_b->declaration->id) {
4007 /* Different type IDs */
4008 goto end;
4009 }
4010
4011 if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
4012 /* Both have unknown type IDs */
4013 goto end;
4014 }
4015
4016 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4017
4018 end:
4019 return ret;
4020 }
4021
4022 BT_HIDDEN
4023 int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4024 {
4025 int field_count = -1;
4026 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4027
4028 switch (type_id) {
4029 case CTF_TYPE_STRUCT:
4030 field_count =
4031 bt_ctf_field_type_structure_get_field_count(field_type);
4032 break;
4033 case CTF_TYPE_VARIANT:
4034 field_count =
4035 bt_ctf_field_type_variant_get_field_count(field_type);
4036 break;
4037 case CTF_TYPE_ARRAY:
4038 case CTF_TYPE_SEQUENCE:
4039 /*
4040 * Array and sequence types always contain a single member
4041 * (the element type).
4042 */
4043 field_count = 1;
4044 break;
4045 default:
4046 break;
4047 }
4048
4049 return field_count;
4050 }
4051
4052 BT_HIDDEN
4053 struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4054 struct bt_ctf_field_type *field_type, int index)
4055 {
4056 struct bt_ctf_field_type *field = NULL;
4057 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4058
4059 switch (type_id) {
4060 case CTF_TYPE_STRUCT:
4061 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4062 index);
4063 break;
4064 case CTF_TYPE_VARIANT:
4065 {
4066 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
4067 &field, index);
4068 if (ret) {
4069 field = NULL;
4070 goto end;
4071 }
4072 break;
4073 }
4074 case CTF_TYPE_ARRAY:
4075 field = bt_ctf_field_type_array_get_element_type(field_type);
4076 break;
4077 case CTF_TYPE_SEQUENCE:
4078 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4079 break;
4080 default:
4081 break;
4082 }
4083 end:
4084 return field;
4085 }
4086
4087 BT_HIDDEN
4088 int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4089 const char *name)
4090 {
4091 int field_index = -1;
4092 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4093
4094 switch (type_id) {
4095 case CTF_TYPE_STRUCT:
4096 field_index = bt_ctf_field_type_structure_get_field_name_index(
4097 field_type, name);
4098 break;
4099 case CTF_TYPE_VARIANT:
4100 field_index = bt_ctf_field_type_variant_get_field_name_index(
4101 field_type, name);
4102 break;
4103 default:
4104 break;
4105 }
4106
4107 return field_index;
4108 }
4109
4110 struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4111 struct bt_ctf_field_type *type)
4112 {
4113 struct bt_ctf_field_path *field_path = NULL;
4114 struct bt_ctf_field_type_variant *variant;
4115
4116 if (!type || !bt_ctf_field_type_is_variant(type)) {
4117 goto end;
4118 }
4119
4120 variant = container_of(type, struct bt_ctf_field_type_variant,
4121 parent);
4122 field_path = bt_get(variant->tag_field_path);
4123 end:
4124 return field_path;
4125 }
4126
4127 struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_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_sequence *sequence;
4132
4133 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4134 goto end;
4135 }
4136
4137 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4138 parent);
4139 field_path = bt_get(sequence->length_field_path);
4140 end:
4141 return field_path;
4142 }
This page took 0.181668 seconds and 4 git commands to generate.