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