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