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