ir: stream: add bt_ctf_stream_is_writer()
[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 }
4b2da5f0
PP
2153 case BT_CTF_TYPE_ID_ENUM:
2154 {
2155 struct bt_ctf_field_type_enumeration *enum_ft = container_of(
2156 type, struct bt_ctf_field_type_enumeration, parent);
2157 ret = bt_ctf_field_type_get_byte_order(enum_ft->container);
2158 break;
2159 }
9a19a512 2160 case BT_CTF_TYPE_ID_FLOAT:
b92ddaaa
JG
2161 {
2162 struct bt_ctf_field_type_floating_point *floating_point =
2163 container_of(type,
2164 struct bt_ctf_field_type_floating_point,
2165 parent);
445c3471 2166 ret = floating_point->user_byte_order;
b92ddaaa
JG
2167 break;
2168 }
2169 default:
c35a1669
JG
2170 goto end;
2171 }
2172
445c3471
PP
2173 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
2174 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
2175 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
2176 ret == BT_CTF_BYTE_ORDER_NETWORK);
2177
b92ddaaa
JG
2178end:
2179 return ret;
2180}
2181
273b65be
JG
2182int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
2183 enum bt_ctf_byte_order byte_order)
2184{
2185 int ret = 0;
2186 int internal_byte_order;
9a19a512 2187 enum bt_ctf_type_id type_id;
273b65be
JG
2188
2189 if (!type || type->frozen) {
2190 ret = -1;
2191 goto end;
2192 }
2193
273b65be
JG
2194 switch (byte_order) {
2195 case BT_CTF_BYTE_ORDER_NATIVE:
c35a1669
JG
2196 /* Leave unset. Will be initialized by parent. */
2197 internal_byte_order = 0;
273b65be
JG
2198 break;
2199 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
2200 internal_byte_order = LITTLE_ENDIAN;
2201 break;
2202 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
2203 case BT_CTF_BYTE_ORDER_NETWORK:
2204 internal_byte_order = BIG_ENDIAN;
2205 break;
2206 default:
2207 ret = -1;
2208 goto end;
2209 }
2210
3fa759e9 2211 type_id = type->declaration->id;
273b65be 2212 if (set_byte_order_funcs[type_id]) {
c35a1669 2213 set_byte_order_funcs[type_id](type, internal_byte_order, 0);
273b65be
JG
2214 }
2215end:
2216 return ret;
2217}
2218
9a19a512 2219enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
b92ddaaa
JG
2220 struct bt_ctf_field_type *type)
2221{
2222 if (!type) {
9a19a512 2223 return BT_CTF_TYPE_ID_UNKNOWN;
b92ddaaa
JG
2224 }
2225
2226 return type->declaration->id;
2227}
2f2d8e05 2228
56db8d7a
PP
2229int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
2230{
9a19a512 2231 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
56db8d7a
PP
2232}
2233
2234int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
2235{
9a19a512 2236 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
56db8d7a
PP
2237}
2238
2239int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
2240{
9a19a512 2241 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
56db8d7a
PP
2242}
2243
2244int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
2245{
9a19a512 2246 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
56db8d7a
PP
2247}
2248
2249int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
2250{
9a19a512 2251 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
56db8d7a
PP
2252}
2253
2254int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
2255{
9a19a512 2256 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
56db8d7a
PP
2257}
2258
2259int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
2260{
9a19a512 2261 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
56db8d7a
PP
2262}
2263
2264int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
2265{
9a19a512 2266 return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
56db8d7a
PP
2267}
2268
273b65be
JG
2269void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
2270{
83509119 2271 bt_get(type);
273b65be
JG
2272}
2273
2274void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
2275{
83509119 2276 bt_put(type);
273b65be
JG
2277}
2278
2279BT_HIDDEN
2280void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
2281{
2282 if (!type) {
2283 return;
2284 }
2285
2286 type->freeze(type);
2287}
2288
2289BT_HIDDEN
b92ddaaa
JG
2290struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
2291 struct bt_ctf_field_type_variant *variant,
2292 int64_t tag_value)
273b65be
JG
2293{
2294 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
2295 GQuark field_name_quark;
2296 gpointer index;
2297 struct structure_field *field_entry;
2298 struct range_overlap_query query = {
2299 .range_start._signed = tag_value,
2300 .range_end._signed = tag_value,
2301 .mapping_name = 0, .overlaps = 0};
273b65be 2302
b92ddaaa
JG
2303 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
2304 &query);
2305 if (!query.overlaps) {
273b65be
JG
2306 goto end;
2307 }
2308
b92ddaaa
JG
2309 field_name_quark = query.mapping_name;
2310 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2311 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
273b65be
JG
2312 goto end;
2313 }
2314
e54fab7e 2315 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
b92ddaaa 2316 type = field_entry->type;
273b65be
JG
2317end:
2318 return type;
2319}
2320
2321BT_HIDDEN
b92ddaaa 2322struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 2323 struct bt_ctf_field_type_variant *variant,
b92ddaaa 2324 uint64_t tag_value)
273b65be
JG
2325{
2326 struct bt_ctf_field_type *type = NULL;
2327 GQuark field_name_quark;
2328 gpointer index;
2329 struct structure_field *field_entry;
b92ddaaa
JG
2330 struct range_overlap_query query = {
2331 .range_start._unsigned = tag_value,
2332 .range_end._unsigned = tag_value,
2333 .mapping_name = 0, .overlaps = 0};
273b65be 2334
b92ddaaa
JG
2335 g_ptr_array_foreach(variant->tag->entries,
2336 check_ranges_overlap_unsigned,
273b65be
JG
2337 &query);
2338 if (!query.overlaps) {
2339 goto end;
2340 }
2341
2342 field_name_quark = query.mapping_name;
2343 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2344 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
2345 goto end;
2346 }
2347
2348 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
2349 type = field_entry->type;
2350end:
2351 return type;
2352}
2353
2354BT_HIDDEN
2355int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
2356 struct metadata_context *context)
2357{
2358 int ret;
2359
2360 if (!type || !context) {
2361 ret = -1;
2362 goto end;
2363 }
2364
81e36fac
PP
2365 /* Make sure field type is valid before serializing it */
2366 ret = bt_ctf_field_type_validate(type);
2367
2368 if (ret) {
2369 goto end;
2370 }
2371
273b65be
JG
2372 ret = type->serialize(type, context);
2373end:
2374 return ret;
2375}
2376
c35a1669
JG
2377BT_HIDDEN
2378void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
2379 int byte_order)
2380{
2381 if (!type) {
2382 return;
2383 }
2384
2385 assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
2386 if (set_byte_order_funcs[type->declaration->id]) {
2387 set_byte_order_funcs[type->declaration->id](type,
2388 byte_order, 1);
2389 }
2390}
2391
24724933
JG
2392struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
2393{
2394 struct bt_ctf_field_type *copy = NULL;
2395
2396 if (!type) {
2397 goto end;
2398 }
2399
2400 copy = type_copy_funcs[type->declaration->id](type);
2401end:
2402 return copy;
2403}
2404
39a5e0db
JG
2405BT_HIDDEN
2406int bt_ctf_field_type_structure_get_field_name_index(
2407 struct bt_ctf_field_type *type, const char *name)
2408{
2409 int ret;
2410 size_t index;
2411 GQuark name_quark;
2412 struct bt_ctf_field_type_structure *structure;
2413
2414 if (!type || !name ||
9a19a512 2415 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
39a5e0db
JG
2416 ret = -1;
2417 goto end;
2418 }
2419
2420 name_quark = g_quark_try_string(name);
2421 if (!name_quark) {
2422 ret = -1;
2423 goto end;
2424 }
2425
2426 structure = container_of(type, struct bt_ctf_field_type_structure,
2427 parent);
2428 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2429 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2430 ret = -1;
2431 goto end;
2432 }
2433 ret = (int) index;
2434end:
2435 return ret;
2436}
736133f1 2437
5cec03e4
JG
2438BT_HIDDEN
2439int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
2440 struct bt_ctf_field_type *field, int index)
2441{
2442 int ret = 0;
2443 struct bt_ctf_field_type_structure *structure;
2444
6c827042 2445 if (!type || !field ||
9a19a512 2446 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
5cec03e4
JG
2447 ret = -1;
2448 goto end;
2449 }
2450
2451 structure = container_of(type, struct bt_ctf_field_type_structure,
2452 parent);
2453 if (index < 0 || index >= structure->fields->len) {
2454 ret = -1;
2455 goto end;
2456 }
2457
83509119
JG
2458 bt_get(field);
2459 bt_put(((struct structure_field *)
5cec03e4
JG
2460 g_ptr_array_index(structure->fields, index))->type);
2461 ((struct structure_field *) structure->fields->pdata[index])->type =
2462 field;
2463end:
2464 return ret;
2465}
2466
736133f1
JG
2467BT_HIDDEN
2468int bt_ctf_field_type_variant_get_field_name_index(
2469 struct bt_ctf_field_type *type, const char *name)
2470{
2471 int ret;
2472 size_t index;
2473 GQuark name_quark;
2474 struct bt_ctf_field_type_variant *variant;
2475
2476 if (!type || !name ||
9a19a512 2477 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
736133f1
JG
2478 ret = -1;
2479 goto end;
2480 }
2481
2482 name_quark = g_quark_try_string(name);
2483 if (!name_quark) {
2484 ret = -1;
2485 goto end;
2486 }
2487
2488 variant = container_of(type, struct bt_ctf_field_type_variant,
2489 parent);
2490 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2491 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2492 ret = -1;
2493 goto end;
2494 }
2495 ret = (int) index;
2496end:
2497 return ret;
2498}
aa4e271c
JG
2499
2500BT_HIDDEN
2501int bt_ctf_field_type_sequence_set_length_field_path(
2502 struct bt_ctf_field_type *type,
2503 struct bt_ctf_field_path *path)
2504{
2505 int ret = 0;
2506 struct bt_ctf_field_type_sequence *sequence;
2507
9a19a512
PP
2508 if (!type || bt_ctf_field_type_get_type_id(type) !=
2509 BT_CTF_TYPE_ID_SEQUENCE) {
aa4e271c
JG
2510 ret = -1;
2511 goto end;
2512 }
2513
2514 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2515 parent);
b011f6b0
PP
2516 bt_get(path);
2517 BT_MOVE(sequence->length_field_path, path);
aa4e271c
JG
2518end:
2519 return ret;
2520}
4a1e8671
JG
2521
2522BT_HIDDEN
2523int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
2524 struct bt_ctf_field_path *path)
2525{
2526 int ret = 0;
2527 struct bt_ctf_field_type_variant *variant;
2528
9a19a512
PP
2529 if (!type || bt_ctf_field_type_get_type_id(type) !=
2530 BT_CTF_TYPE_ID_VARIANT) {
4a1e8671
JG
2531 ret = -1;
2532 goto end;
2533 }
2534
2535 variant = container_of(type, struct bt_ctf_field_type_variant,
2536 parent);
b011f6b0
PP
2537 bt_get(path);
2538 BT_MOVE(variant->tag_field_path, path);
4a1e8671
JG
2539end:
2540 return ret;
2541}
3f39933a
JG
2542
2543BT_HIDDEN
4b5fcb78 2544int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
3f39933a
JG
2545 struct bt_ctf_field_type *tag)
2546{
2547 int ret = 0;
2548 struct bt_ctf_field_type_variant *variant;
2549
f90b8e26 2550 if (!type || !tag ||
9a19a512
PP
2551 bt_ctf_field_type_get_type_id(tag) !=
2552 BT_CTF_TYPE_ID_ENUM) {
3f39933a
JG
2553 ret = -1;
2554 goto end;
2555 }
2556
2557 variant = container_of(type, struct bt_ctf_field_type_variant,
2558 parent);
83509119 2559 bt_get(tag);
3f39933a 2560 if (variant->tag) {
83509119 2561 bt_put(&variant->tag->parent);
3f39933a
JG
2562 }
2563 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
2564 parent);
2565end:
2566 return ret;
2567}
2568
5cec03e4
JG
2569BT_HIDDEN
2570int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
2571 struct bt_ctf_field_type *field, int index)
2572{
2573 int ret = 0;
2574 struct bt_ctf_field_type_variant *variant;
2575
6c827042 2576 if (!type || !field ||
9a19a512 2577 bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
5cec03e4
JG
2578 ret = -1;
2579 goto end;
2580 }
2581
2582 variant = container_of(type, struct bt_ctf_field_type_variant,
2583 parent);
2584 if (index < 0 || index >= variant->fields->len) {
2585 ret = -1;
2586 goto end;
2587 }
2588
83509119
JG
2589 bt_get(field);
2590 bt_put(((struct structure_field *)
5cec03e4
JG
2591 g_ptr_array_index(variant->fields, index))->type);
2592 ((struct structure_field *) variant->fields->pdata[index])->type =
2593 field;
2594end:
2595 return ret;
2596}
2597
273b65be 2598static
de3dd40e 2599void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
273b65be 2600{
de3dd40e
PP
2601 struct bt_ctf_field_type_integer *integer =
2602 (struct bt_ctf_field_type_integer *) type;
273b65be 2603
de3dd40e 2604 if (!type) {
273b65be
JG
2605 return;
2606 }
2607
83509119 2608 bt_put(integer->mapped_clock);
273b65be
JG
2609 g_free(integer);
2610}
2611
2612static
de3dd40e 2613void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
273b65be 2614{
de3dd40e
PP
2615 struct bt_ctf_field_type_enumeration *enumeration =
2616 (struct bt_ctf_field_type_enumeration *) type;
273b65be 2617
de3dd40e 2618 if (!type) {
273b65be
JG
2619 return;
2620 }
2621
273b65be 2622 g_ptr_array_free(enumeration->entries, TRUE);
83509119 2623 bt_put(enumeration->container);
273b65be
JG
2624 g_free(enumeration);
2625}
2626
2627static
de3dd40e 2628void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
273b65be 2629{
de3dd40e
PP
2630 struct bt_ctf_field_type_floating_point *floating_point =
2631 (struct bt_ctf_field_type_floating_point *) type;
273b65be 2632
de3dd40e 2633 if (!type) {
273b65be
JG
2634 return;
2635 }
2636
273b65be
JG
2637 g_free(floating_point);
2638}
2639
2640static
de3dd40e 2641void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
273b65be 2642{
de3dd40e
PP
2643 struct bt_ctf_field_type_structure *structure =
2644 (struct bt_ctf_field_type_structure *) type;
273b65be 2645
de3dd40e 2646 if (!type) {
273b65be
JG
2647 return;
2648 }
2649
273b65be
JG
2650 g_ptr_array_free(structure->fields, TRUE);
2651 g_hash_table_destroy(structure->field_name_to_index);
2652 g_free(structure);
2653}
2654
2655static
de3dd40e 2656void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
273b65be 2657{
de3dd40e
PP
2658 struct bt_ctf_field_type_variant *variant =
2659 (struct bt_ctf_field_type_variant *) type;
273b65be 2660
de3dd40e 2661 if (!type) {
273b65be
JG
2662 return;
2663 }
2664
273b65be
JG
2665 g_ptr_array_free(variant->fields, TRUE);
2666 g_hash_table_destroy(variant->field_name_to_index);
2667 g_string_free(variant->tag_name, TRUE);
83509119 2668 bt_put(&variant->tag->parent);
b011f6b0 2669 BT_PUT(variant->tag_field_path);
273b65be
JG
2670 g_free(variant);
2671}
2672
2673static
de3dd40e 2674void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
273b65be 2675{
de3dd40e
PP
2676 struct bt_ctf_field_type_array *array =
2677 (struct bt_ctf_field_type_array *) type;
273b65be 2678
de3dd40e 2679 if (!type) {
273b65be
JG
2680 return;
2681 }
2682
83509119 2683 bt_put(array->element_type);
273b65be
JG
2684 g_free(array);
2685}
2686
2687static
de3dd40e 2688void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
273b65be 2689{
de3dd40e
PP
2690 struct bt_ctf_field_type_sequence *sequence =
2691 (struct bt_ctf_field_type_sequence *) type;
273b65be 2692
de3dd40e 2693 if (!type) {
273b65be
JG
2694 return;
2695 }
2696
83509119 2697 bt_put(sequence->element_type);
273b65be 2698 g_string_free(sequence->length_field_name, TRUE);
b011f6b0 2699 BT_PUT(sequence->length_field_path);
273b65be
JG
2700 g_free(sequence);
2701}
2702
2703static
de3dd40e 2704void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
273b65be 2705{
de3dd40e
PP
2706 struct bt_ctf_field_type_string *string =
2707 (struct bt_ctf_field_type_string *) type;
273b65be 2708
de3dd40e 2709 if (!type) {
273b65be
JG
2710 return;
2711 }
2712
273b65be
JG
2713 g_free(string);
2714}
2715
2716static
2717void generic_field_type_freeze(struct bt_ctf_field_type *type)
2718{
2719 type->frozen = 1;
2720}
2721
586411e5
PP
2722static
2723void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
2724{
2725 struct bt_ctf_field_type_integer *integer_type = container_of(
2726 type, struct bt_ctf_field_type_integer, parent);
2727
2728 if (integer_type->mapped_clock) {
2729 bt_ctf_clock_freeze(integer_type->mapped_clock);
2730 }
2731
2732 generic_field_type_freeze(type);
2733}
2734
273b65be
JG
2735static
2736void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
2737{
2738 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
2739 type, struct bt_ctf_field_type_enumeration, parent);
2740
2741 generic_field_type_freeze(type);
2742 bt_ctf_field_type_freeze(enumeration_type->container);
2743}
2744
2745static
2746void freeze_structure_field(struct structure_field *field)
2747{
2748 bt_ctf_field_type_freeze(field->type);
2749}
2750
2751static
2752void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
2753{
2754 struct bt_ctf_field_type_structure *structure_type = container_of(
2755 type, struct bt_ctf_field_type_structure, parent);
2756
3ffba961
JG
2757 /* Cache the alignment */
2758 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 2759 generic_field_type_freeze(type);
3ffba961
JG
2760 g_ptr_array_foreach(structure_type->fields,
2761 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2762}
2763
2764static
2765void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
2766{
2767 struct bt_ctf_field_type_variant *variant_type = container_of(
2768 type, struct bt_ctf_field_type_variant, parent);
2769
2770 generic_field_type_freeze(type);
3ffba961
JG
2771 g_ptr_array_foreach(variant_type->fields,
2772 (GFunc) freeze_structure_field, NULL);
273b65be
JG
2773}
2774
2775static
2776void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
2777{
2778 struct bt_ctf_field_type_array *array_type = container_of(
2779 type, struct bt_ctf_field_type_array, parent);
2780
3ffba961
JG
2781 /* Cache the alignment */
2782 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2783 generic_field_type_freeze(type);
2784 bt_ctf_field_type_freeze(array_type->element_type);
2785}
2786
2787static
2788void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
2789{
2790 struct bt_ctf_field_type_sequence *sequence_type = container_of(
2791 type, struct bt_ctf_field_type_sequence, parent);
2792
3ffba961
JG
2793 /* Cache the alignment */
2794 type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
273b65be
JG
2795 generic_field_type_freeze(type);
2796 bt_ctf_field_type_freeze(sequence_type->element_type);
2797}
2798
2799static
87b41f95 2800const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
273b65be
JG
2801{
2802 const char *encoding_string;
2803
2804 switch (encoding) {
87b41f95 2805 case BT_CTF_STRING_ENCODING_NONE:
273b65be
JG
2806 encoding_string = "none";
2807 break;
87b41f95 2808 case BT_CTF_STRING_ENCODING_ASCII:
273b65be
JG
2809 encoding_string = "ASCII";
2810 break;
87b41f95 2811 case BT_CTF_STRING_ENCODING_UTF8:
273b65be
JG
2812 encoding_string = "UTF8";
2813 break;
2814 default:
2815 encoding_string = "unknown";
2816 break;
2817 }
2818
2819 return encoding_string;
2820}
2821
2822static
2823const char *get_integer_base_string(enum bt_ctf_integer_base base)
2824{
2825 const char *base_string;
2826
2827 switch (base) {
2828 case BT_CTF_INTEGER_BASE_DECIMAL:
2829 base_string = "decimal";
2830 break;
2831 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
2832 base_string = "hexadecimal";
2833 break;
2834 case BT_CTF_INTEGER_BASE_OCTAL:
2835 base_string = "octal";
2836 break;
2837 case BT_CTF_INTEGER_BASE_BINARY:
2838 base_string = "binary";
2839 break;
2840 default:
2841 base_string = "unknown";
2842 break;
2843 }
2844
2845 return base_string;
2846}
2847
2848static
2849int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
2850 struct metadata_context *context)
2851{
2852 struct bt_ctf_field_type_integer *integer = container_of(type,
2853 struct bt_ctf_field_type_integer, parent);
6cfb906f 2854 int ret = 0;
273b65be
JG
2855
2856 g_string_append_printf(context->string,
6cfb906f 2857 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
273b65be
JG
2858 integer->declaration.len, type->declaration->alignment,
2859 (integer->declaration.signedness ? "true" : "false"),
2860 get_encoding_string(integer->declaration.encoding),
2861 get_integer_base_string(integer->declaration.base),
2862 get_byte_order_string(integer->declaration.byte_order));
6cfb906f
JG
2863 if (integer->mapped_clock) {
2864 const char *clock_name = bt_ctf_clock_get_name(
2865 integer->mapped_clock);
2866
2867 if (!clock_name) {
2868 ret = -1;
2869 goto end;
2870 }
2871
2872 g_string_append_printf(context->string,
4ebdec03 2873 "; map = clock.%s.value", clock_name);
6cfb906f
JG
2874 }
2875
2876 g_string_append(context->string, "; }");
2877end:
2878 return ret;
273b65be
JG
2879}
2880
2881static
2882int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
2883 struct metadata_context *context)
2884{
2885 size_t entry;
9ce21c30 2886 int ret;
273b65be
JG
2887 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
2888 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
2889 struct bt_ctf_field_type *container_type;
2890 int container_signed;
273b65be 2891
b92ddaaa
JG
2892 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
2893 if (!container_type) {
2894 ret = -1;
2895 goto end;
2896 }
2897
2898 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
2899 if (container_signed < 0) {
2900 ret = container_signed;
2901 goto error_put_container_type;
2902 }
2903
273b65be
JG
2904 g_string_append(context->string, "enum : ");
2905 ret = bt_ctf_field_type_serialize(enumeration->container, context);
2906 if (ret) {
b92ddaaa 2907 goto error_put_container_type;
273b65be
JG
2908 }
2909
2910 g_string_append(context->string, " { ");
2911 for (entry = 0; entry < enumeration->entries->len; entry++) {
2912 struct enumeration_mapping *mapping =
2913 enumeration->entries->pdata[entry];
2914
b92ddaaa
JG
2915 if (container_signed) {
2916 if (mapping->range_start._signed ==
2917 mapping->range_end._signed) {
2918 g_string_append_printf(context->string,
2919 "\"%s\" = %" PRId64,
2920 g_quark_to_string(mapping->string),
2921 mapping->range_start._signed);
2922 } else {
2923 g_string_append_printf(context->string,
2924 "\"%s\" = %" PRId64 " ... %" PRId64,
2925 g_quark_to_string(mapping->string),
2926 mapping->range_start._signed,
2927 mapping->range_end._signed);
2928 }
273b65be 2929 } else {
b92ddaaa
JG
2930 if (mapping->range_start._unsigned ==
2931 mapping->range_end._unsigned) {
2932 g_string_append_printf(context->string,
2933 "\"%s\" = %" PRIu64,
2934 g_quark_to_string(mapping->string),
2935 mapping->range_start._unsigned);
2936 } else {
2937 g_string_append_printf(context->string,
2938 "\"%s\" = %" PRIu64 " ... %" PRIu64,
2939 g_quark_to_string(mapping->string),
2940 mapping->range_start._unsigned,
2941 mapping->range_end._unsigned);
2942 }
273b65be
JG
2943 }
2944
2945 g_string_append(context->string,
2946 ((entry != (enumeration->entries->len - 1)) ?
2947 ", " : " }"));
2948 }
2949
2950 if (context->field_name->len) {
2951 g_string_append_printf(context->string, " %s",
2952 context->field_name->str);
2953 g_string_assign(context->field_name, "");
2954 }
b92ddaaa 2955error_put_container_type:
83509119 2956 bt_put(container_type);
273b65be
JG
2957end:
2958 return ret;
2959}
2960
2961static
2962int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
2963 struct metadata_context *context)
2964{
2965 struct bt_ctf_field_type_floating_point *floating_point = container_of(
2966 type, struct bt_ctf_field_type_floating_point, parent);
2967
2968 g_string_append_printf(context->string,
2969 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
2970 floating_point->declaration.exp->len,
2971 floating_point->declaration.mantissa->len + 1,
2972 get_byte_order_string(floating_point->declaration.byte_order),
2973 type->declaration->alignment);
2974 return 0;
2975}
2976
2977static
2978int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
2979 struct metadata_context *context)
2980{
2981 size_t i;
2982 unsigned int indent;
2983 int ret = 0;
2984 struct bt_ctf_field_type_structure *structure = container_of(type,
2985 struct bt_ctf_field_type_structure, parent);
2986 GString *structure_field_name = context->field_name;
2987
2988 context->field_name = g_string_new("");
2989
2990 context->current_indentation_level++;
2991 g_string_append(context->string, "struct {\n");
2992
2993 for (i = 0; i < structure->fields->len; i++) {
2994 struct structure_field *field;
2995
2996 for (indent = 0; indent < context->current_indentation_level;
2997 indent++) {
2998 g_string_append_c(context->string, '\t');
2999 }
3000
3001 field = structure->fields->pdata[i];
3002 g_string_assign(context->field_name,
3003 g_quark_to_string(field->name));
3004 ret = bt_ctf_field_type_serialize(field->type, context);
3005 if (ret) {
3006 goto end;
3007 }
3008
3009 if (context->field_name->len) {
3010 g_string_append_printf(context->string, " %s",
3011 context->field_name->str);
3012 }
3013 g_string_append(context->string, ";\n");
3014 }
3015
3016 context->current_indentation_level--;
3017 for (indent = 0; indent < context->current_indentation_level;
3018 indent++) {
3019 g_string_append_c(context->string, '\t');
3020 }
3021
3022 g_string_append_printf(context->string, "} align(%zu)",
3023 type->declaration->alignment);
3024end:
3025 g_string_free(context->field_name, TRUE);
3026 context->field_name = structure_field_name;
3027 return ret;
3028}
3029
3030static
3031int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
3032 struct metadata_context *context)
3033{
3034 size_t i;
3035 unsigned int indent;
3036 int ret = 0;
3037 struct bt_ctf_field_type_variant *variant = container_of(
3038 type, struct bt_ctf_field_type_variant, parent);
3039 GString *variant_field_name = context->field_name;
3040
3041 context->field_name = g_string_new("");
6964b7fd
JG
3042 if (variant->tag_name->len > 0) {
3043 g_string_append_printf(context->string,
3044 "variant <%s> {\n", variant->tag_name->str);
3045 } else {
3046 g_string_append(context->string, "variant {\n");
3047 }
3048
273b65be
JG
3049 context->current_indentation_level++;
3050 for (i = 0; i < variant->fields->len; i++) {
3051 struct structure_field *field = variant->fields->pdata[i];
3052
3053 g_string_assign(context->field_name,
3054 g_quark_to_string(field->name));
3055 for (indent = 0; indent < context->current_indentation_level;
3056 indent++) {
3057 g_string_append_c(context->string, '\t');
3058 }
3059
3060 g_string_assign(context->field_name,
3061 g_quark_to_string(field->name));
3062 ret = bt_ctf_field_type_serialize(field->type, context);
3063 if (ret) {
3064 goto end;
3065 }
3066
3067 if (context->field_name->len) {
3068 g_string_append_printf(context->string, " %s;",
3069 context->field_name->str);
3070 }
3071
3072 g_string_append_c(context->string, '\n');
3073 }
3074
3075 context->current_indentation_level--;
3076 for (indent = 0; indent < context->current_indentation_level;
3077 indent++) {
3078 g_string_append_c(context->string, '\t');
3079 }
3080
3081 g_string_append(context->string, "}");
3082end:
3083 g_string_free(context->field_name, TRUE);
3084 context->field_name = variant_field_name;
3085 return ret;
3086}
3087
3088static
3089int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
3090 struct metadata_context *context)
3091{
3092 int ret = 0;
3093 struct bt_ctf_field_type_array *array = container_of(type,
3094 struct bt_ctf_field_type_array, parent);
3095
3096 ret = bt_ctf_field_type_serialize(array->element_type, context);
3097 if (ret) {
3098 goto end;
3099 }
3100
3101 if (context->field_name->len) {
3102 g_string_append_printf(context->string, " %s[%u]",
3103 context->field_name->str, array->length);
3104 g_string_assign(context->field_name, "");
3105 } else {
3106 g_string_append_printf(context->string, "[%u]", array->length);
3107 }
3108end:
3109 return ret;
3110}
3111
3112static
3113int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
3114 struct metadata_context *context)
3115{
3116 int ret = 0;
3117 struct bt_ctf_field_type_sequence *sequence = container_of(
3118 type, struct bt_ctf_field_type_sequence, parent);
3119
3120 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
3121 if (ret) {
3122 goto end;
3123 }
3124
3125 if (context->field_name->len) {
3126 g_string_append_printf(context->string, " %s[%s]",
3127 context->field_name->str,
3128 sequence->length_field_name->str);
3129 g_string_assign(context->field_name, "");
3130 } else {
3131 g_string_append_printf(context->string, "[%s]",
3132 sequence->length_field_name->str);
3133 }
3134end:
3135 return ret;
3136}
3137
3138static
3139int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
3140 struct metadata_context *context)
3141{
3142 struct bt_ctf_field_type_string *string = container_of(
3143 type, struct bt_ctf_field_type_string, parent);
3144
3145 g_string_append_printf(context->string,
3146 "string { encoding = %s; }",
3147 get_encoding_string(string->declaration.encoding));
3148 return 0;
3149}
3150
445c3471
PP
3151static
3152enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
3153 enum bt_ctf_byte_order ret;
3154
3155 switch (byte_order) {
3156 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
3157 case LITTLE_ENDIAN:
3158 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
3159 break;
3160 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
3161 case BIG_ENDIAN:
3162 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
3163 break;
3164 case BT_CTF_BYTE_ORDER_NETWORK:
3165 ret = BT_CTF_BYTE_ORDER_NETWORK;
3166 break;
3167 case BT_CTF_BYTE_ORDER_NATIVE:
3168 ret = BT_CTF_BYTE_ORDER_NATIVE;
3169 break;
3170 default:
3171 ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3172 break;
3173 }
3174
3175 return ret;
3176}
3177
273b65be
JG
3178static
3179void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
c35a1669 3180 int byte_order, int set_native)
273b65be
JG
3181{
3182 struct bt_ctf_field_type_integer *integer_type = container_of(type,
3183 struct bt_ctf_field_type_integer, parent);
3184
c35a1669 3185 if (set_native) {
445c3471
PP
3186 if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
3187 /*
3188 * User byte order is native, so we can set
3189 * the real byte order.
3190 */
3191 integer_type->declaration.byte_order =
3192 byte_order;
3193 }
c35a1669 3194 } else {
445c3471
PP
3195 integer_type->user_byte_order =
3196 get_ctf_ir_byte_order(byte_order);
c35a1669
JG
3197 integer_type->declaration.byte_order = byte_order;
3198 }
3199}
3200
3201static
3202void bt_ctf_field_type_enumeration_set_byte_order(
3203 struct bt_ctf_field_type *type, int byte_order, int set_native)
3204{
3205 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
3206 struct bt_ctf_field_type_enumeration, parent);
3207
3208 /* Safe to assume that container is an integer */
3209 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
3210 byte_order, set_native);
273b65be
JG
3211}
3212
3213static
3214void bt_ctf_field_type_floating_point_set_byte_order(
c35a1669 3215 struct bt_ctf_field_type *type, int byte_order, int set_native)
273b65be
JG
3216{
3217 struct bt_ctf_field_type_floating_point *floating_point_type =
3218 container_of(type, struct bt_ctf_field_type_floating_point,
3219 parent);
3220
c35a1669 3221 if (set_native) {
445c3471
PP
3222 if (floating_point_type->user_byte_order ==
3223 BT_CTF_BYTE_ORDER_NATIVE) {
3224 /*
3225 * User byte order is native, so we can set
3226 * the real byte order.
3227 */
3228 floating_point_type->declaration.byte_order =
3229 byte_order;
3230 floating_point_type->sign.byte_order =
3231 byte_order;
3232 floating_point_type->mantissa.byte_order =
3233 byte_order;
3234 floating_point_type->exp.byte_order =
3235 byte_order;
3236 }
c35a1669 3237 } else {
445c3471
PP
3238 floating_point_type->user_byte_order =
3239 get_ctf_ir_byte_order(byte_order);
c35a1669
JG
3240 floating_point_type->declaration.byte_order = byte_order;
3241 floating_point_type->sign.byte_order = byte_order;
3242 floating_point_type->mantissa.byte_order = byte_order;
3243 floating_point_type->exp.byte_order = byte_order;
3244 }
3245}
3246
3247static
3248void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
3249 int byte_order, int set_native)
3250{
3251 int i;
3252 struct bt_ctf_field_type_structure *structure_type =
3253 container_of(type, struct bt_ctf_field_type_structure,
3254 parent);
3255
3256 for (i = 0; i < structure_type->fields->len; i++) {
3257 struct structure_field *field = g_ptr_array_index(
3258 structure_type->fields, i);
3259 struct bt_ctf_field_type *field_type = field->type;
3260
3261 if (set_byte_order_funcs[field_type->declaration->id]) {
3262 set_byte_order_funcs[field_type->declaration->id](
3263 field_type, byte_order, set_native);
3264 }
3265 }
3266}
3267
3268static
3269void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
3270 int byte_order, int set_native)
3271{
3272 int i;
3273 struct bt_ctf_field_type_variant *variant_type =
3274 container_of(type, struct bt_ctf_field_type_variant,
3275 parent);
3276
3277 for (i = 0; i < variant_type->fields->len; i++) {
3278 struct structure_field *field = g_ptr_array_index(
3279 variant_type->fields, i);
3280 struct bt_ctf_field_type *field_type = field->type;
3281
3282 if (set_byte_order_funcs[field_type->declaration->id]) {
3283 set_byte_order_funcs[field_type->declaration->id](
3284 field_type, byte_order, set_native);
3285 }
3286 }
3287}
3288
3289static
3290void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
3291 int byte_order, int set_native)
3292{
3293 struct bt_ctf_field_type_array *array_type =
3294 container_of(type, struct bt_ctf_field_type_array,
3295 parent);
3296
3297 if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
3298 set_byte_order_funcs[array_type->element_type->declaration->id](
3299 array_type->element_type, byte_order, set_native);
3300 }
3301}
3302
3303static
3304void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
3305 int byte_order, int set_native)
3306{
3307 struct bt_ctf_field_type_sequence *sequence_type =
3308 container_of(type, struct bt_ctf_field_type_sequence,
3309 parent);
3310
3311 if (set_byte_order_funcs[
3312 sequence_type->element_type->declaration->id]) {
3313 set_byte_order_funcs[
3314 sequence_type->element_type->declaration->id](
3315 sequence_type->element_type, byte_order, set_native);
3316 }
273b65be 3317}
24724933
JG
3318
3319static
3320struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
3321 struct bt_ctf_field_type *type)
3322{
3323 struct bt_ctf_field_type *copy;
3324 struct bt_ctf_field_type_integer *integer, *copy_integer;
3325
3326 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
3327 copy = bt_ctf_field_type_integer_create(integer->declaration.len);
3328 if (!copy) {
3329 goto end;
3330 }
3331
3332 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
3333 parent);
3334 copy_integer->declaration = integer->declaration;
3335 if (integer->mapped_clock) {
83509119 3336 bt_get(integer->mapped_clock);
24724933
JG
3337 copy_integer->mapped_clock = integer->mapped_clock;
3338 }
445c3471
PP
3339
3340 copy_integer->user_byte_order = integer->user_byte_order;
3341
24724933
JG
3342end:
3343 return copy;
3344}
3345
3346static
3347struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
3348 struct bt_ctf_field_type *type)
3349{
3350 size_t i;
3351 struct bt_ctf_field_type *copy = NULL, *copy_container;
3352 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
3353
3354 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
3355 parent);
3356
3357 /* Copy the source enumeration's container */
3358 copy_container = bt_ctf_field_type_copy(enumeration->container);
3359 if (!copy_container) {
3360 goto end;
3361 }
3362
3363 copy = bt_ctf_field_type_enumeration_create(copy_container);
3364 if (!copy) {
3365 goto end;
3366 }
3367 copy_enumeration = container_of(copy,
3368 struct bt_ctf_field_type_enumeration, parent);
3369
3370 /* Copy all enumaration entries */
3371 for (i = 0; i < enumeration->entries->len; i++) {
3372 struct enumeration_mapping *mapping = g_ptr_array_index(
3373 enumeration->entries, i);
3374 struct enumeration_mapping* copy_mapping = g_new0(
3375 struct enumeration_mapping, 1);
3376
3377 if (!copy_mapping) {
3378 goto error;
3379 }
3380
3381 *copy_mapping = *mapping;
3382 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
3383 }
3384
3385 copy_enumeration->declaration = enumeration->declaration;
3386end:
83509119 3387 bt_put(copy_container);
24724933
JG
3388 return copy;
3389error:
83509119
JG
3390 bt_put(copy_container);
3391 BT_PUT(copy);
3392 return copy;
24724933
JG
3393}
3394
3395static
3396struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
3397 struct bt_ctf_field_type *type)
3398{
3399 struct bt_ctf_field_type *copy;
3400 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
3401
3402 floating_point = container_of(type,
3403 struct bt_ctf_field_type_floating_point, parent);
3404 copy = bt_ctf_field_type_floating_point_create();
3405 if (!copy) {
3406 goto end;
3407 }
3408
3409 copy_float = container_of(copy,
3410 struct bt_ctf_field_type_floating_point, parent);
3411 copy_float->declaration = floating_point->declaration;
3412 copy_float->sign = floating_point->sign;
3413 copy_float->mantissa = floating_point->mantissa;
3414 copy_float->exp = floating_point->exp;
445c3471 3415 copy_float->user_byte_order = floating_point->user_byte_order;
d480b699
PP
3416 copy_float->declaration.sign = &copy_float->sign;
3417 copy_float->declaration.mantissa = &copy_float->mantissa;
3418 copy_float->declaration.exp = &copy_float->exp;
24724933
JG
3419end:
3420 return copy;
3421}
3422
3423static
3424struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
3425 struct bt_ctf_field_type *type)
3426{
3427 int i;
3428 GHashTableIter iter;
3429 gpointer key, value;
3430 struct bt_ctf_field_type *copy;
3431 struct bt_ctf_field_type_structure *structure, *copy_structure;
3432
3433 structure = container_of(type, struct bt_ctf_field_type_structure,
3434 parent);
3435 copy = bt_ctf_field_type_structure_create();
3436 if (!copy) {
3437 goto end;
3438 }
3439
3440 copy_structure = container_of(copy,
3441 struct bt_ctf_field_type_structure, parent);
3442
3443 /* Copy field_name_to_index */
3444 g_hash_table_iter_init(&iter, structure->field_name_to_index);
3445 while (g_hash_table_iter_next (&iter, &key, &value)) {
3446 g_hash_table_insert(copy_structure->field_name_to_index,
3447 key, value);
3448 }
3449
3450 for (i = 0; i < structure->fields->len; i++) {
3451 struct structure_field *entry, *copy_entry;
3452 struct bt_ctf_field_type *copy_field;
3453
3454 copy_entry = g_new0(struct structure_field, 1);
3455 if (!copy_entry) {
3456 goto error;
3457 }
3458
3459 entry = g_ptr_array_index(structure->fields, i);
3460 copy_field = bt_ctf_field_type_copy(entry->type);
3461 if (!copy_field) {
3462 g_free(copy_entry);
3463 goto error;
3464 }
3465
3466 copy_entry->name = entry->name;
3467 copy_entry->type = copy_field;
3468 g_ptr_array_add(copy_structure->fields, copy_entry);
3469 }
3470
3471 copy_structure->declaration = structure->declaration;
3472end:
3473 return copy;
3474error:
83509119
JG
3475 BT_PUT(copy);
3476 return copy;
24724933
JG
3477}
3478
3479static
3480struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
3481 struct bt_ctf_field_type *type)
3482{
3483 int i;
3484 GHashTableIter iter;
3485 gpointer key, value;
3486 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
3487 struct bt_ctf_field_type_variant *variant, *copy_variant;
3488
3489 variant = container_of(type, struct bt_ctf_field_type_variant,
3490 parent);
3491 if (variant->tag) {
3492 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
3493 if (!copy_tag) {
3494 goto end;
3495 }
3496 }
3497
3498 copy = bt_ctf_field_type_variant_create(copy_tag,
3499 variant->tag_name->len ? variant->tag_name->str : NULL);
3500 if (!copy) {
3501 goto end;
3502 }
3503
3504 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
3505 parent);
3506
3507 /* Copy field_name_to_index */
3508 g_hash_table_iter_init(&iter, variant->field_name_to_index);
3509 while (g_hash_table_iter_next (&iter, &key, &value)) {
3510 g_hash_table_insert(copy_variant->field_name_to_index,
3511 key, value);
3512 }
3513
3514 for (i = 0; i < variant->fields->len; i++) {
3515 struct structure_field *entry, *copy_entry;
3516 struct bt_ctf_field_type *copy_field;
3517
3518 copy_entry = g_new0(struct structure_field, 1);
3519 if (!copy_entry) {
3520 goto error;
3521 }
3522
3523 entry = g_ptr_array_index(variant->fields, i);
3524 copy_field = bt_ctf_field_type_copy(entry->type);
3525 if (!copy_field) {
3526 g_free(copy_entry);
3527 goto error;
3528 }
3529
3530 copy_entry->name = entry->name;
3531 copy_entry->type = copy_field;
3532 g_ptr_array_add(copy_variant->fields, copy_entry);
3533 }
3534
3535 copy_variant->declaration = variant->declaration;
b011f6b0
PP
3536 if (variant->tag_field_path) {
3537 copy_variant->tag_field_path = bt_ctf_field_path_copy(
3538 variant->tag_field_path);
3539 if (!copy_variant->tag_field_path) {
4a1e8671
JG
3540 goto error;
3541 }
3542 }
24724933 3543end:
83509119 3544 bt_put(copy_tag);
24724933
JG
3545 return copy;
3546error:
83509119
JG
3547 bt_put(copy_tag);
3548 BT_PUT(copy);
3549 return copy;
24724933
JG
3550}
3551
3552static
3553struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
3554 struct bt_ctf_field_type *type)
3555{
3556 struct bt_ctf_field_type *copy = NULL, *copy_element;
3557 struct bt_ctf_field_type_array *array, *copy_array;
3558
3559 array = container_of(type, struct bt_ctf_field_type_array,
3560 parent);
3561 copy_element = bt_ctf_field_type_copy(array->element_type);
3562 if (!copy_element) {
3563 goto end;
3564 }
3565
3566 copy = bt_ctf_field_type_array_create(copy_element, array->length);
3567 if (!copy) {
3568 goto end;
3569 }
3570
3571 copy_array = container_of(copy, struct bt_ctf_field_type_array,
3572 parent);
3573 copy_array->declaration = array->declaration;
3574end:
83509119 3575 bt_put(copy_element);
24724933
JG
3576 return copy;
3577}
3578
3579static
3580struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
3581 struct bt_ctf_field_type *type)
3582{
3583 struct bt_ctf_field_type *copy = NULL, *copy_element;
3584 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
3585
3586 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3587 parent);
3588 copy_element = bt_ctf_field_type_copy(sequence->element_type);
3589 if (!copy_element) {
3590 goto end;
3591 }
3592
3593 copy = bt_ctf_field_type_sequence_create(copy_element,
3594 sequence->length_field_name->len ?
3595 sequence->length_field_name->str : NULL);
3596 if (!copy) {
3597 goto end;
3598 }
3599
3600 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
3601 parent);
3602 copy_sequence->declaration = sequence->declaration;
aa4e271c
JG
3603 if (sequence->length_field_path) {
3604 copy_sequence->length_field_path = bt_ctf_field_path_copy(
3605 sequence->length_field_path);
3606 if (!copy_sequence->length_field_path) {
3607 goto error;
3608 }
3609 }
24724933 3610end:
83509119 3611 bt_put(copy_element);
24724933 3612 return copy;
aa4e271c 3613error:
83509119 3614 BT_PUT(copy);
aa4e271c 3615 goto end;
24724933
JG
3616}
3617
3618static
3619struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
3620 struct bt_ctf_field_type *type)
3621{
3622 struct bt_ctf_field_type *copy;
3623 struct bt_ctf_field_type_string *string, *copy_string;
3624
3625 copy = bt_ctf_field_type_string_create();
3626 if (!copy) {
3627 goto end;
3628 }
3629
3630 string = container_of(type, struct bt_ctf_field_type_string,
3631 parent);
3632 copy_string = container_of(type, struct bt_ctf_field_type_string,
3633 parent);
3634 copy_string->declaration = string->declaration;
3635end:
3636 return copy;
3637}
265e809c
PP
3638
3639static
3640int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
3641 struct bt_ctf_field_type *type_b)
3642{
3643 int ret = 1;
3644 struct bt_ctf_field_type_integer *integer_a;
3645 struct bt_ctf_field_type_integer *integer_b;
3646 struct declaration_integer *decl_a;
3647 struct declaration_integer *decl_b;
3648
3649 integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
3650 parent);
3651 integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
3652 parent);
3653 decl_a = &integer_a->declaration;
3654 decl_b = &integer_b->declaration;
3655
3656 /* Length */
3657 if (decl_a->len != decl_b->len) {
3658 goto end;
3659 }
3660
3661 /*
3662 * Compare user byte orders only, not the cached,
3663 * real byte orders.
3664 */
3665 if (integer_a->user_byte_order != integer_b->user_byte_order) {
3666 goto end;
3667 }
3668
3669 /* Signedness */
3670 if (decl_a->signedness != decl_b->signedness) {
3671 goto end;
3672 }
3673
3674 /* Base */
3675 if (decl_a->base != decl_b->base) {
3676 goto end;
3677 }
3678
3679 /* Encoding */
3680 if (decl_a->encoding != decl_b->encoding) {
3681 goto end;
3682 }
3683
3684 /* Mapped clock */
3685 if (integer_a->mapped_clock != integer_b->mapped_clock) {
3686 goto end;
3687 }
3688
3689 /* Equal */
3690 ret = 0;
3691
3692end:
3693 return ret;
3694}
3695
3696static
3697int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
3698 struct bt_ctf_field_type *type_b)
3699{
3700 int ret = 1;
3701 struct bt_ctf_field_type_floating_point *float_a;
3702 struct bt_ctf_field_type_floating_point *float_b;
3703
3704 float_a = container_of(type_a,
3705 struct bt_ctf_field_type_floating_point, parent);
3706 float_b = container_of(type_b,
3707 struct bt_ctf_field_type_floating_point, parent);
3708
3709 /* Sign length */
3710 if (float_a->sign.len != float_b->sign.len) {
3711 goto end;
3712 }
3713
3714 /* Exponent length */
3715 if (float_a->exp.len != float_b->exp.len) {
3716 goto end;
3717 }
3718
3719 /* Mantissa length */
3720 if (float_a->mantissa.len != float_b->mantissa.len) {
3721 goto end;
3722 }
3723
3724 /*
3725 * Compare user byte orders only, not the cached,
3726 * real byte orders.
3727 */
3728 if (float_a->user_byte_order != float_b->user_byte_order) {
3729 goto end;
3730 }
3731
3732 /* Equal */
3733 ret = 0;
3734
3735end:
3736 return ret;
3737}
3738
3739static
3740int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
3741 struct enumeration_mapping *mapping_b)
3742{
3743 int ret = 1;
3744
3745 /* Label */
3746 if (mapping_a->string != mapping_b->string) {
3747 goto end;
3748 }
3749
3750 /* Range start */
3751 if (mapping_a->range_start._unsigned !=
3752 mapping_b->range_start._unsigned) {
3753 goto end;
3754 }
3755
3756 /* Range end */
3757 if (mapping_a->range_end._unsigned !=
3758 mapping_b->range_end._unsigned) {
3759 goto end;
3760 }
3761
3762 /* Equal */
3763 ret = 0;
3764
3765end:
3766 return ret;
3767}
3768
3769static
3770int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
3771 struct bt_ctf_field_type *type_b)
3772{
3773 int ret = 1;
3774 int i;
3775 struct bt_ctf_field_type_enumeration *enum_a;
3776 struct bt_ctf_field_type_enumeration *enum_b;
3777
3778 enum_a = container_of(type_a,
3779 struct bt_ctf_field_type_enumeration, parent);
3780 enum_b = container_of(type_b,
3781 struct bt_ctf_field_type_enumeration, parent);
3782
3783 /* Container field type */
3784 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
3785 if (ret) {
3786 goto end;
3787 }
3788
3789 ret = 1;
3790
3791 /* Entries */
3792 if (enum_a->entries->len != enum_b->entries->len) {
3793 goto end;
3794 }
3795
3796 for (i = 0; i < enum_a->entries->len; ++i) {
3797 struct enumeration_mapping *mapping_a =
3798 g_ptr_array_index(enum_a->entries, i);
3799 struct enumeration_mapping *mapping_b =
3800 g_ptr_array_index(enum_b->entries, i);
3801
3802 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
3803 goto end;
3804 }
3805 }
3806
3807 /* Equal */
3808 ret = 0;
3809
3810end:
3811 return ret;
3812}
3813
3814static
3815int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
3816 struct bt_ctf_field_type *type_b)
3817{
3818 int ret = 1;
3819 struct bt_ctf_field_type_string *string_a;
3820 struct bt_ctf_field_type_string *string_b;
3821
3822 string_a = container_of(type_a,
3823 struct bt_ctf_field_type_string, parent);
3824 string_b = container_of(type_b,
3825 struct bt_ctf_field_type_string, parent);
3826
3827 /* Encoding */
3828 if (string_a->declaration.encoding != string_b->declaration.encoding) {
3829 goto end;
3830 }
3831
3832 /* Equal */
3833 ret = 0;
3834
3835end:
3836 return ret;
3837}
3838
3839static
3840int compare_structure_fields(struct structure_field *field_a,
3841 struct structure_field *field_b)
3842{
3843 int ret = 1;
3844
3845 /* Label */
3846 if (field_a->name != field_b->name) {
3847 goto end;
3848 }
3849
3850 /* Type */
3851 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
3852
3853end:
3854 return ret;
3855}
3856
3857static
3858int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
3859 struct bt_ctf_field_type *type_b)
3860{
3861 int ret = 1;
3862 int i;
3863 struct bt_ctf_field_type_structure *struct_a;
3864 struct bt_ctf_field_type_structure *struct_b;
3865
3866 struct_a = container_of(type_a,
3867 struct bt_ctf_field_type_structure, parent);
3868 struct_b = container_of(type_b,
3869 struct bt_ctf_field_type_structure, parent);
3870
3871 /* Alignment */
3872 if (bt_ctf_field_type_get_alignment(type_a) !=
3873 bt_ctf_field_type_get_alignment(type_b)) {
3874 goto end;
3875 }
3876
3877 /* Fields */
3878 if (struct_a->fields->len != struct_b->fields->len) {
3879 goto end;
3880 }
3881
3882 for (i = 0; i < struct_a->fields->len; ++i) {
3883 struct structure_field *field_a =
3884 g_ptr_array_index(struct_a->fields, i);
3885 struct structure_field *field_b =
3886 g_ptr_array_index(struct_b->fields, i);
3887
3888 ret = compare_structure_fields(field_a, field_b);
3889 if (ret) {
3890 goto end;
3891 }
265e809c
PP
3892 }
3893
3894 /* Equal */
3895 ret = 0;
3896
3897end:
3898 return ret;
3899}
3900
3901static
3902int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
3903 struct bt_ctf_field_type *type_b)
3904{
3905 int ret = 1;
3906 int i;
3907 struct bt_ctf_field_type_variant *variant_a;
3908 struct bt_ctf_field_type_variant *variant_b;
3909
3910 variant_a = container_of(type_a,
3911 struct bt_ctf_field_type_variant, parent);
3912 variant_b = container_of(type_b,
3913 struct bt_ctf_field_type_variant, parent);
3914
3915 /* Tag name */
3916 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
3917 goto end;
3918 }
3919
3920 /* Tag type */
3921 ret = bt_ctf_field_type_compare(
3922 (struct bt_ctf_field_type *) variant_a->tag,
3923 (struct bt_ctf_field_type *) variant_b->tag);
3924 if (ret) {
3925 goto end;
3926 }
3927
3928 ret = 1;
3929
3930 /* Fields */
3931 if (variant_a->fields->len != variant_b->fields->len) {
3932 goto end;
3933 }
3934
3935 for (i = 0; i < variant_a->fields->len; ++i) {
3936 struct structure_field *field_a =
3937 g_ptr_array_index(variant_a->fields, i);
3938 struct structure_field *field_b =
3939 g_ptr_array_index(variant_b->fields, i);
3940
3941 ret = compare_structure_fields(field_a, field_b);
3942 if (ret) {
3943 goto end;
3944 }
265e809c
PP
3945 }
3946
3947 /* Equal */
3948 ret = 0;
3949
3950end:
3951 return ret;
3952}
3953
3954static
3955int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
3956 struct bt_ctf_field_type *type_b)
3957{
3958 int ret = 1;
3959 struct bt_ctf_field_type_array *array_a;
3960 struct bt_ctf_field_type_array *array_b;
3961
3962 array_a = container_of(type_a,
3963 struct bt_ctf_field_type_array, parent);
3964 array_b = container_of(type_b,
3965 struct bt_ctf_field_type_array, parent);
3966
3967 /* Length */
3968 if (array_a->length != array_b->length) {
3969 goto end;
3970 }
3971
3972 /* Element type */
3973 ret = bt_ctf_field_type_compare(array_a->element_type,
3974 array_b->element_type);
3975
3976end:
3977 return ret;
3978}
3979
3980static
3981int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
3982 struct bt_ctf_field_type *type_b)
3983{
3984 int ret = -1;
3985 struct bt_ctf_field_type_sequence *sequence_a;
3986 struct bt_ctf_field_type_sequence *sequence_b;
3987
3988 sequence_a = container_of(type_a,
3989 struct bt_ctf_field_type_sequence, parent);
3990 sequence_b = container_of(type_b,
3991 struct bt_ctf_field_type_sequence, parent);
3992
3993 /* Length name */
3994 if (strcmp(sequence_a->length_field_name->str,
3995 sequence_b->length_field_name->str)) {
3996 goto end;
3997 }
3998
3999 /* Element type */
4000 ret = bt_ctf_field_type_compare(sequence_a->element_type,
4001 sequence_b->element_type);
4002
4003end:
4004 return ret;
4005}
4006
4007int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
4008 struct bt_ctf_field_type *type_b)
4009{
4010 int ret = 1;
4011
4012 if (type_a == type_b) {
4013 /* Same reference: equal (even if both are NULL) */
4014 ret = 0;
4015 goto end;
4016 }
4017
4018 if (!type_a || !type_b) {
4019 ret = -1;
4020 goto end;
4021 }
4022
4023 if (type_a->declaration->id != type_b->declaration->id) {
4024 /* Different type IDs */
4025 goto end;
4026 }
4027
9a19a512 4028 if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
265e809c
PP
4029 /* Both have unknown type IDs */
4030 goto end;
4031 }
4032
4033 ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
4034
4035end:
4036 return ret;
4037}
09840de5
PP
4038
4039BT_HIDDEN
4040int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
4041{
4042 int field_count = -1;
4043 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4044
4045 switch (type_id) {
4046 case CTF_TYPE_STRUCT:
4047 field_count =
4048 bt_ctf_field_type_structure_get_field_count(field_type);
4049 break;
4050 case CTF_TYPE_VARIANT:
4051 field_count =
4052 bt_ctf_field_type_variant_get_field_count(field_type);
4053 break;
4054 case CTF_TYPE_ARRAY:
4055 case CTF_TYPE_SEQUENCE:
4056 /*
4057 * Array and sequence types always contain a single member
4058 * (the element type).
4059 */
4060 field_count = 1;
4061 break;
4062 default:
4063 break;
4064 }
4065
4066 return field_count;
4067}
4068
4069BT_HIDDEN
4070struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
4071 struct bt_ctf_field_type *field_type, int index)
4072{
4073 struct bt_ctf_field_type *field = NULL;
4074 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4075
4076 switch (type_id) {
4077 case CTF_TYPE_STRUCT:
4078 bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
4079 index);
4080 break;
4081 case CTF_TYPE_VARIANT:
8f3a93d9
JG
4082 {
4083 int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
09840de5 4084 &field, index);
8f3a93d9
JG
4085 if (ret) {
4086 field = NULL;
4087 goto end;
4088 }
09840de5 4089 break;
8f3a93d9 4090 }
09840de5
PP
4091 case CTF_TYPE_ARRAY:
4092 field = bt_ctf_field_type_array_get_element_type(field_type);
4093 break;
4094 case CTF_TYPE_SEQUENCE:
4095 field = bt_ctf_field_type_sequence_get_element_type(field_type);
4096 break;
4097 default:
4098 break;
4099 }
8f3a93d9 4100end:
09840de5
PP
4101 return field;
4102}
4103
4104BT_HIDDEN
4105int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
4106 const char *name)
4107{
4108 int field_index = -1;
4109 enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
4110
4111 switch (type_id) {
4112 case CTF_TYPE_STRUCT:
4113 field_index = bt_ctf_field_type_structure_get_field_name_index(
4114 field_type, name);
4115 break;
4116 case CTF_TYPE_VARIANT:
4117 field_index = bt_ctf_field_type_variant_get_field_name_index(
4118 field_type, name);
4119 break;
4120 default:
4121 break;
4122 }
4123
4124 return field_index;
4125}
b011f6b0
PP
4126
4127struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
4128 struct bt_ctf_field_type *type)
4129{
4130 struct bt_ctf_field_path *field_path = NULL;
4131 struct bt_ctf_field_type_variant *variant;
4132
4133 if (!type || !bt_ctf_field_type_is_variant(type)) {
4134 goto end;
4135 }
4136
4137 variant = container_of(type, struct bt_ctf_field_type_variant,
4138 parent);
4139 field_path = bt_get(variant->tag_field_path);
4140end:
4141 return field_path;
4142}
4143
4144struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
4145 struct bt_ctf_field_type *type)
4146{
4147 struct bt_ctf_field_path *field_path = NULL;
4148 struct bt_ctf_field_type_sequence *sequence;
4149
4150 if (!type || !bt_ctf_field_type_is_sequence(type)) {
4151 goto end;
4152 }
4153
4154 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4155 parent);
4156 field_path = bt_get(sequence->length_field_path);
4157end:
4158 return field_path;
4159}
This page took 0.275318 seconds and 4 git commands to generate.