Fix: check enum overlap as long as the type is not frozen
[babeltrace.git] / formats / ctf / ir / fields.c
CommitLineData
273b65be 1/*
2e33ac5a 2 * fields.c
273b65be 3 *
d2dc44b6 4 * Babeltrace CTF IR - Event Fields
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
2e33ac5a
PP
29#include <babeltrace/ctf-ir/fields-internal.h>
30#include <babeltrace/ctf-ir/field-types-internal.h>
83509119
JG
31#include <babeltrace/object-internal.h>
32#include <babeltrace/ref.h>
273b65be 33#include <babeltrace/compiler.h>
a323afb2 34#include <babeltrace/compat/fcntl.h>
273b65be
JG
35
36#define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
37
38static
39struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
40static
41struct bt_ctf_field *bt_ctf_field_enumeration_create(
42 struct bt_ctf_field_type *);
43static
44struct bt_ctf_field *bt_ctf_field_floating_point_create(
45 struct bt_ctf_field_type *);
46static
47struct bt_ctf_field *bt_ctf_field_structure_create(
48 struct bt_ctf_field_type *);
49static
50struct bt_ctf_field *bt_ctf_field_variant_create(
51 struct bt_ctf_field_type *);
52static
53struct bt_ctf_field *bt_ctf_field_array_create(
54 struct bt_ctf_field_type *);
55static
56struct bt_ctf_field *bt_ctf_field_sequence_create(
57 struct bt_ctf_field_type *);
58static
59struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
60
61static
83509119 62void bt_ctf_field_destroy(struct bt_object *);
273b65be
JG
63static
64void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
65static
66void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
67static
68void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
69static
70void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
71static
72void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
73static
74void bt_ctf_field_array_destroy(struct bt_ctf_field *);
75static
76void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
77static
78void bt_ctf_field_string_destroy(struct bt_ctf_field *);
79
80static
ca116246 81int bt_ctf_field_generic_validate(struct bt_ctf_field *);
273b65be 82static
ca116246 83int bt_ctf_field_structure_validate(struct bt_ctf_field *);
273b65be 84static
ca116246 85int bt_ctf_field_variant_validate(struct bt_ctf_field *);
273b65be 86static
ca116246 87int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
273b65be 88static
ca116246 89int bt_ctf_field_array_validate(struct bt_ctf_field *);
273b65be 90static
ca116246 91int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
273b65be 92
12c8a1a3 93static
ca116246 94int bt_ctf_field_generic_reset(struct bt_ctf_field *);
12c8a1a3 95static
ca116246 96int bt_ctf_field_structure_reset(struct bt_ctf_field *);
12c8a1a3 97static
ca116246 98int bt_ctf_field_variant_reset(struct bt_ctf_field *);
12c8a1a3 99static
ca116246 100int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
12c8a1a3 101static
ca116246 102int bt_ctf_field_array_reset(struct bt_ctf_field *);
12c8a1a3 103static
ca116246 104int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
12c8a1a3 105static
ca116246 106int bt_ctf_field_string_reset(struct bt_ctf_field *);
12c8a1a3 107
273b65be
JG
108static
109int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
110 struct ctf_stream_pos *);
111static
112int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
113 struct ctf_stream_pos *);
114static
115int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
116 struct ctf_stream_pos *);
117static
118int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
119 struct ctf_stream_pos *);
120static
121int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
122 struct ctf_stream_pos *);
123static
124int bt_ctf_field_array_serialize(struct bt_ctf_field *,
125 struct ctf_stream_pos *);
126static
127int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
128 struct ctf_stream_pos *);
129static
130int bt_ctf_field_string_serialize(struct bt_ctf_field *,
131 struct ctf_stream_pos *);
132
87d43dc1
JG
133static
134int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
135static
136int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
137static
138int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
139 struct bt_ctf_field *);
140static
141int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
142static
143int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
144static
145int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
146static
147int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
148static
149int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
150
918be005
PP
151static
152void generic_field_freeze(struct bt_ctf_field *);
153static
154void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
155static
156void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
157static
158void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
159static
160void bt_ctf_field_array_freeze(struct bt_ctf_field *);
161static
162void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
163
76f869ab
JG
164static
165bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
166static
167bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
168static
169bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
170static
171bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
172static
173bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
174static
175bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
176
273b65be
JG
177static
178int increase_packet_size(struct ctf_stream_pos *pos);
179
180static
ce6da4fd 181struct bt_ctf_field *(* const field_create_funcs[])(
273b65be 182 struct bt_ctf_field_type *) = {
9a19a512
PP
183 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
184 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
185 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 186 bt_ctf_field_floating_point_create,
9a19a512
PP
187 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
188 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
189 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
190 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
191 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_create,
273b65be
JG
192};
193
194static
ce6da4fd 195void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
9a19a512
PP
196 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_destroy,
197 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_destroy,
198 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 199 bt_ctf_field_floating_point_destroy,
9a19a512
PP
200 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_destroy,
201 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_destroy,
202 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_destroy,
203 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_destroy,
204 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_destroy,
273b65be
JG
205};
206
207static
ce6da4fd 208int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
9a19a512
PP
209 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_validate,
210 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_validate,
211 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_validate,
212 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_validate,
213 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_validate,
214 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_validate,
215 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_validate,
216 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_validate,
273b65be
JG
217};
218
12c8a1a3 219static
ce6da4fd 220int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
9a19a512
PP
221 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_reset,
222 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_reset,
223 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_reset,
224 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_reset,
225 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_reset,
226 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_reset,
227 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_reset,
228 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_reset,
12c8a1a3
JG
229};
230
273b65be 231static
ce6da4fd 232int (* const field_serialize_funcs[])(struct bt_ctf_field *,
273b65be 233 struct ctf_stream_pos *) = {
9a19a512
PP
234 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_serialize,
235 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_serialize,
236 [BT_CTF_TYPE_ID_FLOAT] =
273b65be 237 bt_ctf_field_floating_point_serialize,
9a19a512
PP
238 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_serialize,
239 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_serialize,
240 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_serialize,
241 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_serialize,
242 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_serialize,
273b65be
JG
243};
244
87d43dc1 245static
ce6da4fd
JG
246int (* const field_copy_funcs[])(struct bt_ctf_field *,
247 struct bt_ctf_field *) = {
9a19a512
PP
248 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_copy,
249 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_copy,
250 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_copy,
251 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_copy,
252 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_copy,
253 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_copy,
254 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_copy,
255 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_copy,
87d43dc1
JG
256};
257
918be005
PP
258static
259void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
260 [BT_CTF_TYPE_ID_INTEGER] = generic_field_freeze,
261 [BT_CTF_TYPE_ID_FLOAT] = generic_field_freeze,
262 [BT_CTF_TYPE_ID_STRING] = generic_field_freeze,
263 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
264 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
265 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
266 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
267 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
268};
269
76f869ab
JG
270static
271bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
272 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_is_set,
273 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_is_set,
274 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_is_set,
275 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_is_set,
276 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_is_set,
277 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_is_set,
278 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_is_set,
279 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_is_set,
280};
281
273b65be
JG
282struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
283{
284 struct bt_ctf_field *field = NULL;
9a19a512 285 enum bt_ctf_type_id type_id;
81e36fac 286 int ret;
273b65be
JG
287
288 if (!type) {
289 goto error;
290 }
291
292 type_id = bt_ctf_field_type_get_type_id(type);
9a19a512
PP
293 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
294 type_id >= BT_CTF_NR_TYPE_IDS) {
81e36fac
PP
295 goto error;
296 }
297
298 /* Field class MUST be valid */
299 ret = bt_ctf_field_type_validate(type);
300
301 if (ret) {
302 /* Invalid */
273b65be
JG
303 goto error;
304 }
305
306 field = field_create_funcs[type_id](type);
307 if (!field) {
308 goto error;
309 }
310
311 /* The type's declaration can't change after this point */
312 bt_ctf_field_type_freeze(type);
83509119
JG
313 bt_get(type);
314 bt_object_init(field, bt_ctf_field_destroy);
273b65be
JG
315 field->type = type;
316error:
317 return field;
318}
319
320void bt_ctf_field_get(struct bt_ctf_field *field)
321{
83509119 322 bt_get(field);
273b65be
JG
323}
324
325void bt_ctf_field_put(struct bt_ctf_field *field)
326{
83509119 327 bt_put(field);
273b65be
JG
328}
329
cd95e351
JG
330struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
331{
332 struct bt_ctf_field_type *ret = NULL;
333
334 if (!field) {
335 goto end;
336 }
337
338 ret = field->type;
83509119 339 bt_get(ret);
cd95e351
JG
340end:
341 return ret;
342}
343
9a19a512 344enum bt_ctf_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
4ebcc695 345{
9a19a512 346 enum bt_ctf_type_id ret = BT_CTF_TYPE_ID_UNKNOWN;
4ebcc695
PP
347
348 if (!field) {
349 goto end;
350 }
351
352 ret = bt_ctf_field_type_get_type_id(field->type);
353end:
354 return ret;
355}
356
8f3553be
PP
357int bt_ctf_field_is_integer(struct bt_ctf_field *field)
358{
9a19a512 359 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_INTEGER;
8f3553be
PP
360}
361
362int bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
363{
9a19a512 364 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_FLOAT;
8f3553be
PP
365}
366
367int bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
368{
9a19a512 369 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ENUM;
8f3553be
PP
370}
371
372int bt_ctf_field_is_string(struct bt_ctf_field *field)
373{
9a19a512 374 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRING;
8f3553be
PP
375}
376
377int bt_ctf_field_is_structure(struct bt_ctf_field *field)
378{
9a19a512 379 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRUCT;
8f3553be
PP
380}
381
382int bt_ctf_field_is_array(struct bt_ctf_field *field)
383{
9a19a512 384 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ARRAY;
8f3553be
PP
385}
386
387int bt_ctf_field_is_sequence(struct bt_ctf_field *field)
388{
9a19a512 389 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_SEQUENCE;
8f3553be
PP
390}
391
392int bt_ctf_field_is_variant(struct bt_ctf_field *field)
393{
9a19a512 394 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_VARIANT;
8f3553be
PP
395}
396
cd95e351
JG
397struct bt_ctf_field *bt_ctf_field_sequence_get_length(
398 struct bt_ctf_field *field)
399{
400 struct bt_ctf_field *ret = NULL;
401 struct bt_ctf_field_sequence *sequence;
402
403 if (!field) {
404 goto end;
405 }
406
407 if (bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 408 BT_CTF_TYPE_ID_SEQUENCE) {
cd95e351
JG
409 goto end;
410 }
411
412 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
413 ret = sequence->length;
83509119 414 bt_get(ret);
cd95e351
JG
415end:
416 return ret;
417}
418
273b65be
JG
419int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
420 struct bt_ctf_field *length_field)
421{
422 int ret = 0;
423 struct bt_ctf_field_type_integer *length_type;
424 struct bt_ctf_field_integer *length;
425 struct bt_ctf_field_sequence *sequence;
426 uint64_t sequence_length;
427
918be005 428 if (!field || !length_field || field->frozen) {
273b65be
JG
429 ret = -1;
430 goto end;
431 }
432 if (bt_ctf_field_type_get_type_id(length_field->type) !=
9a19a512 433 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
434 ret = -1;
435 goto end;
436 }
437
438 length_type = container_of(length_field->type,
439 struct bt_ctf_field_type_integer, parent);
152e7331 440 /* The length field must be unsigned */
273b65be
JG
441 if (length_type->declaration.signedness) {
442 ret = -1;
443 goto end;
444 }
445
446 length = container_of(length_field, struct bt_ctf_field_integer,
447 parent);
448 sequence_length = length->definition.value._unsigned;
449 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
450 if (sequence->elements) {
451 g_ptr_array_free(sequence->elements, TRUE);
83509119 452 bt_put(sequence->length);
273b65be
JG
453 }
454
fe0fe95c 455 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
273b65be
JG
456 if (!sequence->elements) {
457 ret = -1;
458 goto end;
459 }
460
fe0fe95c 461 g_ptr_array_set_free_func(sequence->elements,
83509119
JG
462 (GDestroyNotify) bt_put);
463 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
464 bt_get(length_field);
273b65be
JG
465 sequence->length = length_field;
466end:
467 return ret;
468}
469
470struct bt_ctf_field *bt_ctf_field_structure_get_field(
471 struct bt_ctf_field *field, const char *name)
472{
473 struct bt_ctf_field *new_field = NULL;
474 GQuark field_quark;
475 struct bt_ctf_field_structure *structure;
b92ddaaa 476 struct bt_ctf_field_type *field_type = NULL;
273b65be
JG
477 size_t index;
478
479 if (!field || !name ||
480 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 481 BT_CTF_TYPE_ID_STRUCT) {
273b65be
JG
482 goto error;
483 }
484
485 field_quark = g_quark_from_string(name);
486 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
487 field_type =
488 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
489 name);
273b65be
JG
490 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
491 GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
492 goto error;
493 }
494
495 if (structure->fields->pdata[index]) {
496 new_field = structure->fields->pdata[index];
497 goto end;
498 }
499
918be005
PP
500 /* We don't want to modify this field if it's frozen */
501 if (field->frozen) {
502 goto end;
503 }
504
273b65be
JG
505 new_field = bt_ctf_field_create(field_type);
506 if (!new_field) {
507 goto error;
508 }
509
510 structure->fields->pdata[index] = new_field;
511end:
83509119 512 bt_get(new_field);
273b65be 513error:
b92ddaaa 514 if (field_type) {
83509119 515 bt_put(field_type);
b92ddaaa 516 }
273b65be
JG
517 return new_field;
518}
519
cd95e351 520struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
074ee56d 521 struct bt_ctf_field *field, int index)
cd95e351
JG
522{
523 int ret;
524 const char *field_name;
525 struct bt_ctf_field_structure *structure;
526 struct bt_ctf_field_type *structure_type;
527 struct bt_ctf_field_type *field_type = NULL;
528 struct bt_ctf_field *ret_field = NULL;
529
530 if (!field ||
9a19a512
PP
531 bt_ctf_field_type_get_type_id(field->type) !=
532 BT_CTF_TYPE_ID_STRUCT) {
cd95e351
JG
533 goto end;
534 }
535
536 structure = container_of(field, struct bt_ctf_field_structure, parent);
537 if (index >= structure->fields->len) {
538 goto error;
539 }
540
541 ret_field = structure->fields->pdata[index];
542 if (ret_field) {
543 goto end;
544 }
545
918be005
PP
546 /* We don't want to modify this field if it's frozen */
547 if (field->frozen) {
548 goto end;
549 }
550
cd95e351
JG
551 /* Field has not been instanciated yet, create it */
552 structure_type = bt_ctf_field_get_type(field);
553 if (!structure_type) {
554 goto error;
555 }
556
557 ret = bt_ctf_field_type_structure_get_field(structure_type,
558 &field_name, &field_type, index);
83509119 559 bt_put(structure_type);
cd95e351
JG
560 if (ret) {
561 goto error;
562 }
563
564 ret_field = bt_ctf_field_create(field_type);
565 if (!ret_field) {
566 goto error;
567 }
568
569 structure->fields->pdata[index] = ret_field;
570end:
83509119 571 bt_get(ret_field);
cd95e351 572error:
83509119 573 bt_put(field_type);
cd95e351
JG
574 return ret_field;
575}
576
273b65be
JG
577BT_HIDDEN
578int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
579 const char *name, struct bt_ctf_field *value)
580{
581 int ret = 0;
582 GQuark field_quark;
583 struct bt_ctf_field_structure *structure;
b92ddaaa 584 struct bt_ctf_field_type *expected_field_type = NULL;
273b65be
JG
585 size_t index;
586
918be005 587 if (!field || !name || !value || field->frozen ||
273b65be 588 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 589 BT_CTF_TYPE_ID_STRUCT) {
273b65be
JG
590 ret = -1;
591 goto end;
592 }
593
594 field_quark = g_quark_from_string(name);
595 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
596 expected_field_type =
597 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
598 name);
09840de5
PP
599
600 if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
273b65be
JG
601 ret = -1;
602 goto end;
603 }
604
605 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
606 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
607 goto end;
608 }
609
610 if (structure->fields->pdata[index]) {
83509119 611 bt_put(structure->fields->pdata[index]);
273b65be
JG
612 }
613
614 structure->fields->pdata[index] = value;
83509119 615 bt_get(value);
273b65be 616end:
b92ddaaa 617 if (expected_field_type) {
83509119 618 bt_put(expected_field_type);
b92ddaaa 619 }
273b65be
JG
620 return ret;
621}
622
623struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
624 uint64_t index)
625{
626 struct bt_ctf_field *new_field = NULL;
b92ddaaa 627 struct bt_ctf_field_type *field_type = NULL;
273b65be 628 struct bt_ctf_field_array *array;
273b65be
JG
629
630 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 631 BT_CTF_TYPE_ID_ARRAY) {
273b65be
JG
632 goto end;
633 }
634
635 array = container_of(field, struct bt_ctf_field_array, parent);
636 if (index >= array->elements->len) {
637 goto end;
638 }
639
b92ddaaa 640 field_type = bt_ctf_field_type_array_get_element_type(field->type);
273b65be
JG
641 if (array->elements->pdata[(size_t)index]) {
642 new_field = array->elements->pdata[(size_t)index];
643 goto end;
644 }
645
918be005
PP
646 /* We don't want to modify this field if it's frozen */
647 if (field->frozen) {
648 goto end;
649 }
650
273b65be 651 new_field = bt_ctf_field_create(field_type);
273b65be
JG
652 array->elements->pdata[(size_t)index] = new_field;
653end:
b92ddaaa 654 if (field_type) {
83509119 655 bt_put(field_type);
b92ddaaa 656 }
92c8b4f9 657 if (new_field) {
83509119 658 bt_get(new_field);
92c8b4f9 659 }
273b65be
JG
660 return new_field;
661}
662
663struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
664 uint64_t index)
665{
666 struct bt_ctf_field *new_field = NULL;
b92ddaaa 667 struct bt_ctf_field_type *field_type = NULL;
273b65be 668 struct bt_ctf_field_sequence *sequence;
273b65be
JG
669
670 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 671 BT_CTF_TYPE_ID_SEQUENCE) {
273b65be
JG
672 goto end;
673 }
674
675 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
676 if (!sequence->elements || sequence->elements->len <= index) {
677 goto end;
678 }
679
b92ddaaa 680 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
83509119
JG
681 if (sequence->elements->pdata[(size_t) index]) {
682 new_field = sequence->elements->pdata[(size_t) index];
273b65be
JG
683 goto end;
684 }
685
918be005
PP
686 /* We don't want to modify this field if it's frozen */
687 if (field->frozen) {
688 goto end;
689 }
690
273b65be 691 new_field = bt_ctf_field_create(field_type);
83509119 692 sequence->elements->pdata[(size_t) index] = new_field;
273b65be 693end:
b92ddaaa 694 if (field_type) {
83509119 695 bt_put(field_type);
b92ddaaa 696 }
92c8b4f9 697 if (new_field) {
83509119 698 bt_get(new_field);
92c8b4f9 699 }
273b65be
JG
700 return new_field;
701}
702
703struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
704 struct bt_ctf_field *tag_field)
705{
706 struct bt_ctf_field *new_field = NULL;
707 struct bt_ctf_field_variant *variant;
708 struct bt_ctf_field_type_variant *variant_type;
709 struct bt_ctf_field_type *field_type;
710 struct bt_ctf_field *tag_enum = NULL;
711 struct bt_ctf_field_integer *tag_enum_integer;
712 int64_t tag_enum_value;
713
714 if (!field || !tag_field ||
715 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 716 BT_CTF_TYPE_ID_VARIANT ||
273b65be 717 bt_ctf_field_type_get_type_id(tag_field->type) !=
9a19a512 718 BT_CTF_TYPE_ID_ENUM) {
273b65be
JG
719 goto end;
720 }
721
722 variant = container_of(field, struct bt_ctf_field_variant, parent);
723 variant_type = container_of(field->type,
724 struct bt_ctf_field_type_variant, parent);
725 tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
726 if (!tag_enum) {
727 goto end;
728 }
729
730 tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
731 parent);
732
2c661a4d 733 if (bt_ctf_field_validate(tag_field) < 0) {
273b65be
JG
734 goto end;
735 }
736
737 tag_enum_value = tag_enum_integer->definition.value._signed;
2829190c
PP
738
739 /*
740 * If the variant currently has a tag and a payload, and if the
741 * requested tag value is the same as the current one, return
742 * the current payload instead of creating a fresh one.
743 */
744 if (variant->tag && variant->payload) {
745 struct bt_ctf_field *cur_tag_container = NULL;
746 struct bt_ctf_field_integer *cur_tag_enum_integer;
747 int64_t cur_tag_value;
748
749 cur_tag_container =
750 bt_ctf_field_enumeration_get_container(variant->tag);
9a5df386 751 assert(cur_tag_container);
2829190c
PP
752 cur_tag_enum_integer = container_of(cur_tag_container,
753 struct bt_ctf_field_integer, parent);
83509119 754 bt_put(cur_tag_container);
2829190c
PP
755 cur_tag_value = cur_tag_enum_integer->definition.value._signed;
756
757 if (cur_tag_value == tag_enum_value) {
758 new_field = variant->payload;
83509119 759 bt_get(new_field);
2829190c
PP
760 goto end;
761 }
762 }
763
918be005
PP
764 /* We don't want to modify this field if it's frozen */
765 if (field->frozen) {
766 goto end;
767 }
768
b92ddaaa
JG
769 field_type = bt_ctf_field_type_variant_get_field_type_signed(
770 variant_type, tag_enum_value);
273b65be
JG
771 if (!field_type) {
772 goto end;
773 }
774
775 new_field = bt_ctf_field_create(field_type);
776 if (!new_field) {
777 goto end;
778 }
779
83509119
JG
780 bt_put(variant->tag);
781 bt_put(variant->payload);
782 bt_get(new_field);
783 bt_get(tag_field);
273b65be
JG
784 variant->tag = tag_field;
785 variant->payload = new_field;
786end:
83509119 787 bt_put(tag_enum);
273b65be
JG
788 return new_field;
789}
790
3f4a108d
PP
791struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
792 struct bt_ctf_field *variant_field)
793{
794 struct bt_ctf_field *current_field = NULL;
795 struct bt_ctf_field_variant *variant;
796
797 if (!variant_field ||
798 bt_ctf_field_type_get_type_id(variant_field->type) !=
9a19a512 799 BT_CTF_TYPE_ID_VARIANT) {
3f4a108d
PP
800 goto end;
801 }
802
803 variant = container_of(variant_field, struct bt_ctf_field_variant,
804 parent);
805
806 if (variant->payload) {
807 current_field = variant->payload;
83509119 808 bt_get(current_field);
3f4a108d
PP
809 goto end;
810 }
811
812end:
813 return current_field;
814}
815
f78d67fb
JG
816struct bt_ctf_field *bt_ctf_field_variant_get_tag(
817 struct bt_ctf_field *variant_field)
818{
819 struct bt_ctf_field *tag = NULL;
820 struct bt_ctf_field_variant *variant;
821
822 if (!variant_field ||
823 bt_ctf_field_type_get_type_id(variant_field->type) !=
824 BT_CTF_TYPE_ID_VARIANT) {
825 goto end;
826 }
827
828 variant = container_of(variant_field, struct bt_ctf_field_variant,
829 parent);
830 if (variant->tag) {
831 tag = bt_get(variant->tag);
832 }
833end:
834 return tag;
835}
836
273b65be
JG
837struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
838 struct bt_ctf_field *field)
839{
840 struct bt_ctf_field *container = NULL;
841 struct bt_ctf_field_enumeration *enumeration;
842
b92ddaaa 843 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 844 BT_CTF_TYPE_ID_ENUM) {
273b65be
JG
845 goto end;
846 }
847
848 enumeration = container_of(field, struct bt_ctf_field_enumeration,
849 parent);
850 if (!enumeration->payload) {
918be005
PP
851 /* We don't want to modify this field if it's frozen */
852 if (field->frozen) {
853 goto end;
854 }
855
273b65be
JG
856 struct bt_ctf_field_type_enumeration *enumeration_type =
857 container_of(field->type,
858 struct bt_ctf_field_type_enumeration, parent);
859 enumeration->payload =
860 bt_ctf_field_create(enumeration_type->container);
861 }
862
863 container = enumeration->payload;
83509119 864 bt_get(container);
273b65be
JG
865end:
866 return container;
867}
868
96e8f959 869const char *bt_ctf_field_enumeration_get_single_mapping_name(
cd95e351
JG
870 struct bt_ctf_field *field)
871{
872 int ret;
873 const char *name = NULL;
874 struct bt_ctf_field *container = NULL;
875 struct bt_ctf_field_type *container_type = NULL;
876 struct bt_ctf_field_type_integer *integer_type = NULL;
96e8f959 877 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
cd95e351
JG
878
879 container = bt_ctf_field_enumeration_get_container(field);
880 if (!container) {
881 goto end;
882 }
883
884 container_type = bt_ctf_field_get_type(container);
885 if (!container_type) {
886 goto error_put_container;
887 }
888
889 integer_type = container_of(container_type,
890 struct bt_ctf_field_type_integer, parent);
cd95e351 891
10817e06 892 if (!integer_type->declaration.signedness) {
cd95e351 893 uint64_t value;
96e8f959 894
cd95e351
JG
895 ret = bt_ctf_field_unsigned_integer_get_value(container,
896 &value);
897 if (ret) {
898 goto error_put_container_type;
899 }
96e8f959
MD
900 iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
901 field->type, value);
902 if (!iter) {
903 goto error_put_container_type;
904 }
905 (void) bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
906 iter, &name, NULL, NULL);
cd95e351
JG
907 } else {
908 int64_t value;
96e8f959 909
cd95e351
JG
910 ret = bt_ctf_field_signed_integer_get_value(container,
911 &value);
912 if (ret) {
913 goto error_put_container_type;
914 }
96e8f959
MD
915 iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
916 field->type, value);
917 if (!iter) {
918 goto error_put_container_type;
919 }
920 (void) bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
921 iter, &name, NULL, NULL);
cd95e351
JG
922 }
923
924error_put_container_type:
83509119 925 bt_put(container_type);
cd95e351 926error_put_container:
83509119 927 bt_put(container);
cd95e351
JG
928end:
929 return name;
930}
931
932int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
933 int64_t *value)
934{
935 int ret = 0;
936 struct bt_ctf_field_integer *integer;
937 struct bt_ctf_field_type_integer *integer_type;
938
939 if (!field || !value || !field->payload_set ||
940 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 941 BT_CTF_TYPE_ID_INTEGER) {
cd95e351
JG
942 ret = -1;
943 goto end;
944 }
945
946 integer_type = container_of(field->type,
947 struct bt_ctf_field_type_integer, parent);
948 if (!integer_type->declaration.signedness) {
949 ret = -1;
950 goto end;
951 }
952
953 integer = container_of(field,
954 struct bt_ctf_field_integer, parent);
955 *value = integer->definition.value._signed;
956end:
957 return ret;
958}
959
273b65be
JG
960int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
961 int64_t value)
962{
963 int ret = 0;
964 struct bt_ctf_field_integer *integer;
965 struct bt_ctf_field_type_integer *integer_type;
966 unsigned int size;
967 int64_t min_value, max_value;
968
918be005 969 if (!field || field->frozen ||
273b65be 970 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 971 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
972 ret = -1;
973 goto end;
974 }
975
976 integer = container_of(field, struct bt_ctf_field_integer, parent);
977 integer_type = container_of(field->type,
978 struct bt_ctf_field_type_integer, parent);
979 if (!integer_type->declaration.signedness) {
980 ret = -1;
981 goto end;
982 }
983
984 size = integer_type->declaration.len;
9dc0d640
JG
985 min_value = -(1ULL << (size - 1));
986 max_value = (1ULL << (size - 1)) - 1;
273b65be
JG
987 if (value < min_value || value > max_value) {
988 ret = -1;
989 goto end;
990 }
991
992 integer->definition.value._signed = value;
993 integer->parent.payload_set = 1;
994end:
995 return ret;
996}
997
cd95e351
JG
998int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
999 uint64_t *value)
1000{
1001 int ret = 0;
1002 struct bt_ctf_field_integer *integer;
1003 struct bt_ctf_field_type_integer *integer_type;
1004
1005 if (!field || !value || !field->payload_set ||
1006 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1007 BT_CTF_TYPE_ID_INTEGER) {
cd95e351
JG
1008 ret = -1;
1009 goto end;
1010 }
1011
1012 integer_type = container_of(field->type,
1013 struct bt_ctf_field_type_integer, parent);
1014 if (integer_type->declaration.signedness) {
1015 ret = -1;
1016 goto end;
1017 }
1018
1019 integer = container_of(field,
1020 struct bt_ctf_field_integer, parent);
1021 *value = integer->definition.value._unsigned;
1022end:
1023 return ret;
1024}
1025
273b65be
JG
1026int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
1027 uint64_t value)
1028{
1029 int ret = 0;
1030 struct bt_ctf_field_integer *integer;
1031 struct bt_ctf_field_type_integer *integer_type;
1032 unsigned int size;
1033 uint64_t max_value;
1034
918be005 1035 if (!field || field->frozen ||
273b65be 1036 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1037 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
1038 ret = -1;
1039 goto end;
1040 }
1041
1042 integer = container_of(field, struct bt_ctf_field_integer, parent);
1043 integer_type = container_of(field->type,
1044 struct bt_ctf_field_type_integer, parent);
1045 if (integer_type->declaration.signedness) {
1046 ret = -1;
1047 goto end;
1048 }
1049
1050 size = integer_type->declaration.len;
8684abc8 1051 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
273b65be
JG
1052 if (value > max_value) {
1053 ret = -1;
1054 goto end;
1055 }
1056
1057 integer->definition.value._unsigned = value;
1058 integer->parent.payload_set = 1;
1059end:
1060 return ret;
1061}
1062
cd95e351
JG
1063int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1064 double *value)
1065{
1066 int ret = 0;
1067 struct bt_ctf_field_floating_point *floating_point;
1068
1069 if (!field || !value || !field->payload_set ||
1070 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1071 BT_CTF_TYPE_ID_FLOAT) {
cd95e351
JG
1072 ret = -1;
1073 goto end;
1074 }
1075
1076 floating_point = container_of(field,
1077 struct bt_ctf_field_floating_point, parent);
1078 *value = floating_point->definition.value;
1079end:
1080 return ret;
1081}
1082
273b65be
JG
1083int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1084 double value)
1085{
1086 int ret = 0;
1087 struct bt_ctf_field_floating_point *floating_point;
1088
918be005 1089 if (!field || field->frozen ||
273b65be 1090 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1091 BT_CTF_TYPE_ID_FLOAT) {
273b65be
JG
1092 ret = -1;
1093 goto end;
1094 }
1095 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1096 parent);
1097 floating_point->definition.value = value;
1098 floating_point->parent.payload_set = 1;
1099end:
1100 return ret;
1101}
1102
cd95e351
JG
1103const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1104{
1105 const char *ret = NULL;
1106 struct bt_ctf_field_string *string;
1107
1108 if (!field || !field->payload_set ||
1109 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1110 BT_CTF_TYPE_ID_STRING) {
cd95e351
JG
1111 goto end;
1112 }
1113
1114 string = container_of(field,
1115 struct bt_ctf_field_string, parent);
1116 ret = string->payload->str;
1117end:
1118 return ret;
1119}
1120
273b65be
JG
1121int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
1122 const char *value)
1123{
1124 int ret = 0;
1125 struct bt_ctf_field_string *string;
1126
918be005 1127 if (!field || !value || field->frozen ||
273b65be 1128 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1129 BT_CTF_TYPE_ID_STRING) {
273b65be
JG
1130 ret = -1;
1131 goto end;
1132 }
1133
1134 string = container_of(field, struct bt_ctf_field_string, parent);
1135 if (string->payload) {
97736814
JG
1136 g_string_assign(string->payload, value);
1137 } else {
1138 string->payload = g_string_new(value);
273b65be
JG
1139 }
1140
273b65be
JG
1141 string->parent.payload_set = 1;
1142end:
1143 return ret;
1144}
1145
c6f9c5a3
PP
1146int bt_ctf_field_string_append(struct bt_ctf_field *field,
1147 const char *value)
1148{
1149 int ret = 0;
1150 struct bt_ctf_field_string *string_field;
1151
918be005 1152 if (!field || !value || field->frozen ||
c6f9c5a3 1153 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1154 BT_CTF_TYPE_ID_STRING) {
c6f9c5a3
PP
1155 ret = -1;
1156 goto end;
1157 }
1158
1159 string_field = container_of(field, struct bt_ctf_field_string, parent);
1160
1161 if (string_field->payload) {
1162 g_string_append(string_field->payload, value);
1163 } else {
1164 string_field->payload = g_string_new(value);
1165 }
1166
1167 string_field->parent.payload_set = 1;
1168
1169end:
1170 return ret;
1171}
1172
f98c6554
PP
1173int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1174 const char *value, unsigned int length)
1175{
1176 int i;
1177 int ret = 0;
1178 unsigned int effective_length = length;
1179 struct bt_ctf_field_string *string_field;
1180
918be005 1181 if (!field || !value || field->frozen ||
f98c6554 1182 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1183 BT_CTF_TYPE_ID_STRING) {
f98c6554
PP
1184 ret = -1;
1185 goto end;
1186 }
1187
1188 string_field = container_of(field, struct bt_ctf_field_string, parent);
1189
1190 /* make sure no null bytes are appended */
1191 for (i = 0; i < length; ++i) {
1192 if (value[i] == '\0') {
1193 effective_length = i;
1194 break;
1195 }
1196 }
1197
1198 if (string_field->payload) {
ce6d5230 1199 g_string_append_len(string_field->payload, value,
f98c6554
PP
1200 effective_length);
1201 } else {
1202 string_field->payload = g_string_new_len(value,
1203 effective_length);
1204 }
1205
1206 string_field->parent.payload_set = 1;
1207
1208end:
1209 return ret;
1210}
1211
273b65be
JG
1212BT_HIDDEN
1213int bt_ctf_field_validate(struct bt_ctf_field *field)
1214{
1215 int ret = 0;
9a19a512 1216 enum bt_ctf_type_id type_id;
273b65be
JG
1217
1218 if (!field) {
1219 ret = -1;
1220 goto end;
1221 }
1222
1223 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1224 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1225 ret = -1;
1226 goto end;
1227 }
1228
1229 ret = field_validate_funcs[type_id](field);
1230end:
1231 return ret;
1232}
1233
12c8a1a3
JG
1234BT_HIDDEN
1235int bt_ctf_field_reset(struct bt_ctf_field *field)
1236{
1237 int ret = 0;
9a19a512 1238 enum bt_ctf_type_id type_id;
12c8a1a3
JG
1239
1240 if (!field) {
1241 ret = -1;
1242 goto end;
1243 }
1244
1245 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1246 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
12c8a1a3
JG
1247 ret = -1;
1248 goto end;
1249 }
1250
1251 ret = field_reset_funcs[type_id](field);
1252end:
1253 return ret;
1254}
1255
273b65be
JG
1256BT_HIDDEN
1257int bt_ctf_field_serialize(struct bt_ctf_field *field,
1258 struct ctf_stream_pos *pos)
1259{
1260 int ret = 0;
9a19a512 1261 enum bt_ctf_type_id type_id;
273b65be
JG
1262
1263 if (!field || !pos) {
1264 ret = -1;
1265 goto end;
1266 }
1267
1268 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1269 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1270 ret = -1;
1271 goto end;
1272 }
1273
1274 ret = field_serialize_funcs[type_id](field, pos);
1275end:
1276 return ret;
1277}
1278
76f869ab
JG
1279
1280BT_HIDDEN
1281bool bt_ctf_field_is_set(struct bt_ctf_field *field)
1282{
1283 bool is_set = false;
1284 enum bt_ctf_type_id type_id;
1285
1286 if (!field) {
1287 goto end;
1288 }
1289
1290 type_id = bt_ctf_field_type_get_type_id(field->type);
1291 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1292 goto end;
1293 }
1294
1295 is_set = field_is_set_funcs[type_id](field);
1296end:
1297 return is_set;
1298}
1299
87d43dc1
JG
1300struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1301{
1302 int ret;
1303 struct bt_ctf_field *copy = NULL;
9a19a512 1304 enum bt_ctf_type_id type_id;
87d43dc1
JG
1305
1306 if (!field) {
87d43dc1
JG
1307 goto end;
1308 }
1309
1310 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1311 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
87d43dc1
JG
1312 goto end;
1313 }
1314
1315 copy = bt_ctf_field_create(field->type);
1316 if (!copy) {
1317 goto end;
1318 }
1319
70996764 1320 copy->payload_set = field->payload_set;
87d43dc1
JG
1321 ret = field_copy_funcs[type_id](field, copy);
1322 if (ret) {
83509119 1323 bt_put(copy);
87d43dc1
JG
1324 copy = NULL;
1325 }
1326end:
1327 return copy;
1328}
1329
273b65be
JG
1330static
1331struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1332{
1333 struct bt_ctf_field_type_integer *integer_type = container_of(type,
1334 struct bt_ctf_field_type_integer, parent);
1335 struct bt_ctf_field_integer *integer = g_new0(
1336 struct bt_ctf_field_integer, 1);
1337
1338 if (integer) {
1339 integer->definition.declaration = &integer_type->declaration;
1340 }
1341
1342 return integer ? &integer->parent : NULL;
1343}
1344
1345static
1346struct bt_ctf_field *bt_ctf_field_enumeration_create(
1347 struct bt_ctf_field_type *type)
1348{
1349 struct bt_ctf_field_enumeration *enumeration = g_new0(
1350 struct bt_ctf_field_enumeration, 1);
1351
1352 return enumeration ? &enumeration->parent : NULL;
1353}
1354
1355static
1356struct bt_ctf_field *bt_ctf_field_floating_point_create(
1357 struct bt_ctf_field_type *type)
1358{
1359 struct bt_ctf_field_floating_point *floating_point;
1360 struct bt_ctf_field_type_floating_point *floating_point_type;
1361
1362 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
1363 if (!floating_point) {
1364 goto end;
1365 }
1366
1367 floating_point_type = container_of(type,
1368 struct bt_ctf_field_type_floating_point, parent);
1369 floating_point->definition.declaration = container_of(
1370 type->declaration, struct declaration_float, p);
1371
1372
1373 floating_point->definition.sign = &floating_point->sign;
1374 floating_point->sign.declaration = &floating_point_type->sign;
1375 floating_point->definition.sign->p.declaration =
1376 &floating_point_type->sign.p;
1377
1378 floating_point->definition.mantissa = &floating_point->mantissa;
1379 floating_point->mantissa.declaration = &floating_point_type->mantissa;
1380 floating_point->definition.mantissa->p.declaration =
1381 &floating_point_type->mantissa.p;
1382
1383 floating_point->definition.exp = &floating_point->exp;
1384 floating_point->exp.declaration = &floating_point_type->exp;
1385 floating_point->definition.exp->p.declaration =
1386 &floating_point_type->exp.p;
1387
1388end:
1389 return floating_point ? &floating_point->parent : NULL;
1390}
1391
1392static
1393struct bt_ctf_field *bt_ctf_field_structure_create(
1394 struct bt_ctf_field_type *type)
1395{
1396 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1397 struct bt_ctf_field_type_structure, parent);
1398 struct bt_ctf_field_structure *structure = g_new0(
1399 struct bt_ctf_field_structure, 1);
1400 struct bt_ctf_field *field = NULL;
1401
8c1aa858 1402 if (!structure) {
273b65be
JG
1403 goto end;
1404 }
1405
1406 structure->field_name_to_index = structure_type->field_name_to_index;
1407 structure->fields = g_ptr_array_new_with_free_func(
1408 (GDestroyNotify)bt_ctf_field_put);
1409 g_ptr_array_set_size(structure->fields,
1410 g_hash_table_size(structure->field_name_to_index));
1411 field = &structure->parent;
1412end:
1413 return field;
1414}
1415
1416static
1417struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1418{
1419 struct bt_ctf_field_variant *variant = g_new0(
1420 struct bt_ctf_field_variant, 1);
1421 return variant ? &variant->parent : NULL;
1422}
1423
1424static
1425struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1426{
1427 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1428 struct bt_ctf_field_type_array *array_type;
1429 unsigned int array_length;
1430
1431 if (!array || !type) {
1432 goto error;
1433 }
1434
1435 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1436 array_length = array_type->length;
fe0fe95c 1437 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1438 if (!array->elements) {
1439 goto error;
1440 }
1441
fe0fe95c
JG
1442 g_ptr_array_set_free_func(array->elements,
1443 (GDestroyNotify)bt_ctf_field_put);
273b65be
JG
1444 g_ptr_array_set_size(array->elements, array_length);
1445 return &array->parent;
1446error:
1447 g_free(array);
1448 return NULL;
1449}
1450
1451static
1452struct bt_ctf_field *bt_ctf_field_sequence_create(
1453 struct bt_ctf_field_type *type)
1454{
1455 struct bt_ctf_field_sequence *sequence = g_new0(
1456 struct bt_ctf_field_sequence, 1);
1457 return sequence ? &sequence->parent : NULL;
1458}
1459
1460static
1461struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1462{
1463 struct bt_ctf_field_string *string = g_new0(
1464 struct bt_ctf_field_string, 1);
1465 return string ? &string->parent : NULL;
1466}
1467
1468static
83509119 1469void bt_ctf_field_destroy(struct bt_object *obj)
273b65be
JG
1470{
1471 struct bt_ctf_field *field;
1472 struct bt_ctf_field_type *type;
9a19a512 1473 enum bt_ctf_type_id type_id;
273b65be 1474
83509119 1475 field = container_of(obj, struct bt_ctf_field, base);
273b65be
JG
1476 type = field->type;
1477 type_id = bt_ctf_field_type_get_type_id(type);
9a19a512
PP
1478 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
1479 type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1480 return;
1481 }
1482
1483 field_destroy_funcs[type_id](field);
83509119 1484 bt_put(type);
273b65be
JG
1485}
1486
1487static
1488void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1489{
1490 struct bt_ctf_field_integer *integer;
1491
1492 if (!field) {
1493 return;
1494 }
1495
1496 integer = container_of(field, struct bt_ctf_field_integer, parent);
1497 g_free(integer);
1498}
1499
1500static
1501void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1502{
1503 struct bt_ctf_field_enumeration *enumeration;
1504
1505 if (!field) {
1506 return;
1507 }
1508
1509 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1510 parent);
83509119 1511 bt_put(enumeration->payload);
273b65be
JG
1512 g_free(enumeration);
1513}
1514
1515static
1516void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
1517{
1518 struct bt_ctf_field_floating_point *floating_point;
1519
1520 if (!field) {
1521 return;
1522 }
1523
1524 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1525 parent);
1526 g_free(floating_point);
1527}
1528
1529static
1530void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
1531{
1532 struct bt_ctf_field_structure *structure;
1533
1534 if (!field) {
1535 return;
1536 }
1537
1538 structure = container_of(field, struct bt_ctf_field_structure, parent);
1539 g_ptr_array_free(structure->fields, TRUE);
1540 g_free(structure);
1541}
1542
1543static
1544void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
1545{
1546 struct bt_ctf_field_variant *variant;
1547
1548 if (!field) {
1549 return;
1550 }
1551
1552 variant = container_of(field, struct bt_ctf_field_variant, parent);
83509119
JG
1553 bt_put(variant->tag);
1554 bt_put(variant->payload);
273b65be
JG
1555 g_free(variant);
1556}
1557
1558static
1559void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
1560{
1561 struct bt_ctf_field_array *array;
1562
1563 if (!field) {
1564 return;
1565 }
1566
1567 array = container_of(field, struct bt_ctf_field_array, parent);
1568 g_ptr_array_free(array->elements, TRUE);
1569 g_free(array);
1570}
1571
1572static
1573void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
1574{
1575 struct bt_ctf_field_sequence *sequence;
1576
1577 if (!field) {
1578 return;
1579 }
1580
1581 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
4fef87ab
JG
1582 if (sequence->elements) {
1583 g_ptr_array_free(sequence->elements, TRUE);
1584 }
83509119 1585 bt_put(sequence->length);
273b65be
JG
1586 g_free(sequence);
1587}
1588
1589static
1590void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
1591{
1592 struct bt_ctf_field_string *string;
1593 if (!field) {
1594 return;
1595 }
1596
1597 string = container_of(field, struct bt_ctf_field_string, parent);
9b2b7163
JG
1598 if (string->payload) {
1599 g_string_free(string->payload, TRUE);
1600 }
273b65be
JG
1601 g_free(string);
1602}
1603
1604static
1605int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1606{
da2f6971 1607 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
1608}
1609
1610static
1611int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
1612{
1613 int ret;
1614 struct bt_ctf_field_enumeration *enumeration;
1615
1616 if (!field) {
1617 ret = -1;
1618 goto end;
1619 }
1620
1621 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1622 parent);
1623 if (!enumeration->payload) {
1624 ret = -1;
1625 goto end;
1626 }
1627
1628 ret = bt_ctf_field_validate(enumeration->payload);
1629end:
1630 return ret;
1631}
1632
1633static
1634int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
1635{
1636 size_t i;
1637 int ret = 0;
1638 struct bt_ctf_field_structure *structure;
1639
1640 if (!field) {
1641 ret = -1;
1642 goto end;
1643 }
1644
1645 structure = container_of(field, struct bt_ctf_field_structure, parent);
1646 for (i = 0; i < structure->fields->len; i++) {
1647 ret = bt_ctf_field_validate(structure->fields->pdata[i]);
1648 if (ret) {
6ce12048
JG
1649 const char *name;
1650 struct bt_ctf_field_type *field_type =
1651 bt_ctf_field_get_type(field);
1652
1653 (void) bt_ctf_field_type_structure_get_field(field_type,
1654 &name, NULL, i);
1655 fprintf(stderr, "Field %s failed validation\n",
1656 name ? name : "NULL");
e5ed1ccf 1657 bt_put(field_type);
273b65be
JG
1658 goto end;
1659 }
1660 }
1661end:
1662 return ret;
1663}
1664
1665static
1666int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1667{
1668 int ret = 0;
1669 struct bt_ctf_field_variant *variant;
1670
1671 if (!field) {
1672 ret = -1;
1673 goto end;
1674 }
1675
1676 variant = container_of(field, struct bt_ctf_field_variant, parent);
1677 ret = bt_ctf_field_validate(variant->payload);
1678end:
1679 return ret;
1680}
1681
1682static
1683int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1684{
1685 size_t i;
1686 int ret = 0;
1687 struct bt_ctf_field_array *array;
1688
1689 if (!field) {
1690 ret = -1;
1691 goto end;
1692 }
1693
1694 array = container_of(field, struct bt_ctf_field_array, parent);
1695 for (i = 0; i < array->elements->len; i++) {
1696 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1697 if (ret) {
e91f3bab 1698 fprintf(stderr, "Failed to validate array field #%zu\n", i);
273b65be
JG
1699 goto end;
1700 }
1701 }
1702end:
1703 return ret;
1704}
1705
1706static
1707int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1708{
1709 size_t i;
1710 int ret = 0;
1711 struct bt_ctf_field_sequence *sequence;
1712
1713 if (!field) {
1714 ret = -1;
1715 goto end;
1716 }
1717
1718 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1719 for (i = 0; i < sequence->elements->len; i++) {
1720 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1721 if (ret) {
bcfb49d4 1722 fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
273b65be
JG
1723 goto end;
1724 }
1725 }
1726end:
1727 return ret;
1728}
1729
12c8a1a3
JG
1730static
1731int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1732{
1733 int ret = 0;
1734
1735 if (!field) {
1736 ret = -1;
1737 goto end;
1738 }
1739
1740 field->payload_set = 0;
1741end:
1742 return ret;
1743}
1744
1745static
1746int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1747{
1748 int ret = 0;
1749 struct bt_ctf_field_enumeration *enumeration;
1750
1751 if (!field) {
1752 ret = -1;
1753 goto end;
1754 }
1755
1756 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1757 parent);
1758 if (!enumeration->payload) {
1759 goto end;
1760 }
1761
1762 ret = bt_ctf_field_reset(enumeration->payload);
1763end:
1764 return ret;
1765}
1766
1767static
1768int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1769{
1770 size_t i;
1771 int ret = 0;
1772 struct bt_ctf_field_structure *structure;
1773
1774 if (!field) {
1775 ret = -1;
1776 goto end;
1777 }
1778
1779 structure = container_of(field, struct bt_ctf_field_structure, parent);
1780 for (i = 0; i < structure->fields->len; i++) {
1781 struct bt_ctf_field *member = structure->fields->pdata[i];
1782
1783 if (!member) {
1784 /*
1785 * Structure members are lazily initialized; skip if
1786 * this member has not been allocated yet.
1787 */
1788 continue;
1789 }
1790
1791 ret = bt_ctf_field_reset(member);
1792 if (ret) {
1793 goto end;
1794 }
1795 }
1796end:
1797 return ret;
1798}
1799
1800static
1801int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1802{
1803 int ret = 0;
1804 struct bt_ctf_field_variant *variant;
1805
1806 if (!field) {
1807 ret = -1;
1808 goto end;
1809 }
1810
1811 variant = container_of(field, struct bt_ctf_field_variant, parent);
1812 if (variant->payload) {
1813 ret = bt_ctf_field_reset(variant->payload);
1814 }
1815end:
1816 return ret;
1817}
1818
1819static
1820int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1821{
1822 size_t i;
1823 int ret = 0;
1824 struct bt_ctf_field_array *array;
1825
1826 if (!field) {
1827 ret = -1;
1828 goto end;
1829 }
1830
1831 array = container_of(field, struct bt_ctf_field_array, parent);
1832 for (i = 0; i < array->elements->len; i++) {
1833 struct bt_ctf_field *member = array->elements->pdata[i];
1834
1835 if (!member) {
1836 /*
1837 * Array elements are lazily initialized; skip if
1838 * this member has not been allocated yet.
1839 */
1840 continue;
1841 }
1842
1843 ret = bt_ctf_field_reset(member);
1844 if (ret) {
1845 goto end;
1846 }
1847 }
1848end:
1849 return ret;
1850}
1851
1852static
1853int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1854{
1855 size_t i;
1856 int ret = 0;
1857 struct bt_ctf_field_sequence *sequence;
1858
1859 if (!field) {
1860 ret = -1;
1861 goto end;
1862 }
1863
1864 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1865 for (i = 0; i < sequence->elements->len; i++) {
1866 struct bt_ctf_field *member = sequence->elements->pdata[i];
1867
1868 if (!member) {
1869 /*
1870 * Sequence elements are lazily initialized; skip if
1871 * this member has not been allocated yet.
1872 */
1873 continue;
1874 }
1875
1876 ret = bt_ctf_field_reset(member);
1877 if (ret) {
1878 goto end;
1879 }
1880 }
1881end:
1882 return ret;
1883}
1884
1885static
1886int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1887{
1888 int ret = 0;
1889 struct bt_ctf_field_string *string;
1890
1891 if (!field) {
1892 ret = -1;
1893 goto end;
1894 }
1895
1896 ret = bt_ctf_field_generic_reset(field);
1897 if (ret) {
1898 goto end;
1899 }
1900
1901 string = container_of(field, struct bt_ctf_field_string, parent);
1902 if (string->payload) {
1903 g_string_truncate(string->payload, 0);
1904 }
1905end:
1906 return ret;
1907}
1908
273b65be
JG
1909static
1910int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1911 struct ctf_stream_pos *pos)
1912{
1913 int ret = 0;
1914 struct bt_ctf_field_integer *integer = container_of(field,
1915 struct bt_ctf_field_integer, parent);
1916
1917retry:
1918 ret = ctf_integer_write(&pos->parent, &integer->definition.p);
1919 if (ret == -EFAULT) {
1920 /*
1921 * The field is too large to fit in the current packet's
1922 * remaining space. Bump the packet size and retry.
1923 */
1924 ret = increase_packet_size(pos);
1925 if (ret) {
1926 goto end;
1927 }
1928 goto retry;
1929 }
1930end:
1931 return ret;
1932}
1933
1934static
1935int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1936 struct ctf_stream_pos *pos)
1937{
1938 struct bt_ctf_field_enumeration *enumeration = container_of(
1939 field, struct bt_ctf_field_enumeration, parent);
1940
1941 return bt_ctf_field_serialize(enumeration->payload, pos);
1942}
1943
1944static
1945int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1946 struct ctf_stream_pos *pos)
1947{
1948 int ret = 0;
1949 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1950 struct bt_ctf_field_floating_point, parent);
1951
1952retry:
1953 ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
1954 if (ret == -EFAULT) {
1955 /*
1956 * The field is too large to fit in the current packet's
1957 * remaining space. Bump the packet size and retry.
1958 */
1959 ret = increase_packet_size(pos);
1960 if (ret) {
1961 goto end;
1962 }
1963 goto retry;
1964 }
1965end:
1966 return ret;
1967}
1968
1969static
1970int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1971 struct ctf_stream_pos *pos)
1972{
1973 size_t i;
1974 int ret = 0;
1975 struct bt_ctf_field_structure *structure = container_of(
1976 field, struct bt_ctf_field_structure, parent);
1977
1978 while (!ctf_pos_access_ok(pos,
1979 offset_align(pos->offset,
1980 field->type->declaration->alignment))) {
9f56e450
JG
1981 ret = increase_packet_size(pos);
1982 if (ret) {
1983 goto end;
1984 }
273b65be
JG
1985 }
1986
70fd5a51
MD
1987 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1988 ret = -1;
1989 goto end;
1990 }
273b65be
JG
1991
1992 for (i = 0; i < structure->fields->len; i++) {
1993 struct bt_ctf_field *field = g_ptr_array_index(
1994 structure->fields, i);
1995
1996 ret = bt_ctf_field_serialize(field, pos);
1997 if (ret) {
bcfb49d4
JG
1998 const char *name;
1999 struct bt_ctf_field_type *field_type =
2000 bt_ctf_field_get_type(field);
2001
2002 (void) bt_ctf_field_type_structure_get_field(field_type,
2003 &name, NULL, i);
2004 fprintf(stderr, "Field %s failed to serialize\n",
2005 name ? name : "NULL");
2006 bt_put(field_type);
273b65be
JG
2007 break;
2008 }
2009 }
9f56e450 2010end:
273b65be
JG
2011 return ret;
2012}
2013
2014static
2015int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
2016 struct ctf_stream_pos *pos)
2017{
2018 struct bt_ctf_field_variant *variant = container_of(
2019 field, struct bt_ctf_field_variant, parent);
2020
2021 return bt_ctf_field_serialize(variant->payload, pos);
2022}
2023
2024static
2025int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
2026 struct ctf_stream_pos *pos)
2027{
2028 size_t i;
2029 int ret = 0;
2030 struct bt_ctf_field_array *array = container_of(
2031 field, struct bt_ctf_field_array, parent);
2032
2033 for (i = 0; i < array->elements->len; i++) {
2034 ret = bt_ctf_field_serialize(
2035 g_ptr_array_index(array->elements, i), pos);
2036 if (ret) {
bcfb49d4 2037 fprintf(stderr, "Failed to serialize array element #%zu\n", i);
273b65be
JG
2038 goto end;
2039 }
2040 }
2041end:
2042 return ret;
2043}
2044
2045static
2046int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
2047 struct ctf_stream_pos *pos)
2048{
2049 size_t i;
2050 int ret = 0;
2051 struct bt_ctf_field_sequence *sequence = container_of(
2052 field, struct bt_ctf_field_sequence, parent);
2053
2054 for (i = 0; i < sequence->elements->len; i++) {
2055 ret = bt_ctf_field_serialize(
2056 g_ptr_array_index(sequence->elements, i), pos);
2057 if (ret) {
bcfb49d4 2058 fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
273b65be
JG
2059 goto end;
2060 }
2061 }
2062end:
2063 return ret;
2064}
2065
2066static
2067int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
2068 struct ctf_stream_pos *pos)
2069{
2070 size_t i;
2071 int ret = 0;
2072 struct bt_ctf_field_string *string = container_of(field,
2073 struct bt_ctf_field_string, parent);
2074 struct bt_ctf_field_type *character_type =
2075 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
2076 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
2077
2078 for (i = 0; i < string->payload->len + 1; i++) {
2079 ret = bt_ctf_field_unsigned_integer_set_value(character,
2080 (uint64_t) string->payload->str[i]);
2081 if (ret) {
2082 goto end;
2083 }
2084
2085 ret = bt_ctf_field_integer_serialize(character, pos);
2086 if (ret) {
2087 goto end;
2088 }
2089 }
2090end:
83509119
JG
2091 bt_put(character);
2092 bt_put(character_type);
273b65be
JG
2093 return ret;
2094}
2095
87d43dc1
JG
2096static
2097int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2098 struct bt_ctf_field *dst)
2099{
2100 struct bt_ctf_field_integer *integer_src, *integer_dst;
2101
2102 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
8bfa3f9c 2103 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
87d43dc1
JG
2104
2105 memcpy(&integer_dst->definition, &integer_src->definition,
2106 sizeof(struct definition_integer));
2107 return 0;
2108}
2109
2110static
2111int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2112 struct bt_ctf_field *dst)
2113{
2114 int ret = 0;
2115 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2116
2117 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2118 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2119
2120 if (enum_src->payload) {
2121 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2122 if (!enum_dst->payload) {
2123 ret = -1;
2124 goto end;
2125 }
2126 }
2127end:
2128 return ret;
2129}
2130
2131static
2132int bt_ctf_field_floating_point_copy(
2133 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2134{
2135 struct bt_ctf_field_floating_point *float_src, *float_dst;
2136
2137 float_src = container_of(src, struct bt_ctf_field_floating_point,
2138 parent);
2139 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2140 parent);
2141
2142 memcpy(&float_dst->definition, &float_src->definition,
2143 sizeof(struct definition_float));
2144 memcpy(&float_dst->sign, &float_src->sign,
2145 sizeof(struct definition_integer));
2146 memcpy(&float_dst->mantissa, &float_src->mantissa,
2147 sizeof(struct definition_integer));
2148 memcpy(&float_dst->exp, &float_src->exp,
2149 sizeof(struct definition_integer));
2150 return 0;
2151}
2152
2153static
2154int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2155 struct bt_ctf_field *dst)
2156{
8bfa3f9c 2157 int ret = 0, i;
87d43dc1
JG
2158 struct bt_ctf_field_structure *struct_src, *struct_dst;
2159
2160 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2161 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2162
8bfa3f9c 2163 /* This field_name_to_index HT is owned by the structure field type */
87d43dc1 2164 struct_dst->field_name_to_index = struct_src->field_name_to_index;
8bfa3f9c 2165 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
2166
2167 for (i = 0; i < struct_src->fields->len; i++) {
50fd95bf
PP
2168 struct bt_ctf_field *field =
2169 g_ptr_array_index(struct_src->fields, i);
2170 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2171
50fd95bf
PP
2172 if (field) {
2173 field_copy = bt_ctf_field_copy(field);
2174
2175 if (!field_copy) {
2176 ret = -1;
2177 goto end;
2178 }
87d43dc1 2179 }
50fd95bf 2180
8bfa3f9c 2181 g_ptr_array_index(struct_dst->fields, i) = field_copy;
87d43dc1
JG
2182 }
2183end:
2184 return ret;
2185}
2186
2187static
2188int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2189 struct bt_ctf_field *dst)
2190{
2191 int ret = 0;
2192 struct bt_ctf_field_variant *variant_src, *variant_dst;
2193
2194 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2195 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2196
2197 if (variant_src->tag) {
2198 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2199 if (!variant_dst->tag) {
2200 ret = -1;
2201 goto end;
2202 }
2203 }
2204 if (variant_src->payload) {
2205 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2206 if (!variant_dst->payload) {
2207 ret = -1;
2208 goto end;
2209 }
2210 }
2211end:
2212 return ret;
2213}
2214
2215static
2216int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2217 struct bt_ctf_field *dst)
2218{
2219 int ret = 0, i;
2220 struct bt_ctf_field_array *array_src, *array_dst;
2221
2222 array_src = container_of(src, struct bt_ctf_field_array, parent);
2223 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2224
8bfa3f9c 2225 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1 2226 for (i = 0; i < array_src->elements->len; i++) {
50fd95bf
PP
2227 struct bt_ctf_field *field =
2228 g_ptr_array_index(array_src->elements, i);
2229 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2230
50fd95bf
PP
2231 if (field) {
2232 field_copy = bt_ctf_field_copy(field);
2233
2234 if (!field_copy) {
2235 ret = -1;
2236 goto end;
2237 }
87d43dc1 2238 }
50fd95bf 2239
8bfa3f9c 2240 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1
JG
2241 }
2242end:
2243 return ret;
2244}
2245
2246static
2247int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2248 struct bt_ctf_field *dst)
2249{
2250 int ret = 0, i;
2251 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
59ab494d
PP
2252 struct bt_ctf_field *src_length;
2253 struct bt_ctf_field *dst_length;
87d43dc1
JG
2254
2255 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2256 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2257
59ab494d
PP
2258 src_length = bt_ctf_field_sequence_get_length(src);
2259
2260 if (!src_length) {
2261 /* no length set yet: keep destination sequence empty */
2262 goto end;
2263 }
2264
2265 /* copy source length */
2266 dst_length = bt_ctf_field_copy(src_length);
83509119 2267 bt_put(src_length);
59ab494d
PP
2268
2269 if (!dst_length) {
2270 ret = -1;
2271 goto end;
2272 }
2273
2274 /* this will initialize the destination sequence's internal array */
2275 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
83509119 2276 bt_put(dst_length);
59ab494d
PP
2277
2278 if (ret) {
2279 goto end;
2280 }
2281
2282 assert(sequence_dst->elements->len == sequence_src->elements->len);
2283
87d43dc1 2284 for (i = 0; i < sequence_src->elements->len; i++) {
50fd95bf
PP
2285 struct bt_ctf_field *field =
2286 g_ptr_array_index(sequence_src->elements, i);
2287 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2288
50fd95bf
PP
2289 if (field) {
2290 field_copy = bt_ctf_field_copy(field);
2291
2292 if (!field_copy) {
2293 ret = -1;
2294 goto end;
2295 }
87d43dc1 2296 }
59ab494d 2297
8bfa3f9c 2298 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1
JG
2299 }
2300end:
2301 return ret;
2302}
2303
2304static
2305int bt_ctf_field_string_copy(struct bt_ctf_field *src,
2306 struct bt_ctf_field *dst)
2307{
2308 int ret = 0;
2309 struct bt_ctf_field_string *string_src, *string_dst;
2310
2311 string_src = container_of(src, struct bt_ctf_field_string, parent);
2312 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
2313
2314 if (string_src->payload) {
2315 string_dst->payload = g_string_new(string_src->payload->str);
2316 if (!string_dst->payload) {
2317 ret = -1;
2318 goto end;
2319 }
2320 }
2321end:
2322 return ret;
2323}
2324
273b65be
JG
2325static
2326int increase_packet_size(struct ctf_stream_pos *pos)
2327{
2328 int ret;
2329
2330 assert(pos);
2331 ret = munmap_align(pos->base_mma);
2332 if (ret) {
2333 goto end;
2334 }
2335
2336 pos->packet_size += PACKET_LEN_INCREMENT;
d9548894
MD
2337 do {
2338 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
2339 pos->packet_size / CHAR_BIT);
2340 } while (ret == EINTR);
273b65be 2341 if (ret) {
d9548894
MD
2342 errno = EINTR;
2343 ret = -1;
273b65be
JG
2344 goto end;
2345 }
2346
2347 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
2348 pos->flags, pos->fd, pos->mmap_offset);
2349 if (pos->base_mma == MAP_FAILED) {
2350 ret = -1;
2351 }
2352end:
2353 return ret;
2354}
918be005
PP
2355
2356static
2357void generic_field_freeze(struct bt_ctf_field *field)
2358{
2359 field->frozen = 1;
2360}
2361
2362static
2363void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
2364{
2365 struct bt_ctf_field_enumeration *enum_field =
2366 container_of(field, struct bt_ctf_field_enumeration, parent);
2367
2368 bt_ctf_field_freeze(enum_field->payload);
2369 generic_field_freeze(field);
2370}
2371
2372static
2373void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
2374{
2375 int i;
2376 struct bt_ctf_field_structure *structure_field =
2377 container_of(field, struct bt_ctf_field_structure, parent);
2378
2379 for (i = 0; i < structure_field->fields->len; i++) {
2380 struct bt_ctf_field *field =
2381 g_ptr_array_index(structure_field->fields, i);
2382
2383 bt_ctf_field_freeze(field);
2384 }
2385
2386 generic_field_freeze(field);
2387}
2388
2389static
2390void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
2391{
2392 struct bt_ctf_field_variant *variant_field =
2393 container_of(field, struct bt_ctf_field_variant, parent);
2394
2395 bt_ctf_field_freeze(variant_field->tag);
2396 bt_ctf_field_freeze(variant_field->payload);
2397 generic_field_freeze(field);
2398}
2399
2400static
2401void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
2402{
2403 int i;
2404 struct bt_ctf_field_array *array_field =
2405 container_of(field, struct bt_ctf_field_array, parent);
2406
2407 for (i = 0; i < array_field->elements->len; i++) {
2408 struct bt_ctf_field *field =
2409 g_ptr_array_index(array_field->elements, i);
2410
2411 bt_ctf_field_freeze(field);
2412 }
2413
2414 generic_field_freeze(field);
2415}
2416
2417static
2418void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
2419{
2420 int i;
2421 struct bt_ctf_field_sequence *sequence_field =
2422 container_of(field, struct bt_ctf_field_sequence, parent);
2423
2424 bt_ctf_field_freeze(sequence_field->length);
2425
2426 for (i = 0; i < sequence_field->elements->len; i++) {
2427 struct bt_ctf_field *field =
2428 g_ptr_array_index(sequence_field->elements, i);
2429
2430 bt_ctf_field_freeze(field);
2431 }
2432
2433 generic_field_freeze(field);
2434}
2435
2436BT_HIDDEN
2437void bt_ctf_field_freeze(struct bt_ctf_field *field)
2438{
35f77de4
JG
2439 enum bt_ctf_type_id type_id;
2440
918be005
PP
2441 if (!field) {
2442 goto end;
2443 }
2444
35f77de4
JG
2445 type_id = bt_ctf_field_get_type_id(field);
2446 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
2447 type_id >= BT_CTF_NR_TYPE_IDS) {
2448 goto end;
2449 }
918be005 2450
35f77de4 2451 field_freeze_funcs[type_id](field);
918be005
PP
2452end:
2453 return;
2454}
76f869ab
JG
2455
2456static
2457bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
2458{
2459 return field && field->payload_set;
2460}
2461
2462static
2463bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
2464{
2465 bool is_set = false;
2466 struct bt_ctf_field_enumeration *enumeration;
2467
2468 if (!field) {
2469 goto end;
2470 }
2471
2472 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2473 parent);
2474 if (!enumeration->payload) {
2475 goto end;
2476 }
2477
2478 is_set = bt_ctf_field_is_set(enumeration->payload);
2479end:
2480 return is_set;
2481}
2482
2483static
2484bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
2485{
2486 bool is_set = false;
2487 size_t i;
2488 struct bt_ctf_field_structure *structure;
2489
2490 if (!field) {
2491 goto end;
2492 }
2493
2494 structure = container_of(field, struct bt_ctf_field_structure, parent);
2495 for (i = 0; i < structure->fields->len; i++) {
2496 is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
2497 if (!is_set) {
2498 goto end;
2499 }
2500 }
2501end:
2502 return is_set;
2503}
2504
2505static
2506bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
2507{
2508 bool is_set = false;
2509 struct bt_ctf_field_variant *variant;
2510
2511 if (!field) {
2512 goto end;
2513 }
2514
2515 variant = container_of(field, struct bt_ctf_field_variant, parent);
2516 is_set = bt_ctf_field_is_set(variant->payload);
2517end:
2518 return is_set;
2519}
2520
2521static
2522bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
2523{
2524 size_t i;
2525 bool is_set = false;
2526 struct bt_ctf_field_array *array;
2527
2528 if (!field) {
2529 goto end;
2530 }
2531
2532 array = container_of(field, struct bt_ctf_field_array, parent);
2533 for (i = 0; i < array->elements->len; i++) {
24626e8b 2534 is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
76f869ab
JG
2535 if (!is_set) {
2536 goto end;
2537 }
2538 }
2539end:
2540 return is_set;
2541}
2542
2543static
2544bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
2545{
2546 size_t i;
2547 bool is_set = false;
2548 struct bt_ctf_field_sequence *sequence;
2549
2550 if (!field) {
2551 goto end;
2552 }
2553
2554 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
2555 for (i = 0; i < sequence->elements->len; i++) {
2556 is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
2557 if (!is_set) {
2558 goto end;
2559 }
2560 }
2561end:
2562 return is_set;
2563}
This page took 0.148917 seconds and 4 git commands to generate.