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