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