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