Cleanup: Missing space after cast operator
[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>
273b65be
JG
32#include <babeltrace/compiler.h>
33
34#define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
35
36static
37struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
38static
39struct bt_ctf_field *bt_ctf_field_enumeration_create(
40 struct bt_ctf_field_type *);
41static
42struct bt_ctf_field *bt_ctf_field_floating_point_create(
43 struct bt_ctf_field_type *);
44static
45struct bt_ctf_field *bt_ctf_field_structure_create(
46 struct bt_ctf_field_type *);
47static
48struct bt_ctf_field *bt_ctf_field_variant_create(
49 struct bt_ctf_field_type *);
50static
51struct bt_ctf_field *bt_ctf_field_array_create(
52 struct bt_ctf_field_type *);
53static
54struct bt_ctf_field *bt_ctf_field_sequence_create(
55 struct bt_ctf_field_type *);
56static
57struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
58
59static
60void bt_ctf_field_destroy(struct bt_ctf_ref *);
61static
62void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
63static
64void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
65static
66void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
67static
68void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
69static
70void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
71static
72void bt_ctf_field_array_destroy(struct bt_ctf_field *);
73static
74void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
75static
76void bt_ctf_field_string_destroy(struct bt_ctf_field *);
77
78static
79int bt_ctf_field_generic_validate(struct bt_ctf_field *field);
80static
81int bt_ctf_field_structure_validate(struct bt_ctf_field *field);
82static
83int bt_ctf_field_variant_validate(struct bt_ctf_field *field);
84static
85int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field);
86static
87int bt_ctf_field_array_validate(struct bt_ctf_field *field);
88static
89int bt_ctf_field_sequence_validate(struct bt_ctf_field *field);
90
12c8a1a3
JG
91static
92int bt_ctf_field_generic_reset(struct bt_ctf_field *field);
93static
94int bt_ctf_field_structure_reset(struct bt_ctf_field *field);
95static
96int bt_ctf_field_variant_reset(struct bt_ctf_field *field);
97static
98int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field);
99static
100int bt_ctf_field_array_reset(struct bt_ctf_field *field);
101static
102int bt_ctf_field_sequence_reset(struct bt_ctf_field *field);
103static
104int bt_ctf_field_string_reset(struct bt_ctf_field *field);
105
273b65be
JG
106static
107int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
108 struct ctf_stream_pos *);
109static
110int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
111 struct ctf_stream_pos *);
112static
113int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
114 struct ctf_stream_pos *);
115static
116int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
117 struct ctf_stream_pos *);
118static
119int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
120 struct ctf_stream_pos *);
121static
122int bt_ctf_field_array_serialize(struct bt_ctf_field *,
123 struct ctf_stream_pos *);
124static
125int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
126 struct ctf_stream_pos *);
127static
128int bt_ctf_field_string_serialize(struct bt_ctf_field *,
129 struct ctf_stream_pos *);
130
131static
132int increase_packet_size(struct ctf_stream_pos *pos);
133
134static
135struct bt_ctf_field *(*field_create_funcs[])(
136 struct bt_ctf_field_type *) = {
137 [CTF_TYPE_INTEGER] = bt_ctf_field_integer_create,
138 [CTF_TYPE_ENUM] = bt_ctf_field_enumeration_create,
139 [CTF_TYPE_FLOAT] =
140 bt_ctf_field_floating_point_create,
141 [CTF_TYPE_STRUCT] = bt_ctf_field_structure_create,
142 [CTF_TYPE_VARIANT] = bt_ctf_field_variant_create,
143 [CTF_TYPE_ARRAY] = bt_ctf_field_array_create,
144 [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_create,
145 [CTF_TYPE_STRING] = bt_ctf_field_string_create,
146};
147
148static
149void (*field_destroy_funcs[])(struct bt_ctf_field *) = {
150 [CTF_TYPE_INTEGER] = bt_ctf_field_integer_destroy,
151 [CTF_TYPE_ENUM] = bt_ctf_field_enumeration_destroy,
152 [CTF_TYPE_FLOAT] =
153 bt_ctf_field_floating_point_destroy,
154 [CTF_TYPE_STRUCT] = bt_ctf_field_structure_destroy,
155 [CTF_TYPE_VARIANT] = bt_ctf_field_variant_destroy,
156 [CTF_TYPE_ARRAY] = bt_ctf_field_array_destroy,
157 [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_destroy,
158 [CTF_TYPE_STRING] = bt_ctf_field_string_destroy,
159};
160
161static
162int (*field_validate_funcs[])(struct bt_ctf_field *) = {
163 [CTF_TYPE_INTEGER] = bt_ctf_field_generic_validate,
164 [CTF_TYPE_ENUM] = bt_ctf_field_enumeration_validate,
165 [CTF_TYPE_FLOAT] = bt_ctf_field_generic_validate,
166 [CTF_TYPE_STRUCT] = bt_ctf_field_structure_validate,
167 [CTF_TYPE_VARIANT] = bt_ctf_field_variant_validate,
168 [CTF_TYPE_ARRAY] = bt_ctf_field_array_validate,
169 [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_validate,
170 [CTF_TYPE_STRING] = bt_ctf_field_generic_validate,
171};
172
12c8a1a3
JG
173static
174int (*field_reset_funcs[])(struct bt_ctf_field *) = {
175 [CTF_TYPE_INTEGER] = bt_ctf_field_generic_reset,
176 [CTF_TYPE_ENUM] = bt_ctf_field_enumeration_reset,
177 [CTF_TYPE_FLOAT] = bt_ctf_field_generic_reset,
178 [CTF_TYPE_STRUCT] = bt_ctf_field_structure_reset,
179 [CTF_TYPE_VARIANT] = bt_ctf_field_variant_reset,
180 [CTF_TYPE_ARRAY] = bt_ctf_field_array_reset,
181 [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_reset,
182 [CTF_TYPE_STRING] = bt_ctf_field_string_reset,
183};
184
273b65be
JG
185static
186int (*field_serialize_funcs[])(struct bt_ctf_field *,
187 struct ctf_stream_pos *) = {
188 [CTF_TYPE_INTEGER] = bt_ctf_field_integer_serialize,
189 [CTF_TYPE_ENUM] = bt_ctf_field_enumeration_serialize,
190 [CTF_TYPE_FLOAT] =
191 bt_ctf_field_floating_point_serialize,
192 [CTF_TYPE_STRUCT] = bt_ctf_field_structure_serialize,
193 [CTF_TYPE_VARIANT] = bt_ctf_field_variant_serialize,
194 [CTF_TYPE_ARRAY] = bt_ctf_field_array_serialize,
195 [CTF_TYPE_SEQUENCE] = bt_ctf_field_sequence_serialize,
196 [CTF_TYPE_STRING] = bt_ctf_field_string_serialize,
197};
198
199struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
200{
201 struct bt_ctf_field *field = NULL;
202 enum ctf_type_id type_id;
203
204 if (!type) {
205 goto error;
206 }
207
208 type_id = bt_ctf_field_type_get_type_id(type);
9ce21c30
JG
209 if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES ||
210 bt_ctf_field_type_validate(type)) {
273b65be
JG
211 goto error;
212 }
213
214 field = field_create_funcs[type_id](type);
215 if (!field) {
216 goto error;
217 }
218
219 /* The type's declaration can't change after this point */
220 bt_ctf_field_type_freeze(type);
221 bt_ctf_field_type_get(type);
222 bt_ctf_ref_init(&field->ref_count);
223 field->type = type;
224error:
225 return field;
226}
227
228void bt_ctf_field_get(struct bt_ctf_field *field)
229{
230 if (field) {
231 bt_ctf_ref_get(&field->ref_count);
232 }
233}
234
235void bt_ctf_field_put(struct bt_ctf_field *field)
236{
237 if (field) {
238 bt_ctf_ref_put(&field->ref_count, bt_ctf_field_destroy);
239 }
240}
241
cd95e351
JG
242struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
243{
244 struct bt_ctf_field_type *ret = NULL;
245
246 if (!field) {
247 goto end;
248 }
249
250 ret = field->type;
251 bt_ctf_field_type_get(ret);
252end:
253 return ret;
254}
255
256struct bt_ctf_field *bt_ctf_field_sequence_get_length(
257 struct bt_ctf_field *field)
258{
259 struct bt_ctf_field *ret = NULL;
260 struct bt_ctf_field_sequence *sequence;
261
262 if (!field) {
263 goto end;
264 }
265
266 if (bt_ctf_field_type_get_type_id(field->type) !=
267 CTF_TYPE_SEQUENCE) {
268 goto end;
269 }
270
271 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
272 ret = sequence->length;
273 bt_ctf_field_get(ret);
274end:
275 return ret;
276}
277
273b65be
JG
278int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
279 struct bt_ctf_field *length_field)
280{
281 int ret = 0;
282 struct bt_ctf_field_type_integer *length_type;
283 struct bt_ctf_field_integer *length;
284 struct bt_ctf_field_sequence *sequence;
285 uint64_t sequence_length;
286
287 if (!field || !length_field) {
288 ret = -1;
289 goto end;
290 }
291 if (bt_ctf_field_type_get_type_id(length_field->type) !=
292 CTF_TYPE_INTEGER) {
293 ret = -1;
294 goto end;
295 }
296
297 length_type = container_of(length_field->type,
298 struct bt_ctf_field_type_integer, parent);
152e7331 299 /* The length field must be unsigned */
273b65be
JG
300 if (length_type->declaration.signedness) {
301 ret = -1;
302 goto end;
303 }
304
305 length = container_of(length_field, struct bt_ctf_field_integer,
306 parent);
307 sequence_length = length->definition.value._unsigned;
308 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
309 if (sequence->elements) {
310 g_ptr_array_free(sequence->elements, TRUE);
311 bt_ctf_field_put(sequence->length);
312 }
313
fe0fe95c 314 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
273b65be
JG
315 if (!sequence->elements) {
316 ret = -1;
317 goto end;
318 }
319
fe0fe95c
JG
320 g_ptr_array_set_free_func(sequence->elements,
321 (GDestroyNotify)bt_ctf_field_put);
273b65be
JG
322 g_ptr_array_set_size(sequence->elements, (size_t)sequence_length);
323 bt_ctf_field_get(length_field);
324 sequence->length = length_field;
325end:
326 return ret;
327}
328
329struct bt_ctf_field *bt_ctf_field_structure_get_field(
330 struct bt_ctf_field *field, const char *name)
331{
332 struct bt_ctf_field *new_field = NULL;
333 GQuark field_quark;
334 struct bt_ctf_field_structure *structure;
b92ddaaa 335 struct bt_ctf_field_type *field_type = NULL;
273b65be
JG
336 size_t index;
337
338 if (!field || !name ||
339 bt_ctf_field_type_get_type_id(field->type) !=
340 CTF_TYPE_STRUCT) {
341 goto error;
342 }
343
344 field_quark = g_quark_from_string(name);
345 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
346 field_type =
347 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
348 name);
273b65be
JG
349 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
350 GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
351 goto error;
352 }
353
354 if (structure->fields->pdata[index]) {
355 new_field = structure->fields->pdata[index];
356 goto end;
357 }
358
359 new_field = bt_ctf_field_create(field_type);
360 if (!new_field) {
361 goto error;
362 }
363
364 structure->fields->pdata[index] = new_field;
365end:
366 bt_ctf_field_get(new_field);
367error:
b92ddaaa
JG
368 if (field_type) {
369 bt_ctf_field_type_put(field_type);
370 }
273b65be
JG
371 return new_field;
372}
373
cd95e351
JG
374struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
375 struct bt_ctf_field *field, size_t index)
376{
377 int ret;
378 const char *field_name;
379 struct bt_ctf_field_structure *structure;
380 struct bt_ctf_field_type *structure_type;
381 struct bt_ctf_field_type *field_type = NULL;
382 struct bt_ctf_field *ret_field = NULL;
383
384 if (!field ||
385 bt_ctf_field_type_get_type_id(field->type) != CTF_TYPE_STRUCT) {
386 goto end;
387 }
388
389 structure = container_of(field, struct bt_ctf_field_structure, parent);
390 if (index >= structure->fields->len) {
391 goto error;
392 }
393
394 ret_field = structure->fields->pdata[index];
395 if (ret_field) {
396 goto end;
397 }
398
399 /* Field has not been instanciated yet, create it */
400 structure_type = bt_ctf_field_get_type(field);
401 if (!structure_type) {
402 goto error;
403 }
404
405 ret = bt_ctf_field_type_structure_get_field(structure_type,
406 &field_name, &field_type, index);
407 bt_ctf_field_type_put(structure_type);
408 if (ret) {
409 goto error;
410 }
411
412 ret_field = bt_ctf_field_create(field_type);
413 if (!ret_field) {
414 goto error;
415 }
416
417 structure->fields->pdata[index] = ret_field;
418end:
419 bt_ctf_field_get(ret_field);
420error:
421 if (field_type) {
422 bt_ctf_field_type_put(field_type);
423 }
424 return ret_field;
425}
426
273b65be
JG
427BT_HIDDEN
428int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
429 const char *name, struct bt_ctf_field *value)
430{
431 int ret = 0;
432 GQuark field_quark;
433 struct bt_ctf_field_structure *structure;
b92ddaaa 434 struct bt_ctf_field_type *expected_field_type = NULL;
273b65be
JG
435 size_t index;
436
437 if (!field || !name || !value ||
438 bt_ctf_field_type_get_type_id(field->type) !=
439 CTF_TYPE_STRUCT) {
440 ret = -1;
441 goto end;
442 }
443
444 field_quark = g_quark_from_string(name);
445 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
446 expected_field_type =
447 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
448 name);
273b65be
JG
449 if (expected_field_type != value->type) {
450 ret = -1;
451 goto end;
452 }
453
454 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
455 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
456 goto end;
457 }
458
459 if (structure->fields->pdata[index]) {
460 bt_ctf_field_put(structure->fields->pdata[index]);
461 }
462
463 structure->fields->pdata[index] = value;
464 bt_ctf_field_get(value);
465end:
b92ddaaa
JG
466 if (expected_field_type) {
467 bt_ctf_field_type_put(expected_field_type);
468 }
273b65be
JG
469 return ret;
470}
471
472struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
473 uint64_t index)
474{
475 struct bt_ctf_field *new_field = NULL;
b92ddaaa 476 struct bt_ctf_field_type *field_type = NULL;
273b65be 477 struct bt_ctf_field_array *array;
273b65be
JG
478
479 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
480 CTF_TYPE_ARRAY) {
481 goto end;
482 }
483
484 array = container_of(field, struct bt_ctf_field_array, parent);
485 if (index >= array->elements->len) {
486 goto end;
487 }
488
b92ddaaa 489 field_type = bt_ctf_field_type_array_get_element_type(field->type);
273b65be
JG
490 if (array->elements->pdata[(size_t)index]) {
491 new_field = array->elements->pdata[(size_t)index];
492 goto end;
493 }
494
495 new_field = bt_ctf_field_create(field_type);
496 bt_ctf_field_get(new_field);
497 array->elements->pdata[(size_t)index] = new_field;
498end:
b92ddaaa
JG
499 if (field_type) {
500 bt_ctf_field_type_put(field_type);
501 }
273b65be
JG
502 return new_field;
503}
504
505struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
506 uint64_t index)
507{
508 struct bt_ctf_field *new_field = NULL;
b92ddaaa 509 struct bt_ctf_field_type *field_type = NULL;
273b65be 510 struct bt_ctf_field_sequence *sequence;
273b65be
JG
511
512 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
513 CTF_TYPE_SEQUENCE) {
514 goto end;
515 }
516
517 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
518 if (!sequence->elements || sequence->elements->len <= index) {
519 goto end;
520 }
521
b92ddaaa 522 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
273b65be
JG
523 if (sequence->elements->pdata[(size_t)index]) {
524 new_field = sequence->elements->pdata[(size_t)index];
525 goto end;
526 }
527
528 new_field = bt_ctf_field_create(field_type);
529 bt_ctf_field_get(new_field);
530 sequence->elements->pdata[(size_t)index] = new_field;
531end:
b92ddaaa
JG
532 if (field_type) {
533 bt_ctf_field_type_put(field_type);
534 }
273b65be
JG
535 return new_field;
536}
537
538struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
539 struct bt_ctf_field *tag_field)
540{
541 struct bt_ctf_field *new_field = NULL;
542 struct bt_ctf_field_variant *variant;
543 struct bt_ctf_field_type_variant *variant_type;
544 struct bt_ctf_field_type *field_type;
545 struct bt_ctf_field *tag_enum = NULL;
546 struct bt_ctf_field_integer *tag_enum_integer;
547 int64_t tag_enum_value;
548
549 if (!field || !tag_field ||
550 bt_ctf_field_type_get_type_id(field->type) !=
551 CTF_TYPE_VARIANT ||
552 bt_ctf_field_type_get_type_id(tag_field->type) !=
553 CTF_TYPE_ENUM) {
554 goto end;
555 }
556
557 variant = container_of(field, struct bt_ctf_field_variant, parent);
558 variant_type = container_of(field->type,
559 struct bt_ctf_field_type_variant, parent);
560 tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
561 if (!tag_enum) {
562 goto end;
563 }
564
565 tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
566 parent);
567
568 if (!bt_ctf_field_validate(variant->tag)) {
569 goto end;
570 }
571
572 tag_enum_value = tag_enum_integer->definition.value._signed;
b92ddaaa
JG
573 field_type = bt_ctf_field_type_variant_get_field_type_signed(
574 variant_type, tag_enum_value);
273b65be
JG
575 if (!field_type) {
576 goto end;
577 }
578
579 new_field = bt_ctf_field_create(field_type);
580 if (!new_field) {
581 goto end;
582 }
583
584 bt_ctf_field_put(variant->tag);
585 bt_ctf_field_put(variant->payload);
586 bt_ctf_field_get(new_field);
587 bt_ctf_field_get(tag_field);
588 variant->tag = tag_field;
589 variant->payload = new_field;
590end:
591 bt_ctf_field_put(tag_enum);
592 return new_field;
593}
594
595struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
596 struct bt_ctf_field *field)
597{
598 struct bt_ctf_field *container = NULL;
599 struct bt_ctf_field_enumeration *enumeration;
600
b92ddaaa
JG
601 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
602 CTF_TYPE_ENUM) {
273b65be
JG
603 goto end;
604 }
605
606 enumeration = container_of(field, struct bt_ctf_field_enumeration,
607 parent);
608 if (!enumeration->payload) {
609 struct bt_ctf_field_type_enumeration *enumeration_type =
610 container_of(field->type,
611 struct bt_ctf_field_type_enumeration, parent);
612 enumeration->payload =
613 bt_ctf_field_create(enumeration_type->container);
614 }
615
616 container = enumeration->payload;
617 bt_ctf_field_get(container);
618end:
619 return container;
620}
621
cd95e351
JG
622const char *bt_ctf_field_enumeration_get_mapping_name(
623 struct bt_ctf_field *field)
624{
625 int ret;
626 const char *name = NULL;
627 struct bt_ctf_field *container = NULL;
628 struct bt_ctf_field_type *container_type = NULL;
629 struct bt_ctf_field_type_integer *integer_type = NULL;
630 struct bt_ctf_field_type_enumeration *enumeration_type = NULL;
631
632 container = bt_ctf_field_enumeration_get_container(field);
633 if (!container) {
634 goto end;
635 }
636
637 container_type = bt_ctf_field_get_type(container);
638 if (!container_type) {
639 goto error_put_container;
640 }
641
642 integer_type = container_of(container_type,
643 struct bt_ctf_field_type_integer, parent);
644 enumeration_type = container_of(field->type,
645 struct bt_ctf_field_type_enumeration, parent);
646
10817e06 647 if (!integer_type->declaration.signedness) {
cd95e351
JG
648 uint64_t value;
649 ret = bt_ctf_field_unsigned_integer_get_value(container,
650 &value);
651 if (ret) {
652 goto error_put_container_type;
653 }
654
655 name = bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
656 enumeration_type, value);
657 } else {
658 int64_t value;
659 ret = bt_ctf_field_signed_integer_get_value(container,
660 &value);
661 if (ret) {
662 goto error_put_container_type;
663 }
664
665 name = bt_ctf_field_type_enumeration_get_mapping_name_signed(
666 enumeration_type, value);
667 }
668
669error_put_container_type:
670 bt_ctf_field_type_put(container_type);
671error_put_container:
672 bt_ctf_field_put(container);
673end:
674 return name;
675}
676
677int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
678 int64_t *value)
679{
680 int ret = 0;
681 struct bt_ctf_field_integer *integer;
682 struct bt_ctf_field_type_integer *integer_type;
683
684 if (!field || !value || !field->payload_set ||
685 bt_ctf_field_type_get_type_id(field->type) !=
686 CTF_TYPE_INTEGER) {
687 ret = -1;
688 goto end;
689 }
690
691 integer_type = container_of(field->type,
692 struct bt_ctf_field_type_integer, parent);
693 if (!integer_type->declaration.signedness) {
694 ret = -1;
695 goto end;
696 }
697
698 integer = container_of(field,
699 struct bt_ctf_field_integer, parent);
700 *value = integer->definition.value._signed;
701end:
702 return ret;
703}
704
273b65be
JG
705int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
706 int64_t value)
707{
708 int ret = 0;
709 struct bt_ctf_field_integer *integer;
710 struct bt_ctf_field_type_integer *integer_type;
711 unsigned int size;
712 int64_t min_value, max_value;
713
714 if (!field ||
715 bt_ctf_field_type_get_type_id(field->type) !=
716 CTF_TYPE_INTEGER) {
717 ret = -1;
718 goto end;
719 }
720
721 integer = container_of(field, struct bt_ctf_field_integer, parent);
722 integer_type = container_of(field->type,
723 struct bt_ctf_field_type_integer, parent);
724 if (!integer_type->declaration.signedness) {
725 ret = -1;
726 goto end;
727 }
728
729 size = integer_type->declaration.len;
730 min_value = -((int64_t)1 << (size - 1));
731 max_value = ((int64_t)1 << (size - 1)) - 1;
732 if (value < min_value || value > max_value) {
733 ret = -1;
734 goto end;
735 }
736
737 integer->definition.value._signed = value;
738 integer->parent.payload_set = 1;
739end:
740 return ret;
741}
742
cd95e351
JG
743int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
744 uint64_t *value)
745{
746 int ret = 0;
747 struct bt_ctf_field_integer *integer;
748 struct bt_ctf_field_type_integer *integer_type;
749
750 if (!field || !value || !field->payload_set ||
751 bt_ctf_field_type_get_type_id(field->type) !=
752 CTF_TYPE_INTEGER) {
753 ret = -1;
754 goto end;
755 }
756
757 integer_type = container_of(field->type,
758 struct bt_ctf_field_type_integer, parent);
759 if (integer_type->declaration.signedness) {
760 ret = -1;
761 goto end;
762 }
763
764 integer = container_of(field,
765 struct bt_ctf_field_integer, parent);
766 *value = integer->definition.value._unsigned;
767end:
768 return ret;
769}
770
273b65be
JG
771int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
772 uint64_t value)
773{
774 int ret = 0;
775 struct bt_ctf_field_integer *integer;
776 struct bt_ctf_field_type_integer *integer_type;
777 unsigned int size;
778 uint64_t max_value;
779
780 if (!field ||
781 bt_ctf_field_type_get_type_id(field->type) !=
782 CTF_TYPE_INTEGER) {
783 ret = -1;
784 goto end;
785 }
786
787 integer = container_of(field, struct bt_ctf_field_integer, parent);
788 integer_type = container_of(field->type,
789 struct bt_ctf_field_type_integer, parent);
790 if (integer_type->declaration.signedness) {
791 ret = -1;
792 goto end;
793 }
794
795 size = integer_type->declaration.len;
796 max_value = (size == 64) ? UINT64_MAX : ((uint64_t)1 << size) - 1;
797 if (value > max_value) {
798 ret = -1;
799 goto end;
800 }
801
802 integer->definition.value._unsigned = value;
803 integer->parent.payload_set = 1;
804end:
805 return ret;
806}
807
cd95e351
JG
808int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
809 double *value)
810{
811 int ret = 0;
812 struct bt_ctf_field_floating_point *floating_point;
813
814 if (!field || !value || !field->payload_set ||
815 bt_ctf_field_type_get_type_id(field->type) !=
816 CTF_TYPE_FLOAT) {
817 ret = -1;
818 goto end;
819 }
820
821 floating_point = container_of(field,
822 struct bt_ctf_field_floating_point, parent);
823 *value = floating_point->definition.value;
824end:
825 return ret;
826}
827
273b65be
JG
828int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
829 double value)
830{
831 int ret = 0;
832 struct bt_ctf_field_floating_point *floating_point;
833
834 if (!field ||
835 bt_ctf_field_type_get_type_id(field->type) !=
836 CTF_TYPE_FLOAT) {
837 ret = -1;
838 goto end;
839 }
840 floating_point = container_of(field, struct bt_ctf_field_floating_point,
841 parent);
842 floating_point->definition.value = value;
843 floating_point->parent.payload_set = 1;
844end:
845 return ret;
846}
847
cd95e351
JG
848const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
849{
850 const char *ret = NULL;
851 struct bt_ctf_field_string *string;
852
853 if (!field || !field->payload_set ||
854 bt_ctf_field_type_get_type_id(field->type) !=
855 CTF_TYPE_STRING) {
856 goto end;
857 }
858
859 string = container_of(field,
860 struct bt_ctf_field_string, parent);
861 ret = string->payload->str;
862end:
863 return ret;
864}
865
273b65be
JG
866int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
867 const char *value)
868{
869 int ret = 0;
870 struct bt_ctf_field_string *string;
871
872 if (!field || !value ||
873 bt_ctf_field_type_get_type_id(field->type) !=
874 CTF_TYPE_STRING) {
875 ret = -1;
876 goto end;
877 }
878
879 string = container_of(field, struct bt_ctf_field_string, parent);
880 if (string->payload) {
97736814
JG
881 g_string_assign(string->payload, value);
882 } else {
883 string->payload = g_string_new(value);
273b65be
JG
884 }
885
273b65be
JG
886 string->parent.payload_set = 1;
887end:
888 return ret;
889}
890
891BT_HIDDEN
892int bt_ctf_field_validate(struct bt_ctf_field *field)
893{
894 int ret = 0;
895 enum ctf_type_id type_id;
896
897 if (!field) {
898 ret = -1;
899 goto end;
900 }
901
902 type_id = bt_ctf_field_type_get_type_id(field->type);
903 if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) {
904 ret = -1;
905 goto end;
906 }
907
908 ret = field_validate_funcs[type_id](field);
909end:
910 return ret;
911}
912
12c8a1a3
JG
913BT_HIDDEN
914int bt_ctf_field_reset(struct bt_ctf_field *field)
915{
916 int ret = 0;
917 enum ctf_type_id type_id;
918
919 if (!field) {
920 ret = -1;
921 goto end;
922 }
923
924 type_id = bt_ctf_field_type_get_type_id(field->type);
925 if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) {
926 ret = -1;
927 goto end;
928 }
929
930 ret = field_reset_funcs[type_id](field);
931end:
932 return ret;
933}
934
273b65be
JG
935BT_HIDDEN
936int bt_ctf_field_serialize(struct bt_ctf_field *field,
937 struct ctf_stream_pos *pos)
938{
939 int ret = 0;
940 enum ctf_type_id type_id;
941
942 if (!field || !pos) {
943 ret = -1;
944 goto end;
945 }
946
947 type_id = bt_ctf_field_type_get_type_id(field->type);
948 if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) {
949 ret = -1;
950 goto end;
951 }
952
953 ret = field_serialize_funcs[type_id](field, pos);
954end:
955 return ret;
956}
957
958static
959struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
960{
961 struct bt_ctf_field_type_integer *integer_type = container_of(type,
962 struct bt_ctf_field_type_integer, parent);
963 struct bt_ctf_field_integer *integer = g_new0(
964 struct bt_ctf_field_integer, 1);
965
966 if (integer) {
967 integer->definition.declaration = &integer_type->declaration;
968 }
969
970 return integer ? &integer->parent : NULL;
971}
972
973static
974struct bt_ctf_field *bt_ctf_field_enumeration_create(
975 struct bt_ctf_field_type *type)
976{
977 struct bt_ctf_field_enumeration *enumeration = g_new0(
978 struct bt_ctf_field_enumeration, 1);
979
980 return enumeration ? &enumeration->parent : NULL;
981}
982
983static
984struct bt_ctf_field *bt_ctf_field_floating_point_create(
985 struct bt_ctf_field_type *type)
986{
987 struct bt_ctf_field_floating_point *floating_point;
988 struct bt_ctf_field_type_floating_point *floating_point_type;
989
990 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
991 if (!floating_point) {
992 goto end;
993 }
994
995 floating_point_type = container_of(type,
996 struct bt_ctf_field_type_floating_point, parent);
997 floating_point->definition.declaration = container_of(
998 type->declaration, struct declaration_float, p);
999
1000
1001 floating_point->definition.sign = &floating_point->sign;
1002 floating_point->sign.declaration = &floating_point_type->sign;
1003 floating_point->definition.sign->p.declaration =
1004 &floating_point_type->sign.p;
1005
1006 floating_point->definition.mantissa = &floating_point->mantissa;
1007 floating_point->mantissa.declaration = &floating_point_type->mantissa;
1008 floating_point->definition.mantissa->p.declaration =
1009 &floating_point_type->mantissa.p;
1010
1011 floating_point->definition.exp = &floating_point->exp;
1012 floating_point->exp.declaration = &floating_point_type->exp;
1013 floating_point->definition.exp->p.declaration =
1014 &floating_point_type->exp.p;
1015
1016end:
1017 return floating_point ? &floating_point->parent : NULL;
1018}
1019
1020static
1021struct bt_ctf_field *bt_ctf_field_structure_create(
1022 struct bt_ctf_field_type *type)
1023{
1024 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1025 struct bt_ctf_field_type_structure, parent);
1026 struct bt_ctf_field_structure *structure = g_new0(
1027 struct bt_ctf_field_structure, 1);
1028 struct bt_ctf_field *field = NULL;
1029
1030 if (!structure || !structure_type->fields->len) {
1031 goto end;
1032 }
1033
1034 structure->field_name_to_index = structure_type->field_name_to_index;
1035 structure->fields = g_ptr_array_new_with_free_func(
1036 (GDestroyNotify)bt_ctf_field_put);
1037 g_ptr_array_set_size(structure->fields,
1038 g_hash_table_size(structure->field_name_to_index));
1039 field = &structure->parent;
1040end:
1041 return field;
1042}
1043
1044static
1045struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1046{
1047 struct bt_ctf_field_variant *variant = g_new0(
1048 struct bt_ctf_field_variant, 1);
1049 return variant ? &variant->parent : NULL;
1050}
1051
1052static
1053struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1054{
1055 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1056 struct bt_ctf_field_type_array *array_type;
1057 unsigned int array_length;
1058
1059 if (!array || !type) {
1060 goto error;
1061 }
1062
1063 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1064 array_length = array_type->length;
fe0fe95c 1065 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1066 if (!array->elements) {
1067 goto error;
1068 }
1069
fe0fe95c
JG
1070 g_ptr_array_set_free_func(array->elements,
1071 (GDestroyNotify)bt_ctf_field_put);
273b65be
JG
1072 g_ptr_array_set_size(array->elements, array_length);
1073 return &array->parent;
1074error:
1075 g_free(array);
1076 return NULL;
1077}
1078
1079static
1080struct bt_ctf_field *bt_ctf_field_sequence_create(
1081 struct bt_ctf_field_type *type)
1082{
1083 struct bt_ctf_field_sequence *sequence = g_new0(
1084 struct bt_ctf_field_sequence, 1);
1085 return sequence ? &sequence->parent : NULL;
1086}
1087
1088static
1089struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1090{
1091 struct bt_ctf_field_string *string = g_new0(
1092 struct bt_ctf_field_string, 1);
1093 return string ? &string->parent : NULL;
1094}
1095
1096static
1097void bt_ctf_field_destroy(struct bt_ctf_ref *ref)
1098{
1099 struct bt_ctf_field *field;
1100 struct bt_ctf_field_type *type;
1101 enum ctf_type_id type_id;
1102
1103 if (!ref) {
1104 return;
1105 }
1106
1107 field = container_of(ref, struct bt_ctf_field, ref_count);
1108 type = field->type;
1109 type_id = bt_ctf_field_type_get_type_id(type);
1110 if (type_id <= CTF_TYPE_UNKNOWN ||
1111 type_id >= NR_CTF_TYPES) {
1112 return;
1113 }
1114
1115 field_destroy_funcs[type_id](field);
1116 if (type) {
1117 bt_ctf_field_type_put(type);
1118 }
1119}
1120
1121static
1122void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1123{
1124 struct bt_ctf_field_integer *integer;
1125
1126 if (!field) {
1127 return;
1128 }
1129
1130 integer = container_of(field, struct bt_ctf_field_integer, parent);
1131 g_free(integer);
1132}
1133
1134static
1135void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1136{
1137 struct bt_ctf_field_enumeration *enumeration;
1138
1139 if (!field) {
1140 return;
1141 }
1142
1143 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1144 parent);
1145 bt_ctf_field_put(enumeration->payload);
1146 g_free(enumeration);
1147}
1148
1149static
1150void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
1151{
1152 struct bt_ctf_field_floating_point *floating_point;
1153
1154 if (!field) {
1155 return;
1156 }
1157
1158 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1159 parent);
1160 g_free(floating_point);
1161}
1162
1163static
1164void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
1165{
1166 struct bt_ctf_field_structure *structure;
1167
1168 if (!field) {
1169 return;
1170 }
1171
1172 structure = container_of(field, struct bt_ctf_field_structure, parent);
1173 g_ptr_array_free(structure->fields, TRUE);
1174 g_free(structure);
1175}
1176
1177static
1178void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
1179{
1180 struct bt_ctf_field_variant *variant;
1181
1182 if (!field) {
1183 return;
1184 }
1185
1186 variant = container_of(field, struct bt_ctf_field_variant, parent);
1187 bt_ctf_field_put(variant->tag);
1188 bt_ctf_field_put(variant->payload);
1189 g_free(variant);
1190}
1191
1192static
1193void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
1194{
1195 struct bt_ctf_field_array *array;
1196
1197 if (!field) {
1198 return;
1199 }
1200
1201 array = container_of(field, struct bt_ctf_field_array, parent);
1202 g_ptr_array_free(array->elements, TRUE);
1203 g_free(array);
1204}
1205
1206static
1207void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
1208{
1209 struct bt_ctf_field_sequence *sequence;
1210
1211 if (!field) {
1212 return;
1213 }
1214
1215 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1216 g_ptr_array_free(sequence->elements, TRUE);
1217 bt_ctf_field_put(sequence->length);
1218 g_free(sequence);
1219}
1220
1221static
1222void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
1223{
1224 struct bt_ctf_field_string *string;
1225 if (!field) {
1226 return;
1227 }
1228
1229 string = container_of(field, struct bt_ctf_field_string, parent);
1230 g_string_free(string->payload, TRUE);
1231 g_free(string);
1232}
1233
1234static
1235int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1236{
da2f6971 1237 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
1238}
1239
1240static
1241int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
1242{
1243 int ret;
1244 struct bt_ctf_field_enumeration *enumeration;
1245
1246 if (!field) {
1247 ret = -1;
1248 goto end;
1249 }
1250
1251 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1252 parent);
1253 if (!enumeration->payload) {
1254 ret = -1;
1255 goto end;
1256 }
1257
1258 ret = bt_ctf_field_validate(enumeration->payload);
1259end:
1260 return ret;
1261}
1262
1263static
1264int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
1265{
1266 size_t i;
1267 int ret = 0;
1268 struct bt_ctf_field_structure *structure;
1269
1270 if (!field) {
1271 ret = -1;
1272 goto end;
1273 }
1274
1275 structure = container_of(field, struct bt_ctf_field_structure, parent);
1276 for (i = 0; i < structure->fields->len; i++) {
1277 ret = bt_ctf_field_validate(structure->fields->pdata[i]);
1278 if (ret) {
1279 goto end;
1280 }
1281 }
1282end:
1283 return ret;
1284}
1285
1286static
1287int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1288{
1289 int ret = 0;
1290 struct bt_ctf_field_variant *variant;
1291
1292 if (!field) {
1293 ret = -1;
1294 goto end;
1295 }
1296
1297 variant = container_of(field, struct bt_ctf_field_variant, parent);
1298 ret = bt_ctf_field_validate(variant->payload);
1299end:
1300 return ret;
1301}
1302
1303static
1304int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1305{
1306 size_t i;
1307 int ret = 0;
1308 struct bt_ctf_field_array *array;
1309
1310 if (!field) {
1311 ret = -1;
1312 goto end;
1313 }
1314
1315 array = container_of(field, struct bt_ctf_field_array, parent);
1316 for (i = 0; i < array->elements->len; i++) {
1317 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1318 if (ret) {
1319 goto end;
1320 }
1321 }
1322end:
1323 return ret;
1324}
1325
1326static
1327int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1328{
1329 size_t i;
1330 int ret = 0;
1331 struct bt_ctf_field_sequence *sequence;
1332
1333 if (!field) {
1334 ret = -1;
1335 goto end;
1336 }
1337
1338 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1339 for (i = 0; i < sequence->elements->len; i++) {
1340 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1341 if (ret) {
1342 goto end;
1343 }
1344 }
1345end:
1346 return ret;
1347}
1348
12c8a1a3
JG
1349static
1350int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1351{
1352 int ret = 0;
1353
1354 if (!field) {
1355 ret = -1;
1356 goto end;
1357 }
1358
1359 field->payload_set = 0;
1360end:
1361 return ret;
1362}
1363
1364static
1365int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1366{
1367 int ret = 0;
1368 struct bt_ctf_field_enumeration *enumeration;
1369
1370 if (!field) {
1371 ret = -1;
1372 goto end;
1373 }
1374
1375 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1376 parent);
1377 if (!enumeration->payload) {
1378 goto end;
1379 }
1380
1381 ret = bt_ctf_field_reset(enumeration->payload);
1382end:
1383 return ret;
1384}
1385
1386static
1387int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1388{
1389 size_t i;
1390 int ret = 0;
1391 struct bt_ctf_field_structure *structure;
1392
1393 if (!field) {
1394 ret = -1;
1395 goto end;
1396 }
1397
1398 structure = container_of(field, struct bt_ctf_field_structure, parent);
1399 for (i = 0; i < structure->fields->len; i++) {
1400 struct bt_ctf_field *member = structure->fields->pdata[i];
1401
1402 if (!member) {
1403 /*
1404 * Structure members are lazily initialized; skip if
1405 * this member has not been allocated yet.
1406 */
1407 continue;
1408 }
1409
1410 ret = bt_ctf_field_reset(member);
1411 if (ret) {
1412 goto end;
1413 }
1414 }
1415end:
1416 return ret;
1417}
1418
1419static
1420int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1421{
1422 int ret = 0;
1423 struct bt_ctf_field_variant *variant;
1424
1425 if (!field) {
1426 ret = -1;
1427 goto end;
1428 }
1429
1430 variant = container_of(field, struct bt_ctf_field_variant, parent);
1431 if (variant->payload) {
1432 ret = bt_ctf_field_reset(variant->payload);
1433 }
1434end:
1435 return ret;
1436}
1437
1438static
1439int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1440{
1441 size_t i;
1442 int ret = 0;
1443 struct bt_ctf_field_array *array;
1444
1445 if (!field) {
1446 ret = -1;
1447 goto end;
1448 }
1449
1450 array = container_of(field, struct bt_ctf_field_array, parent);
1451 for (i = 0; i < array->elements->len; i++) {
1452 struct bt_ctf_field *member = array->elements->pdata[i];
1453
1454 if (!member) {
1455 /*
1456 * Array elements are lazily initialized; skip if
1457 * this member has not been allocated yet.
1458 */
1459 continue;
1460 }
1461
1462 ret = bt_ctf_field_reset(member);
1463 if (ret) {
1464 goto end;
1465 }
1466 }
1467end:
1468 return ret;
1469}
1470
1471static
1472int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1473{
1474 size_t i;
1475 int ret = 0;
1476 struct bt_ctf_field_sequence *sequence;
1477
1478 if (!field) {
1479 ret = -1;
1480 goto end;
1481 }
1482
1483 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1484 for (i = 0; i < sequence->elements->len; i++) {
1485 struct bt_ctf_field *member = sequence->elements->pdata[i];
1486
1487 if (!member) {
1488 /*
1489 * Sequence elements are lazily initialized; skip if
1490 * this member has not been allocated yet.
1491 */
1492 continue;
1493 }
1494
1495 ret = bt_ctf_field_reset(member);
1496 if (ret) {
1497 goto end;
1498 }
1499 }
1500end:
1501 return ret;
1502}
1503
1504static
1505int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1506{
1507 int ret = 0;
1508 struct bt_ctf_field_string *string;
1509
1510 if (!field) {
1511 ret = -1;
1512 goto end;
1513 }
1514
1515 ret = bt_ctf_field_generic_reset(field);
1516 if (ret) {
1517 goto end;
1518 }
1519
1520 string = container_of(field, struct bt_ctf_field_string, parent);
1521 if (string->payload) {
1522 g_string_truncate(string->payload, 0);
1523 }
1524end:
1525 return ret;
1526}
1527
273b65be
JG
1528static
1529int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1530 struct ctf_stream_pos *pos)
1531{
1532 int ret = 0;
1533 struct bt_ctf_field_integer *integer = container_of(field,
1534 struct bt_ctf_field_integer, parent);
1535
1536retry:
1537 ret = ctf_integer_write(&pos->parent, &integer->definition.p);
1538 if (ret == -EFAULT) {
1539 /*
1540 * The field is too large to fit in the current packet's
1541 * remaining space. Bump the packet size and retry.
1542 */
1543 ret = increase_packet_size(pos);
1544 if (ret) {
1545 goto end;
1546 }
1547 goto retry;
1548 }
1549end:
1550 return ret;
1551}
1552
1553static
1554int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1555 struct ctf_stream_pos *pos)
1556{
1557 struct bt_ctf_field_enumeration *enumeration = container_of(
1558 field, struct bt_ctf_field_enumeration, parent);
1559
1560 return bt_ctf_field_serialize(enumeration->payload, pos);
1561}
1562
1563static
1564int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1565 struct ctf_stream_pos *pos)
1566{
1567 int ret = 0;
1568 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1569 struct bt_ctf_field_floating_point, parent);
1570
1571retry:
1572 ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
1573 if (ret == -EFAULT) {
1574 /*
1575 * The field is too large to fit in the current packet's
1576 * remaining space. Bump the packet size and retry.
1577 */
1578 ret = increase_packet_size(pos);
1579 if (ret) {
1580 goto end;
1581 }
1582 goto retry;
1583 }
1584end:
1585 return ret;
1586}
1587
1588static
1589int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1590 struct ctf_stream_pos *pos)
1591{
1592 size_t i;
1593 int ret = 0;
1594 struct bt_ctf_field_structure *structure = container_of(
1595 field, struct bt_ctf_field_structure, parent);
1596
1597 while (!ctf_pos_access_ok(pos,
1598 offset_align(pos->offset,
1599 field->type->declaration->alignment))) {
9f56e450
JG
1600 ret = increase_packet_size(pos);
1601 if (ret) {
1602 goto end;
1603 }
273b65be
JG
1604 }
1605
70fd5a51
MD
1606 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1607 ret = -1;
1608 goto end;
1609 }
273b65be
JG
1610
1611 for (i = 0; i < structure->fields->len; i++) {
1612 struct bt_ctf_field *field = g_ptr_array_index(
1613 structure->fields, i);
1614
1615 ret = bt_ctf_field_serialize(field, pos);
1616 if (ret) {
1617 break;
1618 }
1619 }
9f56e450 1620end:
273b65be
JG
1621 return ret;
1622}
1623
1624static
1625int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
1626 struct ctf_stream_pos *pos)
1627{
1628 struct bt_ctf_field_variant *variant = container_of(
1629 field, struct bt_ctf_field_variant, parent);
1630
1631 return bt_ctf_field_serialize(variant->payload, pos);
1632}
1633
1634static
1635int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
1636 struct ctf_stream_pos *pos)
1637{
1638 size_t i;
1639 int ret = 0;
1640 struct bt_ctf_field_array *array = container_of(
1641 field, struct bt_ctf_field_array, parent);
1642
1643 for (i = 0; i < array->elements->len; i++) {
1644 ret = bt_ctf_field_serialize(
1645 g_ptr_array_index(array->elements, i), pos);
1646 if (ret) {
1647 goto end;
1648 }
1649 }
1650end:
1651 return ret;
1652}
1653
1654static
1655int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
1656 struct ctf_stream_pos *pos)
1657{
1658 size_t i;
1659 int ret = 0;
1660 struct bt_ctf_field_sequence *sequence = container_of(
1661 field, struct bt_ctf_field_sequence, parent);
1662
1663 for (i = 0; i < sequence->elements->len; i++) {
1664 ret = bt_ctf_field_serialize(
1665 g_ptr_array_index(sequence->elements, i), pos);
1666 if (ret) {
1667 goto end;
1668 }
1669 }
1670end:
1671 return ret;
1672}
1673
1674static
1675int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
1676 struct ctf_stream_pos *pos)
1677{
1678 size_t i;
1679 int ret = 0;
1680 struct bt_ctf_field_string *string = container_of(field,
1681 struct bt_ctf_field_string, parent);
1682 struct bt_ctf_field_type *character_type =
1683 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
1684 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
1685
1686 for (i = 0; i < string->payload->len + 1; i++) {
1687 ret = bt_ctf_field_unsigned_integer_set_value(character,
1688 (uint64_t) string->payload->str[i]);
1689 if (ret) {
1690 goto end;
1691 }
1692
1693 ret = bt_ctf_field_integer_serialize(character, pos);
1694 if (ret) {
1695 goto end;
1696 }
1697 }
1698end:
1699 bt_ctf_field_put(character);
1700 bt_ctf_field_type_put(character_type);
1701 return ret;
1702}
1703
1704static
1705int increase_packet_size(struct ctf_stream_pos *pos)
1706{
1707 int ret;
1708
1709 assert(pos);
1710 ret = munmap_align(pos->base_mma);
1711 if (ret) {
1712 goto end;
1713 }
1714
1715 pos->packet_size += PACKET_LEN_INCREMENT;
1716 ret = posix_fallocate(pos->fd, pos->mmap_offset,
1717 pos->packet_size / CHAR_BIT);
1718 if (ret) {
1719 goto end;
1720 }
1721
1722 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
1723 pos->flags, pos->fd, pos->mmap_offset);
1724 if (pos->base_mma == MAP_FAILED) {
1725 ret = -1;
1726 }
1727end:
1728 return ret;
1729}
This page took 0.090025 seconds and 4 git commands to generate.