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