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