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