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