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