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