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