49144162d49c9c25372a8e0963279453319cd61a
[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 const char *enum_value;
1883 struct bt_ctf_field_type *field_type = NULL;
1884
1885 if (!type || !tag || type->declaration->id != BT_CTF_TYPE_ID_VARIANT) {
1886 goto end;
1887 }
1888
1889 enum_value = bt_ctf_field_enumeration_get_single_mapping_name(tag);
1890 if (!enum_value) {
1891 goto end;
1892 }
1893
1894 /* Already increments field_type's reference count */
1895 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
1896 type, enum_value);
1897 end:
1898 return field_type;
1899 }
1900
1901 int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
1902 {
1903 int ret = 0;
1904 struct bt_ctf_field_type_variant *variant;
1905
1906 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1907 ret = -1;
1908 goto end;
1909 }
1910
1911 variant = container_of(type, struct bt_ctf_field_type_variant,
1912 parent);
1913 ret = (int) variant->fields->len;
1914 end:
1915 return ret;
1916
1917 }
1918
1919 int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
1920 const char **field_name, struct bt_ctf_field_type **field_type,
1921 int index)
1922 {
1923 struct bt_ctf_field_type_variant *variant;
1924 struct structure_field *field;
1925 int ret = 0;
1926
1927 if (!type || index < 0 ||
1928 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
1929 ret = -1;
1930 goto end;
1931 }
1932
1933 variant = container_of(type, struct bt_ctf_field_type_variant,
1934 parent);
1935 if (index >= variant->fields->len) {
1936 ret = -1;
1937 goto end;
1938 }
1939
1940 field = g_ptr_array_index(variant->fields, index);
1941 if (field_type) {
1942 *field_type = field->type;
1943 bt_get(field->type);
1944 }
1945 if (field_name) {
1946 *field_name = g_quark_to_string(field->name);
1947 }
1948 end:
1949 return ret;
1950 }
1951
1952 struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1953 struct bt_ctf_field_type *element_type,
1954 unsigned int length)
1955 {
1956 struct bt_ctf_field_type_array *array = NULL;
1957
1958 if (!element_type || length == 0) {
1959 goto error;
1960 }
1961
1962 array = g_new0(struct bt_ctf_field_type_array, 1);
1963 if (!array) {
1964 goto error;
1965 }
1966
1967 array->parent.declaration = &array->declaration.p;
1968 array->parent.declaration->id = BT_CTF_TYPE_ID_ARRAY;
1969
1970 bt_get(element_type);
1971 array->element_type = element_type;
1972 array->length = length;
1973 bt_ctf_field_type_init(&array->parent, FALSE);
1974 return &array->parent;
1975 error:
1976 return NULL;
1977 }
1978
1979 struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
1980 struct bt_ctf_field_type *type)
1981 {
1982 struct bt_ctf_field_type *ret = NULL;
1983 struct bt_ctf_field_type_array *array;
1984
1985 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
1986 goto end;
1987 }
1988
1989 array = container_of(type, struct bt_ctf_field_type_array, parent);
1990 ret = array->element_type;
1991 bt_get(ret);
1992 end:
1993 return ret;
1994 }
1995
1996 BT_HIDDEN
1997 int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
1998 struct bt_ctf_field_type *element_type)
1999 {
2000 int ret = 0;
2001 struct bt_ctf_field_type_array *array;
2002
2003 if (!type || !element_type ||
2004 (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
2005 ret = -1;
2006 goto end;
2007 }
2008
2009 array = container_of(type, struct bt_ctf_field_type_array, parent);
2010
2011 if (array->element_type) {
2012 BT_PUT(array->element_type);
2013 }
2014
2015 array->element_type = element_type;
2016 bt_get(array->element_type);
2017
2018 end:
2019 return ret;
2020 }
2021
2022 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
2023 {
2024 int64_t ret;
2025 struct bt_ctf_field_type_array *array;
2026
2027 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
2028 ret = -1;
2029 goto end;
2030 }
2031
2032 array = container_of(type, struct bt_ctf_field_type_array, parent);
2033 ret = (int64_t) array->length;
2034 end:
2035 return ret;
2036 }
2037
2038 struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
2039 struct bt_ctf_field_type *element_type,
2040 const char *length_field_name)
2041 {
2042 struct bt_ctf_field_type_sequence *sequence = NULL;
2043
2044 if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
2045 goto error;
2046 }
2047
2048 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
2049 if (!sequence) {
2050 goto error;
2051 }
2052
2053 sequence->parent.declaration = &sequence->declaration.p;
2054 sequence->parent.declaration->id = BT_CTF_TYPE_ID_SEQUENCE;
2055 bt_get(element_type);
2056 sequence->element_type = element_type;
2057 sequence->length_field_name = g_string_new(length_field_name);
2058 bt_ctf_field_type_init(&sequence->parent, FALSE);
2059 return &sequence->parent;
2060 error:
2061 return NULL;
2062 }
2063
2064 struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
2065 struct bt_ctf_field_type *type)
2066 {
2067 struct bt_ctf_field_type *ret = NULL;
2068 struct bt_ctf_field_type_sequence *sequence;
2069
2070 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
2071 goto end;
2072 }
2073
2074 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2075 parent);
2076 ret = sequence->element_type;
2077 bt_get(ret);
2078 end:
2079 return ret;
2080 }
2081
2082 BT_HIDDEN
2083 int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
2084 struct bt_ctf_field_type *element_type)
2085 {
2086 int ret = 0;
2087 struct bt_ctf_field_type_sequence *sequence;
2088
2089 if (!type || !element_type ||
2090 (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
2091 ret = -1;
2092 goto end;
2093 }
2094
2095 sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
2096
2097 if (sequence->element_type) {
2098 BT_PUT(sequence->element_type);
2099 }
2100
2101 sequence->element_type = element_type;
2102 bt_get(sequence->element_type);
2103
2104 end:
2105 return ret;
2106 }
2107
2108 const char *bt_ctf_field_type_sequence_get_length_field_name(
2109 struct bt_ctf_field_type *type)
2110 {
2111 const char *ret = NULL;
2112 struct bt_ctf_field_type_sequence *sequence;
2113
2114 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
2115 goto end;
2116 }
2117
2118 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2119 parent);
2120 ret = sequence->length_field_name->str;
2121 end:
2122 return ret;
2123 }
2124
2125 struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
2126 {
2127 struct bt_ctf_field_type_string *string =
2128 g_new0(struct bt_ctf_field_type_string, 1);
2129
2130 if (!string) {
2131 return NULL;
2132 }
2133
2134 string->parent.declaration = &string->declaration.p;
2135 string->parent.declaration->id = BT_CTF_TYPE_ID_STRING;
2136 bt_ctf_field_type_init(&string->parent, TRUE);
2137 string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
2138 string->parent.declaration->alignment = CHAR_BIT;
2139 return &string->parent;
2140 }
2141
2142 enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
2143 struct bt_ctf_field_type *type)
2144 {
2145 struct bt_ctf_field_type_string *string;
2146 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
2147
2148 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRING)) {
2149 goto end;
2150 }
2151
2152 string = container_of(type, struct bt_ctf_field_type_string,
2153 parent);
2154 ret = string->declaration.encoding;
2155 end:
2156 return ret;
2157 }
2158
2159 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
2160 enum bt_ctf_string_encoding encoding)
2161 {
2162 int ret = 0;
2163 struct bt_ctf_field_type_string *string;
2164
2165 if (!type || type->declaration->id != BT_CTF_TYPE_ID_STRING ||
2166 (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
2167 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
2168 ret = -1;
2169 goto end;
2170 }
2171
2172 string = container_of(type, struct bt_ctf_field_type_string, parent);
2173 string->declaration.encoding = encoding;
2174 end:
2175 return ret;
2176 }
2177
2178 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
2179 {
2180 int ret;
2181 enum bt_ctf_type_id type_id;
2182
2183 if (!type) {
2184 ret = -1;
2185 goto end;
2186 }
2187
2188 if (type->frozen) {
2189 ret = (int) type->declaration->alignment;
2190 goto end;
2191 }
2192
2193 type_id = bt_ctf_field_type_get_type_id(type);
2194 switch (type_id) {
2195 case BT_CTF_TYPE_ID_SEQUENCE:
2196 {
2197 struct bt_ctf_field_type *element =
2198 bt_ctf_field_type_sequence_get_element_type(type);
2199
2200 if (!element) {
2201 ret = -1;
2202 goto end;
2203 }
2204
2205 ret = bt_ctf_field_type_get_alignment(element);
2206 bt_put(element);
2207 break;
2208 }
2209 case BT_CTF_TYPE_ID_ARRAY:
2210 {
2211 struct bt_ctf_field_type *element =
2212 bt_ctf_field_type_array_get_element_type(type);
2213
2214 if (!element) {
2215 ret = -1;
2216 goto end;
2217 }
2218
2219 ret = bt_ctf_field_type_get_alignment(element);
2220 bt_put(element);
2221 break;
2222 }
2223 case BT_CTF_TYPE_ID_STRUCT:
2224 {
2225 int i, element_count;
2226
2227 element_count = bt_ctf_field_type_structure_get_field_count(
2228 type);
2229 if (element_count < 0) {
2230 ret = element_count;
2231 goto end;
2232 }
2233
2234 for (i = 0; i < element_count; i++) {
2235 struct bt_ctf_field_type *field;
2236 int field_alignment;
2237
2238 ret = bt_ctf_field_type_structure_get_field(type, NULL,
2239 &field, i);
2240 if (ret) {
2241 goto end;
2242 }
2243
2244 assert(field);
2245 field_alignment = bt_ctf_field_type_get_alignment(
2246 field);
2247 bt_put(field);
2248 if (field_alignment < 0) {
2249 ret = field_alignment;
2250 goto end;
2251 }
2252
2253 type->declaration->alignment = MAX(field_alignment,
2254 type->declaration->alignment);
2255 }
2256 ret = (int) type->declaration->alignment;
2257 break;
2258 }
2259 case BT_CTF_TYPE_ID_UNKNOWN:
2260 ret = -1;
2261 break;
2262 default:
2263 ret = (int) type->declaration->alignment;
2264 break;
2265 }
2266 end:
2267 return ret;
2268 }
2269
2270 static inline
2271 int is_power_of_two(unsigned int value)
2272 {
2273 return ((value & (value - 1)) == 0) && value > 0;
2274 }
2275
2276 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
2277 unsigned int alignment)
2278 {
2279 int ret = 0;
2280 enum bt_ctf_type_id type_id;
2281
2282 /* Alignment must be a power of two */
2283 if (!type || type->frozen || !is_power_of_two(alignment)) {
2284 ret = -1;
2285 goto end;
2286 }
2287
2288 type_id = bt_ctf_field_type_get_type_id(type);
2289 if (type_id == BT_CTF_TYPE_ID_UNKNOWN) {
2290 ret = -1;
2291 goto end;
2292 }
2293
2294 if (type->declaration->id == BT_CTF_TYPE_ID_STRING &&
2295 alignment != CHAR_BIT) {
2296 ret = -1;
2297 goto end;
2298 }
2299
2300 if (type_id == BT_CTF_TYPE_ID_VARIANT ||
2301 type_id == BT_CTF_TYPE_ID_SEQUENCE ||
2302 type_id == BT_CTF_TYPE_ID_ARRAY) {
2303 /* Setting an alignment on these types makes no sense */
2304 ret = -1;
2305 goto end;
2306 }
2307
2308 type->declaration->alignment = alignment;
2309 ret = 0;
2310 end:
2311 return ret;
2312 }
2313
2314 enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
2315 struct bt_ctf_field_type *type)
2316 {
2317 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
2318
2319 if (!type) {
2320 goto end;
2321 }
2322
2323 switch (type->declaration->id) {
2324 case BT_CTF_TYPE_ID_INTEGER:
2325 {
2326 struct bt_ctf_field_type_integer *integer = container_of(
2327 type, struct bt_ctf_field_type_integer, parent);
2328 ret = integer->user_byte_order;
2329 break;
2330 }
2331 case BT_CTF_TYPE_ID_ENUM:
2332 {
2333 struct bt_ctf_field_type_enumeration *enum_ft = container_of(
2334 type, struct bt_ctf_field_type_enumeration, parent);
2335 ret = bt_ctf_field_type_get_byte_order(enum_ft->container);
2336 break;
2337 }
2338 case BT_CTF_TYPE_ID_FLOAT:
2339 {
2340 struct bt_ctf_field_type_floating_point *floating_point =
2341 container_of(type,
2342 struct bt_ctf_field_type_floating_point,
2343 parent);
2344 ret = floating_point->user_byte_order;
2345 break;
2346 }
2347 default:
2348 goto end;
2349 }
2350
2351 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2352 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2353 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2354 ret == BT_CTF_BYTE_ORDER_NETWORK);
2355
2356 end:
2357 return ret;
2358 }
2359
2360 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2361 enum bt_ctf_byte_order byte_order)
2362 {
2363 int ret = 0;
2364 int internal_byte_order;
2365 enum bt_ctf_type_id type_id;
2366
2367 if (!type || type->frozen) {
2368 ret = -1;
2369 goto end;
2370 }
2371
2372 switch (byte_order) {
2373 case BT_CTF_BYTE_ORDER_NATIVE:
2374 /* Leave unset. Will be initialized by parent. */
2375 internal_byte_order = 0;
2376 break;
2377 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2378 internal_byte_order = LITTLE_ENDIAN;
2379 break;
2380 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2381 case BT_CTF_BYTE_ORDER_NETWORK:
2382 internal_byte_order = BIG_ENDIAN;
2383 break;
2384 default:
2385 ret = -1;
2386 goto end;
2387 }
2388
2389 type_id = type->declaration->id;
2390 if (set_byte_order_funcs[type_id]) {
2391 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
2392 }
2393 end:
2394 return ret;
2395 }
2396
2397 enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
2398 struct bt_ctf_field_type *type)
2399 {
2400 if (!type) {
2401 return BT_CTF_TYPE_ID_UNKNOWN;
2402 }
2403
2404 return type->declaration->id;
2405 }
2406
2407 int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2408 {
2409 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
2410 }
2411
2412 int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2413 {
2414 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
2415 }
2416
2417 int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2418 {
2419 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
2420 }
2421
2422 int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2423 {
2424 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
2425 }
2426
2427 int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2428 {
2429 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
2430 }
2431
2432 int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2433 {
2434 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
2435 }
2436
2437 int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2438 {
2439 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
2440 }
2441
2442 int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2443 {
2444 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
2445 }
2446
2447 void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2448 {
2449 bt_get(type);
2450 }
2451
2452 void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2453 {
2454 bt_put(type);
2455 }
2456
2457 BT_HIDDEN
2458 void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2459 {
2460 if (!type) {
2461 return;
2462 }
2463
2464 type->freeze(type);
2465 }
2466
2467 BT_HIDDEN
2468 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2469 struct bt_ctf_field_type_variant *variant,
2470 int64_t tag_value)
2471 {
2472 struct bt_ctf_field_type *type = NULL;
2473 GQuark field_name_quark;
2474 gpointer index;
2475 struct structure_field *field_entry;
2476 struct range_overlap_query query = {
2477 .range_start._signed = tag_value,
2478 .range_end._signed = tag_value,
2479 .mapping_name = 0,
2480 .overlaps = 0,
2481 };
2482
2483 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2484 &query);
2485 if (!query.overlaps) {
2486 goto end;
2487 }
2488
2489 field_name_quark = query.mapping_name;
2490 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2491 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2492 goto end;
2493 }
2494
2495 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
2496 type = field_entry->type;
2497 end:
2498 return type;
2499 }
2500
2501 BT_HIDDEN
2502 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
2503 struct bt_ctf_field_type_variant *variant,
2504 uint64_t tag_value)
2505 {
2506 struct bt_ctf_field_type *type = NULL;
2507 GQuark field_name_quark;
2508 gpointer index;
2509 struct structure_field *field_entry;
2510 struct range_overlap_query query = {
2511 .range_start._unsigned = tag_value,
2512 .range_end._unsigned = tag_value,
2513 .mapping_name = 0,
2514 .overlaps = 0,
2515 };
2516
2517 g_ptr_array_foreach(variant->tag->entries,
2518 check_ranges_overlap_unsigned,
2519 &query);
2520 if (!query.overlaps) {
2521 goto end;
2522 }
2523
2524 field_name_quark = query.mapping_name;
2525 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2526 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2527 goto end;
2528 }
2529
2530 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2531 type = field_entry->type;
2532 end:
2533 return type;
2534 }
2535
2536 BT_HIDDEN
2537 int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2538 struct metadata_context *context)
2539 {
2540 int ret;
2541
2542 if (!type || !context) {
2543 ret = -1;
2544 goto end;
2545 }
2546
2547 /* Make sure field type is valid before serializing it */
2548 ret = bt_ctf_field_type_validate(type);
2549
2550 if (ret) {
2551 goto end;
2552 }
2553
2554 ret = type->serialize(type, context);
2555 end:
2556 return ret;
2557 }
2558
2559 BT_HIDDEN
2560 void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2561 int byte_order)
2562 {
2563 if (!type) {
2564 return;
2565 }
2566
2567 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2568 if (set_byte_order_funcs[type->declaration->id]) {
2569 set_byte_order_funcs[type->declaration->id](type,
2570 byte_order, 1);
2571 }
2572 }
2573
2574 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2575 {
2576 struct bt_ctf_field_type *copy = NULL;
2577
2578 if (!type) {
2579 goto end;
2580 }
2581
2582 copy = type_copy_funcs[type->declaration->id](type);
2583 end:
2584 return copy;
2585 }
2586
2587 BT_HIDDEN
2588 int bt_ctf_field_type_structure_get_field_name_index(
2589 struct bt_ctf_field_type *type, const char *name)
2590 {
2591 int ret;
2592 size_t index;
2593 GQuark name_quark;
2594 struct bt_ctf_field_type_structure *structure;
2595
2596 if (!type || !name ||
2597 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2598 ret = -1;
2599 goto end;
2600 }
2601
2602 name_quark = g_quark_try_string(name);
2603 if (!name_quark) {
2604 ret = -1;
2605 goto end;
2606 }
2607
2608 structure = container_of(type, struct bt_ctf_field_type_structure,
2609 parent);
2610 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2611 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2612 ret = -1;
2613 goto end;
2614 }
2615 ret = (int) index;
2616 end:
2617 return ret;
2618 }
2619
2620 BT_HIDDEN
2621 int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2622 struct bt_ctf_field_type *field, int index)
2623 {
2624 int ret = 0;
2625 struct bt_ctf_field_type_structure *structure;
2626
2627 if (!type || !field ||
2628 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
2629 ret = -1;
2630 goto end;
2631 }
2632
2633 structure = container_of(type, struct bt_ctf_field_type_structure,
2634 parent);
2635 if (index < 0 || index >= structure->fields->len) {
2636 ret = -1;
2637 goto end;
2638 }
2639
2640 bt_get(field);
2641 bt_put(((struct structure_field *)
2642 g_ptr_array_index(structure->fields, index))->type);
2643 ((struct structure_field *) structure->fields->pdata[index])->type =
2644 field;
2645 end:
2646 return ret;
2647 }
2648
2649 BT_HIDDEN
2650 int bt_ctf_field_type_variant_get_field_name_index(
2651 struct bt_ctf_field_type *type, const char *name)
2652 {
2653 int ret;
2654 size_t index;
2655 GQuark name_quark;
2656 struct bt_ctf_field_type_variant *variant;
2657
2658 if (!type || !name ||
2659 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2660 ret = -1;
2661 goto end;
2662 }
2663
2664 name_quark = g_quark_try_string(name);
2665 if (!name_quark) {
2666 ret = -1;
2667 goto end;
2668 }
2669
2670 variant = container_of(type, struct bt_ctf_field_type_variant,
2671 parent);
2672 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2673 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2674 ret = -1;
2675 goto end;
2676 }
2677 ret = (int) index;
2678 end:
2679 return ret;
2680 }
2681
2682 BT_HIDDEN
2683 int bt_ctf_field_type_sequence_set_length_field_path(
2684 struct bt_ctf_field_type *type,
2685 struct bt_ctf_field_path *path)
2686 {
2687 int ret = 0;
2688 struct bt_ctf_field_type_sequence *sequence;
2689
2690 if (!type || bt_ctf_field_type_get_type_id(type) !=
2691 BT_CTF_TYPE_ID_SEQUENCE) {
2692 ret = -1;
2693 goto end;
2694 }
2695
2696 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2697 parent);
2698 bt_get(path);
2699 BT_MOVE(sequence->length_field_path, path);
2700 end:
2701 return ret;
2702 }
2703
2704 BT_HIDDEN
2705 int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2706 struct bt_ctf_field_path *path)
2707 {
2708 int ret = 0;
2709 struct bt_ctf_field_type_variant *variant;
2710
2711 if (!type || bt_ctf_field_type_get_type_id(type) !=
2712 BT_CTF_TYPE_ID_VARIANT) {
2713 ret = -1;
2714 goto end;
2715 }
2716
2717 variant = container_of(type, struct bt_ctf_field_type_variant,
2718 parent);
2719 bt_get(path);
2720 BT_MOVE(variant->tag_field_path, path);
2721 end:
2722 return ret;
2723 }
2724
2725 BT_HIDDEN
2726 int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
2727 struct bt_ctf_field_type *tag)
2728 {
2729 int ret = 0;
2730 struct bt_ctf_field_type_variant *variant;
2731
2732 if (!type || !tag ||
2733 bt_ctf_field_type_get_type_id(tag) !=
2734 BT_CTF_TYPE_ID_ENUM) {
2735 ret = -1;
2736 goto end;
2737 }
2738
2739 variant = container_of(type, struct bt_ctf_field_type_variant,
2740 parent);
2741 bt_get(tag);
2742 if (variant->tag) {
2743 bt_put(&variant->tag->parent);
2744 }
2745 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2746 parent);
2747 end:
2748 return ret;
2749 }
2750
2751 BT_HIDDEN
2752 int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2753 struct bt_ctf_field_type *field, int index)
2754 {
2755 int ret = 0;
2756 struct bt_ctf_field_type_variant *variant;
2757
2758 if (!type || !field ||
2759 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
2760 ret = -1;
2761 goto end;
2762 }
2763
2764 variant = container_of(type, struct bt_ctf_field_type_variant,
2765 parent);
2766 if (index < 0 || index >= variant->fields->len) {
2767 ret = -1;
2768 goto end;
2769 }
2770
2771 bt_get(field);
2772 bt_put(((struct structure_field *)
2773 g_ptr_array_index(variant->fields, index))->type);
2774 ((struct structure_field *) variant->fields->pdata[index])->type =
2775 field;
2776 end:
2777 return ret;
2778 }
2779
2780 static
2781 void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
2782 {
2783 struct bt_ctf_field_type_integer *integer =
2784 (struct bt_ctf_field_type_integer *) type;
2785
2786 if (!type) {
2787 return;
2788 }
2789
2790 bt_put(integer->mapped_clock);
2791 g_free(integer);
2792 }
2793
2794 static
2795 void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
2796 {
2797 struct bt_ctf_field_type_enumeration *enumeration =
2798 (struct bt_ctf_field_type_enumeration *) type;
2799
2800 if (!type) {
2801 return;
2802 }
2803
2804 g_ptr_array_free(enumeration->entries, TRUE);
2805 bt_put(enumeration->container);
2806 g_free(enumeration);
2807 }
2808
2809 static
2810 void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
2811 {
2812 struct bt_ctf_field_type_floating_point *floating_point =
2813 (struct bt_ctf_field_type_floating_point *) type;
2814
2815 if (!type) {
2816 return;
2817 }
2818
2819 g_free(floating_point);
2820 }
2821
2822 static
2823 void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
2824 {
2825 struct bt_ctf_field_type_structure *structure =
2826 (struct bt_ctf_field_type_structure *) type;
2827
2828 if (!type) {
2829 return;
2830 }
2831
2832 g_ptr_array_free(structure->fields, TRUE);
2833 g_hash_table_destroy(structure->field_name_to_index);
2834 g_free(structure);
2835 }
2836
2837 static
2838 void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
2839 {
2840 struct bt_ctf_field_type_variant *variant =
2841 (struct bt_ctf_field_type_variant *) type;
2842
2843 if (!type) {
2844 return;
2845 }
2846
2847 g_ptr_array_free(variant->fields, TRUE);
2848 g_hash_table_destroy(variant->field_name_to_index);
2849 g_string_free(variant->tag_name, TRUE);
2850 bt_put(&variant->tag->parent);
2851 BT_PUT(variant->tag_field_path);
2852 g_free(variant);
2853 }
2854
2855 static
2856 void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
2857 {
2858 struct bt_ctf_field_type_array *array =
2859 (struct bt_ctf_field_type_array *) type;
2860
2861 if (!type) {
2862 return;
2863 }
2864
2865 bt_put(array->element_type);
2866 g_free(array);
2867 }
2868
2869 static
2870 void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
2871 {
2872 struct bt_ctf_field_type_sequence *sequence =
2873 (struct bt_ctf_field_type_sequence *) type;
2874
2875 if (!type) {
2876 return;
2877 }
2878
2879 bt_put(sequence->element_type);
2880 g_string_free(sequence->length_field_name, TRUE);
2881 BT_PUT(sequence->length_field_path);
2882 g_free(sequence);
2883 }
2884
2885 static
2886 void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
2887 {
2888 struct bt_ctf_field_type_string *string =
2889 (struct bt_ctf_field_type_string *) type;
2890
2891 if (!type) {
2892 return;
2893 }
2894
2895 g_free(string);
2896 }
2897
2898 static
2899 void generic_field_type_freeze(struct bt_ctf_field_type *type)
2900 {
2901 type->frozen = 1;
2902 }
2903
2904 static
2905 void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2906 {
2907 struct bt_ctf_field_type_integer *integer_type = container_of(
2908 type, struct bt_ctf_field_type_integer, parent);
2909
2910 if (integer_type->mapped_clock) {
2911 bt_ctf_clock_class_freeze(integer_type->mapped_clock);
2912 }
2913
2914 generic_field_type_freeze(type);
2915 }
2916
2917 static
2918 void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2919 {
2920 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2921 type, struct bt_ctf_field_type_enumeration, parent);
2922
2923 set_enumeration_range_overlap(type);
2924
2925 generic_field_type_freeze(type);
2926 bt_ctf_field_type_freeze(enumeration_type->container);
2927 }
2928
2929 static
2930 void freeze_structure_field(struct structure_field *field)
2931 {
2932 bt_ctf_field_type_freeze(field->type);
2933 }
2934
2935 static
2936 void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2937 {
2938 struct bt_ctf_field_type_structure *structure_type = container_of(
2939 type, struct bt_ctf_field_type_structure, parent);
2940
2941 /* Cache the alignment */
2942 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2943 generic_field_type_freeze(type);
2944 g_ptr_array_foreach(structure_type->fields,
2945 (GFunc) freeze_structure_field, NULL);
2946 }
2947
2948 static
2949 void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2950 {
2951 struct bt_ctf_field_type_variant *variant_type = container_of(
2952 type, struct bt_ctf_field_type_variant, parent);
2953
2954 generic_field_type_freeze(type);
2955 g_ptr_array_foreach(variant_type->fields,
2956 (GFunc) freeze_structure_field, NULL);
2957 }
2958
2959 static
2960 void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2961 {
2962 struct bt_ctf_field_type_array *array_type = container_of(
2963 type, struct bt_ctf_field_type_array, parent);
2964
2965 /* Cache the alignment */
2966 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2967 generic_field_type_freeze(type);
2968 bt_ctf_field_type_freeze(array_type->element_type);
2969 }
2970
2971 static
2972 void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2973 {
2974 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2975 type, struct bt_ctf_field_type_sequence, parent);
2976
2977 /* Cache the alignment */
2978 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
2979 generic_field_type_freeze(type);
2980 bt_ctf_field_type_freeze(sequence_type->element_type);
2981 }
2982
2983 static
2984 const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
2985 {
2986 const char *encoding_string;
2987
2988 switch (encoding) {
2989 case BT_CTF_STRING_ENCODING_NONE:
2990 encoding_string = "none";
2991 break;
2992 case BT_CTF_STRING_ENCODING_ASCII:
2993 encoding_string = "ASCII";
2994 break;
2995 case BT_CTF_STRING_ENCODING_UTF8:
2996 encoding_string = "UTF8";
2997 break;
2998 default:
2999 encoding_string = "unknown";
3000 break;
3001 }
3002
3003 return encoding_string;
3004 }
3005
3006 static
3007 const char *get_integer_base_string(enum bt_ctf_integer_base base)
3008 {
3009 const char *base_string;
3010
3011 switch (base) {
3012 case BT_CTF_INTEGER_BASE_DECIMAL:
3013 base_string = "decimal";
3014 break;
3015 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
3016 base_string = "hexadecimal";
3017 break;
3018 case BT_CTF_INTEGER_BASE_OCTAL:
3019 base_string = "octal";
3020 break;
3021 case BT_CTF_INTEGER_BASE_BINARY:
3022 base_string = "binary";
3023 break;
3024 default:
3025 base_string = "unknown";
3026 break;
3027 }
3028
3029 return base_string;
3030 }
3031
3032 static
3033 int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
3034 struct metadata_context *context)
3035 {
3036 struct bt_ctf_field_type_integer *integer = container_of(type,
3037 struct bt_ctf_field_type_integer, parent);
3038 int ret = 0;
3039
3040 g_string_append_printf(context->string,
3041 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
3042 integer->declaration.len, type->declaration->alignment,
3043 (integer->declaration.signedness ? "true" : "false"),
3044 get_encoding_string(integer->declaration.encoding),
3045 get_integer_base_string(integer->declaration.base),
3046 get_byte_order_string(integer->declaration.byte_order));
3047 if (integer->mapped_clock) {
3048 const char *clock_name = bt_ctf_clock_class_get_name(
3049 integer->mapped_clock);
3050
3051 if (!clock_name) {
3052 ret = -1;
3053 goto end;
3054 }
3055
3056 g_string_append_printf(context->string,
3057 "; map = clock.%s.value", clock_name);
3058 }
3059
3060 g_string_append(context->string, "; }");
3061 end:
3062 return ret;
3063 }
3064
3065 static
3066 int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
3067 struct metadata_context *context)
3068 {
3069 size_t entry;
3070 int ret;
3071 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
3072 struct bt_ctf_field_type_enumeration, parent);
3073 struct bt_ctf_field_type *container_type;
3074 int container_signed;
3075
3076 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
3077 if (!container_type) {
3078 ret = -1;
3079 goto end;
3080 }
3081
3082 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
3083 if (container_signed < 0) {
3084 ret = container_signed;
3085 goto error_put_container_type;
3086 }
3087
3088 g_string_append(context->string, "enum : ");
3089 ret = bt_ctf_field_type_serialize(enumeration->container, context);
3090 if (ret) {
3091 goto error_put_container_type;
3092 }
3093
3094 g_string_append(context->string, " { ");
3095 for (entry = 0; entry < enumeration->entries->len; entry++) {
3096 struct enumeration_mapping *mapping =
3097 enumeration->entries->pdata[entry];
3098
3099 if (container_signed) {
3100 if (mapping->range_start._signed ==
3101 mapping->range_end._signed) {
3102 g_string_append_printf(context->string,
3103 "\"%s\" = %" PRId64,
3104 g_quark_to_string(mapping->string),
3105 mapping->range_start._signed);
3106 } else {
3107 g_string_append_printf(context->string,
3108 "\"%s\" = %" PRId64 " ... %" PRId64,
3109 g_quark_to_string(mapping->string),
3110 mapping->range_start._signed,
3111 mapping->range_end._signed);
3112 }
3113 } else {
3114 if (mapping->range_start._unsigned ==
3115 mapping->range_end._unsigned) {
3116 g_string_append_printf(context->string,
3117 "\"%s\" = %" PRIu64,
3118 g_quark_to_string(mapping->string),
3119 mapping->range_start._unsigned);
3120 } else {
3121 g_string_append_printf(context->string,
3122 "\"%s\" = %" PRIu64 " ... %" PRIu64,
3123 g_quark_to_string(mapping->string),
3124 mapping->range_start._unsigned,
3125 mapping->range_end._unsigned);
3126 }
3127 }
3128
3129 g_string_append(context->string,
3130 ((entry != (enumeration->entries->len - 1)) ?
3131 ", " : " }"));
3132 }
3133
3134 if (context->field_name->len) {
3135 g_string_append_printf(context->string, " %s",
3136 context->field_name->str);
3137 g_string_assign(context->field_name, "");
3138 }
3139 error_put_container_type:
3140 bt_put(container_type);
3141 end:
3142 return ret;
3143 }
3144
3145 static
3146 int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
3147 struct metadata_context *context)
3148 {
3149 struct bt_ctf_field_type_floating_point *floating_point = container_of(
3150 type, struct bt_ctf_field_type_floating_point, parent);
3151
3152 g_string_append_printf(context->string,
3153 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
3154 floating_point->declaration.exp->len,
3155 floating_point->declaration.mantissa->len + 1,
3156 get_byte_order_string(floating_point->declaration.byte_order),
3157 type->declaration->alignment);
3158 return 0;
3159 }
3160
3161 static
3162 int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
3163 struct metadata_context *context)
3164 {
3165 size_t i;
3166 unsigned int indent;
3167 int ret = 0;
3168 struct bt_ctf_field_type_structure *structure = container_of(type,
3169 struct bt_ctf_field_type_structure, parent);
3170 GString *structure_field_name = context->field_name;
3171
3172 context->field_name = g_string_new("");
3173
3174 context->current_indentation_level++;
3175 g_string_append(context->string, "struct {\n");
3176
3177 for (i = 0; i < structure->fields->len; i++) {
3178 struct structure_field *field;
3179
3180 for (indent = 0; indent < context->current_indentation_level;
3181 indent++) {
3182 g_string_append_c(context->string, '\t');
3183 }
3184
3185 field = structure->fields->pdata[i];
3186 g_string_assign(context->field_name,
3187 g_quark_to_string(field->name));
3188 ret = bt_ctf_field_type_serialize(field->type, context);
3189 if (ret) {
3190 goto end;
3191 }
3192
3193 if (context->field_name->len) {
3194 g_string_append_printf(context->string, " %s",
3195 context->field_name->str);
3196 }
3197 g_string_append(context->string, ";\n");
3198 }
3199
3200 context->current_indentation_level--;
3201 for (indent = 0; indent < context->current_indentation_level;
3202 indent++) {
3203 g_string_append_c(context->string, '\t');
3204 }
3205
3206 g_string_append_printf(context->string, "} align(%zu)",
3207 type->declaration->alignment);
3208 end:
3209 g_string_free(context->field_name, TRUE);
3210 context->field_name = structure_field_name;
3211 return ret;
3212 }
3213
3214 static
3215 int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3216 struct metadata_context *context)
3217 {
3218 size_t i;
3219 unsigned int indent;
3220 int ret = 0;
3221 struct bt_ctf_field_type_variant *variant = container_of(
3222 type, struct bt_ctf_field_type_variant, parent);
3223 GString *variant_field_name = context->field_name;
3224
3225 context->field_name = g_string_new("");
3226 if (variant->tag_name->len > 0) {
3227 g_string_append_printf(context->string,
3228 "variant <%s> {\n", variant->tag_name->str);
3229 } else {
3230 g_string_append(context->string, "variant {\n");
3231 }
3232
3233 context->current_indentation_level++;
3234 for (i = 0; i < variant->fields->len; i++) {
3235 struct structure_field *field = variant->fields->pdata[i];
3236
3237 g_string_assign(context->field_name,
3238 g_quark_to_string(field->name));
3239 for (indent = 0; indent < context->current_indentation_level;
3240 indent++) {
3241 g_string_append_c(context->string, '\t');
3242 }
3243
3244 g_string_assign(context->field_name,
3245 g_quark_to_string(field->name));
3246 ret = bt_ctf_field_type_serialize(field->type, context);
3247 if (ret) {
3248 goto end;
3249 }
3250
3251 if (context->field_name->len) {
3252 g_string_append_printf(context->string, " %s;",
3253 context->field_name->str);
3254 }
3255
3256 g_string_append_c(context->string, '\n');
3257 }
3258
3259 context->current_indentation_level--;
3260 for (indent = 0; indent < context->current_indentation_level;
3261 indent++) {
3262 g_string_append_c(context->string, '\t');
3263 }
3264
3265 g_string_append(context->string, "}");
3266 end:
3267 g_string_free(context->field_name, TRUE);
3268 context->field_name = variant_field_name;
3269 return ret;
3270 }
3271
3272 static
3273 int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3274 struct metadata_context *context)
3275 {
3276 int ret = 0;
3277 struct bt_ctf_field_type_array *array = container_of(type,
3278 struct bt_ctf_field_type_array, parent);
3279
3280 ret = bt_ctf_field_type_serialize(array->element_type, context);
3281 if (ret) {
3282 goto end;
3283 }
3284
3285 if (context->field_name->len) {
3286 g_string_append_printf(context->string, " %s[%u]",
3287 context->field_name->str, array->length);
3288 g_string_assign(context->field_name, "");
3289 } else {
3290 g_string_append_printf(context->string, "[%u]", array->length);
3291 }
3292 end:
3293 return ret;
3294 }
3295
3296 static
3297 int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3298 struct metadata_context *context)
3299 {
3300 int ret = 0;
3301 struct bt_ctf_field_type_sequence *sequence = container_of(
3302 type, struct bt_ctf_field_type_sequence, parent);
3303
3304 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3305 if (ret) {
3306 goto end;
3307 }
3308
3309 if (context->field_name->len) {
3310 g_string_append_printf(context->string, " %s[%s]",
3311 context->field_name->str,
3312 sequence->length_field_name->str);
3313 g_string_assign(context->field_name, "");
3314 } else {
3315 g_string_append_printf(context->string, "[%s]",
3316 sequence->length_field_name->str);
3317 }
3318 end:
3319 return ret;
3320 }
3321
3322 static
3323 int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3324 struct metadata_context *context)
3325 {
3326 struct bt_ctf_field_type_string *string = container_of(
3327 type, struct bt_ctf_field_type_string, parent);
3328
3329 g_string_append_printf(context->string,
3330 "string { encoding = %s; }",
3331 get_encoding_string(string->declaration.encoding));
3332 return 0;
3333 }
3334
3335 static
3336 enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3337 enum bt_ctf_byte_order ret;
3338
3339 switch (byte_order) {
3340 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3341 case LITTLE_ENDIAN:
3342 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3343 break;
3344 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3345 case BIG_ENDIAN:
3346 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3347 break;
3348 case BT_CTF_BYTE_ORDER_NETWORK:
3349 ret = BT_CTF_BYTE_ORDER_NETWORK;
3350 break;
3351 case BT_CTF_BYTE_ORDER_NATIVE:
3352 ret = BT_CTF_BYTE_ORDER_NATIVE;
3353 break;
3354 default:
3355 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3356 break;
3357 }
3358
3359 return ret;
3360 }
3361
3362 static
3363 void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
3364 int byte_order, int set_native)
3365 {
3366 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3367 struct bt_ctf_field_type_integer, parent);
3368
3369 if (set_native) {
3370 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3371 /*
3372 * User byte order is native, so we can set
3373 * the real byte order.
3374 */
3375 integer_type->declaration.byte_order =
3376 byte_order;
3377 }
3378 } else {
3379 integer_type->user_byte_order =
3380 get_ctf_ir_byte_order(byte_order);
3381 integer_type->declaration.byte_order = byte_order;
3382 }
3383 }
3384
3385 static
3386 void bt_ctf_field_type_enumeration_set_byte_order(
3387 struct bt_ctf_field_type *type, int byte_order, int set_native)
3388 {
3389 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3390 struct bt_ctf_field_type_enumeration, parent);
3391
3392 /* Safe to assume that container is an integer */
3393 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3394 byte_order, set_native);
3395 }
3396
3397 static
3398 void bt_ctf_field_type_floating_point_set_byte_order(
3399 struct bt_ctf_field_type *type, int byte_order, int set_native)
3400 {
3401 struct bt_ctf_field_type_floating_point *floating_point_type =
3402 container_of(type, struct bt_ctf_field_type_floating_point,
3403 parent);
3404
3405 if (set_native) {
3406 if (floating_point_type->user_byte_order ==
3407 BT_CTF_BYTE_ORDER_NATIVE) {
3408 /*
3409 * User byte order is native, so we can set
3410 * the real byte order.
3411 */
3412 floating_point_type->declaration.byte_order =
3413 byte_order;
3414 floating_point_type->sign.byte_order =
3415 byte_order;
3416 floating_point_type->mantissa.byte_order =
3417 byte_order;
3418 floating_point_type->exp.byte_order =
3419 byte_order;
3420 }
3421 } else {
3422 floating_point_type->user_byte_order =
3423 get_ctf_ir_byte_order(byte_order);
3424 floating_point_type->declaration.byte_order = byte_order;
3425 floating_point_type->sign.byte_order = byte_order;
3426 floating_point_type->mantissa.byte_order = byte_order;
3427 floating_point_type->exp.byte_order = byte_order;
3428 }
3429 }
3430
3431 static
3432 void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3433 int byte_order, int set_native)
3434 {
3435 int i;
3436 struct bt_ctf_field_type_structure *structure_type =
3437 container_of(type, struct bt_ctf_field_type_structure,
3438 parent);
3439
3440 for (i = 0; i < structure_type->fields->len; i++) {
3441 struct structure_field *field = g_ptr_array_index(
3442 structure_type->fields, i);
3443 struct bt_ctf_field_type *field_type = field->type;
3444
3445 if (set_byte_order_funcs[field_type->declaration->id]) {
3446 set_byte_order_funcs[field_type->declaration->id](
3447 field_type, byte_order, set_native);
3448 }
3449 }
3450 }
3451
3452 static
3453 void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3454 int byte_order, int set_native)
3455 {
3456 int i;
3457 struct bt_ctf_field_type_variant *variant_type =
3458 container_of(type, struct bt_ctf_field_type_variant,
3459 parent);
3460
3461 for (i = 0; i < variant_type->fields->len; i++) {
3462 struct structure_field *field = g_ptr_array_index(
3463 variant_type->fields, i);
3464 struct bt_ctf_field_type *field_type = field->type;
3465
3466 if (set_byte_order_funcs[field_type->declaration->id]) {
3467 set_byte_order_funcs[field_type->declaration->id](
3468 field_type, byte_order, set_native);
3469 }
3470 }
3471 }
3472
3473 static
3474 void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3475 int byte_order, int set_native)
3476 {
3477 struct bt_ctf_field_type_array *array_type =
3478 container_of(type, struct bt_ctf_field_type_array,
3479 parent);
3480
3481 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3482 set_byte_order_funcs[array_type->element_type->declaration->id](
3483 array_type->element_type, byte_order, set_native);
3484 }
3485 }
3486
3487 static
3488 void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3489 int byte_order, int set_native)
3490 {
3491 struct bt_ctf_field_type_sequence *sequence_type =
3492 container_of(type, struct bt_ctf_field_type_sequence,
3493 parent);
3494
3495 if (set_byte_order_funcs[
3496 sequence_type->element_type->declaration->id]) {
3497 set_byte_order_funcs[
3498 sequence_type->element_type->declaration->id](
3499 sequence_type->element_type, byte_order, set_native);
3500 }
3501 }
3502
3503 static
3504 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3505 struct bt_ctf_field_type *type)
3506 {
3507 struct bt_ctf_field_type *copy;
3508 struct bt_ctf_field_type_integer *integer, *copy_integer;
3509
3510 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3511 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3512 if (!copy) {
3513 goto end;
3514 }
3515
3516 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3517 parent);
3518 copy_integer->declaration = integer->declaration;
3519 if (integer->mapped_clock) {
3520 bt_get(integer->mapped_clock);
3521 copy_integer->mapped_clock = integer->mapped_clock;
3522 }
3523
3524 copy_integer->user_byte_order = integer->user_byte_order;
3525
3526 end:
3527 return copy;
3528 }
3529
3530 static
3531 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3532 struct bt_ctf_field_type *type)
3533 {
3534 size_t i;
3535 struct bt_ctf_field_type *copy = NULL, *copy_container;
3536 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3537
3538 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3539 parent);
3540
3541 /* Copy the source enumeration's container */
3542 copy_container = bt_ctf_field_type_copy(enumeration->container);
3543 if (!copy_container) {
3544 goto end;
3545 }
3546
3547 copy = bt_ctf_field_type_enumeration_create(copy_container);
3548 if (!copy) {
3549 goto end;
3550 }
3551 copy_enumeration = container_of(copy,
3552 struct bt_ctf_field_type_enumeration, parent);
3553
3554 /* Copy all enumaration entries */
3555 for (i = 0; i < enumeration->entries->len; i++) {
3556 struct enumeration_mapping *mapping = g_ptr_array_index(
3557 enumeration->entries, i);
3558 struct enumeration_mapping *copy_mapping = g_new0(
3559 struct enumeration_mapping, 1);
3560
3561 if (!copy_mapping) {
3562 goto error;
3563 }
3564
3565 *copy_mapping = *mapping;
3566 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3567 }
3568
3569 copy_enumeration->declaration = enumeration->declaration;
3570 end:
3571 bt_put(copy_container);
3572 return copy;
3573 error:
3574 bt_put(copy_container);
3575 BT_PUT(copy);
3576 return copy;
3577 }
3578
3579 static
3580 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3581 struct bt_ctf_field_type *type)
3582 {
3583 struct bt_ctf_field_type *copy;
3584 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3585
3586 floating_point = container_of(type,
3587 struct bt_ctf_field_type_floating_point, parent);
3588 copy = bt_ctf_field_type_floating_point_create();
3589 if (!copy) {
3590 goto end;
3591 }
3592
3593 copy_float = container_of(copy,
3594 struct bt_ctf_field_type_floating_point, parent);
3595 copy_float->declaration = floating_point->declaration;
3596 copy_float->sign = floating_point->sign;
3597 copy_float->mantissa = floating_point->mantissa;
3598 copy_float->exp = floating_point->exp;
3599 copy_float->user_byte_order = floating_point->user_byte_order;
3600 copy_float->declaration.sign = &copy_float->sign;
3601 copy_float->declaration.mantissa = &copy_float->mantissa;
3602 copy_float->declaration.exp = &copy_float->exp;
3603 end:
3604 return copy;
3605 }
3606
3607 static
3608 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3609 struct bt_ctf_field_type *type)
3610 {
3611 int i;
3612 GHashTableIter iter;
3613 gpointer key, value;
3614 struct bt_ctf_field_type *copy;
3615 struct bt_ctf_field_type_structure *structure, *copy_structure;
3616
3617 structure = container_of(type, struct bt_ctf_field_type_structure,
3618 parent);
3619 copy = bt_ctf_field_type_structure_create();
3620 if (!copy) {
3621 goto end;
3622 }
3623
3624 copy_structure = container_of(copy,
3625 struct bt_ctf_field_type_structure, parent);
3626
3627 /* Copy field_name_to_index */
3628 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3629 while (g_hash_table_iter_next (&iter, &key, &value)) {
3630 g_hash_table_insert(copy_structure->field_name_to_index,
3631 key, value);
3632 }
3633
3634 for (i = 0; i < structure->fields->len; i++) {
3635 struct structure_field *entry, *copy_entry;
3636 struct bt_ctf_field_type *copy_field;
3637
3638 copy_entry = g_new0(struct structure_field, 1);
3639 if (!copy_entry) {
3640 goto error;
3641 }
3642
3643 entry = g_ptr_array_index(structure->fields, i);
3644 copy_field = bt_ctf_field_type_copy(entry->type);
3645 if (!copy_field) {
3646 g_free(copy_entry);
3647 goto error;
3648 }
3649
3650 copy_entry->name = entry->name;
3651 copy_entry->type = copy_field;
3652 g_ptr_array_add(copy_structure->fields, copy_entry);
3653 }
3654
3655 copy_structure->declaration = structure->declaration;
3656 end:
3657 return copy;
3658 error:
3659 BT_PUT(copy);
3660 return copy;
3661 }
3662
3663 static
3664 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3665 struct bt_ctf_field_type *type)
3666 {
3667 int i;
3668 GHashTableIter iter;
3669 gpointer key, value;
3670 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3671 struct bt_ctf_field_type_variant *variant, *copy_variant;
3672
3673 variant = container_of(type, struct bt_ctf_field_type_variant,
3674 parent);
3675 if (variant->tag) {
3676 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3677 if (!copy_tag) {
3678 goto end;
3679 }
3680 }
3681
3682 copy = bt_ctf_field_type_variant_create(copy_tag,
3683 variant->tag_name->len ? variant->tag_name->str : NULL);
3684 if (!copy) {
3685 goto end;
3686 }
3687
3688 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3689 parent);
3690
3691 /* Copy field_name_to_index */
3692 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3693 while (g_hash_table_iter_next (&iter, &key, &value)) {
3694 g_hash_table_insert(copy_variant->field_name_to_index,
3695 key, value);
3696 }
3697
3698 for (i = 0; i < variant->fields->len; i++) {
3699 struct structure_field *entry, *copy_entry;
3700 struct bt_ctf_field_type *copy_field;
3701
3702 copy_entry = g_new0(struct structure_field, 1);
3703 if (!copy_entry) {
3704 goto error;
3705 }
3706
3707 entry = g_ptr_array_index(variant->fields, i);
3708 copy_field = bt_ctf_field_type_copy(entry->type);
3709 if (!copy_field) {
3710 g_free(copy_entry);
3711 goto error;
3712 }
3713
3714 copy_entry->name = entry->name;
3715 copy_entry->type = copy_field;
3716 g_ptr_array_add(copy_variant->fields, copy_entry);
3717 }
3718
3719 copy_variant->declaration = variant->declaration;
3720 if (variant->tag_field_path) {
3721 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3722 variant->tag_field_path);
3723 if (!copy_variant->tag_field_path) {
3724 goto error;
3725 }
3726 }
3727 end:
3728 bt_put(copy_tag);
3729 return copy;
3730 error:
3731 bt_put(copy_tag);
3732 BT_PUT(copy);
3733 return copy;
3734 }
3735
3736 static
3737 struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3738 struct bt_ctf_field_type *type)
3739 {
3740 struct bt_ctf_field_type *copy = NULL, *copy_element;
3741 struct bt_ctf_field_type_array *array, *copy_array;
3742
3743 array = container_of(type, struct bt_ctf_field_type_array,
3744 parent);
3745 copy_element = bt_ctf_field_type_copy(array->element_type);
3746 if (!copy_element) {
3747 goto end;
3748 }
3749
3750 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3751 if (!copy) {
3752 goto end;
3753 }
3754
3755 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3756 parent);
3757 copy_array->declaration = array->declaration;
3758 end:
3759 bt_put(copy_element);
3760 return copy;
3761 }
3762
3763 static
3764 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3765 struct bt_ctf_field_type *type)
3766 {
3767 struct bt_ctf_field_type *copy = NULL, *copy_element;
3768 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3769
3770 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3771 parent);
3772 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3773 if (!copy_element) {
3774 goto end;
3775 }
3776
3777 copy = bt_ctf_field_type_sequence_create(copy_element,
3778 sequence->length_field_name->len ?
3779 sequence->length_field_name->str : NULL);
3780 if (!copy) {
3781 goto end;
3782 }
3783
3784 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3785 parent);
3786 copy_sequence->declaration = sequence->declaration;
3787 if (sequence->length_field_path) {
3788 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3789 sequence->length_field_path);
3790 if (!copy_sequence->length_field_path) {
3791 goto error;
3792 }
3793 }
3794 end:
3795 bt_put(copy_element);
3796 return copy;
3797 error:
3798 BT_PUT(copy);
3799 goto end;
3800 }
3801
3802 static
3803 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3804 struct bt_ctf_field_type *type)
3805 {
3806 struct bt_ctf_field_type *copy;
3807 struct bt_ctf_field_type_string *string, *copy_string;
3808
3809 copy = bt_ctf_field_type_string_create();
3810 if (!copy) {
3811 goto end;
3812 }
3813
3814 string = container_of(type, struct bt_ctf_field_type_string,
3815 parent);
3816 copy_string = container_of(type, struct bt_ctf_field_type_string,
3817 parent);
3818 copy_string->declaration = string->declaration;
3819 end:
3820 return copy;
3821 }
3822
3823 static
3824 int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3825 struct bt_ctf_field_type *type_b)
3826 {
3827 int ret = 1;
3828 struct bt_ctf_field_type_integer *integer_a;
3829 struct bt_ctf_field_type_integer *integer_b;
3830 struct declaration_integer *decl_a;
3831 struct declaration_integer *decl_b;
3832
3833 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3834 parent);
3835 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3836 parent);
3837 decl_a = &integer_a->declaration;
3838 decl_b = &integer_b->declaration;
3839
3840 /* Length */
3841 if (decl_a->len != decl_b->len) {
3842 goto end;
3843 }
3844
3845 /*
3846 * Compare user byte orders only, not the cached,
3847 * real byte orders.
3848 */
3849 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3850 goto end;
3851 }
3852
3853 /* Signedness */
3854 if (decl_a->signedness != decl_b->signedness) {
3855 goto end;
3856 }
3857
3858 /* Base */
3859 if (decl_a->base != decl_b->base) {
3860 goto end;
3861 }
3862
3863 /* Encoding */
3864 if (decl_a->encoding != decl_b->encoding) {
3865 goto end;
3866 }
3867
3868 /* Mapped clock */
3869 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3870 goto end;
3871 }
3872
3873 /* Equal */
3874 ret = 0;
3875
3876 end:
3877 return ret;
3878 }
3879
3880 static
3881 int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3882 struct bt_ctf_field_type *type_b)
3883 {
3884 int ret = 1;
3885 struct bt_ctf_field_type_floating_point *float_a;
3886 struct bt_ctf_field_type_floating_point *float_b;
3887
3888 float_a = container_of(type_a,
3889 struct bt_ctf_field_type_floating_point, parent);
3890 float_b = container_of(type_b,
3891 struct bt_ctf_field_type_floating_point, parent);
3892
3893 /* Sign length */
3894 if (float_a->sign.len != float_b->sign.len) {
3895 goto end;
3896 }
3897
3898 /* Exponent length */
3899 if (float_a->exp.len != float_b->exp.len) {
3900 goto end;
3901 }
3902
3903 /* Mantissa length */
3904 if (float_a->mantissa.len != float_b->mantissa.len) {
3905 goto end;
3906 }
3907
3908 /*
3909 * Compare user byte orders only, not the cached,
3910 * real byte orders.
3911 */
3912 if (float_a->user_byte_order != float_b->user_byte_order) {
3913 goto end;
3914 }
3915
3916 /* Equal */
3917 ret = 0;
3918
3919 end:
3920 return ret;
3921 }
3922
3923 static
3924 int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3925 struct enumeration_mapping *mapping_b)
3926 {
3927 int ret = 1;
3928
3929 /* Label */
3930 if (mapping_a->string != mapping_b->string) {
3931 goto end;
3932 }
3933
3934 /* Range start */
3935 if (mapping_a->range_start._unsigned !=
3936 mapping_b->range_start._unsigned) {
3937 goto end;
3938 }
3939
3940 /* Range end */
3941 if (mapping_a->range_end._unsigned !=
3942 mapping_b->range_end._unsigned) {
3943 goto end;
3944 }
3945
3946 /* Equal */
3947 ret = 0;
3948
3949 end:
3950 return ret;
3951 }
3952
3953 static
3954 int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3955 struct bt_ctf_field_type *type_b)
3956 {
3957 int ret = 1;
3958 int i;
3959 struct bt_ctf_field_type_enumeration *enum_a;
3960 struct bt_ctf_field_type_enumeration *enum_b;
3961
3962 enum_a = container_of(type_a,
3963 struct bt_ctf_field_type_enumeration, parent);
3964 enum_b = container_of(type_b,
3965 struct bt_ctf_field_type_enumeration, parent);
3966
3967 /* Container field type */
3968 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3969 if (ret) {
3970 goto end;
3971 }
3972
3973 ret = 1;
3974
3975 /* Entries */
3976 if (enum_a->entries->len != enum_b->entries->len) {
3977 goto end;
3978 }
3979
3980 for (i = 0; i < enum_a->entries->len; ++i) {
3981 struct enumeration_mapping *mapping_a =
3982 g_ptr_array_index(enum_a->entries, i);
3983 struct enumeration_mapping *mapping_b =
3984 g_ptr_array_index(enum_b->entries, i);
3985
3986 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3987 goto end;
3988 }
3989 }
3990
3991 /* Equal */
3992 ret = 0;
3993
3994 end:
3995 return ret;
3996 }
3997
3998 static
3999 int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
4000 struct bt_ctf_field_type *type_b)
4001 {
4002 int ret = 1;
4003 struct bt_ctf_field_type_string *string_a;
4004 struct bt_ctf_field_type_string *string_b;
4005
4006 string_a = container_of(type_a,
4007 struct bt_ctf_field_type_string, parent);
4008 string_b = container_of(type_b,
4009 struct bt_ctf_field_type_string, parent);
4010
4011 /* Encoding */
4012 if (string_a->declaration.encoding != string_b->declaration.encoding) {
4013 goto end;
4014 }
4015
4016 /* Equal */
4017 ret = 0;
4018
4019 end:
4020 return ret;
4021 }
4022
4023 static
4024 int compare_structure_fields(struct structure_field *field_a,
4025 struct structure_field *field_b)
4026 {
4027 int ret = 1;
4028
4029 /* Label */
4030 if (field_a->name != field_b->name) {
4031 goto end;
4032 }
4033
4034 /* Type */
4035 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
4036
4037 end:
4038 return ret;
4039 }
4040
4041 static
4042 int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
4043 struct bt_ctf_field_type *type_b)
4044 {
4045 int ret = 1;
4046 int i;
4047 struct bt_ctf_field_type_structure *struct_a;
4048 struct bt_ctf_field_type_structure *struct_b;
4049
4050 struct_a = container_of(type_a,
4051 struct bt_ctf_field_type_structure, parent);
4052 struct_b = container_of(type_b,
4053 struct bt_ctf_field_type_structure, parent);
4054
4055 /* Alignment */
4056 if (bt_ctf_field_type_get_alignment(type_a) !=
4057 bt_ctf_field_type_get_alignment(type_b)) {
4058 goto end;
4059 }
4060
4061 /* Fields */
4062 if (struct_a->fields->len != struct_b->fields->len) {
4063 goto end;
4064 }
4065
4066 for (i = 0; i < struct_a->fields->len; ++i) {
4067 struct structure_field *field_a =
4068 g_ptr_array_index(struct_a->fields, i);
4069 struct structure_field *field_b =
4070 g_ptr_array_index(struct_b->fields, i);
4071
4072 ret = compare_structure_fields(field_a, field_b);
4073 if (ret) {
4074 goto end;
4075 }
4076 }
4077
4078 /* Equal */
4079 ret = 0;
4080
4081 end:
4082 return ret;
4083 }
4084
4085 static
4086 int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
4087 struct bt_ctf_field_type *type_b)
4088 {
4089 int ret = 1;
4090 int i;
4091 struct bt_ctf_field_type_variant *variant_a;
4092 struct bt_ctf_field_type_variant *variant_b;
4093
4094 variant_a = container_of(type_a,
4095 struct bt_ctf_field_type_variant, parent);
4096 variant_b = container_of(type_b,
4097 struct bt_ctf_field_type_variant, parent);
4098
4099 /* Tag name */
4100 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
4101 goto end;
4102 }
4103
4104 /* Tag type */
4105 ret = bt_ctf_field_type_compare(
4106 (struct bt_ctf_field_type *) variant_a->tag,
4107 (struct bt_ctf_field_type *) variant_b->tag);
4108 if (ret) {
4109 goto end;
4110 }
4111
4112 ret = 1;
4113
4114 /* Fields */
4115 if (variant_a->fields->len != variant_b->fields->len) {
4116 goto end;
4117 }
4118
4119 for (i = 0; i < variant_a->fields->len; ++i) {
4120 struct structure_field *field_a =
4121 g_ptr_array_index(variant_a->fields, i);
4122 struct structure_field *field_b =
4123 g_ptr_array_index(variant_b->fields, i);
4124
4125 ret = compare_structure_fields(field_a, field_b);
4126 if (ret) {
4127 goto end;
4128 }
4129 }
4130
4131 /* Equal */
4132 ret = 0;
4133
4134 end:
4135 return ret;
4136 }
4137
4138 static
4139 int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
4140 struct bt_ctf_field_type *type_b)
4141 {
4142 int ret = 1;
4143 struct bt_ctf_field_type_array *array_a;
4144 struct bt_ctf_field_type_array *array_b;
4145
4146 array_a = container_of(type_a,
4147 struct bt_ctf_field_type_array, parent);
4148 array_b = container_of(type_b,
4149 struct bt_ctf_field_type_array, parent);
4150
4151 /* Length */
4152 if (array_a->length != array_b->length) {
4153 goto end;
4154 }
4155
4156 /* Element type */
4157 ret = bt_ctf_field_type_compare(array_a->element_type,
4158 array_b->element_type);
4159
4160 end:
4161 return ret;
4162 }
4163
4164 static
4165 int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
4166 struct bt_ctf_field_type *type_b)
4167 {
4168 int ret = -1;
4169 struct bt_ctf_field_type_sequence *sequence_a;
4170 struct bt_ctf_field_type_sequence *sequence_b;
4171
4172 sequence_a = container_of(type_a,
4173 struct bt_ctf_field_type_sequence, parent);
4174 sequence_b = container_of(type_b,
4175 struct bt_ctf_field_type_sequence, parent);
4176
4177 /* Length name */
4178 if (strcmp(sequence_a->length_field_name->str,
4179 sequence_b->length_field_name->str)) {
4180 goto end;
4181 }
4182
4183 /* Element type */
4184 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4185 sequence_b->element_type);
4186
4187 end:
4188 return ret;
4189 }
4190
4191 int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4192 struct bt_ctf_field_type *type_b)
4193 {
4194 int ret = 1;
4195
4196 if (type_a == type_b) {
4197 /* Same reference: equal (even if both are NULL) */
4198 ret = 0;
4199 goto end;
4200 }
4201
4202 if (!type_a || !type_b) {
4203 ret = -1;
4204 goto end;
4205 }
4206
4207 if (type_a->declaration->id != type_b->declaration->id) {
4208 /* Different type IDs */
4209 goto end;
4210 }
4211
4212 if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
4213 /* Both have unknown type IDs */
4214 goto end;
4215 }
4216
4217 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4218
4219 end:
4220 return ret;
4221 }
4222
4223 BT_HIDDEN
4224 int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4225 {
4226 int field_count = -1;
4227 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4228
4229 switch (type_id) {
4230 case CTF_TYPE_STRUCT:
4231 field_count =
4232 bt_ctf_field_type_structure_get_field_count(field_type);
4233 break;
4234 case CTF_TYPE_VARIANT:
4235 field_count =
4236 bt_ctf_field_type_variant_get_field_count(field_type);
4237 break;
4238 case CTF_TYPE_ARRAY:
4239 case CTF_TYPE_SEQUENCE:
4240 /*
4241 * Array and sequence types always contain a single member
4242 * (the element type).
4243 */
4244 field_count = 1;
4245 break;
4246 default:
4247 break;
4248 }
4249
4250 return field_count;
4251 }
4252
4253 BT_HIDDEN
4254 struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4255 struct bt_ctf_field_type *field_type, int index)
4256 {
4257 struct bt_ctf_field_type *field = NULL;
4258 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4259
4260 switch (type_id) {
4261 case CTF_TYPE_STRUCT:
4262 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4263 index);
4264 break;
4265 case CTF_TYPE_VARIANT:
4266 {
4267 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
4268 &field, index);
4269 if (ret) {
4270 field = NULL;
4271 goto end;
4272 }
4273 break;
4274 }
4275 case CTF_TYPE_ARRAY:
4276 field = bt_ctf_field_type_array_get_element_type(field_type);
4277 break;
4278 case CTF_TYPE_SEQUENCE:
4279 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4280 break;
4281 default:
4282 break;
4283 }
4284 end:
4285 return field;
4286 }
4287
4288 BT_HIDDEN
4289 int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4290 const char *name)
4291 {
4292 int field_index = -1;
4293 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4294
4295 switch (type_id) {
4296 case CTF_TYPE_STRUCT:
4297 field_index = bt_ctf_field_type_structure_get_field_name_index(
4298 field_type, name);
4299 break;
4300 case CTF_TYPE_VARIANT:
4301 field_index = bt_ctf_field_type_variant_get_field_name_index(
4302 field_type, name);
4303 break;
4304 default:
4305 break;
4306 }
4307
4308 return field_index;
4309 }
4310
4311 struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4312 struct bt_ctf_field_type *type)
4313 {
4314 struct bt_ctf_field_path *field_path = NULL;
4315 struct bt_ctf_field_type_variant *variant;
4316
4317 if (!type || !bt_ctf_field_type_is_variant(type)) {
4318 goto end;
4319 }
4320
4321 variant = container_of(type, struct bt_ctf_field_type_variant,
4322 parent);
4323 field_path = bt_get(variant->tag_field_path);
4324 end:
4325 return field_path;
4326 }
4327
4328 struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
4329 struct bt_ctf_field_type *type)
4330 {
4331 struct bt_ctf_field_path *field_path = NULL;
4332 struct bt_ctf_field_type_sequence *sequence;
4333
4334 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4335 goto end;
4336 }
4337
4338 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4339 parent);
4340 field_path = bt_get(sequence->length_field_path);
4341 end:
4342 return field_path;
4343 }
This page took 0.118461 seconds and 4 git commands to generate.