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