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