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