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