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