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