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