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