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