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