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