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