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