Change CTF IR header descriptions from CTF Writer to CTF IR
[babeltrace.git] / formats / ctf / ir / event-fields.c
1 /*
2 * event-fields.c
3 *
4 * Babeltrace CTF IR - Event Fields
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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>
30 #include <babeltrace/ctf-ir/event-fields-internal.h>
31 #include <babeltrace/ctf-ir/event-types-internal.h>
32 #include <babeltrace/compiler.h>
33
34 #define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
35
36 static
37 struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
38 static
39 struct bt_ctf_field *bt_ctf_field_enumeration_create(
40 struct bt_ctf_field_type *);
41 static
42 struct bt_ctf_field *bt_ctf_field_floating_point_create(
43 struct bt_ctf_field_type *);
44 static
45 struct bt_ctf_field *bt_ctf_field_structure_create(
46 struct bt_ctf_field_type *);
47 static
48 struct bt_ctf_field *bt_ctf_field_variant_create(
49 struct bt_ctf_field_type *);
50 static
51 struct bt_ctf_field *bt_ctf_field_array_create(
52 struct bt_ctf_field_type *);
53 static
54 struct bt_ctf_field *bt_ctf_field_sequence_create(
55 struct bt_ctf_field_type *);
56 static
57 struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
58
59 static
60 void bt_ctf_field_destroy(struct bt_ctf_ref *);
61 static
62 void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
63 static
64 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
65 static
66 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
67 static
68 void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
69 static
70 void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
71 static
72 void bt_ctf_field_array_destroy(struct bt_ctf_field *);
73 static
74 void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
75 static
76 void bt_ctf_field_string_destroy(struct bt_ctf_field *);
77
78 static
79 int bt_ctf_field_generic_validate(struct bt_ctf_field *field);
80 static
81 int bt_ctf_field_structure_validate(struct bt_ctf_field *field);
82 static
83 int bt_ctf_field_variant_validate(struct bt_ctf_field *field);
84 static
85 int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field);
86 static
87 int bt_ctf_field_array_validate(struct bt_ctf_field *field);
88 static
89 int bt_ctf_field_sequence_validate(struct bt_ctf_field *field);
90
91 static
92 int bt_ctf_field_generic_reset(struct bt_ctf_field *field);
93 static
94 int bt_ctf_field_structure_reset(struct bt_ctf_field *field);
95 static
96 int bt_ctf_field_variant_reset(struct bt_ctf_field *field);
97 static
98 int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field);
99 static
100 int bt_ctf_field_array_reset(struct bt_ctf_field *field);
101 static
102 int bt_ctf_field_sequence_reset(struct bt_ctf_field *field);
103 static
104 int bt_ctf_field_string_reset(struct bt_ctf_field *field);
105
106 static
107 int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
108 struct ctf_stream_pos *);
109 static
110 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
111 struct ctf_stream_pos *);
112 static
113 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
114 struct ctf_stream_pos *);
115 static
116 int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
117 struct ctf_stream_pos *);
118 static
119 int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
120 struct ctf_stream_pos *);
121 static
122 int bt_ctf_field_array_serialize(struct bt_ctf_field *,
123 struct ctf_stream_pos *);
124 static
125 int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
126 struct ctf_stream_pos *);
127 static
128 int bt_ctf_field_string_serialize(struct bt_ctf_field *,
129 struct ctf_stream_pos *);
130
131 static
132 int increase_packet_size(struct ctf_stream_pos *pos);
133
134 static
135 struct 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
148 static
149 void (*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
161 static
162 int (*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
173 static
174 int (*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
185 static
186 int (*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
199 struct 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);
209 if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES ||
210 bt_ctf_field_type_validate(type)) {
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;
224 error:
225 return field;
226 }
227
228 void bt_ctf_field_get(struct bt_ctf_field *field)
229 {
230 if (field) {
231 bt_ctf_ref_get(&field->ref_count);
232 }
233 }
234
235 void 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
242 struct 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);
252 end:
253 return ret;
254 }
255
256 struct 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);
274 end:
275 return ret;
276 }
277
278 int 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);
299 /* The length field must be unsigned */
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
314 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
315 if (!sequence->elements) {
316 ret = -1;
317 goto end;
318 }
319
320 g_ptr_array_set_free_func(sequence->elements,
321 (GDestroyNotify)bt_ctf_field_put);
322 g_ptr_array_set_size(sequence->elements, (size_t)sequence_length);
323 bt_ctf_field_get(length_field);
324 sequence->length = length_field;
325 end:
326 return ret;
327 }
328
329 struct 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;
335 struct bt_ctf_field_type *field_type = NULL;
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);
346 field_type =
347 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
348 name);
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;
365 end:
366 bt_ctf_field_get(new_field);
367 error:
368 if (field_type) {
369 bt_ctf_field_type_put(field_type);
370 }
371 return new_field;
372 }
373
374 struct 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;
418 end:
419 bt_ctf_field_get(ret_field);
420 error:
421 if (field_type) {
422 bt_ctf_field_type_put(field_type);
423 }
424 return ret_field;
425 }
426
427 BT_HIDDEN
428 int 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;
434 struct bt_ctf_field_type *expected_field_type = NULL;
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);
446 expected_field_type =
447 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
448 name);
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);
465 end:
466 if (expected_field_type) {
467 bt_ctf_field_type_put(expected_field_type);
468 }
469 return ret;
470 }
471
472 struct 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;
476 struct bt_ctf_field_type *field_type = NULL;
477 struct bt_ctf_field_array *array;
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
489 field_type = bt_ctf_field_type_array_get_element_type(field->type);
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;
498 end:
499 if (field_type) {
500 bt_ctf_field_type_put(field_type);
501 }
502 return new_field;
503 }
504
505 struct 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;
509 struct bt_ctf_field_type *field_type = NULL;
510 struct bt_ctf_field_sequence *sequence;
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
522 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
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;
531 end:
532 if (field_type) {
533 bt_ctf_field_type_put(field_type);
534 }
535 return new_field;
536 }
537
538 struct 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;
573 field_type = bt_ctf_field_type_variant_get_field_type_signed(
574 variant_type, tag_enum_value);
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;
590 end:
591 bt_ctf_field_put(tag_enum);
592 return new_field;
593 }
594
595 struct 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
601 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
602 CTF_TYPE_ENUM) {
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);
618 end:
619 return container;
620 }
621
622 const 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
647 if (!integer_type->declaration.signedness) {
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
669 error_put_container_type:
670 bt_ctf_field_type_put(container_type);
671 error_put_container:
672 bt_ctf_field_put(container);
673 end:
674 return name;
675 }
676
677 int 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;
701 end:
702 return ret;
703 }
704
705 int 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;
739 end:
740 return ret;
741 }
742
743 int 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;
767 end:
768 return ret;
769 }
770
771 int 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;
804 end:
805 return ret;
806 }
807
808 int 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;
824 end:
825 return ret;
826 }
827
828 int 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;
844 end:
845 return ret;
846 }
847
848 const 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;
862 end:
863 return ret;
864 }
865
866 int 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) {
881 g_string_assign(string->payload, value);
882 } else {
883 string->payload = g_string_new(value);
884 }
885
886 string->parent.payload_set = 1;
887 end:
888 return ret;
889 }
890
891 BT_HIDDEN
892 int 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);
909 end:
910 return ret;
911 }
912
913 BT_HIDDEN
914 int 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);
931 end:
932 return ret;
933 }
934
935 BT_HIDDEN
936 int 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);
954 end:
955 return ret;
956 }
957
958 static
959 struct 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
973 static
974 struct 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
983 static
984 struct 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
1016 end:
1017 return floating_point ? &floating_point->parent : NULL;
1018 }
1019
1020 static
1021 struct 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;
1040 end:
1041 return field;
1042 }
1043
1044 static
1045 struct 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
1052 static
1053 struct 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;
1065 array->elements = g_ptr_array_sized_new(array_length);
1066 if (!array->elements) {
1067 goto error;
1068 }
1069
1070 g_ptr_array_set_free_func(array->elements,
1071 (GDestroyNotify)bt_ctf_field_put);
1072 g_ptr_array_set_size(array->elements, array_length);
1073 return &array->parent;
1074 error:
1075 g_free(array);
1076 return NULL;
1077 }
1078
1079 static
1080 struct 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
1088 static
1089 struct 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
1096 static
1097 void 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
1121 static
1122 void 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
1134 static
1135 void 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
1149 static
1150 void 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
1163 static
1164 void 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
1177 static
1178 void 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
1192 static
1193 void 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
1206 static
1207 void 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
1221 static
1222 void 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
1234 static
1235 int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1236 {
1237 return (field && field->payload_set) ? 0 : -1;
1238 }
1239
1240 static
1241 int 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);
1259 end:
1260 return ret;
1261 }
1262
1263 static
1264 int 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 }
1282 end:
1283 return ret;
1284 }
1285
1286 static
1287 int 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);
1299 end:
1300 return ret;
1301 }
1302
1303 static
1304 int 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 }
1322 end:
1323 return ret;
1324 }
1325
1326 static
1327 int 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 }
1345 end:
1346 return ret;
1347 }
1348
1349 static
1350 int 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;
1360 end:
1361 return ret;
1362 }
1363
1364 static
1365 int 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);
1382 end:
1383 return ret;
1384 }
1385
1386 static
1387 int 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 }
1415 end:
1416 return ret;
1417 }
1418
1419 static
1420 int 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 }
1434 end:
1435 return ret;
1436 }
1437
1438 static
1439 int 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 }
1467 end:
1468 return ret;
1469 }
1470
1471 static
1472 int 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 }
1500 end:
1501 return ret;
1502 }
1503
1504 static
1505 int 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 }
1524 end:
1525 return ret;
1526 }
1527
1528 static
1529 int 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
1536 retry:
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 }
1549 end:
1550 return ret;
1551 }
1552
1553 static
1554 int 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
1563 static
1564 int 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
1571 retry:
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 }
1584 end:
1585 return ret;
1586 }
1587
1588 static
1589 int 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))) {
1600 ret = increase_packet_size(pos);
1601 if (ret) {
1602 goto end;
1603 }
1604 }
1605
1606 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1607 ret = -1;
1608 goto end;
1609 }
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 }
1620 end:
1621 return ret;
1622 }
1623
1624 static
1625 int 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
1634 static
1635 int 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 }
1650 end:
1651 return ret;
1652 }
1653
1654 static
1655 int 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 }
1670 end:
1671 return ret;
1672 }
1673
1674 static
1675 int 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 }
1698 end:
1699 bt_ctf_field_put(character);
1700 bt_ctf_field_type_put(character_type);
1701 return ret;
1702 }
1703
1704 static
1705 int 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 }
1727 end:
1728 return ret;
1729 }
This page took 0.098631 seconds and 4 git commands to generate.