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