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