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