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