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