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