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