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