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