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