Fix: only serialize a field if it is set
[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
e0f15669
JG
869struct bt_ctf_field_type_enumeration_mapping_iterator *
870bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *field)
cd95e351
JG
871{
872 int ret;
cd95e351
JG
873 struct bt_ctf_field *container = NULL;
874 struct bt_ctf_field_type *container_type = NULL;
875 struct bt_ctf_field_type_integer *integer_type = NULL;
96e8f959 876 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
cd95e351
JG
877
878 container = bt_ctf_field_enumeration_get_container(field);
879 if (!container) {
880 goto end;
881 }
882
883 container_type = bt_ctf_field_get_type(container);
884 if (!container_type) {
885 goto error_put_container;
886 }
887
888 integer_type = container_of(container_type,
889 struct bt_ctf_field_type_integer, parent);
cd95e351 890
10817e06 891 if (!integer_type->declaration.signedness) {
cd95e351 892 uint64_t value;
96e8f959 893
cd95e351
JG
894 ret = bt_ctf_field_unsigned_integer_get_value(container,
895 &value);
896 if (ret) {
897 goto error_put_container_type;
898 }
96e8f959
MD
899 iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
900 field->type, value);
cd95e351
JG
901 } else {
902 int64_t value;
96e8f959 903
cd95e351
JG
904 ret = bt_ctf_field_signed_integer_get_value(container,
905 &value);
906 if (ret) {
907 goto error_put_container_type;
908 }
96e8f959
MD
909 iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
910 field->type, value);
cd95e351
JG
911 }
912
913error_put_container_type:
83509119 914 bt_put(container_type);
cd95e351 915error_put_container:
83509119 916 bt_put(container);
cd95e351 917end:
e0f15669 918 return iter;
cd95e351
JG
919}
920
921int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
922 int64_t *value)
923{
924 int ret = 0;
925 struct bt_ctf_field_integer *integer;
926 struct bt_ctf_field_type_integer *integer_type;
927
928 if (!field || !value || !field->payload_set ||
929 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 930 BT_CTF_TYPE_ID_INTEGER) {
cd95e351
JG
931 ret = -1;
932 goto end;
933 }
934
935 integer_type = container_of(field->type,
936 struct bt_ctf_field_type_integer, parent);
937 if (!integer_type->declaration.signedness) {
938 ret = -1;
939 goto end;
940 }
941
942 integer = container_of(field,
943 struct bt_ctf_field_integer, parent);
944 *value = integer->definition.value._signed;
945end:
946 return ret;
947}
948
273b65be
JG
949int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
950 int64_t value)
951{
952 int ret = 0;
953 struct bt_ctf_field_integer *integer;
954 struct bt_ctf_field_type_integer *integer_type;
955 unsigned int size;
956 int64_t min_value, max_value;
957
918be005 958 if (!field || field->frozen ||
273b65be 959 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 960 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
961 ret = -1;
962 goto end;
963 }
964
965 integer = container_of(field, struct bt_ctf_field_integer, parent);
966 integer_type = container_of(field->type,
967 struct bt_ctf_field_type_integer, parent);
968 if (!integer_type->declaration.signedness) {
969 ret = -1;
970 goto end;
971 }
972
973 size = integer_type->declaration.len;
9dc0d640
JG
974 min_value = -(1ULL << (size - 1));
975 max_value = (1ULL << (size - 1)) - 1;
273b65be
JG
976 if (value < min_value || value > max_value) {
977 ret = -1;
978 goto end;
979 }
980
981 integer->definition.value._signed = value;
982 integer->parent.payload_set = 1;
983end:
984 return ret;
985}
986
cd95e351
JG
987int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
988 uint64_t *value)
989{
990 int ret = 0;
991 struct bt_ctf_field_integer *integer;
992 struct bt_ctf_field_type_integer *integer_type;
993
994 if (!field || !value || !field->payload_set ||
995 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 996 BT_CTF_TYPE_ID_INTEGER) {
cd95e351
JG
997 ret = -1;
998 goto end;
999 }
1000
1001 integer_type = container_of(field->type,
1002 struct bt_ctf_field_type_integer, parent);
1003 if (integer_type->declaration.signedness) {
1004 ret = -1;
1005 goto end;
1006 }
1007
1008 integer = container_of(field,
1009 struct bt_ctf_field_integer, parent);
1010 *value = integer->definition.value._unsigned;
1011end:
1012 return ret;
1013}
1014
273b65be
JG
1015int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
1016 uint64_t value)
1017{
1018 int ret = 0;
1019 struct bt_ctf_field_integer *integer;
1020 struct bt_ctf_field_type_integer *integer_type;
1021 unsigned int size;
1022 uint64_t max_value;
1023
918be005 1024 if (!field || field->frozen ||
273b65be 1025 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1026 BT_CTF_TYPE_ID_INTEGER) {
273b65be
JG
1027 ret = -1;
1028 goto end;
1029 }
1030
1031 integer = container_of(field, struct bt_ctf_field_integer, parent);
1032 integer_type = container_of(field->type,
1033 struct bt_ctf_field_type_integer, parent);
1034 if (integer_type->declaration.signedness) {
1035 ret = -1;
1036 goto end;
1037 }
1038
1039 size = integer_type->declaration.len;
8684abc8 1040 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
273b65be
JG
1041 if (value > max_value) {
1042 ret = -1;
1043 goto end;
1044 }
1045
1046 integer->definition.value._unsigned = value;
1047 integer->parent.payload_set = 1;
1048end:
1049 return ret;
1050}
1051
cd95e351
JG
1052int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1053 double *value)
1054{
1055 int ret = 0;
1056 struct bt_ctf_field_floating_point *floating_point;
1057
1058 if (!field || !value || !field->payload_set ||
1059 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1060 BT_CTF_TYPE_ID_FLOAT) {
cd95e351
JG
1061 ret = -1;
1062 goto end;
1063 }
1064
1065 floating_point = container_of(field,
1066 struct bt_ctf_field_floating_point, parent);
1067 *value = floating_point->definition.value;
1068end:
1069 return ret;
1070}
1071
273b65be
JG
1072int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1073 double value)
1074{
1075 int ret = 0;
1076 struct bt_ctf_field_floating_point *floating_point;
1077
918be005 1078 if (!field || field->frozen ||
273b65be 1079 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1080 BT_CTF_TYPE_ID_FLOAT) {
273b65be
JG
1081 ret = -1;
1082 goto end;
1083 }
1084 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1085 parent);
1086 floating_point->definition.value = value;
1087 floating_point->parent.payload_set = 1;
1088end:
1089 return ret;
1090}
1091
cd95e351
JG
1092const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1093{
1094 const char *ret = NULL;
1095 struct bt_ctf_field_string *string;
1096
1097 if (!field || !field->payload_set ||
1098 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1099 BT_CTF_TYPE_ID_STRING) {
cd95e351
JG
1100 goto end;
1101 }
1102
1103 string = container_of(field,
1104 struct bt_ctf_field_string, parent);
1105 ret = string->payload->str;
1106end:
1107 return ret;
1108}
1109
273b65be
JG
1110int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
1111 const char *value)
1112{
1113 int ret = 0;
1114 struct bt_ctf_field_string *string;
1115
918be005 1116 if (!field || !value || field->frozen ||
273b65be 1117 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1118 BT_CTF_TYPE_ID_STRING) {
273b65be
JG
1119 ret = -1;
1120 goto end;
1121 }
1122
1123 string = container_of(field, struct bt_ctf_field_string, parent);
1124 if (string->payload) {
97736814
JG
1125 g_string_assign(string->payload, value);
1126 } else {
1127 string->payload = g_string_new(value);
273b65be
JG
1128 }
1129
273b65be
JG
1130 string->parent.payload_set = 1;
1131end:
1132 return ret;
1133}
1134
c6f9c5a3
PP
1135int bt_ctf_field_string_append(struct bt_ctf_field *field,
1136 const char *value)
1137{
1138 int ret = 0;
1139 struct bt_ctf_field_string *string_field;
1140
918be005 1141 if (!field || !value || field->frozen ||
c6f9c5a3 1142 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1143 BT_CTF_TYPE_ID_STRING) {
c6f9c5a3
PP
1144 ret = -1;
1145 goto end;
1146 }
1147
1148 string_field = container_of(field, struct bt_ctf_field_string, parent);
1149
1150 if (string_field->payload) {
1151 g_string_append(string_field->payload, value);
1152 } else {
1153 string_field->payload = g_string_new(value);
1154 }
1155
1156 string_field->parent.payload_set = 1;
1157
1158end:
1159 return ret;
1160}
1161
f98c6554
PP
1162int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1163 const char *value, unsigned int length)
1164{
1165 int i;
1166 int ret = 0;
1167 unsigned int effective_length = length;
1168 struct bt_ctf_field_string *string_field;
1169
918be005 1170 if (!field || !value || field->frozen ||
f98c6554 1171 bt_ctf_field_type_get_type_id(field->type) !=
9a19a512 1172 BT_CTF_TYPE_ID_STRING) {
f98c6554
PP
1173 ret = -1;
1174 goto end;
1175 }
1176
1177 string_field = container_of(field, struct bt_ctf_field_string, parent);
1178
1179 /* make sure no null bytes are appended */
1180 for (i = 0; i < length; ++i) {
1181 if (value[i] == '\0') {
1182 effective_length = i;
1183 break;
1184 }
1185 }
1186
1187 if (string_field->payload) {
ce6d5230 1188 g_string_append_len(string_field->payload, value,
f98c6554
PP
1189 effective_length);
1190 } else {
1191 string_field->payload = g_string_new_len(value,
1192 effective_length);
1193 }
1194
1195 string_field->parent.payload_set = 1;
1196
1197end:
1198 return ret;
1199}
1200
273b65be
JG
1201BT_HIDDEN
1202int bt_ctf_field_validate(struct bt_ctf_field *field)
1203{
1204 int ret = 0;
9a19a512 1205 enum bt_ctf_type_id type_id;
273b65be
JG
1206
1207 if (!field) {
1208 ret = -1;
1209 goto end;
1210 }
1211
1212 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1213 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1214 ret = -1;
1215 goto end;
1216 }
1217
1218 ret = field_validate_funcs[type_id](field);
1219end:
1220 return ret;
1221}
1222
12c8a1a3
JG
1223BT_HIDDEN
1224int bt_ctf_field_reset(struct bt_ctf_field *field)
1225{
1226 int ret = 0;
9a19a512 1227 enum bt_ctf_type_id type_id;
12c8a1a3
JG
1228
1229 if (!field) {
1230 ret = -1;
1231 goto end;
1232 }
1233
1234 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1235 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
12c8a1a3
JG
1236 ret = -1;
1237 goto end;
1238 }
1239
1240 ret = field_reset_funcs[type_id](field);
1241end:
1242 return ret;
1243}
1244
273b65be
JG
1245BT_HIDDEN
1246int bt_ctf_field_serialize(struct bt_ctf_field *field,
1247 struct ctf_stream_pos *pos)
1248{
1249 int ret = 0;
9a19a512 1250 enum bt_ctf_type_id type_id;
273b65be
JG
1251
1252 if (!field || !pos) {
1253 ret = -1;
1254 goto end;
1255 }
1256
1257 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1258 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1259 ret = -1;
1260 goto end;
1261 }
1262
1263 ret = field_serialize_funcs[type_id](field, pos);
1264end:
1265 return ret;
1266}
1267
76f869ab
JG
1268
1269BT_HIDDEN
1270bool bt_ctf_field_is_set(struct bt_ctf_field *field)
1271{
1272 bool is_set = false;
1273 enum bt_ctf_type_id type_id;
1274
1275 if (!field) {
1276 goto end;
1277 }
1278
1279 type_id = bt_ctf_field_type_get_type_id(field->type);
1280 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1281 goto end;
1282 }
1283
1284 is_set = field_is_set_funcs[type_id](field);
1285end:
1286 return is_set;
1287}
1288
87d43dc1
JG
1289struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1290{
1291 int ret;
1292 struct bt_ctf_field *copy = NULL;
9a19a512 1293 enum bt_ctf_type_id type_id;
87d43dc1
JG
1294
1295 if (!field) {
87d43dc1
JG
1296 goto end;
1297 }
1298
1299 type_id = bt_ctf_field_type_get_type_id(field->type);
9a19a512 1300 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
87d43dc1
JG
1301 goto end;
1302 }
1303
1304 copy = bt_ctf_field_create(field->type);
1305 if (!copy) {
1306 goto end;
1307 }
1308
70996764 1309 copy->payload_set = field->payload_set;
87d43dc1
JG
1310 ret = field_copy_funcs[type_id](field, copy);
1311 if (ret) {
83509119 1312 bt_put(copy);
87d43dc1
JG
1313 copy = NULL;
1314 }
1315end:
1316 return copy;
1317}
1318
273b65be
JG
1319static
1320struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1321{
1322 struct bt_ctf_field_type_integer *integer_type = container_of(type,
1323 struct bt_ctf_field_type_integer, parent);
1324 struct bt_ctf_field_integer *integer = g_new0(
1325 struct bt_ctf_field_integer, 1);
1326
1327 if (integer) {
1328 integer->definition.declaration = &integer_type->declaration;
1329 }
1330
1331 return integer ? &integer->parent : NULL;
1332}
1333
1334static
1335struct bt_ctf_field *bt_ctf_field_enumeration_create(
1336 struct bt_ctf_field_type *type)
1337{
1338 struct bt_ctf_field_enumeration *enumeration = g_new0(
1339 struct bt_ctf_field_enumeration, 1);
1340
1341 return enumeration ? &enumeration->parent : NULL;
1342}
1343
1344static
1345struct bt_ctf_field *bt_ctf_field_floating_point_create(
1346 struct bt_ctf_field_type *type)
1347{
1348 struct bt_ctf_field_floating_point *floating_point;
1349 struct bt_ctf_field_type_floating_point *floating_point_type;
1350
1351 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
1352 if (!floating_point) {
1353 goto end;
1354 }
1355
1356 floating_point_type = container_of(type,
1357 struct bt_ctf_field_type_floating_point, parent);
1358 floating_point->definition.declaration = container_of(
1359 type->declaration, struct declaration_float, p);
1360
1361
1362 floating_point->definition.sign = &floating_point->sign;
1363 floating_point->sign.declaration = &floating_point_type->sign;
1364 floating_point->definition.sign->p.declaration =
1365 &floating_point_type->sign.p;
1366
1367 floating_point->definition.mantissa = &floating_point->mantissa;
1368 floating_point->mantissa.declaration = &floating_point_type->mantissa;
1369 floating_point->definition.mantissa->p.declaration =
1370 &floating_point_type->mantissa.p;
1371
1372 floating_point->definition.exp = &floating_point->exp;
1373 floating_point->exp.declaration = &floating_point_type->exp;
1374 floating_point->definition.exp->p.declaration =
1375 &floating_point_type->exp.p;
1376
1377end:
1378 return floating_point ? &floating_point->parent : NULL;
1379}
1380
1381static
1382struct bt_ctf_field *bt_ctf_field_structure_create(
1383 struct bt_ctf_field_type *type)
1384{
1385 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1386 struct bt_ctf_field_type_structure, parent);
1387 struct bt_ctf_field_structure *structure = g_new0(
1388 struct bt_ctf_field_structure, 1);
1389 struct bt_ctf_field *field = NULL;
1390
8c1aa858 1391 if (!structure) {
273b65be
JG
1392 goto end;
1393 }
1394
1395 structure->field_name_to_index = structure_type->field_name_to_index;
1396 structure->fields = g_ptr_array_new_with_free_func(
1397 (GDestroyNotify)bt_ctf_field_put);
1398 g_ptr_array_set_size(structure->fields,
1399 g_hash_table_size(structure->field_name_to_index));
1400 field = &structure->parent;
1401end:
1402 return field;
1403}
1404
1405static
1406struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1407{
1408 struct bt_ctf_field_variant *variant = g_new0(
1409 struct bt_ctf_field_variant, 1);
1410 return variant ? &variant->parent : NULL;
1411}
1412
1413static
1414struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1415{
1416 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1417 struct bt_ctf_field_type_array *array_type;
1418 unsigned int array_length;
1419
1420 if (!array || !type) {
1421 goto error;
1422 }
1423
1424 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1425 array_length = array_type->length;
fe0fe95c 1426 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1427 if (!array->elements) {
1428 goto error;
1429 }
1430
fe0fe95c
JG
1431 g_ptr_array_set_free_func(array->elements,
1432 (GDestroyNotify)bt_ctf_field_put);
273b65be
JG
1433 g_ptr_array_set_size(array->elements, array_length);
1434 return &array->parent;
1435error:
1436 g_free(array);
1437 return NULL;
1438}
1439
1440static
1441struct bt_ctf_field *bt_ctf_field_sequence_create(
1442 struct bt_ctf_field_type *type)
1443{
1444 struct bt_ctf_field_sequence *sequence = g_new0(
1445 struct bt_ctf_field_sequence, 1);
1446 return sequence ? &sequence->parent : NULL;
1447}
1448
1449static
1450struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1451{
1452 struct bt_ctf_field_string *string = g_new0(
1453 struct bt_ctf_field_string, 1);
1454 return string ? &string->parent : NULL;
1455}
1456
1457static
83509119 1458void bt_ctf_field_destroy(struct bt_object *obj)
273b65be
JG
1459{
1460 struct bt_ctf_field *field;
1461 struct bt_ctf_field_type *type;
9a19a512 1462 enum bt_ctf_type_id type_id;
273b65be 1463
83509119 1464 field = container_of(obj, struct bt_ctf_field, base);
273b65be
JG
1465 type = field->type;
1466 type_id = bt_ctf_field_type_get_type_id(type);
9a19a512
PP
1467 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
1468 type_id >= BT_CTF_NR_TYPE_IDS) {
273b65be
JG
1469 return;
1470 }
1471
1472 field_destroy_funcs[type_id](field);
83509119 1473 bt_put(type);
273b65be
JG
1474}
1475
1476static
1477void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1478{
1479 struct bt_ctf_field_integer *integer;
1480
1481 if (!field) {
1482 return;
1483 }
1484
1485 integer = container_of(field, struct bt_ctf_field_integer, parent);
1486 g_free(integer);
1487}
1488
1489static
1490void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1491{
1492 struct bt_ctf_field_enumeration *enumeration;
1493
1494 if (!field) {
1495 return;
1496 }
1497
1498 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1499 parent);
83509119 1500 bt_put(enumeration->payload);
273b65be
JG
1501 g_free(enumeration);
1502}
1503
1504static
1505void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
1506{
1507 struct bt_ctf_field_floating_point *floating_point;
1508
1509 if (!field) {
1510 return;
1511 }
1512
1513 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1514 parent);
1515 g_free(floating_point);
1516}
1517
1518static
1519void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
1520{
1521 struct bt_ctf_field_structure *structure;
1522
1523 if (!field) {
1524 return;
1525 }
1526
1527 structure = container_of(field, struct bt_ctf_field_structure, parent);
1528 g_ptr_array_free(structure->fields, TRUE);
1529 g_free(structure);
1530}
1531
1532static
1533void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
1534{
1535 struct bt_ctf_field_variant *variant;
1536
1537 if (!field) {
1538 return;
1539 }
1540
1541 variant = container_of(field, struct bt_ctf_field_variant, parent);
83509119
JG
1542 bt_put(variant->tag);
1543 bt_put(variant->payload);
273b65be
JG
1544 g_free(variant);
1545}
1546
1547static
1548void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
1549{
1550 struct bt_ctf_field_array *array;
1551
1552 if (!field) {
1553 return;
1554 }
1555
1556 array = container_of(field, struct bt_ctf_field_array, parent);
1557 g_ptr_array_free(array->elements, TRUE);
1558 g_free(array);
1559}
1560
1561static
1562void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
1563{
1564 struct bt_ctf_field_sequence *sequence;
1565
1566 if (!field) {
1567 return;
1568 }
1569
1570 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
4fef87ab
JG
1571 if (sequence->elements) {
1572 g_ptr_array_free(sequence->elements, TRUE);
1573 }
83509119 1574 bt_put(sequence->length);
273b65be
JG
1575 g_free(sequence);
1576}
1577
1578static
1579void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
1580{
1581 struct bt_ctf_field_string *string;
1582 if (!field) {
1583 return;
1584 }
1585
1586 string = container_of(field, struct bt_ctf_field_string, parent);
9b2b7163
JG
1587 if (string->payload) {
1588 g_string_free(string->payload, TRUE);
1589 }
273b65be
JG
1590 g_free(string);
1591}
1592
1593static
1594int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1595{
da2f6971 1596 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
1597}
1598
1599static
1600int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
1601{
1602 int ret;
1603 struct bt_ctf_field_enumeration *enumeration;
1604
1605 if (!field) {
1606 ret = -1;
1607 goto end;
1608 }
1609
1610 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1611 parent);
1612 if (!enumeration->payload) {
1613 ret = -1;
1614 goto end;
1615 }
1616
1617 ret = bt_ctf_field_validate(enumeration->payload);
1618end:
1619 return ret;
1620}
1621
1622static
1623int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
1624{
1625 size_t i;
1626 int ret = 0;
1627 struct bt_ctf_field_structure *structure;
1628
1629 if (!field) {
1630 ret = -1;
1631 goto end;
1632 }
1633
1634 structure = container_of(field, struct bt_ctf_field_structure, parent);
1635 for (i = 0; i < structure->fields->len; i++) {
1636 ret = bt_ctf_field_validate(structure->fields->pdata[i]);
1637 if (ret) {
6ce12048
JG
1638 const char *name;
1639 struct bt_ctf_field_type *field_type =
1640 bt_ctf_field_get_type(field);
1641
1642 (void) bt_ctf_field_type_structure_get_field(field_type,
1643 &name, NULL, i);
1644 fprintf(stderr, "Field %s failed validation\n",
1645 name ? name : "NULL");
e5ed1ccf 1646 bt_put(field_type);
273b65be
JG
1647 goto end;
1648 }
1649 }
1650end:
1651 return ret;
1652}
1653
1654static
1655int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1656{
1657 int ret = 0;
1658 struct bt_ctf_field_variant *variant;
1659
1660 if (!field) {
1661 ret = -1;
1662 goto end;
1663 }
1664
1665 variant = container_of(field, struct bt_ctf_field_variant, parent);
1666 ret = bt_ctf_field_validate(variant->payload);
1667end:
1668 return ret;
1669}
1670
1671static
1672int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1673{
1674 size_t i;
1675 int ret = 0;
1676 struct bt_ctf_field_array *array;
1677
1678 if (!field) {
1679 ret = -1;
1680 goto end;
1681 }
1682
1683 array = container_of(field, struct bt_ctf_field_array, parent);
1684 for (i = 0; i < array->elements->len; i++) {
1685 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1686 if (ret) {
e91f3bab 1687 fprintf(stderr, "Failed to validate array field #%zu\n", i);
273b65be
JG
1688 goto end;
1689 }
1690 }
1691end:
1692 return ret;
1693}
1694
1695static
1696int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1697{
1698 size_t i;
1699 int ret = 0;
1700 struct bt_ctf_field_sequence *sequence;
1701
1702 if (!field) {
1703 ret = -1;
1704 goto end;
1705 }
1706
1707 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1708 for (i = 0; i < sequence->elements->len; i++) {
1709 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1710 if (ret) {
bcfb49d4 1711 fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
273b65be
JG
1712 goto end;
1713 }
1714 }
1715end:
1716 return ret;
1717}
1718
12c8a1a3
JG
1719static
1720int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1721{
1722 int ret = 0;
1723
1724 if (!field) {
1725 ret = -1;
1726 goto end;
1727 }
1728
1729 field->payload_set = 0;
1730end:
1731 return ret;
1732}
1733
1734static
1735int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1736{
1737 int ret = 0;
1738 struct bt_ctf_field_enumeration *enumeration;
1739
1740 if (!field) {
1741 ret = -1;
1742 goto end;
1743 }
1744
1745 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1746 parent);
1747 if (!enumeration->payload) {
1748 goto end;
1749 }
1750
1751 ret = bt_ctf_field_reset(enumeration->payload);
1752end:
1753 return ret;
1754}
1755
1756static
1757int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1758{
1759 size_t i;
1760 int ret = 0;
1761 struct bt_ctf_field_structure *structure;
1762
1763 if (!field) {
1764 ret = -1;
1765 goto end;
1766 }
1767
1768 structure = container_of(field, struct bt_ctf_field_structure, parent);
1769 for (i = 0; i < structure->fields->len; i++) {
1770 struct bt_ctf_field *member = structure->fields->pdata[i];
1771
1772 if (!member) {
1773 /*
1774 * Structure members are lazily initialized; skip if
1775 * this member has not been allocated yet.
1776 */
1777 continue;
1778 }
1779
1780 ret = bt_ctf_field_reset(member);
1781 if (ret) {
1782 goto end;
1783 }
1784 }
1785end:
1786 return ret;
1787}
1788
1789static
1790int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1791{
1792 int ret = 0;
1793 struct bt_ctf_field_variant *variant;
1794
1795 if (!field) {
1796 ret = -1;
1797 goto end;
1798 }
1799
1800 variant = container_of(field, struct bt_ctf_field_variant, parent);
1801 if (variant->payload) {
1802 ret = bt_ctf_field_reset(variant->payload);
1803 }
1804end:
1805 return ret;
1806}
1807
1808static
1809int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1810{
1811 size_t i;
1812 int ret = 0;
1813 struct bt_ctf_field_array *array;
1814
1815 if (!field) {
1816 ret = -1;
1817 goto end;
1818 }
1819
1820 array = container_of(field, struct bt_ctf_field_array, parent);
1821 for (i = 0; i < array->elements->len; i++) {
1822 struct bt_ctf_field *member = array->elements->pdata[i];
1823
1824 if (!member) {
1825 /*
1826 * Array elements are lazily initialized; skip if
1827 * this member has not been allocated yet.
1828 */
1829 continue;
1830 }
1831
1832 ret = bt_ctf_field_reset(member);
1833 if (ret) {
1834 goto end;
1835 }
1836 }
1837end:
1838 return ret;
1839}
1840
1841static
1842int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1843{
1844 size_t i;
1845 int ret = 0;
1846 struct bt_ctf_field_sequence *sequence;
1847
1848 if (!field) {
1849 ret = -1;
1850 goto end;
1851 }
1852
1853 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1854 for (i = 0; i < sequence->elements->len; i++) {
1855 struct bt_ctf_field *member = sequence->elements->pdata[i];
1856
1857 if (!member) {
1858 /*
1859 * Sequence elements are lazily initialized; skip if
1860 * this member has not been allocated yet.
1861 */
1862 continue;
1863 }
1864
1865 ret = bt_ctf_field_reset(member);
1866 if (ret) {
1867 goto end;
1868 }
1869 }
1870end:
1871 return ret;
1872}
1873
1874static
1875int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1876{
1877 int ret = 0;
1878 struct bt_ctf_field_string *string;
1879
1880 if (!field) {
1881 ret = -1;
1882 goto end;
1883 }
1884
1885 ret = bt_ctf_field_generic_reset(field);
1886 if (ret) {
1887 goto end;
1888 }
1889
1890 string = container_of(field, struct bt_ctf_field_string, parent);
1891 if (string->payload) {
1892 g_string_truncate(string->payload, 0);
1893 }
1894end:
1895 return ret;
1896}
1897
273b65be
JG
1898static
1899int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1900 struct ctf_stream_pos *pos)
1901{
1902 int ret = 0;
1903 struct bt_ctf_field_integer *integer = container_of(field,
1904 struct bt_ctf_field_integer, parent);
1905
fa21dcb1
JG
1906 if (!bt_ctf_field_generic_is_set(field)) {
1907 ret = -1;
1908 goto end;
1909 }
273b65be
JG
1910retry:
1911 ret = ctf_integer_write(&pos->parent, &integer->definition.p);
1912 if (ret == -EFAULT) {
1913 /*
1914 * The field is too large to fit in the current packet's
1915 * remaining space. Bump the packet size and retry.
1916 */
1917 ret = increase_packet_size(pos);
1918 if (ret) {
1919 goto end;
1920 }
1921 goto retry;
1922 }
1923end:
1924 return ret;
1925}
1926
1927static
1928int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1929 struct ctf_stream_pos *pos)
1930{
1931 struct bt_ctf_field_enumeration *enumeration = container_of(
1932 field, struct bt_ctf_field_enumeration, parent);
1933
1934 return bt_ctf_field_serialize(enumeration->payload, pos);
1935}
1936
1937static
1938int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1939 struct ctf_stream_pos *pos)
1940{
1941 int ret = 0;
1942 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1943 struct bt_ctf_field_floating_point, parent);
1944
fa21dcb1
JG
1945 if (!bt_ctf_field_generic_is_set(field)) {
1946 ret = -1;
1947 goto end;
1948 }
273b65be
JG
1949retry:
1950 ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
1951 if (ret == -EFAULT) {
1952 /*
1953 * The field is too large to fit in the current packet's
1954 * remaining space. Bump the packet size and retry.
1955 */
1956 ret = increase_packet_size(pos);
1957 if (ret) {
1958 goto end;
1959 }
1960 goto retry;
1961 }
1962end:
1963 return ret;
1964}
1965
1966static
1967int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1968 struct ctf_stream_pos *pos)
1969{
1970 size_t i;
1971 int ret = 0;
1972 struct bt_ctf_field_structure *structure = container_of(
1973 field, struct bt_ctf_field_structure, parent);
1974
1975 while (!ctf_pos_access_ok(pos,
1976 offset_align(pos->offset,
1977 field->type->declaration->alignment))) {
9f56e450
JG
1978 ret = increase_packet_size(pos);
1979 if (ret) {
1980 goto end;
1981 }
273b65be
JG
1982 }
1983
70fd5a51
MD
1984 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1985 ret = -1;
1986 goto end;
1987 }
273b65be
JG
1988
1989 for (i = 0; i < structure->fields->len; i++) {
bf3a205b 1990 struct bt_ctf_field *member = g_ptr_array_index(
273b65be
JG
1991 structure->fields, i);
1992
bf3a205b 1993 ret = bt_ctf_field_serialize(member, pos);
273b65be 1994 if (ret) {
bcfb49d4 1995 const char *name;
bf3a205b 1996 struct bt_ctf_field_type *structure_type =
bcfb49d4
JG
1997 bt_ctf_field_get_type(field);
1998
bf3a205b
JG
1999 (void) bt_ctf_field_type_structure_get_field(
2000 structure_type, &name, NULL, i);
bcfb49d4
JG
2001 fprintf(stderr, "Field %s failed to serialize\n",
2002 name ? name : "NULL");
bf3a205b 2003 bt_put(structure_type);
273b65be
JG
2004 break;
2005 }
2006 }
9f56e450 2007end:
273b65be
JG
2008 return ret;
2009}
2010
2011static
2012int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
2013 struct ctf_stream_pos *pos)
2014{
2015 struct bt_ctf_field_variant *variant = container_of(
2016 field, struct bt_ctf_field_variant, parent);
2017
2018 return bt_ctf_field_serialize(variant->payload, pos);
2019}
2020
2021static
2022int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
2023 struct ctf_stream_pos *pos)
2024{
2025 size_t i;
2026 int ret = 0;
2027 struct bt_ctf_field_array *array = container_of(
2028 field, struct bt_ctf_field_array, parent);
2029
2030 for (i = 0; i < array->elements->len; i++) {
2031 ret = bt_ctf_field_serialize(
2032 g_ptr_array_index(array->elements, i), pos);
2033 if (ret) {
bcfb49d4 2034 fprintf(stderr, "Failed to serialize array element #%zu\n", i);
273b65be
JG
2035 goto end;
2036 }
2037 }
2038end:
2039 return ret;
2040}
2041
2042static
2043int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
2044 struct ctf_stream_pos *pos)
2045{
2046 size_t i;
2047 int ret = 0;
2048 struct bt_ctf_field_sequence *sequence = container_of(
2049 field, struct bt_ctf_field_sequence, parent);
2050
2051 for (i = 0; i < sequence->elements->len; i++) {
2052 ret = bt_ctf_field_serialize(
2053 g_ptr_array_index(sequence->elements, i), pos);
2054 if (ret) {
bcfb49d4 2055 fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
273b65be
JG
2056 goto end;
2057 }
2058 }
2059end:
2060 return ret;
2061}
2062
2063static
2064int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
2065 struct ctf_stream_pos *pos)
2066{
2067 size_t i;
2068 int ret = 0;
2069 struct bt_ctf_field_string *string = container_of(field,
2070 struct bt_ctf_field_string, parent);
2071 struct bt_ctf_field_type *character_type =
2072 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
2073 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
2074
2075 for (i = 0; i < string->payload->len + 1; i++) {
2076 ret = bt_ctf_field_unsigned_integer_set_value(character,
2077 (uint64_t) string->payload->str[i]);
2078 if (ret) {
2079 goto end;
2080 }
2081
2082 ret = bt_ctf_field_integer_serialize(character, pos);
2083 if (ret) {
2084 goto end;
2085 }
2086 }
2087end:
83509119
JG
2088 bt_put(character);
2089 bt_put(character_type);
273b65be
JG
2090 return ret;
2091}
2092
87d43dc1
JG
2093static
2094int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2095 struct bt_ctf_field *dst)
2096{
2097 struct bt_ctf_field_integer *integer_src, *integer_dst;
2098
2099 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
8bfa3f9c 2100 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
87d43dc1
JG
2101
2102 memcpy(&integer_dst->definition, &integer_src->definition,
2103 sizeof(struct definition_integer));
2104 return 0;
2105}
2106
2107static
2108int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2109 struct bt_ctf_field *dst)
2110{
2111 int ret = 0;
2112 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2113
2114 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2115 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2116
2117 if (enum_src->payload) {
2118 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2119 if (!enum_dst->payload) {
2120 ret = -1;
2121 goto end;
2122 }
2123 }
2124end:
2125 return ret;
2126}
2127
2128static
2129int bt_ctf_field_floating_point_copy(
2130 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2131{
2132 struct bt_ctf_field_floating_point *float_src, *float_dst;
2133
2134 float_src = container_of(src, struct bt_ctf_field_floating_point,
2135 parent);
2136 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2137 parent);
2138
2139 memcpy(&float_dst->definition, &float_src->definition,
2140 sizeof(struct definition_float));
2141 memcpy(&float_dst->sign, &float_src->sign,
2142 sizeof(struct definition_integer));
2143 memcpy(&float_dst->mantissa, &float_src->mantissa,
2144 sizeof(struct definition_integer));
2145 memcpy(&float_dst->exp, &float_src->exp,
2146 sizeof(struct definition_integer));
2147 return 0;
2148}
2149
2150static
2151int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2152 struct bt_ctf_field *dst)
2153{
8bfa3f9c 2154 int ret = 0, i;
87d43dc1
JG
2155 struct bt_ctf_field_structure *struct_src, *struct_dst;
2156
2157 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2158 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2159
8bfa3f9c 2160 /* This field_name_to_index HT is owned by the structure field type */
87d43dc1 2161 struct_dst->field_name_to_index = struct_src->field_name_to_index;
8bfa3f9c 2162 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
2163
2164 for (i = 0; i < struct_src->fields->len; i++) {
50fd95bf
PP
2165 struct bt_ctf_field *field =
2166 g_ptr_array_index(struct_src->fields, i);
2167 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2168
50fd95bf
PP
2169 if (field) {
2170 field_copy = bt_ctf_field_copy(field);
2171
2172 if (!field_copy) {
2173 ret = -1;
2174 goto end;
2175 }
87d43dc1 2176 }
50fd95bf 2177
8bfa3f9c 2178 g_ptr_array_index(struct_dst->fields, i) = field_copy;
87d43dc1
JG
2179 }
2180end:
2181 return ret;
2182}
2183
2184static
2185int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2186 struct bt_ctf_field *dst)
2187{
2188 int ret = 0;
2189 struct bt_ctf_field_variant *variant_src, *variant_dst;
2190
2191 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2192 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2193
2194 if (variant_src->tag) {
2195 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2196 if (!variant_dst->tag) {
2197 ret = -1;
2198 goto end;
2199 }
2200 }
2201 if (variant_src->payload) {
2202 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2203 if (!variant_dst->payload) {
2204 ret = -1;
2205 goto end;
2206 }
2207 }
2208end:
2209 return ret;
2210}
2211
2212static
2213int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2214 struct bt_ctf_field *dst)
2215{
2216 int ret = 0, i;
2217 struct bt_ctf_field_array *array_src, *array_dst;
2218
2219 array_src = container_of(src, struct bt_ctf_field_array, parent);
2220 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2221
8bfa3f9c 2222 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1 2223 for (i = 0; i < array_src->elements->len; i++) {
50fd95bf
PP
2224 struct bt_ctf_field *field =
2225 g_ptr_array_index(array_src->elements, i);
2226 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2227
50fd95bf
PP
2228 if (field) {
2229 field_copy = bt_ctf_field_copy(field);
2230
2231 if (!field_copy) {
2232 ret = -1;
2233 goto end;
2234 }
87d43dc1 2235 }
50fd95bf 2236
8bfa3f9c 2237 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1
JG
2238 }
2239end:
2240 return ret;
2241}
2242
2243static
2244int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2245 struct bt_ctf_field *dst)
2246{
2247 int ret = 0, i;
2248 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
59ab494d
PP
2249 struct bt_ctf_field *src_length;
2250 struct bt_ctf_field *dst_length;
87d43dc1
JG
2251
2252 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2253 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2254
59ab494d
PP
2255 src_length = bt_ctf_field_sequence_get_length(src);
2256
2257 if (!src_length) {
2258 /* no length set yet: keep destination sequence empty */
2259 goto end;
2260 }
2261
2262 /* copy source length */
2263 dst_length = bt_ctf_field_copy(src_length);
83509119 2264 bt_put(src_length);
59ab494d
PP
2265
2266 if (!dst_length) {
2267 ret = -1;
2268 goto end;
2269 }
2270
2271 /* this will initialize the destination sequence's internal array */
2272 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
83509119 2273 bt_put(dst_length);
59ab494d
PP
2274
2275 if (ret) {
2276 goto end;
2277 }
2278
2279 assert(sequence_dst->elements->len == sequence_src->elements->len);
2280
87d43dc1 2281 for (i = 0; i < sequence_src->elements->len; i++) {
50fd95bf
PP
2282 struct bt_ctf_field *field =
2283 g_ptr_array_index(sequence_src->elements, i);
2284 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2285
50fd95bf
PP
2286 if (field) {
2287 field_copy = bt_ctf_field_copy(field);
2288
2289 if (!field_copy) {
2290 ret = -1;
2291 goto end;
2292 }
87d43dc1 2293 }
59ab494d 2294
8bfa3f9c 2295 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1
JG
2296 }
2297end:
2298 return ret;
2299}
2300
2301static
2302int bt_ctf_field_string_copy(struct bt_ctf_field *src,
2303 struct bt_ctf_field *dst)
2304{
2305 int ret = 0;
2306 struct bt_ctf_field_string *string_src, *string_dst;
2307
2308 string_src = container_of(src, struct bt_ctf_field_string, parent);
2309 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
2310
2311 if (string_src->payload) {
2312 string_dst->payload = g_string_new(string_src->payload->str);
2313 if (!string_dst->payload) {
2314 ret = -1;
2315 goto end;
2316 }
2317 }
2318end:
2319 return ret;
2320}
2321
273b65be
JG
2322static
2323int increase_packet_size(struct ctf_stream_pos *pos)
2324{
2325 int ret;
2326
2327 assert(pos);
2328 ret = munmap_align(pos->base_mma);
2329 if (ret) {
2330 goto end;
2331 }
2332
2333 pos->packet_size += PACKET_LEN_INCREMENT;
d9548894
MD
2334 do {
2335 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
2336 pos->packet_size / CHAR_BIT);
2337 } while (ret == EINTR);
273b65be 2338 if (ret) {
d9548894
MD
2339 errno = EINTR;
2340 ret = -1;
273b65be
JG
2341 goto end;
2342 }
2343
2344 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
2345 pos->flags, pos->fd, pos->mmap_offset);
2346 if (pos->base_mma == MAP_FAILED) {
2347 ret = -1;
2348 }
2349end:
2350 return ret;
2351}
918be005
PP
2352
2353static
2354void generic_field_freeze(struct bt_ctf_field *field)
2355{
2356 field->frozen = 1;
2357}
2358
2359static
2360void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
2361{
2362 struct bt_ctf_field_enumeration *enum_field =
2363 container_of(field, struct bt_ctf_field_enumeration, parent);
2364
2365 bt_ctf_field_freeze(enum_field->payload);
2366 generic_field_freeze(field);
2367}
2368
2369static
2370void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
2371{
2372 int i;
2373 struct bt_ctf_field_structure *structure_field =
2374 container_of(field, struct bt_ctf_field_structure, parent);
2375
2376 for (i = 0; i < structure_field->fields->len; i++) {
2377 struct bt_ctf_field *field =
2378 g_ptr_array_index(structure_field->fields, i);
2379
2380 bt_ctf_field_freeze(field);
2381 }
2382
2383 generic_field_freeze(field);
2384}
2385
2386static
2387void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
2388{
2389 struct bt_ctf_field_variant *variant_field =
2390 container_of(field, struct bt_ctf_field_variant, parent);
2391
2392 bt_ctf_field_freeze(variant_field->tag);
2393 bt_ctf_field_freeze(variant_field->payload);
2394 generic_field_freeze(field);
2395}
2396
2397static
2398void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
2399{
2400 int i;
2401 struct bt_ctf_field_array *array_field =
2402 container_of(field, struct bt_ctf_field_array, parent);
2403
2404 for (i = 0; i < array_field->elements->len; i++) {
2405 struct bt_ctf_field *field =
2406 g_ptr_array_index(array_field->elements, i);
2407
2408 bt_ctf_field_freeze(field);
2409 }
2410
2411 generic_field_freeze(field);
2412}
2413
2414static
2415void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
2416{
2417 int i;
2418 struct bt_ctf_field_sequence *sequence_field =
2419 container_of(field, struct bt_ctf_field_sequence, parent);
2420
2421 bt_ctf_field_freeze(sequence_field->length);
2422
2423 for (i = 0; i < sequence_field->elements->len; i++) {
2424 struct bt_ctf_field *field =
2425 g_ptr_array_index(sequence_field->elements, i);
2426
2427 bt_ctf_field_freeze(field);
2428 }
2429
2430 generic_field_freeze(field);
2431}
2432
2433BT_HIDDEN
2434void bt_ctf_field_freeze(struct bt_ctf_field *field)
2435{
35f77de4
JG
2436 enum bt_ctf_type_id type_id;
2437
918be005
PP
2438 if (!field) {
2439 goto end;
2440 }
2441
35f77de4
JG
2442 type_id = bt_ctf_field_get_type_id(field);
2443 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
2444 type_id >= BT_CTF_NR_TYPE_IDS) {
2445 goto end;
2446 }
918be005 2447
35f77de4 2448 field_freeze_funcs[type_id](field);
918be005
PP
2449end:
2450 return;
2451}
76f869ab
JG
2452
2453static
2454bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
2455{
2456 return field && field->payload_set;
2457}
2458
2459static
2460bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
2461{
2462 bool is_set = false;
2463 struct bt_ctf_field_enumeration *enumeration;
2464
2465 if (!field) {
2466 goto end;
2467 }
2468
2469 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2470 parent);
2471 if (!enumeration->payload) {
2472 goto end;
2473 }
2474
2475 is_set = bt_ctf_field_is_set(enumeration->payload);
2476end:
2477 return is_set;
2478}
2479
2480static
2481bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
2482{
2483 bool is_set = false;
2484 size_t i;
2485 struct bt_ctf_field_structure *structure;
2486
2487 if (!field) {
2488 goto end;
2489 }
2490
2491 structure = container_of(field, struct bt_ctf_field_structure, parent);
2492 for (i = 0; i < structure->fields->len; i++) {
2493 is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
2494 if (!is_set) {
2495 goto end;
2496 }
2497 }
2498end:
2499 return is_set;
2500}
2501
2502static
2503bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
2504{
2505 bool is_set = false;
2506 struct bt_ctf_field_variant *variant;
2507
2508 if (!field) {
2509 goto end;
2510 }
2511
2512 variant = container_of(field, struct bt_ctf_field_variant, parent);
2513 is_set = bt_ctf_field_is_set(variant->payload);
2514end:
2515 return is_set;
2516}
2517
2518static
2519bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
2520{
2521 size_t i;
2522 bool is_set = false;
2523 struct bt_ctf_field_array *array;
2524
2525 if (!field) {
2526 goto end;
2527 }
2528
2529 array = container_of(field, struct bt_ctf_field_array, parent);
2530 for (i = 0; i < array->elements->len; i++) {
24626e8b 2531 is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
76f869ab
JG
2532 if (!is_set) {
2533 goto end;
2534 }
2535 }
2536end:
2537 return is_set;
2538}
2539
2540static
2541bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
2542{
2543 size_t i;
2544 bool is_set = false;
2545 struct bt_ctf_field_sequence *sequence;
2546
2547 if (!field) {
2548 goto end;
2549 }
2550
2551 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
2552 for (i = 0; i < sequence->elements->len; i++) {
2553 is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
2554 if (!is_set) {
2555 goto end;
2556 }
2557 }
2558end:
2559 return is_set;
2560}
This page took 0.148569 seconds and 4 git commands to generate.