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