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