Add bt_ctf_field_type_copy() which allows deep copy of IR types
[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
ca116246 79int bt_ctf_field_generic_validate(struct bt_ctf_field *);
273b65be 80static
ca116246 81int bt_ctf_field_structure_validate(struct bt_ctf_field *);
273b65be 82static
ca116246 83int bt_ctf_field_variant_validate(struct bt_ctf_field *);
273b65be 84static
ca116246 85int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
273b65be 86static
ca116246 87int bt_ctf_field_array_validate(struct bt_ctf_field *);
273b65be 88static
ca116246 89int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
273b65be 90
12c8a1a3 91static
ca116246 92int bt_ctf_field_generic_reset(struct bt_ctf_field *);
12c8a1a3 93static
ca116246 94int bt_ctf_field_structure_reset(struct bt_ctf_field *);
12c8a1a3 95static
ca116246 96int bt_ctf_field_variant_reset(struct bt_ctf_field *);
12c8a1a3 97static
ca116246 98int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
12c8a1a3 99static
ca116246 100int bt_ctf_field_array_reset(struct bt_ctf_field *);
12c8a1a3 101static
ca116246 102int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
12c8a1a3 103static
ca116246 104int bt_ctf_field_string_reset(struct bt_ctf_field *);
12c8a1a3 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) {
87d43dc1
JG
996 goto end;
997 }
998
999 type_id = bt_ctf_field_type_get_type_id(field->type);
1000 if (type_id <= CTF_TYPE_UNKNOWN || type_id >= NR_CTF_TYPES) {
87d43dc1
JG
1001 goto end;
1002 }
1003
1004 copy = bt_ctf_field_create(field->type);
1005 if (!copy) {
1006 goto end;
1007 }
1008
87d43dc1
JG
1009 ret = field_copy_funcs[type_id](field, copy);
1010 if (ret) {
1011 bt_ctf_field_put(copy);
1012 copy = NULL;
1013 }
1014end:
1015 return copy;
1016}
1017
273b65be
JG
1018static
1019struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1020{
1021 struct bt_ctf_field_type_integer *integer_type = container_of(type,
1022 struct bt_ctf_field_type_integer, parent);
1023 struct bt_ctf_field_integer *integer = g_new0(
1024 struct bt_ctf_field_integer, 1);
1025
1026 if (integer) {
1027 integer->definition.declaration = &integer_type->declaration;
1028 }
1029
1030 return integer ? &integer->parent : NULL;
1031}
1032
1033static
1034struct bt_ctf_field *bt_ctf_field_enumeration_create(
1035 struct bt_ctf_field_type *type)
1036{
1037 struct bt_ctf_field_enumeration *enumeration = g_new0(
1038 struct bt_ctf_field_enumeration, 1);
1039
1040 return enumeration ? &enumeration->parent : NULL;
1041}
1042
1043static
1044struct bt_ctf_field *bt_ctf_field_floating_point_create(
1045 struct bt_ctf_field_type *type)
1046{
1047 struct bt_ctf_field_floating_point *floating_point;
1048 struct bt_ctf_field_type_floating_point *floating_point_type;
1049
1050 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
1051 if (!floating_point) {
1052 goto end;
1053 }
1054
1055 floating_point_type = container_of(type,
1056 struct bt_ctf_field_type_floating_point, parent);
1057 floating_point->definition.declaration = container_of(
1058 type->declaration, struct declaration_float, p);
1059
1060
1061 floating_point->definition.sign = &floating_point->sign;
1062 floating_point->sign.declaration = &floating_point_type->sign;
1063 floating_point->definition.sign->p.declaration =
1064 &floating_point_type->sign.p;
1065
1066 floating_point->definition.mantissa = &floating_point->mantissa;
1067 floating_point->mantissa.declaration = &floating_point_type->mantissa;
1068 floating_point->definition.mantissa->p.declaration =
1069 &floating_point_type->mantissa.p;
1070
1071 floating_point->definition.exp = &floating_point->exp;
1072 floating_point->exp.declaration = &floating_point_type->exp;
1073 floating_point->definition.exp->p.declaration =
1074 &floating_point_type->exp.p;
1075
1076end:
1077 return floating_point ? &floating_point->parent : NULL;
1078}
1079
1080static
1081struct bt_ctf_field *bt_ctf_field_structure_create(
1082 struct bt_ctf_field_type *type)
1083{
1084 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1085 struct bt_ctf_field_type_structure, parent);
1086 struct bt_ctf_field_structure *structure = g_new0(
1087 struct bt_ctf_field_structure, 1);
1088 struct bt_ctf_field *field = NULL;
1089
1090 if (!structure || !structure_type->fields->len) {
1091 goto end;
1092 }
1093
1094 structure->field_name_to_index = structure_type->field_name_to_index;
1095 structure->fields = g_ptr_array_new_with_free_func(
1096 (GDestroyNotify)bt_ctf_field_put);
1097 g_ptr_array_set_size(structure->fields,
1098 g_hash_table_size(structure->field_name_to_index));
1099 field = &structure->parent;
1100end:
1101 return field;
1102}
1103
1104static
1105struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1106{
1107 struct bt_ctf_field_variant *variant = g_new0(
1108 struct bt_ctf_field_variant, 1);
1109 return variant ? &variant->parent : NULL;
1110}
1111
1112static
1113struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1114{
1115 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1116 struct bt_ctf_field_type_array *array_type;
1117 unsigned int array_length;
1118
1119 if (!array || !type) {
1120 goto error;
1121 }
1122
1123 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1124 array_length = array_type->length;
fe0fe95c 1125 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1126 if (!array->elements) {
1127 goto error;
1128 }
1129
fe0fe95c
JG
1130 g_ptr_array_set_free_func(array->elements,
1131 (GDestroyNotify)bt_ctf_field_put);
273b65be
JG
1132 g_ptr_array_set_size(array->elements, array_length);
1133 return &array->parent;
1134error:
1135 g_free(array);
1136 return NULL;
1137}
1138
1139static
1140struct bt_ctf_field *bt_ctf_field_sequence_create(
1141 struct bt_ctf_field_type *type)
1142{
1143 struct bt_ctf_field_sequence *sequence = g_new0(
1144 struct bt_ctf_field_sequence, 1);
1145 return sequence ? &sequence->parent : NULL;
1146}
1147
1148static
1149struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1150{
1151 struct bt_ctf_field_string *string = g_new0(
1152 struct bt_ctf_field_string, 1);
1153 return string ? &string->parent : NULL;
1154}
1155
1156static
1157void bt_ctf_field_destroy(struct bt_ctf_ref *ref)
1158{
1159 struct bt_ctf_field *field;
1160 struct bt_ctf_field_type *type;
1161 enum ctf_type_id type_id;
1162
1163 if (!ref) {
1164 return;
1165 }
1166
1167 field = container_of(ref, struct bt_ctf_field, ref_count);
1168 type = field->type;
1169 type_id = bt_ctf_field_type_get_type_id(type);
1170 if (type_id <= CTF_TYPE_UNKNOWN ||
1171 type_id >= NR_CTF_TYPES) {
1172 return;
1173 }
1174
1175 field_destroy_funcs[type_id](field);
1176 if (type) {
1177 bt_ctf_field_type_put(type);
1178 }
1179}
1180
1181static
1182void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1183{
1184 struct bt_ctf_field_integer *integer;
1185
1186 if (!field) {
1187 return;
1188 }
1189
1190 integer = container_of(field, struct bt_ctf_field_integer, parent);
1191 g_free(integer);
1192}
1193
1194static
1195void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1196{
1197 struct bt_ctf_field_enumeration *enumeration;
1198
1199 if (!field) {
1200 return;
1201 }
1202
1203 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1204 parent);
1205 bt_ctf_field_put(enumeration->payload);
1206 g_free(enumeration);
1207}
1208
1209static
1210void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
1211{
1212 struct bt_ctf_field_floating_point *floating_point;
1213
1214 if (!field) {
1215 return;
1216 }
1217
1218 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1219 parent);
1220 g_free(floating_point);
1221}
1222
1223static
1224void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
1225{
1226 struct bt_ctf_field_structure *structure;
1227
1228 if (!field) {
1229 return;
1230 }
1231
1232 structure = container_of(field, struct bt_ctf_field_structure, parent);
1233 g_ptr_array_free(structure->fields, TRUE);
1234 g_free(structure);
1235}
1236
1237static
1238void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
1239{
1240 struct bt_ctf_field_variant *variant;
1241
1242 if (!field) {
1243 return;
1244 }
1245
1246 variant = container_of(field, struct bt_ctf_field_variant, parent);
1247 bt_ctf_field_put(variant->tag);
1248 bt_ctf_field_put(variant->payload);
1249 g_free(variant);
1250}
1251
1252static
1253void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
1254{
1255 struct bt_ctf_field_array *array;
1256
1257 if (!field) {
1258 return;
1259 }
1260
1261 array = container_of(field, struct bt_ctf_field_array, parent);
1262 g_ptr_array_free(array->elements, TRUE);
1263 g_free(array);
1264}
1265
1266static
1267void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
1268{
1269 struct bt_ctf_field_sequence *sequence;
1270
1271 if (!field) {
1272 return;
1273 }
1274
1275 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1276 g_ptr_array_free(sequence->elements, TRUE);
1277 bt_ctf_field_put(sequence->length);
1278 g_free(sequence);
1279}
1280
1281static
1282void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
1283{
1284 struct bt_ctf_field_string *string;
1285 if (!field) {
1286 return;
1287 }
1288
1289 string = container_of(field, struct bt_ctf_field_string, parent);
1290 g_string_free(string->payload, TRUE);
1291 g_free(string);
1292}
1293
1294static
1295int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1296{
da2f6971 1297 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
1298}
1299
1300static
1301int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
1302{
1303 int ret;
1304 struct bt_ctf_field_enumeration *enumeration;
1305
1306 if (!field) {
1307 ret = -1;
1308 goto end;
1309 }
1310
1311 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1312 parent);
1313 if (!enumeration->payload) {
1314 ret = -1;
1315 goto end;
1316 }
1317
1318 ret = bt_ctf_field_validate(enumeration->payload);
1319end:
1320 return ret;
1321}
1322
1323static
1324int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
1325{
1326 size_t i;
1327 int ret = 0;
1328 struct bt_ctf_field_structure *structure;
1329
1330 if (!field) {
1331 ret = -1;
1332 goto end;
1333 }
1334
1335 structure = container_of(field, struct bt_ctf_field_structure, parent);
1336 for (i = 0; i < structure->fields->len; i++) {
1337 ret = bt_ctf_field_validate(structure->fields->pdata[i]);
1338 if (ret) {
1339 goto end;
1340 }
1341 }
1342end:
1343 return ret;
1344}
1345
1346static
1347int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1348{
1349 int ret = 0;
1350 struct bt_ctf_field_variant *variant;
1351
1352 if (!field) {
1353 ret = -1;
1354 goto end;
1355 }
1356
1357 variant = container_of(field, struct bt_ctf_field_variant, parent);
1358 ret = bt_ctf_field_validate(variant->payload);
1359end:
1360 return ret;
1361}
1362
1363static
1364int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1365{
1366 size_t i;
1367 int ret = 0;
1368 struct bt_ctf_field_array *array;
1369
1370 if (!field) {
1371 ret = -1;
1372 goto end;
1373 }
1374
1375 array = container_of(field, struct bt_ctf_field_array, parent);
1376 for (i = 0; i < array->elements->len; i++) {
1377 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1378 if (ret) {
1379 goto end;
1380 }
1381 }
1382end:
1383 return ret;
1384}
1385
1386static
1387int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1388{
1389 size_t i;
1390 int ret = 0;
1391 struct bt_ctf_field_sequence *sequence;
1392
1393 if (!field) {
1394 ret = -1;
1395 goto end;
1396 }
1397
1398 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1399 for (i = 0; i < sequence->elements->len; i++) {
1400 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1401 if (ret) {
1402 goto end;
1403 }
1404 }
1405end:
1406 return ret;
1407}
1408
12c8a1a3
JG
1409static
1410int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1411{
1412 int ret = 0;
1413
1414 if (!field) {
1415 ret = -1;
1416 goto end;
1417 }
1418
1419 field->payload_set = 0;
1420end:
1421 return ret;
1422}
1423
1424static
1425int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1426{
1427 int ret = 0;
1428 struct bt_ctf_field_enumeration *enumeration;
1429
1430 if (!field) {
1431 ret = -1;
1432 goto end;
1433 }
1434
1435 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1436 parent);
1437 if (!enumeration->payload) {
1438 goto end;
1439 }
1440
1441 ret = bt_ctf_field_reset(enumeration->payload);
1442end:
1443 return ret;
1444}
1445
1446static
1447int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1448{
1449 size_t i;
1450 int ret = 0;
1451 struct bt_ctf_field_structure *structure;
1452
1453 if (!field) {
1454 ret = -1;
1455 goto end;
1456 }
1457
1458 structure = container_of(field, struct bt_ctf_field_structure, parent);
1459 for (i = 0; i < structure->fields->len; i++) {
1460 struct bt_ctf_field *member = structure->fields->pdata[i];
1461
1462 if (!member) {
1463 /*
1464 * Structure members are lazily initialized; skip if
1465 * this member has not been allocated yet.
1466 */
1467 continue;
1468 }
1469
1470 ret = bt_ctf_field_reset(member);
1471 if (ret) {
1472 goto end;
1473 }
1474 }
1475end:
1476 return ret;
1477}
1478
1479static
1480int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1481{
1482 int ret = 0;
1483 struct bt_ctf_field_variant *variant;
1484
1485 if (!field) {
1486 ret = -1;
1487 goto end;
1488 }
1489
1490 variant = container_of(field, struct bt_ctf_field_variant, parent);
1491 if (variant->payload) {
1492 ret = bt_ctf_field_reset(variant->payload);
1493 }
1494end:
1495 return ret;
1496}
1497
1498static
1499int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1500{
1501 size_t i;
1502 int ret = 0;
1503 struct bt_ctf_field_array *array;
1504
1505 if (!field) {
1506 ret = -1;
1507 goto end;
1508 }
1509
1510 array = container_of(field, struct bt_ctf_field_array, parent);
1511 for (i = 0; i < array->elements->len; i++) {
1512 struct bt_ctf_field *member = array->elements->pdata[i];
1513
1514 if (!member) {
1515 /*
1516 * Array elements are lazily initialized; skip if
1517 * this member has not been allocated yet.
1518 */
1519 continue;
1520 }
1521
1522 ret = bt_ctf_field_reset(member);
1523 if (ret) {
1524 goto end;
1525 }
1526 }
1527end:
1528 return ret;
1529}
1530
1531static
1532int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1533{
1534 size_t i;
1535 int ret = 0;
1536 struct bt_ctf_field_sequence *sequence;
1537
1538 if (!field) {
1539 ret = -1;
1540 goto end;
1541 }
1542
1543 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1544 for (i = 0; i < sequence->elements->len; i++) {
1545 struct bt_ctf_field *member = sequence->elements->pdata[i];
1546
1547 if (!member) {
1548 /*
1549 * Sequence elements are lazily initialized; skip if
1550 * this member has not been allocated yet.
1551 */
1552 continue;
1553 }
1554
1555 ret = bt_ctf_field_reset(member);
1556 if (ret) {
1557 goto end;
1558 }
1559 }
1560end:
1561 return ret;
1562}
1563
1564static
1565int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1566{
1567 int ret = 0;
1568 struct bt_ctf_field_string *string;
1569
1570 if (!field) {
1571 ret = -1;
1572 goto end;
1573 }
1574
1575 ret = bt_ctf_field_generic_reset(field);
1576 if (ret) {
1577 goto end;
1578 }
1579
1580 string = container_of(field, struct bt_ctf_field_string, parent);
1581 if (string->payload) {
1582 g_string_truncate(string->payload, 0);
1583 }
1584end:
1585 return ret;
1586}
1587
273b65be
JG
1588static
1589int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1590 struct ctf_stream_pos *pos)
1591{
1592 int ret = 0;
1593 struct bt_ctf_field_integer *integer = container_of(field,
1594 struct bt_ctf_field_integer, parent);
1595
1596retry:
1597 ret = ctf_integer_write(&pos->parent, &integer->definition.p);
1598 if (ret == -EFAULT) {
1599 /*
1600 * The field is too large to fit in the current packet's
1601 * remaining space. Bump the packet size and retry.
1602 */
1603 ret = increase_packet_size(pos);
1604 if (ret) {
1605 goto end;
1606 }
1607 goto retry;
1608 }
1609end:
1610 return ret;
1611}
1612
1613static
1614int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1615 struct ctf_stream_pos *pos)
1616{
1617 struct bt_ctf_field_enumeration *enumeration = container_of(
1618 field, struct bt_ctf_field_enumeration, parent);
1619
1620 return bt_ctf_field_serialize(enumeration->payload, pos);
1621}
1622
1623static
1624int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1625 struct ctf_stream_pos *pos)
1626{
1627 int ret = 0;
1628 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1629 struct bt_ctf_field_floating_point, parent);
1630
1631retry:
1632 ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
1633 if (ret == -EFAULT) {
1634 /*
1635 * The field is too large to fit in the current packet's
1636 * remaining space. Bump the packet size and retry.
1637 */
1638 ret = increase_packet_size(pos);
1639 if (ret) {
1640 goto end;
1641 }
1642 goto retry;
1643 }
1644end:
1645 return ret;
1646}
1647
1648static
1649int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1650 struct ctf_stream_pos *pos)
1651{
1652 size_t i;
1653 int ret = 0;
1654 struct bt_ctf_field_structure *structure = container_of(
1655 field, struct bt_ctf_field_structure, parent);
1656
1657 while (!ctf_pos_access_ok(pos,
1658 offset_align(pos->offset,
1659 field->type->declaration->alignment))) {
9f56e450
JG
1660 ret = increase_packet_size(pos);
1661 if (ret) {
1662 goto end;
1663 }
273b65be
JG
1664 }
1665
70fd5a51
MD
1666 if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
1667 ret = -1;
1668 goto end;
1669 }
273b65be
JG
1670
1671 for (i = 0; i < structure->fields->len; i++) {
1672 struct bt_ctf_field *field = g_ptr_array_index(
1673 structure->fields, i);
1674
1675 ret = bt_ctf_field_serialize(field, pos);
1676 if (ret) {
1677 break;
1678 }
1679 }
9f56e450 1680end:
273b65be
JG
1681 return ret;
1682}
1683
1684static
1685int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
1686 struct ctf_stream_pos *pos)
1687{
1688 struct bt_ctf_field_variant *variant = container_of(
1689 field, struct bt_ctf_field_variant, parent);
1690
1691 return bt_ctf_field_serialize(variant->payload, pos);
1692}
1693
1694static
1695int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
1696 struct ctf_stream_pos *pos)
1697{
1698 size_t i;
1699 int ret = 0;
1700 struct bt_ctf_field_array *array = container_of(
1701 field, struct bt_ctf_field_array, parent);
1702
1703 for (i = 0; i < array->elements->len; i++) {
1704 ret = bt_ctf_field_serialize(
1705 g_ptr_array_index(array->elements, i), pos);
1706 if (ret) {
1707 goto end;
1708 }
1709 }
1710end:
1711 return ret;
1712}
1713
1714static
1715int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
1716 struct ctf_stream_pos *pos)
1717{
1718 size_t i;
1719 int ret = 0;
1720 struct bt_ctf_field_sequence *sequence = container_of(
1721 field, struct bt_ctf_field_sequence, parent);
1722
1723 for (i = 0; i < sequence->elements->len; i++) {
1724 ret = bt_ctf_field_serialize(
1725 g_ptr_array_index(sequence->elements, i), pos);
1726 if (ret) {
1727 goto end;
1728 }
1729 }
1730end:
1731 return ret;
1732}
1733
1734static
1735int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
1736 struct ctf_stream_pos *pos)
1737{
1738 size_t i;
1739 int ret = 0;
1740 struct bt_ctf_field_string *string = container_of(field,
1741 struct bt_ctf_field_string, parent);
1742 struct bt_ctf_field_type *character_type =
1743 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
1744 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
1745
1746 for (i = 0; i < string->payload->len + 1; i++) {
1747 ret = bt_ctf_field_unsigned_integer_set_value(character,
1748 (uint64_t) string->payload->str[i]);
1749 if (ret) {
1750 goto end;
1751 }
1752
1753 ret = bt_ctf_field_integer_serialize(character, pos);
1754 if (ret) {
1755 goto end;
1756 }
1757 }
1758end:
1759 bt_ctf_field_put(character);
1760 bt_ctf_field_type_put(character_type);
1761 return ret;
1762}
1763
87d43dc1
JG
1764static
1765int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
1766 struct bt_ctf_field *dst)
1767{
1768 struct bt_ctf_field_integer *integer_src, *integer_dst;
1769
1770 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
8bfa3f9c 1771 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
87d43dc1
JG
1772
1773 memcpy(&integer_dst->definition, &integer_src->definition,
1774 sizeof(struct definition_integer));
1775 return 0;
1776}
1777
1778static
1779int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
1780 struct bt_ctf_field *dst)
1781{
1782 int ret = 0;
1783 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
1784
1785 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
1786 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
1787
1788 if (enum_src->payload) {
1789 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
1790 if (!enum_dst->payload) {
1791 ret = -1;
1792 goto end;
1793 }
1794 }
1795end:
1796 return ret;
1797}
1798
1799static
1800int bt_ctf_field_floating_point_copy(
1801 struct bt_ctf_field *src, struct bt_ctf_field *dst)
1802{
1803 struct bt_ctf_field_floating_point *float_src, *float_dst;
1804
1805 float_src = container_of(src, struct bt_ctf_field_floating_point,
1806 parent);
1807 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
1808 parent);
1809
1810 memcpy(&float_dst->definition, &float_src->definition,
1811 sizeof(struct definition_float));
1812 memcpy(&float_dst->sign, &float_src->sign,
1813 sizeof(struct definition_integer));
1814 memcpy(&float_dst->mantissa, &float_src->mantissa,
1815 sizeof(struct definition_integer));
1816 memcpy(&float_dst->exp, &float_src->exp,
1817 sizeof(struct definition_integer));
1818 return 0;
1819}
1820
1821static
1822int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
1823 struct bt_ctf_field *dst)
1824{
8bfa3f9c 1825 int ret = 0, i;
87d43dc1
JG
1826 struct bt_ctf_field_structure *struct_src, *struct_dst;
1827
1828 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
1829 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
1830
8bfa3f9c 1831 /* This field_name_to_index HT is owned by the structure field type */
87d43dc1 1832 struct_dst->field_name_to_index = struct_src->field_name_to_index;
8bfa3f9c 1833 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
1834
1835 for (i = 0; i < struct_src->fields->len; i++) {
1836 struct bt_ctf_field *field_copy = bt_ctf_field_copy(
1837 g_ptr_array_index(struct_src->fields, i));
1838
1839 if (!field_copy) {
1840 ret = -1;
1841 goto end;
1842 }
8bfa3f9c 1843 g_ptr_array_index(struct_dst->fields, i) = field_copy;
87d43dc1
JG
1844 }
1845end:
1846 return ret;
1847}
1848
1849static
1850int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
1851 struct bt_ctf_field *dst)
1852{
1853 int ret = 0;
1854 struct bt_ctf_field_variant *variant_src, *variant_dst;
1855
1856 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
1857 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
1858
1859 if (variant_src->tag) {
1860 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
1861 if (!variant_dst->tag) {
1862 ret = -1;
1863 goto end;
1864 }
1865 }
1866 if (variant_src->payload) {
1867 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
1868 if (!variant_dst->payload) {
1869 ret = -1;
1870 goto end;
1871 }
1872 }
1873end:
1874 return ret;
1875}
1876
1877static
1878int bt_ctf_field_array_copy(struct bt_ctf_field *src,
1879 struct bt_ctf_field *dst)
1880{
1881 int ret = 0, i;
1882 struct bt_ctf_field_array *array_src, *array_dst;
1883
1884 array_src = container_of(src, struct bt_ctf_field_array, parent);
1885 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
1886
8bfa3f9c 1887 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1
JG
1888 for (i = 0; i < array_src->elements->len; i++) {
1889 struct bt_ctf_field *field_copy = bt_ctf_field_copy(
1890 g_ptr_array_index(array_src->elements, i));
1891
1892 if (!field_copy) {
1893 ret = -1;
1894 goto end;
1895 }
8bfa3f9c 1896 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1
JG
1897 }
1898end:
1899 return ret;
1900}
1901
1902static
1903int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
1904 struct bt_ctf_field *dst)
1905{
1906 int ret = 0, i;
1907 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
1908
1909 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
1910 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
1911
8bfa3f9c 1912 g_ptr_array_set_size(sequence_dst->elements,
87d43dc1
JG
1913 sequence_src->elements->len);
1914 for (i = 0; i < sequence_src->elements->len; i++) {
1915 struct bt_ctf_field *field_copy = bt_ctf_field_copy(
1916 g_ptr_array_index(sequence_src->elements, i));
1917
1918 if (!field_copy) {
1919 ret = -1;
1920 goto end;
1921 }
8bfa3f9c 1922 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1
JG
1923 }
1924end:
1925 return ret;
1926}
1927
1928static
1929int bt_ctf_field_string_copy(struct bt_ctf_field *src,
1930 struct bt_ctf_field *dst)
1931{
1932 int ret = 0;
1933 struct bt_ctf_field_string *string_src, *string_dst;
1934
1935 string_src = container_of(src, struct bt_ctf_field_string, parent);
1936 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
1937
1938 if (string_src->payload) {
1939 string_dst->payload = g_string_new(string_src->payload->str);
1940 if (!string_dst->payload) {
1941 ret = -1;
1942 goto end;
1943 }
1944 }
1945end:
1946 return ret;
1947}
1948
273b65be
JG
1949static
1950int increase_packet_size(struct ctf_stream_pos *pos)
1951{
1952 int ret;
1953
1954 assert(pos);
1955 ret = munmap_align(pos->base_mma);
1956 if (ret) {
1957 goto end;
1958 }
1959
1960 pos->packet_size += PACKET_LEN_INCREMENT;
1961 ret = posix_fallocate(pos->fd, pos->mmap_offset,
1962 pos->packet_size / CHAR_BIT);
1963 if (ret) {
1964 goto end;
1965 }
1966
1967 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
1968 pos->flags, pos->fd, pos->mmap_offset);
1969 if (pos->base_mma == MAP_FAILED) {
1970 ret = -1;
1971 }
1972end:
1973 return ret;
1974}
This page took 0.102935 seconds and 4 git commands to generate.