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