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