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