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