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