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