fields.c: get non-existing field: log level WARN -> VERBOSE
[babeltrace.git] / lib / ctf-ir / fields.c
1 /*
2 * fields.c
3 *
4 * Babeltrace CTF IR - Event Fields
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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
29 #define BT_LOG_TAG "FIELDS"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/ctf-ir/fields-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-writer/serialize-internal.h>
35 #include <babeltrace/object-internal.h>
36 #include <babeltrace/ref.h>
37 #include <babeltrace/compiler-internal.h>
38 #include <babeltrace/compat/fcntl-internal.h>
39 #include <babeltrace/align-internal.h>
40 #include <inttypes.h>
41
42 #define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
43
44 static
45 struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
46 static
47 struct bt_ctf_field *bt_ctf_field_enumeration_create(
48 struct bt_ctf_field_type *);
49 static
50 struct bt_ctf_field *bt_ctf_field_floating_point_create(
51 struct bt_ctf_field_type *);
52 static
53 struct bt_ctf_field *bt_ctf_field_structure_create(
54 struct bt_ctf_field_type *);
55 static
56 struct bt_ctf_field *bt_ctf_field_variant_create(
57 struct bt_ctf_field_type *);
58 static
59 struct bt_ctf_field *bt_ctf_field_array_create(
60 struct bt_ctf_field_type *);
61 static
62 struct bt_ctf_field *bt_ctf_field_sequence_create(
63 struct bt_ctf_field_type *);
64 static
65 struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
66
67 static
68 void bt_ctf_field_destroy(struct bt_object *);
69 static
70 void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
71 static
72 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
73 static
74 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
75 static
76 void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
77 static
78 void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
79 static
80 void bt_ctf_field_array_destroy(struct bt_ctf_field *);
81 static
82 void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
83 static
84 void bt_ctf_field_string_destroy(struct bt_ctf_field *);
85
86 static
87 int bt_ctf_field_generic_validate(struct bt_ctf_field *);
88 static
89 int bt_ctf_field_structure_validate(struct bt_ctf_field *);
90 static
91 int bt_ctf_field_variant_validate(struct bt_ctf_field *);
92 static
93 int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
94 static
95 int bt_ctf_field_array_validate(struct bt_ctf_field *);
96 static
97 int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
98
99 static
100 int bt_ctf_field_generic_reset(struct bt_ctf_field *);
101 static
102 int bt_ctf_field_structure_reset(struct bt_ctf_field *);
103 static
104 int bt_ctf_field_variant_reset(struct bt_ctf_field *);
105 static
106 int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
107 static
108 int bt_ctf_field_array_reset(struct bt_ctf_field *);
109 static
110 int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
111 static
112 int bt_ctf_field_string_reset(struct bt_ctf_field *);
113
114 static
115 int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
116 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
117 static
118 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
119 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
120 static
121 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
122 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
123 static
124 int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
125 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
126 static
127 int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
128 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
129 static
130 int bt_ctf_field_array_serialize(struct bt_ctf_field *,
131 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
132 static
133 int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
134 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
135 static
136 int bt_ctf_field_string_serialize(struct bt_ctf_field *,
137 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
138
139 static
140 int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
141 static
142 int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
143 static
144 int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
145 struct bt_ctf_field *);
146 static
147 int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
148 static
149 int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
150 static
151 int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
152 static
153 int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
154 static
155 int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
156
157 static
158 void generic_field_freeze(struct bt_ctf_field *);
159 static
160 void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
161 static
162 void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
163 static
164 void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
165 static
166 void bt_ctf_field_array_freeze(struct bt_ctf_field *);
167 static
168 void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
169
170 static
171 bt_bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
172 static
173 bt_bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
174 static
175 bt_bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
176 static
177 bt_bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
178 static
179 bt_bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
180 static
181 bt_bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
182
183 static
184 int increase_packet_size(struct bt_ctf_stream_pos *pos);
185
186 static
187 struct bt_ctf_field *(* const field_create_funcs[])(
188 struct bt_ctf_field_type *) = {
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] =
192 bt_ctf_field_floating_point_create,
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,
198 };
199
200 static
201 void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
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] =
205 bt_ctf_field_floating_point_destroy,
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,
211 };
212
213 static
214 int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
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,
223 };
224
225 static
226 int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
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,
235 };
236
237 static
238 int (* const field_serialize_funcs[])(struct bt_ctf_field *,
239 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order) = {
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] =
243 bt_ctf_field_floating_point_serialize,
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,
249 };
250
251 static
252 int (* const field_copy_funcs[])(struct bt_ctf_field *,
253 struct bt_ctf_field *) = {
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,
262 };
263
264 static
265 void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
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,
274 };
275
276 static
277 bt_bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
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,
286 };
287
288 struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
289 {
290 struct bt_ctf_field *field = NULL;
291 enum bt_ctf_field_type_id type_id;
292 int ret;
293
294 if (!type) {
295 BT_LOGW_STR("Invalid parameter: field type is NULL.");
296 goto error;
297 }
298
299 type_id = bt_ctf_field_type_get_type_id(type);
300 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN ||
301 type_id >= BT_CTF_NR_TYPE_IDS) {
302 BT_LOGW("Invalid parameter: unknown field type ID: "
303 "ft-addr=%p, ft-id=%d", type, type_id);
304 goto error;
305 }
306
307 /* Field class MUST be valid */
308 ret = bt_ctf_field_type_validate(type);
309 if (ret) {
310 /* Invalid */
311 BT_LOGW("Invalid parameter: field type is invalid: "
312 "ft-addr=%p", type);
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);
323 bt_get(type);
324 bt_object_init(field, bt_ctf_field_destroy);
325 field->type = type;
326 error:
327 return field;
328 }
329
330 /* Pre-2.0 CTF writer backward compatibility */
331 void bt_ctf_field_get(struct bt_ctf_field *field)
332 {
333 bt_get(field);
334 }
335
336 /* Pre-2.0 CTF writer backward compatibility */
337 void bt_ctf_field_put(struct bt_ctf_field *field)
338 {
339 bt_put(field);
340 }
341
342 struct 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) {
347 BT_LOGW_STR("Invalid parameter: field is NULL.");
348 goto end;
349 }
350
351 ret = field->type;
352 bt_get(ret);
353 end:
354 return ret;
355 }
356
357 enum bt_ctf_field_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
358 {
359 enum bt_ctf_field_type_id ret = BT_CTF_FIELD_TYPE_ID_UNKNOWN;
360
361 if (!field) {
362 BT_LOGW_STR("Invalid parameter: field is NULL.");
363 goto end;
364 }
365
366 ret = bt_ctf_field_type_get_type_id(field->type);
367 end:
368 return ret;
369 }
370
371 bt_bool bt_ctf_field_is_integer(struct bt_ctf_field *field)
372 {
373 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_INTEGER;
374 }
375
376 bt_bool bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
377 {
378 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_FLOAT;
379 }
380
381 bt_bool bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
382 {
383 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_ENUM;
384 }
385
386 bt_bool bt_ctf_field_is_string(struct bt_ctf_field *field)
387 {
388 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_STRING;
389 }
390
391 bt_bool bt_ctf_field_is_structure(struct bt_ctf_field *field)
392 {
393 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_STRUCT;
394 }
395
396 bt_bool bt_ctf_field_is_array(struct bt_ctf_field *field)
397 {
398 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_ARRAY;
399 }
400
401 bt_bool bt_ctf_field_is_sequence(struct bt_ctf_field *field)
402 {
403 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_SEQUENCE;
404 }
405
406 bt_bool bt_ctf_field_is_variant(struct bt_ctf_field *field)
407 {
408 return bt_ctf_field_get_type_id(field) == BT_CTF_FIELD_TYPE_ID_VARIANT;
409 }
410
411 struct 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) {
418 BT_LOGW_STR("Invalid parameter: field is NULL.");
419 goto end;
420 }
421
422 if (bt_ctf_field_type_get_type_id(field->type) !=
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));
428 goto end;
429 }
430
431 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
432 ret = sequence->length;
433 bt_get(ret);
434 end:
435 return ret;
436 }
437
438 int 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
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);
462 ret = -1;
463 goto end;
464 }
465
466 if (bt_ctf_field_type_get_type_id(length_field->type) !=
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));
472 ret = -1;
473 goto end;
474 }
475
476 length_type = container_of(length_field->type,
477 struct bt_ctf_field_type_integer, parent);
478 /* The length field must be unsigned */
479 if (length_type->is_signed) {
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);
484 ret = -1;
485 goto end;
486 }
487
488 length = container_of(length_field, struct bt_ctf_field_integer,
489 parent);
490 sequence_length = length->payload.unsignd;
491 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
492 if (sequence->elements) {
493 g_ptr_array_free(sequence->elements, TRUE);
494 bt_put(sequence->length);
495 }
496
497 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
498 if (!sequence->elements) {
499 BT_LOGE_STR("Failed to allocate a GPtrArray.");
500 ret = -1;
501 goto end;
502 }
503
504 g_ptr_array_set_free_func(sequence->elements,
505 (GDestroyNotify) bt_put);
506 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
507 bt_get(length_field);
508 sequence->length = length_field;
509 end:
510 return ret;
511 }
512
513 struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
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;
519 struct bt_ctf_field_type *field_type = NULL;
520 size_t index;
521
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) !=
533 BT_CTF_FIELD_TYPE_ID_STRUCT) {
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));
538 goto error;
539 }
540
541 field_quark = g_quark_from_string(name);
542 structure = container_of(field, struct bt_ctf_field_structure, parent);
543 field_type =
544 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
545 name);
546 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
547 GUINT_TO_POINTER(field_quark),
548 NULL, (gpointer *)&index)) {
549 BT_LOGV("Invalid parameter: no such field in structure field's type: "
550 "struct-field-addr=%p, struct-ft-addr=%p, "
551 "field-ft-addr=%p, name=\"%s\"",
552 field, field->type, field_type, name);
553 goto error;
554 }
555
556 if (structure->fields->pdata[index]) {
557 new_field = structure->fields->pdata[index];
558 goto end;
559 }
560
561 /* We don't want to modify this field if it's frozen */
562 if (field->frozen) {
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);
571 goto end;
572 }
573
574 new_field = bt_ctf_field_create(field_type);
575 if (!new_field) {
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);
580 goto error;
581 }
582
583 structure->fields->pdata[index] = new_field;
584 end:
585 bt_get(new_field);
586 error:
587 if (field_type) {
588 bt_put(field_type);
589 }
590 return new_field;
591 }
592
593 struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
594 struct bt_ctf_field *field, uint64_t index)
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
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));
614 goto end;
615 }
616
617 structure = container_of(field, struct bt_ctf_field_structure, parent);
618 if (index >= structure->fields->len) {
619 BT_LOGW("Invalid parameter: index is out of bounds: "
620 "addr=%p, index=%" PRIu64 ", count=%u",
621 field, index, structure->fields->len);
622 goto error;
623 }
624
625 ret_field = structure->fields->pdata[index];
626 if (ret_field) {
627 goto end;
628 }
629
630 /* We don't want to modify this field if it's frozen */
631 if (field->frozen) {
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);
640 goto end;
641 }
642
643 /* Field has not been instanciated yet, create it */
644 structure_type = bt_ctf_field_get_type(field);
645 assert(structure_type);
646 ret = bt_ctf_field_type_structure_get_field(structure_type,
647 &field_name, &field_type, index);
648 assert(ret == 0);
649 bt_put(structure_type);
650 ret_field = bt_ctf_field_create(field_type);
651 if (!ret_field) {
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);
656 goto error;
657 }
658
659 structure->fields->pdata[index] = ret_field;
660 end:
661 bt_get(ret_field);
662 error:
663 bt_put(field_type);
664 return ret_field;
665 }
666
667 int 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;
673 struct bt_ctf_field_type *expected_field_type = NULL;
674 size_t index;
675
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) !=
695 BT_CTF_FIELD_TYPE_ID_STRUCT) {
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));
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);
706 expected_field_type =
707 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
708 name);
709
710 if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
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);
715 ret = -1;
716 goto end;
717 }
718
719 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
720 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
721 BT_LOGV("Invalid parameter: no such field in structure field's type: "
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;
726 goto end;
727 }
728
729 if (structure->fields->pdata[index]) {
730 bt_put(structure->fields->pdata[index]);
731 }
732
733 structure->fields->pdata[index] = value;
734 bt_get(value);
735 end:
736 if (expected_field_type) {
737 bt_put(expected_field_type);
738 }
739 return ret;
740 }
741
742 struct 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;
746 struct bt_ctf_field_type *field_type = NULL;
747 struct bt_ctf_field_array *array;
748
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));
760 goto end;
761 }
762
763 array = container_of(field, struct bt_ctf_field_array, parent);
764 if (index >= array->elements->len) {
765 BT_LOGW("Invalid parameter: index is out of bounds: "
766 "addr=%p, index=%" PRIu64 ", count=%u",
767 field, index, array->elements->len);
768 goto end;
769 }
770
771 field_type = bt_ctf_field_type_array_get_element_type(field->type);
772 if (array->elements->pdata[(size_t)index]) {
773 new_field = array->elements->pdata[(size_t)index];
774 goto end;
775 }
776
777 /* We don't want to modify this field if it's frozen */
778 if (field->frozen) {
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);
787 goto end;
788 }
789
790 new_field = bt_ctf_field_create(field_type);
791 array->elements->pdata[(size_t)index] = new_field;
792 end:
793 if (field_type) {
794 bt_put(field_type);
795 }
796 if (new_field) {
797 bt_get(new_field);
798 }
799 return new_field;
800 }
801
802 struct 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;
806 struct bt_ctf_field_type *field_type = NULL;
807 struct bt_ctf_field_sequence *sequence;
808
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));
820 goto end;
821 }
822
823 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
824 if (!sequence->elements) {
825 BT_LOGV("Sequence field's elements do not exist: addr=%p",
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);
834 goto end;
835 }
836
837 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
838 if (sequence->elements->pdata[(size_t) index]) {
839 new_field = sequence->elements->pdata[(size_t) index];
840 goto end;
841 }
842
843 /* We don't want to modify this field if it's frozen */
844 if (field->frozen) {
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);
853 goto end;
854 }
855
856 new_field = bt_ctf_field_create(field_type);
857 sequence->elements->pdata[(size_t) index] = new_field;
858 end:
859 if (field_type) {
860 bt_put(field_type);
861 }
862 if (new_field) {
863 bt_get(new_field);
864 }
865 return new_field;
866 }
867
868 struct 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
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) !=
899 BT_CTF_FIELD_TYPE_ID_ENUM) {
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));
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
918 if (bt_ctf_field_validate(tag_field) < 0) {
919 BT_LOGW("Invalid parameter: tag field is invalid: "
920 "variant-field-addr=%p, tag-field-addr=%p",
921 field, tag_field);
922 goto end;
923 }
924
925 tag_enum_value = tag_enum_integer->payload.signd;
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);
939 assert(cur_tag_container);
940 cur_tag_enum_integer = container_of(cur_tag_container,
941 struct bt_ctf_field_integer, parent);
942 bt_put(cur_tag_container);
943 cur_tag_value = cur_tag_enum_integer->payload.signd;
944
945 if (cur_tag_value == tag_enum_value) {
946 new_field = variant->payload;
947 bt_get(new_field);
948 goto end;
949 }
950 }
951
952 /* We don't want to modify this field if it's frozen */
953 if (field->frozen) {
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);
963 goto end;
964 }
965
966 field_type = bt_ctf_field_type_variant_get_field_type_signed(
967 variant_type, tag_enum_value);
968 if (!field_type) {
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);
973 goto end;
974 }
975
976 new_field = bt_ctf_field_create(field_type);
977 if (!new_field) {
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);
981 goto end;
982 }
983
984 bt_put(variant->tag);
985 bt_put(variant->payload);
986 bt_get(new_field);
987 bt_get(tag_field);
988 variant->tag = tag_field;
989 variant->payload = new_field;
990 end:
991 bt_put(tag_enum);
992 return new_field;
993 }
994
995 struct 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
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) !=
1007 BT_CTF_FIELD_TYPE_ID_VARIANT) {
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));
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;
1020 bt_get(current_field);
1021 goto end;
1022 }
1023
1024 end:
1025 return current_field;
1026 }
1027
1028 struct 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
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) !=
1040 BT_CTF_FIELD_TYPE_ID_VARIANT) {
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));
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 }
1053 end:
1054 return tag;
1055 }
1056
1057 struct 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
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));
1074 goto end;
1075 }
1076
1077 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1078 parent);
1079 if (!enumeration->payload) {
1080 /* We don't want to modify this field if it's frozen */
1081 if (field->frozen) {
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);
1091 goto end;
1092 }
1093
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;
1102 bt_get(container);
1103 end:
1104 return container;
1105 }
1106
1107 struct bt_ctf_field_type_enumeration_mapping_iterator *
1108 bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *field)
1109 {
1110 int ret;
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;
1114 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
1115
1116 container = bt_ctf_field_enumeration_get_container(field);
1117 if (!container) {
1118 BT_LOGW("Invalid parameter: enumeration field has no container field: "
1119 "addr=%p", field);
1120 goto end;
1121 }
1122
1123 container_type = bt_ctf_field_get_type(container);
1124 assert(container_type);
1125 integer_type = container_of(container_type,
1126 struct bt_ctf_field_type_integer, parent);
1127
1128 if (!integer_type->is_signed) {
1129 uint64_t value;
1130
1131 ret = bt_ctf_field_unsigned_integer_get_value(container,
1132 &value);
1133 if (ret) {
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);
1137 goto error_put_container_type;
1138 }
1139 iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
1140 field->type, value);
1141 } else {
1142 int64_t value;
1143
1144 ret = bt_ctf_field_signed_integer_get_value(container,
1145 &value);
1146 if (ret) {
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);
1150 goto error_put_container_type;
1151 }
1152 iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
1153 field->type, value);
1154 }
1155
1156 error_put_container_type:
1157 bt_put(container_type);
1158 bt_put(container);
1159 end:
1160 return iter;
1161 }
1162
1163 int 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
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) !=
1189 BT_CTF_FIELD_TYPE_ID_INTEGER) {
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));
1194 ret = -1;
1195 goto end;
1196 }
1197
1198 integer_type = container_of(field->type,
1199 struct bt_ctf_field_type_integer, parent);
1200 if (!integer_type->is_signed) {
1201 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1202 "field-addr=%p, ft-addr=%p", field, field->type);
1203 ret = -1;
1204 goto end;
1205 }
1206
1207 integer = container_of(field,
1208 struct bt_ctf_field_integer, parent);
1209 *value = integer->payload.signd;
1210 end:
1211 return ret;
1212 }
1213
1214 int 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
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) !=
1237 BT_CTF_FIELD_TYPE_ID_INTEGER) {
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));
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);
1249 if (!integer_type->is_signed) {
1250 BT_LOGW("Invalid parameter: integer field's type is not signed: "
1251 "field-addr=%p, ft-addr=%p", field, field->type);
1252 ret = -1;
1253 goto end;
1254 }
1255
1256 size = integer_type->size;
1257 min_value = -(1ULL << (size - 1));
1258 max_value = (1ULL << (size - 1)) - 1;
1259 if (value < min_value || value > max_value) {
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);
1264 ret = -1;
1265 goto end;
1266 }
1267
1268 integer->payload.signd = value;
1269 integer->parent.payload_set = 1;
1270 end:
1271 return ret;
1272 }
1273
1274 int 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
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) !=
1300 BT_CTF_FIELD_TYPE_ID_INTEGER) {
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));
1305 ret = -1;
1306 goto end;
1307 }
1308
1309 integer_type = container_of(field->type,
1310 struct bt_ctf_field_type_integer, parent);
1311 if (integer_type->is_signed) {
1312 BT_LOGW("Invalid parameter: integer field's type is signed: "
1313 "field-addr=%p, ft-addr=%p", field, field->type);
1314 ret = -1;
1315 goto end;
1316 }
1317
1318 integer = container_of(field,
1319 struct bt_ctf_field_integer, parent);
1320 *value = integer->payload.unsignd;
1321 end:
1322 return ret;
1323 }
1324
1325 int 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
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) !=
1348 BT_CTF_FIELD_TYPE_ID_INTEGER) {
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));
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);
1360 if (integer_type->is_signed) {
1361 BT_LOGW("Invalid parameter: integer field's type is signed: "
1362 "field-addr=%p, ft-addr=%p", field, field->type);
1363 ret = -1;
1364 goto end;
1365 }
1366
1367 size = integer_type->size;
1368 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
1369 if (value > max_value) {
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);
1374 ret = -1;
1375 goto end;
1376 }
1377
1378 integer->payload.unsignd = value;
1379 integer->parent.payload_set = 1;
1380 end:
1381 return ret;
1382 }
1383
1384 int 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
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) !=
1409 BT_CTF_FIELD_TYPE_ID_FLOAT) {
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));
1414 ret = -1;
1415 goto end;
1416 }
1417
1418 floating_point = container_of(field,
1419 struct bt_ctf_field_floating_point, parent);
1420 *value = floating_point->payload;
1421 end:
1422 return ret;
1423 }
1424
1425 int 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
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) !=
1445 BT_CTF_FIELD_TYPE_ID_FLOAT) {
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));
1450 ret = -1;
1451 goto end;
1452 }
1453
1454 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1455 parent);
1456 floating_point->payload = value;
1457 floating_point->parent.payload_set = 1;
1458 end:
1459 return ret;
1460 }
1461
1462 const 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
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) !=
1478 BT_CTF_FIELD_TYPE_ID_STRING) {
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));
1483 goto end;
1484 }
1485
1486 string = container_of(field,
1487 struct bt_ctf_field_string, parent);
1488 ret = string->payload->str;
1489 end:
1490 return ret;
1491 }
1492
1493 int 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
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) !=
1519 BT_CTF_FIELD_TYPE_ID_STRING) {
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));
1524 ret = -1;
1525 goto end;
1526 }
1527
1528 string = container_of(field, struct bt_ctf_field_string, parent);
1529 if (string->payload) {
1530 g_string_assign(string->payload, value);
1531 } else {
1532 string->payload = g_string_new(value);
1533 }
1534
1535 string->parent.payload_set = 1;
1536 end:
1537 return ret;
1538 }
1539
1540 int 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
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) !=
1566 BT_CTF_FIELD_TYPE_ID_STRING) {
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));
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
1585 end:
1586 return ret;
1587 }
1588
1589 int 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
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) !=
1617 BT_CTF_FIELD_TYPE_ID_STRING) {
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));
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) {
1637 g_string_append_len(string_field->payload, value,
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
1646 end:
1647 return ret;
1648 }
1649
1650 BT_HIDDEN
1651 int bt_ctf_field_validate(struct bt_ctf_field *field)
1652 {
1653 int ret = 0;
1654 enum bt_ctf_field_type_id type_id;
1655
1656 if (!field) {
1657 BT_LOGD_STR("Invalid parameter: field is NULL.");
1658 ret = -1;
1659 goto end;
1660 }
1661
1662 type_id = bt_ctf_field_type_get_type_id(field->type);
1663 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1664 BT_LOGW("Invalid parameter: unknown field type ID: "
1665 "addr=%p, ft-addr=%p, ft-id=%d",
1666 field, field->type, type_id);
1667 ret = -1;
1668 goto end;
1669 }
1670
1671 ret = field_validate_funcs[type_id](field);
1672 end:
1673 return ret;
1674 }
1675
1676 BT_HIDDEN
1677 int bt_ctf_field_reset(struct bt_ctf_field *field)
1678 {
1679 int ret = 0;
1680 enum bt_ctf_field_type_id type_id;
1681
1682 if (!field) {
1683 BT_LOGD_STR("Invalid parameter: field is NULL.");
1684 ret = -1;
1685 goto end;
1686 }
1687
1688 type_id = bt_ctf_field_type_get_type_id(field->type);
1689 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1690 BT_LOGW("Invalid parameter: unknown field type ID: "
1691 "addr=%p, ft-addr=%p, ft-id=%d",
1692 field, field->type, type_id);
1693 ret = -1;
1694 goto end;
1695 }
1696
1697 ret = field_reset_funcs[type_id](field);
1698 end:
1699 return ret;
1700 }
1701
1702 BT_HIDDEN
1703 int bt_ctf_field_serialize(struct bt_ctf_field *field,
1704 struct bt_ctf_stream_pos *pos,
1705 enum bt_ctf_byte_order native_byte_order)
1706 {
1707 int ret = 0;
1708 enum bt_ctf_field_type_id type_id;
1709
1710 assert(pos);
1711
1712 if (!field) {
1713 BT_LOGD_STR("Invalid parameter: field is NULL.");
1714 ret = -1;
1715 goto end;
1716 }
1717
1718 type_id = bt_ctf_field_type_get_type_id(field->type);
1719 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1720 BT_LOGW("Invalid parameter: unknown field type ID: "
1721 "addr=%p, ft-addr=%p, ft-id=%d",
1722 field, field->type, type_id);
1723 ret = -1;
1724 goto end;
1725 }
1726
1727 ret = field_serialize_funcs[type_id](field, pos, native_byte_order);
1728 end:
1729 return ret;
1730 }
1731
1732
1733 BT_HIDDEN
1734 bt_bool bt_ctf_field_is_set(struct bt_ctf_field *field)
1735 {
1736 bt_bool is_set = BT_FALSE;
1737 enum bt_ctf_field_type_id type_id;
1738
1739 if (!field) {
1740 goto end;
1741 }
1742
1743 type_id = bt_ctf_field_type_get_type_id(field->type);
1744 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
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);
1748 goto end;
1749 }
1750
1751 is_set = field_is_set_funcs[type_id](field);
1752 end:
1753 return is_set;
1754 }
1755
1756 struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1757 {
1758 int ret;
1759 struct bt_ctf_field *copy = NULL;
1760 enum bt_ctf_field_type_id type_id;
1761
1762 if (!field) {
1763 BT_LOGW_STR("Invalid parameter: field is NULL.");
1764 goto end;
1765 }
1766
1767 type_id = bt_ctf_field_type_get_type_id(field->type);
1768 if (type_id <= BT_CTF_FIELD_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
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);
1772 goto end;
1773 }
1774
1775 copy = bt_ctf_field_create(field->type);
1776 if (!copy) {
1777 BT_LOGW("Cannot create field: ft-addr=%p", field->type);
1778 goto end;
1779 }
1780
1781 copy->payload_set = field->payload_set;
1782 ret = field_copy_funcs[type_id](field, copy);
1783 if (ret) {
1784 bt_put(copy);
1785 copy = NULL;
1786 }
1787 end:
1788 return copy;
1789 }
1790
1791 static
1792 struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1793 {
1794 struct bt_ctf_field_integer *integer = g_new0(
1795 struct bt_ctf_field_integer, 1);
1796
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
1806 return integer ? &integer->parent : NULL;
1807 }
1808
1809 static
1810 struct 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
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
1825 return enumeration ? &enumeration->parent : NULL;
1826 }
1827
1828 static
1829 struct 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;
1833
1834 BT_LOGD("Creating floating point number field object: ft-addr=%p", type);
1835 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
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
1844 return floating_point ? &floating_point->parent : NULL;
1845 }
1846
1847 static
1848 struct 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
1857 BT_LOGD("Creating structure field object: ft-addr=%p", type);
1858
1859 if (!structure) {
1860 BT_LOGE_STR("Failed to allocate one structure field.");
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;
1870 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p",
1871 field, type);
1872 end:
1873 return field;
1874 }
1875
1876 static
1877 struct 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);
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
1891 return variant ? &variant->parent : NULL;
1892 }
1893
1894 static
1895 struct 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
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.");
1906 goto error;
1907 }
1908
1909 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1910 array_length = array_type->length;
1911 array->elements = g_ptr_array_sized_new(array_length);
1912 if (!array->elements) {
1913 goto error;
1914 }
1915
1916 g_ptr_array_set_free_func(array->elements,
1917 (GDestroyNotify)bt_ctf_field_put);
1918 g_ptr_array_set_size(array->elements, array_length);
1919 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1920 &array->parent, type);
1921 return &array->parent;
1922 error:
1923 g_free(array);
1924 return NULL;
1925 }
1926
1927 static
1928 struct 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);
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
1943 return sequence ? &sequence->parent : NULL;
1944 }
1945
1946 static
1947 struct 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);
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
1961 return string ? &string->parent : NULL;
1962 }
1963
1964 static
1965 void bt_ctf_field_destroy(struct bt_object *obj)
1966 {
1967 struct bt_ctf_field *field;
1968 struct bt_ctf_field_type *type;
1969 enum bt_ctf_field_type_id type_id;
1970
1971 field = container_of(obj, struct bt_ctf_field, base);
1972 type = field->type;
1973 type_id = bt_ctf_field_type_get_type_id(type);
1974 assert(type_id > BT_CTF_FIELD_TYPE_ID_UNKNOWN &&
1975 type_id < BT_CTF_NR_TYPE_IDS);
1976 field_destroy_funcs[type_id](field);
1977 BT_LOGD_STR("Putting field's type.");
1978 bt_put(type);
1979 }
1980
1981 static
1982 void 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
1990 BT_LOGD("Destroying integer field object: addr=%p", field);
1991 integer = container_of(field, struct bt_ctf_field_integer, parent);
1992 g_free(integer);
1993 }
1994
1995 static
1996 void 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
2004 BT_LOGD("Destroying enumeration field object: addr=%p", field);
2005 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2006 parent);
2007 BT_LOGD_STR("Putting payload field.");
2008 bt_put(enumeration->payload);
2009 g_free(enumeration);
2010 }
2011
2012 static
2013 void 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
2021 BT_LOGD("Destroying floating point number field object: addr=%p", field);
2022 floating_point = container_of(field, struct bt_ctf_field_floating_point,
2023 parent);
2024 g_free(floating_point);
2025 }
2026
2027 static
2028 void 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
2036 BT_LOGD("Destroying structure field object: addr=%p", field);
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
2042 static
2043 void 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
2051 BT_LOGD("Destroying variant field object: addr=%p", field);
2052 variant = container_of(field, struct bt_ctf_field_variant, parent);
2053 BT_LOGD_STR("Putting tag field.");
2054 bt_put(variant->tag);
2055 BT_LOGD_STR("Putting payload field.");
2056 bt_put(variant->payload);
2057 g_free(variant);
2058 }
2059
2060 static
2061 void 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
2069 BT_LOGD("Destroying array field object: addr=%p", field);
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
2075 static
2076 void 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
2084 BT_LOGD("Destroying sequence field object: addr=%p", field);
2085 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
2086 if (sequence->elements) {
2087 g_ptr_array_free(sequence->elements, TRUE);
2088 }
2089 BT_LOGD_STR("Putting length field.");
2090 bt_put(sequence->length);
2091 g_free(sequence);
2092 }
2093
2094 static
2095 void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
2096 {
2097 struct bt_ctf_field_string *string;
2098
2099 if (!field) {
2100 return;
2101 }
2102
2103 BT_LOGD("Destroying string field object: addr=%p", field);
2104 string = container_of(field, struct bt_ctf_field_string, parent);
2105 if (string->payload) {
2106 g_string_free(string->payload, TRUE);
2107 }
2108 g_free(string);
2109 }
2110
2111 static
2112 int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
2113 {
2114 return (field && field->payload_set) ? 0 : -1;
2115 }
2116
2117 static
2118 int 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) {
2124 BT_LOGD_STR("Invalid parameter: field is NULL.");
2125 ret = -1;
2126 goto end;
2127 }
2128
2129 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2130 parent);
2131 if (!enumeration->payload) {
2132 BT_LOGW("Invalid enumeration field: payload is not set: "
2133 "addr=%p", field);
2134 ret = -1;
2135 goto end;
2136 }
2137
2138 ret = bt_ctf_field_validate(enumeration->payload);
2139 end:
2140 return ret;
2141 }
2142
2143 static
2144 int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
2145 {
2146 int64_t i;
2147 int ret = 0;
2148 struct bt_ctf_field_structure *structure;
2149
2150 if (!field) {
2151 BT_LOGD_STR("Invalid parameter: field is NULL.");
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++) {
2158 struct bt_ctf_field *entry_field = structure->fields->pdata[i];
2159 ret = bt_ctf_field_validate(entry_field);
2160
2161 if (ret) {
2162 int this_ret;
2163 const char *name;
2164 struct bt_ctf_field_type *field_type =
2165 bt_ctf_field_get_type(field);
2166
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);
2174 bt_put(field_type);
2175 goto end;
2176 }
2177 }
2178 end:
2179 return ret;
2180 }
2181
2182 static
2183 int 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) {
2189 BT_LOGD_STR("Invalid parameter: field is NULL.");
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);
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 }
2201 end:
2202 return ret;
2203 }
2204
2205 static
2206 int bt_ctf_field_array_validate(struct bt_ctf_field *field)
2207 {
2208 int64_t i;
2209 int ret = 0;
2210 struct bt_ctf_field_array *array;
2211
2212 if (!field) {
2213 BT_LOGD_STR("Invalid parameter: field is NULL.");
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++) {
2220 struct bt_ctf_field *elem_field = array->elements->pdata[i];
2221
2222 ret = bt_ctf_field_validate(elem_field);
2223 if (ret) {
2224 BT_LOGW("Invalid array field's element field: "
2225 "array-field-addr=%p, field-addr=%p, "
2226 "index=%" PRId64, field, elem_field, i);
2227 goto end;
2228 }
2229 }
2230 end:
2231 return ret;
2232 }
2233
2234 static
2235 int 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) {
2242 BT_LOGD_STR("Invalid parameter: field is NULL.");
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++) {
2249 struct bt_ctf_field *elem_field = sequence->elements->pdata[i];
2250
2251 ret = bt_ctf_field_validate(elem_field);
2252 if (ret) {
2253 BT_LOGW("Invalid sequence field's element field: "
2254 "sequence-field-addr=%p, field-addr=%p, "
2255 "index=%" PRId64, field, elem_field, i);
2256 goto end;
2257 }
2258 }
2259 end:
2260 return ret;
2261 }
2262
2263 static
2264 int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
2265 {
2266 int ret = 0;
2267
2268 if (!field) {
2269 BT_LOGD_STR("Invalid parameter: field is NULL.");
2270 ret = -1;
2271 goto end;
2272 }
2273
2274 field->payload_set = 0;
2275 end:
2276 return ret;
2277 }
2278
2279 static
2280 int 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) {
2286 BT_LOGD_STR("Invalid parameter: field is NULL.");
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);
2298 end:
2299 return ret;
2300 }
2301
2302 static
2303 int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
2304 {
2305 int64_t i;
2306 int ret = 0;
2307 struct bt_ctf_field_structure *structure;
2308
2309 if (!field) {
2310 BT_LOGD_STR("Invalid parameter: field is NULL.");
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) {
2329 BT_LOGE("Failed to reset structure field's field: "
2330 "struct-field-addr=%p, field-addr=%p, "
2331 "index=%" PRId64, field, member, i);
2332 goto end;
2333 }
2334 }
2335 end:
2336 return ret;
2337 }
2338
2339 static
2340 int 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) {
2346 BT_LOGD_STR("Invalid parameter: field is NULL.");
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);
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 }
2359 }
2360 end:
2361 return ret;
2362 }
2363
2364 static
2365 int 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) {
2372 BT_LOGD_STR("Invalid parameter: field is NULL.");
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) {
2391 BT_LOGE("Failed to reset array field's field: "
2392 "array-field-addr=%p, field-addr=%p, "
2393 "index=%" PRId64, field, member, i);
2394 goto end;
2395 }
2396 }
2397 end:
2398 return ret;
2399 }
2400
2401 static
2402 int 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) {
2409 BT_LOGD_STR("Invalid parameter: field is NULL.");
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) {
2428 BT_LOGE("Failed to reset sequence field's field: "
2429 "sequence-field-addr=%p, field-addr=%p, "
2430 "index=%" PRId64, field, member, i);
2431 goto end;
2432 }
2433 }
2434 end:
2435 return ret;
2436 }
2437
2438 static
2439 int 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) {
2445 BT_LOGD_STR("Invalid parameter: field is NULL.");
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 }
2459 end:
2460 return ret;
2461 }
2462
2463 static
2464 int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
2465 struct bt_ctf_stream_pos *pos,
2466 enum bt_ctf_byte_order native_byte_order)
2467 {
2468 int ret = 0;
2469 struct bt_ctf_field_integer *integer = container_of(field,
2470 struct bt_ctf_field_integer, parent);
2471
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
2476 if (!bt_ctf_field_generic_is_set(field)) {
2477 BT_LOGW_STR("Field's payload is not set.");
2478 ret = -1;
2479 goto end;
2480 }
2481 retry:
2482 ret = bt_ctf_field_integer_write(integer, pos, native_byte_order);
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) {
2490 BT_LOGE("Cannot increase packet size: ret=%d", ret);
2491 goto end;
2492 }
2493 goto retry;
2494 }
2495 end:
2496 return ret;
2497 }
2498
2499 static
2500 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
2501 struct bt_ctf_stream_pos *pos,
2502 enum bt_ctf_byte_order native_byte_order)
2503 {
2504 struct bt_ctf_field_enumeration *enumeration = container_of(
2505 field, struct bt_ctf_field_enumeration, parent);
2506
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.");
2511 return bt_ctf_field_serialize(enumeration->payload, pos,
2512 native_byte_order);
2513 }
2514
2515 static
2516 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
2517 struct bt_ctf_stream_pos *pos,
2518 enum bt_ctf_byte_order native_byte_order)
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
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
2528 if (!bt_ctf_field_generic_is_set(field)) {
2529 BT_LOGW_STR("Field's payload is not set.");
2530 ret = -1;
2531 goto end;
2532 }
2533 retry:
2534 ret = bt_ctf_field_floating_point_write(floating_point, pos,
2535 native_byte_order);
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) {
2543 BT_LOGE("Cannot increase packet size: ret=%d", ret);
2544 goto end;
2545 }
2546 goto retry;
2547 }
2548 end:
2549 return ret;
2550 }
2551
2552 static
2553 int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
2554 struct bt_ctf_stream_pos *pos,
2555 enum bt_ctf_byte_order native_byte_order)
2556 {
2557 int64_t i;
2558 int ret = 0;
2559 struct bt_ctf_field_structure *structure = container_of(
2560 field, struct bt_ctf_field_structure, parent);
2561
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
2566 while (!bt_ctf_stream_pos_access_ok(pos,
2567 offset_align(pos->offset, field->type->alignment))) {
2568 ret = increase_packet_size(pos);
2569 if (ret) {
2570 BT_LOGE("Cannot increase packet size: ret=%d", ret);
2571 goto end;
2572 }
2573 }
2574
2575 if (!bt_ctf_stream_pos_align(pos, field->type->alignment)) {
2576 BT_LOGE("Cannot align packet's position: pos-offset=%" PRId64 ", "
2577 "align=%u", pos->offset, field->type->alignment);
2578 ret = -1;
2579 goto end;
2580 }
2581
2582 for (i = 0; i < structure->fields->len; i++) {
2583 struct bt_ctf_field *member = g_ptr_array_index(
2584 structure->fields, i);
2585
2586 BT_LOGV("Serializing structure field's field: pos-offset=%" PRId64 ", "
2587 "field-addr=%p, index=%" PRId64,
2588 pos->offset, member, i);
2589 ret = bt_ctf_field_serialize(member, pos, native_byte_order);
2590 if (ret) {
2591 int this_ret;
2592 const char *name;
2593 struct bt_ctf_field_type *structure_type =
2594 bt_ctf_field_get_type(field);
2595
2596 this_ret = bt_ctf_field_type_structure_get_field(
2597 structure_type, &name, NULL, i);
2598 assert(this_ret == 0);
2599 BT_LOGW("Cannot serialize structure field's field: "
2600 "struct-field-addr=%p, field-addr=%p, "
2601 "field-name=\"%s\", index=%" PRId64,
2602 field, member, name, i);
2603 bt_put(structure_type);
2604 break;
2605 }
2606 }
2607 end:
2608 return ret;
2609 }
2610
2611 static
2612 int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
2613 struct bt_ctf_stream_pos *pos,
2614 enum bt_ctf_byte_order native_byte_order)
2615 {
2616 struct bt_ctf_field_variant *variant = container_of(
2617 field, struct bt_ctf_field_variant, parent);
2618
2619 BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64 ", "
2620 "native-bo=%s", field, pos->offset,
2621 bt_ctf_byte_order_string(native_byte_order));
2622 BT_LOGV_STR("Serializing variant field's payload field.");
2623 return bt_ctf_field_serialize(variant->payload, pos,
2624 native_byte_order);
2625 }
2626
2627 static
2628 int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
2629 struct bt_ctf_stream_pos *pos,
2630 enum bt_ctf_byte_order native_byte_order)
2631 {
2632 int64_t i;
2633 int ret = 0;
2634 struct bt_ctf_field_array *array = container_of(
2635 field, struct bt_ctf_field_array, parent);
2636
2637 BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64 ", "
2638 "native-bo=%s", field, pos->offset,
2639 bt_ctf_byte_order_string(native_byte_order));
2640
2641 for (i = 0; i < array->elements->len; i++) {
2642 struct bt_ctf_field *elem_field =
2643 g_ptr_array_index(array->elements, i);
2644
2645 BT_LOGV("Serializing array field's element field: "
2646 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
2647 pos->offset, elem_field, i);
2648 ret = bt_ctf_field_serialize(elem_field, pos,
2649 native_byte_order);
2650 if (ret) {
2651 BT_LOGW("Cannot serialize array field's element field: "
2652 "array-field-addr=%p, field-addr=%p, "
2653 "index=%" PRId64, field, elem_field, i);
2654 goto end;
2655 }
2656 }
2657 end:
2658 return ret;
2659 }
2660
2661 static
2662 int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
2663 struct bt_ctf_stream_pos *pos,
2664 enum bt_ctf_byte_order native_byte_order)
2665 {
2666 int64_t i;
2667 int ret = 0;
2668 struct bt_ctf_field_sequence *sequence = container_of(
2669 field, struct bt_ctf_field_sequence, parent);
2670
2671 BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64 ", "
2672 "native-bo=%s", field, pos->offset,
2673 bt_ctf_byte_order_string(native_byte_order));
2674
2675 for (i = 0; i < sequence->elements->len; i++) {
2676 struct bt_ctf_field *elem_field =
2677 g_ptr_array_index(sequence->elements, i);
2678
2679 BT_LOGV("Serializing sequence field's element field: "
2680 "pos-offset=%" PRId64 ", field-addr=%p, index=%" PRId64,
2681 pos->offset, elem_field, i);
2682 ret = bt_ctf_field_serialize(elem_field, pos,
2683 native_byte_order);
2684 if (ret) {
2685 BT_LOGW("Cannot serialize sequence field's element field: "
2686 "sequence-field-addr=%p, field-addr=%p, "
2687 "index=%" PRId64, field, elem_field, i);
2688 goto end;
2689 }
2690 }
2691 end:
2692 return ret;
2693 }
2694
2695 static
2696 int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
2697 struct bt_ctf_stream_pos *pos,
2698 enum bt_ctf_byte_order native_byte_order)
2699 {
2700 int64_t i;
2701 int ret = 0;
2702 struct bt_ctf_field_string *string = container_of(field,
2703 struct bt_ctf_field_string, parent);
2704 struct bt_ctf_field_type *character_type =
2705 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
2706 struct bt_ctf_field *character;
2707
2708 BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64 ", "
2709 "native-bo=%s", field, pos->offset,
2710 bt_ctf_byte_order_string(native_byte_order));
2711
2712 BT_LOGV_STR("Creating character field from string field's character field type.");
2713 character = bt_ctf_field_create(character_type);
2714
2715 for (i = 0; i < string->payload->len + 1; i++) {
2716 const uint64_t chr = (uint64_t) string->payload->str[i];
2717
2718 ret = bt_ctf_field_unsigned_integer_set_value(character, chr);
2719 if (ret) {
2720 BT_LOGE("Cannot set character field's value: "
2721 "pos-offset=%" PRId64 ", field-addr=%p, "
2722 "index=%" PRId64 ", char-int=%" PRIu64,
2723 pos->offset, character, i, chr);
2724 goto end;
2725 }
2726
2727 BT_LOGV("Serializing string field's character field: "
2728 "pos-offset=%" PRId64 ", field-addr=%p, "
2729 "index=%" PRId64 ", char-int=%" PRIu64,
2730 pos->offset, character, i, chr);
2731 ret = bt_ctf_field_integer_serialize(character, pos,
2732 native_byte_order);
2733 if (ret) {
2734 BT_LOGE_STR("Cannot serialize character field.");
2735 goto end;
2736 }
2737 }
2738 end:
2739 bt_put(character);
2740 bt_put(character_type);
2741 return ret;
2742 }
2743
2744 static
2745 int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2746 struct bt_ctf_field *dst)
2747 {
2748 struct bt_ctf_field_integer *integer_src, *integer_dst;
2749
2750 BT_LOGD("Copying integer field: src-field-addr=%p, dst-field-addr=%p",
2751 src, dst);
2752 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
2753 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
2754 integer_dst->payload = integer_src->payload;
2755 BT_LOGD_STR("Copied integer field.");
2756 return 0;
2757 }
2758
2759 static
2760 int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2761 struct bt_ctf_field *dst)
2762 {
2763 int ret = 0;
2764 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2765
2766 BT_LOGD("Copying enumeration field: src-field-addr=%p, dst-field-addr=%p",
2767 src, dst);
2768 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2769 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2770
2771 if (enum_src->payload) {
2772 BT_LOGD_STR("Copying enumeration field's payload field.");
2773 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2774 if (!enum_dst->payload) {
2775 BT_LOGE_STR("Cannot copy enumeration field's payload field.");
2776 ret = -1;
2777 goto end;
2778 }
2779 }
2780
2781 BT_LOGD_STR("Copied enumeration field.");
2782 end:
2783 return ret;
2784 }
2785
2786 static
2787 int bt_ctf_field_floating_point_copy(
2788 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2789 {
2790 struct bt_ctf_field_floating_point *float_src, *float_dst;
2791
2792 BT_LOGD("Copying floating point number field: src-field-addr=%p, dst-field-addr=%p",
2793 src, dst);
2794 float_src = container_of(src, struct bt_ctf_field_floating_point,
2795 parent);
2796 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2797 parent);
2798 float_dst->payload = float_src->payload;
2799 BT_LOGD_STR("Copied floating point number field.");
2800 return 0;
2801 }
2802
2803 static
2804 int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2805 struct bt_ctf_field *dst)
2806 {
2807 int ret = 0;
2808 int64_t i;
2809 struct bt_ctf_field_structure *struct_src, *struct_dst;
2810
2811 BT_LOGD("Copying structure field: src-field-addr=%p, dst-field-addr=%p",
2812 src, dst);
2813 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2814 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2815
2816 /* This field_name_to_index HT is owned by the structure field type */
2817 struct_dst->field_name_to_index = struct_src->field_name_to_index;
2818 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
2819
2820 for (i = 0; i < struct_src->fields->len; i++) {
2821 struct bt_ctf_field *field =
2822 g_ptr_array_index(struct_src->fields, i);
2823 struct bt_ctf_field *field_copy = NULL;
2824
2825 if (field) {
2826 BT_LOGD("Copying structure field's field: src-field-addr=%p",
2827 "index=%" PRId64, field, i);
2828 field_copy = bt_ctf_field_copy(field);
2829 if (!field_copy) {
2830 BT_LOGE("Cannot copy structure field's field: "
2831 "src-field-addr=%p, index=%" PRId64,
2832 field, i);
2833 ret = -1;
2834 goto end;
2835 }
2836 }
2837
2838 g_ptr_array_index(struct_dst->fields, i) = field_copy;
2839 }
2840
2841 BT_LOGD_STR("Copied structure field.");
2842
2843 end:
2844 return ret;
2845 }
2846
2847 static
2848 int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2849 struct bt_ctf_field *dst)
2850 {
2851 int ret = 0;
2852 struct bt_ctf_field_variant *variant_src, *variant_dst;
2853
2854 BT_LOGD("Copying variant field: src-field-addr=%p, dst-field-addr=%p",
2855 src, dst);
2856 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2857 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2858
2859 if (variant_src->tag) {
2860 BT_LOGD_STR("Copying variant field's tag field.");
2861 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2862 if (!variant_dst->tag) {
2863 BT_LOGE_STR("Cannot copy variant field's tag field.");
2864 ret = -1;
2865 goto end;
2866 }
2867 }
2868 if (variant_src->payload) {
2869 BT_LOGD_STR("Copying variant field's payload field.");
2870 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2871 if (!variant_dst->payload) {
2872 BT_LOGE_STR("Cannot copy variant field's payload field.");
2873 ret = -1;
2874 goto end;
2875 }
2876 }
2877
2878 BT_LOGD_STR("Copied variant field.");
2879
2880 end:
2881 return ret;
2882 }
2883
2884 static
2885 int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2886 struct bt_ctf_field *dst)
2887 {
2888 int ret = 0;
2889 int64_t i;
2890 struct bt_ctf_field_array *array_src, *array_dst;
2891
2892 BT_LOGD("Copying array field: src-field-addr=%p, dst-field-addr=%p",
2893 src, dst);
2894 array_src = container_of(src, struct bt_ctf_field_array, parent);
2895 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2896
2897 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
2898 for (i = 0; i < array_src->elements->len; i++) {
2899 struct bt_ctf_field *field =
2900 g_ptr_array_index(array_src->elements, i);
2901 struct bt_ctf_field *field_copy = NULL;
2902
2903 if (field) {
2904 BT_LOGD("Copying array field's element field: field-addr=%p, "
2905 "index=%" PRId64, field, i);
2906 field_copy = bt_ctf_field_copy(field);
2907 if (!field_copy) {
2908 BT_LOGE("Cannot copy array field's element field: "
2909 "src-field-addr=%p, index=%" PRId64,
2910 field, i);
2911 ret = -1;
2912 goto end;
2913 }
2914 }
2915
2916 g_ptr_array_index(array_dst->elements, i) = field_copy;
2917 }
2918
2919 BT_LOGD_STR("Copied array field.");
2920
2921 end:
2922 return ret;
2923 }
2924
2925 static
2926 int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2927 struct bt_ctf_field *dst)
2928 {
2929 int ret = 0;
2930 int64_t i;
2931 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
2932 struct bt_ctf_field *src_length;
2933 struct bt_ctf_field *dst_length;
2934
2935 BT_LOGD("Copying sequence field: src-field-addr=%p, dst-field-addr=%p",
2936 src, dst);
2937 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2938 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2939
2940 src_length = bt_ctf_field_sequence_get_length(src);
2941 if (!src_length) {
2942 /* no length set yet: keep destination sequence empty */
2943 goto end;
2944 }
2945
2946 /* copy source length */
2947 BT_LOGD_STR("Copying sequence field's length field.");
2948 dst_length = bt_ctf_field_copy(src_length);
2949 BT_PUT(src_length);
2950 if (!dst_length) {
2951 BT_LOGE_STR("Cannot copy sequence field's length field.");
2952 ret = -1;
2953 goto end;
2954 }
2955
2956 /* this will initialize the destination sequence's internal array */
2957 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
2958 bt_put(dst_length);
2959 if (ret) {
2960 BT_LOGE("Cannot set sequence field copy's length field: "
2961 "dst-length-field-addr=%p", dst_length);
2962 ret = -1;
2963 goto end;
2964 }
2965
2966 assert(sequence_dst->elements->len == sequence_src->elements->len);
2967
2968 for (i = 0; i < sequence_src->elements->len; i++) {
2969 struct bt_ctf_field *field =
2970 g_ptr_array_index(sequence_src->elements, i);
2971 struct bt_ctf_field *field_copy = NULL;
2972
2973 if (field) {
2974 BT_LOGD("Copying sequence field's element field: field-addr=%p, "
2975 "index=%" PRId64, field, i);
2976 field_copy = bt_ctf_field_copy(field);
2977 if (!field_copy) {
2978 BT_LOGE("Cannot copy sequence field's element field: "
2979 "src-field-addr=%p, index=%" PRId64,
2980 field, i);
2981 ret = -1;
2982 goto end;
2983 }
2984 }
2985
2986 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
2987 }
2988
2989 BT_LOGD_STR("Copied sequence field.");
2990
2991 end:
2992 return ret;
2993 }
2994
2995 static
2996 int bt_ctf_field_string_copy(struct bt_ctf_field *src,
2997 struct bt_ctf_field *dst)
2998 {
2999 int ret = 0;
3000 struct bt_ctf_field_string *string_src, *string_dst;
3001
3002 BT_LOGD("Copying string field: src-field-addr=%p, dst-field-addr=%p",
3003 src, dst);
3004 string_src = container_of(src, struct bt_ctf_field_string, parent);
3005 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
3006
3007 if (string_src->payload) {
3008 string_dst->payload = g_string_new(string_src->payload->str);
3009 if (!string_dst->payload) {
3010 BT_LOGE_STR("Failed to allocate a GString.");
3011 ret = -1;
3012 goto end;
3013 }
3014 }
3015
3016 BT_LOGD_STR("Copied string field.");
3017
3018 end:
3019 return ret;
3020 }
3021
3022 static
3023 int increase_packet_size(struct bt_ctf_stream_pos *pos)
3024 {
3025 int ret;
3026
3027 assert(pos);
3028 BT_LOGV("Increasing packet size: pos-offset=%" PRId64 ", "
3029 "cur-packet-size=%" PRIu64,
3030 pos->offset, pos->packet_size);
3031 ret = munmap_align(pos->base_mma);
3032 if (ret) {
3033 BT_LOGE("Failed to perform an aligned memory unmapping: "
3034 "ret=%d, errno=%d", ret, errno);
3035 goto end;
3036 }
3037
3038 pos->packet_size += PACKET_LEN_INCREMENT;
3039 do {
3040 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
3041 pos->packet_size / CHAR_BIT);
3042 } while (ret == EINTR);
3043 if (ret) {
3044 BT_LOGE("Failed to preallocate memory space: ret=%d, errno=%d",
3045 ret, errno);
3046 errno = EINTR;
3047 ret = -1;
3048 goto end;
3049 }
3050
3051 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
3052 pos->flags, pos->fd, pos->mmap_offset);
3053 if (pos->base_mma == MAP_FAILED) {
3054 BT_LOGE("Failed to perform an aligned memory mapping: "
3055 "ret=%d, errno=%d", ret, errno);
3056 ret = -1;
3057 }
3058
3059 BT_LOGV("Increased packet size: pos-offset=%" PRId64 ", "
3060 "new-packet-size=%" PRIu64,
3061 pos->offset, pos->packet_size);
3062 end:
3063 return ret;
3064 }
3065
3066 static
3067 void generic_field_freeze(struct bt_ctf_field *field)
3068 {
3069 field->frozen = 1;
3070 }
3071
3072 static
3073 void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
3074 {
3075 struct bt_ctf_field_enumeration *enum_field =
3076 container_of(field, struct bt_ctf_field_enumeration, parent);
3077
3078 BT_LOGD("Freezing enumeration field object: addr=%p", field);
3079 BT_LOGD("Freezing enumeration field object's contained payload field: payload-field-addr=%p", enum_field->payload);
3080 bt_ctf_field_freeze(enum_field->payload);
3081 generic_field_freeze(field);
3082 }
3083
3084 static
3085 void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
3086 {
3087 int64_t i;
3088 struct bt_ctf_field_structure *structure_field =
3089 container_of(field, struct bt_ctf_field_structure, parent);
3090
3091 BT_LOGD("Freezing structure field object: addr=%p", field);
3092
3093 for (i = 0; i < structure_field->fields->len; i++) {
3094 struct bt_ctf_field *field =
3095 g_ptr_array_index(structure_field->fields, i);
3096
3097 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
3098 field, i);
3099 bt_ctf_field_freeze(field);
3100 }
3101
3102 generic_field_freeze(field);
3103 }
3104
3105 static
3106 void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
3107 {
3108 struct bt_ctf_field_variant *variant_field =
3109 container_of(field, struct bt_ctf_field_variant, parent);
3110
3111 BT_LOGD("Freezing variant field object: addr=%p", field);
3112 BT_LOGD("Freezing variant field object's tag field: tag-field-addr=%p", variant_field->tag);
3113 bt_ctf_field_freeze(variant_field->tag);
3114 BT_LOGD("Freezing variant field object's payload field: payload-field-addr=%p", variant_field->payload);
3115 bt_ctf_field_freeze(variant_field->payload);
3116 generic_field_freeze(field);
3117 }
3118
3119 static
3120 void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
3121 {
3122 int64_t i;
3123 struct bt_ctf_field_array *array_field =
3124 container_of(field, struct bt_ctf_field_array, parent);
3125
3126 BT_LOGD("Freezing array field object: addr=%p", field);
3127
3128 for (i = 0; i < array_field->elements->len; i++) {
3129 struct bt_ctf_field *elem_field =
3130 g_ptr_array_index(array_field->elements, i);
3131
3132 BT_LOGD("Freezing array field object's element field: "
3133 "element-field-addr=%p, index=%" PRId64,
3134 elem_field, i);
3135 bt_ctf_field_freeze(elem_field);
3136 }
3137
3138 generic_field_freeze(field);
3139 }
3140
3141 static
3142 void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
3143 {
3144 int64_t i;
3145 struct bt_ctf_field_sequence *sequence_field =
3146 container_of(field, struct bt_ctf_field_sequence, parent);
3147
3148 BT_LOGD("Freezing sequence field object: addr=%p", field);
3149 BT_LOGD("Freezing sequence field object's length field: length-field-addr=%p",
3150 sequence_field->length);
3151 bt_ctf_field_freeze(sequence_field->length);
3152
3153 for (i = 0; i < sequence_field->elements->len; i++) {
3154 struct bt_ctf_field *elem_field =
3155 g_ptr_array_index(sequence_field->elements, i);
3156
3157 BT_LOGD("Freezing sequence field object's element field: "
3158 "element-field-addr=%p, index=%" PRId64,
3159 elem_field, i);
3160 bt_ctf_field_freeze(elem_field);
3161 }
3162
3163 generic_field_freeze(field);
3164 }
3165
3166 BT_HIDDEN
3167 void bt_ctf_field_freeze(struct bt_ctf_field *field)
3168 {
3169 enum bt_ctf_field_type_id type_id;
3170
3171 if (!field) {
3172 goto end;
3173 }
3174
3175 if (field->frozen) {
3176 goto end;
3177 }
3178
3179 BT_LOGD("Freezing field object: addr=%p", field);
3180 type_id = bt_ctf_field_get_type_id(field);
3181 assert(type_id > BT_CTF_FIELD_TYPE_ID_UNKNOWN &&
3182 type_id < BT_CTF_NR_TYPE_IDS);
3183 field_freeze_funcs[type_id](field);
3184 end:
3185 return;
3186 }
3187
3188 static
3189 bt_bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
3190 {
3191 return field && field->payload_set;
3192 }
3193
3194 static
3195 bt_bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
3196 {
3197 bt_bool is_set = BT_FALSE;
3198 struct bt_ctf_field_enumeration *enumeration;
3199
3200 if (!field) {
3201 goto end;
3202 }
3203
3204 enumeration = container_of(field, struct bt_ctf_field_enumeration,
3205 parent);
3206 if (!enumeration->payload) {
3207 goto end;
3208 }
3209
3210 is_set = bt_ctf_field_is_set(enumeration->payload);
3211 end:
3212 return is_set;
3213 }
3214
3215 static
3216 bt_bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
3217 {
3218 bt_bool is_set = BT_FALSE;
3219 size_t i;
3220 struct bt_ctf_field_structure *structure;
3221
3222 if (!field) {
3223 goto end;
3224 }
3225
3226 structure = container_of(field, struct bt_ctf_field_structure, parent);
3227 for (i = 0; i < structure->fields->len; i++) {
3228 is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
3229 if (!is_set) {
3230 goto end;
3231 }
3232 }
3233 end:
3234 return is_set;
3235 }
3236
3237 static
3238 bt_bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
3239 {
3240 bt_bool is_set = BT_FALSE;
3241 struct bt_ctf_field_variant *variant;
3242
3243 if (!field) {
3244 goto end;
3245 }
3246
3247 variant = container_of(field, struct bt_ctf_field_variant, parent);
3248 is_set = bt_ctf_field_is_set(variant->payload);
3249 end:
3250 return is_set;
3251 }
3252
3253 static
3254 bt_bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
3255 {
3256 size_t i;
3257 bt_bool is_set = BT_FALSE;
3258 struct bt_ctf_field_array *array;
3259
3260 if (!field) {
3261 goto end;
3262 }
3263
3264 array = container_of(field, struct bt_ctf_field_array, parent);
3265 for (i = 0; i < array->elements->len; i++) {
3266 is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
3267 if (!is_set) {
3268 goto end;
3269 }
3270 }
3271 end:
3272 return is_set;
3273 }
3274
3275 static
3276 bt_bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
3277 {
3278 size_t i;
3279 bt_bool is_set = BT_FALSE;
3280 struct bt_ctf_field_sequence *sequence;
3281
3282 if (!field) {
3283 goto end;
3284 }
3285
3286 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
3287 for (i = 0; i < sequence->elements->len; i++) {
3288 is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
3289 if (!is_set) {
3290 goto end;
3291 }
3292 }
3293 end:
3294 return is_set;
3295 }
This page took 0.093134 seconds and 5 git commands to generate.