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