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