Python test: remove useless test
[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
fc25abce
PP
29#define BT_LOG_TAG "FIELDS"
30#include <babeltrace/lib-logging-internal.h>
31
2e33ac5a
PP
32#include <babeltrace/ctf-ir/fields-internal.h>
33#include <babeltrace/ctf-ir/field-types-internal.h>
dc3fffef 34#include <babeltrace/ctf-writer/serialize-internal.h>
83509119
JG
35#include <babeltrace/object-internal.h>
36#include <babeltrace/ref.h>
3d9990ac
PP
37#include <babeltrace/compiler-internal.h>
38#include <babeltrace/compat/fcntl-internal.h>
39#include <babeltrace/align-internal.h>
fc25abce 40#include <inttypes.h>
273b65be 41
273b65be
JG
42static
43struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
44static
45struct bt_ctf_field *bt_ctf_field_enumeration_create(
46 struct bt_ctf_field_type *);
47static
48struct bt_ctf_field *bt_ctf_field_floating_point_create(
49 struct bt_ctf_field_type *);
50static
51struct bt_ctf_field *bt_ctf_field_structure_create(
52 struct bt_ctf_field_type *);
53static
54struct bt_ctf_field *bt_ctf_field_variant_create(
55 struct bt_ctf_field_type *);
56static
57struct bt_ctf_field *bt_ctf_field_array_create(
58 struct bt_ctf_field_type *);
59static
60struct bt_ctf_field *bt_ctf_field_sequence_create(
61 struct bt_ctf_field_type *);
62static
63struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
64
65static
83509119 66void bt_ctf_field_destroy(struct bt_object *);
273b65be
JG
67static
68void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
69static
70void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
71static
72void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
73static
74void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
75static
76void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
77static
78void bt_ctf_field_array_destroy(struct bt_ctf_field *);
79static
80void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
81static
82void bt_ctf_field_string_destroy(struct bt_ctf_field *);
83
84static
ca116246 85int bt_ctf_field_generic_validate(struct bt_ctf_field *);
273b65be 86static
ca116246 87int bt_ctf_field_structure_validate(struct bt_ctf_field *);
273b65be 88static
ca116246 89int bt_ctf_field_variant_validate(struct bt_ctf_field *);
273b65be 90static
ca116246 91int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
273b65be 92static
ca116246 93int bt_ctf_field_array_validate(struct bt_ctf_field *);
273b65be 94static
ca116246 95int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
273b65be 96
12c8a1a3 97static
ca116246 98int bt_ctf_field_generic_reset(struct bt_ctf_field *);
12c8a1a3 99static
ca116246 100int bt_ctf_field_structure_reset(struct bt_ctf_field *);
12c8a1a3 101static
ca116246 102int bt_ctf_field_variant_reset(struct bt_ctf_field *);
12c8a1a3 103static
ca116246 104int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
12c8a1a3 105static
ca116246 106int bt_ctf_field_array_reset(struct bt_ctf_field *);
12c8a1a3 107static
ca116246 108int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
12c8a1a3 109static
ca116246 110int bt_ctf_field_string_reset(struct bt_ctf_field *);
12c8a1a3 111
273b65be
JG
112static
113int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
dc3fffef 114 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
115static
116int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
dc3fffef 117 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
118static
119int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
dc3fffef 120 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
121static
122int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
dc3fffef 123 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
124static
125int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
dc3fffef 126 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
127static
128int bt_ctf_field_array_serialize(struct bt_ctf_field *,
dc3fffef 129 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
130static
131int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
dc3fffef 132 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be
JG
133static
134int bt_ctf_field_string_serialize(struct bt_ctf_field *,
dc3fffef 135 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
273b65be 136
87d43dc1
JG
137static
138int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
139static
140int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
141static
142int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
143 struct bt_ctf_field *);
144static
145int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
146static
147int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
148static
149int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
150static
151int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
152static
153int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
154
918be005
PP
155static
156void generic_field_freeze(struct bt_ctf_field *);
157static
158void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
159static
160void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
161static
162void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
163static
164void bt_ctf_field_array_freeze(struct bt_ctf_field *);
165static
166void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
167
76f869ab 168static
c55a9f58 169bt_bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
76f869ab 170static
c55a9f58 171bt_bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
76f869ab 172static
c55a9f58 173bt_bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
76f869ab 174static
c55a9f58 175bt_bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
76f869ab 176static
c55a9f58 177bt_bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
76f869ab 178static
c55a9f58 179bt_bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
76f869ab 180
273b65be 181static
dc3fffef 182int increase_packet_size(struct bt_ctf_stream_pos *pos);
273b65be
JG
183
184static
ce6da4fd 185struct bt_ctf_field *(* const field_create_funcs[])(
273b65be 186 struct bt_ctf_field_type *) = {
1487a16a
PP
187 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
188 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
189 [BT_CTF_FIELD_TYPE_ID_FLOAT] =
273b65be 190 bt_ctf_field_floating_point_create,
1487a16a
PP
191 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
192 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
193 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
194 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
195 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_create,
273b65be
JG
196};
197
198static
ce6da4fd 199void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
1487a16a
PP
200 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_destroy,
201 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_destroy,
202 [BT_CTF_FIELD_TYPE_ID_FLOAT] =
273b65be 203 bt_ctf_field_floating_point_destroy,
1487a16a
PP
204 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_destroy,
205 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_destroy,
206 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_destroy,
207 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_destroy,
208 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_destroy,
273b65be
JG
209};
210
211static
ce6da4fd 212int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
1487a16a
PP
213 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_generic_validate,
214 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_validate,
215 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_generic_validate,
216 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_validate,
217 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_validate,
218 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_validate,
219 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_validate,
220 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_generic_validate,
273b65be
JG
221};
222
12c8a1a3 223static
ce6da4fd 224int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
1487a16a
PP
225 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_generic_reset,
226 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_reset,
227 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_generic_reset,
228 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_reset,
229 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_reset,
230 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_reset,
231 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_reset,
232 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_reset,
12c8a1a3
JG
233};
234
273b65be 235static
ce6da4fd 236int (* const field_serialize_funcs[])(struct bt_ctf_field *,
dc3fffef 237 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order) = {
1487a16a
PP
238 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_serialize,
239 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_serialize,
240 [BT_CTF_FIELD_TYPE_ID_FLOAT] =
273b65be 241 bt_ctf_field_floating_point_serialize,
1487a16a
PP
242 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_serialize,
243 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_serialize,
244 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_serialize,
245 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_serialize,
246 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_serialize,
273b65be
JG
247};
248
87d43dc1 249static
ce6da4fd
JG
250int (* const field_copy_funcs[])(struct bt_ctf_field *,
251 struct bt_ctf_field *) = {
1487a16a
PP
252 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_copy,
253 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_copy,
254 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_copy,
255 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_copy,
256 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_copy,
257 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_copy,
258 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_copy,
259 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_copy,
87d43dc1
JG
260};
261
918be005
PP
262static
263void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
1487a16a
PP
264 [BT_CTF_FIELD_TYPE_ID_INTEGER] = generic_field_freeze,
265 [BT_CTF_FIELD_TYPE_ID_FLOAT] = generic_field_freeze,
266 [BT_CTF_FIELD_TYPE_ID_STRING] = generic_field_freeze,
267 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
268 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
269 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
270 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
271 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
918be005
PP
272};
273
76f869ab 274static
c55a9f58 275bt_bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
1487a16a
PP
276 [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_generic_is_set,
277 [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_is_set,
278 [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_generic_is_set,
279 [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_is_set,
280 [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_is_set,
281 [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_is_set,
282 [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_is_set,
283 [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_generic_is_set,
76f869ab
JG
284};
285
273b65be
JG
286struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
287{
288 struct bt_ctf_field *field = NULL;
1487a16a 289 enum bt_ctf_field_type_id type_id;
81e36fac 290 int ret;
273b65be
JG
291
292 if (!type) {
fc25abce 293 BT_LOGW_STR("Invalid parameter: field type is NULL.");
273b65be
JG
294 goto error;
295 }
296
297 type_id = bt_ctf_field_type_get_type_id(type);
1487a16a 298 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN ||
9a19a512 299 type_id >= BT_CTF_NR_TYPE_IDS) {
fc25abce
PP
300 BT_LOGW("Invalid parameter: unknown field type ID: "
301 "ft-addr=%p, ft-id=%d", type, type_id);
81e36fac
PP
302 goto error;
303 }
304
305 /* Field class MUST be valid */
306 ret = bt_ctf_field_type_validate(type);
81e36fac
PP
307 if (ret) {
308 /* Invalid */
fc25abce
PP
309 BT_LOGW("Invalid parameter: field type is invalid: "
310 "ft-addr=%p", type);
273b65be
JG
311 goto error;
312 }
313
314 field = field_create_funcs[type_id](type);
315 if (!field) {
316 goto error;
317 }
318
319 /* The type's declaration can't change after this point */
320 bt_ctf_field_type_freeze(type);
83509119
JG
321 bt_get(type);
322 bt_object_init(field, bt_ctf_field_destroy);
273b65be
JG
323 field->type = type;
324error:
325 return field;
326}
327
fc25abce 328/* Pre-2.0 CTF writer backward compatibility */
273b65be
JG
329void bt_ctf_field_get(struct bt_ctf_field *field)
330{
83509119 331 bt_get(field);
273b65be
JG
332}
333
fc25abce 334/* Pre-2.0 CTF writer backward compatibility */
273b65be
JG
335void bt_ctf_field_put(struct bt_ctf_field *field)
336{
83509119 337 bt_put(field);
273b65be
JG
338}
339
cd95e351
JG
340struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
341{
342 struct bt_ctf_field_type *ret = NULL;
343
344 if (!field) {
fc25abce 345 BT_LOGW_STR("Invalid parameter: field is NULL.");
cd95e351
JG
346 goto end;
347 }
348
349 ret = field->type;
83509119 350 bt_get(ret);
cd95e351
JG
351end:
352 return ret;
353}
354
1487a16a 355enum bt_ctf_field_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
4ebcc695 356{
1487a16a 357 enum bt_ctf_field_type_id ret = BT_CTF_FIELD_TYPE_ID_UNKNOWN;
4ebcc695
PP
358
359 if (!field) {
fc25abce 360 BT_LOGW_STR("Invalid parameter: field is NULL.");
4ebcc695
PP
361 goto end;
362 }
363
364 ret = bt_ctf_field_type_get_type_id(field->type);
365end:
366 return ret;
367}
368
c14d64fa 369bt_bool bt_ctf_field_is_integer(struct bt_ctf_field *field)
8f3553be 370{
1487a16a 371 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_INTEGER;
8f3553be
PP
372}
373
c14d64fa 374bt_bool bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
8f3553be 375{
1487a16a 376 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_FLOAT;
8f3553be
PP
377}
378
c14d64fa 379bt_bool bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
8f3553be 380{
1487a16a 381 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_ENUM;
8f3553be
PP
382}
383
c14d64fa 384bt_bool bt_ctf_field_is_string(struct bt_ctf_field *field)
8f3553be 385{
1487a16a 386 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_STRING;
8f3553be
PP
387}
388
c14d64fa 389bt_bool bt_ctf_field_is_structure(struct bt_ctf_field *field)
8f3553be 390{
1487a16a 391 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_STRUCT;
8f3553be
PP
392}
393
c14d64fa 394bt_bool bt_ctf_field_is_array(struct bt_ctf_field *field)
8f3553be 395{
1487a16a 396 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_ARRAY;
8f3553be
PP
397}
398
c14d64fa 399bt_bool bt_ctf_field_is_sequence(struct bt_ctf_field *field)
8f3553be 400{
1487a16a 401 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_SEQUENCE;
8f3553be
PP
402}
403
c14d64fa 404bt_bool bt_ctf_field_is_variant(struct bt_ctf_field *field)
8f3553be 405{
1487a16a 406 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_VARIANT;
8f3553be
PP
407}
408
cd95e351
JG
409struct bt_ctf_field *bt_ctf_field_sequence_get_length(
410 struct bt_ctf_field *field)
411{
412 struct bt_ctf_field *ret = NULL;
413 struct bt_ctf_field_sequence *sequence;
414
415 if (!field) {
fc25abce 416 BT_LOGW_STR("Invalid parameter: field is NULL.");
cd95e351
JG
417 goto end;
418 }
419
420 if (bt_ctf_field_type_get_type_id(field->type) !=
fc25abce
PP
421 BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
422 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
423 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
424 field->type,
425 bt_ctf_field_type_id_string(field->type->id));
cd95e351
JG
426 goto end;
427 }
428
429 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
430 ret = sequence->length;
83509119 431 bt_get(ret);
cd95e351
JG
432end:
433 return ret;
434}
435
273b65be
JG
436int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
437 struct bt_ctf_field *length_field)
438{
439 int ret = 0;
440 struct bt_ctf_field_type_integer *length_type;
441 struct bt_ctf_field_integer *length;
442 struct bt_ctf_field_sequence *sequence;
443 uint64_t sequence_length;
444
fc25abce
PP
445 if (!field) {
446 BT_LOGW_STR("Invalid parameter: field is NULL.");
447 ret = -1;
448 goto end;
449 }
450
451 if (!length_field) {
452 BT_LOGW_STR("Invalid parameter: length field is NULL.");
453 ret = -1;
454 goto end;
455 }
456
457 if (field->frozen) {
458 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
459 field);
273b65be
JG
460 ret = -1;
461 goto end;
462 }
fc25abce 463
273b65be 464 if (bt_ctf_field_type_get_type_id(length_field->type) !=
fc25abce
PP
465 BT_CTF_FIELD_TYPE_ID_INTEGER) {
466 BT_LOGW("Invalid parameter: length field's type is not an integer field type: "
467 "field-addr=%p, length-field-addr=%p, length-ft-addr=%p, length-ft-id=%s",
468 field, length_field, length_field->type,
469 bt_ctf_field_type_id_string(length_field->type->id));
273b65be
JG
470 ret = -1;
471 goto end;
472 }
473
474 length_type = container_of(length_field->type,
475 struct bt_ctf_field_type_integer, parent);
152e7331 476 /* The length field must be unsigned */
dc3fffef 477 if (length_type->is_signed) {
fc25abce
PP
478 BT_LOGW("Invalid parameter: length field's type is signed: "
479 "field-addr=%p, length-field-addr=%p, "
480 "length-field-ft-addr=%p", field, length_field,
481 length_field->type);
273b65be
JG
482 ret = -1;
483 goto end;
484 }
485
486 length = container_of(length_field, struct bt_ctf_field_integer,
487 parent);
dc3fffef 488 sequence_length = length->payload.unsignd;
273b65be
JG
489 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
490 if (sequence->elements) {
491 g_ptr_array_free(sequence->elements, TRUE);
83509119 492 bt_put(sequence->length);
273b65be
JG
493 }
494
fe0fe95c 495 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
273b65be 496 if (!sequence->elements) {
fc25abce 497 BT_LOGE_STR("Failed to allocate a GPtrArray.");
273b65be
JG
498 ret = -1;
499 goto end;
500 }
501
fe0fe95c 502 g_ptr_array_set_free_func(sequence->elements,
83509119
JG
503 (GDestroyNotify) bt_put);
504 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
505 bt_get(length_field);
273b65be
JG
506 sequence->length = length_field;
507end:
508 return ret;
509}
510
9ac68eb1 511struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
273b65be
JG
512 struct bt_ctf_field *field, const char *name)
513{
514 struct bt_ctf_field *new_field = NULL;
515 GQuark field_quark;
516 struct bt_ctf_field_structure *structure;
b92ddaaa 517 struct bt_ctf_field_type *field_type = NULL;
273b65be
JG
518 size_t index;
519
fc25abce
PP
520 if (!field) {
521 BT_LOGW_STR("Invalid parameter: field is NULL.");
522 goto error;
523 }
524
525 if (!name) {
526 BT_LOGW_STR("Invalid parameter: field name is NULL.");
527 goto error;
528 }
529
530 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 531 BT_CTF_FIELD_TYPE_ID_STRUCT) {
fc25abce
PP
532 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
533 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
534 field->type,
535 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
536 goto error;
537 }
538
539 field_quark = g_quark_from_string(name);
540 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
541 field_type =
542 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
543 name);
273b65be 544 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
fc25abce
PP
545 GUINT_TO_POINTER(field_quark),
546 NULL, (gpointer *)&index)) {
6fa8d37b 547 BT_LOGV("Invalid parameter: no such field in structure field's type: "
fc25abce
PP
548 "struct-field-addr=%p, struct-ft-addr=%p, "
549 "field-ft-addr=%p, name=\"%s\"",
550 field, field->type, field_type, name);
273b65be
JG
551 goto error;
552 }
553
554 if (structure->fields->pdata[index]) {
555 new_field = structure->fields->pdata[index];
556 goto end;
557 }
558
918be005
PP
559 /* We don't want to modify this field if it's frozen */
560 if (field->frozen) {
e67720a9
PP
561 /*
562 * Not logging a warning here because the user could
563 * legitimately check if a structure field is set with
564 * this function: if the preconditions are satisfied,
565 * a NULL return value means this.
566 */
567 BT_LOGV("Not creating a field because structure field is frozen: "
568 "struct-field-addr=%p, name=\"%s\"", field, name);
918be005
PP
569 goto end;
570 }
571
273b65be
JG
572 new_field = bt_ctf_field_create(field_type);
573 if (!new_field) {
fc25abce
PP
574 BT_LOGW("Cannot create field: "
575 "struct-field-addr=%p, struct-ft-addr=%p, "
576 "field-ft-addr=%p, name=\"%s\"",
577 field, field->type, field_type, name);
273b65be
JG
578 goto error;
579 }
580
581 structure->fields->pdata[index] = new_field;
582end:
83509119 583 bt_get(new_field);
273b65be 584error:
b92ddaaa 585 if (field_type) {
83509119 586 bt_put(field_type);
b92ddaaa 587 }
273b65be
JG
588 return new_field;
589}
590
cd95e351 591struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
9ac68eb1 592 struct bt_ctf_field *field, uint64_t index)
cd95e351
JG
593{
594 int ret;
595 const char *field_name;
596 struct bt_ctf_field_structure *structure;
597 struct bt_ctf_field_type *structure_type;
598 struct bt_ctf_field_type *field_type = NULL;
599 struct bt_ctf_field *ret_field = NULL;
600
fc25abce
PP
601 if (!field) {
602 BT_LOGW_STR("Invalid parameter: field is NULL.");
603 goto end;
604 }
605
606 if (bt_ctf_field_type_get_type_id(field->type) !=
607 BT_CTF_FIELD_TYPE_ID_STRUCT) {
608 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
609 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
610 field->type,
611 bt_ctf_field_type_id_string(field->type->id));
cd95e351
JG
612 goto end;
613 }
614
615 structure = container_of(field, struct bt_ctf_field_structure, parent);
616 if (index >= structure->fields->len) {
fc25abce
PP
617 BT_LOGW("Invalid parameter: index is out of bounds: "
618 "addr=%p, index=%" PRIu64 ", count=%u",
619 field, index, structure->fields->len);
cd95e351
JG
620 goto error;
621 }
622
623 ret_field = structure->fields->pdata[index];
624 if (ret_field) {
625 goto end;
626 }
627
918be005
PP
628 /* We don't want to modify this field if it's frozen */
629 if (field->frozen) {
e67720a9
PP
630 /*
631 * Not logging a warning here because the user could
632 * legitimately check if a structure field is set with
633 * this function: if the preconditions are satisfied,
634 * a NULL return value means this.
635 */
636 BT_LOGV("Not creating a field because structure field is frozen: "
637 "struct-field-addr=%p, index=%" PRIu64, field, index);
918be005
PP
638 goto end;
639 }
640
cd95e351
JG
641 /* Field has not been instanciated yet, create it */
642 structure_type = bt_ctf_field_get_type(field);
fc25abce 643 assert(structure_type);
cd95e351
JG
644 ret = bt_ctf_field_type_structure_get_field(structure_type,
645 &field_name, &field_type, index);
fc25abce 646 assert(ret == 0);
83509119 647 bt_put(structure_type);
cd95e351
JG
648 ret_field = bt_ctf_field_create(field_type);
649 if (!ret_field) {
fc25abce
PP
650 BT_LOGW("Cannot create field: "
651 "struct-field-addr=%p, struct-ft-addr=%p, "
652 "field-ft-addr=%p, index=%" PRIu64,
653 field, field->type, field_type, index);
cd95e351
JG
654 goto error;
655 }
656
657 structure->fields->pdata[index] = ret_field;
658end:
83509119 659 bt_get(ret_field);
cd95e351 660error:
83509119 661 bt_put(field_type);
cd95e351
JG
662 return ret_field;
663}
664
2225de6b 665int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *field,
273b65be
JG
666 const char *name, struct bt_ctf_field *value)
667{
668 int ret = 0;
669 GQuark field_quark;
670 struct bt_ctf_field_structure *structure;
b92ddaaa 671 struct bt_ctf_field_type *expected_field_type = NULL;
273b65be
JG
672 size_t index;
673
fc25abce
PP
674 if (!field) {
675 BT_LOGW_STR("Invalid parameter: structure field is NULL.");
676 ret = -1;
677 goto end;
678 }
679
680 if (!name) {
681 BT_LOGW_STR("Invalid parameter: field name is NULL.");
682 ret = -1;
683 goto end;
684 }
685
686 if (!value) {
687 BT_LOGW_STR("Invalid parameter: field is NULL.");
688 ret = -1;
689 goto end;
690 }
691
692 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 693 BT_CTF_FIELD_TYPE_ID_STRUCT) {
fc25abce
PP
694 BT_LOGW("Invalid parameter: field's type is not a structure field type: "
695 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
696 field->type,
697 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
698 ret = -1;
699 goto end;
700 }
701
702 field_quark = g_quark_from_string(name);
703 structure = container_of(field, struct bt_ctf_field_structure, parent);
b92ddaaa
JG
704 expected_field_type =
705 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
706 name);
09840de5
PP
707
708 if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
fc25abce
PP
709 BT_LOGW("Invalid parameter: field type of field to set is different from the expected field type: "
710 "struct-field-addr=%p, field-addr=%p, "
711 "field-ft-addr=%p, expected-ft-addr=%p",
712 field, value, value->type, expected_field_type);
273b65be
JG
713 ret = -1;
714 goto end;
715 }
716
717 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
fc25abce 718 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
6fa8d37b 719 BT_LOGV("Invalid parameter: no such field in structure field's type: "
fc25abce
PP
720 "struct-field-addr=%p, struct-ft-addr=%p, "
721 "field-ft-addr=%p, name=\"%s\"",
722 field, field->type, value->type, name);
723 ret = -1;
273b65be
JG
724 goto end;
725 }
726
727 if (structure->fields->pdata[index]) {
83509119 728 bt_put(structure->fields->pdata[index]);
273b65be
JG
729 }
730
731 structure->fields->pdata[index] = value;
83509119 732 bt_get(value);
273b65be 733end:
b92ddaaa 734 if (expected_field_type) {
83509119 735 bt_put(expected_field_type);
b92ddaaa 736 }
273b65be
JG
737 return ret;
738}
739
740struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
741 uint64_t index)
742{
743 struct bt_ctf_field *new_field = NULL;
b92ddaaa 744 struct bt_ctf_field_type *field_type = NULL;
273b65be 745 struct bt_ctf_field_array *array;
273b65be 746
fc25abce
PP
747 if (!field) {
748 BT_LOGW_STR("Invalid parameter: field is NULL.");
749 goto end;
750 }
751
752 if (bt_ctf_field_type_get_type_id(field->type) !=
753 BT_CTF_FIELD_TYPE_ID_ARRAY) {
754 BT_LOGW("Invalid parameter: field's type is not an array field type: "
755 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
756 field->type,
757 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
758 goto end;
759 }
760
761 array = container_of(field, struct bt_ctf_field_array, parent);
762 if (index >= array->elements->len) {
fc25abce
PP
763 BT_LOGW("Invalid parameter: index is out of bounds: "
764 "addr=%p, index=%" PRIu64 ", count=%u",
765 field, index, array->elements->len);
273b65be
JG
766 goto end;
767 }
768
b92ddaaa 769 field_type = bt_ctf_field_type_array_get_element_type(field->type);
273b65be
JG
770 if (array->elements->pdata[(size_t)index]) {
771 new_field = array->elements->pdata[(size_t)index];
772 goto end;
773 }
774
918be005
PP
775 /* We don't want to modify this field if it's frozen */
776 if (field->frozen) {
e67720a9
PP
777 /*
778 * Not logging a warning here because the user could
779 * legitimately check if a array field is set with
780 * this function: if the preconditions are satisfied,
781 * a NULL return value means this.
782 */
783 BT_LOGV("Not creating a field because array field is frozen: "
784 "array-field-addr=%p, index=%" PRIu64, field, index);
918be005
PP
785 goto end;
786 }
787
273b65be 788 new_field = bt_ctf_field_create(field_type);
273b65be
JG
789 array->elements->pdata[(size_t)index] = new_field;
790end:
b92ddaaa 791 if (field_type) {
83509119 792 bt_put(field_type);
b92ddaaa 793 }
92c8b4f9 794 if (new_field) {
83509119 795 bt_get(new_field);
92c8b4f9 796 }
273b65be
JG
797 return new_field;
798}
799
800struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
801 uint64_t index)
802{
803 struct bt_ctf_field *new_field = NULL;
b92ddaaa 804 struct bt_ctf_field_type *field_type = NULL;
273b65be 805 struct bt_ctf_field_sequence *sequence;
273b65be 806
fc25abce
PP
807 if (!field) {
808 BT_LOGW_STR("Invalid parameter: field is NULL.");
809 goto end;
810 }
811
812 if (bt_ctf_field_type_get_type_id(field->type) !=
813 BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
814 BT_LOGW("Invalid parameter: field's type is not a sequence field type: "
815 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
816 field->type,
817 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
818 goto end;
819 }
820
821 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
fc25abce 822 if (!sequence->elements) {
6fa8d37b 823 BT_LOGV("Sequence field's elements do not exist: addr=%p",
fc25abce
PP
824 field);
825 goto end;
826 }
827
828 if (index >= sequence->elements->len) {
829 BT_LOGW("Invalid parameter: index is out of bounds: "
830 "addr=%p, index=%" PRIu64 ", count=%u",
831 field, index, sequence->elements->len);
273b65be
JG
832 goto end;
833 }
834
b92ddaaa 835 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
83509119
JG
836 if (sequence->elements->pdata[(size_t) index]) {
837 new_field = sequence->elements->pdata[(size_t) index];
273b65be
JG
838 goto end;
839 }
840
918be005
PP
841 /* We don't want to modify this field if it's frozen */
842 if (field->frozen) {
e67720a9
PP
843 /*
844 * Not logging a warning here because the user could
845 * legitimately check if a sequence field is set with
846 * this function: if the preconditions are satisfied,
847 * a NULL return value means this.
848 */
849 BT_LOGV("Not creating a field because sequence field is frozen: "
850 "sequence-field-addr=%p, index=%" PRIu64, field, index);
918be005
PP
851 goto end;
852 }
853
273b65be 854 new_field = bt_ctf_field_create(field_type);
83509119 855 sequence->elements->pdata[(size_t) index] = new_field;
273b65be 856end:
b92ddaaa 857 if (field_type) {
83509119 858 bt_put(field_type);
b92ddaaa 859 }
92c8b4f9 860 if (new_field) {
83509119 861 bt_get(new_field);
92c8b4f9 862 }
273b65be
JG
863 return new_field;
864}
865
866struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
867 struct bt_ctf_field *tag_field)
868{
869 struct bt_ctf_field *new_field = NULL;
870 struct bt_ctf_field_variant *variant;
871 struct bt_ctf_field_type_variant *variant_type;
872 struct bt_ctf_field_type *field_type;
873 struct bt_ctf_field *tag_enum = NULL;
874 struct bt_ctf_field_integer *tag_enum_integer;
875 int64_t tag_enum_value;
876
fc25abce
PP
877 if (!field) {
878 BT_LOGW_STR("Invalid parameter: field is NULL.");
879 goto end;
880 }
881
882 if (!tag_field) {
883 BT_LOGW_STR("Invalid parameter: tag field is NULL.");
884 goto end;
885 }
886
887 if (bt_ctf_field_type_get_type_id(field->type) !=
888 BT_CTF_FIELD_TYPE_ID_VARIANT) {
889 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
890 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
891 field->type,
892 bt_ctf_field_type_id_string(field->type->id));
893 goto end;
894 }
895
896 if (bt_ctf_field_type_get_type_id(tag_field->type) !=
1487a16a 897 BT_CTF_FIELD_TYPE_ID_ENUM) {
fc25abce
PP
898 BT_LOGW("Invalid parameter: tag field's type is not an enumeration field type: "
899 "field-addr=%p, ft-addr=%p, ft-id=%s", tag_field,
900 tag_field->type,
901 bt_ctf_field_type_id_string(tag_field->type->id));
273b65be
JG
902 goto end;
903 }
904
905 variant = container_of(field, struct bt_ctf_field_variant, parent);
906 variant_type = container_of(field->type,
907 struct bt_ctf_field_type_variant, parent);
908 tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
909 if (!tag_enum) {
910 goto end;
911 }
912
913 tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
914 parent);
915
2c661a4d 916 if (bt_ctf_field_validate(tag_field) < 0) {
fc25abce
PP
917 BT_LOGW("Invalid parameter: tag field is invalid: "
918 "variant-field-addr=%p, tag-field-addr=%p",
919 field, tag_field);
273b65be
JG
920 goto end;
921 }
922
dc3fffef 923 tag_enum_value = tag_enum_integer->payload.signd;
2829190c
PP
924
925 /*
926 * If the variant currently has a tag and a payload, and if the
927 * requested tag value is the same as the current one, return
928 * the current payload instead of creating a fresh one.
929 */
930 if (variant->tag && variant->payload) {
931 struct bt_ctf_field *cur_tag_container = NULL;
932 struct bt_ctf_field_integer *cur_tag_enum_integer;
933 int64_t cur_tag_value;
934
935 cur_tag_container =
936 bt_ctf_field_enumeration_get_container(variant->tag);
9a5df386 937 assert(cur_tag_container);
2829190c
PP
938 cur_tag_enum_integer = container_of(cur_tag_container,
939 struct bt_ctf_field_integer, parent);
83509119 940 bt_put(cur_tag_container);
dc3fffef 941 cur_tag_value = cur_tag_enum_integer->payload.signd;
2829190c
PP
942
943 if (cur_tag_value == tag_enum_value) {
944 new_field = variant->payload;
83509119 945 bt_get(new_field);
2829190c
PP
946 goto end;
947 }
948 }
949
918be005
PP
950 /* We don't want to modify this field if it's frozen */
951 if (field->frozen) {
e67720a9
PP
952 /*
953 * Not logging a warning here because the user could
954 * legitimately check if a variant field is set with
955 * this function: if the preconditions are satisfied,
956 * a NULL return value means this.
957 */
958 BT_LOGV("Not creating a field because variant field is frozen: "
959 "variant-field-addr=%p, tag-field-addr=%p",
960 field, tag_field);
918be005
PP
961 goto end;
962 }
963
b92ddaaa
JG
964 field_type = bt_ctf_field_type_variant_get_field_type_signed(
965 variant_type, tag_enum_value);
273b65be 966 if (!field_type) {
fc25abce
PP
967 BT_LOGW("Cannot get variant field type's field: "
968 "variant-field-addr=%p, variant-ft-addr=%p, "
969 "tag-value-signed=%" PRId64,
970 field, variant_type, tag_enum_value);
273b65be
JG
971 goto end;
972 }
973
974 new_field = bt_ctf_field_create(field_type);
975 if (!new_field) {
fc25abce
PP
976 BT_LOGW("Cannot create field: "
977 "variant-field-addr=%p, variant-ft-addr=%p, "
978 "field-ft-addr=%p", field, field->type, field_type);
273b65be
JG
979 goto end;
980 }
981
83509119
JG
982 bt_put(variant->tag);
983 bt_put(variant->payload);
984 bt_get(new_field);
985 bt_get(tag_field);
273b65be
JG
986 variant->tag = tag_field;
987 variant->payload = new_field;
988end:
83509119 989 bt_put(tag_enum);
273b65be
JG
990 return new_field;
991}
992
3f4a108d
PP
993struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
994 struct bt_ctf_field *variant_field)
995{
996 struct bt_ctf_field *current_field = NULL;
997 struct bt_ctf_field_variant *variant;
998
fc25abce
PP
999 if (!variant_field) {
1000 BT_LOGW_STR("Invalid parameter: field is NULL.");
1001 goto end;
1002 }
1003
1004 if (bt_ctf_field_type_get_type_id(variant_field->type) !=
1487a16a 1005 BT_CTF_FIELD_TYPE_ID_VARIANT) {
fc25abce
PP
1006 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
1007 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field,
1008 variant_field->type,
1009 bt_ctf_field_type_id_string(variant_field->type->id));
3f4a108d
PP
1010 goto end;
1011 }
1012
1013 variant = container_of(variant_field, struct bt_ctf_field_variant,
1014 parent);
1015
1016 if (variant->payload) {
1017 current_field = variant->payload;
83509119 1018 bt_get(current_field);
3f4a108d
PP
1019 goto end;
1020 }
1021
1022end:
1023 return current_field;
1024}
1025
f78d67fb
JG
1026struct bt_ctf_field *bt_ctf_field_variant_get_tag(
1027 struct bt_ctf_field *variant_field)
1028{
1029 struct bt_ctf_field *tag = NULL;
1030 struct bt_ctf_field_variant *variant;
1031
fc25abce
PP
1032 if (!variant_field) {
1033 BT_LOGW_STR("Invalid parameter: field is NULL.");
1034 goto end;
1035 }
1036
1037 if (bt_ctf_field_type_get_type_id(variant_field->type) !=
1487a16a 1038 BT_CTF_FIELD_TYPE_ID_VARIANT) {
fc25abce
PP
1039 BT_LOGW("Invalid parameter: field's type is not a variant field type: "
1040 "field-addr=%p, ft-addr=%p, ft-id=%s", variant_field,
1041 variant_field->type,
1042 bt_ctf_field_type_id_string(variant_field->type->id));
f78d67fb
JG
1043 goto end;
1044 }
1045
1046 variant = container_of(variant_field, struct bt_ctf_field_variant,
1047 parent);
1048 if (variant->tag) {
1049 tag = bt_get(variant->tag);
1050 }
1051end:
1052 return tag;
1053}
1054
273b65be
JG
1055struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
1056 struct bt_ctf_field *field)
1057{
1058 struct bt_ctf_field *container = NULL;
1059 struct bt_ctf_field_enumeration *enumeration;
1060
fc25abce
PP
1061 if (!field) {
1062 BT_LOGW_STR("Invalid parameter: field is NULL.");
1063 goto end;
1064 }
1065
1066 if (bt_ctf_field_type_get_type_id(field->type) !=
1067 BT_CTF_FIELD_TYPE_ID_ENUM) {
1068 BT_LOGW("Invalid parameter: field's type is not an enumeration field type: "
1069 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1070 field->type,
1071 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
1072 goto end;
1073 }
1074
1075 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1076 parent);
1077 if (!enumeration->payload) {
918be005
PP
1078 /* We don't want to modify this field if it's frozen */
1079 if (field->frozen) {
e67720a9
PP
1080 /*
1081 * Not logging a warning here because the user
1082 * could legitimately check if an enumeration's
1083 * container field is set with this function: if
1084 * the preconditions are satisfied, a NULL
1085 * return value means this.
1086 */
1087 BT_LOGV("Not creating a field because enumeration field is frozen: "
1088 "enum-field-addr=%p", field);
918be005
PP
1089 goto end;
1090 }
1091
273b65be
JG
1092 struct bt_ctf_field_type_enumeration *enumeration_type =
1093 container_of(field->type,
1094 struct bt_ctf_field_type_enumeration, parent);
1095 enumeration->payload =
1096 bt_ctf_field_create(enumeration_type->container);
1097 }
1098
1099 container = enumeration->payload;
83509119 1100 bt_get(container);
273b65be
JG
1101end:
1102 return container;
1103}
1104
e0f15669
JG
1105struct bt_ctf_field_type_enumeration_mapping_iterator *
1106bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *field)
cd95e351
JG
1107{
1108 int ret;
cd95e351
JG
1109 struct bt_ctf_field *container = NULL;
1110 struct bt_ctf_field_type *container_type = NULL;
1111 struct bt_ctf_field_type_integer *integer_type = NULL;
96e8f959 1112 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
cd95e351
JG
1113
1114 container = bt_ctf_field_enumeration_get_container(field);
1115 if (!container) {
fc25abce
PP
1116 BT_LOGW("Invalid parameter: enumeration field has no container field: "
1117 "addr=%p", field);
cd95e351
JG
1118 goto end;
1119 }
1120
1121 container_type = bt_ctf_field_get_type(container);
fc25abce 1122 assert(container_type);
cd95e351
JG
1123 integer_type = container_of(container_type,
1124 struct bt_ctf_field_type_integer, parent);
cd95e351 1125
dc3fffef 1126 if (!integer_type->is_signed) {
cd95e351 1127 uint64_t value;
96e8f959 1128
cd95e351
JG
1129 ret = bt_ctf_field_unsigned_integer_get_value(container,
1130 &value);
1131 if (ret) {
fc25abce
PP
1132 BT_LOGW("Cannot get value from signed enumeration field's payload field: "
1133 "enum-field-addr=%p, payload-field-addr=%p",
1134 field, container);
cd95e351
JG
1135 goto error_put_container_type;
1136 }
96e8f959
MD
1137 iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
1138 field->type, value);
cd95e351
JG
1139 } else {
1140 int64_t value;
96e8f959 1141
cd95e351
JG
1142 ret = bt_ctf_field_signed_integer_get_value(container,
1143 &value);
1144 if (ret) {
fc25abce
PP
1145 BT_LOGW("Cannot get value from unsigned enumeration field's payload field: "
1146 "enum-field-addr=%p, payload-field-addr=%p",
1147 field, container);
cd95e351
JG
1148 goto error_put_container_type;
1149 }
96e8f959
MD
1150 iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
1151 field->type, value);
cd95e351
JG
1152 }
1153
1154error_put_container_type:
83509119 1155 bt_put(container_type);
83509119 1156 bt_put(container);
cd95e351 1157end:
e0f15669 1158 return iter;
cd95e351
JG
1159}
1160
1161int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
1162 int64_t *value)
1163{
1164 int ret = 0;
1165 struct bt_ctf_field_integer *integer;
1166 struct bt_ctf_field_type_integer *integer_type;
1167
fc25abce
PP
1168 if (!field) {
1169 BT_LOGW_STR("Invalid parameter: field is NULL.");
1170 ret = -1;
1171 goto end;
1172 }
1173
1174 if (!value) {
1175 BT_LOGW_STR("Invalid parameter: value is NULL.");
1176 ret = -1;
1177 goto end;
1178 }
1179
1180 if (!field->payload_set) {
1181 BT_LOGV("Field's payload is not set: addr=%p", field);
1182 ret = -1;
1183 goto end;
1184 }
1185
1186 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1187 BT_CTF_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1188 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1189 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1190 field->type,
1191 bt_ctf_field_type_id_string(field->type->id));
cd95e351
JG
1192 ret = -1;
1193 goto end;
1194 }
1195
1196 integer_type = container_of(field->type,
1197 struct bt_ctf_field_type_integer, parent);
dc3fffef 1198 if (!integer_type->is_signed) {
fc25abce
PP
1199 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1200 "field-addr=%p, ft-addr=%p", field, field->type);
cd95e351
JG
1201 ret = -1;
1202 goto end;
1203 }
1204
1205 integer = container_of(field,
1206 struct bt_ctf_field_integer, parent);
dc3fffef 1207 *value = integer->payload.signd;
cd95e351
JG
1208end:
1209 return ret;
1210}
1211
273b65be
JG
1212int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
1213 int64_t value)
1214{
1215 int ret = 0;
1216 struct bt_ctf_field_integer *integer;
1217 struct bt_ctf_field_type_integer *integer_type;
1218 unsigned int size;
1219 int64_t min_value, max_value;
1220
fc25abce
PP
1221 if (!field) {
1222 BT_LOGW_STR("Invalid parameter: field is NULL.");
1223 ret = -1;
1224 goto end;
1225 }
1226
1227 if (field->frozen) {
1228 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1229 field);
1230 ret = -1;
1231 goto end;
1232 }
1233
1234 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1235 BT_CTF_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1236 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1237 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1238 field->type,
1239 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
1240 ret = -1;
1241 goto end;
1242 }
1243
1244 integer = container_of(field, struct bt_ctf_field_integer, parent);
1245 integer_type = container_of(field->type,
1246 struct bt_ctf_field_type_integer, parent);
dc3fffef 1247 if (!integer_type->is_signed) {
fc25abce
PP
1248 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1249 "field-addr=%p, ft-addr=%p", field, field->type);
273b65be
JG
1250 ret = -1;
1251 goto end;
1252 }
1253
dc3fffef 1254 size = integer_type->size;
9dc0d640
JG
1255 min_value = -(1ULL << (size - 1));
1256 max_value = (1ULL << (size - 1)) - 1;
273b65be 1257 if (value < min_value || value > max_value) {
fc25abce
PP
1258 BT_LOGW("Invalid parameter: value is out of bounds: "
1259 "addr=%p, value=%" PRId64 ", "
1260 "min-value=%" PRId64 ", max-value=%" PRId64,
1261 field, value, min_value, max_value);
273b65be
JG
1262 ret = -1;
1263 goto end;
1264 }
1265
dc3fffef 1266 integer->payload.signd = value;
d990a4fb 1267 integer->parent.payload_set = true;
273b65be
JG
1268end:
1269 return ret;
1270}
1271
cd95e351
JG
1272int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
1273 uint64_t *value)
1274{
1275 int ret = 0;
1276 struct bt_ctf_field_integer *integer;
1277 struct bt_ctf_field_type_integer *integer_type;
1278
fc25abce
PP
1279 if (!field) {
1280 BT_LOGW_STR("Invalid parameter: field is NULL.");
1281 ret = -1;
1282 goto end;
1283 }
1284
1285 if (!value) {
1286 BT_LOGW_STR("Invalid parameter: value is NULL.");
1287 ret = -1;
1288 goto end;
1289 }
1290
1291 if (!field->payload_set) {
1292 BT_LOGV("Field's payload is not set: addr=%p", field);
1293 ret = -1;
1294 goto end;
1295 }
1296
1297 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1298 BT_CTF_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1299 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1300 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1301 field->type,
1302 bt_ctf_field_type_id_string(field->type->id));
cd95e351
JG
1303 ret = -1;
1304 goto end;
1305 }
1306
1307 integer_type = container_of(field->type,
1308 struct bt_ctf_field_type_integer, parent);
dc3fffef 1309 if (integer_type->is_signed) {
fc25abce
PP
1310 BT_LOGW("Invalid parameter: integer field's type is signed: "
1311 "field-addr=%p, ft-addr=%p", field, field->type);
cd95e351
JG
1312 ret = -1;
1313 goto end;
1314 }
1315
1316 integer = container_of(field,
1317 struct bt_ctf_field_integer, parent);
dc3fffef 1318 *value = integer->payload.unsignd;
cd95e351
JG
1319end:
1320 return ret;
1321}
1322
273b65be
JG
1323int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
1324 uint64_t value)
1325{
1326 int ret = 0;
1327 struct bt_ctf_field_integer *integer;
1328 struct bt_ctf_field_type_integer *integer_type;
1329 unsigned int size;
1330 uint64_t max_value;
1331
fc25abce
PP
1332 if (!field) {
1333 BT_LOGW_STR("Invalid parameter: field is NULL.");
1334 ret = -1;
1335 goto end;
1336 }
1337
1338 if (field->frozen) {
1339 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1340 field);
1341 ret = -1;
1342 goto end;
1343 }
1344
1345 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1346 BT_CTF_FIELD_TYPE_ID_INTEGER) {
fc25abce
PP
1347 BT_LOGW("Invalid parameter: field's type is not an integer field type: "
1348 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1349 field->type,
1350 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
1351 ret = -1;
1352 goto end;
1353 }
1354
1355 integer = container_of(field, struct bt_ctf_field_integer, parent);
1356 integer_type = container_of(field->type,
1357 struct bt_ctf_field_type_integer, parent);
dc3fffef 1358 if (integer_type->is_signed) {
fc25abce
PP
1359 BT_LOGW("Invalid parameter: integer field's type is signed: "
1360 "field-addr=%p, ft-addr=%p", field, field->type);
273b65be
JG
1361 ret = -1;
1362 goto end;
1363 }
1364
dc3fffef 1365 size = integer_type->size;
8684abc8 1366 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
273b65be 1367 if (value > max_value) {
fc25abce
PP
1368 BT_LOGW("Invalid parameter: value is out of bounds: "
1369 "addr=%p, value=%" PRIu64 ", "
1370 "min-value=%" PRIu64 ", max-value=%" PRIu64,
1371 field, value, (uint64_t) 0, max_value);
273b65be
JG
1372 ret = -1;
1373 goto end;
1374 }
1375
dc3fffef 1376 integer->payload.unsignd = value;
d990a4fb 1377 integer->parent.payload_set = true;
273b65be
JG
1378end:
1379 return ret;
1380}
1381
cd95e351
JG
1382int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1383 double *value)
1384{
1385 int ret = 0;
1386 struct bt_ctf_field_floating_point *floating_point;
1387
fc25abce
PP
1388 if (!field) {
1389 BT_LOGW_STR("Invalid parameter: field is NULL.");
1390 ret = -1;
1391 goto end;
1392 }
1393
1394 if (!value) {
1395 BT_LOGW_STR("Invalid parameter: value is NULL.");
1396 ret = -1;
1397 goto end;
1398 }
1399
1400 if (!field->payload_set) {
1401 BT_LOGV("Field's payload is not set: addr=%p", field);
1402 ret = -1;
1403 goto end;
1404 }
1405
1406 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1407 BT_CTF_FIELD_TYPE_ID_FLOAT) {
fc25abce
PP
1408 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1409 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1410 field->type,
1411 bt_ctf_field_type_id_string(field->type->id));
cd95e351
JG
1412 ret = -1;
1413 goto end;
1414 }
1415
1416 floating_point = container_of(field,
1417 struct bt_ctf_field_floating_point, parent);
dc3fffef 1418 *value = floating_point->payload;
cd95e351
JG
1419end:
1420 return ret;
1421}
1422
273b65be
JG
1423int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1424 double value)
1425{
1426 int ret = 0;
1427 struct bt_ctf_field_floating_point *floating_point;
1428
fc25abce
PP
1429 if (!field) {
1430 BT_LOGW_STR("Invalid parameter: field is NULL.");
1431 ret = -1;
1432 goto end;
1433 }
1434
1435 if (field->frozen) {
1436 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1437 field);
1438 ret = -1;
1439 goto end;
1440 }
1441
1442 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1443 BT_CTF_FIELD_TYPE_ID_FLOAT) {
fc25abce
PP
1444 BT_LOGW("Invalid parameter: field's type is not a floating point number field type: "
1445 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1446 field->type,
1447 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
1448 ret = -1;
1449 goto end;
1450 }
fc25abce 1451
273b65be
JG
1452 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1453 parent);
dc3fffef 1454 floating_point->payload = value;
d990a4fb 1455 floating_point->parent.payload_set = true;
273b65be
JG
1456end:
1457 return ret;
1458}
1459
cd95e351
JG
1460const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1461{
1462 const char *ret = NULL;
1463 struct bt_ctf_field_string *string;
1464
fc25abce
PP
1465 if (!field) {
1466 BT_LOGW_STR("Invalid parameter: field is NULL.");
1467 goto end;
1468 }
1469
1470 if (!field->payload_set) {
1471 BT_LOGV("Field's payload is not set: addr=%p", field);
1472 goto end;
1473 }
1474
1475 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1476 BT_CTF_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1477 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1478 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1479 field->type,
1480 bt_ctf_field_type_id_string(field->type->id));
cd95e351
JG
1481 goto end;
1482 }
1483
1484 string = container_of(field,
1485 struct bt_ctf_field_string, parent);
1486 ret = string->payload->str;
1487end:
1488 return ret;
1489}
1490
273b65be
JG
1491int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
1492 const char *value)
1493{
1494 int ret = 0;
1495 struct bt_ctf_field_string *string;
1496
fc25abce
PP
1497 if (!field) {
1498 BT_LOGW_STR("Invalid parameter: field is NULL.");
1499 ret = -1;
1500 goto end;
1501 }
1502
1503 if (!value) {
1504 BT_LOGW_STR("Invalid parameter: value is NULL.");
1505 ret = -1;
1506 goto end;
1507 }
1508
1509 if (field->frozen) {
1510 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1511 field);
1512 ret = -1;
1513 goto end;
1514 }
1515
1516 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1517 BT_CTF_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1518 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1519 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1520 field->type,
1521 bt_ctf_field_type_id_string(field->type->id));
273b65be
JG
1522 ret = -1;
1523 goto end;
1524 }
1525
1526 string = container_of(field, struct bt_ctf_field_string, parent);
1527 if (string->payload) {
97736814
JG
1528 g_string_assign(string->payload, value);
1529 } else {
1530 string->payload = g_string_new(value);
273b65be
JG
1531 }
1532
d990a4fb 1533 string->parent.payload_set = true;
273b65be
JG
1534end:
1535 return ret;
1536}
1537
c6f9c5a3
PP
1538int bt_ctf_field_string_append(struct bt_ctf_field *field,
1539 const char *value)
1540{
1541 int ret = 0;
1542 struct bt_ctf_field_string *string_field;
1543
fc25abce
PP
1544 if (!field) {
1545 BT_LOGW_STR("Invalid parameter: field is NULL.");
1546 ret = -1;
1547 goto end;
1548 }
1549
1550 if (!value) {
1551 BT_LOGW_STR("Invalid parameter: value is NULL.");
1552 ret = -1;
1553 goto end;
1554 }
1555
1556 if (field->frozen) {
1557 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1558 field);
1559 ret = -1;
1560 goto end;
1561 }
1562
1563 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1564 BT_CTF_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1565 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1566 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1567 field->type,
1568 bt_ctf_field_type_id_string(field->type->id));
c6f9c5a3
PP
1569 ret = -1;
1570 goto end;
1571 }
1572
1573 string_field = container_of(field, struct bt_ctf_field_string, parent);
1574
1575 if (string_field->payload) {
1576 g_string_append(string_field->payload, value);
1577 } else {
1578 string_field->payload = g_string_new(value);
1579 }
1580
d990a4fb 1581 string_field->parent.payload_set = true;
c6f9c5a3
PP
1582
1583end:
1584 return ret;
1585}
1586
f98c6554
PP
1587int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1588 const char *value, unsigned int length)
1589{
1590 int i;
1591 int ret = 0;
1592 unsigned int effective_length = length;
1593 struct bt_ctf_field_string *string_field;
1594
fc25abce
PP
1595 if (!field) {
1596 BT_LOGW_STR("Invalid parameter: field is NULL.");
1597 ret = -1;
1598 goto end;
1599 }
1600
1601 if (!value) {
1602 BT_LOGW_STR("Invalid parameter: value is NULL.");
1603 ret = -1;
1604 goto end;
1605 }
1606
1607 if (field->frozen) {
1608 BT_LOGW("Invalid parameter: field is frozen: addr=%p",
1609 field);
1610 ret = -1;
1611 goto end;
1612 }
1613
1614 if (bt_ctf_field_type_get_type_id(field->type) !=
1487a16a 1615 BT_CTF_FIELD_TYPE_ID_STRING) {
fc25abce
PP
1616 BT_LOGW("Invalid parameter: field's type is not a string field type: "
1617 "field-addr=%p, ft-addr=%p, ft-id=%s", field,
1618 field->type,
1619 bt_ctf_field_type_id_string(field->type->id));
f98c6554
PP
1620 ret = -1;
1621 goto end;
1622 }
1623
1624 string_field = container_of(field, struct bt_ctf_field_string, parent);
1625
1626 /* make sure no null bytes are appended */
1627 for (i = 0; i < length; ++i) {
1628 if (value[i] == '\0') {
1629 effective_length = i;
1630 break;
1631 }
1632 }
1633
1634 if (string_field->payload) {
ce6d5230 1635 g_string_append_len(string_field->payload, value,
f98c6554
PP
1636 effective_length);
1637 } else {
1638 string_field->payload = g_string_new_len(value,
1639 effective_length);
1640 }
1641
d990a4fb 1642 string_field->parent.payload_set = true;
f98c6554
PP
1643
1644end:
1645 return ret;
1646}
1647
273b65be
JG
1648BT_HIDDEN
1649int bt_ctf_field_validate(struct bt_ctf_field *field)
1650{
1651 int ret = 0;
1487a16a 1652 enum bt_ctf_field_type_id type_id;
273b65be
JG
1653
1654 if (!field) {
fc25abce 1655 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
1656 ret = -1;
1657 goto end;
1658 }
1659
1660 type_id = bt_ctf_field_type_get_type_id(field->type);
1487a16a 1661 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
fc25abce
PP
1662 BT_LOGW("Invalid parameter: unknown field type ID: "
1663 "addr=%p, ft-addr=%p, ft-id=%d",
1664 field, field->type, type_id);
273b65be
JG
1665 ret = -1;
1666 goto end;
1667 }
1668
1669 ret = field_validate_funcs[type_id](field);
1670end:
1671 return ret;
1672}
1673
12c8a1a3
JG
1674BT_HIDDEN
1675int bt_ctf_field_reset(struct bt_ctf_field *field)
1676{
1677 int ret = 0;
1487a16a 1678 enum bt_ctf_field_type_id type_id;
12c8a1a3
JG
1679
1680 if (!field) {
fc25abce 1681 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
1682 ret = -1;
1683 goto end;
1684 }
1685
1686 type_id = bt_ctf_field_type_get_type_id(field->type);
1487a16a 1687 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
fc25abce
PP
1688 BT_LOGW("Invalid parameter: unknown field type ID: "
1689 "addr=%p, ft-addr=%p, ft-id=%d",
1690 field, field->type, type_id);
12c8a1a3
JG
1691 ret = -1;
1692 goto end;
1693 }
1694
1695 ret = field_reset_funcs[type_id](field);
1696end:
1697 return ret;
1698}
1699
273b65be
JG
1700BT_HIDDEN
1701int bt_ctf_field_serialize(struct bt_ctf_field *field,
dc3fffef
PP
1702 struct bt_ctf_stream_pos *pos,
1703 enum bt_ctf_byte_order native_byte_order)
273b65be
JG
1704{
1705 int ret = 0;
1487a16a 1706 enum bt_ctf_field_type_id type_id;
273b65be 1707
fc25abce
PP
1708 assert(pos);
1709
1710 if (!field) {
1711 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
1712 ret = -1;
1713 goto end;
1714 }
1715
1716 type_id = bt_ctf_field_type_get_type_id(field->type);
1487a16a 1717 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
fc25abce
PP
1718 BT_LOGW("Invalid parameter: unknown field type ID: "
1719 "addr=%p, ft-addr=%p, ft-id=%d",
1720 field, field->type, type_id);
273b65be
JG
1721 ret = -1;
1722 goto end;
1723 }
1724
dc3fffef 1725 ret = field_serialize_funcs[type_id](field, pos, native_byte_order);
273b65be
JG
1726end:
1727 return ret;
1728}
1729
76f869ab
JG
1730
1731BT_HIDDEN
c55a9f58 1732bt_bool bt_ctf_field_is_set(struct bt_ctf_field *field)
76f869ab 1733{
c55a9f58 1734 bt_bool is_set = BT_FALSE;
1487a16a 1735 enum bt_ctf_field_type_id type_id;
76f869ab
JG
1736
1737 if (!field) {
1738 goto end;
1739 }
1740
1741 type_id = bt_ctf_field_type_get_type_id(field->type);
1487a16a 1742 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
fc25abce
PP
1743 BT_LOGW("Invalid parameter: unknown field type ID: "
1744 "field-addr=%p, ft-addr=%p, ft-id=%d",
1745 field, field->type, type_id);
76f869ab
JG
1746 goto end;
1747 }
1748
1749 is_set = field_is_set_funcs[type_id](field);
1750end:
1751 return is_set;
1752}
1753
87d43dc1
JG
1754struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1755{
1756 int ret;
1757 struct bt_ctf_field *copy = NULL;
1487a16a 1758 enum bt_ctf_field_type_id type_id;
87d43dc1
JG
1759
1760 if (!field) {
fc25abce 1761 BT_LOGW_STR("Invalid parameter: field is NULL.");
87d43dc1
JG
1762 goto end;
1763 }
1764
1765 type_id = bt_ctf_field_type_get_type_id(field->type);
1487a16a 1766 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
fc25abce
PP
1767 BT_LOGW("Invalid parameter: unknown field type ID: "
1768 "field-addr=%p, ft-addr=%p, ft-id=%d",
1769 field, field->type, type_id);
87d43dc1
JG
1770 goto end;
1771 }
1772
1773 copy = bt_ctf_field_create(field->type);
1774 if (!copy) {
fc25abce 1775 BT_LOGW("Cannot create field: ft-addr=%p", field->type);
87d43dc1
JG
1776 goto end;
1777 }
1778
70996764 1779 copy->payload_set = field->payload_set;
87d43dc1
JG
1780 ret = field_copy_funcs[type_id](field, copy);
1781 if (ret) {
83509119 1782 bt_put(copy);
87d43dc1
JG
1783 copy = NULL;
1784 }
1785end:
1786 return copy;
1787}
1788
273b65be
JG
1789static
1790struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1791{
273b65be
JG
1792 struct bt_ctf_field_integer *integer = g_new0(
1793 struct bt_ctf_field_integer, 1);
1794
fc25abce
PP
1795 BT_LOGD("Creating integer field object: ft-addr=%p", type);
1796
1797 if (integer) {
1798 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
1799 &integer->parent, type);
1800 } else {
1801 BT_LOGE_STR("Failed to allocate one integer field.");
1802 }
1803
273b65be
JG
1804 return integer ? &integer->parent : NULL;
1805}
1806
1807static
1808struct bt_ctf_field *bt_ctf_field_enumeration_create(
1809 struct bt_ctf_field_type *type)
1810{
1811 struct bt_ctf_field_enumeration *enumeration = g_new0(
1812 struct bt_ctf_field_enumeration, 1);
1813
fc25abce
PP
1814 BT_LOGD("Creating enumeration field object: ft-addr=%p", type);
1815
1816 if (enumeration) {
1817 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
1818 &enumeration->parent, type);
1819 } else {
1820 BT_LOGE_STR("Failed to allocate one enumeration field.");
1821 }
1822
273b65be
JG
1823 return enumeration ? &enumeration->parent : NULL;
1824}
1825
1826static
1827struct bt_ctf_field *bt_ctf_field_floating_point_create(
1828 struct bt_ctf_field_type *type)
1829{
1830 struct bt_ctf_field_floating_point *floating_point;
273b65be 1831
fc25abce 1832 BT_LOGD("Creating floating point number field object: ft-addr=%p", type);
273b65be 1833 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
fc25abce
PP
1834
1835 if (floating_point) {
1836 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
1837 &floating_point->parent, type);
1838 } else {
1839 BT_LOGE_STR("Failed to allocate one floating point number field.");
1840 }
1841
273b65be
JG
1842 return floating_point ? &floating_point->parent : NULL;
1843}
1844
1845static
1846struct bt_ctf_field *bt_ctf_field_structure_create(
1847 struct bt_ctf_field_type *type)
1848{
1849 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1850 struct bt_ctf_field_type_structure, parent);
1851 struct bt_ctf_field_structure *structure = g_new0(
1852 struct bt_ctf_field_structure, 1);
1853 struct bt_ctf_field *field = NULL;
1854
fc25abce
PP
1855 BT_LOGD("Creating structure field object: ft-addr=%p", type);
1856
8c1aa858 1857 if (!structure) {
fc25abce 1858 BT_LOGE_STR("Failed to allocate one structure field.");
273b65be
JG
1859 goto end;
1860 }
1861
1862 structure->field_name_to_index = structure_type->field_name_to_index;
1863 structure->fields = g_ptr_array_new_with_free_func(
1864 (GDestroyNotify)bt_ctf_field_put);
1865 g_ptr_array_set_size(structure->fields,
1866 g_hash_table_size(structure->field_name_to_index));
1867 field = &structure->parent;
fc25abce
PP
1868 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p",
1869 field, type);
273b65be
JG
1870end:
1871 return field;
1872}
1873
1874static
1875struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1876{
1877 struct bt_ctf_field_variant *variant = g_new0(
1878 struct bt_ctf_field_variant, 1);
fc25abce
PP
1879
1880 BT_LOGD("Creating variant field object: ft-addr=%p", type);
1881
1882 if (variant) {
1883 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1884 &variant->parent, type);
1885 } else {
1886 BT_LOGE_STR("Failed to allocate one variant field.");
1887 }
1888
273b65be
JG
1889 return variant ? &variant->parent : NULL;
1890}
1891
1892static
1893struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1894{
1895 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1896 struct bt_ctf_field_type_array *array_type;
1897 unsigned int array_length;
1898
fc25abce
PP
1899 BT_LOGD("Creating array field object: ft-addr=%p", type);
1900 assert(type);
1901
1902 if (!array) {
1903 BT_LOGE_STR("Failed to allocate one array field.");
273b65be
JG
1904 goto error;
1905 }
1906
1907 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1908 array_length = array_type->length;
fe0fe95c 1909 array->elements = g_ptr_array_sized_new(array_length);
273b65be
JG
1910 if (!array->elements) {
1911 goto error;
1912 }
1913
fe0fe95c
JG
1914 g_ptr_array_set_free_func(array->elements,
1915 (GDestroyNotify)bt_ctf_field_put);
273b65be 1916 g_ptr_array_set_size(array->elements, array_length);
fc25abce
PP
1917 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1918 &array->parent, type);
273b65be
JG
1919 return &array->parent;
1920error:
1921 g_free(array);
1922 return NULL;
1923}
1924
1925static
1926struct bt_ctf_field *bt_ctf_field_sequence_create(
1927 struct bt_ctf_field_type *type)
1928{
1929 struct bt_ctf_field_sequence *sequence = g_new0(
1930 struct bt_ctf_field_sequence, 1);
fc25abce
PP
1931
1932 BT_LOGD("Creating sequence field object: ft-addr=%p", type);
1933
1934 if (sequence) {
1935 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1936 &sequence->parent, type);
1937 } else {
1938 BT_LOGE_STR("Failed to allocate one sequence field.");
1939 }
1940
273b65be
JG
1941 return sequence ? &sequence->parent : NULL;
1942}
1943
1944static
1945struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1946{
1947 struct bt_ctf_field_string *string = g_new0(
1948 struct bt_ctf_field_string, 1);
fc25abce
PP
1949
1950 BT_LOGD("Creating string field object: ft-addr=%p", type);
1951
1952 if (string) {
1953 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1954 &string->parent, type);
1955 } else {
1956 BT_LOGE_STR("Failed to allocate one string field.");
1957 }
1958
273b65be
JG
1959 return string ? &string->parent : NULL;
1960}
1961
1962static
83509119 1963void bt_ctf_field_destroy(struct bt_object *obj)
273b65be
JG
1964{
1965 struct bt_ctf_field *field;
1966 struct bt_ctf_field_type *type;
1487a16a 1967 enum bt_ctf_field_type_id type_id;
273b65be 1968
83509119 1969 field = container_of(obj, struct bt_ctf_field, base);
273b65be
JG
1970 type = field->type;
1971 type_id = bt_ctf_field_type_get_type_id(type);
fc25abce
PP
1972 assert(type_id > BT_CTF_FIELD_TYPE_ID_UNKNOWN &&
1973 type_id < BT_CTF_NR_TYPE_IDS);
273b65be 1974 field_destroy_funcs[type_id](field);
fc25abce 1975 BT_LOGD_STR("Putting field's type.");
83509119 1976 bt_put(type);
273b65be
JG
1977}
1978
1979static
1980void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1981{
1982 struct bt_ctf_field_integer *integer;
1983
1984 if (!field) {
1985 return;
1986 }
1987
fc25abce 1988 BT_LOGD("Destroying integer field object: addr=%p", field);
273b65be
JG
1989 integer = container_of(field, struct bt_ctf_field_integer, parent);
1990 g_free(integer);
1991}
1992
1993static
1994void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1995{
1996 struct bt_ctf_field_enumeration *enumeration;
1997
1998 if (!field) {
1999 return;
2000 }
2001
fc25abce 2002 BT_LOGD("Destroying enumeration field object: addr=%p", field);
273b65be
JG
2003 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2004 parent);
fc25abce 2005 BT_LOGD_STR("Putting payload field.");
83509119 2006 bt_put(enumeration->payload);
273b65be
JG
2007 g_free(enumeration);
2008}
2009
2010static
2011void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
2012{
2013 struct bt_ctf_field_floating_point *floating_point;
2014
2015 if (!field) {
2016 return;
2017 }
2018
fc25abce 2019 BT_LOGD("Destroying floating point number field object: addr=%p", field);
273b65be
JG
2020 floating_point = container_of(field, struct bt_ctf_field_floating_point,
2021 parent);
2022 g_free(floating_point);
2023}
2024
2025static
2026void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
2027{
2028 struct bt_ctf_field_structure *structure;
2029
2030 if (!field) {
2031 return;
2032 }
2033
fc25abce 2034 BT_LOGD("Destroying structure field object: addr=%p", field);
273b65be
JG
2035 structure = container_of(field, struct bt_ctf_field_structure, parent);
2036 g_ptr_array_free(structure->fields, TRUE);
2037 g_free(structure);
2038}
2039
2040static
2041void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
2042{
2043 struct bt_ctf_field_variant *variant;
2044
2045 if (!field) {
2046 return;
2047 }
2048
fc25abce 2049 BT_LOGD("Destroying variant field object: addr=%p", field);
273b65be 2050 variant = container_of(field, struct bt_ctf_field_variant, parent);
fc25abce 2051 BT_LOGD_STR("Putting tag field.");
83509119 2052 bt_put(variant->tag);
fc25abce 2053 BT_LOGD_STR("Putting payload field.");
83509119 2054 bt_put(variant->payload);
273b65be
JG
2055 g_free(variant);
2056}
2057
2058static
2059void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
2060{
2061 struct bt_ctf_field_array *array;
2062
2063 if (!field) {
2064 return;
2065 }
2066
fc25abce 2067 BT_LOGD("Destroying array field object: addr=%p", field);
273b65be
JG
2068 array = container_of(field, struct bt_ctf_field_array, parent);
2069 g_ptr_array_free(array->elements, TRUE);
2070 g_free(array);
2071}
2072
2073static
2074void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
2075{
2076 struct bt_ctf_field_sequence *sequence;
2077
2078 if (!field) {
2079 return;
2080 }
2081
fc25abce 2082 BT_LOGD("Destroying sequence field object: addr=%p", field);
273b65be 2083 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
4fef87ab
JG
2084 if (sequence->elements) {
2085 g_ptr_array_free(sequence->elements, TRUE);
2086 }
fc25abce 2087 BT_LOGD_STR("Putting length field.");
83509119 2088 bt_put(sequence->length);
273b65be
JG
2089 g_free(sequence);
2090}
2091
2092static
2093void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
2094{
2095 struct bt_ctf_field_string *string;
fc25abce 2096
273b65be
JG
2097 if (!field) {
2098 return;
2099 }
2100
fc25abce 2101 BT_LOGD("Destroying string field object: addr=%p", field);
273b65be 2102 string = container_of(field, struct bt_ctf_field_string, parent);
9b2b7163
JG
2103 if (string->payload) {
2104 g_string_free(string->payload, TRUE);
2105 }
273b65be
JG
2106 g_free(string);
2107}
2108
2109static
2110int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
2111{
da2f6971 2112 return (field && field->payload_set) ? 0 : -1;
273b65be
JG
2113}
2114
2115static
2116int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
2117{
2118 int ret;
2119 struct bt_ctf_field_enumeration *enumeration;
2120
2121 if (!field) {
fc25abce 2122 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2123 ret = -1;
2124 goto end;
2125 }
2126
2127 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2128 parent);
2129 if (!enumeration->payload) {
fc25abce
PP
2130 BT_LOGW("Invalid enumeration field: payload is not set: "
2131 "addr=%p", field);
273b65be
JG
2132 ret = -1;
2133 goto end;
2134 }
2135
2136 ret = bt_ctf_field_validate(enumeration->payload);
2137end:
2138 return ret;
2139}
2140
2141static
2142int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
2143{
fc25abce 2144 int64_t i;
273b65be
JG
2145 int ret = 0;
2146 struct bt_ctf_field_structure *structure;
2147
2148 if (!field) {
fc25abce 2149 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2150 ret = -1;
2151 goto end;
2152 }
2153
2154 structure = container_of(field, struct bt_ctf_field_structure, parent);
2155 for (i = 0; i < structure->fields->len; i++) {
fc25abce
PP
2156 struct bt_ctf_field *entry_field = structure->fields->pdata[i];
2157 ret = bt_ctf_field_validate(entry_field);
2158
273b65be 2159 if (ret) {
fc25abce 2160 int this_ret;
6ce12048
JG
2161 const char *name;
2162 struct bt_ctf_field_type *field_type =
2163 bt_ctf_field_get_type(field);
2164
fc25abce
PP
2165 this_ret = bt_ctf_field_type_structure_get_field(
2166 field_type, &name, NULL, i);
2167 assert(this_ret == 0);
2168 BT_LOGW("Invalid structure field's field: "
2169 "struct-field-addr=%p, field-addr=%p, "
2170 "field-name=\"%s\", index=%" PRId64,
2171 field, entry_field, name, i);
e5ed1ccf 2172 bt_put(field_type);
273b65be
JG
2173 goto end;
2174 }
2175 }
2176end:
2177 return ret;
2178}
2179
2180static
2181int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
2182{
2183 int ret = 0;
2184 struct bt_ctf_field_variant *variant;
2185
2186 if (!field) {
fc25abce 2187 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2188 ret = -1;
2189 goto end;
2190 }
2191
2192 variant = container_of(field, struct bt_ctf_field_variant, parent);
2193 ret = bt_ctf_field_validate(variant->payload);
fc25abce
PP
2194 if (ret) {
2195 BT_LOGW("Invalid variant field's payload field: "
2196 "variant-field-addr=%p, variant-payload-field-addr=%p",
2197 field, variant->payload);
2198 }
273b65be
JG
2199end:
2200 return ret;
2201}
2202
2203static
2204int bt_ctf_field_array_validate(struct bt_ctf_field *field)
2205{
fc25abce 2206 int64_t i;
273b65be
JG
2207 int ret = 0;
2208 struct bt_ctf_field_array *array;
2209
2210 if (!field) {
fc25abce 2211 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2212 ret = -1;
2213 goto end;
2214 }
2215
2216 array = container_of(field, struct bt_ctf_field_array, parent);
2217 for (i = 0; i < array->elements->len; i++) {
fc25abce
PP
2218 struct bt_ctf_field *elem_field = array->elements->pdata[i];
2219
2220 ret = bt_ctf_field_validate(elem_field);
273b65be 2221 if (ret) {
fc25abce
PP
2222 BT_LOGW("Invalid array field's element field: "
2223 "array-field-addr=%p, field-addr=%p, "
2224 "index=%" PRId64, field, elem_field, i);
273b65be
JG
2225 goto end;
2226 }
2227 }
2228end:
2229 return ret;
2230}
2231
2232static
2233int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
2234{
2235 size_t i;
2236 int ret = 0;
2237 struct bt_ctf_field_sequence *sequence;
2238
2239 if (!field) {
fc25abce 2240 BT_LOGD_STR("Invalid parameter: field is NULL.");
273b65be
JG
2241 ret = -1;
2242 goto end;
2243 }
2244
2245 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
2246 for (i = 0; i < sequence->elements->len; i++) {
fc25abce
PP
2247 struct bt_ctf_field *elem_field = sequence->elements->pdata[i];
2248
2249 ret = bt_ctf_field_validate(elem_field);
273b65be 2250 if (ret) {
fc25abce
PP
2251 BT_LOGW("Invalid sequence field's element field: "
2252 "sequence-field-addr=%p, field-addr=%p, "
1974687e 2253 "index=%zu", field, elem_field, i);
273b65be
JG
2254 goto end;
2255 }
2256 }
2257end:
2258 return ret;
2259}
2260
12c8a1a3
JG
2261static
2262int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
2263{
2264 int ret = 0;
2265
2266 if (!field) {
fc25abce 2267 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2268 ret = -1;
2269 goto end;
2270 }
2271
d990a4fb 2272 field->payload_set = false;
12c8a1a3
JG
2273end:
2274 return ret;
2275}
2276
2277static
2278int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
2279{
2280 int ret = 0;
2281 struct bt_ctf_field_enumeration *enumeration;
2282
2283 if (!field) {
fc25abce 2284 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2285 ret = -1;
2286 goto end;
2287 }
2288
2289 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2290 parent);
2291 if (!enumeration->payload) {
2292 goto end;
2293 }
2294
2295 ret = bt_ctf_field_reset(enumeration->payload);
2296end:
2297 return ret;
2298}
2299
2300static
2301int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
2302{
fc25abce 2303 int64_t i;
12c8a1a3
JG
2304 int ret = 0;
2305 struct bt_ctf_field_structure *structure;
2306
2307 if (!field) {
fc25abce 2308 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2309 ret = -1;
2310 goto end;
2311 }
2312
2313 structure = container_of(field, struct bt_ctf_field_structure, parent);
2314 for (i = 0; i < structure->fields->len; i++) {
2315 struct bt_ctf_field *member = structure->fields->pdata[i];
2316
2317 if (!member) {
2318 /*
2319 * Structure members are lazily initialized; skip if
2320 * this member has not been allocated yet.
2321 */
2322 continue;
2323 }
2324
2325 ret = bt_ctf_field_reset(member);
2326 if (ret) {
fc25abce
PP
2327 BT_LOGE("Failed to reset structure field's field: "
2328 "struct-field-addr=%p, field-addr=%p, "
2329 "index=%" PRId64, field, member, i);
12c8a1a3
JG
2330 goto end;
2331 }
2332 }
2333end:
2334 return ret;
2335}
2336
2337static
2338int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
2339{
2340 int ret = 0;
2341 struct bt_ctf_field_variant *variant;
2342
2343 if (!field) {
fc25abce 2344 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2345 ret = -1;
2346 goto end;
2347 }
2348
2349 variant = container_of(field, struct bt_ctf_field_variant, parent);
2350 if (variant->payload) {
2351 ret = bt_ctf_field_reset(variant->payload);
fc25abce
PP
2352 if (ret) {
2353 BT_LOGW("Failed to reset variant field's payload field: "
2354 "variant-field-addr=%p, payload-field-addr=%p",
2355 field, variant->payload);
2356 }
12c8a1a3
JG
2357 }
2358end:
2359 return ret;
2360}
2361
2362static
2363int bt_ctf_field_array_reset(struct bt_ctf_field *field)
2364{
2365 size_t i;
2366 int ret = 0;
2367 struct bt_ctf_field_array *array;
2368
2369 if (!field) {
fc25abce 2370 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2371 ret = -1;
2372 goto end;
2373 }
2374
2375 array = container_of(field, struct bt_ctf_field_array, parent);
2376 for (i = 0; i < array->elements->len; i++) {
2377 struct bt_ctf_field *member = array->elements->pdata[i];
2378
2379 if (!member) {
2380 /*
2381 * Array elements are lazily initialized; skip if
2382 * this member has not been allocated yet.
2383 */
2384 continue;
2385 }
2386
2387 ret = bt_ctf_field_reset(member);
2388 if (ret) {
fc25abce
PP
2389 BT_LOGE("Failed to reset array field's field: "
2390 "array-field-addr=%p, field-addr=%p, "
1974687e 2391 "index=%zu", field, member, i);
12c8a1a3
JG
2392 goto end;
2393 }
2394 }
2395end:
2396 return ret;
2397}
2398
2399static
2400int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
2401{
2402 size_t i;
2403 int ret = 0;
2404 struct bt_ctf_field_sequence *sequence;
2405
2406 if (!field) {
fc25abce 2407 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2408 ret = -1;
2409 goto end;
2410 }
2411
2412 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
2413 for (i = 0; i < sequence->elements->len; i++) {
2414 struct bt_ctf_field *member = sequence->elements->pdata[i];
2415
2416 if (!member) {
2417 /*
2418 * Sequence elements are lazily initialized; skip if
2419 * this member has not been allocated yet.
2420 */
2421 continue;
2422 }
2423
2424 ret = bt_ctf_field_reset(member);
2425 if (ret) {
fc25abce
PP
2426 BT_LOGE("Failed to reset sequence field's field: "
2427 "sequence-field-addr=%p, field-addr=%p, "
1974687e 2428 "index=%zu", field, member, i);
12c8a1a3
JG
2429 goto end;
2430 }
2431 }
2432end:
2433 return ret;
2434}
2435
2436static
2437int bt_ctf_field_string_reset(struct bt_ctf_field *field)
2438{
2439 int ret = 0;
2440 struct bt_ctf_field_string *string;
2441
2442 if (!field) {
fc25abce 2443 BT_LOGD_STR("Invalid parameter: field is NULL.");
12c8a1a3
JG
2444 ret = -1;
2445 goto end;
2446 }
2447
2448 ret = bt_ctf_field_generic_reset(field);
2449 if (ret) {
2450 goto end;
2451 }
2452
2453 string = container_of(field, struct bt_ctf_field_string, parent);
2454 if (string->payload) {
2455 g_string_truncate(string->payload, 0);
2456 }
2457end:
2458 return ret;
2459}
2460
273b65be
JG
2461static
2462int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2463 struct bt_ctf_stream_pos *pos,
2464 enum bt_ctf_byte_order native_byte_order)
273b65be
JG
2465{
2466 int ret = 0;
2467 struct bt_ctf_field_integer *integer = container_of(field,
2468 struct bt_ctf_field_integer, parent);
2469
fc25abce
PP
2470 BT_LOGV("Serializing integer field: addr=%p, pos-offset=%" PRId64 ", "
2471 "native-bo=%s", field, pos->offset,
2472 bt_ctf_byte_order_string(native_byte_order));
2473
fa21dcb1 2474 if (!bt_ctf_field_generic_is_set(field)) {
fc25abce 2475 BT_LOGW_STR("Field's payload is not set.");
fa21dcb1
JG
2476 ret = -1;
2477 goto end;
2478 }
273b65be 2479retry:
dc3fffef 2480 ret = bt_ctf_field_integer_write(integer, pos, native_byte_order);
273b65be
JG
2481 if (ret == -EFAULT) {
2482 /*
2483 * The field is too large to fit in the current packet's
2484 * remaining space. Bump the packet size and retry.
2485 */
2486 ret = increase_packet_size(pos);
2487 if (ret) {
fc25abce 2488 BT_LOGE("Cannot increase packet size: ret=%d", ret);
273b65be
JG
2489 goto end;
2490 }
2491 goto retry;
2492 }
2493end:
2494 return ret;
2495}
2496
2497static
2498int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2499 struct bt_ctf_stream_pos *pos,
2500 enum bt_ctf_byte_order native_byte_order)
273b65be
JG
2501{
2502 struct bt_ctf_field_enumeration *enumeration = container_of(
2503 field, struct bt_ctf_field_enumeration, parent);
2504
fc25abce
PP
2505 BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64 ", "
2506 "native-bo=%s", field, pos->offset,
2507 bt_ctf_byte_order_string(native_byte_order));
2508 BT_LOGV_STR("Serializing enumeration field's payload field.");
dc3fffef
PP
2509 return bt_ctf_field_serialize(enumeration->payload, pos,
2510 native_byte_order);
273b65be
JG
2511}
2512
2513static
2514int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2515 struct bt_ctf_stream_pos *pos,
2516 enum bt_ctf_byte_order native_byte_order)
273b65be
JG
2517{
2518 int ret = 0;
2519 struct bt_ctf_field_floating_point *floating_point = container_of(field,
2520 struct bt_ctf_field_floating_point, parent);
2521
fc25abce
PP
2522 BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64 ", "
2523 "native-bo=%s", field, pos->offset,
2524 bt_ctf_byte_order_string(native_byte_order));
2525
fa21dcb1 2526 if (!bt_ctf_field_generic_is_set(field)) {
fc25abce 2527 BT_LOGW_STR("Field's payload is not set.");
fa21dcb1
JG
2528 ret = -1;
2529 goto end;
2530 }
273b65be 2531retry:
dc3fffef
PP
2532 ret = bt_ctf_field_floating_point_write(floating_point, pos,
2533 native_byte_order);
273b65be
JG
2534 if (ret == -EFAULT) {
2535 /*
2536 * The field is too large to fit in the current packet's
2537 * remaining space. Bump the packet size and retry.
2538 */
2539 ret = increase_packet_size(pos);
2540 if (ret) {
fc25abce 2541 BT_LOGE("Cannot increase packet size: ret=%d", ret);
273b65be
JG
2542 goto end;
2543 }
2544 goto retry;
2545 }
2546end:
2547 return ret;
2548}
2549
2550static
2551int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2552 struct bt_ctf_stream_pos *pos,
2553 enum bt_ctf_byte_order native_byte_order)
273b65be 2554{
fc25abce 2555 int64_t i;
273b65be
JG
2556 int ret = 0;
2557 struct bt_ctf_field_structure *structure = container_of(
2558 field, struct bt_ctf_field_structure, parent);
2559
fc25abce
PP
2560 BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64 ", "
2561 "native-bo=%s", field, pos->offset,
2562 bt_ctf_byte_order_string(native_byte_order));
2563
dc3fffef
PP
2564 while (!bt_ctf_stream_pos_access_ok(pos,
2565 offset_align(pos->offset, field->type->alignment))) {
9f56e450
JG
2566 ret = increase_packet_size(pos);
2567 if (ret) {
fc25abce 2568 BT_LOGE("Cannot increase packet size: ret=%d", ret);
9f56e450
JG
2569 goto end;
2570 }
273b65be
JG
2571 }
2572
dc3fffef 2573 if (!bt_ctf_stream_pos_align(pos, field->type->alignment)) {
fc25abce
PP
2574 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64 ", "
2575 "align=%u", pos->offset, field->type->alignment);
70fd5a51
MD
2576 ret = -1;
2577 goto end;
2578 }
273b65be
JG
2579
2580 for (i = 0; i < structure->fields->len; i++) {
bf3a205b 2581 struct bt_ctf_field *member = g_ptr_array_index(
273b65be 2582 structure->fields, i);
b3376dd9
PP
2583 const char *field_name = NULL;
2584
2585 if (BT_LOG_ON_WARN) {
2586 ret = bt_ctf_field_type_structure_get_field(
2587 field->type, &field_name, NULL, i);
2588 assert(ret == 0);
2589 }
273b65be 2590
fc25abce
PP
2591 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64 ", "
2592 "field-addr=%p, index=%" PRId64,
2593 pos->offset, member, i);
b3376dd9
PP
2594
2595 if (!member) {
2596 BT_LOGW("Cannot serialize structure field's field: field is not set: "
2597 "struct-field-addr=%p, "
2598 "field-name=\"%s\", index=%" PRId64,
2599 field, field_name, i);
2600 ret = -1;
2601 goto end;
2602 }
2603
dc3fffef 2604 ret = bt_ctf_field_serialize(member, pos, native_byte_order);
273b65be 2605 if (ret) {
fc25abce
PP
2606 BT_LOGW("Cannot serialize structure field's field: "
2607 "struct-field-addr=%p, field-addr=%p, "
2608 "field-name=\"%s\", index=%" PRId64,
b3376dd9 2609 field->type, member, field_name, i);
273b65be
JG
2610 break;
2611 }
2612 }
9f56e450 2613end:
273b65be
JG
2614 return ret;
2615}
2616
2617static
2618int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2619 struct bt_ctf_stream_pos *pos,
2620 enum bt_ctf_byte_order native_byte_order)
273b65be
JG
2621{
2622 struct bt_ctf_field_variant *variant = container_of(
2623 field, struct bt_ctf_field_variant, parent);
2624
fc25abce
PP
2625 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64 ", "
2626 "native-bo=%s", field, pos->offset,
2627 bt_ctf_byte_order_string(native_byte_order));
2628 BT_LOGV_STR("Serializing variant field's payload field.");
dc3fffef
PP
2629 return bt_ctf_field_serialize(variant->payload, pos,
2630 native_byte_order);
273b65be
JG
2631}
2632
2633static
2634int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2635 struct bt_ctf_stream_pos *pos,
2636 enum bt_ctf_byte_order native_byte_order)
273b65be 2637{
fc25abce 2638 int64_t i;
273b65be
JG
2639 int ret = 0;
2640 struct bt_ctf_field_array *array = container_of(
2641 field, struct bt_ctf_field_array, parent);
2642
fc25abce
PP
2643 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64 ", "
2644 "native-bo=%s", field, pos->offset,
2645 bt_ctf_byte_order_string(native_byte_order));
2646
273b65be 2647 for (i = 0; i < array->elements->len; i++) {
fc25abce
PP
2648 struct bt_ctf_field *elem_field =
2649 g_ptr_array_index(array->elements, i);
2650
2651 BT_LOGV("Serializing array field's element field: "
2652 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
2653 pos->offset, elem_field, i);
2654 ret = bt_ctf_field_serialize(elem_field, pos,
dc3fffef 2655 native_byte_order);
273b65be 2656 if (ret) {
fc25abce
PP
2657 BT_LOGW("Cannot serialize array field's element field: "
2658 "array-field-addr=%p, field-addr=%p, "
2659 "index=%" PRId64, field, elem_field, i);
273b65be
JG
2660 goto end;
2661 }
2662 }
2663end:
2664 return ret;
2665}
2666
2667static
2668int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2669 struct bt_ctf_stream_pos *pos,
2670 enum bt_ctf_byte_order native_byte_order)
273b65be 2671{
fc25abce 2672 int64_t i;
273b65be
JG
2673 int ret = 0;
2674 struct bt_ctf_field_sequence *sequence = container_of(
2675 field, struct bt_ctf_field_sequence, parent);
2676
fc25abce
PP
2677 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64 ", "
2678 "native-bo=%s", field, pos->offset,
2679 bt_ctf_byte_order_string(native_byte_order));
2680
273b65be 2681 for (i = 0; i < sequence->elements->len; i++) {
fc25abce
PP
2682 struct bt_ctf_field *elem_field =
2683 g_ptr_array_index(sequence->elements, i);
2684
2685 BT_LOGV("Serializing sequence field's element field: "
2686 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
2687 pos->offset, elem_field, i);
2688 ret = bt_ctf_field_serialize(elem_field, pos,
dc3fffef 2689 native_byte_order);
273b65be 2690 if (ret) {
fc25abce
PP
2691 BT_LOGW("Cannot serialize sequence field's element field: "
2692 "sequence-field-addr=%p, field-addr=%p, "
2693 "index=%" PRId64, field, elem_field, i);
273b65be
JG
2694 goto end;
2695 }
2696 }
2697end:
2698 return ret;
2699}
2700
2701static
2702int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
dc3fffef
PP
2703 struct bt_ctf_stream_pos *pos,
2704 enum bt_ctf_byte_order native_byte_order)
273b65be 2705{
fc25abce 2706 int64_t i;
273b65be
JG
2707 int ret = 0;
2708 struct bt_ctf_field_string *string = container_of(field,
2709 struct bt_ctf_field_string, parent);
2710 struct bt_ctf_field_type *character_type =
2711 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
fc25abce
PP
2712 struct bt_ctf_field *character;
2713
2714 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64 ", "
2715 "native-bo=%s", field, pos->offset,
2716 bt_ctf_byte_order_string(native_byte_order));
2717
2718 BT_LOGV_STR("Creating character field from string field's character field type.");
2719 character = bt_ctf_field_create(character_type);
273b65be
JG
2720
2721 for (i = 0; i < string->payload->len + 1; i++) {
fc25abce
PP
2722 const uint64_t chr = (uint64_t) string->payload->str[i];
2723
2724 ret = bt_ctf_field_unsigned_integer_set_value(character, chr);
273b65be 2725 if (ret) {
b3376dd9 2726 BT_LOGW("Cannot set character field's value: "
fc25abce
PP
2727 "pos-offset=%" PRId64 ", field-addr=%p, "
2728 "index=%" PRId64 ", char-int=%" PRIu64,
2729 pos->offset, character, i, chr);
273b65be
JG
2730 goto end;
2731 }
2732
fc25abce
PP
2733 BT_LOGV("Serializing string field's character field: "
2734 "pos-offset=%" PRId64 ", field-addr=%p, "
2735 "index=%" PRId64 ", char-int=%" PRIu64,
2736 pos->offset, character, i, chr);
dc3fffef
PP
2737 ret = bt_ctf_field_integer_serialize(character, pos,
2738 native_byte_order);
273b65be 2739 if (ret) {
b3376dd9 2740 BT_LOGW_STR("Cannot serialize character field.");
273b65be
JG
2741 goto end;
2742 }
2743 }
2744end:
83509119
JG
2745 bt_put(character);
2746 bt_put(character_type);
273b65be
JG
2747 return ret;
2748}
2749
87d43dc1
JG
2750static
2751int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2752 struct bt_ctf_field *dst)
2753{
2754 struct bt_ctf_field_integer *integer_src, *integer_dst;
2755
fc25abce
PP
2756 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
2757 src, dst);
87d43dc1 2758 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
8bfa3f9c 2759 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
dc3fffef 2760 integer_dst->payload = integer_src->payload;
fc25abce 2761 BT_LOGD_STR("Copied integer field.");
87d43dc1
JG
2762 return 0;
2763}
2764
2765static
2766int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2767 struct bt_ctf_field *dst)
2768{
2769 int ret = 0;
2770 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2771
fc25abce
PP
2772 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
2773 src, dst);
87d43dc1
JG
2774 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2775 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2776
2777 if (enum_src->payload) {
fc25abce 2778 BT_LOGD_STR("Copying enumeration field's payload field.");
87d43dc1
JG
2779 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2780 if (!enum_dst->payload) {
fc25abce 2781 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
87d43dc1
JG
2782 ret = -1;
2783 goto end;
2784 }
2785 }
fc25abce
PP
2786
2787 BT_LOGD_STR("Copied enumeration field.");
87d43dc1
JG
2788end:
2789 return ret;
2790}
2791
2792static
2793int bt_ctf_field_floating_point_copy(
2794 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2795{
2796 struct bt_ctf_field_floating_point *float_src, *float_dst;
2797
fc25abce
PP
2798 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2799 src, dst);
87d43dc1
JG
2800 float_src = container_of(src, struct bt_ctf_field_floating_point,
2801 parent);
2802 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2803 parent);
dc3fffef 2804 float_dst->payload = float_src->payload;
fc25abce 2805 BT_LOGD_STR("Copied floating point number field.");
87d43dc1
JG
2806 return 0;
2807}
2808
2809static
2810int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2811 struct bt_ctf_field *dst)
2812{
fc25abce
PP
2813 int ret = 0;
2814 int64_t i;
87d43dc1
JG
2815 struct bt_ctf_field_structure *struct_src, *struct_dst;
2816
fc25abce
PP
2817 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2818 src, dst);
87d43dc1
JG
2819 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2820 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2821
8bfa3f9c 2822 /* This field_name_to_index HT is owned by the structure field type */
87d43dc1 2823 struct_dst->field_name_to_index = struct_src->field_name_to_index;
8bfa3f9c 2824 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
87d43dc1
JG
2825
2826 for (i = 0; i < struct_src->fields->len; i++) {
50fd95bf
PP
2827 struct bt_ctf_field *field =
2828 g_ptr_array_index(struct_src->fields, i);
2829 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2830
50fd95bf 2831 if (field) {
32e87ceb 2832 BT_LOGD("Copying structure field's field: src-field-addr=%p"
fc25abce 2833 "index=%" PRId64, field, i);
50fd95bf 2834 field_copy = bt_ctf_field_copy(field);
50fd95bf 2835 if (!field_copy) {
fc25abce
PP
2836 BT_LOGE("Cannot copy structure field's field: "
2837 "src-field-addr=%p, index=%" PRId64,
2838 field, i);
50fd95bf
PP
2839 ret = -1;
2840 goto end;
2841 }
87d43dc1 2842 }
50fd95bf 2843
8bfa3f9c 2844 g_ptr_array_index(struct_dst->fields, i) = field_copy;
87d43dc1 2845 }
fc25abce
PP
2846
2847 BT_LOGD_STR("Copied structure field.");
2848
87d43dc1
JG
2849end:
2850 return ret;
2851}
2852
2853static
2854int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2855 struct bt_ctf_field *dst)
2856{
2857 int ret = 0;
2858 struct bt_ctf_field_variant *variant_src, *variant_dst;
2859
fc25abce
PP
2860 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2861 src, dst);
87d43dc1
JG
2862 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2863 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2864
2865 if (variant_src->tag) {
fc25abce 2866 BT_LOGD_STR("Copying variant field's tag field.");
87d43dc1
JG
2867 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2868 if (!variant_dst->tag) {
fc25abce 2869 BT_LOGE_STR("Cannot copy variant field's tag field.");
87d43dc1
JG
2870 ret = -1;
2871 goto end;
2872 }
2873 }
2874 if (variant_src->payload) {
fc25abce 2875 BT_LOGD_STR("Copying variant field's payload field.");
87d43dc1
JG
2876 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2877 if (!variant_dst->payload) {
fc25abce 2878 BT_LOGE_STR("Cannot copy variant field's payload field.");
87d43dc1
JG
2879 ret = -1;
2880 goto end;
2881 }
2882 }
fc25abce
PP
2883
2884 BT_LOGD_STR("Copied variant field.");
2885
87d43dc1
JG
2886end:
2887 return ret;
2888}
2889
2890static
2891int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2892 struct bt_ctf_field *dst)
2893{
fc25abce
PP
2894 int ret = 0;
2895 int64_t i;
87d43dc1
JG
2896 struct bt_ctf_field_array *array_src, *array_dst;
2897
fc25abce
PP
2898 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2899 src, dst);
87d43dc1
JG
2900 array_src = container_of(src, struct bt_ctf_field_array, parent);
2901 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2902
8bfa3f9c 2903 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
87d43dc1 2904 for (i = 0; i < array_src->elements->len; i++) {
50fd95bf
PP
2905 struct bt_ctf_field *field =
2906 g_ptr_array_index(array_src->elements, i);
2907 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2908
50fd95bf 2909 if (field) {
fc25abce
PP
2910 BT_LOGD("Copying array field's element field: field-addr=%p, "
2911 "index=%" PRId64, field, i);
50fd95bf 2912 field_copy = bt_ctf_field_copy(field);
50fd95bf 2913 if (!field_copy) {
fc25abce
PP
2914 BT_LOGE("Cannot copy array field's element field: "
2915 "src-field-addr=%p, index=%" PRId64,
2916 field, i);
50fd95bf
PP
2917 ret = -1;
2918 goto end;
2919 }
87d43dc1 2920 }
50fd95bf 2921
8bfa3f9c 2922 g_ptr_array_index(array_dst->elements, i) = field_copy;
87d43dc1 2923 }
fc25abce
PP
2924
2925 BT_LOGD_STR("Copied array field.");
2926
87d43dc1
JG
2927end:
2928 return ret;
2929}
2930
2931static
2932int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2933 struct bt_ctf_field *dst)
2934{
fc25abce
PP
2935 int ret = 0;
2936 int64_t i;
87d43dc1 2937 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
59ab494d
PP
2938 struct bt_ctf_field *src_length;
2939 struct bt_ctf_field *dst_length;
87d43dc1 2940
fc25abce
PP
2941 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2942 src, dst);
87d43dc1
JG
2943 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2944 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2945
59ab494d 2946 src_length = bt_ctf_field_sequence_get_length(src);
59ab494d
PP
2947 if (!src_length) {
2948 /* no length set yet: keep destination sequence empty */
2949 goto end;
2950 }
2951
2952 /* copy source length */
fc25abce 2953 BT_LOGD_STR("Copying sequence field's length field.");
59ab494d 2954 dst_length = bt_ctf_field_copy(src_length);
fc25abce 2955 BT_PUT(src_length);
59ab494d 2956 if (!dst_length) {
fc25abce 2957 BT_LOGE_STR("Cannot copy sequence field's length field.");
59ab494d
PP
2958 ret = -1;
2959 goto end;
2960 }
2961
2962 /* this will initialize the destination sequence's internal array */
2963 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
83509119 2964 bt_put(dst_length);
59ab494d 2965 if (ret) {
fc25abce
PP
2966 BT_LOGE("Cannot set sequence field copy's length field: "
2967 "dst-length-field-addr=%p", dst_length);
2968 ret = -1;
59ab494d
PP
2969 goto end;
2970 }
2971
2972 assert(sequence_dst->elements->len == sequence_src->elements->len);
2973
87d43dc1 2974 for (i = 0; i < sequence_src->elements->len; i++) {
50fd95bf
PP
2975 struct bt_ctf_field *field =
2976 g_ptr_array_index(sequence_src->elements, i);
2977 struct bt_ctf_field *field_copy = NULL;
87d43dc1 2978
50fd95bf 2979 if (field) {
fc25abce
PP
2980 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2981 "index=%" PRId64, field, i);
50fd95bf 2982 field_copy = bt_ctf_field_copy(field);
50fd95bf 2983 if (!field_copy) {
fc25abce
PP
2984 BT_LOGE("Cannot copy sequence field's element field: "
2985 "src-field-addr=%p, index=%" PRId64,
2986 field, i);
50fd95bf
PP
2987 ret = -1;
2988 goto end;
2989 }
87d43dc1 2990 }
59ab494d 2991
8bfa3f9c 2992 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
87d43dc1 2993 }
fc25abce
PP
2994
2995 BT_LOGD_STR("Copied sequence field.");
2996
87d43dc1
JG
2997end:
2998 return ret;
2999}
3000
3001static
3002int bt_ctf_field_string_copy(struct bt_ctf_field *src,
3003 struct bt_ctf_field *dst)
3004{
3005 int ret = 0;
3006 struct bt_ctf_field_string *string_src, *string_dst;
3007
fc25abce
PP
3008 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
3009 src, dst);
87d43dc1
JG
3010 string_src = container_of(src, struct bt_ctf_field_string, parent);
3011 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
3012
3013 if (string_src->payload) {
3014 string_dst->payload = g_string_new(string_src->payload->str);
3015 if (!string_dst->payload) {
fc25abce 3016 BT_LOGE_STR("Failed to allocate a GString.");
87d43dc1
JG
3017 ret = -1;
3018 goto end;
3019 }
3020 }
fc25abce
PP
3021
3022 BT_LOGD_STR("Copied string field.");
3023
87d43dc1
JG
3024end:
3025 return ret;
3026}
3027
273b65be 3028static
dc3fffef 3029int increase_packet_size(struct bt_ctf_stream_pos *pos)
273b65be
JG
3030{
3031 int ret;
3032
3033 assert(pos);
fc25abce
PP
3034 BT_LOGV("Increasing packet size: pos-offset=%" PRId64 ", "
3035 "cur-packet-size=%" PRIu64,
3036 pos->offset, pos->packet_size);
273b65be
JG
3037 ret = munmap_align(pos->base_mma);
3038 if (ret) {
c606e638
PP
3039 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
3040 ": ret=%d", ret);
273b65be
JG
3041 goto end;
3042 }
3043
3044 pos->packet_size += PACKET_LEN_INCREMENT;
d9548894
MD
3045 do {
3046 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
3047 pos->packet_size / CHAR_BIT);
3048 } while (ret == EINTR);
273b65be 3049 if (ret) {
c606e638
PP
3050 BT_LOGE_ERRNO("Failed to preallocate memory space",
3051 ": ret=%d", ret);
d9548894
MD
3052 errno = EINTR;
3053 ret = -1;
273b65be
JG
3054 goto end;
3055 }
3056
3057 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
3058 pos->flags, pos->fd, pos->mmap_offset);
3059 if (pos->base_mma == MAP_FAILED) {
c606e638
PP
3060 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
3061 ": ret=%d", ret);
273b65be
JG
3062 ret = -1;
3063 }
fc25abce
PP
3064
3065 BT_LOGV("Increased packet size: pos-offset=%" PRId64 ", "
3066 "new-packet-size=%" PRIu64,
3067 pos->offset, pos->packet_size);
b3376dd9
PP
3068 assert(pos->packet_size % 8 == 0);
3069
273b65be
JG
3070end:
3071 return ret;
3072}
918be005
PP
3073
3074static
3075void generic_field_freeze(struct bt_ctf_field *field)
3076{
d990a4fb 3077 field->frozen = true;
918be005
PP
3078}
3079
3080static
3081void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
3082{
3083 struct bt_ctf_field_enumeration *enum_field =
3084 container_of(field, struct bt_ctf_field_enumeration, parent);
3085
fc25abce
PP
3086 BT_LOGD("Freezing enumeration field object: addr=%p", field);
3087 BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field->payload);
918be005
PP
3088 bt_ctf_field_freeze(enum_field->payload);
3089 generic_field_freeze(field);
3090}
3091
3092static
3093void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
3094{
fc25abce 3095 int64_t i;
918be005
PP
3096 struct bt_ctf_field_structure *structure_field =
3097 container_of(field, struct bt_ctf_field_structure, parent);
3098
fc25abce
PP
3099 BT_LOGD("Freezing structure field object: addr=%p", field);
3100
918be005
PP
3101 for (i = 0; i < structure_field->fields->len; i++) {
3102 struct bt_ctf_field *field =
3103 g_ptr_array_index(structure_field->fields, i);
3104
fc25abce
PP
3105 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
3106 field, i);
918be005
PP
3107 bt_ctf_field_freeze(field);
3108 }
3109
3110 generic_field_freeze(field);
3111}
3112
3113static
3114void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
3115{
3116 struct bt_ctf_field_variant *variant_field =
3117 container_of(field, struct bt_ctf_field_variant, parent);
3118
fc25abce
PP
3119 BT_LOGD("Freezing variant field object: addr=%p", field);
3120 BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field->tag);
918be005 3121 bt_ctf_field_freeze(variant_field->tag);
fc25abce 3122 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field->payload);
918be005
PP
3123 bt_ctf_field_freeze(variant_field->payload);
3124 generic_field_freeze(field);
3125}
3126
3127static
3128void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
3129{
fc25abce 3130 int64_t i;
918be005
PP
3131 struct bt_ctf_field_array *array_field =
3132 container_of(field, struct bt_ctf_field_array, parent);
3133
fc25abce
PP
3134 BT_LOGD("Freezing array field object: addr=%p", field);
3135
918be005 3136 for (i = 0; i < array_field->elements->len; i++) {
fc25abce 3137 struct bt_ctf_field *elem_field =
918be005
PP
3138 g_ptr_array_index(array_field->elements, i);
3139
fc25abce
PP
3140 BT_LOGD("Freezing array field object's element field: "
3141 "element-field-addr=%p, index=%" PRId64,
3142 elem_field, i);
3143 bt_ctf_field_freeze(elem_field);
918be005
PP
3144 }
3145
3146 generic_field_freeze(field);
3147}
3148
3149static
3150void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
3151{
fc25abce 3152 int64_t i;
918be005
PP
3153 struct bt_ctf_field_sequence *sequence_field =
3154 container_of(field, struct bt_ctf_field_sequence, parent);
3155
fc25abce
PP
3156 BT_LOGD("Freezing sequence field object: addr=%p", field);
3157 BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p",
3158 sequence_field->length);
918be005
PP
3159 bt_ctf_field_freeze(sequence_field->length);
3160
3161 for (i = 0; i < sequence_field->elements->len; i++) {
fc25abce 3162 struct bt_ctf_field *elem_field =
918be005
PP
3163 g_ptr_array_index(sequence_field->elements, i);
3164
fc25abce
PP
3165 BT_LOGD("Freezing sequence field object's element field: "
3166 "element-field-addr=%p, index=%" PRId64,
3167 elem_field, i);
3168 bt_ctf_field_freeze(elem_field);
918be005
PP
3169 }
3170
3171 generic_field_freeze(field);
3172}
3173
3174BT_HIDDEN
3175void bt_ctf_field_freeze(struct bt_ctf_field *field)
3176{
1487a16a 3177 enum bt_ctf_field_type_id type_id;
35f77de4 3178
918be005
PP
3179 if (!field) {
3180 goto end;
3181 }
3182
fc25abce 3183 if (field->frozen) {
35f77de4
JG
3184 goto end;
3185 }
918be005 3186
fc25abce
PP
3187 BT_LOGD("Freezing field object: addr=%p", field);
3188 type_id = bt_ctf_field_get_type_id(field);
3189 assert(type_id > BT_CTF_FIELD_TYPE_ID_UNKNOWN &&
3190 type_id < BT_CTF_NR_TYPE_IDS);
35f77de4 3191 field_freeze_funcs[type_id](field);
918be005
PP
3192end:
3193 return;
3194}
76f869ab
JG
3195
3196static
c55a9f58 3197bt_bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
76f869ab
JG
3198{
3199 return field && field->payload_set;
3200}
3201
3202static
c55a9f58 3203bt_bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
76f869ab 3204{
c55a9f58 3205 bt_bool is_set = BT_FALSE;
76f869ab
JG
3206 struct bt_ctf_field_enumeration *enumeration;
3207
3208 if (!field) {
3209 goto end;
3210 }
3211
3212 enumeration = container_of(field, struct bt_ctf_field_enumeration,
3213 parent);
3214 if (!enumeration->payload) {
3215 goto end;
3216 }
3217
3218 is_set = bt_ctf_field_is_set(enumeration->payload);
3219end:
3220 return is_set;
3221}
3222
3223static
c55a9f58 3224bt_bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
76f869ab 3225{
c55a9f58 3226 bt_bool is_set = BT_FALSE;
76f869ab
JG
3227 size_t i;
3228 struct bt_ctf_field_structure *structure;
3229
3230 if (!field) {
3231 goto end;
3232 }
3233
3234 structure = container_of(field, struct bt_ctf_field_structure, parent);
3235 for (i = 0; i < structure->fields->len; i++) {
3236 is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
3237 if (!is_set) {
3238 goto end;
3239 }
3240 }
3241end:
3242 return is_set;
3243}
3244
3245static
c55a9f58 3246bt_bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
76f869ab 3247{
c55a9f58 3248 bt_bool is_set = BT_FALSE;
76f869ab
JG
3249 struct bt_ctf_field_variant *variant;
3250
3251 if (!field) {
3252 goto end;
3253 }
3254
3255 variant = container_of(field, struct bt_ctf_field_variant, parent);
3256 is_set = bt_ctf_field_is_set(variant->payload);
3257end:
3258 return is_set;
3259}
3260
3261static
c55a9f58 3262bt_bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
76f869ab
JG
3263{
3264 size_t i;
c55a9f58 3265 bt_bool is_set = BT_FALSE;
76f869ab
JG
3266 struct bt_ctf_field_array *array;
3267
3268 if (!field) {
3269 goto end;
3270 }
3271
3272 array = container_of(field, struct bt_ctf_field_array, parent);
3273 for (i = 0; i < array->elements->len; i++) {
24626e8b 3274 is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
76f869ab
JG
3275 if (!is_set) {
3276 goto end;
3277 }
3278 }
3279end:
3280 return is_set;
3281}
3282
3283static
c55a9f58 3284bt_bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
76f869ab
JG
3285{
3286 size_t i;
c55a9f58 3287 bt_bool is_set = BT_FALSE;
76f869ab
JG
3288 struct bt_ctf_field_sequence *sequence;
3289
3290 if (!field) {
3291 goto end;
3292 }
3293
3294 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
3295 for (i = 0; i < sequence->elements->len; i++) {
3296 is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
3297 if (!is_set) {
3298 goto end;
3299 }
3300 }
3301end:
3302 return is_set;
3303}
This page took 0.201266 seconds and 4 git commands to generate.