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