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