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