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