ir: clock: use value in cycles instead of ns
[babeltrace.git] / formats / ctf / ir / field-types.c
CommitLineData
273b65be 1/*
2e33ac5a 2 * field-types.c
273b65be 3 *
d2dc44b6 4 * Babeltrace CTF IR - Event Types
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
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
2e33ac5a 29#include <babeltrace/ctf-ir/field-types-internal.h>
b011f6b0 30#include <babeltrace/ctf-ir/field-path-internal.h>
654c1444 31#include <babeltrace/ctf-ir/utils.h>
83509119 32#include <babeltrace/ref.h>
6cfb906f 33#include <babeltrace/ctf-ir/clock.h>
586411e5 34#include <babeltrace/ctf-ir/clock-internal.h>
273b65be 35#include <babeltrace/ctf-writer/writer-internal.h>
83509119
JG
36#include <babeltrace/object-internal.h>
37#include <babeltrace/ref.h>
273b65be
JG
38#include <babeltrace/compiler.h>
39#include <babeltrace/endian.h>
40#include <float.h>
41#include <inttypes.h>
a39fa057 42#include <stdlib.h>
273b65be
JG
43
44struct range_overlap_query {
b92ddaaa
JG
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;
273b65be
JG
54 int overlaps;
55 GQuark mapping_name;
56};
57
2f2d8e05 58static
83509119 59void bt_ctf_field_type_destroy(struct bt_object *);
273b65be 60static
de3dd40e 61void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
273b65be 62static
de3dd40e 63void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
273b65be 64static
de3dd40e 65void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
273b65be 66static
de3dd40e 67void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
273b65be 68static
de3dd40e 69void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
273b65be 70static
de3dd40e 71void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
273b65be 72static
de3dd40e 73void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
273b65be 74static
de3dd40e 75void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
273b65be
JG
76
77static
de3dd40e 78void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
9a19a512
PP
79 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_destroy,
80 [BT_CTF_TYPE_ID_ENUM] =
273b65be 81 bt_ctf_field_type_enumeration_destroy,
9a19a512 82 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 83 bt_ctf_field_type_floating_point_destroy,
9a19a512
PP
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,
273b65be
JG
89};
90
91static
92void generic_field_type_freeze(struct bt_ctf_field_type *);
93static
586411e5
PP
94void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
95static
273b65be
JG
96void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
97static
98void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
99static
100void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
101static
102void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
103static
104void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
105
106static
107type_freeze_func const type_freeze_funcs[] = {
586411e5 108 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_freeze,
9a19a512
PP
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,
273b65be
JG
116};
117
118static
119int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
120 struct metadata_context *);
121static
122int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
123 struct metadata_context *);
124static
125int bt_ctf_field_type_floating_point_serialize(
126 struct bt_ctf_field_type *, struct metadata_context *);
127static
128int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
129 struct metadata_context *);
130static
131int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
132 struct metadata_context *);
133static
134int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
135 struct metadata_context *);
136static
137int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
138 struct metadata_context *);
139static
140int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
141 struct metadata_context *);
142
143static
144type_serialize_func const type_serialize_funcs[] = {
9a19a512
PP
145 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_serialize,
146 [BT_CTF_TYPE_ID_ENUM] =
273b65be 147 bt_ctf_field_type_enumeration_serialize,
9a19a512 148 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 149 bt_ctf_field_type_floating_point_serialize,
9a19a512 150 [BT_CTF_TYPE_ID_STRUCT] =
273b65be 151 bt_ctf_field_type_structure_serialize,
9a19a512
PP
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,
273b65be
JG
156};
157
158static
159void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
c35a1669
JG
160 int byte_order, int set_native);
161static
162void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
163 int byte_order, int set_native);
273b65be
JG
164static
165void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669
JG
166 struct bt_ctf_field_type *, int byte_order, int set_native);
167static
168void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
169 int byte_order, int set_native);
170static
171void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
172 int byte_order, int set_native);
173static
174void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
175 int byte_order, int set_native);
176static
177void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
178 int byte_order, int set_native);
273b65be 179
c35a1669 180/* The set_native flag only set the byte order if it is set to native */
273b65be
JG
181static
182void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
c35a1669 183 int byte_order, int set_native) = {
9a19a512
PP
184 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
185 [BT_CTF_TYPE_ID_ENUM] =
c35a1669 186 bt_ctf_field_type_enumeration_set_byte_order,
9a19a512 187 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 188 bt_ctf_field_type_floating_point_set_byte_order,
9a19a512 189 [BT_CTF_TYPE_ID_STRUCT] =
c35a1669 190 bt_ctf_field_type_structure_set_byte_order,
9a19a512
PP
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,
273b65be
JG
195};
196
24724933
JG
197static
198struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
199 struct bt_ctf_field_type *);
200static
201struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
202 struct bt_ctf_field_type *);
203static
204struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
205 struct bt_ctf_field_type *);
206static
207struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
208 struct bt_ctf_field_type *);
209static
210struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
211 struct bt_ctf_field_type *);
212static
213struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
214 struct bt_ctf_field_type *);
215static
216struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
217 struct bt_ctf_field_type *);
218static
219struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
220 struct bt_ctf_field_type *);
221
222static
223struct bt_ctf_field_type *(* const type_copy_funcs[])(
224 struct bt_ctf_field_type *) = {
9a19a512
PP
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,
24724933
JG
233};
234
265e809c
PP
235static
236int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
237 struct bt_ctf_field_type *);
238static
239int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
240 struct bt_ctf_field_type *);
241static
242int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
243 struct bt_ctf_field_type *);
244static
245int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
246 struct bt_ctf_field_type *);
247static
248int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
249 struct bt_ctf_field_type *);
250static
251int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
252 struct bt_ctf_field_type *);
253static
254int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
255 struct bt_ctf_field_type *);
256static
257int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
258 struct bt_ctf_field_type *);
259
260static
261int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
262 struct bt_ctf_field_type *) = {
9a19a512
PP
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,
265e809c
PP
271};
272
81e36fac
PP
273static
274int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
275static
276int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
277static
278int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
279static
280int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
281static
282int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
283
284static
285int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
9a19a512
PP
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,
81e36fac
PP
294};
295
273b65be
JG
296static
297void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
298{
299 g_free(mapping);
300}
301
302static
303void destroy_structure_field(struct structure_field *field)
304{
83509119 305 bt_put(field->type);
273b65be
JG
306 g_free(field);
307}
308
309static
310void check_ranges_overlap(gpointer element, gpointer query)
311{
312 struct enumeration_mapping *mapping = element;
313 struct range_overlap_query *overlap_query = query;
314
b92ddaaa
JG
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
326static
327void 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) {
273b65be
JG
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
b92ddaaa
JG
343static
344gint 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
350static
351gint 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
273b65be 357static
59acd4f5 358void bt_ctf_field_type_init(struct bt_ctf_field_type *type, int init_bo)
273b65be 359{
9a19a512 360 enum bt_ctf_type_id type_id = type->declaration->id;
273b65be 361
9a19a512
PP
362 assert(type && (type_id > BT_CTF_TYPE_ID_UNKNOWN) &&
363 (type_id < BT_CTF_NR_TYPE_IDS));
273b65be 364
83509119 365 bt_object_init(type, bt_ctf_field_type_destroy);
273b65be
JG
366 type->freeze = type_freeze_funcs[type_id];
367 type->serialize = type_serialize_funcs[type_id];
59acd4f5
PP
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
273b65be
JG
375 type->declaration->alignment = 1;
376}
377
378static
379int 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 */
fe0fe95c
JG
389 if (g_hash_table_lookup_extended(field_name_to_index,
390 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
273b65be
JG
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
83509119 401 bt_get(field_type);
273b65be
JG
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);
273b65be
JG
408end:
409 return ret;
410}
411
2f2d8e05 412static
83509119 413void bt_ctf_field_type_destroy(struct bt_object *obj)
2f2d8e05
JG
414{
415 struct bt_ctf_field_type *type;
9a19a512 416 enum bt_ctf_type_id type_id;
2f2d8e05 417
83509119 418 type = container_of(obj, struct bt_ctf_field_type, base);
2f2d8e05 419 type_id = type->declaration->id;
9a19a512
PP
420 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
421 type_id >= BT_CTF_NR_TYPE_IDS) {
2f2d8e05
JG
422 return;
423 }
424
de3dd40e 425 type_destroy_funcs[type_id](type);
2f2d8e05
JG
426}
427
81e36fac
PP
428static
429int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
9ce21c30
JG
430{
431 int ret = 0;
432
81e36fac
PP
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) {
9ce21c30
JG
440 ret = -1;
441 goto end;
442 }
443
81e36fac
PP
444 ret = bt_ctf_field_type_validate(container_type);
445 if (ret) {
446 goto end;
447 }
9ce21c30 448
81e36fac
PP
449 /* Ensure enum has entries */
450 ret = enumeration->entries->len ? 0 : -1;
451
452end:
453 BT_PUT(container_type);
454 return ret;
455}
456
457static
458int 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;
5d161ecc 470 }
81e36fac
PP
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
480end:
481 BT_PUT(element_type);
482
483 return ret;
484}
485
486static
487int 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
500end:
501 BT_PUT(element_type);
502
503 return ret;
504}
505
506static
507int 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
534end:
535 BT_PUT(child_type);
536
537 return ret;
538}
539
540static
541int 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,
c6c0ca42 548 parent);
81e36fac
PP
549 int i;
550 int tag_mappings_count;
c6c0ca42 551
81e36fac
PP
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;
c6c0ca42 564 }
c6c0ca42 565
81e36fac
PP
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) {
c6c0ca42 578 ret = -1;
81e36fac 579 goto end;
c6c0ca42 580 }
81e36fac
PP
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);
c6c0ca42 590 }
81e36fac
PP
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
613end:
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 */
625BT_HIDDEN
626int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
627{
628 int ret = 0;
9a19a512 629 enum bt_ctf_type_id id = bt_ctf_field_type_get_type_id(type);
81e36fac
PP
630
631 if (!type) {
632 ret = -1;
633 goto end;
9ce21c30 634 }
81e36fac
PP
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
9ce21c30
JG
650end:
651 return ret;
652}
653
273b65be
JG
654struct 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
1f02e293 659 if (!integer || size == 0 || size > 64) {
273b65be
JG
660 return NULL;
661 }
662
663 integer->parent.declaration = &integer->declaration.p;
9a19a512 664 integer->parent.declaration->id = BT_CTF_TYPE_ID_INTEGER;
273b65be
JG
665 integer->declaration.len = size;
666 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
87b41f95 667 integer->declaration.encoding = BT_CTF_STRING_ENCODING_NONE;
59acd4f5 668 bt_ctf_field_type_init(&integer->parent, TRUE);
273b65be
JG
669 return &integer->parent;
670}
671
b92ddaaa
JG
672int 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
9a19a512 677 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
b92ddaaa
JG
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;
684end:
685 return ret;
686}
687
688int 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
9a19a512 693 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
b92ddaaa
JG
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;
700end:
701 return ret;
702}
703
273b65be
JG
704int 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 ||
9a19a512 711 type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
712 ret = -1;
713 goto end;
714 }
715
716 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
273b65be
JG
717 integer->declaration.signedness = !!is_signed;
718end:
719 return ret;
720}
721
b92ddaaa
JG
722enum 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
9a19a512 728 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
b92ddaaa
JG
729 goto end;
730 }
731
732 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
733 ret = integer->declaration.base;
734end:
735 return ret;
736}
737
273b65be
JG
738int 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 ||
9a19a512 744 type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
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 }
763end:
764 return ret;
765}
766
87b41f95 767enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
b92ddaaa
JG
768 struct bt_ctf_field_type *type)
769{
87b41f95 770 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
b92ddaaa
JG
771 struct bt_ctf_field_type_integer *integer;
772
9a19a512 773 if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
b92ddaaa
JG
774 goto end;
775 }
776
777 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
778 ret = integer->declaration.encoding;
779end:
780 return ret;
781}
782
273b65be 783int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
87b41f95 784 enum bt_ctf_string_encoding encoding)
273b65be
JG
785{
786 int ret = 0;
787 struct bt_ctf_field_type_integer *integer;
788
789 if (!type || type->frozen ||
9a19a512 790 (type->declaration->id != BT_CTF_TYPE_ID_INTEGER) ||
87b41f95
PP
791 (encoding < BT_CTF_STRING_ENCODING_NONE) ||
792 (encoding >= BT_CTF_STRING_ENCODING_UNKNOWN)) {
273b65be
JG
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;
799end:
800 return ret;
801}
802
6cfb906f
JG
803struct 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;
83509119 815 bt_get(clock);
6cfb906f
JG
816end:
817 return clock;
818}
819
820int 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);
83509119
JG
833 bt_put(integer->mapped_clock);
834 bt_get(clock);
6cfb906f
JG
835 integer->mapped_clock = clock;
836end:
837 return ret;
838}
839
273b65be
JG
840struct 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
9a19a512 849 if (integer_container_type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
2a610bb7
JG
850 goto error;
851 }
852
273b65be
JG
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;
9a19a512 859 enumeration->parent.declaration->id = BT_CTF_TYPE_ID_ENUM;
83509119 860 bt_get(integer_container_type);
273b65be
JG
861 enumeration->container = integer_container_type;
862 enumeration->entries = g_ptr_array_new_with_free_func(
863 (GDestroyNotify)destroy_enumeration_mapping);
59acd4f5 864 bt_ctf_field_type_init(&enumeration->parent, FALSE);
273b65be
JG
865 return &enumeration->parent;
866error:
867 g_free(enumeration);
868 return NULL;
869}
870
b92ddaaa
JG
871struct 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
9a19a512 881 if (type->declaration->id != BT_CTF_TYPE_ID_ENUM) {
b92ddaaa
JG
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;
83509119 888 bt_get(container_type);
b92ddaaa
JG
889end:
890 return container_type;
891}
892
273b65be
JG
893int 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;
a39fa057 902 char *escaped_string;
273b65be 903
9a19a512 904 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
273b65be
JG
905 type->frozen ||
906 (range_end < range_start)) {
907 ret = -1;
908 goto end;
909 }
910
a39fa057 911 if (!string || strlen(string) == 0) {
273b65be
JG
912 ret = -1;
913 goto end;
914 }
915
a39fa057
JG
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);
b92ddaaa
JG
923 query = (struct range_overlap_query) {
924 .range_start._signed = range_start,
925 .range_end._signed = range_end,
273b65be
JG
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;
a39fa057 935 goto error_free;
273b65be
JG
936 }
937
938 mapping = g_new(struct enumeration_mapping, 1);
939 if (!mapping) {
940 ret = -1;
a39fa057 941 goto error_free;
273b65be
JG
942 }
943
b92ddaaa
JG
944 *mapping = (struct enumeration_mapping) {
945 .range_start._signed = range_start,
946 .range_end._signed = range_end, .string = mapping_name};
273b65be 947 g_ptr_array_add(enumeration->entries, mapping);
b92ddaaa
JG
948 g_ptr_array_sort(enumeration->entries,
949 (GCompareFunc)compare_enumeration_mappings_signed);
950error_free:
951 free(escaped_string);
952end:
953 return ret;
954}
955
956int 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
9a19a512 967 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
b92ddaaa
JG
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);
a39fa057
JG
1014error_free:
1015 free(escaped_string);
273b65be
JG
1016end:
1017 return ret;
1018}
1019
e5958c30
JG
1020const 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) {
b92ddaaa
JG
1027 .range_start._unsigned = value,
1028 .range_end._unsigned = value,
e5958c30
JG
1029 .overlaps = 0 };
1030
b92ddaaa
JG
1031 g_ptr_array_foreach(enumeration_type->entries,
1032 check_ranges_overlap_unsigned,
e5958c30
JG
1033 &query);
1034 if (!query.overlaps) {
1035 goto end;
1036 }
1037
1038 name = g_quark_to_string(query.mapping_name);
1039end:
1040 return name;
1041}
1042
1043const 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) {
b92ddaaa
JG
1050 .range_start._signed = value,
1051 .range_end._signed = value,
e5958c30
JG
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);
1061end:
1062 return name;
1063}
1064
074ee56d 1065int bt_ctf_field_type_enumeration_get_mapping_count(
b92ddaaa
JG
1066 struct bt_ctf_field_type *type)
1067{
074ee56d 1068 int ret = 0;
b92ddaaa
JG
1069 struct bt_ctf_field_type_enumeration *enumeration;
1070
9a19a512 1071 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
b92ddaaa
JG
1072 ret = -1;
1073 goto end;
1074 }
1075
1076 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1077 parent);
074ee56d 1078 ret = (int) enumeration->entries->len;
b92ddaaa
JG
1079end:
1080 return ret;
1081}
1082
1083static inline
1084struct enumeration_mapping *get_enumeration_mapping(
074ee56d 1085 struct bt_ctf_field_type *type, int index)
b92ddaaa
JG
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);
1097end:
1098 return mapping;
1099}
1100
1101int bt_ctf_field_type_enumeration_get_mapping(
074ee56d 1102 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
1103 const char **string, int64_t *range_start, int64_t *range_end)
1104{
1105 struct enumeration_mapping *mapping;
1106 int ret = 0;
1107
074ee56d 1108 if (!type || index < 0 || !string || !range_start || !range_end ||
9a19a512 1109 (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
b92ddaaa
JG
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;
1123end:
1124 return ret;
1125}
1126
1127int bt_ctf_field_type_enumeration_get_mapping_unsigned(
074ee56d 1128 struct bt_ctf_field_type *type, int index,
b92ddaaa
JG
1129 const char **string, uint64_t *range_start, uint64_t *range_end)
1130{
1131 struct enumeration_mapping *mapping;
1132 int ret = 0;
1133
074ee56d 1134 if (!type || index < 0 || !string || !range_start || !range_end ||
9a19a512 1135 (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
b92ddaaa
JG
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;
1149end:
1150 return ret;
1151}
1152
1153int bt_ctf_field_type_enumeration_get_mapping_index_by_name(
074ee56d 1154 struct bt_ctf_field_type *type, const char *name)
b92ddaaa 1155{
b92ddaaa
JG
1156 GQuark name_quark;
1157 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 1158 int i, ret = 0;
b92ddaaa 1159
074ee56d 1160 if (!type || !name ||
9a19a512 1161 (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
b92ddaaa
JG
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) {
074ee56d 1179 ret = i;
b92ddaaa
JG
1180 goto end;
1181 }
1182 }
1183
1184 ret = -1;
1185end:
1186 return ret;
1187}
1188
1189int bt_ctf_field_type_enumeration_get_mapping_index_by_value(
074ee56d 1190 struct bt_ctf_field_type *type, int64_t value)
b92ddaaa
JG
1191{
1192 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 1193 int i, ret = 0;
b92ddaaa 1194
9a19a512 1195 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
b92ddaaa
JG
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) {
074ee56d 1208 ret = i;
b92ddaaa
JG
1209 goto end;
1210 }
1211 }
1212
1213 ret = -1;
1214end:
1215 return ret;
1216}
1217
1218int bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(
074ee56d 1219 struct bt_ctf_field_type *type, uint64_t value)
b92ddaaa
JG
1220{
1221 struct bt_ctf_field_type_enumeration *enumeration;
074ee56d 1222 int i, ret = 0;
b92ddaaa 1223
9a19a512 1224 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
b92ddaaa
JG
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) {
074ee56d 1237 ret = i;
b92ddaaa
JG
1238 goto end;
1239 }
1240 }
1241
1242 ret = -1;
1243end:
1244 return ret;
1245}
1246
273b65be
JG
1247struct 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;
9a19a512 1261 floating_point->parent.declaration->id = BT_CTF_TYPE_ID_FLOAT;
273b65be
JG
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
59acd4f5 1269 bt_ctf_field_type_init(&floating_point->parent, TRUE);
273b65be
JG
1270end:
1271 return floating_point ? &floating_point->parent : NULL;
1272}
1273
b92ddaaa
JG
1274int 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
9a19a512 1280 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
b92ddaaa
JG
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;
1288end:
1289 return ret;
1290}
1291
273b65be
JG
1292int 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 ||
9a19a512 1300 (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
273b65be
JG
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;
1316end:
1317 return ret;
1318}
1319
b92ddaaa
JG
1320int 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
9a19a512 1326 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
b92ddaaa
JG
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;
1334end:
1335 return ret;
1336}
1337
273b65be
JG
1338int 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 ||
9a19a512 1346 (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
273b65be
JG
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;
1362end:
1363 return ret;
1364}
1365
1366struct 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;
9a19a512 1376 structure->parent.declaration->id = BT_CTF_TYPE_ID_STRUCT;
273b65be
JG
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);
59acd4f5 1380 bt_ctf_field_type_init(&structure->parent, TRUE);
273b65be
JG
1381 return &structure->parent;
1382error:
1383 return NULL;
1384}
1385
1386int 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 ||
654c1444 1394 bt_ctf_validate_identifier(field_name) ||
9a19a512 1395 (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
e6235f1f 1396 ret = -1;
273b65be
JG
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 }
b92ddaaa
JG
1407end:
1408 return ret;
1409}
1410
074ee56d 1411int bt_ctf_field_type_structure_get_field_count(
b92ddaaa
JG
1412 struct bt_ctf_field_type *type)
1413{
074ee56d 1414 int ret = 0;
b92ddaaa
JG
1415 struct bt_ctf_field_type_structure *structure;
1416
9a19a512 1417 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
b92ddaaa
JG
1418 ret = -1;
1419 goto end;
1420 }
1421
1422 structure = container_of(type, struct bt_ctf_field_type_structure,
1423 parent);
074ee56d 1424 ret = (int) structure->fields->len;
b92ddaaa
JG
1425end:
1426 return ret;
1427}
1428
1429int 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,
074ee56d 1431 int index)
b92ddaaa
JG
1432{
1433 struct bt_ctf_field_type_structure *structure;
1434 struct structure_field *field;
1435 int ret = 0;
1436
9a19a512
PP
1437 if (!type || index < 0 ||
1438 (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
b92ddaaa
JG
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);
f9b799fc
JG
1451 if (field_type) {
1452 *field_type = field->type;
83509119 1453 bt_get(field->type);
f9b799fc
JG
1454 }
1455 if (field_name) {
1456 *field_name = g_quark_to_string(field->name);
1457 }
b92ddaaa
JG
1458end:
1459 return ret;
1460}
1461
1462struct 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;
273b65be 1486 }
b92ddaaa
JG
1487
1488 field = structure->fields->pdata[index];
1489 field_type = field->type;
83509119 1490 bt_get(field_type);
273b65be 1491end:
b92ddaaa 1492 return field_type;
273b65be
JG
1493}
1494
1495struct 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
6964b7fd 1500 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
273b65be
JG
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;
9a19a512 1510 variant->parent.declaration->id = BT_CTF_TYPE_ID_VARIANT;
273b65be 1511 variant->tag_name = g_string_new(tag_name);
273b65be
JG
1512 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
1513 variant->fields = g_ptr_array_new_with_free_func(
83509119 1514 (GDestroyNotify) destroy_structure_field);
6964b7fd 1515 if (enum_tag) {
83509119 1516 bt_get(enum_tag);
6964b7fd
JG
1517 variant->tag = container_of(enum_tag,
1518 struct bt_ctf_field_type_enumeration, parent);
1519 }
1520
59acd4f5 1521 bt_ctf_field_type_init(&variant->parent, TRUE);
46caf2cb
JG
1522 /* A variant's alignment is undefined */
1523 variant->parent.declaration->alignment = 0;
273b65be
JG
1524 return &variant->parent;
1525error:
1526 return NULL;
1527}
1528
b92ddaaa
JG
1529struct 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
9a19a512 1535 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
b92ddaaa
JG
1536 goto end;
1537 }
1538
1539 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd
JG
1540 if (!variant->tag) {
1541 goto end;
1542 }
1543
b92ddaaa 1544 tag_type = &variant->tag->parent;
83509119 1545 bt_get(tag_type);
b92ddaaa
JG
1546end:
1547 return tag_type;
1548}
1549
1550const 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
9a19a512 1556 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
b92ddaaa
JG
1557 goto end;
1558 }
1559
1560 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd
JG
1561 if (variant->tag_name->len == 0) {
1562 goto end;
1563 }
1564
b92ddaaa
JG
1565 tag_name = variant->tag_name->str;
1566end:
1567 return tag_name;
1568}
1569
d9b1ab6d
JG
1570int 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 ||
9a19a512 1577 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT) ||
d9b1ab6d
JG
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);
1585end:
1586 return ret;
1587}
1588
273b65be
JG
1589int 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;
273b65be
JG
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 ||
654c1444 1599 bt_ctf_validate_identifier(field_name) ||
9a19a512 1600 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
273b65be
JG
1601 ret = -1;
1602 goto end;
1603 }
1604
1605 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
273b65be 1606
6964b7fd
JG
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;
273b65be
JG
1626 }
1627 }
1628
6964b7fd
JG
1629 if (add_structure_field(variant->fields, variant->field_name_to_index,
1630 field_type, field_name)) {
273b65be
JG
1631 ret = -1;
1632 goto end;
1633 }
1634end:
1635 return ret;
1636}
1637
b92ddaaa
JG
1638struct 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;
83509119 1665 bt_get(field_type);
b92ddaaa
JG
1666end:
1667 return field_type;
1668}
1669
1670struct 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
9a19a512 1677 if (!type || !tag || type->declaration->id != BT_CTF_TYPE_ID_VARIANT) {
b92ddaaa
JG
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);
1689end:
1690 return field_type;
1691}
1692
074ee56d 1693int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
b92ddaaa 1694{
074ee56d 1695 int ret = 0;
b92ddaaa
JG
1696 struct bt_ctf_field_type_variant *variant;
1697
9a19a512 1698 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
b92ddaaa
JG
1699 ret = -1;
1700 goto end;
1701 }
1702
1703 variant = container_of(type, struct bt_ctf_field_type_variant,
1704 parent);
074ee56d 1705 ret = (int) variant->fields->len;
b92ddaaa
JG
1706end:
1707 return ret;
1708
1709}
1710
1711int 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,
074ee56d 1713 int index)
b92ddaaa
JG
1714{
1715 struct bt_ctf_field_type_variant *variant;
1716 struct structure_field *field;
1717 int ret = 0;
1718
9a19a512
PP
1719 if (!type || index < 0 ||
1720 (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
b92ddaaa
JG
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);
647f3b93
JG
1733 if (field_type) {
1734 *field_type = field->type;
83509119 1735 bt_get(field->type);
647f3b93
JG
1736 }
1737 if (field_name) {
1738 *field_name = g_quark_to_string(field->name);
1739 }
b92ddaaa
JG
1740end:
1741 return ret;
1742}
1743
273b65be
JG
1744struct 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
81e36fac 1750 if (!element_type || length == 0) {
273b65be
JG
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;
9a19a512 1760 array->parent.declaration->id = BT_CTF_TYPE_ID_ARRAY;
c35a1669 1761
83509119 1762 bt_get(element_type);
273b65be
JG
1763 array->element_type = element_type;
1764 array->length = length;
59acd4f5 1765 bt_ctf_field_type_init(&array->parent, FALSE);
273b65be
JG
1766 return &array->parent;
1767error:
1768 return NULL;
1769}
1770
b92ddaaa
JG
1771struct 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
9a19a512 1777 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
b92ddaaa
JG
1778 goto end;
1779 }
1780
1781 array = container_of(type, struct bt_ctf_field_type_array, parent);
1782 ret = array->element_type;
83509119 1783 bt_get(ret);
b92ddaaa
JG
1784end:
1785 return ret;
1786}
1787
626e93aa
PP
1788BT_HIDDEN
1789int 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 ||
9a19a512 1796 (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
626e93aa
PP
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
1810end:
1811 return ret;
1812}
1813
b92ddaaa
JG
1814int64_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
9a19a512 1819 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
b92ddaaa
JG
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;
1826end:
1827 return ret;
1828}
1829
273b65be
JG
1830struct 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
81e36fac 1836 if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
273b65be
JG
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;
9a19a512 1846 sequence->parent.declaration->id = BT_CTF_TYPE_ID_SEQUENCE;
83509119 1847 bt_get(element_type);
273b65be
JG
1848 sequence->element_type = element_type;
1849 sequence->length_field_name = g_string_new(length_field_name);
59acd4f5 1850 bt_ctf_field_type_init(&sequence->parent, FALSE);
273b65be
JG
1851 return &sequence->parent;
1852error:
1853 return NULL;
1854}
1855
b92ddaaa
JG
1856struct 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
9a19a512 1862 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
b92ddaaa
JG
1863 goto end;
1864 }
1865
1866 sequence = container_of(type, struct bt_ctf_field_type_sequence,
1867 parent);
1868 ret = sequence->element_type;
83509119 1869 bt_get(ret);
b92ddaaa
JG
1870end:
1871 return ret;
1872}
1873
626e93aa
PP
1874BT_HIDDEN
1875int 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 ||
9a19a512 1882 (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
626e93aa
PP
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
1896end:
1897 return ret;
1898}
1899
b92ddaaa
JG
1900const 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
9a19a512 1906 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
b92ddaaa
JG
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;
1913end:
1914 return ret;
1915}
1916
273b65be
JG
1917struct 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;
9a19a512 1927 string->parent.declaration->id = BT_CTF_TYPE_ID_STRING;
59acd4f5 1928 bt_ctf_field_type_init(&string->parent, TRUE);
87b41f95 1929 string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
273b65be
JG
1930 string->parent.declaration->alignment = CHAR_BIT;
1931 return &string->parent;
1932}
1933
87b41f95 1934enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
b92ddaaa
JG
1935 struct bt_ctf_field_type *type)
1936{
1937 struct bt_ctf_field_type_string *string;
87b41f95 1938 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
b92ddaaa 1939
9a19a512 1940 if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRING)) {
b92ddaaa
JG
1941 goto end;
1942 }
1943
1944 string = container_of(type, struct bt_ctf_field_type_string,
1945 parent);
1946 ret = string->declaration.encoding;
1947end:
1948 return ret;
1949}
1950
1951int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
87b41f95 1952 enum bt_ctf_string_encoding encoding)
273b65be
JG
1953{
1954 int ret = 0;
1955 struct bt_ctf_field_type_string *string;
1956
9a19a512 1957 if (!type || type->declaration->id != BT_CTF_TYPE_ID_STRING ||
87b41f95
PP
1958 (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
1959 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
273b65be
JG
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;
1966end:
1967 return ret;
1968}
1969
b92ddaaa
JG
1970int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
1971{
1972 int ret;
9a19a512 1973 enum bt_ctf_type_id type_id;
b92ddaaa
JG
1974
1975 if (!type) {
1976 ret = -1;
1977 goto end;
1978 }
1979
3ffba961
JG
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) {
9a19a512 1987 case BT_CTF_TYPE_ID_SEQUENCE:
3ffba961
JG
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);
83509119 1998 bt_put(element);
3ffba961
JG
1999 break;
2000 }
9a19a512 2001 case BT_CTF_TYPE_ID_ARRAY:
3ffba961
JG
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);
83509119 2012 bt_put(element);
3ffba961
JG
2013 break;
2014 }
9a19a512 2015 case BT_CTF_TYPE_ID_STRUCT:
3ffba961
JG
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);
83509119 2039 bt_put(field);
3ffba961
JG
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 }
9a19a512 2051 case BT_CTF_TYPE_ID_UNKNOWN:
3ffba961
JG
2052 ret = -1;
2053 break;
2054 default:
2055 ret = (int) type->declaration->alignment;
2056 break;
2057 }
b92ddaaa
JG
2058end:
2059 return ret;
2060}
2061
9ad2f879
PP
2062static inline
2063int is_power_of_two(unsigned int value)
2064{
2065 return ((value & (value - 1)) == 0) && value > 0;
2066}
2067
273b65be
JG
2068int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
2069 unsigned int alignment)
2070{
2071 int ret = 0;
9a19a512 2072 enum bt_ctf_type_id type_id;
273b65be 2073
9ad2f879
PP
2074 /* Alignment must be a power of two */
2075 if (!type || type->frozen || !is_power_of_two(alignment)) {
273b65be
JG
2076 ret = -1;
2077 goto end;
2078 }
2079
6a43d732 2080 type_id = bt_ctf_field_type_get_type_id(type);
9a19a512 2081 if (type_id == BT_CTF_TYPE_ID_UNKNOWN) {
6a43d732
JG
2082 ret = -1;
2083 goto end;
2084 }
2085
9a19a512 2086 if (type->declaration->id == BT_CTF_TYPE_ID_STRING &&
273b65be
JG
2087 alignment != CHAR_BIT) {
2088 ret = -1;
2089 goto end;
2090 }
2091
9a19a512
PP
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) {
6a43d732
JG
2095 /* Setting an alignment on these types makes no sense */
2096 ret = -1;
2097 goto end;
2098 }
2099
273b65be
JG
2100 type->declaration->alignment = alignment;
2101 ret = 0;
2102end:
2103 return ret;
2104}
2105
b92ddaaa
JG
2106enum 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) {
9a19a512 2116 case BT_CTF_TYPE_ID_INTEGER:
b92ddaaa
JG
2117 {
2118 struct bt_ctf_field_type_integer *integer = container_of(
2119 type, struct bt_ctf_field_type_integer, parent);
445c3471 2120 ret = integer->user_byte_order;
b92ddaaa
JG
2121 break;
2122 }
9a19a512 2123 case BT_CTF_TYPE_ID_FLOAT:
b92ddaaa
JG
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);
445c3471 2129 ret = floating_point->user_byte_order;
b92ddaaa
JG
2130 break;
2131 }
2132 default:
c35a1669
JG
2133 goto end;
2134 }
2135
445c3471
PP
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
b92ddaaa
JG
2141end:
2142 return ret;
2143}
2144
273b65be
JG
2145int 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;
9a19a512 2150 enum bt_ctf_type_id type_id;
273b65be
JG
2151
2152 if (!type || type->frozen) {
2153 ret = -1;
2154 goto end;
2155 }
2156
273b65be
JG
2157 switch (byte_order) {
2158 case BT_CTF_BYTE_ORDER_NATIVE:
c35a1669
JG
2159 /* Leave unset. Will be initialized by parent. */
2160 internal_byte_order = 0;
273b65be
JG
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
3fa759e9 2174 type_id = type->declaration->id;
273b65be 2175 if (set_byte_order_funcs[type_id]) {
c35a1669 2176 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
273b65be
JG
2177 }
2178end:
2179 return ret;
2180}
2181
9a19a512 2182enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
b92ddaaa
JG
2183 struct bt_ctf_field_type *type)
2184{
2185 if (!type) {
9a19a512 2186 return BT_CTF_TYPE_ID_UNKNOWN;
b92ddaaa
JG
2187 }
2188
2189 return type->declaration->id;
2190}
2f2d8e05 2191
56db8d7a
PP
2192int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2193{
9a19a512 2194 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
56db8d7a
PP
2195}
2196
2197int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2198{
9a19a512 2199 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
56db8d7a
PP
2200}
2201
2202int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2203{
9a19a512 2204 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
56db8d7a
PP
2205}
2206
2207int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2208{
9a19a512 2209 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
56db8d7a
PP
2210}
2211
2212int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2213{
9a19a512 2214 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
56db8d7a
PP
2215}
2216
2217int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2218{
9a19a512 2219 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
56db8d7a
PP
2220}
2221
2222int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2223{
9a19a512 2224 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
56db8d7a
PP
2225}
2226
2227int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2228{
9a19a512 2229 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
56db8d7a
PP
2230}
2231
273b65be
JG
2232void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2233{
83509119 2234 bt_get(type);
273b65be
JG
2235}
2236
2237void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2238{
83509119 2239 bt_put(type);
273b65be
JG
2240}
2241
2242BT_HIDDEN
2243void 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
2252BT_HIDDEN
b92ddaaa
JG
2253struct 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)
273b65be
JG
2256{
2257 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
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};
273b65be 2265
b92ddaaa
JG
2266 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2267 &query);
2268 if (!query.overlaps) {
273b65be
JG
2269 goto end;
2270 }
2271
b92ddaaa
JG
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)) {
273b65be
JG
2275 goto end;
2276 }
2277
e54fab7e 2278 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
b92ddaaa 2279 type = field_entry->type;
273b65be
JG
2280end:
2281 return type;
2282}
2283
2284BT_HIDDEN
b92ddaaa 2285struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 2286 struct bt_ctf_field_type_variant *variant,
b92ddaaa 2287 uint64_t tag_value)
273b65be
JG
2288{
2289 struct bt_ctf_field_type *type = NULL;
2290 GQuark field_name_quark;
2291 gpointer index;
2292 struct structure_field *field_entry;
b92ddaaa
JG
2293 struct range_overlap_query query = {
2294 .range_start._unsigned = tag_value,
2295 .range_end._unsigned = tag_value,
2296 .mapping_name = 0, .overlaps = 0};
273b65be 2297
b92ddaaa
JG
2298 g_ptr_array_foreach(variant->tag->entries,
2299 check_ranges_overlap_unsigned,
273b65be
JG
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;
2313end:
2314 return type;
2315}
2316
2317BT_HIDDEN
2318int 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
81e36fac
PP
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
273b65be
JG
2335 ret = type->serialize(type, context);
2336end:
2337 return ret;
2338}
2339
c35a1669
JG
2340BT_HIDDEN
2341void 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
24724933
JG
2355BT_HIDDEN
2356struct 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);
2365end:
2366 return copy;
2367}
2368
39a5e0db
JG
2369BT_HIDDEN
2370int 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 ||
9a19a512 2379 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
39a5e0db
JG
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;
2398end:
2399 return ret;
2400}
736133f1 2401
5cec03e4
JG
2402BT_HIDDEN
2403int 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
6c827042 2409 if (!type || !field ||
9a19a512 2410 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
5cec03e4
JG
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
83509119
JG
2422 bt_get(field);
2423 bt_put(((struct structure_field *)
5cec03e4
JG
2424 g_ptr_array_index(structure->fields, index))->type);
2425 ((struct structure_field *) structure->fields->pdata[index])->type =
2426 field;
2427end:
2428 return ret;
2429}
2430
736133f1
JG
2431BT_HIDDEN
2432int 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 ||
9a19a512 2441 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
736133f1
JG
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;
2460end:
2461 return ret;
2462}
aa4e271c
JG
2463
2464BT_HIDDEN
2465int 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
9a19a512
PP
2472 if (!type || bt_ctf_field_type_get_type_id(type) !=
2473 BT_CTF_TYPE_ID_SEQUENCE) {
aa4e271c
JG
2474 ret = -1;
2475 goto end;
2476 }
2477
2478 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2479 parent);
b011f6b0
PP
2480 bt_get(path);
2481 BT_MOVE(sequence->length_field_path, path);
aa4e271c
JG
2482end:
2483 return ret;
2484}
4a1e8671
JG
2485
2486BT_HIDDEN
2487int 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
9a19a512
PP
2493 if (!type || bt_ctf_field_type_get_type_id(type) !=
2494 BT_CTF_TYPE_ID_VARIANT) {
4a1e8671
JG
2495 ret = -1;
2496 goto end;
2497 }
2498
2499 variant = container_of(type, struct bt_ctf_field_type_variant,
2500 parent);
b011f6b0
PP
2501 bt_get(path);
2502 BT_MOVE(variant->tag_field_path, path);
4a1e8671
JG
2503end:
2504 return ret;
2505}
3f39933a
JG
2506
2507BT_HIDDEN
4b5fcb78 2508int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
3f39933a
JG
2509 struct bt_ctf_field_type *tag)
2510{
2511 int ret = 0;
2512 struct bt_ctf_field_type_variant *variant;
2513
f90b8e26 2514 if (!type || !tag ||
9a19a512
PP
2515 bt_ctf_field_type_get_type_id(tag) !=
2516 BT_CTF_TYPE_ID_ENUM) {
3f39933a
JG
2517 ret = -1;
2518 goto end;
2519 }
2520
2521 variant = container_of(type, struct bt_ctf_field_type_variant,
2522 parent);
83509119 2523 bt_get(tag);
3f39933a 2524 if (variant->tag) {
83509119 2525 bt_put(&variant->tag->parent);
3f39933a
JG
2526 }
2527 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2528 parent);
2529end:
2530 return ret;
2531}
2532
5cec03e4
JG
2533BT_HIDDEN
2534int 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
6c827042 2540 if (!type || !field ||
9a19a512 2541 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
5cec03e4
JG
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
83509119
JG
2553 bt_get(field);
2554 bt_put(((struct structure_field *)
5cec03e4
JG
2555 g_ptr_array_index(variant->fields, index))->type);
2556 ((struct structure_field *) variant->fields->pdata[index])->type =
2557 field;
2558end:
2559 return ret;
2560}
2561
273b65be 2562static
de3dd40e 2563void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
273b65be 2564{
de3dd40e
PP
2565 struct bt_ctf_field_type_integer *integer =
2566 (struct bt_ctf_field_type_integer *) type;
273b65be 2567
de3dd40e 2568 if (!type) {
273b65be
JG
2569 return;
2570 }
2571
83509119 2572 bt_put(integer->mapped_clock);
273b65be
JG
2573 g_free(integer);
2574}
2575
2576static
de3dd40e 2577void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
273b65be 2578{
de3dd40e
PP
2579 struct bt_ctf_field_type_enumeration *enumeration =
2580 (struct bt_ctf_field_type_enumeration *) type;
273b65be 2581
de3dd40e 2582 if (!type) {
273b65be
JG
2583 return;
2584 }
2585
273b65be 2586 g_ptr_array_free(enumeration->entries, TRUE);
83509119 2587 bt_put(enumeration->container);
273b65be
JG
2588 g_free(enumeration);
2589}
2590
2591static
de3dd40e 2592void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
273b65be 2593{
de3dd40e
PP
2594 struct bt_ctf_field_type_floating_point *floating_point =
2595 (struct bt_ctf_field_type_floating_point *) type;
273b65be 2596
de3dd40e 2597 if (!type) {
273b65be
JG
2598 return;
2599 }
2600
273b65be
JG
2601 g_free(floating_point);
2602}
2603
2604static
de3dd40e 2605void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
273b65be 2606{
de3dd40e
PP
2607 struct bt_ctf_field_type_structure *structure =
2608 (struct bt_ctf_field_type_structure *) type;
273b65be 2609
de3dd40e 2610 if (!type) {
273b65be
JG
2611 return;
2612 }
2613
273b65be
JG
2614 g_ptr_array_free(structure->fields, TRUE);
2615 g_hash_table_destroy(structure->field_name_to_index);
2616 g_free(structure);
2617}
2618
2619static
de3dd40e 2620void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
273b65be 2621{
de3dd40e
PP
2622 struct bt_ctf_field_type_variant *variant =
2623 (struct bt_ctf_field_type_variant *) type;
273b65be 2624
de3dd40e 2625 if (!type) {
273b65be
JG
2626 return;
2627 }
2628
273b65be
JG
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);
83509119 2632 bt_put(&variant->tag->parent);
b011f6b0 2633 BT_PUT(variant->tag_field_path);
273b65be
JG
2634 g_free(variant);
2635}
2636
2637static
de3dd40e 2638void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
273b65be 2639{
de3dd40e
PP
2640 struct bt_ctf_field_type_array *array =
2641 (struct bt_ctf_field_type_array *) type;
273b65be 2642
de3dd40e 2643 if (!type) {
273b65be
JG
2644 return;
2645 }
2646
83509119 2647 bt_put(array->element_type);
273b65be
JG
2648 g_free(array);
2649}
2650
2651static
de3dd40e 2652void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
273b65be 2653{
de3dd40e
PP
2654 struct bt_ctf_field_type_sequence *sequence =
2655 (struct bt_ctf_field_type_sequence *) type;
273b65be 2656
de3dd40e 2657 if (!type) {
273b65be
JG
2658 return;
2659 }
2660
83509119 2661 bt_put(sequence->element_type);
273b65be 2662 g_string_free(sequence->length_field_name, TRUE);
b011f6b0 2663 BT_PUT(sequence->length_field_path);
273b65be
JG
2664 g_free(sequence);
2665}
2666
2667static
de3dd40e 2668void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
273b65be 2669{
de3dd40e
PP
2670 struct bt_ctf_field_type_string *string =
2671 (struct bt_ctf_field_type_string *) type;
273b65be 2672
de3dd40e 2673 if (!type) {
273b65be
JG
2674 return;
2675 }
2676
273b65be
JG
2677 g_free(string);
2678}
2679
2680static
2681void generic_field_type_freeze(struct bt_ctf_field_type *type)
2682{
2683 type->frozen = 1;
2684}
2685
586411e5
PP
2686static
2687void 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
273b65be
JG
2699static
2700void 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
2709static
2710void freeze_structure_field(struct structure_field *field)
2711{
2712 bt_ctf_field_type_freeze(field->type);
2713}
2714
2715static
2716void 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
3ffba961
JG
2721 /* Cache the alignment */
2722 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2723 generic_field_type_freeze(type);
3ffba961
JG
2724 g_ptr_array_foreach(structure_type->fields,
2725 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2726}
2727
2728static
2729void 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);
3ffba961
JG
2735 g_ptr_array_foreach(variant_type->fields,
2736 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2737}
2738
2739static
2740void 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
3ffba961
JG
2745 /* Cache the alignment */
2746 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2747 generic_field_type_freeze(type);
2748 bt_ctf_field_type_freeze(array_type->element_type);
2749}
2750
2751static
2752void 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
3ffba961
JG
2757 /* Cache the alignment */
2758 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2759 generic_field_type_freeze(type);
2760 bt_ctf_field_type_freeze(sequence_type->element_type);
2761}
2762
2763static
87b41f95 2764const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
273b65be
JG
2765{
2766 const char *encoding_string;
2767
2768 switch (encoding) {
87b41f95 2769 case BT_CTF_STRING_ENCODING_NONE:
273b65be
JG
2770 encoding_string = "none";
2771 break;
87b41f95 2772 case BT_CTF_STRING_ENCODING_ASCII:
273b65be
JG
2773 encoding_string = "ASCII";
2774 break;
87b41f95 2775 case BT_CTF_STRING_ENCODING_UTF8:
273b65be
JG
2776 encoding_string = "UTF8";
2777 break;
2778 default:
2779 encoding_string = "unknown";
2780 break;
2781 }
2782
2783 return encoding_string;
2784}
2785
2786static
2787const 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
2812static
2813int 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);
6cfb906f 2818 int ret = 0;
273b65be
JG
2819
2820 g_string_append_printf(context->string,
6cfb906f 2821 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
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));
6cfb906f
JG
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,
4ebdec03 2837 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2838 }
2839
2840 g_string_append(context->string, "; }");
2841end:
2842 return ret;
273b65be
JG
2843}
2844
2845static
2846int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2847 struct metadata_context *context)
2848{
2849 size_t entry;
9ce21c30 2850 int ret;
273b65be
JG
2851 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2852 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2853 struct bt_ctf_field_type *container_type;
2854 int container_signed;
273b65be 2855
b92ddaaa
JG
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
273b65be
JG
2868 g_string_append(context->string, "enum : ");
2869 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2870 if (ret) {
b92ddaaa 2871 goto error_put_container_type;
273b65be
JG
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
b92ddaaa
JG
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 }
273b65be 2893 } else {
b92ddaaa
JG
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 }
273b65be
JG
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 }
b92ddaaa 2919error_put_container_type:
83509119 2920 bt_put(container_type);
273b65be
JG
2921end:
2922 return ret;
2923}
2924
2925static
2926int 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
2941static
2942int 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);
2988end:
2989 g_string_free(context->field_name, TRUE);
2990 context->field_name = structure_field_name;
2991 return ret;
2992}
2993
2994static
2995int 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("");
6964b7fd
JG
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
273b65be
JG
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, "}");
3046end:
3047 g_string_free(context->field_name, TRUE);
3048 context->field_name = variant_field_name;
3049 return ret;
3050}
3051
3052static
3053int 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 }
3072end:
3073 return ret;
3074}
3075
3076static
3077int 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 }
3098end:
3099 return ret;
3100}
3101
3102static
3103int 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
445c3471
PP
3115static
3116enum 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
273b65be
JG
3142static
3143void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 3144 int byte_order, int set_native)
273b65be
JG
3145{
3146 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3147 struct bt_ctf_field_type_integer, parent);
3148
c35a1669 3149 if (set_native) {
445c3471
PP
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 }
c35a1669 3158 } else {
445c3471
PP
3159 integer_type->user_byte_order =
3160 get_ctf_ir_byte_order(byte_order);
c35a1669
JG
3161 integer_type->declaration.byte_order = byte_order;
3162 }
3163}
3164
3165static
3166void 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);
273b65be
JG
3175}
3176
3177static
3178void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 3179 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
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
c35a1669 3185 if (set_native) {
445c3471
PP
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 }
c35a1669 3201 } else {
445c3471
PP
3202 floating_point_type->user_byte_order =
3203 get_ctf_ir_byte_order(byte_order);
c35a1669
JG
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
3211static
3212void 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
3232static
3233void 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
3253static
3254void 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
3267static
3268void 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 }
273b65be 3281}
24724933
JG
3282
3283static
3284struct 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) {
83509119 3300 bt_get(integer->mapped_clock);
24724933
JG
3301 copy_integer->mapped_clock = integer->mapped_clock;
3302 }
445c3471
PP
3303
3304 copy_integer->user_byte_order = integer->user_byte_order;
3305
24724933
JG
3306end:
3307 return copy;
3308}
3309
3310static
3311struct 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;
3350end:
83509119 3351 bt_put(copy_container);
24724933
JG
3352 return copy;
3353error:
83509119
JG
3354 bt_put(copy_container);
3355 BT_PUT(copy);
3356 return copy;
24724933
JG
3357}
3358
3359static
3360struct 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;
445c3471 3379 copy_float->user_byte_order = floating_point->user_byte_order;
d480b699
PP
3380 copy_float->declaration.sign = &copy_float->sign;
3381 copy_float->declaration.mantissa = &copy_float->mantissa;
3382 copy_float->declaration.exp = &copy_float->exp;
24724933
JG
3383end:
3384 return copy;
3385}
3386
3387static
3388struct 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;
3436end:
3437 return copy;
3438error:
83509119
JG
3439 BT_PUT(copy);
3440 return copy;
24724933
JG
3441}
3442
3443static
3444struct 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;
b011f6b0
PP
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) {
4a1e8671
JG
3504 goto error;
3505 }
3506 }
24724933 3507end:
83509119 3508 bt_put(copy_tag);
24724933
JG
3509 return copy;
3510error:
83509119
JG
3511 bt_put(copy_tag);
3512 BT_PUT(copy);
3513 return copy;
24724933
JG
3514}
3515
3516static
3517struct 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;
3538end:
83509119 3539 bt_put(copy_element);
24724933
JG
3540 return copy;
3541}
3542
3543static
3544struct 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;
aa4e271c
JG
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 }
24724933 3574end:
83509119 3575 bt_put(copy_element);
24724933 3576 return copy;
aa4e271c 3577error:
83509119 3578 BT_PUT(copy);
aa4e271c 3579 goto end;
24724933
JG
3580}
3581
3582static
3583struct 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;
3599end:
3600 return copy;
3601}
265e809c
PP
3602
3603static
3604int 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
3656end:
3657 return ret;
3658}
3659
3660static
3661int 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
3699end:
3700 return ret;
3701}
3702
3703static
3704int 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
3729end:
3730 return ret;
3731}
3732
3733static
3734int 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
3774end:
3775 return ret;
3776}
3777
3778static
3779int 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
3799end:
3800 return ret;
3801}
3802
3803static
3804int 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
3817end:
3818 return ret;
3819}
3820
3821static
3822int 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 }
265e809c
PP
3856 }
3857
3858 /* Equal */
3859 ret = 0;
3860
3861end:
3862 return ret;
3863}
3864
3865static
3866int 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 }
265e809c
PP
3909 }
3910
3911 /* Equal */
3912 ret = 0;
3913
3914end:
3915 return ret;
3916}
3917
3918static
3919int 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
3940end:
3941 return ret;
3942}
3943
3944static
3945int 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
3967end:
3968 return ret;
3969}
3970
3971int 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
9a19a512 3992 if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
265e809c
PP
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
3999end:
4000 return ret;
4001}
09840de5
PP
4002
4003BT_HIDDEN
4004int 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
4033BT_HIDDEN
4034struct 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
4062BT_HIDDEN
4063int 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}
b011f6b0
PP
4084
4085struct 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);
4098end:
4099 return field_path;
4100}
4101
4102struct 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);
4115end:
4116 return field_path;
4117}
This page took 0.244113 seconds and 4 git commands to generate.