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