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