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