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