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