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