lib/ctf-ir/field-types.c: logging: log more details when freezing
[babeltrace.git] / lib / ctf-ir / field-types.c
CommitLineData
273b65be 1/*
2e33ac5a 2 * field-types.c
273b65be 3 *
d2dc44b6 4 * Babeltrace CTF IR - Event Types
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
4e8304f7
PP
29#define BT_LOG_TAG "FIELD-TYPES"
30#include <babeltrace/lib-logging-internal.h>
31
2e33ac5a 32#include <babeltrace/ctf-ir/field-types-internal.h>
b011f6b0 33#include <babeltrace/ctf-ir/field-path-internal.h>
654c1444 34#include <babeltrace/ctf-ir/utils.h>
83509119 35#include <babeltrace/ref.h>
ac0c6bdd
PP
36#include <babeltrace/ctf-ir/clock-class.h>
37#include <babeltrace/ctf-ir/clock-class-internal.h>
273b65be 38#include <babeltrace/ctf-writer/writer-internal.h>
83509119
JG
39#include <babeltrace/object-internal.h>
40#include <babeltrace/ref.h>
3d9990ac
PP
41#include <babeltrace/compiler-internal.h>
42#include <babeltrace/endian-internal.h>
273b65be
JG
43#include <float.h>
44#include <inttypes.h>
a39fa057 45#include <stdlib.h>
273b65be
JG
46
47struct range_overlap_query {
b92ddaaa
JG
48 union {
49 uint64_t _unsigned;
50 int64_t _signed;
51 } range_start;
52
53 union {
54 uint64_t _unsigned;
55 int64_t _signed;
56 } range_end;
273b65be
JG
57 int overlaps;
58 GQuark mapping_name;
59};
60
2f2d8e05 61static
83509119 62void bt_ctf_field_type_destroy(struct bt_object *);
273b65be 63static
de3dd40e 64void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
273b65be 65static
de3dd40e 66void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
273b65be 67static
de3dd40e 68void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
273b65be 69static
de3dd40e 70void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
273b65be 71static
de3dd40e 72void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
273b65be 73static
de3dd40e 74void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
273b65be 75static
de3dd40e 76void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
273b65be 77static
de3dd40e 78void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
273b65be
JG
79
80static
de3dd40e 81void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
1487a16a
PP
82 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_destroy,
83 [BT_CTF_FIELD_TYPE_ID_ENUM] =
273b65be 84 bt_ctf_field_type_enumeration_destroy,
1487a16a 85 [BT_CTF_FIELD_TYPE_ID_FLOAT] =
273b65be 86 bt_ctf_field_type_floating_point_destroy,
1487a16a
PP
87 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_destroy,
88 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_destroy,
89 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_destroy,
90 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
91 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_type_string_destroy,
273b65be
JG
92};
93
94static
95void generic_field_type_freeze(struct bt_ctf_field_type *);
96static
586411e5
PP
97void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
98static
273b65be
JG
99void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
100static
101void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
102static
103void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
104static
105void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
106static
107void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
108
109static
110type_freeze_func const type_freeze_funcs[] = {
1487a16a
PP
111 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_freeze,
112 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_freeze,
113 [BT_CTF_FIELD_TYPE_ID_FLOAT] = generic_field_type_freeze,
114 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_freeze,
115 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_freeze,
116 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_freeze,
117 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
118 [BT_CTF_FIELD_TYPE_ID_STRING] = generic_field_type_freeze,
273b65be
JG
119};
120
121static
122int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
123 struct metadata_context *);
124static
125int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
126 struct metadata_context *);
127static
128int bt_ctf_field_type_floating_point_serialize(
129 struct bt_ctf_field_type *, struct metadata_context *);
130static
131int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
132 struct metadata_context *);
133static
134int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
135 struct metadata_context *);
136static
137int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
138 struct metadata_context *);
139static
140int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
141 struct metadata_context *);
142static
143int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
144 struct metadata_context *);
145
146static
147type_serialize_func const type_serialize_funcs[] = {
1487a16a
PP
148 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_serialize,
149 [BT_CTF_FIELD_TYPE_ID_ENUM] =
273b65be 150 bt_ctf_field_type_enumeration_serialize,
1487a16a 151 [BT_CTF_FIELD_TYPE_ID_FLOAT] =
273b65be 152 bt_ctf_field_type_floating_point_serialize,
1487a16a 153 [BT_CTF_FIELD_TYPE_ID_STRUCT] =
273b65be 154 bt_ctf_field_type_structure_serialize,
1487a16a
PP
155 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_serialize,
156 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_serialize,
157 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
158 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_type_string_serialize,
273b65be
JG
159};
160
161static
162void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
dc3fffef 163 enum bt_ctf_byte_order byte_order);
c35a1669
JG
164static
165void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
dc3fffef 166 enum bt_ctf_byte_order byte_order);
273b65be
JG
167static
168void bt_ctf_field_type_floating_point_set_byte_order(
dc3fffef 169 struct bt_ctf_field_type *, enum bt_ctf_byte_order byte_order);
c35a1669
JG
170static
171void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
dc3fffef 172 enum bt_ctf_byte_order byte_order);
c35a1669
JG
173static
174void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
dc3fffef 175 enum bt_ctf_byte_order byte_order);
c35a1669
JG
176static
177void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
dc3fffef 178 enum bt_ctf_byte_order byte_order);
c35a1669
JG
179static
180void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
dc3fffef 181 enum bt_ctf_byte_order byte_order);
273b65be
JG
182
183static
184void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
dc3fffef 185 enum bt_ctf_byte_order) = {
1487a16a
PP
186 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
187 [BT_CTF_FIELD_TYPE_ID_ENUM] =
c35a1669 188 bt_ctf_field_type_enumeration_set_byte_order,
1487a16a 189 [BT_CTF_FIELD_TYPE_ID_FLOAT] =
273b65be 190 bt_ctf_field_type_floating_point_set_byte_order,
1487a16a 191 [BT_CTF_FIELD_TYPE_ID_STRUCT] =
c35a1669 192 bt_ctf_field_type_structure_set_byte_order,
1487a16a
PP
193 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
194 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_set_byte_order,
195 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
196 [BT_CTF_FIELD_TYPE_ID_STRING] = NULL,
273b65be
JG
197};
198
24724933
JG
199static
200struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
201 struct bt_ctf_field_type *);
202static
203struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
204 struct bt_ctf_field_type *);
205static
206struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
207 struct bt_ctf_field_type *);
208static
209struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
210 struct bt_ctf_field_type *);
211static
212struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
213 struct bt_ctf_field_type *);
214static
215struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
216 struct bt_ctf_field_type *);
217static
218struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
219 struct bt_ctf_field_type *);
220static
221struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
222 struct bt_ctf_field_type *);
223
224static
225struct bt_ctf_field_type *(* const type_copy_funcs[])(
226 struct bt_ctf_field_type *) = {
1487a16a
PP
227 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_copy,
228 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_copy,
229 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_copy,
230 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_copy,
231 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_copy,
232 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_copy,
233 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_copy,
234 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_type_string_copy,
24724933
JG
235};
236
265e809c
PP
237static
238int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
239 struct bt_ctf_field_type *);
240static
241int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
242 struct bt_ctf_field_type *);
243static
244int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
245 struct bt_ctf_field_type *);
246static
247int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
248 struct bt_ctf_field_type *);
249static
250int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
251 struct bt_ctf_field_type *);
252static
253int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
254 struct bt_ctf_field_type *);
255static
256int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
257 struct bt_ctf_field_type *);
258static
259int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
260 struct bt_ctf_field_type *);
261
262static
263int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
264 struct bt_ctf_field_type *) = {
1487a16a
PP
265 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_compare,
266 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_compare,
267 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_compare,
268 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_compare,
269 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_compare,
270 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_compare,
271 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_compare,
272 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_type_string_compare,
265e809c
PP
273};
274
b3dbeb52
PP
275static
276int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *);
81e36fac
PP
277static
278int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
279static
280int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
281static
282int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
283static
284int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
285static
286int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
287
288static
289int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
1487a16a
PP
290 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_validate,
291 [BT_CTF_FIELD_TYPE_ID_FLOAT] = NULL,
292 [BT_CTF_FIELD_TYPE_ID_STRING] = NULL,
293 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_validate,
294 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_validate,
295 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_validate,
296 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_type_array_validate,
297 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_validate,
81e36fac
PP
298};
299
273b65be
JG
300static
301void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
302{
303 g_free(mapping);
304}
305
306static
307void destroy_structure_field(struct structure_field *field)
308{
83509119 309 bt_put(field->type);
273b65be
JG
310 g_free(field);
311}
312
313static
314void check_ranges_overlap(gpointer element, gpointer query)
315{
316 struct enumeration_mapping *mapping = element;
317 struct range_overlap_query *overlap_query = query;
318
b92ddaaa 319 if (mapping->range_start._signed <= overlap_query->range_end._signed
4e8304f7
PP
320 && overlap_query->range_start._signed <=
321 mapping->range_end._signed) {
b92ddaaa
JG
322 overlap_query->overlaps = 1;
323 overlap_query->mapping_name = mapping->string;
324 }
325
326 overlap_query->overlaps |=
327 mapping->string == overlap_query->mapping_name;
4e8304f7
PP
328
329 if (overlap_query->overlaps) {
330 BT_LOGV("Overlapping enumeration field type mappings: "
331 "mapping-name=\"%s\", "
332 "mapping-a-range-start=%" PRId64 ", "
333 "mapping-a-range-end=%" PRId64 ", "
334 "mapping-b-range-start=%" PRId64 ", "
335 "mapping-b-range-end=%" PRId64,
336 g_quark_to_string(mapping->string),
337 mapping->range_start._signed,
338 mapping->range_end._signed,
339 overlap_query->range_start._signed,
340 overlap_query->range_end._signed);
341 }
b92ddaaa
JG
342}
343
344static
345void check_ranges_overlap_unsigned(gpointer element, gpointer query)
346{
347 struct enumeration_mapping *mapping = element;
348 struct range_overlap_query *overlap_query = query;
349
350 if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
4e8304f7
PP
351 && overlap_query->range_start._unsigned <=
352 mapping->range_end._unsigned) {
273b65be
JG
353 overlap_query->overlaps = 1;
354 overlap_query->mapping_name = mapping->string;
355 }
356
357 overlap_query->overlaps |=
358 mapping->string == overlap_query->mapping_name;
4e8304f7
PP
359
360 if (overlap_query->overlaps) {
361 BT_LOGW("Overlapping enumeration field type mappings: "
362 "mapping-name=\"%s\", "
363 "mapping-a-range-start=%" PRIu64 ", "
364 "mapping-a-range-end=%" PRIu64 ", "
365 "mapping-b-range-start=%" PRIu64 ", "
366 "mapping-b-range-end=%" PRIu64,
367 g_quark_to_string(mapping->string),
368 mapping->range_start._unsigned,
369 mapping->range_end._unsigned,
370 overlap_query->range_start._unsigned,
371 overlap_query->range_end._unsigned);
372 }
273b65be
JG
373}
374
b92ddaaa
JG
375static
376gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
377 struct enumeration_mapping **b)
378{
379 return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
380}
381
382static
383gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
384 struct enumeration_mapping **b)
385{
386 return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
387}
388
273b65be 389static
c55a9f58 390void bt_ctf_field_type_init(struct bt_ctf_field_type *type, bt_bool init_bo)
273b65be 391{
1487a16a 392 assert(type && (type->id > BT_CTF_FIELD_TYPE_ID_UNKNOWN) &&
dc3fffef 393 (type->id < BT_CTF_NR_TYPE_IDS));
273b65be 394
83509119 395 bt_object_init(type, bt_ctf_field_type_destroy);
dc3fffef
PP
396 type->freeze = type_freeze_funcs[type->id];
397 type->serialize = type_serialize_funcs[type->id];
59acd4f5
PP
398
399 if (init_bo) {
400 int ret = bt_ctf_field_type_set_byte_order(type,
401 BT_CTF_BYTE_ORDER_NATIVE);
dc3fffef 402 assert(ret == 0);
59acd4f5
PP
403 }
404
dc3fffef 405 type->alignment = 1;
273b65be
JG
406}
407
408static
409int add_structure_field(GPtrArray *fields,
410 GHashTable *field_name_to_index,
411 struct bt_ctf_field_type *field_type,
412 const char *field_name)
413{
414 int ret = 0;
415 GQuark name_quark = g_quark_from_string(field_name);
416 struct structure_field *field;
417
418 /* Make sure structure does not contain a field of the same name */
fe0fe95c 419 if (g_hash_table_lookup_extended(field_name_to_index,
4e8304f7
PP
420 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
421 BT_LOGW("Structure or variant field type already contains a field type with this name: "
422 "field-name=\"%s\"", field_name);
273b65be
JG
423 ret = -1;
424 goto end;
425 }
426
427 field = g_new0(struct structure_field, 1);
428 if (!field) {
4e8304f7 429 BT_LOGE_STR("Failed to allocate one structure/variant field type field.");
273b65be
JG
430 ret = -1;
431 goto end;
432 }
433
83509119 434 bt_get(field_type);
273b65be
JG
435 field->name = name_quark;
436 field->type = field_type;
437 g_hash_table_insert(field_name_to_index,
5b44aff2
MJ
438 GUINT_TO_POINTER(name_quark),
439 GUINT_TO_POINTER(fields->len));
273b65be 440 g_ptr_array_add(fields, field);
dfc1504d
PP
441 BT_LOGV("Added structure/variant field type field: field-ft-addr=%p, "
442 "field-name=\"%s\"", field_type, field_name);
273b65be
JG
443end:
444 return ret;
445}
446
2f2d8e05 447static
83509119 448void bt_ctf_field_type_destroy(struct bt_object *obj)
2f2d8e05
JG
449{
450 struct bt_ctf_field_type *type;
1487a16a 451 enum bt_ctf_field_type_id type_id;
2f2d8e05 452
4e8304f7 453 BT_LOGD("Destroying field type object: addr=%p", obj);
83509119 454 type = container_of(obj, struct bt_ctf_field_type, base);
dc3fffef 455 type_id = type->id;
1487a16a 456 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN ||
4e8304f7
PP
457 type_id >= BT_CTF_NR_TYPE_IDS) {
458 BT_LOGW("Unknown field type ID: addr=%p, id=%d", obj, type_id);
2f2d8e05
JG
459 return;
460 }
461
de3dd40e 462 type_destroy_funcs[type_id](type);
2f2d8e05
JG
463}
464
b3dbeb52
PP
465static
466int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type)
467{
468 int ret = 0;
469
470 struct bt_ctf_field_type_integer *integer =
471 container_of(type, struct bt_ctf_field_type_integer,
472 parent);
473
dc3fffef 474 if (integer->mapped_clock && integer->is_signed) {
4e8304f7
PP
475 BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
476 "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
477 type, integer->mapped_clock,
478 bt_ctf_clock_class_get_name(integer->mapped_clock));
b3dbeb52
PP
479 ret = -1;
480 goto end;
481 }
482
483end:
484 return ret;
485}
486
d49e1284
JG
487static
488struct enumeration_mapping *get_enumeration_mapping(
4e8304f7 489 struct bt_ctf_field_type *type, uint64_t index)
d49e1284
JG
490{
491 struct enumeration_mapping *mapping = NULL;
492 struct bt_ctf_field_type_enumeration *enumeration;
493
494 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
495 parent);
496 if (index >= enumeration->entries->len) {
4e8304f7
PP
497 BT_LOGW("Invalid parameter: index is out of bounds: "
498 "addr=%p, index=%" PRIu64 ", count=%u",
499 type, index, enumeration->entries->len);
d49e1284
JG
500 goto end;
501 }
502
503 mapping = g_ptr_array_index(enumeration->entries, index);
504end:
505 return mapping;
506}
507
508/*
509 * Note: This algorithm is O(n^2) vs number of enumeration mappings.
510 * Only used when freezing an enumeration.
511 */
512static
513void set_enumeration_range_overlap(
514 struct bt_ctf_field_type *type)
515{
4e8304f7 516 int64_t i, j, len;
d49e1284
JG
517 struct bt_ctf_field_type *container_type;
518 struct bt_ctf_field_type_enumeration *enumeration_type;
519 int is_signed;
520
4e8304f7
PP
521 BT_LOGV("Setting enumeration field type's overlap flag: addr=%p",
522 type);
d49e1284
JG
523 enumeration_type = container_of(type,
524 struct bt_ctf_field_type_enumeration, parent);
525
526 len = enumeration_type->entries->len;
527 container_type = enumeration_type->container;
528 is_signed = bt_ctf_field_type_integer_get_signed(container_type);
529
530 for (i = 0; i < len; i++) {
531 for (j = i + 1; j < len; j++) {
532 struct enumeration_mapping *mapping[2];
533
534 mapping[0] = get_enumeration_mapping(type, i);
535 mapping[1] = get_enumeration_mapping(type, j);
536 if (is_signed) {
537 if (mapping[0]->range_start._signed
538 <= mapping[1]->range_end._signed
539 && mapping[0]->range_end._signed
540 >= mapping[1]->range_start._signed) {
c55a9f58 541 enumeration_type->has_overlapping_ranges = BT_TRUE;
dfc1504d 542 goto end;
d49e1284
JG
543 }
544 } else {
545 if (mapping[0]->range_start._unsigned
546 <= mapping[1]->range_end._unsigned
547 && mapping[0]->range_end._unsigned
548 >= mapping[1]->range_start._unsigned) {
c55a9f58 549 enumeration_type->has_overlapping_ranges = BT_TRUE;
dfc1504d 550 goto end;
d49e1284
JG
551 }
552 }
553 }
554 }
dfc1504d
PP
555
556end:
557 if (enumeration_type->has_overlapping_ranges) {
558 BT_LOGV_STR("Enumeration field type has overlapping ranges.");
559 } else {
560 BT_LOGV_STR("Enumeration field type has no overlapping ranges.");
561 }
d49e1284
JG
562}
563
81e36fac
PP
564static
565int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
9ce21c30
JG
566{
567 int ret = 0;
568
81e36fac
PP
569 struct bt_ctf_field_type_enumeration *enumeration =
570 container_of(type, struct bt_ctf_field_type_enumeration,
571 parent);
572 struct bt_ctf_field_type *container_type =
573 bt_ctf_field_type_enumeration_get_container_type(type);
574
4e8304f7 575 assert(container_type);
81e36fac
PP
576 ret = bt_ctf_field_type_validate(container_type);
577 if (ret) {
4e8304f7
PP
578 BT_LOGW("Invalid enumeration field type: container type is invalid: "
579 "enum-ft-addr=%p, int-ft-addr=%p",
580 type, container_type);
81e36fac
PP
581 goto end;
582 }
9ce21c30 583
81e36fac 584 /* Ensure enum has entries */
4e8304f7
PP
585 if (enumeration->entries->len == 0) {
586 BT_LOGW("Invalid enumeration field type: no entries: "
587 "addr=%p", type);
588 ret = -1;
589 goto end;
590 }
81e36fac
PP
591
592end:
593 BT_PUT(container_type);
594 return ret;
595}
596
597static
598int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type)
599{
600 int ret = 0;
601 struct bt_ctf_field_type *element_type = NULL;
602 struct bt_ctf_field_type_sequence *sequence =
603 container_of(type, struct bt_ctf_field_type_sequence,
604 parent);
605
606 /* Length field name should be set at this point */
607 if (sequence->length_field_name->len == 0) {
4e8304f7
PP
608 BT_LOGW("Invalid sequence field type: no length field name: "
609 "addr=%p", type);
81e36fac
PP
610 ret = -1;
611 goto end;
5d161ecc 612 }
81e36fac
PP
613
614 element_type = bt_ctf_field_type_sequence_get_element_type(type);
4e8304f7 615 assert(element_type);
81e36fac 616 ret = bt_ctf_field_type_validate(element_type);
4e8304f7
PP
617 if (ret) {
618 BT_LOGW("Invalid sequence field type: invalid element field type: "
619 "seq-ft-addr=%p, element-ft-add=%p",
620 type, element_type);
621 }
81e36fac
PP
622
623end:
624 BT_PUT(element_type);
625
626 return ret;
627}
628
629static
630int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type)
631{
632 int ret = 0;
633 struct bt_ctf_field_type *element_type = NULL;
634
635 element_type = bt_ctf_field_type_array_get_element_type(type);
4e8304f7 636 assert(element_type);
81e36fac 637 ret = bt_ctf_field_type_validate(element_type);
4e8304f7
PP
638 if (ret) {
639 BT_LOGW("Invalid array field type: invalid element field type: "
640 "array-ft-addr=%p, element-ft-add=%p",
641 type, element_type);
642 }
81e36fac 643
81e36fac 644 BT_PUT(element_type);
81e36fac
PP
645 return ret;
646}
647
648static
649int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type)
650{
651 int ret = 0;
652 struct bt_ctf_field_type *child_type = NULL;
544d0515
PP
653 int64_t field_count = bt_ctf_field_type_structure_get_field_count(type);
654 int64_t i;
81e36fac 655
4e8304f7 656 assert(field_count >= 0);
81e36fac
PP
657
658 for (i = 0; i < field_count; ++i) {
4e8304f7 659 const char *field_name;
81e36fac 660
4e8304f7
PP
661 ret = bt_ctf_field_type_structure_get_field_by_index(type,
662 &field_name, &child_type, i);
663 assert(ret == 0);
81e36fac
PP
664 ret = bt_ctf_field_type_validate(child_type);
665 if (ret) {
4e8304f7
PP
666 BT_LOGW("Invalid structure field type: "
667 "a contained field type is invalid: "
668 "struct-ft-addr=%p, field-ft-addr=%p, "
669 "field-name=\"%s\", field-index=%" PRId64,
670 type, child_type, field_name, i);
81e36fac
PP
671 goto end;
672 }
673
674 BT_PUT(child_type);
675 }
676
677end:
678 BT_PUT(child_type);
679
680 return ret;
681}
682
96e8f959 683static
c55a9f58 684bt_bool bt_ctf_field_type_enumeration_has_overlapping_ranges(
96e8f959
MD
685 struct bt_ctf_field_type_enumeration *enumeration_type)
686{
d49e1284
JG
687 if (!enumeration_type->parent.frozen) {
688 set_enumeration_range_overlap(&enumeration_type->parent);
689 }
96e8f959
MD
690 return enumeration_type->has_overlapping_ranges;
691}
692
96436111
JG
693static
694int bt_ctf_field_type_enumeration_get_mapping_name(
695 struct bt_ctf_field_type *enum_field_type,
4e8304f7 696 uint64_t index,
96436111
JG
697 const char **mapping_name)
698{
699 int ret = 0;
700 struct enumeration_mapping *mapping;
701
4e8304f7 702 assert(enum_field_type);
96436111 703 mapping = get_enumeration_mapping(enum_field_type, index);
4e8304f7 704 assert(mapping);
96436111
JG
705 if (mapping_name) {
706 *mapping_name = g_quark_to_string(mapping->string);
707 }
4e8304f7 708
96436111
JG
709 return ret;
710}
711
81e36fac
PP
712static
713int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type)
714{
715 int ret = 0;
544d0515 716 int64_t field_count;
81e36fac
PP
717 struct bt_ctf_field_type *child_type = NULL;
718 struct bt_ctf_field_type_variant *variant =
719 container_of(type, struct bt_ctf_field_type_variant,
c6c0ca42 720 parent);
544d0515
PP
721 int64_t i;
722 int64_t tag_mappings_count;
c6c0ca42 723
4e8304f7
PP
724 if (variant->tag_name->len == 0) {
725 BT_LOGW("Invalid variant field type: no tag field name: "
726 "addr=%p", type);
727 ret = -1;
728 goto end;
729 }
730
731 if (!variant->tag) {
732 BT_LOGW("Invalid variant field type: no tag field type: "
733 "addr=%p, tag-field-name=\"%s\"", type,
734 variant->tag_name->str);
81e36fac
PP
735 ret = -1;
736 goto end;
737 }
738
96e8f959
MD
739 if (bt_ctf_field_type_enumeration_has_overlapping_ranges(
740 variant->tag)) {
4e8304f7
PP
741 BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
742 "variant-ft-addr=%p, tag-field-name=\"%s\", "
743 "enum-ft-addr=%p", type, variant->tag_name->str,
744 variant->tag);
96e8f959
MD
745 ret = -1;
746 goto end;
747 }
748
81e36fac
PP
749 tag_mappings_count =
750 bt_ctf_field_type_enumeration_get_mapping_count(
751 (struct bt_ctf_field_type *) variant->tag);
752
e9eb537e
PP
753 /*
754 * Validate that each mapping found in the tag has a name which
755 * is also the name of a field in this variant field type.
756 *
757 * The opposite is accepted: variant FT fields which cannot be
758 * selected because the variant FT tag has no mapping named as
759 * such. This scenario, while not ideal, cannot cause any error.
760 */
81e36fac
PP
761 for (i = 0; i < tag_mappings_count; ++i) {
762 const char *label;
81e36fac
PP
763 struct bt_ctf_field_type *ft;
764
96e8f959 765 ret = bt_ctf_field_type_enumeration_get_mapping_name(
81e36fac 766 (struct bt_ctf_field_type *) variant->tag,
96e8f959 767 i, &label);
4e8304f7
PP
768 assert(ret == 0);
769 assert(label);
81e36fac
PP
770 ft = bt_ctf_field_type_variant_get_field_type_by_name(
771 type, label);
772 if (!ft) {
4e8304f7
PP
773 BT_LOGW("Invalid variant field type: "
774 "enumeration tag field type contains a mapping which does not name a variant field type field: "
775 "variant-ft-addr=%p, tag-field-name=\"%s\", "
776 "enum-ft-addr=%p, mapping-name=\"%s\"",
777 type, variant->tag_name->str, variant->tag,
778 label);
81e36fac
PP
779 ret = -1;
780 goto end;
781 }
782
783 BT_PUT(ft);
c6c0ca42 784 }
81e36fac
PP
785
786 field_count = bt_ctf_field_type_variant_get_field_count(type);
787 if (field_count < 0) {
4e8304f7
PP
788 BT_LOGW("Invalid variant field type: no fields: "
789 "addr=%p, tag-field-name=\"%s\"",
790 type, variant->tag_name->str);
81e36fac
PP
791 ret = -1;
792 goto end;
793 }
794
795 for (i = 0; i < field_count; ++i) {
4e8304f7 796 const char *field_name;
81e36fac 797
4e8304f7
PP
798 ret = bt_ctf_field_type_variant_get_field_by_index(type,
799 &field_name, &child_type, i);
800 assert(ret == 0);
81e36fac
PP
801 ret = bt_ctf_field_type_validate(child_type);
802 if (ret) {
4e8304f7
PP
803 BT_LOGW("Invalid variant field type: "
804 "a contained field type is invalid: "
805 "variant-ft-addr=%p, tag-field-name=\"%s\", "
806 "field-ft-addr=%p, field-name=\"%s\", "
807 "field-index=%" PRId64,
808 type, variant->tag_name->str, child_type,
809 field_name, i);
81e36fac
PP
810 goto end;
811 }
812
813 BT_PUT(child_type);
814 }
815
816end:
817 BT_PUT(child_type);
818
819 return ret;
820}
821
822/*
823 * This function validates a given field type without considering
824 * where this field type is located. It only validates the properties
825 * of the given field type and the properties of its children if
826 * applicable.
827 */
828BT_HIDDEN
829int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
830{
831 int ret = 0;
1487a16a 832 enum bt_ctf_field_type_id id = bt_ctf_field_type_get_type_id(type);
81e36fac 833
4e8304f7 834 assert(type);
81e36fac
PP
835
836 if (type->valid) {
837 /* Already marked as valid */
838 goto end;
839 }
840
841 if (type_validate_funcs[id]) {
842 ret = type_validate_funcs[id](type);
843 }
844
845 if (!ret && type->frozen) {
846 /* Field type is valid */
847 type->valid = 1;
848 }
849
9ce21c30
JG
850end:
851 return ret;
852}
853
273b65be
JG
854struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
855{
856 struct bt_ctf_field_type_integer *integer =
857 g_new0(struct bt_ctf_field_type_integer, 1);
858
4e8304f7
PP
859 BT_LOGD("Creating integer field type object: size=%u", size);
860
861 if (!integer) {
862 BT_LOGE_STR("Failed to allocate one integer field type.");
863 return NULL;
864 }
865
866 if (size == 0 || size > 64) {
867 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
868 "size=%u", size);
273b65be
JG
869 return NULL;
870 }
871
1487a16a 872 integer->parent.id = BT_CTF_FIELD_TYPE_ID_INTEGER;
dc3fffef
PP
873 integer->size = size;
874 integer->base = BT_CTF_INTEGER_BASE_DECIMAL;
875 integer->encoding = BT_CTF_STRING_ENCODING_NONE;
59acd4f5 876 bt_ctf_field_type_init(&integer->parent, TRUE);
4e8304f7
PP
877 BT_LOGD("Created integer field type object: addr=%p, size=%u",
878 &integer->parent, size);
273b65be
JG
879 return &integer->parent;
880}
881
b92ddaaa
JG
882int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
883{
884 int ret = 0;
885 struct bt_ctf_field_type_integer *integer;
886
4e8304f7
PP
887 if (!type) {
888 BT_LOGW_STR("Invalid parameter: field type is NULL.");
889 ret = -1;
890 goto end;
891 }
892
893 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
894 BT_LOGW("Invalid parameter: field type is not an integer field type: "
895 "addr=%p, ft-id=%s", type,
896 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
897 ret = -1;
898 goto end;
899 }
900
901 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 902 ret = (int) integer->size;
b92ddaaa
JG
903end:
904 return ret;
905}
906
907int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
908{
909 int ret = 0;
910 struct bt_ctf_field_type_integer *integer;
911
4e8304f7
PP
912 if (!type) {
913 BT_LOGW_STR("Invalid parameter: field type is NULL.");
914 ret = -1;
915 goto end;
916 }
917
918 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
919 BT_LOGW("Invalid parameter: field type is not an integer field type: "
920 "addr=%p, ft-id=%s", type,
921 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
922 ret = -1;
923 goto end;
924 }
925
926 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 927 ret = integer->is_signed;
b92ddaaa
JG
928end:
929 return ret;
930}
931
c14d64fa
PP
932bt_bool bt_ctf_field_type_integer_is_signed(
933 struct bt_ctf_field_type *int_field_type)
934{
935 return bt_ctf_field_type_integer_get_signed(int_field_type) ?
936 BT_TRUE : BT_FALSE;
937}
938
273b65be 939int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
c14d64fa 940 bt_bool is_signed)
273b65be
JG
941{
942 int ret = 0;
943 struct bt_ctf_field_type_integer *integer;
944
4e8304f7
PP
945 if (!type) {
946 BT_LOGW_STR("Invalid parameter: field type is NULL.");
947 ret = -1;
948 goto end;
949 }
950
951 if (type->frozen) {
952 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
953 type);
954 ret = -1;
955 goto end;
956 }
957
958 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
959 BT_LOGW("Invalid parameter: field type is not an integer field type: "
960 "addr=%p, ft-id=%s", type,
961 bt_ctf_field_type_id_string(type->id));
273b65be
JG
962 ret = -1;
963 goto end;
964 }
965
966 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 967 integer->is_signed = !!is_signed;
dfc1504d
PP
968 BT_LOGV("Set integer field type's signedness: addr=%p, is-signed=%d",
969 type, is_signed);
273b65be
JG
970end:
971 return ret;
972}
973
c3c35de4
JD
974int bt_ctf_field_type_integer_set_size(struct bt_ctf_field_type *type,
975 size_t size)
976{
977 int ret = 0;
978 struct bt_ctf_field_type_integer *integer;
979
4e8304f7
PP
980 if (!type) {
981 BT_LOGW_STR("Invalid parameter: field type is NULL.");
982 ret = -1;
983 goto end;
984 }
985
986 if (type->frozen) {
987 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
988 type);
989 ret = -1;
990 goto end;
991 }
992
993 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
994 BT_LOGW("Invalid parameter: field type is not an integer field type: "
995 "addr=%p, ft-id=%s", type,
996 bt_ctf_field_type_id_string(type->id));
997 ret = -1;
998 goto end;
999 }
1000
1001 if (size == 0 || size > 64) {
1002 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
1003 "addr=%p, size=%u", type, size);
c3c35de4
JD
1004 ret = -1;
1005 goto end;
1006 }
1007
1008 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
1009 integer->size = size;
dfc1504d
PP
1010 BT_LOGV("Set integer field type's size: addr=%p, size=%u",
1011 type, size);
c3c35de4
JD
1012end:
1013 return ret;
1014}
1015
b92ddaaa
JG
1016enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
1017 struct bt_ctf_field_type *type)
1018{
1019 enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
1020 struct bt_ctf_field_type_integer *integer;
1021
4e8304f7
PP
1022 if (!type) {
1023 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1024 goto end;
1025 }
1026
1027 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1028 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1029 "addr=%p, ft-id=%s", type,
1030 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
1031 goto end;
1032 }
1033
1034 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 1035 ret = integer->base;
b92ddaaa
JG
1036end:
1037 return ret;
1038}
1039
273b65be
JG
1040int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
1041 enum bt_ctf_integer_base base)
1042{
1043 int ret = 0;
1044
4e8304f7
PP
1045 if (!type) {
1046 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1047 ret = -1;
1048 goto end;
1049 }
1050
1051 if (type->frozen) {
1052 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1053 type);
1054 ret = -1;
1055 goto end;
1056 }
1057
1058 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1059 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1060 "addr=%p, ft-id=%s", type,
1061 bt_ctf_field_type_id_string(type->id));
273b65be
JG
1062 ret = -1;
1063 goto end;
1064 }
1065
1066 switch (base) {
1067 case BT_CTF_INTEGER_BASE_BINARY:
1068 case BT_CTF_INTEGER_BASE_OCTAL:
1069 case BT_CTF_INTEGER_BASE_DECIMAL:
1070 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
1071 {
1072 struct bt_ctf_field_type_integer *integer = container_of(type,
1073 struct bt_ctf_field_type_integer, parent);
dc3fffef 1074 integer->base = base;
273b65be
JG
1075 break;
1076 }
1077 default:
4e8304f7
PP
1078 BT_LOGW("Invalid parameter: unknown integer field type base: "
1079 "addr=%p, base=%d", type, base);
273b65be
JG
1080 ret = -1;
1081 }
dfc1504d
PP
1082
1083 BT_LOGV("Set integer field type's base: addr=%p, base=%s",
1084 type, bt_ctf_integer_base_string(base));
1085
273b65be
JG
1086end:
1087 return ret;
1088}
1089
87b41f95 1090enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
b92ddaaa
JG
1091 struct bt_ctf_field_type *type)
1092{
87b41f95 1093 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
b92ddaaa
JG
1094 struct bt_ctf_field_type_integer *integer;
1095
4e8304f7
PP
1096 if (!type) {
1097 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1098 goto end;
1099 }
1100
1101 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1102 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1103 "addr=%p, ft-id=%s", type,
1104 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
1105 goto end;
1106 }
1107
1108 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 1109 ret = integer->encoding;
b92ddaaa
JG
1110end:
1111 return ret;
1112}
1113
273b65be 1114int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
87b41f95 1115 enum bt_ctf_string_encoding encoding)
273b65be
JG
1116{
1117 int ret = 0;
1118 struct bt_ctf_field_type_integer *integer;
1119
4e8304f7
PP
1120 if (!type) {
1121 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1122 ret = -1;
1123 goto end;
1124 }
1125
1126 if (type->frozen) {
1127 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1128 type);
1129 ret = -1;
1130 goto end;
1131 }
1132
1133 if (type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
1134 BT_LOGW("Invalid parameter: field type is not an integer field type: "
1135 "addr=%p, ft-id=%s", type,
1136 bt_ctf_field_type_id_string(type->id));
1137 ret = -1;
1138 goto end;
1139 }
1140
1141 if (encoding < BT_CTF_STRING_ENCODING_NONE ||
1142 encoding >= BT_CTF_STRING_ENCODING_UNKNOWN) {
1143 BT_LOGW("Invalid parameter: unknown string encoding: "
1144 "addr=%p, encoding=%d", type, encoding);
273b65be
JG
1145 ret = -1;
1146 goto end;
1147 }
1148
1149 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 1150 integer->encoding = encoding;
dfc1504d
PP
1151 BT_LOGV("Set integer field type's encoding: addr=%p, encoding=%s",
1152 type, bt_ctf_string_encoding_string(encoding));
273b65be
JG
1153end:
1154 return ret;
1155}
1156
ac0c6bdd 1157struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
6cfb906f
JG
1158 struct bt_ctf_field_type *type)
1159{
1160 struct bt_ctf_field_type_integer *integer;
ac0c6bdd 1161 struct bt_ctf_clock_class *clock_class = NULL;
6cfb906f
JG
1162
1163 if (!type) {
4e8304f7 1164 BT_LOGW_STR("Invalid parameter: field type is NULL.");
6cfb906f
JG
1165 goto end;
1166 }
1167
1168 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
ac0c6bdd
PP
1169 clock_class = integer->mapped_clock;
1170 bt_get(clock_class);
6cfb906f 1171end:
ac0c6bdd 1172 return clock_class;
6cfb906f
JG
1173}
1174
ac0c6bdd 1175int bt_ctf_field_type_integer_set_mapped_clock_class(
6cfb906f 1176 struct bt_ctf_field_type *type,
ac0c6bdd 1177 struct bt_ctf_clock_class *clock_class)
6cfb906f
JG
1178{
1179 struct bt_ctf_field_type_integer *integer;
1180 int ret = 0;
1181
4e8304f7
PP
1182 if (!type) {
1183 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1184 ret = -1;
1185 goto end;
1186 }
1187
1188 if (!clock_class) {
1189 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
1190 ret = -1;
1191 goto end;
1192 }
1193
1194 if (type->frozen) {
1195 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1196 type);
1197 ret = -1;
1198 goto end;
1199 }
1200
1201 if (!bt_ctf_clock_class_is_valid(clock_class)) {
1202 BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
1203 "clock-class-addr=%p, clock-class-name=\"%s\"",
1204 type, clock_class,
1205 bt_ctf_clock_class_get_name(clock_class));
6cfb906f
JG
1206 ret = -1;
1207 goto end;
1208 }
1209
1210 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
83509119 1211 bt_put(integer->mapped_clock);
ac0c6bdd 1212 integer->mapped_clock = bt_get(clock_class);
dfc1504d
PP
1213 BT_LOGV("Set integer field type's mapped clock class: ft-addr=%p, "
1214 "clock-class-addr=%p, clock-class-name=\"%s\"",
1215 type, clock_class, bt_ctf_clock_class_get_name(clock_class));
6cfb906f
JG
1216end:
1217 return ret;
1218}
1219
96e8f959 1220static
d49e1284 1221void bt_ctf_field_type_enum_iter_destroy(struct bt_object *obj)
96e8f959 1222{
d49e1284
JG
1223 struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
1224 container_of(obj,
1225 struct bt_ctf_field_type_enumeration_mapping_iterator,
1226 base);
96e8f959 1227
d49e1284
JG
1228 bt_put(&iter->enumeration_type->parent);
1229 g_free(iter);
1230}
1231
1232static
1233struct bt_ctf_field_type_enumeration_mapping_iterator *
1234bt_ctf_field_type_enumeration_find_mappings_type(
1235 struct bt_ctf_field_type *type,
1236 enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type)
1237{
1238 struct bt_ctf_field_type_enumeration *enumeration_type;
1239 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
1240
4e8304f7
PP
1241 if (!type) {
1242 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1243 goto end;
1244 }
1245
1246 if (type->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
1247 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1248 "addr=%p, ft-id=%s", type,
1249 bt_ctf_field_type_id_string(type->id));
96e8f959
MD
1250 goto end;
1251 }
1252
d49e1284
JG
1253 enumeration_type = container_of(type,
1254 struct bt_ctf_field_type_enumeration, parent);
1255 iter = g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator, 1);
1256 if (!iter) {
4e8304f7 1257 BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
d49e1284
JG
1258 goto end;
1259 }
1260
1261 bt_object_init(&iter->base, bt_ctf_field_type_enum_iter_destroy);
1262 bt_get(type);
1263 iter->enumeration_type = enumeration_type;
1264 iter->index = -1;
1265 iter->type = iterator_type;
96e8f959 1266end:
d49e1284 1267 return iter;
96e8f959
MD
1268}
1269
d49e1284
JG
1270struct bt_ctf_field_type_enumeration_mapping_iterator *
1271bt_ctf_field_type_enumeration_find_mappings_by_name(
1272 struct bt_ctf_field_type *type, const char *name)
96e8f959 1273{
d49e1284 1274 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
96e8f959 1275
d49e1284
JG
1276 iter = bt_ctf_field_type_enumeration_find_mappings_type(
1277 type, ITERATOR_BY_NAME);
1278 if (!iter) {
4e8304f7
PP
1279 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1280 "ft-addr=%p, mapping-name=\"%s\"", type, name);
d49e1284
JG
1281 goto error;
1282 }
1283
1284 iter->u.name_quark = g_quark_try_string(name);
1285 if (!iter->u.name_quark) {
4e8304f7 1286 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
d49e1284
JG
1287 goto error;
1288 }
1289
1290 /* Advance iterator to first entry, or leave index at -1. */
1291 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
1292 /* No entry found. */
1293 goto error;
1294 }
1295
1296 return iter;
1297error:
1298 bt_put(iter);
1299 return NULL;
96e8f959
MD
1300}
1301
1302int bt_ctf_field_type_enumeration_mapping_iterator_next(
1303 struct bt_ctf_field_type_enumeration_mapping_iterator *iter)
1304{
1305 struct bt_ctf_field_type_enumeration *enumeration;
1306 struct bt_ctf_field_type *type;
1307 int i, ret = 0, len;
1308
4e8304f7
PP
1309 if (!iter) {
1310 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
1311 ret = -1;
1312 goto end;
1313 }
1314
96e8f959
MD
1315 enumeration = iter->enumeration_type;
1316 type = &enumeration->parent;
1317 len = enumeration->entries->len;
1318 for (i = iter->index + 1; i < len; i++) {
1319 struct enumeration_mapping *mapping =
1320 get_enumeration_mapping(type, i);
1321
d49e1284 1322 switch (iter->type) {
96e8f959
MD
1323 case ITERATOR_BY_NAME:
1324 if (mapping->string == iter->u.name_quark) {
1325 iter->index = i;
1326 goto end;
1327 }
1328 break;
1329 case ITERATOR_BY_SIGNED_VALUE:
1330 {
1331 int64_t value = iter->u.signed_value;
1332
1333 if (value >= mapping->range_start._signed &&
1334 value <= mapping->range_end._signed) {
1335 iter->index = i;
1336 goto end;
1337 }
1338 break;
1339 }
1340 case ITERATOR_BY_UNSIGNED_VALUE:
1341 {
1342 uint64_t value = iter->u.unsigned_value;
1343
1344 if (value >= mapping->range_start._unsigned &&
1345 value <= mapping->range_end._unsigned) {
1346 iter->index = i;
1347 goto end;
1348 }
1349 break;
1350 }
1351 default:
1352 abort();
1353 }
1354 }
1355
1356 ret = -1;
1357end:
1358 return ret;
1359}
1360
96e8f959 1361struct bt_ctf_field_type_enumeration_mapping_iterator *
d49e1284
JG
1362bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
1363 struct bt_ctf_field_type *type, int64_t value)
96e8f959 1364{
d49e1284 1365 struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
96e8f959 1366
d49e1284 1367 iter = bt_ctf_field_type_enumeration_find_mappings_type(
96e8f959
MD
1368 type, ITERATOR_BY_SIGNED_VALUE);
1369 if (!iter) {
4e8304f7
PP
1370 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1371 "ft-addr=%p, value=%" PRId64, type, value);
96e8f959
MD
1372 goto error;
1373 }
d49e1284 1374
96e8f959
MD
1375 if (bt_ctf_field_type_integer_get_signed(
1376 iter->enumeration_type->container) != 1) {
4e8304f7
PP
1377 BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
1378 "enum-ft-addr=%p, int-ft-addr=%p",
1379 type, iter->enumeration_type->container);
96e8f959
MD
1380 goto error;
1381 }
4e8304f7 1382
96e8f959 1383 iter->u.signed_value = value;
d49e1284 1384
96e8f959
MD
1385 /* Advance iterator to first entry, or leave index at -1. */
1386 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
1387 /* No entry found. */
1388 goto error;
1389 }
96e8f959 1390
d49e1284 1391 return iter;
96e8f959
MD
1392error:
1393 bt_put(iter);
1394 return NULL;
1395}
1396
1397struct bt_ctf_field_type_enumeration_mapping_iterator *
d49e1284
JG
1398bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
1399 struct bt_ctf_field_type *type, uint64_t value)
96e8f959 1400{
4e8304f7
PP
1401 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
1402
1403 if (!type) {
1404 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1405 goto error;
1406 }
96e8f959 1407
d49e1284 1408 iter = bt_ctf_field_type_enumeration_find_mappings_type(
96e8f959
MD
1409 type, ITERATOR_BY_UNSIGNED_VALUE);
1410 if (!iter) {
4e8304f7
PP
1411 BT_LOGE("Cannot create enumeration field type mapping iterator: "
1412 "ft-addr=%p, value=%" PRIu64, type, value);
96e8f959
MD
1413 goto error;
1414 }
d49e1284 1415
96e8f959
MD
1416 if (bt_ctf_field_type_integer_get_signed(
1417 iter->enumeration_type->container) != 0) {
4e8304f7
PP
1418 BT_LOGW("Invalid parameter: enumeration field type is signed: "
1419 "enum-ft-addr=%p, int-ft-addr=%p",
1420 type, iter->enumeration_type->container);
96e8f959
MD
1421 goto error;
1422 }
1423 iter->u.unsigned_value = value;
d49e1284 1424
96e8f959
MD
1425 /* Advance iterator to first entry, or leave index at -1. */
1426 if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
1427 /* No entry found. */
1428 goto error;
1429 }
96e8f959 1430
d49e1284 1431 return iter;
96e8f959
MD
1432error:
1433 bt_put(iter);
1434 return NULL;
1435}
1436
d49e1284
JG
1437int bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
1438 struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
1439 const char **mapping_name, int64_t *range_begin,
1440 int64_t *range_end)
1441{
1442 int ret = 0;
1443
1444 if (!iter) {
4e8304f7 1445 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
d49e1284
JG
1446 ret = -1;
1447 goto end;
1448 }
1449
1450 ret = bt_ctf_field_type_enumeration_get_mapping_signed(
1451 &iter->enumeration_type->parent, iter->index,
1452 mapping_name, range_begin, range_end);
1453end:
1454 return ret;
1455}
1456
1457int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
1458 struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
1459 const char **mapping_name, uint64_t *range_begin,
1460 uint64_t *range_end)
1461{
1462 int ret = 0;
1463
1464 if (!iter) {
4e8304f7 1465 BT_LOGW_STR("Invalid parameter: enumeration field type mapping iterator is NULL.");
d49e1284
JG
1466 ret = -1;
1467 goto end;
1468 }
1469
1470 ret = bt_ctf_field_type_enumeration_get_mapping_unsigned(
1471 &iter->enumeration_type->parent, iter->index,
1472 mapping_name, range_begin, range_end);
1473end:
1474 return ret;
96e8f959
MD
1475}
1476
1477int bt_ctf_field_type_enumeration_get_mapping_signed(
1478 struct bt_ctf_field_type *enum_field_type,
9ac68eb1 1479 uint64_t index, const char **mapping_name, int64_t *range_begin,
96e8f959
MD
1480 int64_t *range_end)
1481{
d49e1284 1482 int ret = 0;
96e8f959
MD
1483 struct enumeration_mapping *mapping;
1484
9ac68eb1 1485 if (!enum_field_type) {
4e8304f7 1486 BT_LOGW_STR("Invalid parameter: field type is NULL.");
d49e1284
JG
1487 ret = -1;
1488 goto end;
96e8f959 1489 }
d49e1284 1490
96e8f959
MD
1491 mapping = get_enumeration_mapping(enum_field_type, index);
1492 if (!mapping) {
4e8304f7 1493 /* get_enumeration_mapping() reports any error */
d49e1284
JG
1494 ret = -1;
1495 goto end;
96e8f959 1496 }
d49e1284 1497
96e8f959
MD
1498 if (mapping_name) {
1499 *mapping_name = g_quark_to_string(mapping->string);
1500 }
d49e1284 1501
96e8f959
MD
1502 if (range_begin) {
1503 *range_begin = mapping->range_start._signed;
1504 }
d49e1284 1505
96e8f959
MD
1506 if (range_end) {
1507 *range_end = mapping->range_end._signed;
1508 }
d49e1284
JG
1509end:
1510 return ret;
96e8f959
MD
1511}
1512
1513int bt_ctf_field_type_enumeration_get_mapping_unsigned(
1514 struct bt_ctf_field_type *enum_field_type,
9ac68eb1 1515 uint64_t index,
96e8f959
MD
1516 const char **mapping_name, uint64_t *range_begin,
1517 uint64_t *range_end)
1518{
d49e1284 1519 int ret = 0;
96e8f959
MD
1520 struct enumeration_mapping *mapping;
1521
9ac68eb1 1522 if (!enum_field_type) {
4e8304f7 1523 BT_LOGW_STR("Invalid parameter: field type is NULL.");
d49e1284
JG
1524 ret = -1;
1525 goto end;
96e8f959 1526 }
d49e1284 1527
96e8f959
MD
1528 mapping = get_enumeration_mapping(enum_field_type, index);
1529 if (!mapping) {
4e8304f7 1530 /* get_enumeration_mapping() reports any error */
d49e1284
JG
1531 ret = -1;
1532 goto end;
96e8f959 1533 }
d49e1284 1534
96e8f959
MD
1535 if (mapping_name) {
1536 *mapping_name = g_quark_to_string(mapping->string);
1537 }
d49e1284 1538
96e8f959
MD
1539 if (range_begin) {
1540 *range_begin = mapping->range_start._unsigned;
1541 }
d49e1284 1542
96e8f959
MD
1543 if (range_end) {
1544 *range_end = mapping->range_end._unsigned;
1545 }
d49e1284
JG
1546end:
1547 return ret;
96e8f959
MD
1548}
1549
273b65be
JG
1550struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
1551 struct bt_ctf_field_type *integer_container_type)
1552{
1553 struct bt_ctf_field_type_enumeration *enumeration = NULL;
1554
4e8304f7
PP
1555 BT_LOGD("Creating enumeration field type object: int-ft-addr=%p",
1556 integer_container_type);
1557
273b65be 1558 if (!integer_container_type) {
4e8304f7 1559 BT_LOGW_STR("Invalid parameter: field type is NULL.");
273b65be
JG
1560 goto error;
1561 }
1562
1487a16a 1563 if (integer_container_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4e8304f7
PP
1564 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
1565 "container-ft-addr=%p, container-ft-id=%s",
1566 integer_container_type,
1567 bt_ctf_field_type_id_string(integer_container_type->id));
2a610bb7
JG
1568 goto error;
1569 }
1570
273b65be
JG
1571 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
1572 if (!enumeration) {
4e8304f7 1573 BT_LOGE_STR("Failed to allocate one enumeration field type.");
273b65be
JG
1574 goto error;
1575 }
1576
1487a16a 1577 enumeration->parent.id = BT_CTF_FIELD_TYPE_ID_ENUM;
83509119 1578 bt_get(integer_container_type);
273b65be
JG
1579 enumeration->container = integer_container_type;
1580 enumeration->entries = g_ptr_array_new_with_free_func(
1581 (GDestroyNotify)destroy_enumeration_mapping);
59acd4f5 1582 bt_ctf_field_type_init(&enumeration->parent, FALSE);
4e8304f7
PP
1583 BT_LOGD("Created enumeration field type object: addr=%p, "
1584 "int-ft-addr=%p, int-ft-size=%u",
1585 &enumeration->parent, integer_container_type,
1586 bt_ctf_field_type_integer_get_size(integer_container_type));
273b65be
JG
1587 return &enumeration->parent;
1588error:
1589 g_free(enumeration);
1590 return NULL;
1591}
1592
b92ddaaa
JG
1593struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
1594 struct bt_ctf_field_type *type)
1595{
1596 struct bt_ctf_field_type *container_type = NULL;
1597 struct bt_ctf_field_type_enumeration *enumeration_type;
1598
1599 if (!type) {
4e8304f7 1600 BT_LOGW_STR("Invalid parameter: field type is NULL.");
b92ddaaa
JG
1601 goto end;
1602 }
1603
1487a16a 1604 if (type->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
4e8304f7
PP
1605 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1606 "addr=%p, ft-id=%s", type,
1607 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
1608 goto end;
1609 }
1610
1611 enumeration_type = container_of(type,
1612 struct bt_ctf_field_type_enumeration, parent);
1613 container_type = enumeration_type->container;
83509119 1614 bt_get(container_type);
b92ddaaa
JG
1615end:
1616 return container_type;
1617}
1618
dfc1504d 1619int bt_ctf_field_type_enumeration_add_mapping_signed(
273b65be
JG
1620 struct bt_ctf_field_type *type, const char *string,
1621 int64_t range_start, int64_t range_end)
1622{
1623 int ret = 0;
1624 GQuark mapping_name;
1625 struct enumeration_mapping *mapping;
1626 struct bt_ctf_field_type_enumeration *enumeration;
a39fa057 1627 char *escaped_string;
273b65be 1628
4e8304f7
PP
1629 if (!type) {
1630 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1631 ret = -1;
1632 goto end;
1633 }
1634
1635 if (!string) {
1636 BT_LOGW_STR("Invalid parameter: string is NULL.");
1637 ret = -1;
1638 goto end;
1639 }
1640
1641 if (type->frozen) {
1642 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1643 type);
1644 ret = -1;
1645 goto end;
1646 }
1647
1648 if (type->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
1649 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1650 "addr=%p, ft-id=%s", type,
1651 bt_ctf_field_type_id_string(type->id));
1652 ret = -1;
1653 goto end;
1654 }
1655
1656 if (range_end < range_start) {
1657 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1658 "addr=%p, range-start=%" PRId64 ", range-end=%" PRId64,
1659 type, range_start, range_end);
273b65be
JG
1660 ret = -1;
1661 goto end;
1662 }
1663
4e8304f7
PP
1664 if (strlen(string) == 0) {
1665 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1666 "enum-ft-addr=%p, mapping-name-addr=%p", type,
1667 string);
273b65be
JG
1668 ret = -1;
1669 goto end;
1670 }
1671
a39fa057
JG
1672 escaped_string = g_strescape(string, NULL);
1673 if (!escaped_string) {
4e8304f7
PP
1674 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1675 "mapping-name-addr=%p, mapping-name=\"%s\"",
1676 type, string, string);
a39fa057
JG
1677 ret = -1;
1678 goto end;
1679 }
1680
273b65be
JG
1681 mapping = g_new(struct enumeration_mapping, 1);
1682 if (!mapping) {
4e8304f7 1683 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
273b65be 1684 ret = -1;
a39fa057 1685 goto error_free;
273b65be 1686 }
96e8f959 1687 mapping_name = g_quark_from_string(escaped_string);
b92ddaaa
JG
1688 *mapping = (struct enumeration_mapping) {
1689 .range_start._signed = range_start,
96e8f959
MD
1690 .range_end._signed = range_end,
1691 .string = mapping_name,
1692 };
1693 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1694 parent);
273b65be 1695 g_ptr_array_add(enumeration->entries, mapping);
b92ddaaa
JG
1696 g_ptr_array_sort(enumeration->entries,
1697 (GCompareFunc)compare_enumeration_mappings_signed);
dfc1504d
PP
1698 BT_LOGV("Added mapping to signed enumeration field type: addr=%p, "
1699 "name=\"%s\", range-start=%" PRId64 ", "
1700 "range-end=%" PRId64,
1701 type, string, range_start, range_end);
b92ddaaa
JG
1702error_free:
1703 free(escaped_string);
1704end:
1705 return ret;
1706}
1707
1708int bt_ctf_field_type_enumeration_add_mapping_unsigned(
1709 struct bt_ctf_field_type *type, const char *string,
1710 uint64_t range_start, uint64_t range_end)
1711{
1712 int ret = 0;
1713 GQuark mapping_name;
1714 struct enumeration_mapping *mapping;
1715 struct bt_ctf_field_type_enumeration *enumeration;
b92ddaaa
JG
1716 char *escaped_string;
1717
4e8304f7
PP
1718 if (!type) {
1719 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1720 ret = -1;
1721 goto end;
1722 }
1723
1724 if (!string) {
1725 BT_LOGW_STR("Invalid parameter: string is NULL.");
1726 ret = -1;
1727 goto end;
1728 }
1729
1730 if (type->frozen) {
1731 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1732 type);
1733 ret = -1;
1734 goto end;
1735 }
1736
1737 if (type->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
1738 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1739 "addr=%p, ft-id=%s", type,
1740 bt_ctf_field_type_id_string(type->id));
1741 ret = -1;
1742 goto end;
1743 }
1744
1745 if (range_end < range_start) {
1746 BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
1747 "addr=%p, range-start=%" PRIu64 ", range-end=%" PRIu64,
1748 type, range_start, range_end);
b92ddaaa
JG
1749 ret = -1;
1750 goto end;
1751 }
1752
4e8304f7
PP
1753 if (strlen(string) == 0) {
1754 BT_LOGW("Invalid parameter: mapping name is an empty string: "
1755 "enum-ft-addr=%p, mapping-name-addr=%p", type,
1756 string);
b92ddaaa
JG
1757 ret = -1;
1758 goto end;
1759 }
1760
1761 escaped_string = g_strescape(string, NULL);
1762 if (!escaped_string) {
4e8304f7
PP
1763 BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
1764 "mapping-name-addr=%p, mapping-name=\"%s\"",
1765 type, string, string);
b92ddaaa
JG
1766 ret = -1;
1767 goto end;
1768 }
1769
b92ddaaa
JG
1770 mapping = g_new(struct enumeration_mapping, 1);
1771 if (!mapping) {
4e8304f7 1772 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
b92ddaaa
JG
1773 ret = -1;
1774 goto error_free;
1775 }
96e8f959 1776 mapping_name = g_quark_from_string(escaped_string);
b92ddaaa
JG
1777 *mapping = (struct enumeration_mapping) {
1778 .range_start._unsigned = range_start,
96e8f959
MD
1779 .range_end._unsigned = range_end,
1780 .string = mapping_name,
1781 };
1782 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1783 parent);
b92ddaaa
JG
1784 g_ptr_array_add(enumeration->entries, mapping);
1785 g_ptr_array_sort(enumeration->entries,
1786 (GCompareFunc)compare_enumeration_mappings_unsigned);
dfc1504d
PP
1787 BT_LOGV("Added mapping to unsigned enumeration field type: addr=%p, "
1788 "name=\"%s\", range-start=%" PRIu64 ", "
1789 "range-end=%" PRIu64,
1790 type, string, range_start, range_end);
a39fa057
JG
1791error_free:
1792 free(escaped_string);
273b65be
JG
1793end:
1794 return ret;
1795}
1796
544d0515 1797int64_t bt_ctf_field_type_enumeration_get_mapping_count(
b92ddaaa
JG
1798 struct bt_ctf_field_type *type)
1799{
544d0515 1800 int64_t ret = 0;
b92ddaaa
JG
1801 struct bt_ctf_field_type_enumeration *enumeration;
1802
4e8304f7
PP
1803 if (!type) {
1804 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1805 ret = (int64_t) -1;
1806 goto end;
1807 }
1808
1809 if (type->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
1810 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
1811 "addr=%p, ft-id=%s", type,
1812 bt_ctf_field_type_id_string(type->id));
9ac68eb1 1813 ret = (int64_t) -1;
b92ddaaa
JG
1814 goto end;
1815 }
1816
1817 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
1818 parent);
544d0515 1819 ret = (int64_t) enumeration->entries->len;
b92ddaaa
JG
1820end:
1821 return ret;
1822}
1823
273b65be
JG
1824struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
1825{
1826 struct bt_ctf_field_type_floating_point *floating_point =
1827 g_new0(struct bt_ctf_field_type_floating_point, 1);
1828
4e8304f7
PP
1829 BT_LOGD_STR("Creating floating point number field type object.");
1830
273b65be 1831 if (!floating_point) {
4e8304f7 1832 BT_LOGE_STR("Failed to allocate one floating point number field type.");
273b65be
JG
1833 goto end;
1834 }
1835
1487a16a 1836 floating_point->parent.id = BT_CTF_FIELD_TYPE_ID_FLOAT;
dc3fffef
PP
1837 floating_point->exp_dig = sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
1838 floating_point->mant_dig = FLT_MANT_DIG;
59acd4f5 1839 bt_ctf_field_type_init(&floating_point->parent, TRUE);
4e8304f7
PP
1840 BT_LOGD("Created floating point number field type object: addr=%p, "
1841 "exp-size=%u, mant-size=%u", &floating_point->parent,
1842 floating_point->exp_dig, floating_point->mant_dig);
273b65be
JG
1843end:
1844 return floating_point ? &floating_point->parent : NULL;
1845}
1846
b92ddaaa
JG
1847int bt_ctf_field_type_floating_point_get_exponent_digits(
1848 struct bt_ctf_field_type *type)
1849{
1850 int ret = 0;
1851 struct bt_ctf_field_type_floating_point *floating_point;
1852
4e8304f7
PP
1853 if (!type) {
1854 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1855 ret = -1;
1856 goto end;
1857 }
1858
1859 if (type->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
1860 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1861 "addr=%p, ft-id=%s", type,
1862 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
1863 ret = -1;
1864 goto end;
1865 }
1866
1867 floating_point = container_of(type,
1868 struct bt_ctf_field_type_floating_point, parent);
dc3fffef 1869 ret = (int) floating_point->exp_dig;
b92ddaaa
JG
1870end:
1871 return ret;
1872}
1873
273b65be
JG
1874int bt_ctf_field_type_floating_point_set_exponent_digits(
1875 struct bt_ctf_field_type *type,
1876 unsigned int exponent_digits)
1877{
1878 int ret = 0;
1879 struct bt_ctf_field_type_floating_point *floating_point;
1880
4e8304f7
PP
1881 if (!type) {
1882 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1883 ret = -1;
1884 goto end;
1885 }
1886
1887 if (type->frozen) {
1888 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1889 type);
1890 ret = -1;
1891 goto end;
1892 }
1893
1894 if (type->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
1895 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1896 "addr=%p, ft-id=%s", type,
1897 bt_ctf_field_type_id_string(type->id));
273b65be
JG
1898 ret = -1;
1899 goto end;
1900 }
1901
1902 floating_point = container_of(type,
1903 struct bt_ctf_field_type_floating_point, parent);
1904 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
1905 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
1906 (exponent_digits !=
1907 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
4e8304f7
PP
1908 BT_LOGW("Invalid parameter: invalid exponent size: "
1909 "addr=%p, exp-size=%u", type, exponent_digits);
273b65be
JG
1910 ret = -1;
1911 goto end;
1912 }
1913
dc3fffef 1914 floating_point->exp_dig = exponent_digits;
dfc1504d
PP
1915 BT_LOGV("Set floating point number field type's exponent size: addr=%p, "
1916 "exp-size=%u", type, exponent_digits);
273b65be
JG
1917end:
1918 return ret;
1919}
1920
b92ddaaa
JG
1921int bt_ctf_field_type_floating_point_get_mantissa_digits(
1922 struct bt_ctf_field_type *type)
1923{
1924 int ret = 0;
1925 struct bt_ctf_field_type_floating_point *floating_point;
1926
4e8304f7
PP
1927 if (!type) {
1928 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1929 ret = -1;
1930 goto end;
1931 }
1932
1933 if (type->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
1934 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1935 "addr=%p, ft-id=%s", type,
1936 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
1937 ret = -1;
1938 goto end;
1939 }
1940
1941 floating_point = container_of(type,
1942 struct bt_ctf_field_type_floating_point, parent);
dc3fffef 1943 ret = (int) floating_point->mant_dig;
b92ddaaa
JG
1944end:
1945 return ret;
1946}
1947
273b65be
JG
1948int bt_ctf_field_type_floating_point_set_mantissa_digits(
1949 struct bt_ctf_field_type *type,
1950 unsigned int mantissa_digits)
1951{
1952 int ret = 0;
1953 struct bt_ctf_field_type_floating_point *floating_point;
1954
4e8304f7
PP
1955 if (!type) {
1956 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1957 ret = -1;
1958 goto end;
1959 }
1960
1961 if (type->frozen) {
1962 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
1963 type);
1964 ret = -1;
1965 goto end;
1966 }
1967
1968 if (type->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
1969 BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
1970 "addr=%p, ft-id=%s", type,
1971 bt_ctf_field_type_id_string(type->id));
273b65be
JG
1972 ret = -1;
1973 goto end;
1974 }
1975
1976 floating_point = container_of(type,
1977 struct bt_ctf_field_type_floating_point, parent);
1978
1979 if ((mantissa_digits != FLT_MANT_DIG) &&
1980 (mantissa_digits != DBL_MANT_DIG) &&
1981 (mantissa_digits != LDBL_MANT_DIG)) {
4e8304f7
PP
1982 BT_LOGW("Invalid parameter: invalid mantissa size: "
1983 "addr=%p, mant-size=%u", type, mantissa_digits);
273b65be
JG
1984 ret = -1;
1985 goto end;
1986 }
1987
dc3fffef 1988 floating_point->mant_dig = mantissa_digits;
dfc1504d
PP
1989 BT_LOGV("Set floating point number field type's mantissa size: addr=%p, "
1990 "mant-size=%u", type, mantissa_digits);
273b65be
JG
1991end:
1992 return ret;
1993}
1994
1995struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
1996{
1997 struct bt_ctf_field_type_structure *structure =
1998 g_new0(struct bt_ctf_field_type_structure, 1);
1999
4e8304f7
PP
2000 BT_LOGD_STR("Creating structure field type object.");
2001
273b65be 2002 if (!structure) {
4e8304f7 2003 BT_LOGE_STR("Failed to allocate one structure field type.");
273b65be
JG
2004 goto error;
2005 }
2006
1487a16a 2007 structure->parent.id = BT_CTF_FIELD_TYPE_ID_STRUCT;
273b65be
JG
2008 structure->fields = g_ptr_array_new_with_free_func(
2009 (GDestroyNotify)destroy_structure_field);
2010 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
59acd4f5 2011 bt_ctf_field_type_init(&structure->parent, TRUE);
4e8304f7
PP
2012 BT_LOGD("Created structure field type object: addr=%p",
2013 &structure->parent);
273b65be
JG
2014 return &structure->parent;
2015error:
2016 return NULL;
2017}
2018
2019int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
2020 struct bt_ctf_field_type *field_type,
2021 const char *field_name)
2022{
2023 int ret = 0;
2024 struct bt_ctf_field_type_structure *structure;
2025
73892edc
PP
2026 /*
2027 * TODO: check that `field_type` does not contain `type`,
2028 * recursively.
2029 */
4e8304f7
PP
2030 if (!type) {
2031 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2032 ret = -1;
2033 goto end;
2034 }
2035
2036 if (!field_name) {
2037 BT_LOGW_STR("Invalid parameter: field name is NULL.");
2038 ret = -1;
2039 goto end;
2040 }
2041
2042 if (type->frozen) {
2043 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2044 type);
2045 ret = -1;
2046 goto end;
2047 }
2048
2049 if (bt_ctf_validate_identifier(field_name)) {
2050 BT_LOGW("Invalid parameter: field name is not a valid CTF identifier: "
2051 "struct-ft-addr=%p, field-name=\"%s\"",
2052 type, field_name);
2053 ret = -1;
2054 goto end;
2055 }
2056
2057 if (type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
2058 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2059 "addr=%p, ft-id=%s", type,
2060 bt_ctf_field_type_id_string(type->id));
2061 ret = -1;
2062 goto end;
2063 }
2064
2065 if (type == field_type) {
2066 BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
2067 "addr=%p", type);
e6235f1f 2068 ret = -1;
273b65be
JG
2069 goto end;
2070 }
2071
2072 structure = container_of(type,
2073 struct bt_ctf_field_type_structure, parent);
2074 if (add_structure_field(structure->fields,
4e8304f7
PP
2075 structure->field_name_to_index, field_type, field_name)) {
2076 BT_LOGW("Cannot add field to structure field type: "
2077 "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2078 type, field_type, field_name);
273b65be
JG
2079 ret = -1;
2080 goto end;
2081 }
dfc1504d
PP
2082
2083 BT_LOGV("Added structure field type field: struct-ft-addr=%p, "
2084 "field-ft-addr=%p, field-name=\"%s\"", type,
2085 field_type, field_name);
b92ddaaa
JG
2086end:
2087 return ret;
2088}
2089
544d0515 2090int64_t bt_ctf_field_type_structure_get_field_count(
b92ddaaa
JG
2091 struct bt_ctf_field_type *type)
2092{
544d0515 2093 int64_t ret = 0;
b92ddaaa
JG
2094 struct bt_ctf_field_type_structure *structure;
2095
4e8304f7
PP
2096 if (!type) {
2097 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2098 ret = (int64_t) -1;
2099 goto end;
2100 }
2101
2102 if (type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
2103 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2104 "addr=%p, ft-id=%s", type,
2105 bt_ctf_field_type_id_string(type->id));
9ac68eb1 2106 ret = (int64_t) -1;
b92ddaaa
JG
2107 goto end;
2108 }
2109
2110 structure = container_of(type, struct bt_ctf_field_type_structure,
2111 parent);
544d0515 2112 ret = (int64_t) structure->fields->len;
b92ddaaa
JG
2113end:
2114 return ret;
2115}
2116
9ac68eb1
PP
2117int bt_ctf_field_type_structure_get_field_by_index(
2118 struct bt_ctf_field_type *type,
b92ddaaa 2119 const char **field_name, struct bt_ctf_field_type **field_type,
9ac68eb1 2120 uint64_t index)
b92ddaaa
JG
2121{
2122 struct bt_ctf_field_type_structure *structure;
2123 struct structure_field *field;
2124 int ret = 0;
2125
4e8304f7
PP
2126 if (!type) {
2127 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2128 ret = -1;
2129 goto end;
2130 }
2131
2132 if (type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
2133 BT_LOGW("Invalid parameter: field type is not a structure field type: "
2134 "addr=%p, ft-id=%s", type,
2135 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2136 ret = -1;
2137 goto end;
2138 }
2139
2140 structure = container_of(type, struct bt_ctf_field_type_structure,
2141 parent);
2142 if (index >= structure->fields->len) {
4e8304f7
PP
2143 BT_LOGW("Invalid parameter: index is out of bounds: "
2144 "addr=%p, index=%" PRIu64 ", count=%u",
2145 type, index, structure->fields->len);
b92ddaaa
JG
2146 ret = -1;
2147 goto end;
2148 }
2149
2150 field = g_ptr_array_index(structure->fields, index);
f9b799fc
JG
2151 if (field_type) {
2152 *field_type = field->type;
83509119 2153 bt_get(field->type);
f9b799fc
JG
2154 }
2155 if (field_name) {
2156 *field_name = g_quark_to_string(field->name);
2157 }
b92ddaaa
JG
2158end:
2159 return ret;
2160}
2161
2162struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
2163 struct bt_ctf_field_type *type,
2164 const char *name)
2165{
2166 size_t index;
2167 GQuark name_quark;
2168 struct structure_field *field;
2169 struct bt_ctf_field_type_structure *structure;
2170 struct bt_ctf_field_type *field_type = NULL;
2171
4e8304f7
PP
2172 if (!type) {
2173 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2174 goto end;
2175 }
2176
2177 if (!name) {
2178 BT_LOGW_STR("Invalid parameter: name is NULL.");
b92ddaaa
JG
2179 goto end;
2180 }
2181
2182 name_quark = g_quark_try_string(name);
2183 if (!name_quark) {
4e8304f7 2184 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
b92ddaaa
JG
2185 goto end;
2186 }
2187
2188 structure = container_of(type, struct bt_ctf_field_type_structure,
2189 parent);
2190 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
2191 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2192 goto end;
273b65be 2193 }
b92ddaaa
JG
2194
2195 field = structure->fields->pdata[index];
2196 field_type = field->type;
83509119 2197 bt_get(field_type);
273b65be 2198end:
b92ddaaa 2199 return field_type;
273b65be
JG
2200}
2201
2202struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
2203 struct bt_ctf_field_type *enum_tag, const char *tag_name)
2204{
2205 struct bt_ctf_field_type_variant *variant = NULL;
2206
4e8304f7
PP
2207 BT_LOGD("Creating variant field type object: "
2208 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2209 enum_tag, tag_name);
2210
6964b7fd 2211 if (tag_name && bt_ctf_validate_identifier(tag_name)) {
4e8304f7
PP
2212 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2213 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2214 enum_tag, tag_name);
273b65be
JG
2215 goto error;
2216 }
2217
2218 variant = g_new0(struct bt_ctf_field_type_variant, 1);
2219 if (!variant) {
4e8304f7 2220 BT_LOGE_STR("Failed to allocate one variant field type.");
273b65be
JG
2221 goto error;
2222 }
2223
1487a16a 2224 variant->parent.id = BT_CTF_FIELD_TYPE_ID_VARIANT;
273b65be 2225 variant->tag_name = g_string_new(tag_name);
273b65be
JG
2226 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
2227 variant->fields = g_ptr_array_new_with_free_func(
83509119 2228 (GDestroyNotify) destroy_structure_field);
6964b7fd 2229 if (enum_tag) {
83509119 2230 bt_get(enum_tag);
6964b7fd
JG
2231 variant->tag = container_of(enum_tag,
2232 struct bt_ctf_field_type_enumeration, parent);
2233 }
2234
59acd4f5 2235 bt_ctf_field_type_init(&variant->parent, TRUE);
46caf2cb 2236 /* A variant's alignment is undefined */
dc3fffef 2237 variant->parent.alignment = 0;
4e8304f7
PP
2238 BT_LOGD("Created variant field type object: addr=%p, "
2239 "tag-ft-addr=%p, tag-field-name=\"%s\"",
2240 &variant->parent, enum_tag, tag_name);
273b65be
JG
2241 return &variant->parent;
2242error:
2243 return NULL;
2244}
2245
b92ddaaa
JG
2246struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
2247 struct bt_ctf_field_type *type)
2248{
2249 struct bt_ctf_field_type_variant *variant;
2250 struct bt_ctf_field_type *tag_type = NULL;
2251
4e8304f7
PP
2252 if (!type) {
2253 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2254 goto end;
2255 }
2256
2257 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2258 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2259 "addr=%p, ft-id=%s", type,
2260 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2261 goto end;
2262 }
2263
2264 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd 2265 if (!variant->tag) {
4e8304f7
PP
2266 BT_LOGV("Variant field type has no tag field type: "
2267 "addr=%p", type);
6964b7fd
JG
2268 goto end;
2269 }
2270
b92ddaaa 2271 tag_type = &variant->tag->parent;
83509119 2272 bt_get(tag_type);
b92ddaaa
JG
2273end:
2274 return tag_type;
2275}
2276
2277const char *bt_ctf_field_type_variant_get_tag_name(
2278 struct bt_ctf_field_type *type)
2279{
2280 struct bt_ctf_field_type_variant *variant;
2281 const char *tag_name = NULL;
2282
4e8304f7
PP
2283 if (!type) {
2284 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2285 goto end;
2286 }
2287
2288 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2289 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2290 "addr=%p, ft-id=%s", type,
2291 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2292 goto end;
2293 }
2294
2295 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
6964b7fd 2296 if (variant->tag_name->len == 0) {
4e8304f7
PP
2297 BT_LOGV("Variant field type has no tag field name: "
2298 "addr=%p", type);
6964b7fd
JG
2299 goto end;
2300 }
2301
b92ddaaa
JG
2302 tag_name = variant->tag_name->str;
2303end:
2304 return tag_name;
2305}
2306
d9b1ab6d
JG
2307int bt_ctf_field_type_variant_set_tag_name(
2308 struct bt_ctf_field_type *type, const char *name)
2309{
2310 int ret = 0;
2311 struct bt_ctf_field_type_variant *variant;
2312
4e8304f7
PP
2313 if (!type) {
2314 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2315 ret = -1;
2316 goto end;
2317 }
2318
2319 if (type->frozen) {
2320 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2321 type);
2322 ret = -1;
2323 goto end;
2324 }
2325
2326 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2327 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2328 "addr=%p, ft-id=%s", type,
2329 bt_ctf_field_type_id_string(type->id));
2330 ret = -1;
2331 goto end;
2332 }
2333
2334 if (bt_ctf_validate_identifier(name)) {
2335 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
2336 "variant-ft-addr=%p, tag-field-name=\"%s\"",
2337 type, name);
d9b1ab6d
JG
2338 ret = -1;
2339 goto end;
2340 }
2341
2342 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
2343 g_string_assign(variant->tag_name, name);
dfc1504d
PP
2344 BT_LOGV("Set variant field type's tag field name: addr=%p, "
2345 "tag-field-name=\"%s\"", type, name);
d9b1ab6d
JG
2346end:
2347 return ret;
2348}
2349
4e8304f7
PP
2350int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
2351 struct bt_ctf_field_type *field_type,
2352 const char *field_name)
2353{
2354 size_t i;
2355 int ret = 0;
2356 struct bt_ctf_field_type_variant *variant;
2357 GQuark field_name_quark = g_quark_from_string(field_name);
2358
2359 /*
2360 * TODO: check that `field_type` does not contain `type`,
2361 * recursively.
2362 */
2363 if (!type) {
2364 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2365 ret = -1;
2366 goto end;
2367 }
2368
2369 if (type->frozen) {
2370 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
2371 type);
2372 ret = -1;
2373 goto end;
2374 }
2375
2376 if (bt_ctf_validate_identifier(field_name)) {
2377 BT_LOGW("Invalid parameter: field name is not a valid CTF identifier: "
2378 "variant-ft-addr=%p, field-name=\"%s\"",
2379 type, field_name);
2380 ret = -1;
2381 goto end;
2382 }
2383
2384 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2385 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2386 "addr=%p, ft-id=%s", type,
2387 bt_ctf_field_type_id_string(type->id));
2388 ret = -1;
2389 goto end;
2390 }
273b65be 2391
4e8304f7
PP
2392 if (type == field_type) {
2393 BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
2394 "addr=%p", type);
273b65be
JG
2395 ret = -1;
2396 goto end;
2397 }
2398
2399 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
273b65be 2400
6964b7fd
JG
2401 /* The user has explicitly provided a tag; validate against it. */
2402 if (variant->tag) {
2403 int name_found = 0;
2404
2405 /* Make sure this name is present in the enum tag */
2406 for (i = 0; i < variant->tag->entries->len; i++) {
2407 struct enumeration_mapping *mapping =
2408 g_ptr_array_index(variant->tag->entries, i);
2409
2410 if (mapping->string == field_name_quark) {
2411 name_found = 1;
2412 break;
2413 }
2414 }
2415
2416 if (!name_found) {
2417 /* Validation failed */
4e8304f7
PP
2418 BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
2419 "variant-ft-addr=%p, tag-ft-addr=%p, "
2420 "tag-field-name=\"%s\""
2421 "field-ft-addr=%p, field-name=\"%s\"",
2422 type, variant->tag, variant->tag_name->str,
2423 field_type, field_name);
6964b7fd
JG
2424 ret = -1;
2425 goto end;
273b65be
JG
2426 }
2427 }
2428
6964b7fd 2429 if (add_structure_field(variant->fields, variant->field_name_to_index,
4e8304f7
PP
2430 field_type, field_name)) {
2431 BT_LOGW("Cannot add field to variant field type: "
2432 "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
2433 type, field_type, field_name);
273b65be
JG
2434 ret = -1;
2435 goto end;
2436 }
dfc1504d
PP
2437
2438 BT_LOGV("Added variant field type field: variant-ft-addr=%p, "
2439 "field-ft-addr=%p, field-name=\"%s\"", type,
2440 field_type, field_name);
2441
273b65be
JG
2442end:
2443 return ret;
2444}
2445
b92ddaaa
JG
2446struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
2447 struct bt_ctf_field_type *type,
2448 const char *field_name)
2449{
2450 size_t index;
2451 GQuark name_quark;
2452 struct structure_field *field;
2453 struct bt_ctf_field_type_variant *variant;
2454 struct bt_ctf_field_type *field_type = NULL;
2455
4e8304f7
PP
2456 if (!type) {
2457 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2458 goto end;
2459 }
2460
2461 if (!field_name) {
2462 BT_LOGW_STR("Invalid parameter: field name is NULL.");
b92ddaaa
JG
2463 goto end;
2464 }
2465
2466 name_quark = g_quark_try_string(field_name);
2467 if (!name_quark) {
4e8304f7 2468 BT_LOGE("Cannot get GQuark: string=\"%s\"", field_name);
b92ddaaa
JG
2469 goto end;
2470 }
2471
2472 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
2473 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
2474 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
2475 goto end;
2476 }
2477
2478 field = g_ptr_array_index(variant->fields, index);
2479 field_type = field->type;
83509119 2480 bt_get(field_type);
b92ddaaa
JG
2481end:
2482 return field_type;
2483}
2484
2485struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
2486 struct bt_ctf_field_type *type,
2487 struct bt_ctf_field *tag)
2488{
e0f15669 2489 int ret;
b92ddaaa
JG
2490 const char *enum_value;
2491 struct bt_ctf_field_type *field_type = NULL;
e0f15669 2492 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
b92ddaaa 2493
4e8304f7
PP
2494 if (!type) {
2495 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
2496 goto end;
2497 }
2498
2499 if (!tag) {
2500 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
2501 goto end;
2502 }
2503
2504 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2505 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2506 "addr=%p, ft-id=%s", type,
2507 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2508 goto end;
2509 }
2510
e0f15669
JG
2511 iter = bt_ctf_field_enumeration_get_mappings(tag);
2512 if (!iter) {
4e8304f7
PP
2513 BT_LOGE("Cannot get enumeration field type mapping iterator from enumeration field: "
2514 "enum-field-addr=%p", tag);
e0f15669
JG
2515 goto end;
2516 }
2517
5c3f3b7e
PP
2518 ret = bt_ctf_field_type_enumeration_mapping_iterator_get_signed(iter,
2519 &enum_value, NULL, NULL);
e0f15669 2520 if (ret) {
4e8304f7
PP
2521 BT_LOGW("Cannot get enumeration field type mapping iterator's current mapping: "
2522 "iter-addr=%p", iter);
b92ddaaa
JG
2523 goto end;
2524 }
2525
b92ddaaa
JG
2526 field_type = bt_ctf_field_type_variant_get_field_type_by_name(
2527 type, enum_value);
2528end:
e0f15669 2529 bt_put(iter);
b92ddaaa
JG
2530 return field_type;
2531}
2532
544d0515 2533int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
b92ddaaa 2534{
544d0515 2535 int64_t ret = 0;
b92ddaaa
JG
2536 struct bt_ctf_field_type_variant *variant;
2537
4e8304f7
PP
2538 if (!type) {
2539 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2540 ret = (int64_t) -1;
2541 goto end;
2542 }
2543
2544 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2545 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2546 "addr=%p, ft-id=%s", type,
2547 bt_ctf_field_type_id_string(type->id));
9ac68eb1 2548 ret = (int64_t) -1;
b92ddaaa
JG
2549 goto end;
2550 }
2551
2552 variant = container_of(type, struct bt_ctf_field_type_variant,
2553 parent);
544d0515 2554 ret = (int64_t) variant->fields->len;
b92ddaaa
JG
2555end:
2556 return ret;
2557
2558}
2559
9ac68eb1 2560int bt_ctf_field_type_variant_get_field_by_index(struct bt_ctf_field_type *type,
b92ddaaa 2561 const char **field_name, struct bt_ctf_field_type **field_type,
9ac68eb1 2562 uint64_t index)
b92ddaaa
JG
2563{
2564 struct bt_ctf_field_type_variant *variant;
2565 struct structure_field *field;
2566 int ret = 0;
2567
4e8304f7
PP
2568 if (!type) {
2569 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2570 ret = -1;
2571 goto end;
2572 }
2573
2574 if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
2575 BT_LOGW("Invalid parameter: field type is not a variant field type: "
2576 "addr=%p, ft-id=%s", type,
2577 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2578 ret = -1;
2579 goto end;
2580 }
2581
2582 variant = container_of(type, struct bt_ctf_field_type_variant,
2583 parent);
2584 if (index >= variant->fields->len) {
4e8304f7
PP
2585 BT_LOGW("Invalid parameter: index is out of bounds: "
2586 "addr=%p, index=%" PRIu64 ", count=%u",
2587 type, index, variant->fields->len);
b92ddaaa
JG
2588 ret = -1;
2589 goto end;
2590 }
2591
2592 field = g_ptr_array_index(variant->fields, index);
647f3b93
JG
2593 if (field_type) {
2594 *field_type = field->type;
83509119 2595 bt_get(field->type);
647f3b93
JG
2596 }
2597 if (field_name) {
2598 *field_name = g_quark_to_string(field->name);
2599 }
b92ddaaa
JG
2600end:
2601 return ret;
2602}
2603
273b65be
JG
2604struct bt_ctf_field_type *bt_ctf_field_type_array_create(
2605 struct bt_ctf_field_type *element_type,
2606 unsigned int length)
2607{
2608 struct bt_ctf_field_type_array *array = NULL;
2609
4e8304f7
PP
2610 BT_LOGD("Creating array field type object: element-ft-addr=%p, "
2611 "length=%u", element_type, length);
2612
2613 if (!element_type) {
2614 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2615 goto error;
2616 }
2617
2618 if (length == 0) {
2619 BT_LOGW_STR("Invalid parameter: length is zero.");
273b65be
JG
2620 goto error;
2621 }
2622
2623 array = g_new0(struct bt_ctf_field_type_array, 1);
2624 if (!array) {
4e8304f7 2625 BT_LOGE_STR("Failed to allocate one array field type.");
273b65be
JG
2626 goto error;
2627 }
2628
1487a16a 2629 array->parent.id = BT_CTF_FIELD_TYPE_ID_ARRAY;
83509119 2630 bt_get(element_type);
273b65be
JG
2631 array->element_type = element_type;
2632 array->length = length;
59acd4f5 2633 bt_ctf_field_type_init(&array->parent, FALSE);
4e8304f7
PP
2634 BT_LOGD("Created array field type object: addr=%p, "
2635 "element-ft-addr=%p, length=%u",
2636 &array->parent, element_type, length);
273b65be
JG
2637 return &array->parent;
2638error:
2639 return NULL;
2640}
2641
b92ddaaa
JG
2642struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
2643 struct bt_ctf_field_type *type)
2644{
2645 struct bt_ctf_field_type *ret = NULL;
2646 struct bt_ctf_field_type_array *array;
2647
4e8304f7
PP
2648 if (!type) {
2649 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2650 goto end;
2651 }
2652
2653 if (type->id != BT_CTF_FIELD_TYPE_ID_ARRAY) {
2654 BT_LOGW("Invalid parameter: field type is not an array field type: "
2655 "addr=%p, ft-id=%s", type,
2656 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2657 goto end;
2658 }
2659
2660 array = container_of(type, struct bt_ctf_field_type_array, parent);
2661 ret = array->element_type;
83509119 2662 bt_get(ret);
b92ddaaa
JG
2663end:
2664 return ret;
2665}
2666
626e93aa
PP
2667BT_HIDDEN
2668int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
2669 struct bt_ctf_field_type *element_type)
2670{
2671 int ret = 0;
2672 struct bt_ctf_field_type_array *array;
2673
4e8304f7
PP
2674 if (!type) {
2675 BT_LOGW_STR("Invalid parameter: array field type is NULL.");
2676 ret = -1;
2677 goto end;
2678 }
2679
2680 if (!element_type) {
2681 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2682 ret = -1;
2683 goto end;
2684 }
2685
2686 if (type->id != BT_CTF_FIELD_TYPE_ID_ARRAY) {
2687 BT_LOGW("Invalid parameter: field type is not an array field type: "
2688 "addr=%p, ft-id=%s", type,
2689 bt_ctf_field_type_id_string(type->id));
626e93aa
PP
2690 ret = -1;
2691 goto end;
2692 }
2693
2694 array = container_of(type, struct bt_ctf_field_type_array, parent);
2695
2696 if (array->element_type) {
2697 BT_PUT(array->element_type);
2698 }
2699
2700 array->element_type = element_type;
2701 bt_get(array->element_type);
dfc1504d
PP
2702 BT_LOGV("Set array field type's element field type: array-ft-addr=%p, "
2703 "element-ft-addr=%p", type, element_type);
626e93aa
PP
2704
2705end:
2706 return ret;
2707}
2708
b92ddaaa
JG
2709int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
2710{
2711 int64_t ret;
2712 struct bt_ctf_field_type_array *array;
2713
4e8304f7
PP
2714 if (!type) {
2715 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2716 ret = (int64_t) -1;
2717 goto end;
2718 }
2719
2720 if (type->id != BT_CTF_FIELD_TYPE_ID_ARRAY) {
2721 BT_LOGW("Invalid parameter: field type is not an array field type: "
2722 "addr=%p, ft-id=%s", type,
2723 bt_ctf_field_type_id_string(type->id));
9ac68eb1 2724 ret = (int64_t) -1;
b92ddaaa
JG
2725 goto end;
2726 }
2727
2728 array = container_of(type, struct bt_ctf_field_type_array, parent);
2729 ret = (int64_t) array->length;
2730end:
2731 return ret;
2732}
2733
273b65be
JG
2734struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
2735 struct bt_ctf_field_type *element_type,
2736 const char *length_field_name)
2737{
2738 struct bt_ctf_field_type_sequence *sequence = NULL;
2739
4e8304f7
PP
2740 BT_LOGD("Creating sequence field type object: element-ft-addr=%p, "
2741 "length-field-name=\"%s\"", element_type, length_field_name);
2742
2743 if (!element_type) {
2744 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2745 goto error;
2746 }
2747
2748 if (bt_ctf_validate_identifier(length_field_name)) {
2749 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
2750 "length-field-name=\"%s\"", length_field_name);
273b65be
JG
2751 goto error;
2752 }
2753
2754 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
2755 if (!sequence) {
4e8304f7 2756 BT_LOGE_STR("Failed to allocate one sequence field type.");
273b65be
JG
2757 goto error;
2758 }
2759
1487a16a 2760 sequence->parent.id = BT_CTF_FIELD_TYPE_ID_SEQUENCE;
83509119 2761 bt_get(element_type);
273b65be
JG
2762 sequence->element_type = element_type;
2763 sequence->length_field_name = g_string_new(length_field_name);
59acd4f5 2764 bt_ctf_field_type_init(&sequence->parent, FALSE);
4e8304f7
PP
2765 BT_LOGD("Created sequence field type object: addr=%p, "
2766 "element-ft-addr=%p, length-field-name=\"%s\"",
2767 &sequence->parent, element_type, length_field_name);
273b65be
JG
2768 return &sequence->parent;
2769error:
2770 return NULL;
2771}
2772
b92ddaaa
JG
2773struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
2774 struct bt_ctf_field_type *type)
2775{
2776 struct bt_ctf_field_type *ret = NULL;
2777 struct bt_ctf_field_type_sequence *sequence;
2778
4e8304f7
PP
2779 if (!type) {
2780 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2781 goto end;
2782 }
2783
2784 if (type->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
2785 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2786 "addr=%p, ft-id=%s", type,
2787 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2788 goto end;
2789 }
2790
2791 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2792 parent);
2793 ret = sequence->element_type;
83509119 2794 bt_get(ret);
b92ddaaa
JG
2795end:
2796 return ret;
2797}
2798
626e93aa
PP
2799BT_HIDDEN
2800int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
2801 struct bt_ctf_field_type *element_type)
2802{
2803 int ret = 0;
2804 struct bt_ctf_field_type_sequence *sequence;
2805
4e8304f7
PP
2806 if (!type) {
2807 BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
626e93aa
PP
2808 ret = -1;
2809 goto end;
2810 }
2811
4e8304f7
PP
2812 if (!element_type) {
2813 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
2814 ret = -1;
2815 goto end;
2816 }
2817
2818 if (type->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
2819 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2820 "addr=%p, ft-id=%s", type,
2821 bt_ctf_field_type_id_string(type->id));
2822 ret = -1;
2823 goto end;
2824 }
626e93aa 2825
4e8304f7 2826 sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
626e93aa
PP
2827 if (sequence->element_type) {
2828 BT_PUT(sequence->element_type);
2829 }
2830
2831 sequence->element_type = element_type;
2832 bt_get(sequence->element_type);
dfc1504d
PP
2833 BT_LOGV("Set sequence field type's element field type: sequence-ft-addr=%p, "
2834 "element-ft-addr=%p", type, element_type);
626e93aa
PP
2835
2836end:
2837 return ret;
2838}
2839
b92ddaaa
JG
2840const char *bt_ctf_field_type_sequence_get_length_field_name(
2841 struct bt_ctf_field_type *type)
2842{
2843 const char *ret = NULL;
2844 struct bt_ctf_field_type_sequence *sequence;
2845
4e8304f7
PP
2846 if (!type) {
2847 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2848 goto end;
2849 }
2850
2851 if (type->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
2852 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
2853 "addr=%p, ft-id=%s", type,
2854 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2855 goto end;
2856 }
2857
2858 sequence = container_of(type, struct bt_ctf_field_type_sequence,
2859 parent);
2860 ret = sequence->length_field_name->str;
2861end:
2862 return ret;
2863}
2864
273b65be
JG
2865struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
2866{
2867 struct bt_ctf_field_type_string *string =
2868 g_new0(struct bt_ctf_field_type_string, 1);
2869
4e8304f7
PP
2870 BT_LOGD_STR("Creating string field type object.");
2871
273b65be 2872 if (!string) {
4e8304f7 2873 BT_LOGE_STR("Failed to allocate one string field type.");
273b65be
JG
2874 return NULL;
2875 }
2876
1487a16a 2877 string->parent.id = BT_CTF_FIELD_TYPE_ID_STRING;
59acd4f5 2878 bt_ctf_field_type_init(&string->parent, TRUE);
dc3fffef
PP
2879 string->encoding = BT_CTF_STRING_ENCODING_UTF8;
2880 string->parent.alignment = CHAR_BIT;
4e8304f7 2881 BT_LOGD("Created string field type object: addr=%p", &string->parent);
273b65be
JG
2882 return &string->parent;
2883}
2884
87b41f95 2885enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
b92ddaaa
JG
2886 struct bt_ctf_field_type *type)
2887{
2888 struct bt_ctf_field_type_string *string;
87b41f95 2889 enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
b92ddaaa 2890
4e8304f7
PP
2891 if (!type) {
2892 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2893 goto end;
2894 }
2895
2896 if (type->id != BT_CTF_FIELD_TYPE_ID_STRING) {
2897 BT_LOGW("Invalid parameter: field type is not a string field type: "
2898 "addr=%p, ft-id=%s", type,
2899 bt_ctf_field_type_id_string(type->id));
b92ddaaa
JG
2900 goto end;
2901 }
2902
2903 string = container_of(type, struct bt_ctf_field_type_string,
2904 parent);
dc3fffef 2905 ret = string->encoding;
b92ddaaa
JG
2906end:
2907 return ret;
2908}
2909
2910int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
87b41f95 2911 enum bt_ctf_string_encoding encoding)
273b65be
JG
2912{
2913 int ret = 0;
2914 struct bt_ctf_field_type_string *string;
2915
4e8304f7
PP
2916 if (!type) {
2917 BT_LOGW_STR("Invalid parameter: field type is NULL.");
2918 ret = -1;
2919 goto end;
2920 }
2921
2922 if (type->id != BT_CTF_FIELD_TYPE_ID_STRING) {
2923 BT_LOGW("Invalid parameter: field type is not a string field type: "
2924 "addr=%p, ft-id=%s", type,
2925 bt_ctf_field_type_id_string(type->id));
2926 ret = -1;
2927 goto end;
2928 }
2929
2930 if ((encoding != BT_CTF_STRING_ENCODING_UTF8 &&
2931 encoding != BT_CTF_STRING_ENCODING_ASCII)) {
2932 BT_LOGW("Invalid parameter: unknown string encoding: "
2933 "addr=%p, encoding=%d", type, encoding);
273b65be
JG
2934 ret = -1;
2935 goto end;
2936 }
2937
2938 string = container_of(type, struct bt_ctf_field_type_string, parent);
dc3fffef 2939 string->encoding = encoding;
dfc1504d
PP
2940 BT_LOGV("Set string field type's encoding: addr=%p, encoding=%s",
2941 type, bt_ctf_string_encoding_string(encoding));
273b65be
JG
2942end:
2943 return ret;
2944}
2945
b92ddaaa
JG
2946int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
2947{
2948 int ret;
1487a16a 2949 enum bt_ctf_field_type_id type_id;
b92ddaaa
JG
2950
2951 if (!type) {
4e8304f7 2952 BT_LOGW_STR("Invalid parameter: field type is NULL.");
b92ddaaa
JG
2953 ret = -1;
2954 goto end;
2955 }
2956
3ffba961 2957 if (type->frozen) {
dc3fffef 2958 ret = (int) type->alignment;
3ffba961
JG
2959 goto end;
2960 }
2961
2962 type_id = bt_ctf_field_type_get_type_id(type);
2963 switch (type_id) {
1487a16a 2964 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
3ffba961
JG
2965 {
2966 struct bt_ctf_field_type *element =
2967 bt_ctf_field_type_sequence_get_element_type(type);
2968
4e8304f7 2969 assert(element);
3ffba961 2970 ret = bt_ctf_field_type_get_alignment(element);
83509119 2971 bt_put(element);
3ffba961
JG
2972 break;
2973 }
1487a16a 2974 case BT_CTF_FIELD_TYPE_ID_ARRAY:
3ffba961
JG
2975 {
2976 struct bt_ctf_field_type *element =
2977 bt_ctf_field_type_array_get_element_type(type);
2978
4e8304f7 2979 assert(element);
3ffba961 2980 ret = bt_ctf_field_type_get_alignment(element);
83509119 2981 bt_put(element);
3ffba961
JG
2982 break;
2983 }
1487a16a 2984 case BT_CTF_FIELD_TYPE_ID_STRUCT:
3ffba961 2985 {
544d0515 2986 int64_t i, element_count;
3ffba961
JG
2987
2988 element_count = bt_ctf_field_type_structure_get_field_count(
2989 type);
4e8304f7 2990 assert(element_count >= 0);
3ffba961
JG
2991
2992 for (i = 0; i < element_count; i++) {
2993 struct bt_ctf_field_type *field;
2994 int field_alignment;
2995
9ac68eb1
PP
2996 ret = bt_ctf_field_type_structure_get_field_by_index(
2997 type, NULL, &field, i);
4e8304f7 2998 assert(ret == 0);
3ffba961
JG
2999 assert(field);
3000 field_alignment = bt_ctf_field_type_get_alignment(
3001 field);
83509119 3002 bt_put(field);
3ffba961
JG
3003 if (field_alignment < 0) {
3004 ret = field_alignment;
3005 goto end;
3006 }
3007
dc3fffef 3008 type->alignment = MAX(field_alignment, type->alignment);
3ffba961 3009 }
dc3fffef 3010 ret = (int) type->alignment;
3ffba961
JG
3011 break;
3012 }
1487a16a 3013 case BT_CTF_FIELD_TYPE_ID_UNKNOWN:
4e8304f7
PP
3014 BT_LOGW("Invalid parameter: unknown field type ID: "
3015 "addr=%p, ft-id=%d", type, type_id);
3ffba961
JG
3016 ret = -1;
3017 break;
3018 default:
dc3fffef 3019 ret = (int) type->alignment;
3ffba961
JG
3020 break;
3021 }
b92ddaaa
JG
3022end:
3023 return ret;
3024}
3025
9ad2f879
PP
3026static inline
3027int is_power_of_two(unsigned int value)
3028{
3029 return ((value & (value - 1)) == 0) && value > 0;
3030}
3031
273b65be
JG
3032int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
3033 unsigned int alignment)
3034{
3035 int ret = 0;
1487a16a 3036 enum bt_ctf_field_type_id type_id;
273b65be 3037
9ad2f879 3038 /* Alignment must be a power of two */
4e8304f7
PP
3039 if (!type) {
3040 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3041 ret = -1;
3042 goto end;
3043 }
3044
3045 if (type->frozen) {
3046 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3047 type);
3048 ret = -1;
3049 goto end;
3050 }
3051
3052 if (!is_power_of_two(alignment)) {
3053 BT_LOGW("Invalid parameter: alignment is not a power of two: "
3054 "addr=%p, align=%u", type, alignment);
273b65be
JG
3055 ret = -1;
3056 goto end;
3057 }
3058
6a43d732 3059 type_id = bt_ctf_field_type_get_type_id(type);
1487a16a 3060 if (type_id == BT_CTF_FIELD_TYPE_ID_UNKNOWN) {
4e8304f7
PP
3061 BT_LOGW("Invalid parameter: unknown field type ID: "
3062 "addr=%p, ft-id=%d", type, type_id);
6a43d732
JG
3063 ret = -1;
3064 goto end;
3065 }
3066
1487a16a 3067 if (type->id == BT_CTF_FIELD_TYPE_ID_STRING &&
4e8304f7
PP
3068 alignment != CHAR_BIT) {
3069 BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
3070 "addr=%p, align=%u", CHAR_BIT, type, alignment);
273b65be
JG
3071 ret = -1;
3072 goto end;
3073 }
3074
1487a16a 3075 if (type_id == BT_CTF_FIELD_TYPE_ID_VARIANT ||
4e8304f7
PP
3076 type_id == BT_CTF_FIELD_TYPE_ID_SEQUENCE ||
3077 type_id == BT_CTF_FIELD_TYPE_ID_ARRAY) {
6a43d732 3078 /* Setting an alignment on these types makes no sense */
4e8304f7
PP
3079 BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
3080 "addr=%p, ft-id=%s", type,
3081 bt_ctf_field_type_id_string(type->id));
6a43d732
JG
3082 ret = -1;
3083 goto end;
3084 }
3085
dc3fffef 3086 type->alignment = alignment;
273b65be 3087 ret = 0;
dfc1504d
PP
3088 BT_LOGV("Set field type's alignment: addr=%p, align=%u",
3089 type, alignment);
273b65be
JG
3090end:
3091 return ret;
3092}
3093
b92ddaaa
JG
3094enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
3095 struct bt_ctf_field_type *type)
3096{
3097 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
3098
3099 if (!type) {
4e8304f7 3100 BT_LOGW_STR("Invalid parameter: field type is NULL.");
b92ddaaa
JG
3101 goto end;
3102 }
3103
dc3fffef 3104 switch (type->id) {
1487a16a 3105 case BT_CTF_FIELD_TYPE_ID_INTEGER:
b92ddaaa
JG
3106 {
3107 struct bt_ctf_field_type_integer *integer = container_of(
3108 type, struct bt_ctf_field_type_integer, parent);
445c3471 3109 ret = integer->user_byte_order;
b92ddaaa
JG
3110 break;
3111 }
1487a16a 3112 case BT_CTF_FIELD_TYPE_ID_ENUM:
4b2da5f0
PP
3113 {
3114 struct bt_ctf_field_type_enumeration *enum_ft = container_of(
3115 type, struct bt_ctf_field_type_enumeration, parent);
3116 ret = bt_ctf_field_type_get_byte_order(enum_ft->container);
3117 break;
3118 }
1487a16a 3119 case BT_CTF_FIELD_TYPE_ID_FLOAT:
b92ddaaa
JG
3120 {
3121 struct bt_ctf_field_type_floating_point *floating_point =
3122 container_of(type,
3123 struct bt_ctf_field_type_floating_point,
3124 parent);
445c3471 3125 ret = floating_point->user_byte_order;
b92ddaaa
JG
3126 break;
3127 }
3128 default:
4e8304f7
PP
3129 BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
3130 "addr=%p, ft-id=%s", type,
3131 bt_ctf_field_type_id_string(type->id));
c35a1669
JG
3132 goto end;
3133 }
3134
445c3471
PP
3135 assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
3136 ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
3137 ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
3138 ret == BT_CTF_BYTE_ORDER_NETWORK);
3139
b92ddaaa
JG
3140end:
3141 return ret;
3142}
3143
273b65be
JG
3144int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
3145 enum bt_ctf_byte_order byte_order)
3146{
3147 int ret = 0;
273b65be 3148
4e8304f7
PP
3149 if (!type) {
3150 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3151 ret = -1;
3152 goto end;
3153 }
3154
3155 if (type->frozen) {
3156 BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
3157 type);
273b65be
JG
3158 ret = -1;
3159 goto end;
3160 }
3161
dc3fffef
PP
3162 if (byte_order != BT_CTF_BYTE_ORDER_NATIVE &&
3163 byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
3164 byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
3165 byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
4e8304f7
PP
3166 BT_LOGW("Invalid parameter: unknown byte order: "
3167 "addr=%p, bo=%s", type,
3168 bt_ctf_byte_order_string(byte_order));
273b65be
JG
3169 ret = -1;
3170 goto end;
3171 }
3172
dc3fffef
PP
3173 if (set_byte_order_funcs[type->id]) {
3174 set_byte_order_funcs[type->id](type, byte_order);
273b65be 3175 }
dfc1504d
PP
3176
3177 BT_LOGV("Set field type's byte order: addr=%p, bo=%s",
3178 type, bt_ctf_byte_order_string(byte_order));
3179
273b65be
JG
3180end:
3181 return ret;
3182}
3183
1487a16a 3184enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
b92ddaaa
JG
3185 struct bt_ctf_field_type *type)
3186{
3187 if (!type) {
4e8304f7 3188 BT_LOGW_STR("Invalid parameter: field type is NULL.");
1487a16a 3189 return BT_CTF_FIELD_TYPE_ID_UNKNOWN;
b92ddaaa
JG
3190 }
3191
dc3fffef 3192 return type->id;
b92ddaaa 3193}
2f2d8e05 3194
56db8d7a
PP
3195int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
3196{
1487a16a 3197 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_INTEGER;
56db8d7a
PP
3198}
3199
3200int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
3201{
1487a16a 3202 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_FLOAT;
56db8d7a
PP
3203}
3204
3205int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
3206{
1487a16a 3207 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_ENUM;
56db8d7a
PP
3208}
3209
3210int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
3211{
1487a16a 3212 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_STRING;
56db8d7a
PP
3213}
3214
3215int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
3216{
1487a16a 3217 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_STRUCT;
56db8d7a
PP
3218}
3219
3220int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
3221{
1487a16a 3222 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_ARRAY;
56db8d7a
PP
3223}
3224
3225int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
3226{
1487a16a 3227 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_SEQUENCE;
56db8d7a
PP
3228}
3229
3230int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
3231{
1487a16a 3232 return bt_ctf_field_type_get_type_id(type) == BT_CTF_FIELD_TYPE_ID_VARIANT;
56db8d7a
PP
3233}
3234
4e8304f7 3235/* Pre-2.0 CTF writer backward compatibility */
273b65be
JG
3236void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
3237{
83509119 3238 bt_get(type);
273b65be
JG
3239}
3240
4e8304f7 3241/* Pre-2.0 CTF writer backward compatibility */
273b65be
JG
3242void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
3243{
83509119 3244 bt_put(type);
273b65be
JG
3245}
3246
3247BT_HIDDEN
3248void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
3249{
4e8304f7 3250 if (!type || type->frozen) {
273b65be
JG
3251 return;
3252 }
3253
4e8304f7 3254 BT_LOGD("Freezing field type: addr=%p", type);
273b65be
JG
3255 type->freeze(type);
3256}
3257
3258BT_HIDDEN
b92ddaaa
JG
3259struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
3260 struct bt_ctf_field_type_variant *variant,
3261 int64_t tag_value)
273b65be
JG
3262{
3263 struct bt_ctf_field_type *type = NULL;
b92ddaaa
JG
3264 GQuark field_name_quark;
3265 gpointer index;
3266 struct structure_field *field_entry;
3267 struct range_overlap_query query = {
3268 .range_start._signed = tag_value,
3269 .range_end._signed = tag_value,
96e8f959
MD
3270 .mapping_name = 0,
3271 .overlaps = 0,
3272 };
273b65be 3273
b92ddaaa
JG
3274 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
3275 &query);
3276 if (!query.overlaps) {
273b65be
JG
3277 goto end;
3278 }
3279
b92ddaaa
JG
3280 field_name_quark = query.mapping_name;
3281 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
3282 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
273b65be
JG
3283 goto end;
3284 }
3285
e54fab7e 3286 field_entry = g_ptr_array_index(variant->fields, (size_t) index);
b92ddaaa 3287 type = field_entry->type;
273b65be
JG
3288end:
3289 return type;
3290}
3291
3292BT_HIDDEN
b92ddaaa 3293struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
273b65be 3294 struct bt_ctf_field_type_variant *variant,
b92ddaaa 3295 uint64_t tag_value)
273b65be
JG
3296{
3297 struct bt_ctf_field_type *type = NULL;
3298 GQuark field_name_quark;
3299 gpointer index;
3300 struct structure_field *field_entry;
b92ddaaa
JG
3301 struct range_overlap_query query = {
3302 .range_start._unsigned = tag_value,
3303 .range_end._unsigned = tag_value,
96e8f959
MD
3304 .mapping_name = 0,
3305 .overlaps = 0,
3306 };
273b65be 3307
b92ddaaa
JG
3308 g_ptr_array_foreach(variant->tag->entries,
3309 check_ranges_overlap_unsigned,
273b65be
JG
3310 &query);
3311 if (!query.overlaps) {
3312 goto end;
3313 }
3314
3315 field_name_quark = query.mapping_name;
3316 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
3317 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
3318 goto end;
3319 }
3320
3321 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
3322 type = field_entry->type;
3323end:
3324 return type;
3325}
3326
3327BT_HIDDEN
3328int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
3329 struct metadata_context *context)
3330{
3331 int ret;
3332
4e8304f7
PP
3333 assert(type);
3334 assert(context);
3335
3336 BT_LOGD("Serializing field type's metadata: "
3337 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be 3338
81e36fac
PP
3339 /* Make sure field type is valid before serializing it */
3340 ret = bt_ctf_field_type_validate(type);
81e36fac 3341 if (ret) {
4e8304f7 3342 BT_LOGW_STR("Cannot serialize field type's metadata: field type is invalid.");
81e36fac
PP
3343 goto end;
3344 }
3345
273b65be
JG
3346 ret = type->serialize(type, context);
3347end:
3348 return ret;
3349}
3350
24724933
JG
3351struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
3352{
3353 struct bt_ctf_field_type *copy = NULL;
3354
4e8304f7
PP
3355 BT_LOGD("Copying field type object: addr=%p", type);
3356
24724933 3357 if (!type) {
4e8304f7 3358 BT_LOGW_STR("Invalid parameter: field type is NULL.");
24724933
JG
3359 goto end;
3360 }
3361
dc3fffef 3362 copy = type_copy_funcs[type->id](type);
4e8304f7
PP
3363 if (!copy) {
3364 BT_LOGE_STR("Cannot copy field type.");
3365 goto end;
3366 }
3367
dc3fffef 3368 copy->alignment = type->alignment;
4e8304f7 3369 BT_LOGD("Copied field type object: copy-ft-addr=%p", copy);
24724933
JG
3370end:
3371 return copy;
3372}
3373
39a5e0db
JG
3374BT_HIDDEN
3375int bt_ctf_field_type_structure_get_field_name_index(
3376 struct bt_ctf_field_type *type, const char *name)
3377{
3378 int ret;
3379 size_t index;
3380 GQuark name_quark;
3381 struct bt_ctf_field_type_structure *structure;
3382
4e8304f7
PP
3383 if (!type) {
3384 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3385 ret = -1;
3386 goto end;
3387 }
3388
3389 if (!name) {
3390 BT_LOGW_STR("Invalid parameter: field name is NULL.");
3391 ret = -1;
3392 goto end;
3393 }
3394
3395 if (bt_ctf_field_type_get_type_id(type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
3396 BT_LOGW("Invalid parameter: field type is not a structure field type: "
3397 "addr=%p, ft-id=%s", type,
3398 bt_ctf_field_type_id_string(type->id));
39a5e0db
JG
3399 ret = -1;
3400 goto end;
3401 }
3402
3403 name_quark = g_quark_try_string(name);
3404 if (!name_quark) {
4e8304f7 3405 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
39a5e0db
JG
3406 ret = -1;
3407 goto end;
3408 }
3409
3410 structure = container_of(type, struct bt_ctf_field_type_structure,
3411 parent);
3412 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
3413 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
3414 ret = -1;
3415 goto end;
3416 }
3417 ret = (int) index;
3418end:
3419 return ret;
3420}
736133f1
JG
3421
3422BT_HIDDEN
3423int bt_ctf_field_type_variant_get_field_name_index(
3424 struct bt_ctf_field_type *type, const char *name)
3425{
3426 int ret;
3427 size_t index;
3428 GQuark name_quark;
3429 struct bt_ctf_field_type_variant *variant;
3430
4e8304f7
PP
3431 if (!type) {
3432 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3433 ret = -1;
3434 goto end;
3435 }
3436
3437 if (!name) {
3438 BT_LOGW_STR("Invalid parameter: field name is NULL.");
3439 ret = -1;
3440 goto end;
3441 }
3442
3443 if (bt_ctf_field_type_get_type_id(type) != BT_CTF_FIELD_TYPE_ID_VARIANT) {
3444 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3445 "addr=%p, ft-id=%s", type,
3446 bt_ctf_field_type_id_string(type->id));
736133f1
JG
3447 ret = -1;
3448 goto end;
3449 }
3450
3451 name_quark = g_quark_try_string(name);
3452 if (!name_quark) {
4e8304f7 3453 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
736133f1
JG
3454 ret = -1;
3455 goto end;
3456 }
3457
3458 variant = container_of(type, struct bt_ctf_field_type_variant,
3459 parent);
3460 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
3461 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
3462 ret = -1;
3463 goto end;
3464 }
3465 ret = (int) index;
3466end:
3467 return ret;
3468}
aa4e271c
JG
3469
3470BT_HIDDEN
3471int bt_ctf_field_type_sequence_set_length_field_path(
3472 struct bt_ctf_field_type *type,
3473 struct bt_ctf_field_path *path)
3474{
3475 int ret = 0;
3476 struct bt_ctf_field_type_sequence *sequence;
3477
4e8304f7
PP
3478 if (!type) {
3479 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3480 ret = -1;
3481 goto end;
3482 }
3483
3484 if (bt_ctf_field_type_get_type_id(type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
3485 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
3486 "addr=%p, ft-id=%s", type,
3487 bt_ctf_field_type_id_string(type->id));
aa4e271c
JG
3488 ret = -1;
3489 goto end;
3490 }
3491
3492 sequence = container_of(type, struct bt_ctf_field_type_sequence,
3493 parent);
b011f6b0
PP
3494 bt_get(path);
3495 BT_MOVE(sequence->length_field_path, path);
dfc1504d
PP
3496 BT_LOGV("Set sequence field type's length field path: ft-addr=%p, "
3497 "field-path-addr=%p", type, path);
aa4e271c
JG
3498end:
3499 return ret;
3500}
4a1e8671
JG
3501
3502BT_HIDDEN
3503int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
3504 struct bt_ctf_field_path *path)
3505{
3506 int ret = 0;
3507 struct bt_ctf_field_type_variant *variant;
3508
4e8304f7
PP
3509 if (!type) {
3510 BT_LOGW_STR("Invalid parameter: field type is NULL.");
3511 ret = -1;
3512 goto end;
3513 }
3514
3515 if (bt_ctf_field_type_get_type_id(type) != BT_CTF_FIELD_TYPE_ID_VARIANT) {
3516 BT_LOGW("Invalid parameter: field type is not a variant field type: "
3517 "addr=%p, ft-id=%s", type,
3518 bt_ctf_field_type_id_string(type->id));
4a1e8671
JG
3519 ret = -1;
3520 goto end;
3521 }
3522
3523 variant = container_of(type, struct bt_ctf_field_type_variant,
3524 parent);
b011f6b0
PP
3525 bt_get(path);
3526 BT_MOVE(variant->tag_field_path, path);
dfc1504d
PP
3527 BT_LOGV("Set variant field type's tag field path: ft-addr=%p, "
3528 "field-path-addr=%p", type, path);
4a1e8671
JG
3529end:
3530 return ret;
3531}
3f39933a
JG
3532
3533BT_HIDDEN
4b5fcb78 3534int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
3f39933a
JG
3535 struct bt_ctf_field_type *tag)
3536{
3537 int ret = 0;
3538 struct bt_ctf_field_type_variant *variant;
3539
4e8304f7
PP
3540 if (!type) {
3541 BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
3f39933a
JG
3542 ret = -1;
3543 goto end;
3544 }
3545
4e8304f7
PP
3546 if (!tag) {
3547 BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
3548 ret = -1;
3549 goto end;
3f39933a 3550 }
5cec03e4 3551
4e8304f7
PP
3552 if (bt_ctf_field_type_get_type_id(tag) != BT_CTF_FIELD_TYPE_ID_ENUM) {
3553 BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
3554 "addr=%p, ft-id=%s", type,
3555 bt_ctf_field_type_id_string(type->id));
5cec03e4
JG
3556 ret = -1;
3557 goto end;
3558 }
3559
3560 variant = container_of(type, struct bt_ctf_field_type_variant,
3561 parent);
4e8304f7
PP
3562 bt_get(tag);
3563 if (variant->tag) {
3564 bt_put(&variant->tag->parent);
5cec03e4 3565 }
4e8304f7
PP
3566 variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
3567 parent);
dfc1504d
PP
3568 BT_LOGV("Set variant field type's tag field type: variant-ft-addr=%p, "
3569 "tag-ft-addr=%p", type, tag);
5cec03e4
JG
3570end:
3571 return ret;
3572}
3573
273b65be 3574static
de3dd40e 3575void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
273b65be 3576{
de3dd40e
PP
3577 struct bt_ctf_field_type_integer *integer =
3578 (struct bt_ctf_field_type_integer *) type;
273b65be 3579
de3dd40e 3580 if (!type) {
273b65be
JG
3581 return;
3582 }
3583
4e8304f7 3584 BT_LOGD("Destroying integer field type object: addr=%p", type);
83509119 3585 bt_put(integer->mapped_clock);
273b65be
JG
3586 g_free(integer);
3587}
3588
3589static
de3dd40e 3590void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
273b65be 3591{
de3dd40e
PP
3592 struct bt_ctf_field_type_enumeration *enumeration =
3593 (struct bt_ctf_field_type_enumeration *) type;
273b65be 3594
de3dd40e 3595 if (!type) {
273b65be
JG
3596 return;
3597 }
3598
4e8304f7 3599 BT_LOGD("Destroying enumeration field type object: addr=%p", type);
273b65be 3600 g_ptr_array_free(enumeration->entries, TRUE);
83509119 3601 bt_put(enumeration->container);
273b65be
JG
3602 g_free(enumeration);
3603}
3604
3605static
de3dd40e 3606void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
273b65be 3607{
de3dd40e
PP
3608 struct bt_ctf_field_type_floating_point *floating_point =
3609 (struct bt_ctf_field_type_floating_point *) type;
273b65be 3610
de3dd40e 3611 if (!type) {
273b65be
JG
3612 return;
3613 }
3614
4e8304f7 3615 BT_LOGD("Destroying floating point number field type object: addr=%p", type);
273b65be
JG
3616 g_free(floating_point);
3617}
3618
3619static
de3dd40e 3620void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
273b65be 3621{
de3dd40e
PP
3622 struct bt_ctf_field_type_structure *structure =
3623 (struct bt_ctf_field_type_structure *) type;
273b65be 3624
de3dd40e 3625 if (!type) {
273b65be
JG
3626 return;
3627 }
3628
4e8304f7 3629 BT_LOGD("Destroying structure field type object: addr=%p", type);
273b65be
JG
3630 g_ptr_array_free(structure->fields, TRUE);
3631 g_hash_table_destroy(structure->field_name_to_index);
3632 g_free(structure);
3633}
3634
3635static
de3dd40e 3636void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
273b65be 3637{
de3dd40e
PP
3638 struct bt_ctf_field_type_variant *variant =
3639 (struct bt_ctf_field_type_variant *) type;
273b65be 3640
de3dd40e 3641 if (!type) {
273b65be
JG
3642 return;
3643 }
3644
4e8304f7 3645 BT_LOGD("Destroying variant field type object: addr=%p", type);
273b65be
JG
3646 g_ptr_array_free(variant->fields, TRUE);
3647 g_hash_table_destroy(variant->field_name_to_index);
3648 g_string_free(variant->tag_name, TRUE);
83509119 3649 bt_put(&variant->tag->parent);
b011f6b0 3650 BT_PUT(variant->tag_field_path);
273b65be
JG
3651 g_free(variant);
3652}
3653
3654static
de3dd40e 3655void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
273b65be 3656{
de3dd40e
PP
3657 struct bt_ctf_field_type_array *array =
3658 (struct bt_ctf_field_type_array *) type;
273b65be 3659
de3dd40e 3660 if (!type) {
273b65be
JG
3661 return;
3662 }
3663
4e8304f7 3664 BT_LOGD("Destroying array field type object: addr=%p", type);
83509119 3665 bt_put(array->element_type);
273b65be
JG
3666 g_free(array);
3667}
3668
3669static
de3dd40e 3670void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
273b65be 3671{
de3dd40e
PP
3672 struct bt_ctf_field_type_sequence *sequence =
3673 (struct bt_ctf_field_type_sequence *) type;
273b65be 3674
de3dd40e 3675 if (!type) {
273b65be
JG
3676 return;
3677 }
3678
4e8304f7 3679 BT_LOGD("Destroying sequence field type object: addr=%p", type);
83509119 3680 bt_put(sequence->element_type);
273b65be 3681 g_string_free(sequence->length_field_name, TRUE);
b011f6b0 3682 BT_PUT(sequence->length_field_path);
273b65be
JG
3683 g_free(sequence);
3684}
3685
3686static
de3dd40e 3687void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
273b65be 3688{
de3dd40e
PP
3689 struct bt_ctf_field_type_string *string =
3690 (struct bt_ctf_field_type_string *) type;
273b65be 3691
de3dd40e 3692 if (!type) {
273b65be
JG
3693 return;
3694 }
3695
4e8304f7 3696 BT_LOGD("Destroying string field type object: addr=%p", type);
273b65be
JG
3697 g_free(string);
3698}
3699
3700static
3701void generic_field_type_freeze(struct bt_ctf_field_type *type)
3702{
3703 type->frozen = 1;
3704}
3705
586411e5
PP
3706static
3707void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
3708{
3709 struct bt_ctf_field_type_integer *integer_type = container_of(
3710 type, struct bt_ctf_field_type_integer, parent);
3711
4e8304f7
PP
3712 BT_LOGD("Freezing integer field type object: addr=%p", type);
3713
586411e5 3714 if (integer_type->mapped_clock) {
ac0c6bdd 3715 bt_ctf_clock_class_freeze(integer_type->mapped_clock);
586411e5
PP
3716 }
3717
3718 generic_field_type_freeze(type);
3719}
3720
273b65be
JG
3721static
3722void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
3723{
3724 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
3725 type, struct bt_ctf_field_type_enumeration, parent);
3726
4e8304f7 3727 BT_LOGD("Freezing enumeration field type object: addr=%p", type);
d49e1284 3728 set_enumeration_range_overlap(type);
273b65be 3729 generic_field_type_freeze(type);
225f3384
PP
3730 BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
3731 enumeration_type->container);
273b65be
JG
3732 bt_ctf_field_type_freeze(enumeration_type->container);
3733}
3734
3735static
3736void freeze_structure_field(struct structure_field *field)
3737{
225f3384
PP
3738 BT_LOGD("Freezing structure/variant field type field: field-addr=%p, "
3739 "field-ft-addr=%p, field-name=\"%s\"", field,
3740 field->type, g_quark_to_string(field->name));
273b65be
JG
3741 bt_ctf_field_type_freeze(field->type);
3742}
3743
3744static
3745void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
3746{
3747 struct bt_ctf_field_type_structure *structure_type = container_of(
3748 type, struct bt_ctf_field_type_structure, parent);
3749
3ffba961 3750 /* Cache the alignment */
4e8304f7 3751 BT_LOGD("Freezing structure field type object: addr=%p", type);
dc3fffef 3752 type->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 3753 generic_field_type_freeze(type);
3ffba961
JG
3754 g_ptr_array_foreach(structure_type->fields,
3755 (GFunc) freeze_structure_field, NULL);
273b65be
JG
3756}
3757
3758static
3759void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
3760{
3761 struct bt_ctf_field_type_variant *variant_type = container_of(
3762 type, struct bt_ctf_field_type_variant, parent);
3763
4e8304f7 3764 BT_LOGD("Freezing variant field type object: addr=%p", type);
273b65be 3765 generic_field_type_freeze(type);
3ffba961
JG
3766 g_ptr_array_foreach(variant_type->fields,
3767 (GFunc) freeze_structure_field, NULL);
273b65be
JG
3768}
3769
3770static
3771void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
3772{
3773 struct bt_ctf_field_type_array *array_type = container_of(
3774 type, struct bt_ctf_field_type_array, parent);
3775
3ffba961 3776 /* Cache the alignment */
4e8304f7 3777 BT_LOGD("Freezing array field type object: addr=%p", type);
dc3fffef 3778 type->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 3779 generic_field_type_freeze(type);
225f3384
PP
3780 BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
3781 array_type->element_type);
273b65be
JG
3782 bt_ctf_field_type_freeze(array_type->element_type);
3783}
3784
3785static
3786void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
3787{
3788 struct bt_ctf_field_type_sequence *sequence_type = container_of(
3789 type, struct bt_ctf_field_type_sequence, parent);
3790
3ffba961 3791 /* Cache the alignment */
4e8304f7 3792 BT_LOGD("Freezing sequence field type object: addr=%p", type);
dc3fffef 3793 type->alignment = bt_ctf_field_type_get_alignment(type);
273b65be 3794 generic_field_type_freeze(type);
225f3384
PP
3795 BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
3796 sequence_type->element_type);
273b65be
JG
3797 bt_ctf_field_type_freeze(sequence_type->element_type);
3798}
3799
3800static
87b41f95 3801const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
273b65be
JG
3802{
3803 const char *encoding_string;
3804
3805 switch (encoding) {
87b41f95 3806 case BT_CTF_STRING_ENCODING_NONE:
273b65be
JG
3807 encoding_string = "none";
3808 break;
87b41f95 3809 case BT_CTF_STRING_ENCODING_ASCII:
273b65be
JG
3810 encoding_string = "ASCII";
3811 break;
87b41f95 3812 case BT_CTF_STRING_ENCODING_UTF8:
273b65be
JG
3813 encoding_string = "UTF8";
3814 break;
3815 default:
3816 encoding_string = "unknown";
3817 break;
3818 }
3819
3820 return encoding_string;
3821}
3822
3823static
3824const char *get_integer_base_string(enum bt_ctf_integer_base base)
3825{
3826 const char *base_string;
3827
3828 switch (base) {
3829 case BT_CTF_INTEGER_BASE_DECIMAL:
3830 base_string = "decimal";
3831 break;
3832 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
3833 base_string = "hexadecimal";
3834 break;
3835 case BT_CTF_INTEGER_BASE_OCTAL:
3836 base_string = "octal";
3837 break;
3838 case BT_CTF_INTEGER_BASE_BINARY:
3839 base_string = "binary";
3840 break;
3841 default:
3842 base_string = "unknown";
3843 break;
3844 }
3845
3846 return base_string;
3847}
3848
3849static
3850int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
3851 struct metadata_context *context)
3852{
3853 struct bt_ctf_field_type_integer *integer = container_of(type,
3854 struct bt_ctf_field_type_integer, parent);
6cfb906f 3855 int ret = 0;
273b65be 3856
4e8304f7
PP
3857 BT_LOGD("Serializing integer field type's metadata: "
3858 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be 3859 g_string_append_printf(context->string,
dc3fffef
PP
3860 "integer { size = %u; align = %u; signed = %s; encoding = %s; base = %s; byte_order = %s",
3861 integer->size, type->alignment,
3862 (integer->is_signed ? "true" : "false"),
3863 get_encoding_string(integer->encoding),
3864 get_integer_base_string(integer->base),
3865 get_byte_order_string(integer->user_byte_order));
6cfb906f 3866 if (integer->mapped_clock) {
ac0c6bdd 3867 const char *clock_name = bt_ctf_clock_class_get_name(
6cfb906f
JG
3868 integer->mapped_clock);
3869
4e8304f7 3870 assert(clock_name);
6cfb906f 3871 g_string_append_printf(context->string,
4ebdec03 3872 "; map = clock.%s.value", clock_name);
6cfb906f
JG
3873 }
3874
3875 g_string_append(context->string, "; }");
6cfb906f 3876 return ret;
273b65be
JG
3877}
3878
3879static
3880int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
3881 struct metadata_context *context)
3882{
3883 size_t entry;
9ce21c30 3884 int ret;
273b65be
JG
3885 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
3886 struct bt_ctf_field_type_enumeration, parent);
b92ddaaa
JG
3887 struct bt_ctf_field_type *container_type;
3888 int container_signed;
273b65be 3889
4e8304f7
PP
3890 BT_LOGD("Serializing enumeration field type's metadata: "
3891 "ft-addr=%p, metadata-context-addr=%p", type, context);
b92ddaaa 3892 container_type = bt_ctf_field_type_enumeration_get_container_type(type);
4e8304f7 3893 assert(container_type);
b92ddaaa 3894 container_signed = bt_ctf_field_type_integer_get_signed(container_type);
4e8304f7 3895 assert(container_signed >= 0);
273b65be
JG
3896 g_string_append(context->string, "enum : ");
3897 ret = bt_ctf_field_type_serialize(enumeration->container, context);
3898 if (ret) {
4e8304f7
PP
3899 BT_LOGW("Cannot serialize enumeration field type's container field type's metadata: "
3900 "container-ft-addr=%p", enumeration->container);
3901 goto end;
273b65be
JG
3902 }
3903
3904 g_string_append(context->string, " { ");
3905 for (entry = 0; entry < enumeration->entries->len; entry++) {
3906 struct enumeration_mapping *mapping =
3907 enumeration->entries->pdata[entry];
3908
b92ddaaa
JG
3909 if (container_signed) {
3910 if (mapping->range_start._signed ==
3911 mapping->range_end._signed) {
3912 g_string_append_printf(context->string,
3913 "\"%s\" = %" PRId64,
3914 g_quark_to_string(mapping->string),
3915 mapping->range_start._signed);
3916 } else {
3917 g_string_append_printf(context->string,
3918 "\"%s\" = %" PRId64 " ... %" PRId64,
3919 g_quark_to_string(mapping->string),
3920 mapping->range_start._signed,
3921 mapping->range_end._signed);
3922 }
273b65be 3923 } else {
b92ddaaa
JG
3924 if (mapping->range_start._unsigned ==
3925 mapping->range_end._unsigned) {
3926 g_string_append_printf(context->string,
3927 "\"%s\" = %" PRIu64,
3928 g_quark_to_string(mapping->string),
3929 mapping->range_start._unsigned);
3930 } else {
3931 g_string_append_printf(context->string,
3932 "\"%s\" = %" PRIu64 " ... %" PRIu64,
3933 g_quark_to_string(mapping->string),
3934 mapping->range_start._unsigned,
3935 mapping->range_end._unsigned);
3936 }
273b65be
JG
3937 }
3938
3939 g_string_append(context->string,
3940 ((entry != (enumeration->entries->len - 1)) ?
3941 ", " : " }"));
3942 }
3943
3944 if (context->field_name->len) {
3945 g_string_append_printf(context->string, " %s",
3946 context->field_name->str);
3947 g_string_assign(context->field_name, "");
3948 }
3949end:
4e8304f7 3950 bt_put(container_type);
273b65be
JG
3951 return ret;
3952}
3953
3954static
3955int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
3956 struct metadata_context *context)
3957{
3958 struct bt_ctf_field_type_floating_point *floating_point = container_of(
3959 type, struct bt_ctf_field_type_floating_point, parent);
3960
4e8304f7
PP
3961 BT_LOGD("Serializing floating point number field type's metadata: "
3962 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be 3963 g_string_append_printf(context->string,
dc3fffef
PP
3964 "floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
3965 floating_point->exp_dig,
3966 floating_point->mant_dig,
3967 get_byte_order_string(floating_point->user_byte_order),
3968 type->alignment);
273b65be
JG
3969 return 0;
3970}
3971
3972static
3973int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
3974 struct metadata_context *context)
3975{
3976 size_t i;
3977 unsigned int indent;
4e8304f7 3978 int64_t ret = 0;
273b65be
JG
3979 struct bt_ctf_field_type_structure *structure = container_of(type,
3980 struct bt_ctf_field_type_structure, parent);
3981 GString *structure_field_name = context->field_name;
3982
4e8304f7
PP
3983 BT_LOGD("Serializing structure field type's metadata: "
3984 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be
JG
3985 context->field_name = g_string_new("");
3986
3987 context->current_indentation_level++;
3988 g_string_append(context->string, "struct {\n");
3989
3990 for (i = 0; i < structure->fields->len; i++) {
dfc1504d
PP
3991 struct structure_field *field = structure->fields->pdata[i];
3992
3993 BT_LOGV("Serializing structure field type's field metadata: "
3994 "index=%" PRId64 ", "
3995 "field-ft-addr=%p, field-name=\"%s\"",
3996 i, field, g_quark_to_string(field->name));
273b65be
JG
3997
3998 for (indent = 0; indent < context->current_indentation_level;
3999 indent++) {
4000 g_string_append_c(context->string, '\t');
4001 }
4002
273b65be
JG
4003 g_string_assign(context->field_name,
4004 g_quark_to_string(field->name));
4005 ret = bt_ctf_field_type_serialize(field->type, context);
4006 if (ret) {
4e8304f7
PP
4007 BT_LOGW("Cannot serialize structure field type's field's metadata: "
4008 "index=%" PRId64 ", "
4009 "field-ft-addr=%p, field-name=\"%s\"",
4010 i, field->type,
4011 g_quark_to_string(field->name));
273b65be
JG
4012 goto end;
4013 }
4014
4015 if (context->field_name->len) {
4016 g_string_append_printf(context->string, " %s",
4017 context->field_name->str);
4018 }
4019 g_string_append(context->string, ";\n");
4020 }
4021
4022 context->current_indentation_level--;
4023 for (indent = 0; indent < context->current_indentation_level;
4024 indent++) {
4025 g_string_append_c(context->string, '\t');
4026 }
4027
dc3fffef
PP
4028 g_string_append_printf(context->string, "} align(%u)",
4029 type->alignment);
273b65be
JG
4030end:
4031 g_string_free(context->field_name, TRUE);
4032 context->field_name = structure_field_name;
4033 return ret;
4034}
4035
4036static
4037int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
4038 struct metadata_context *context)
4039{
4040 size_t i;
4041 unsigned int indent;
4042 int ret = 0;
4043 struct bt_ctf_field_type_variant *variant = container_of(
4044 type, struct bt_ctf_field_type_variant, parent);
4045 GString *variant_field_name = context->field_name;
4046
4e8304f7
PP
4047 BT_LOGD("Serializing variant field type's metadata: "
4048 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be 4049 context->field_name = g_string_new("");
6964b7fd
JG
4050 if (variant->tag_name->len > 0) {
4051 g_string_append_printf(context->string,
4052 "variant <%s> {\n", variant->tag_name->str);
4053 } else {
4054 g_string_append(context->string, "variant {\n");
4055 }
4056
273b65be
JG
4057 context->current_indentation_level++;
4058 for (i = 0; i < variant->fields->len; i++) {
4059 struct structure_field *field = variant->fields->pdata[i];
4060
dfc1504d
PP
4061 BT_LOGV("Serializing variant field type's field metadata: "
4062 "index=%" PRId64 ", "
4063 "field-ft-addr=%p, field-name=\"%s\"",
4064 i, field, g_quark_to_string(field->name));
4065
273b65be
JG
4066 g_string_assign(context->field_name,
4067 g_quark_to_string(field->name));
4068 for (indent = 0; indent < context->current_indentation_level;
4069 indent++) {
4070 g_string_append_c(context->string, '\t');
4071 }
4072
4073 g_string_assign(context->field_name,
4074 g_quark_to_string(field->name));
4075 ret = bt_ctf_field_type_serialize(field->type, context);
4076 if (ret) {
4e8304f7
PP
4077 BT_LOGW("Cannot serialize variant field type's field's metadata: "
4078 "index=%" PRId64 ", "
4079 "field-ft-addr=%p, field-name=\"%s\"",
4080 i, field->type,
4081 g_quark_to_string(field->name));
273b65be
JG
4082 goto end;
4083 }
4084
4085 if (context->field_name->len) {
4086 g_string_append_printf(context->string, " %s;",
4087 context->field_name->str);
4088 }
4089
4090 g_string_append_c(context->string, '\n');
4091 }
4092
4093 context->current_indentation_level--;
4094 for (indent = 0; indent < context->current_indentation_level;
4095 indent++) {
4096 g_string_append_c(context->string, '\t');
4097 }
4098
4099 g_string_append(context->string, "}");
4100end:
4101 g_string_free(context->field_name, TRUE);
4102 context->field_name = variant_field_name;
4103 return ret;
4104}
4105
4106static
4107int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
4108 struct metadata_context *context)
4109{
4110 int ret = 0;
4111 struct bt_ctf_field_type_array *array = container_of(type,
4112 struct bt_ctf_field_type_array, parent);
4113
4e8304f7
PP
4114 BT_LOGD("Serializing array field type's metadata: "
4115 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be
JG
4116 ret = bt_ctf_field_type_serialize(array->element_type, context);
4117 if (ret) {
4e8304f7
PP
4118 BT_LOGW("Cannot serialize array field type's element field type's metadata: "
4119 "element-ft-addr=%p", array->element_type);
273b65be
JG
4120 goto end;
4121 }
4122
4123 if (context->field_name->len) {
4124 g_string_append_printf(context->string, " %s[%u]",
4125 context->field_name->str, array->length);
4126 g_string_assign(context->field_name, "");
4127 } else {
4128 g_string_append_printf(context->string, "[%u]", array->length);
4129 }
4130end:
4131 return ret;
4132}
4133
4134static
4135int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
4136 struct metadata_context *context)
4137{
4138 int ret = 0;
4139 struct bt_ctf_field_type_sequence *sequence = container_of(
4140 type, struct bt_ctf_field_type_sequence, parent);
4141
4e8304f7
PP
4142 BT_LOGD("Serializing sequence field type's metadata: "
4143 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be
JG
4144 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
4145 if (ret) {
4e8304f7
PP
4146 BT_LOGW("Cannot serialize sequence field type's element field type's metadata: "
4147 "element-ft-addr=%p", sequence->element_type);
273b65be
JG
4148 goto end;
4149 }
4150
4151 if (context->field_name->len) {
4152 g_string_append_printf(context->string, " %s[%s]",
4153 context->field_name->str,
4154 sequence->length_field_name->str);
4155 g_string_assign(context->field_name, "");
4156 } else {
4157 g_string_append_printf(context->string, "[%s]",
4158 sequence->length_field_name->str);
4159 }
4160end:
4161 return ret;
4162}
4163
4164static
4165int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
4166 struct metadata_context *context)
4167{
4168 struct bt_ctf_field_type_string *string = container_of(
4169 type, struct bt_ctf_field_type_string, parent);
4170
4e8304f7
PP
4171 BT_LOGD("Serializing string field type's metadata: "
4172 "ft-addr=%p, metadata-context-addr=%p", type, context);
273b65be
JG
4173 g_string_append_printf(context->string,
4174 "string { encoding = %s; }",
dc3fffef 4175 get_encoding_string(string->encoding));
273b65be
JG
4176 return 0;
4177}
4178
4179static
4180void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
dc3fffef 4181 enum bt_ctf_byte_order byte_order)
273b65be
JG
4182{
4183 struct bt_ctf_field_type_integer *integer_type = container_of(type,
4184 struct bt_ctf_field_type_integer, parent);
4185
dc3fffef 4186 integer_type->user_byte_order = byte_order;
c35a1669
JG
4187}
4188
4189static
4190void bt_ctf_field_type_enumeration_set_byte_order(
dc3fffef 4191 struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order)
c35a1669
JG
4192{
4193 struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
4194 struct bt_ctf_field_type_enumeration, parent);
4195
4196 /* Safe to assume that container is an integer */
4197 bt_ctf_field_type_integer_set_byte_order(enum_type->container,
dc3fffef 4198 byte_order);
273b65be
JG
4199}
4200
4201static
4202void bt_ctf_field_type_floating_point_set_byte_order(
dc3fffef 4203 struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order)
273b65be
JG
4204{
4205 struct bt_ctf_field_type_floating_point *floating_point_type =
4206 container_of(type, struct bt_ctf_field_type_floating_point,
4207 parent);
4208
dc3fffef 4209 floating_point_type->user_byte_order = byte_order;
c35a1669
JG
4210}
4211
4212static
4213void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
dc3fffef 4214 enum bt_ctf_byte_order byte_order)
c35a1669
JG
4215{
4216 int i;
4217 struct bt_ctf_field_type_structure *structure_type =
4218 container_of(type, struct bt_ctf_field_type_structure,
4219 parent);
4220
4221 for (i = 0; i < structure_type->fields->len; i++) {
4222 struct structure_field *field = g_ptr_array_index(
4223 structure_type->fields, i);
4224 struct bt_ctf_field_type *field_type = field->type;
4225
dc3fffef
PP
4226 if (set_byte_order_funcs[field_type->id]) {
4227 set_byte_order_funcs[field_type->id](
4228 field_type, byte_order);
c35a1669
JG
4229 }
4230 }
4231}
4232
4233static
4234void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
dc3fffef 4235 enum bt_ctf_byte_order byte_order)
c35a1669
JG
4236{
4237 int i;
4238 struct bt_ctf_field_type_variant *variant_type =
4239 container_of(type, struct bt_ctf_field_type_variant,
4240 parent);
4241
4242 for (i = 0; i < variant_type->fields->len; i++) {
4243 struct structure_field *field = g_ptr_array_index(
4244 variant_type->fields, i);
4245 struct bt_ctf_field_type *field_type = field->type;
4246
dc3fffef
PP
4247 if (set_byte_order_funcs[field_type->id]) {
4248 set_byte_order_funcs[field_type->id](
4249 field_type, byte_order);
c35a1669
JG
4250 }
4251 }
4252}
4253
4254static
4255void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
dc3fffef 4256 enum bt_ctf_byte_order byte_order)
c35a1669
JG
4257{
4258 struct bt_ctf_field_type_array *array_type =
4259 container_of(type, struct bt_ctf_field_type_array,
4260 parent);
4261
dc3fffef
PP
4262 if (set_byte_order_funcs[array_type->element_type->id]) {
4263 set_byte_order_funcs[array_type->element_type->id](
4264 array_type->element_type, byte_order);
c35a1669
JG
4265 }
4266}
4267
4268static
4269void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
dc3fffef 4270 enum bt_ctf_byte_order byte_order)
c35a1669
JG
4271{
4272 struct bt_ctf_field_type_sequence *sequence_type =
4273 container_of(type, struct bt_ctf_field_type_sequence,
4274 parent);
4275
4276 if (set_byte_order_funcs[
dc3fffef 4277 sequence_type->element_type->id]) {
c35a1669 4278 set_byte_order_funcs[
dc3fffef
PP
4279 sequence_type->element_type->id](
4280 sequence_type->element_type, byte_order);
c35a1669 4281 }
273b65be 4282}
24724933
JG
4283
4284static
4285struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
4286 struct bt_ctf_field_type *type)
4287{
4288 struct bt_ctf_field_type *copy;
4289 struct bt_ctf_field_type_integer *integer, *copy_integer;
4290
4e8304f7 4291 BT_LOGD("Copying integer field type's: addr=%p", type);
24724933 4292 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
dc3fffef 4293 copy = bt_ctf_field_type_integer_create(integer->size);
24724933 4294 if (!copy) {
4e8304f7 4295 BT_LOGE_STR("Cannot create integer field type.");
24724933
JG
4296 goto end;
4297 }
4298
4299 copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
4300 parent);
dc3fffef 4301 copy_integer->mapped_clock = bt_get(integer->mapped_clock);
445c3471 4302 copy_integer->user_byte_order = integer->user_byte_order;
dc3fffef
PP
4303 copy_integer->is_signed = integer->is_signed;
4304 copy_integer->size = integer->size;
4305 copy_integer->base = integer->base;
4306 copy_integer->encoding = integer->encoding;
4e8304f7
PP
4307 BT_LOGD("Copied integer field type: original-ft-addr=%p, copy-ft-addr=%p",
4308 type, copy);
445c3471 4309
24724933
JG
4310end:
4311 return copy;
4312}
4313
4314static
4315struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
4316 struct bt_ctf_field_type *type)
4317{
4318 size_t i;
4319 struct bt_ctf_field_type *copy = NULL, *copy_container;
4320 struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
4321
4e8304f7 4322 BT_LOGD("Copying enumeration field type's: addr=%p", type);
24724933
JG
4323 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
4324 parent);
4325
4326 /* Copy the source enumeration's container */
4327 copy_container = bt_ctf_field_type_copy(enumeration->container);
4328 if (!copy_container) {
4e8304f7 4329 BT_LOGE_STR("Cannot copy enumeration field type's container field type.");
24724933
JG
4330 goto end;
4331 }
4332
4333 copy = bt_ctf_field_type_enumeration_create(copy_container);
4334 if (!copy) {
4e8304f7 4335 BT_LOGE_STR("Cannot create enumeration field type.");
24724933
JG
4336 goto end;
4337 }
4338 copy_enumeration = container_of(copy,
4339 struct bt_ctf_field_type_enumeration, parent);
4340
4341 /* Copy all enumaration entries */
4342 for (i = 0; i < enumeration->entries->len; i++) {
4343 struct enumeration_mapping *mapping = g_ptr_array_index(
4344 enumeration->entries, i);
96e8f959 4345 struct enumeration_mapping *copy_mapping = g_new0(
24724933
JG
4346 struct enumeration_mapping, 1);
4347
4348 if (!copy_mapping) {
4e8304f7 4349 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
24724933
JG
4350 goto error;
4351 }
4352
4353 *copy_mapping = *mapping;
4354 g_ptr_array_add(copy_enumeration->entries, copy_mapping);
4355 }
4356
4e8304f7
PP
4357 BT_LOGD("Copied enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
4358 type, copy);
4359
24724933 4360end:
83509119 4361 bt_put(copy_container);
24724933
JG
4362 return copy;
4363error:
83509119
JG
4364 bt_put(copy_container);
4365 BT_PUT(copy);
4366 return copy;
24724933
JG
4367}
4368
4369static
4370struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
4371 struct bt_ctf_field_type *type)
4372{
4373 struct bt_ctf_field_type *copy;
4374 struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
4375
4e8304f7 4376 BT_LOGD("Copying floating point number field type's: addr=%p", type);
24724933
JG
4377 floating_point = container_of(type,
4378 struct bt_ctf_field_type_floating_point, parent);
4379 copy = bt_ctf_field_type_floating_point_create();
4380 if (!copy) {
4e8304f7 4381 BT_LOGE_STR("Cannot create floating point number field type.");
24724933
JG
4382 goto end;
4383 }
4384
4385 copy_float = container_of(copy,
4386 struct bt_ctf_field_type_floating_point, parent);
445c3471 4387 copy_float->user_byte_order = floating_point->user_byte_order;
dc3fffef
PP
4388 copy_float->exp_dig = floating_point->exp_dig;
4389 copy_float->mant_dig = floating_point->mant_dig;
4e8304f7
PP
4390 BT_LOGD("Copied floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
4391 type, copy);
24724933
JG
4392end:
4393 return copy;
4394}
4395
4396static
4397struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
4398 struct bt_ctf_field_type *type)
4399{
4e8304f7 4400 int64_t i;
24724933
JG
4401 GHashTableIter iter;
4402 gpointer key, value;
4403 struct bt_ctf_field_type *copy;
4404 struct bt_ctf_field_type_structure *structure, *copy_structure;
4405
4e8304f7 4406 BT_LOGD("Copying structure field type's: addr=%p", type);
24724933
JG
4407 structure = container_of(type, struct bt_ctf_field_type_structure,
4408 parent);
4409 copy = bt_ctf_field_type_structure_create();
4410 if (!copy) {
4e8304f7 4411 BT_LOGE_STR("Cannot create structure field type.");
24724933
JG
4412 goto end;
4413 }
4414
4415 copy_structure = container_of(copy,
4416 struct bt_ctf_field_type_structure, parent);
4417
4418 /* Copy field_name_to_index */
4419 g_hash_table_iter_init(&iter, structure->field_name_to_index);
4420 while (g_hash_table_iter_next (&iter, &key, &value)) {
4421 g_hash_table_insert(copy_structure->field_name_to_index,
4422 key, value);
4423 }
4424
4425 for (i = 0; i < structure->fields->len; i++) {
4426 struct structure_field *entry, *copy_entry;
4427 struct bt_ctf_field_type *copy_field;
4428
dfc1504d
PP
4429 entry = g_ptr_array_index(structure->fields, i);
4430 BT_LOGV("Copying structure field type's field: "
4431 "index=%" PRId64 ", "
4432 "field-ft-addr=%p, field-name=\"%s\"",
4433 i, entry, g_quark_to_string(entry->name));
24724933
JG
4434 copy_entry = g_new0(struct structure_field, 1);
4435 if (!copy_entry) {
4e8304f7 4436 BT_LOGE_STR("Failed to allocate one structure field type field.");
24724933
JG
4437 goto error;
4438 }
4439
24724933
JG
4440 copy_field = bt_ctf_field_type_copy(entry->type);
4441 if (!copy_field) {
4e8304f7
PP
4442 BT_LOGE("Cannot copy structure field type's field: "
4443 "index=%" PRId64 ", "
4444 "field-ft-addr=%p, field-name=\"%s\"",
4445 i, entry, g_quark_to_string(entry->name));
24724933
JG
4446 g_free(copy_entry);
4447 goto error;
4448 }
4449
4450 copy_entry->name = entry->name;
4451 copy_entry->type = copy_field;
4452 g_ptr_array_add(copy_structure->fields, copy_entry);
4453 }
4454
4e8304f7
PP
4455 BT_LOGD("Copied structure field type: original-ft-addr=%p, copy-ft-addr=%p",
4456 type, copy);
4457
24724933
JG
4458end:
4459 return copy;
4460error:
83509119
JG
4461 BT_PUT(copy);
4462 return copy;
24724933
JG
4463}
4464
4465static
4466struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
4467 struct bt_ctf_field_type *type)
4468{
4e8304f7 4469 int64_t i;
24724933
JG
4470 GHashTableIter iter;
4471 gpointer key, value;
4472 struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
4473 struct bt_ctf_field_type_variant *variant, *copy_variant;
4474
4e8304f7 4475 BT_LOGD("Copying variant field type's: addr=%p", type);
24724933
JG
4476 variant = container_of(type, struct bt_ctf_field_type_variant,
4477 parent);
4478 if (variant->tag) {
4479 copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
4480 if (!copy_tag) {
4e8304f7 4481 BT_LOGE_STR("Cannot copy variant field type's tag field type.");
24724933
JG
4482 goto end;
4483 }
4484 }
4485
4486 copy = bt_ctf_field_type_variant_create(copy_tag,
4487 variant->tag_name->len ? variant->tag_name->str : NULL);
4488 if (!copy) {
4e8304f7 4489 BT_LOGE_STR("Cannot create variant field type.");
24724933
JG
4490 goto end;
4491 }
4492
4493 copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
4494 parent);
4495
4496 /* Copy field_name_to_index */
4497 g_hash_table_iter_init(&iter, variant->field_name_to_index);
4498 while (g_hash_table_iter_next (&iter, &key, &value)) {
4499 g_hash_table_insert(copy_variant->field_name_to_index,
4500 key, value);
4501 }
4502
4503 for (i = 0; i < variant->fields->len; i++) {
4504 struct structure_field *entry, *copy_entry;
4505 struct bt_ctf_field_type *copy_field;
4506
dfc1504d
PP
4507 entry = g_ptr_array_index(variant->fields, i);
4508 BT_LOGV("Copying variant field type's field: "
4509 "index=%" PRId64 ", "
4510 "field-ft-addr=%p, field-name=\"%s\"",
4511 i, entry, g_quark_to_string(entry->name));
24724933
JG
4512 copy_entry = g_new0(struct structure_field, 1);
4513 if (!copy_entry) {
4e8304f7 4514 BT_LOGE_STR("Failed to allocate one variant field type field.");
24724933
JG
4515 goto error;
4516 }
4517
24724933
JG
4518 copy_field = bt_ctf_field_type_copy(entry->type);
4519 if (!copy_field) {
4e8304f7
PP
4520 BT_LOGE("Cannot copy variant field type's field: "
4521 "index=%" PRId64 ", "
4522 "field-ft-addr=%p, field-name=\"%s\"",
4523 i, entry, g_quark_to_string(entry->name));
24724933
JG
4524 g_free(copy_entry);
4525 goto error;
4526 }
4527
4528 copy_entry->name = entry->name;
4529 copy_entry->type = copy_field;
4530 g_ptr_array_add(copy_variant->fields, copy_entry);
4531 }
4532
b011f6b0 4533 if (variant->tag_field_path) {
dfc1504d 4534 BT_LOGV_STR("Copying variant field type's tag field path.");
b011f6b0
PP
4535 copy_variant->tag_field_path = bt_ctf_field_path_copy(
4536 variant->tag_field_path);
4537 if (!copy_variant->tag_field_path) {
4e8304f7 4538 BT_LOGE_STR("Cannot copy variant field type's tag field path.");
4a1e8671
JG
4539 goto error;
4540 }
4541 }
4e8304f7
PP
4542
4543 BT_LOGD("Copied variant field type: original-ft-addr=%p, copy-ft-addr=%p",
4544 type, copy);
4545
24724933 4546end:
83509119 4547 bt_put(copy_tag);
24724933
JG
4548 return copy;
4549error:
83509119
JG
4550 bt_put(copy_tag);
4551 BT_PUT(copy);
4552 return copy;
24724933
JG
4553}
4554
4555static
4556struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
4557 struct bt_ctf_field_type *type)
4558{
4559 struct bt_ctf_field_type *copy = NULL, *copy_element;
dc3fffef 4560 struct bt_ctf_field_type_array *array;
24724933 4561
4e8304f7 4562 BT_LOGD("Copying array field type's: addr=%p", type);
24724933
JG
4563 array = container_of(type, struct bt_ctf_field_type_array,
4564 parent);
4565 copy_element = bt_ctf_field_type_copy(array->element_type);
4566 if (!copy_element) {
4e8304f7 4567 BT_LOGE_STR("Cannot copy array field type's element field type.");
24724933
JG
4568 goto end;
4569 }
4570
4571 copy = bt_ctf_field_type_array_create(copy_element, array->length);
4572 if (!copy) {
4e8304f7 4573 BT_LOGE_STR("Cannot create array field type.");
24724933
JG
4574 goto end;
4575 }
4e8304f7
PP
4576
4577 BT_LOGD("Copied array field type: original-ft-addr=%p, copy-ft-addr=%p",
4578 type, copy);
4579
24724933 4580end:
83509119 4581 bt_put(copy_element);
24724933
JG
4582 return copy;
4583}
4584
4585static
4586struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
4587 struct bt_ctf_field_type *type)
4588{
4589 struct bt_ctf_field_type *copy = NULL, *copy_element;
4590 struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
4591
4e8304f7 4592 BT_LOGD("Copying sequence field type's: addr=%p", type);
24724933
JG
4593 sequence = container_of(type, struct bt_ctf_field_type_sequence,
4594 parent);
4595 copy_element = bt_ctf_field_type_copy(sequence->element_type);
4596 if (!copy_element) {
4e8304f7 4597 BT_LOGE_STR("Cannot copy sequence field type's element field type.");
24724933
JG
4598 goto end;
4599 }
4600
4601 copy = bt_ctf_field_type_sequence_create(copy_element,
4602 sequence->length_field_name->len ?
4603 sequence->length_field_name->str : NULL);
4604 if (!copy) {
4e8304f7 4605 BT_LOGE_STR("Cannot create sequence field type.");
24724933
JG
4606 goto end;
4607 }
4608
4609 copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
4610 parent);
aa4e271c 4611 if (sequence->length_field_path) {
dfc1504d 4612 BT_LOGV_STR("Copying sequence field type's length field path.");
aa4e271c
JG
4613 copy_sequence->length_field_path = bt_ctf_field_path_copy(
4614 sequence->length_field_path);
4615 if (!copy_sequence->length_field_path) {
4e8304f7 4616 BT_LOGE_STR("Cannot copy sequence field type's length field path.");
aa4e271c
JG
4617 goto error;
4618 }
4619 }
4e8304f7
PP
4620
4621 BT_LOGD("Copied sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
4622 type, copy);
4623
24724933 4624end:
83509119 4625 bt_put(copy_element);
24724933 4626 return copy;
aa4e271c 4627error:
83509119 4628 BT_PUT(copy);
aa4e271c 4629 goto end;
24724933
JG
4630}
4631
4632static
4633struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
4634 struct bt_ctf_field_type *type)
4635{
4636 struct bt_ctf_field_type *copy;
dc3fffef 4637 struct bt_ctf_field_type_string *string;
24724933 4638
4e8304f7 4639 BT_LOGD("Copying string field type's: addr=%p", type);
24724933
JG
4640 copy = bt_ctf_field_type_string_create();
4641 if (!copy) {
4e8304f7 4642 BT_LOGE_STR("Cannot create string field type.");
24724933
JG
4643 goto end;
4644 }
4645
4646 string = container_of(type, struct bt_ctf_field_type_string,
4647 parent);
4e8304f7
PP
4648 BT_LOGD("Copied string field type: original-ft-addr=%p, copy-ft-addr=%p",
4649 type, copy);
24724933
JG
4650end:
4651 return copy;
4652}
265e809c
PP
4653
4654static
4655int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
4656 struct bt_ctf_field_type *type_b)
4657{
4658 int ret = 1;
dc3fffef
PP
4659 struct bt_ctf_field_type_integer *int_type_a;
4660 struct bt_ctf_field_type_integer *int_type_b;
265e809c 4661
dc3fffef 4662 int_type_a = container_of(type_a, struct bt_ctf_field_type_integer,
265e809c 4663 parent);
dc3fffef 4664 int_type_b = container_of(type_b, struct bt_ctf_field_type_integer,
265e809c 4665 parent);
265e809c
PP
4666
4667 /* Length */
dc3fffef 4668 if (int_type_a->size != int_type_b->size) {
4e8304f7
PP
4669 BT_LOGV("Integer field types differ: different sizes: "
4670 "ft-a-size=%u, ft-b-size=%u",
4671 int_type_a->size, int_type_b->size);
265e809c
PP
4672 goto end;
4673 }
4674
dc3fffef
PP
4675 /* Byte order */
4676 if (int_type_a->user_byte_order != int_type_b->user_byte_order) {
4e8304f7
PP
4677 BT_LOGV("Integer field types differ: different byte orders: "
4678 "ft-a-bo=%s, ft-b-bo=%s",
4679 bt_ctf_byte_order_string(int_type_a->user_byte_order),
4680 bt_ctf_byte_order_string(int_type_b->user_byte_order));
265e809c
PP
4681 goto end;
4682 }
4683
4684 /* Signedness */
dc3fffef 4685 if (int_type_a->is_signed != int_type_b->is_signed) {
4e8304f7
PP
4686 BT_LOGV("Integer field types differ: different signedness: "
4687 "ft-a-is-signed=%d, ft-b-is-signed=%d",
4688 int_type_a->is_signed,
4689 int_type_b->is_signed);
265e809c
PP
4690 goto end;
4691 }
4692
4693 /* Base */
dc3fffef 4694 if (int_type_a->base != int_type_b->base) {
4e8304f7
PP
4695 BT_LOGV("Integer field types differ: different bases: "
4696 "ft-a-base=%s, ft-b-base=%s",
4697 bt_ctf_integer_base_string(int_type_a->base),
4698 bt_ctf_integer_base_string(int_type_b->base));
265e809c
PP
4699 goto end;
4700 }
4701
4702 /* Encoding */
dc3fffef 4703 if (int_type_a->encoding != int_type_b->encoding) {
4e8304f7
PP
4704 BT_LOGV("Integer field types differ: different encodings: "
4705 "ft-a-encoding=%s, ft-b-encoding=%s",
4706 bt_ctf_string_encoding_string(int_type_a->encoding),
4707 bt_ctf_string_encoding_string(int_type_b->encoding));
265e809c
PP
4708 goto end;
4709 }
4710
4711 /* Mapped clock */
dc3fffef 4712 if (int_type_a->mapped_clock != int_type_b->mapped_clock) {
4e8304f7
PP
4713 BT_LOGV("Integer field types differ: different mapped clock classes: "
4714 "ft-a-mapped-clock-class-addr=%p, "
4715 "ft-b-mapped-clock-class-addr=%p, ",
4716 "ft-a-mapped-clock-class-name=\"%s\", ",
4717 "ft-b-mapped-clock-class-name=\"%s\"",
4718 int_type_a->mapped_clock, int_type_b->mapped_clock,
4719 int_type_a->mapped_clock ? bt_ctf_clock_class_get_name(int_type_a->mapped_clock) : "",
4720 int_type_b->mapped_clock ? bt_ctf_clock_class_get_name(int_type_b->mapped_clock) : "");
265e809c
PP
4721 goto end;
4722 }
4723
4724 /* Equal */
4725 ret = 0;
4726
4727end:
4728 return ret;
4729}
4730
4731static
4732int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
4733 struct bt_ctf_field_type *type_b)
4734{
4735 int ret = 1;
4736 struct bt_ctf_field_type_floating_point *float_a;
4737 struct bt_ctf_field_type_floating_point *float_b;
4738
4739 float_a = container_of(type_a,
4740 struct bt_ctf_field_type_floating_point, parent);
4741 float_b = container_of(type_b,
4742 struct bt_ctf_field_type_floating_point, parent);
4743
dc3fffef
PP
4744 /* Byte order */
4745 if (float_a->user_byte_order != float_b->user_byte_order) {
4e8304f7
PP
4746 BT_LOGV("Floating point number field types differ: different byte orders: "
4747 "ft-a-bo=%s, ft-b-bo=%s",
4748 bt_ctf_byte_order_string(float_a->user_byte_order),
4749 bt_ctf_byte_order_string(float_b->user_byte_order));
265e809c
PP
4750 goto end;
4751 }
4752
4753 /* Exponent length */
dc3fffef 4754 if (float_a->exp_dig != float_b->exp_dig) {
4e8304f7
PP
4755 BT_LOGV("Floating point number field types differ: different exponent sizes: "
4756 "ft-a-exp-size=%s, ft-b-exp-size=%s",
4757 float_a->exp_dig, float_b->exp_dig);
265e809c
PP
4758 goto end;
4759 }
4760
4761 /* Mantissa length */
dc3fffef 4762 if (float_a->mant_dig != float_b->mant_dig) {
4e8304f7
PP
4763 BT_LOGV("Floating point number field types differ: different mantissa sizes: "
4764 "ft-a-mant-size=%s, ft-b-mant-size=%s",
4765 float_a->mant_dig, float_b->mant_dig);
265e809c
PP
4766 goto end;
4767 }
4768
4769 /* Equal */
4770 ret = 0;
4771
4772end:
4773 return ret;
4774}
4775
4776static
4777int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
4778 struct enumeration_mapping *mapping_b)
4779{
4780 int ret = 1;
4781
4782 /* Label */
4783 if (mapping_a->string != mapping_b->string) {
4e8304f7
PP
4784 BT_LOGV("Enumeration field type mappings differ: different names: "
4785 "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
4786 g_quark_to_string(mapping_a->string),
4787 g_quark_to_string(mapping_b->string));
265e809c
PP
4788 goto end;
4789 }
4790
4791 /* Range start */
4792 if (mapping_a->range_start._unsigned !=
4793 mapping_b->range_start._unsigned) {
4e8304f7
PP
4794 BT_LOGV("Enumeration field type mappings differ: different starts of range: "
4795 "mapping-a-range-start-unsigned=%" PRIu64 ", "
4796 "mapping-b-range-start-unsigned=%" PRIu64,
4797 mapping_a->range_start._unsigned,
4798 mapping_b->range_start._unsigned);
265e809c
PP
4799 goto end;
4800 }
4801
4802 /* Range end */
4803 if (mapping_a->range_end._unsigned !=
4804 mapping_b->range_end._unsigned) {
4e8304f7
PP
4805 BT_LOGV("Enumeration field type mappings differ: different ends of range: "
4806 "mapping-a-range-end-unsigned=%" PRIu64 ", "
4807 "mapping-b-range-end-unsigned=%" PRIu64,
4808 mapping_a->range_end._unsigned,
4809 mapping_b->range_end._unsigned);
265e809c
PP
4810 goto end;
4811 }
4812
4813 /* Equal */
4814 ret = 0;
4815
4816end:
4817 return ret;
4818}
4819
4820static
4821int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
4822 struct bt_ctf_field_type *type_b)
4823{
4824 int ret = 1;
4825 int i;
4826 struct bt_ctf_field_type_enumeration *enum_a;
4827 struct bt_ctf_field_type_enumeration *enum_b;
4828
4829 enum_a = container_of(type_a,
4830 struct bt_ctf_field_type_enumeration, parent);
4831 enum_b = container_of(type_b,
4832 struct bt_ctf_field_type_enumeration, parent);
4833
4834 /* Container field type */
4835 ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
4836 if (ret) {
4e8304f7
PP
4837 BT_LOGV("Enumeration field types differ: different container field types: "
4838 "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
4839 enum_a->container, enum_b->container);
265e809c
PP
4840 goto end;
4841 }
4842
4843 ret = 1;
4844
4845 /* Entries */
4846 if (enum_a->entries->len != enum_b->entries->len) {
4847 goto end;
4848 }
4849
4850 for (i = 0; i < enum_a->entries->len; ++i) {
4851 struct enumeration_mapping *mapping_a =
4852 g_ptr_array_index(enum_a->entries, i);
4853 struct enumeration_mapping *mapping_b =
4854 g_ptr_array_index(enum_b->entries, i);
4855
4856 if (compare_enumeration_mappings(mapping_a, mapping_b)) {
4e8304f7
PP
4857 BT_LOGV("Enumeration field types differ: different mappings: "
4858 "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
4859 "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
4860 mapping_a, mapping_b,
4861 g_quark_to_string(mapping_a->string),
4862 g_quark_to_string(mapping_b->string));
265e809c
PP
4863 goto end;
4864 }
4865 }
4866
4867 /* Equal */
4868 ret = 0;
4869
4870end:
4871 return ret;
4872}
4873
4874static
4875int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
4876 struct bt_ctf_field_type *type_b)
4877{
4878 int ret = 1;
4879 struct bt_ctf_field_type_string *string_a;
4880 struct bt_ctf_field_type_string *string_b;
4881
4882 string_a = container_of(type_a,
4883 struct bt_ctf_field_type_string, parent);
4884 string_b = container_of(type_b,
4885 struct bt_ctf_field_type_string, parent);
4886
4887 /* Encoding */
dc3fffef 4888 if (string_a->encoding != string_b->encoding) {
4e8304f7
PP
4889 BT_LOGV("String field types differ: different encodings: "
4890 "ft-a-encoding=%s, ft-b-encoding=%s",
4891 bt_ctf_string_encoding_string(string_a->encoding),
4892 bt_ctf_string_encoding_string(string_b->encoding));
265e809c
PP
4893 goto end;
4894 }
4895
4896 /* Equal */
4897 ret = 0;
4898
4899end:
4900 return ret;
4901}
4902
4903static
4904int compare_structure_fields(struct structure_field *field_a,
4905 struct structure_field *field_b)
4906{
4907 int ret = 1;
4908
4909 /* Label */
4910 if (field_a->name != field_b->name) {
4e8304f7
PP
4911 BT_LOGV("Structure/variant field type fields differ: different names: "
4912 "field-a-name=%s, field-b-name=%s",
4913 g_quark_to_string(field_a->name),
4914 g_quark_to_string(field_b->name));
265e809c
PP
4915 goto end;
4916 }
4917
4918 /* Type */
4919 ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
4e8304f7
PP
4920 if (ret == 1) {
4921 BT_LOGV("Structure/variant field type fields differ: different field types: "
4922 "field-name=\"%s\", field-a-ft-addr=%s, field-b-ft-addr=%s",
4923 g_quark_to_string(field_a->name),
4924 field_a->type, field_b->type);
4925 }
265e809c
PP
4926
4927end:
4928 return ret;
4929}
4930
4931static
4932int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
4933 struct bt_ctf_field_type *type_b)
4934{
4935 int ret = 1;
4936 int i;
4937 struct bt_ctf_field_type_structure *struct_a;
4938 struct bt_ctf_field_type_structure *struct_b;
4939
4940 struct_a = container_of(type_a,
4941 struct bt_ctf_field_type_structure, parent);
4942 struct_b = container_of(type_b,
4943 struct bt_ctf_field_type_structure, parent);
4944
4945 /* Alignment */
4946 if (bt_ctf_field_type_get_alignment(type_a) !=
4947 bt_ctf_field_type_get_alignment(type_b)) {
4e8304f7
PP
4948 BT_LOGV("Structure field types differ: different alignments: "
4949 "ft-a-align=%u, ft-b-align=%u",
4950 bt_ctf_field_type_get_alignment(type_a),
4951 bt_ctf_field_type_get_alignment(type_b));
265e809c
PP
4952 goto end;
4953 }
4954
4955 /* Fields */
4956 if (struct_a->fields->len != struct_b->fields->len) {
4e8304f7
PP
4957 BT_LOGV("Structure field types differ: different field counts: "
4958 "ft-a-field-count=%u, ft-b-field-count=%u",
4959 struct_a->fields->len, struct_b->fields->len);
265e809c
PP
4960 goto end;
4961 }
4962
4963 for (i = 0; i < struct_a->fields->len; ++i) {
4964 struct structure_field *field_a =
4965 g_ptr_array_index(struct_a->fields, i);
4966 struct structure_field *field_b =
4967 g_ptr_array_index(struct_b->fields, i);
4968
4969 ret = compare_structure_fields(field_a, field_b);
4970 if (ret) {
4e8304f7
PP
4971 /* compare_structure_fields() logs what differs */
4972 BT_LOGV_STR("Structure field types differ: different fields.");
265e809c
PP
4973 goto end;
4974 }
265e809c
PP
4975 }
4976
4977 /* Equal */
4978 ret = 0;
4979
4980end:
4981 return ret;
4982}
4983
4984static
4985int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
4986 struct bt_ctf_field_type *type_b)
4987{
4988 int ret = 1;
4989 int i;
4990 struct bt_ctf_field_type_variant *variant_a;
4991 struct bt_ctf_field_type_variant *variant_b;
4992
4993 variant_a = container_of(type_a,
4994 struct bt_ctf_field_type_variant, parent);
4995 variant_b = container_of(type_b,
4996 struct bt_ctf_field_type_variant, parent);
4997
4998 /* Tag name */
4999 if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
4e8304f7
PP
5000 BT_LOGV("Variant field types differ: different tag field names: "
5001 "ft-a-tag-field-name=%u, ft-b-tag-field-name=%u",
5002 variant_a->tag_name->str, variant_b->tag_name->str);
265e809c
PP
5003 goto end;
5004 }
5005
5006 /* Tag type */
5007 ret = bt_ctf_field_type_compare(
5008 (struct bt_ctf_field_type *) variant_a->tag,
5009 (struct bt_ctf_field_type *) variant_b->tag);
5010 if (ret) {
4e8304f7
PP
5011 BT_LOGV("Variant field types differ: different tag field types: "
5012 "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
5013 variant_a->tag, variant_b->tag);
265e809c
PP
5014 goto end;
5015 }
5016
5017 ret = 1;
5018
5019 /* Fields */
5020 if (variant_a->fields->len != variant_b->fields->len) {
4e8304f7
PP
5021 BT_LOGV("Structure field types differ: different field counts: "
5022 "ft-a-field-count=%u, ft-b-field-count=%u",
5023 variant_a->fields->len, variant_b->fields->len);
265e809c
PP
5024 goto end;
5025 }
5026
5027 for (i = 0; i < variant_a->fields->len; ++i) {
5028 struct structure_field *field_a =
5029 g_ptr_array_index(variant_a->fields, i);
5030 struct structure_field *field_b =
5031 g_ptr_array_index(variant_b->fields, i);
5032
5033 ret = compare_structure_fields(field_a, field_b);
5034 if (ret) {
4e8304f7
PP
5035 /* compare_structure_fields() logs what differs */
5036 BT_LOGV_STR("Variant field types differ: different fields.");
265e809c
PP
5037 goto end;
5038 }
265e809c
PP
5039 }
5040
5041 /* Equal */
5042 ret = 0;
5043
5044end:
5045 return ret;
5046}
5047
5048static
5049int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
5050 struct bt_ctf_field_type *type_b)
5051{
5052 int ret = 1;
5053 struct bt_ctf_field_type_array *array_a;
5054 struct bt_ctf_field_type_array *array_b;
5055
5056 array_a = container_of(type_a,
5057 struct bt_ctf_field_type_array, parent);
5058 array_b = container_of(type_b,
5059 struct bt_ctf_field_type_array, parent);
5060
5061 /* Length */
5062 if (array_a->length != array_b->length) {
4e8304f7
PP
5063 BT_LOGV("Structure field types differ: different lengths: "
5064 "ft-a-length=%u, ft-b-length=%u",
5065 array_a->length, array_b->length);
265e809c
PP
5066 goto end;
5067 }
5068
5069 /* Element type */
5070 ret = bt_ctf_field_type_compare(array_a->element_type,
5071 array_b->element_type);
4e8304f7
PP
5072 if (ret == 1) {
5073 BT_LOGV("Array field types differ: different element field types: "
5074 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
5075 array_a->element_type, array_b->element_type);
5076 }
265e809c
PP
5077
5078end:
5079 return ret;
5080}
5081
5082static
5083int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
5084 struct bt_ctf_field_type *type_b)
5085{
5086 int ret = -1;
5087 struct bt_ctf_field_type_sequence *sequence_a;
5088 struct bt_ctf_field_type_sequence *sequence_b;
5089
5090 sequence_a = container_of(type_a,
5091 struct bt_ctf_field_type_sequence, parent);
5092 sequence_b = container_of(type_b,
5093 struct bt_ctf_field_type_sequence, parent);
5094
5095 /* Length name */
5096 if (strcmp(sequence_a->length_field_name->str,
5097 sequence_b->length_field_name->str)) {
4e8304f7
PP
5098 BT_LOGV("Sequence field types differ: different length field names: "
5099 "ft-a-length-field-name=%u, ft-b-length-field-name=%u",
5100 sequence_a->length_field_name->str,
5101 sequence_b->length_field_name->str);
265e809c
PP
5102 goto end;
5103 }
5104
5105 /* Element type */
5106 ret = bt_ctf_field_type_compare(sequence_a->element_type,
5107 sequence_b->element_type);
4e8304f7
PP
5108 if (ret == 1) {
5109 BT_LOGV("Sequence field types differ: different element field types: "
5110 "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
5111 sequence_a->element_type, sequence_b->element_type);
5112 }
265e809c
PP
5113
5114end:
5115 return ret;
5116}
5117
5118int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
5119 struct bt_ctf_field_type *type_b)
5120{
5121 int ret = 1;
5122
5123 if (type_a == type_b) {
5124 /* Same reference: equal (even if both are NULL) */
5125 ret = 0;
5126 goto end;
5127 }
5128
4e8304f7
PP
5129 if (!type_a) {
5130 BT_LOGW_STR("Invalid parameter: field type A is NULL.");
5131 ret = -1;
5132 goto end;
5133 }
5134
5135 if (!type_b) {
5136 BT_LOGW_STR("Invalid parameter: field type B is NULL.");
265e809c
PP
5137 ret = -1;
5138 goto end;
5139 }
5140
dc3fffef 5141 if (type_a->id != type_b->id) {
265e809c 5142 /* Different type IDs */
4e8304f7
PP
5143 BT_LOGV("Field types differ: different IDs: "
5144 "ft-a-addr=%p, ft-b-addr=%p, "
5145 "ft-a-id=%s, ft-b-id=%s",
5146 type_a, type_b,
5147 bt_ctf_field_type_id_string(type_a->id),
5148 bt_ctf_field_type_id_string(type_b->id));
265e809c
PP
5149 goto end;
5150 }
5151
1487a16a 5152 if (type_a->id == BT_CTF_FIELD_TYPE_ID_UNKNOWN) {
265e809c 5153 /* Both have unknown type IDs */
4e8304f7 5154 BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
265e809c
PP
5155 goto end;
5156 }
5157
dc3fffef 5158 ret = type_compare_funcs[type_a->id](type_a, type_b);
4e8304f7
PP
5159 if (ret == 1) {
5160 BT_LOGV("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
5161 type_a, type_b);
5162 }
265e809c
PP
5163
5164end:
5165 return ret;
5166}
09840de5
PP
5167
5168BT_HIDDEN
544d0515 5169int64_t bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
09840de5 5170{
544d0515 5171 int64_t field_count = -1;
1487a16a 5172 enum bt_ctf_field_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
09840de5
PP
5173
5174 switch (type_id) {
5175 case CTF_TYPE_STRUCT:
5176 field_count =
5177 bt_ctf_field_type_structure_get_field_count(field_type);
5178 break;
5179 case CTF_TYPE_VARIANT:
5180 field_count =
5181 bt_ctf_field_type_variant_get_field_count(field_type);
5182 break;
5183 case CTF_TYPE_ARRAY:
5184 case CTF_TYPE_SEQUENCE:
5185 /*
5186 * Array and sequence types always contain a single member
5187 * (the element type).
5188 */
5189 field_count = 1;
5190 break;
5191 default:
5192 break;
5193 }
5194
5195 return field_count;
5196}
5197
5198BT_HIDDEN
5199struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
5200 struct bt_ctf_field_type *field_type, int index)
5201{
5202 struct bt_ctf_field_type *field = NULL;
1487a16a 5203 enum bt_ctf_field_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
09840de5
PP
5204
5205 switch (type_id) {
5206 case CTF_TYPE_STRUCT:
9ac68eb1
PP
5207 bt_ctf_field_type_structure_get_field_by_index(field_type,
5208 NULL, &field, index);
09840de5
PP
5209 break;
5210 case CTF_TYPE_VARIANT:
8f3a93d9 5211 {
9ac68eb1
PP
5212 int ret = bt_ctf_field_type_variant_get_field_by_index(
5213 field_type, NULL, &field, index);
8f3a93d9
JG
5214 if (ret) {
5215 field = NULL;
5216 goto end;
5217 }
09840de5 5218 break;
8f3a93d9 5219 }
09840de5
PP
5220 case CTF_TYPE_ARRAY:
5221 field = bt_ctf_field_type_array_get_element_type(field_type);
5222 break;
5223 case CTF_TYPE_SEQUENCE:
5224 field = bt_ctf_field_type_sequence_get_element_type(field_type);
5225 break;
5226 default:
5227 break;
5228 }
8f3a93d9 5229end:
09840de5
PP
5230 return field;
5231}
5232
5233BT_HIDDEN
5234int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
5235 const char *name)
5236{
5237 int field_index = -1;
1487a16a 5238 enum bt_ctf_field_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
09840de5
PP
5239
5240 switch (type_id) {
5241 case CTF_TYPE_STRUCT:
5242 field_index = bt_ctf_field_type_structure_get_field_name_index(
5243 field_type, name);
5244 break;
5245 case CTF_TYPE_VARIANT:
5246 field_index = bt_ctf_field_type_variant_get_field_name_index(
5247 field_type, name);
5248 break;
5249 default:
5250 break;
5251 }
5252
5253 return field_index;
5254}
b011f6b0
PP
5255
5256struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
5257 struct bt_ctf_field_type *type)
5258{
5259 struct bt_ctf_field_path *field_path = NULL;
5260 struct bt_ctf_field_type_variant *variant;
5261
4e8304f7
PP
5262 if (!type) {
5263 BT_LOGW_STR("Invalid parameter: field type is NULL.");
5264 goto end;
5265 }
5266
5267 if (!bt_ctf_field_type_is_variant(type)) {
5268 BT_LOGW("Invalid parameter: field type is not a variant field type: "
5269 "addr=%p, ft-id=%s", type,
5270 bt_ctf_field_type_id_string(type->id));
b011f6b0
PP
5271 goto end;
5272 }
5273
5274 variant = container_of(type, struct bt_ctf_field_type_variant,
5275 parent);
5276 field_path = bt_get(variant->tag_field_path);
5277end:
5278 return field_path;
5279}
5280
5281struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
5282 struct bt_ctf_field_type *type)
5283{
5284 struct bt_ctf_field_path *field_path = NULL;
5285 struct bt_ctf_field_type_sequence *sequence;
5286
4e8304f7
PP
5287 if (!type) {
5288 BT_LOGW_STR("Invalid parameter: field type is NULL.");
5289 goto end;
5290 }
5291
5292 if (!bt_ctf_field_type_is_sequence(type)) {
5293 BT_LOGW("Invalid parameter: field type is not a sequence field type: "
5294 "addr=%p, ft-id=%s", type,
5295 bt_ctf_field_type_id_string(type->id));
b011f6b0
PP
5296 goto end;
5297 }
5298
5299 sequence = container_of(type, struct bt_ctf_field_type_sequence,
5300 parent);
5301 field_path = bt_get(sequence->length_field_path);
5302end:
5303 return field_path;
5304}
This page took 0.307021 seconds and 4 git commands to generate.