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