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