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