Remove Babeltrace 1 files and reorganize the tree
[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 #include <babeltrace/ctf-ir/fields-internal.h>
30 #include <babeltrace/ctf-ir/field-types-internal.h>
31 #include <babeltrace/ctf-writer/serialize-internal.h>
32 #include <babeltrace/object-internal.h>
33 #include <babeltrace/ref.h>
34 #include <babeltrace/compiler.h>
35 #include <babeltrace/compat/fcntl.h>
36 #include <babeltrace/align.h>
37
38 #define PACKET_LEN_INCREMENT (getpagesize() * 8 * CHAR_BIT)
39
40 static
41 struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
42 static
43 struct bt_ctf_field *bt_ctf_field_enumeration_create(
44 struct bt_ctf_field_type *);
45 static
46 struct bt_ctf_field *bt_ctf_field_floating_point_create(
47 struct bt_ctf_field_type *);
48 static
49 struct bt_ctf_field *bt_ctf_field_structure_create(
50 struct bt_ctf_field_type *);
51 static
52 struct bt_ctf_field *bt_ctf_field_variant_create(
53 struct bt_ctf_field_type *);
54 static
55 struct bt_ctf_field *bt_ctf_field_array_create(
56 struct bt_ctf_field_type *);
57 static
58 struct bt_ctf_field *bt_ctf_field_sequence_create(
59 struct bt_ctf_field_type *);
60 static
61 struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
62
63 static
64 void bt_ctf_field_destroy(struct bt_object *);
65 static
66 void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
67 static
68 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
69 static
70 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
71 static
72 void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
73 static
74 void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
75 static
76 void bt_ctf_field_array_destroy(struct bt_ctf_field *);
77 static
78 void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
79 static
80 void bt_ctf_field_string_destroy(struct bt_ctf_field *);
81
82 static
83 int bt_ctf_field_generic_validate(struct bt_ctf_field *);
84 static
85 int bt_ctf_field_structure_validate(struct bt_ctf_field *);
86 static
87 int bt_ctf_field_variant_validate(struct bt_ctf_field *);
88 static
89 int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
90 static
91 int bt_ctf_field_array_validate(struct bt_ctf_field *);
92 static
93 int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
94
95 static
96 int bt_ctf_field_generic_reset(struct bt_ctf_field *);
97 static
98 int bt_ctf_field_structure_reset(struct bt_ctf_field *);
99 static
100 int bt_ctf_field_variant_reset(struct bt_ctf_field *);
101 static
102 int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
103 static
104 int bt_ctf_field_array_reset(struct bt_ctf_field *);
105 static
106 int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
107 static
108 int bt_ctf_field_string_reset(struct bt_ctf_field *);
109
110 static
111 int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
112 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
113 static
114 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
115 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
116 static
117 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
118 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
119 static
120 int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
121 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
122 static
123 int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
124 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
125 static
126 int bt_ctf_field_array_serialize(struct bt_ctf_field *,
127 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
128 static
129 int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
130 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
131 static
132 int bt_ctf_field_string_serialize(struct bt_ctf_field *,
133 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
134
135 static
136 int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
137 static
138 int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
139 static
140 int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
141 struct bt_ctf_field *);
142 static
143 int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
144 static
145 int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
146 static
147 int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
148 static
149 int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
150 static
151 int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
152
153 static
154 void generic_field_freeze(struct bt_ctf_field *);
155 static
156 void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
157 static
158 void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
159 static
160 void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
161 static
162 void bt_ctf_field_array_freeze(struct bt_ctf_field *);
163 static
164 void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
165
166 static
167 bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
168 static
169 bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
170 static
171 bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
172 static
173 bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
174 static
175 bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
176 static
177 bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
178
179 static
180 int increase_packet_size(struct bt_ctf_stream_pos *pos);
181
182 static
183 struct bt_ctf_field *(* const field_create_funcs[])(
184 struct bt_ctf_field_type *) = {
185 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
186 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
187 [BT_CTF_TYPE_ID_FLOAT] =
188 bt_ctf_field_floating_point_create,
189 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
190 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
191 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
192 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
193 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_create,
194 };
195
196 static
197 void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
198 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_destroy,
199 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_destroy,
200 [BT_CTF_TYPE_ID_FLOAT] =
201 bt_ctf_field_floating_point_destroy,
202 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_destroy,
203 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_destroy,
204 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_destroy,
205 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_destroy,
206 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_destroy,
207 };
208
209 static
210 int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
211 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_validate,
212 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_validate,
213 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_validate,
214 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_validate,
215 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_validate,
216 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_validate,
217 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_validate,
218 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_validate,
219 };
220
221 static
222 int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
223 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_reset,
224 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_reset,
225 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_reset,
226 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_reset,
227 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_reset,
228 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_reset,
229 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_reset,
230 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_reset,
231 };
232
233 static
234 int (* const field_serialize_funcs[])(struct bt_ctf_field *,
235 struct bt_ctf_stream_pos *, enum bt_ctf_byte_order) = {
236 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_serialize,
237 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_serialize,
238 [BT_CTF_TYPE_ID_FLOAT] =
239 bt_ctf_field_floating_point_serialize,
240 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_serialize,
241 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_serialize,
242 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_serialize,
243 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_serialize,
244 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_serialize,
245 };
246
247 static
248 int (* const field_copy_funcs[])(struct bt_ctf_field *,
249 struct bt_ctf_field *) = {
250 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_copy,
251 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_copy,
252 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_copy,
253 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_copy,
254 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_copy,
255 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_copy,
256 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_copy,
257 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_copy,
258 };
259
260 static
261 void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
262 [BT_CTF_TYPE_ID_INTEGER] = generic_field_freeze,
263 [BT_CTF_TYPE_ID_FLOAT] = generic_field_freeze,
264 [BT_CTF_TYPE_ID_STRING] = generic_field_freeze,
265 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
266 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
267 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
268 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
269 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
270 };
271
272 static
273 bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
274 [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_is_set,
275 [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_is_set,
276 [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_is_set,
277 [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_is_set,
278 [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_is_set,
279 [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_is_set,
280 [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_is_set,
281 [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_is_set,
282 };
283
284 struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
285 {
286 struct bt_ctf_field *field = NULL;
287 enum bt_ctf_type_id type_id;
288 int ret;
289
290 if (!type) {
291 goto error;
292 }
293
294 type_id = bt_ctf_field_type_get_type_id(type);
295 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
296 type_id >= BT_CTF_NR_TYPE_IDS) {
297 goto error;
298 }
299
300 /* Field class MUST be valid */
301 ret = bt_ctf_field_type_validate(type);
302
303 if (ret) {
304 /* Invalid */
305 goto error;
306 }
307
308 field = field_create_funcs[type_id](type);
309 if (!field) {
310 goto error;
311 }
312
313 /* The type's declaration can't change after this point */
314 bt_ctf_field_type_freeze(type);
315 bt_get(type);
316 bt_object_init(field, bt_ctf_field_destroy);
317 field->type = type;
318 error:
319 return field;
320 }
321
322 void bt_ctf_field_get(struct bt_ctf_field *field)
323 {
324 bt_get(field);
325 }
326
327 void bt_ctf_field_put(struct bt_ctf_field *field)
328 {
329 bt_put(field);
330 }
331
332 struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
333 {
334 struct bt_ctf_field_type *ret = NULL;
335
336 if (!field) {
337 goto end;
338 }
339
340 ret = field->type;
341 bt_get(ret);
342 end:
343 return ret;
344 }
345
346 enum bt_ctf_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
347 {
348 enum bt_ctf_type_id ret = BT_CTF_TYPE_ID_UNKNOWN;
349
350 if (!field) {
351 goto end;
352 }
353
354 ret = bt_ctf_field_type_get_type_id(field->type);
355 end:
356 return ret;
357 }
358
359 int bt_ctf_field_is_integer(struct bt_ctf_field *field)
360 {
361 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_INTEGER;
362 }
363
364 int bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
365 {
366 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_FLOAT;
367 }
368
369 int bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
370 {
371 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ENUM;
372 }
373
374 int bt_ctf_field_is_string(struct bt_ctf_field *field)
375 {
376 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRING;
377 }
378
379 int bt_ctf_field_is_structure(struct bt_ctf_field *field)
380 {
381 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRUCT;
382 }
383
384 int bt_ctf_field_is_array(struct bt_ctf_field *field)
385 {
386 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ARRAY;
387 }
388
389 int bt_ctf_field_is_sequence(struct bt_ctf_field *field)
390 {
391 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_SEQUENCE;
392 }
393
394 int bt_ctf_field_is_variant(struct bt_ctf_field *field)
395 {
396 return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_VARIANT;
397 }
398
399 struct bt_ctf_field *bt_ctf_field_sequence_get_length(
400 struct bt_ctf_field *field)
401 {
402 struct bt_ctf_field *ret = NULL;
403 struct bt_ctf_field_sequence *sequence;
404
405 if (!field) {
406 goto end;
407 }
408
409 if (bt_ctf_field_type_get_type_id(field->type) !=
410 BT_CTF_TYPE_ID_SEQUENCE) {
411 goto end;
412 }
413
414 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
415 ret = sequence->length;
416 bt_get(ret);
417 end:
418 return ret;
419 }
420
421 int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
422 struct bt_ctf_field *length_field)
423 {
424 int ret = 0;
425 struct bt_ctf_field_type_integer *length_type;
426 struct bt_ctf_field_integer *length;
427 struct bt_ctf_field_sequence *sequence;
428 uint64_t sequence_length;
429
430 if (!field || !length_field || field->frozen) {
431 ret = -1;
432 goto end;
433 }
434 if (bt_ctf_field_type_get_type_id(length_field->type) !=
435 BT_CTF_TYPE_ID_INTEGER) {
436 ret = -1;
437 goto end;
438 }
439
440 length_type = container_of(length_field->type,
441 struct bt_ctf_field_type_integer, parent);
442 /* The length field must be unsigned */
443 if (length_type->is_signed) {
444 ret = -1;
445 goto end;
446 }
447
448 length = container_of(length_field, struct bt_ctf_field_integer,
449 parent);
450 sequence_length = length->payload.unsignd;
451 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
452 if (sequence->elements) {
453 g_ptr_array_free(sequence->elements, TRUE);
454 bt_put(sequence->length);
455 }
456
457 sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
458 if (!sequence->elements) {
459 ret = -1;
460 goto end;
461 }
462
463 g_ptr_array_set_free_func(sequence->elements,
464 (GDestroyNotify) bt_put);
465 g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
466 bt_get(length_field);
467 sequence->length = length_field;
468 end:
469 return ret;
470 }
471
472 struct bt_ctf_field *bt_ctf_field_structure_get_field(
473 struct bt_ctf_field *field, const char *name)
474 {
475 struct bt_ctf_field *new_field = NULL;
476 GQuark field_quark;
477 struct bt_ctf_field_structure *structure;
478 struct bt_ctf_field_type *field_type = NULL;
479 size_t index;
480
481 if (!field || !name ||
482 bt_ctf_field_type_get_type_id(field->type) !=
483 BT_CTF_TYPE_ID_STRUCT) {
484 goto error;
485 }
486
487 field_quark = g_quark_from_string(name);
488 structure = container_of(field, struct bt_ctf_field_structure, parent);
489 field_type =
490 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
491 name);
492 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
493 GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
494 goto error;
495 }
496
497 if (structure->fields->pdata[index]) {
498 new_field = structure->fields->pdata[index];
499 goto end;
500 }
501
502 /* We don't want to modify this field if it's frozen */
503 if (field->frozen) {
504 goto end;
505 }
506
507 new_field = bt_ctf_field_create(field_type);
508 if (!new_field) {
509 goto error;
510 }
511
512 structure->fields->pdata[index] = new_field;
513 end:
514 bt_get(new_field);
515 error:
516 if (field_type) {
517 bt_put(field_type);
518 }
519 return new_field;
520 }
521
522 struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
523 struct bt_ctf_field *field, int index)
524 {
525 int ret;
526 const char *field_name;
527 struct bt_ctf_field_structure *structure;
528 struct bt_ctf_field_type *structure_type;
529 struct bt_ctf_field_type *field_type = NULL;
530 struct bt_ctf_field *ret_field = NULL;
531
532 if (!field ||
533 bt_ctf_field_type_get_type_id(field->type) !=
534 BT_CTF_TYPE_ID_STRUCT) {
535 goto end;
536 }
537
538 structure = container_of(field, struct bt_ctf_field_structure, parent);
539 if (index >= structure->fields->len) {
540 goto error;
541 }
542
543 ret_field = structure->fields->pdata[index];
544 if (ret_field) {
545 goto end;
546 }
547
548 /* We don't want to modify this field if it's frozen */
549 if (field->frozen) {
550 goto end;
551 }
552
553 /* Field has not been instanciated yet, create it */
554 structure_type = bt_ctf_field_get_type(field);
555 if (!structure_type) {
556 goto error;
557 }
558
559 ret = bt_ctf_field_type_structure_get_field(structure_type,
560 &field_name, &field_type, index);
561 bt_put(structure_type);
562 if (ret) {
563 goto error;
564 }
565
566 ret_field = bt_ctf_field_create(field_type);
567 if (!ret_field) {
568 goto error;
569 }
570
571 structure->fields->pdata[index] = ret_field;
572 end:
573 bt_get(ret_field);
574 error:
575 bt_put(field_type);
576 return ret_field;
577 }
578
579 BT_HIDDEN
580 int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
581 const char *name, struct bt_ctf_field *value)
582 {
583 int ret = 0;
584 GQuark field_quark;
585 struct bt_ctf_field_structure *structure;
586 struct bt_ctf_field_type *expected_field_type = NULL;
587 size_t index;
588
589 if (!field || !name || !value || field->frozen ||
590 bt_ctf_field_type_get_type_id(field->type) !=
591 BT_CTF_TYPE_ID_STRUCT) {
592 ret = -1;
593 goto end;
594 }
595
596 field_quark = g_quark_from_string(name);
597 structure = container_of(field, struct bt_ctf_field_structure, parent);
598 expected_field_type =
599 bt_ctf_field_type_structure_get_field_type_by_name(field->type,
600 name);
601
602 if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
603 ret = -1;
604 goto end;
605 }
606
607 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
608 GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
609 goto end;
610 }
611
612 if (structure->fields->pdata[index]) {
613 bt_put(structure->fields->pdata[index]);
614 }
615
616 structure->fields->pdata[index] = value;
617 bt_get(value);
618 end:
619 if (expected_field_type) {
620 bt_put(expected_field_type);
621 }
622 return ret;
623 }
624
625 struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
626 uint64_t index)
627 {
628 struct bt_ctf_field *new_field = NULL;
629 struct bt_ctf_field_type *field_type = NULL;
630 struct bt_ctf_field_array *array;
631
632 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
633 BT_CTF_TYPE_ID_ARRAY) {
634 goto end;
635 }
636
637 array = container_of(field, struct bt_ctf_field_array, parent);
638 if (index >= array->elements->len) {
639 goto end;
640 }
641
642 field_type = bt_ctf_field_type_array_get_element_type(field->type);
643 if (array->elements->pdata[(size_t)index]) {
644 new_field = array->elements->pdata[(size_t)index];
645 goto end;
646 }
647
648 /* We don't want to modify this field if it's frozen */
649 if (field->frozen) {
650 goto end;
651 }
652
653 new_field = bt_ctf_field_create(field_type);
654 array->elements->pdata[(size_t)index] = new_field;
655 end:
656 if (field_type) {
657 bt_put(field_type);
658 }
659 if (new_field) {
660 bt_get(new_field);
661 }
662 return new_field;
663 }
664
665 struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
666 uint64_t index)
667 {
668 struct bt_ctf_field *new_field = NULL;
669 struct bt_ctf_field_type *field_type = NULL;
670 struct bt_ctf_field_sequence *sequence;
671
672 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
673 BT_CTF_TYPE_ID_SEQUENCE) {
674 goto end;
675 }
676
677 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
678 if (!sequence->elements || sequence->elements->len <= index) {
679 goto end;
680 }
681
682 field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
683 if (sequence->elements->pdata[(size_t) index]) {
684 new_field = sequence->elements->pdata[(size_t) index];
685 goto end;
686 }
687
688 /* We don't want to modify this field if it's frozen */
689 if (field->frozen) {
690 goto end;
691 }
692
693 new_field = bt_ctf_field_create(field_type);
694 sequence->elements->pdata[(size_t) index] = new_field;
695 end:
696 if (field_type) {
697 bt_put(field_type);
698 }
699 if (new_field) {
700 bt_get(new_field);
701 }
702 return new_field;
703 }
704
705 struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
706 struct bt_ctf_field *tag_field)
707 {
708 struct bt_ctf_field *new_field = NULL;
709 struct bt_ctf_field_variant *variant;
710 struct bt_ctf_field_type_variant *variant_type;
711 struct bt_ctf_field_type *field_type;
712 struct bt_ctf_field *tag_enum = NULL;
713 struct bt_ctf_field_integer *tag_enum_integer;
714 int64_t tag_enum_value;
715
716 if (!field || !tag_field ||
717 bt_ctf_field_type_get_type_id(field->type) !=
718 BT_CTF_TYPE_ID_VARIANT ||
719 bt_ctf_field_type_get_type_id(tag_field->type) !=
720 BT_CTF_TYPE_ID_ENUM) {
721 goto end;
722 }
723
724 variant = container_of(field, struct bt_ctf_field_variant, parent);
725 variant_type = container_of(field->type,
726 struct bt_ctf_field_type_variant, parent);
727 tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
728 if (!tag_enum) {
729 goto end;
730 }
731
732 tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
733 parent);
734
735 if (bt_ctf_field_validate(tag_field) < 0) {
736 goto end;
737 }
738
739 tag_enum_value = tag_enum_integer->payload.signd;
740
741 /*
742 * If the variant currently has a tag and a payload, and if the
743 * requested tag value is the same as the current one, return
744 * the current payload instead of creating a fresh one.
745 */
746 if (variant->tag && variant->payload) {
747 struct bt_ctf_field *cur_tag_container = NULL;
748 struct bt_ctf_field_integer *cur_tag_enum_integer;
749 int64_t cur_tag_value;
750
751 cur_tag_container =
752 bt_ctf_field_enumeration_get_container(variant->tag);
753 assert(cur_tag_container);
754 cur_tag_enum_integer = container_of(cur_tag_container,
755 struct bt_ctf_field_integer, parent);
756 bt_put(cur_tag_container);
757 cur_tag_value = cur_tag_enum_integer->payload.signd;
758
759 if (cur_tag_value == tag_enum_value) {
760 new_field = variant->payload;
761 bt_get(new_field);
762 goto end;
763 }
764 }
765
766 /* We don't want to modify this field if it's frozen */
767 if (field->frozen) {
768 goto end;
769 }
770
771 field_type = bt_ctf_field_type_variant_get_field_type_signed(
772 variant_type, tag_enum_value);
773 if (!field_type) {
774 goto end;
775 }
776
777 new_field = bt_ctf_field_create(field_type);
778 if (!new_field) {
779 goto end;
780 }
781
782 bt_put(variant->tag);
783 bt_put(variant->payload);
784 bt_get(new_field);
785 bt_get(tag_field);
786 variant->tag = tag_field;
787 variant->payload = new_field;
788 end:
789 bt_put(tag_enum);
790 return new_field;
791 }
792
793 struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
794 struct bt_ctf_field *variant_field)
795 {
796 struct bt_ctf_field *current_field = NULL;
797 struct bt_ctf_field_variant *variant;
798
799 if (!variant_field ||
800 bt_ctf_field_type_get_type_id(variant_field->type) !=
801 BT_CTF_TYPE_ID_VARIANT) {
802 goto end;
803 }
804
805 variant = container_of(variant_field, struct bt_ctf_field_variant,
806 parent);
807
808 if (variant->payload) {
809 current_field = variant->payload;
810 bt_get(current_field);
811 goto end;
812 }
813
814 end:
815 return current_field;
816 }
817
818 struct bt_ctf_field *bt_ctf_field_variant_get_tag(
819 struct bt_ctf_field *variant_field)
820 {
821 struct bt_ctf_field *tag = NULL;
822 struct bt_ctf_field_variant *variant;
823
824 if (!variant_field ||
825 bt_ctf_field_type_get_type_id(variant_field->type) !=
826 BT_CTF_TYPE_ID_VARIANT) {
827 goto end;
828 }
829
830 variant = container_of(variant_field, struct bt_ctf_field_variant,
831 parent);
832 if (variant->tag) {
833 tag = bt_get(variant->tag);
834 }
835 end:
836 return tag;
837 }
838
839 struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
840 struct bt_ctf_field *field)
841 {
842 struct bt_ctf_field *container = NULL;
843 struct bt_ctf_field_enumeration *enumeration;
844
845 if (!field || bt_ctf_field_type_get_type_id(field->type) !=
846 BT_CTF_TYPE_ID_ENUM) {
847 goto end;
848 }
849
850 enumeration = container_of(field, struct bt_ctf_field_enumeration,
851 parent);
852 if (!enumeration->payload) {
853 /* We don't want to modify this field if it's frozen */
854 if (field->frozen) {
855 goto end;
856 }
857
858 struct bt_ctf_field_type_enumeration *enumeration_type =
859 container_of(field->type,
860 struct bt_ctf_field_type_enumeration, parent);
861 enumeration->payload =
862 bt_ctf_field_create(enumeration_type->container);
863 }
864
865 container = enumeration->payload;
866 bt_get(container);
867 end:
868 return container;
869 }
870
871 struct bt_ctf_field_type_enumeration_mapping_iterator *
872 bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *field)
873 {
874 int ret;
875 struct bt_ctf_field *container = NULL;
876 struct bt_ctf_field_type *container_type = NULL;
877 struct bt_ctf_field_type_integer *integer_type = NULL;
878 struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
879
880 container = bt_ctf_field_enumeration_get_container(field);
881 if (!container) {
882 goto end;
883 }
884
885 container_type = bt_ctf_field_get_type(container);
886 if (!container_type) {
887 goto error_put_container;
888 }
889
890 integer_type = container_of(container_type,
891 struct bt_ctf_field_type_integer, parent);
892
893 if (!integer_type->is_signed) {
894 uint64_t value;
895
896 ret = bt_ctf_field_unsigned_integer_get_value(container,
897 &value);
898 if (ret) {
899 goto error_put_container_type;
900 }
901 iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
902 field->type, value);
903 } else {
904 int64_t value;
905
906 ret = bt_ctf_field_signed_integer_get_value(container,
907 &value);
908 if (ret) {
909 goto error_put_container_type;
910 }
911 iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
912 field->type, value);
913 }
914
915 error_put_container_type:
916 bt_put(container_type);
917 error_put_container:
918 bt_put(container);
919 end:
920 return iter;
921 }
922
923 int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
924 int64_t *value)
925 {
926 int ret = 0;
927 struct bt_ctf_field_integer *integer;
928 struct bt_ctf_field_type_integer *integer_type;
929
930 if (!field || !value || !field->payload_set ||
931 bt_ctf_field_type_get_type_id(field->type) !=
932 BT_CTF_TYPE_ID_INTEGER) {
933 ret = -1;
934 goto end;
935 }
936
937 integer_type = container_of(field->type,
938 struct bt_ctf_field_type_integer, parent);
939 if (!integer_type->is_signed) {
940 ret = -1;
941 goto end;
942 }
943
944 integer = container_of(field,
945 struct bt_ctf_field_integer, parent);
946 *value = integer->payload.signd;
947 end:
948 return ret;
949 }
950
951 int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
952 int64_t value)
953 {
954 int ret = 0;
955 struct bt_ctf_field_integer *integer;
956 struct bt_ctf_field_type_integer *integer_type;
957 unsigned int size;
958 int64_t min_value, max_value;
959
960 if (!field || field->frozen ||
961 bt_ctf_field_type_get_type_id(field->type) !=
962 BT_CTF_TYPE_ID_INTEGER) {
963 ret = -1;
964 goto end;
965 }
966
967 integer = container_of(field, struct bt_ctf_field_integer, parent);
968 integer_type = container_of(field->type,
969 struct bt_ctf_field_type_integer, parent);
970 if (!integer_type->is_signed) {
971 ret = -1;
972 goto end;
973 }
974
975 size = integer_type->size;
976 min_value = -(1ULL << (size - 1));
977 max_value = (1ULL << (size - 1)) - 1;
978 if (value < min_value || value > max_value) {
979 ret = -1;
980 goto end;
981 }
982
983 integer->payload.signd = value;
984 integer->parent.payload_set = 1;
985 end:
986 return ret;
987 }
988
989 int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
990 uint64_t *value)
991 {
992 int ret = 0;
993 struct bt_ctf_field_integer *integer;
994 struct bt_ctf_field_type_integer *integer_type;
995
996 if (!field || !value || !field->payload_set ||
997 bt_ctf_field_type_get_type_id(field->type) !=
998 BT_CTF_TYPE_ID_INTEGER) {
999 ret = -1;
1000 goto end;
1001 }
1002
1003 integer_type = container_of(field->type,
1004 struct bt_ctf_field_type_integer, parent);
1005 if (integer_type->is_signed) {
1006 ret = -1;
1007 goto end;
1008 }
1009
1010 integer = container_of(field,
1011 struct bt_ctf_field_integer, parent);
1012 *value = integer->payload.unsignd;
1013 end:
1014 return ret;
1015 }
1016
1017 int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
1018 uint64_t value)
1019 {
1020 int ret = 0;
1021 struct bt_ctf_field_integer *integer;
1022 struct bt_ctf_field_type_integer *integer_type;
1023 unsigned int size;
1024 uint64_t max_value;
1025
1026 if (!field || field->frozen ||
1027 bt_ctf_field_type_get_type_id(field->type) !=
1028 BT_CTF_TYPE_ID_INTEGER) {
1029 ret = -1;
1030 goto end;
1031 }
1032
1033 integer = container_of(field, struct bt_ctf_field_integer, parent);
1034 integer_type = container_of(field->type,
1035 struct bt_ctf_field_type_integer, parent);
1036 if (integer_type->is_signed) {
1037 ret = -1;
1038 goto end;
1039 }
1040
1041 size = integer_type->size;
1042 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
1043 if (value > max_value) {
1044 ret = -1;
1045 goto end;
1046 }
1047
1048 integer->payload.unsignd = value;
1049 integer->parent.payload_set = 1;
1050 end:
1051 return ret;
1052 }
1053
1054 int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
1055 double *value)
1056 {
1057 int ret = 0;
1058 struct bt_ctf_field_floating_point *floating_point;
1059
1060 if (!field || !value || !field->payload_set ||
1061 bt_ctf_field_type_get_type_id(field->type) !=
1062 BT_CTF_TYPE_ID_FLOAT) {
1063 ret = -1;
1064 goto end;
1065 }
1066
1067 floating_point = container_of(field,
1068 struct bt_ctf_field_floating_point, parent);
1069 *value = floating_point->payload;
1070 end:
1071 return ret;
1072 }
1073
1074 int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
1075 double value)
1076 {
1077 int ret = 0;
1078 struct bt_ctf_field_floating_point *floating_point;
1079
1080 if (!field || field->frozen ||
1081 bt_ctf_field_type_get_type_id(field->type) !=
1082 BT_CTF_TYPE_ID_FLOAT) {
1083 ret = -1;
1084 goto end;
1085 }
1086 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1087 parent);
1088 floating_point->payload = value;
1089 floating_point->parent.payload_set = 1;
1090 end:
1091 return ret;
1092 }
1093
1094 const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
1095 {
1096 const char *ret = NULL;
1097 struct bt_ctf_field_string *string;
1098
1099 if (!field || !field->payload_set ||
1100 bt_ctf_field_type_get_type_id(field->type) !=
1101 BT_CTF_TYPE_ID_STRING) {
1102 goto end;
1103 }
1104
1105 string = container_of(field,
1106 struct bt_ctf_field_string, parent);
1107 ret = string->payload->str;
1108 end:
1109 return ret;
1110 }
1111
1112 int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
1113 const char *value)
1114 {
1115 int ret = 0;
1116 struct bt_ctf_field_string *string;
1117
1118 if (!field || !value || field->frozen ||
1119 bt_ctf_field_type_get_type_id(field->type) !=
1120 BT_CTF_TYPE_ID_STRING) {
1121 ret = -1;
1122 goto end;
1123 }
1124
1125 string = container_of(field, struct bt_ctf_field_string, parent);
1126 if (string->payload) {
1127 g_string_assign(string->payload, value);
1128 } else {
1129 string->payload = g_string_new(value);
1130 }
1131
1132 string->parent.payload_set = 1;
1133 end:
1134 return ret;
1135 }
1136
1137 int bt_ctf_field_string_append(struct bt_ctf_field *field,
1138 const char *value)
1139 {
1140 int ret = 0;
1141 struct bt_ctf_field_string *string_field;
1142
1143 if (!field || !value || field->frozen ||
1144 bt_ctf_field_type_get_type_id(field->type) !=
1145 BT_CTF_TYPE_ID_STRING) {
1146 ret = -1;
1147 goto end;
1148 }
1149
1150 string_field = container_of(field, struct bt_ctf_field_string, parent);
1151
1152 if (string_field->payload) {
1153 g_string_append(string_field->payload, value);
1154 } else {
1155 string_field->payload = g_string_new(value);
1156 }
1157
1158 string_field->parent.payload_set = 1;
1159
1160 end:
1161 return ret;
1162 }
1163
1164 int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
1165 const char *value, unsigned int length)
1166 {
1167 int i;
1168 int ret = 0;
1169 unsigned int effective_length = length;
1170 struct bt_ctf_field_string *string_field;
1171
1172 if (!field || !value || field->frozen ||
1173 bt_ctf_field_type_get_type_id(field->type) !=
1174 BT_CTF_TYPE_ID_STRING) {
1175 ret = -1;
1176 goto end;
1177 }
1178
1179 string_field = container_of(field, struct bt_ctf_field_string, parent);
1180
1181 /* make sure no null bytes are appended */
1182 for (i = 0; i < length; ++i) {
1183 if (value[i] == '\0') {
1184 effective_length = i;
1185 break;
1186 }
1187 }
1188
1189 if (string_field->payload) {
1190 g_string_append_len(string_field->payload, value,
1191 effective_length);
1192 } else {
1193 string_field->payload = g_string_new_len(value,
1194 effective_length);
1195 }
1196
1197 string_field->parent.payload_set = 1;
1198
1199 end:
1200 return ret;
1201 }
1202
1203 BT_HIDDEN
1204 int bt_ctf_field_validate(struct bt_ctf_field *field)
1205 {
1206 int ret = 0;
1207 enum bt_ctf_type_id type_id;
1208
1209 if (!field) {
1210 ret = -1;
1211 goto end;
1212 }
1213
1214 type_id = bt_ctf_field_type_get_type_id(field->type);
1215 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1216 ret = -1;
1217 goto end;
1218 }
1219
1220 ret = field_validate_funcs[type_id](field);
1221 end:
1222 return ret;
1223 }
1224
1225 BT_HIDDEN
1226 int bt_ctf_field_reset(struct bt_ctf_field *field)
1227 {
1228 int ret = 0;
1229 enum bt_ctf_type_id type_id;
1230
1231 if (!field) {
1232 ret = -1;
1233 goto end;
1234 }
1235
1236 type_id = bt_ctf_field_type_get_type_id(field->type);
1237 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1238 ret = -1;
1239 goto end;
1240 }
1241
1242 ret = field_reset_funcs[type_id](field);
1243 end:
1244 return ret;
1245 }
1246
1247 BT_HIDDEN
1248 int bt_ctf_field_serialize(struct bt_ctf_field *field,
1249 struct bt_ctf_stream_pos *pos,
1250 enum bt_ctf_byte_order native_byte_order)
1251 {
1252 int ret = 0;
1253 enum bt_ctf_type_id type_id;
1254
1255 if (!field || !pos) {
1256 ret = -1;
1257 goto end;
1258 }
1259
1260 type_id = bt_ctf_field_type_get_type_id(field->type);
1261 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1262 ret = -1;
1263 goto end;
1264 }
1265
1266 ret = field_serialize_funcs[type_id](field, pos, native_byte_order);
1267 end:
1268 return ret;
1269 }
1270
1271
1272 BT_HIDDEN
1273 bool bt_ctf_field_is_set(struct bt_ctf_field *field)
1274 {
1275 bool is_set = false;
1276 enum bt_ctf_type_id type_id;
1277
1278 if (!field) {
1279 goto end;
1280 }
1281
1282 type_id = bt_ctf_field_type_get_type_id(field->type);
1283 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1284 goto end;
1285 }
1286
1287 is_set = field_is_set_funcs[type_id](field);
1288 end:
1289 return is_set;
1290 }
1291
1292 struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
1293 {
1294 int ret;
1295 struct bt_ctf_field *copy = NULL;
1296 enum bt_ctf_type_id type_id;
1297
1298 if (!field) {
1299 goto end;
1300 }
1301
1302 type_id = bt_ctf_field_type_get_type_id(field->type);
1303 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
1304 goto end;
1305 }
1306
1307 copy = bt_ctf_field_create(field->type);
1308 if (!copy) {
1309 goto end;
1310 }
1311
1312 copy->payload_set = field->payload_set;
1313 ret = field_copy_funcs[type_id](field, copy);
1314 if (ret) {
1315 bt_put(copy);
1316 copy = NULL;
1317 }
1318 end:
1319 return copy;
1320 }
1321
1322 static
1323 struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
1324 {
1325 struct bt_ctf_field_integer *integer = g_new0(
1326 struct bt_ctf_field_integer, 1);
1327
1328 return integer ? &integer->parent : NULL;
1329 }
1330
1331 static
1332 struct bt_ctf_field *bt_ctf_field_enumeration_create(
1333 struct bt_ctf_field_type *type)
1334 {
1335 struct bt_ctf_field_enumeration *enumeration = g_new0(
1336 struct bt_ctf_field_enumeration, 1);
1337
1338 return enumeration ? &enumeration->parent : NULL;
1339 }
1340
1341 static
1342 struct bt_ctf_field *bt_ctf_field_floating_point_create(
1343 struct bt_ctf_field_type *type)
1344 {
1345 struct bt_ctf_field_floating_point *floating_point;
1346
1347 floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
1348 return floating_point ? &floating_point->parent : NULL;
1349 }
1350
1351 static
1352 struct bt_ctf_field *bt_ctf_field_structure_create(
1353 struct bt_ctf_field_type *type)
1354 {
1355 struct bt_ctf_field_type_structure *structure_type = container_of(type,
1356 struct bt_ctf_field_type_structure, parent);
1357 struct bt_ctf_field_structure *structure = g_new0(
1358 struct bt_ctf_field_structure, 1);
1359 struct bt_ctf_field *field = NULL;
1360
1361 if (!structure) {
1362 goto end;
1363 }
1364
1365 structure->field_name_to_index = structure_type->field_name_to_index;
1366 structure->fields = g_ptr_array_new_with_free_func(
1367 (GDestroyNotify)bt_ctf_field_put);
1368 g_ptr_array_set_size(structure->fields,
1369 g_hash_table_size(structure->field_name_to_index));
1370 field = &structure->parent;
1371 end:
1372 return field;
1373 }
1374
1375 static
1376 struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
1377 {
1378 struct bt_ctf_field_variant *variant = g_new0(
1379 struct bt_ctf_field_variant, 1);
1380 return variant ? &variant->parent : NULL;
1381 }
1382
1383 static
1384 struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
1385 {
1386 struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
1387 struct bt_ctf_field_type_array *array_type;
1388 unsigned int array_length;
1389
1390 if (!array || !type) {
1391 goto error;
1392 }
1393
1394 array_type = container_of(type, struct bt_ctf_field_type_array, parent);
1395 array_length = array_type->length;
1396 array->elements = g_ptr_array_sized_new(array_length);
1397 if (!array->elements) {
1398 goto error;
1399 }
1400
1401 g_ptr_array_set_free_func(array->elements,
1402 (GDestroyNotify)bt_ctf_field_put);
1403 g_ptr_array_set_size(array->elements, array_length);
1404 return &array->parent;
1405 error:
1406 g_free(array);
1407 return NULL;
1408 }
1409
1410 static
1411 struct bt_ctf_field *bt_ctf_field_sequence_create(
1412 struct bt_ctf_field_type *type)
1413 {
1414 struct bt_ctf_field_sequence *sequence = g_new0(
1415 struct bt_ctf_field_sequence, 1);
1416 return sequence ? &sequence->parent : NULL;
1417 }
1418
1419 static
1420 struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
1421 {
1422 struct bt_ctf_field_string *string = g_new0(
1423 struct bt_ctf_field_string, 1);
1424 return string ? &string->parent : NULL;
1425 }
1426
1427 static
1428 void bt_ctf_field_destroy(struct bt_object *obj)
1429 {
1430 struct bt_ctf_field *field;
1431 struct bt_ctf_field_type *type;
1432 enum bt_ctf_type_id type_id;
1433
1434 field = container_of(obj, struct bt_ctf_field, base);
1435 type = field->type;
1436 type_id = bt_ctf_field_type_get_type_id(type);
1437 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
1438 type_id >= BT_CTF_NR_TYPE_IDS) {
1439 return;
1440 }
1441
1442 field_destroy_funcs[type_id](field);
1443 bt_put(type);
1444 }
1445
1446 static
1447 void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
1448 {
1449 struct bt_ctf_field_integer *integer;
1450
1451 if (!field) {
1452 return;
1453 }
1454
1455 integer = container_of(field, struct bt_ctf_field_integer, parent);
1456 g_free(integer);
1457 }
1458
1459 static
1460 void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
1461 {
1462 struct bt_ctf_field_enumeration *enumeration;
1463
1464 if (!field) {
1465 return;
1466 }
1467
1468 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1469 parent);
1470 bt_put(enumeration->payload);
1471 g_free(enumeration);
1472 }
1473
1474 static
1475 void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
1476 {
1477 struct bt_ctf_field_floating_point *floating_point;
1478
1479 if (!field) {
1480 return;
1481 }
1482
1483 floating_point = container_of(field, struct bt_ctf_field_floating_point,
1484 parent);
1485 g_free(floating_point);
1486 }
1487
1488 static
1489 void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
1490 {
1491 struct bt_ctf_field_structure *structure;
1492
1493 if (!field) {
1494 return;
1495 }
1496
1497 structure = container_of(field, struct bt_ctf_field_structure, parent);
1498 g_ptr_array_free(structure->fields, TRUE);
1499 g_free(structure);
1500 }
1501
1502 static
1503 void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
1504 {
1505 struct bt_ctf_field_variant *variant;
1506
1507 if (!field) {
1508 return;
1509 }
1510
1511 variant = container_of(field, struct bt_ctf_field_variant, parent);
1512 bt_put(variant->tag);
1513 bt_put(variant->payload);
1514 g_free(variant);
1515 }
1516
1517 static
1518 void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
1519 {
1520 struct bt_ctf_field_array *array;
1521
1522 if (!field) {
1523 return;
1524 }
1525
1526 array = container_of(field, struct bt_ctf_field_array, parent);
1527 g_ptr_array_free(array->elements, TRUE);
1528 g_free(array);
1529 }
1530
1531 static
1532 void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
1533 {
1534 struct bt_ctf_field_sequence *sequence;
1535
1536 if (!field) {
1537 return;
1538 }
1539
1540 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1541 if (sequence->elements) {
1542 g_ptr_array_free(sequence->elements, TRUE);
1543 }
1544 bt_put(sequence->length);
1545 g_free(sequence);
1546 }
1547
1548 static
1549 void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
1550 {
1551 struct bt_ctf_field_string *string;
1552 if (!field) {
1553 return;
1554 }
1555
1556 string = container_of(field, struct bt_ctf_field_string, parent);
1557 if (string->payload) {
1558 g_string_free(string->payload, TRUE);
1559 }
1560 g_free(string);
1561 }
1562
1563 static
1564 int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
1565 {
1566 return (field && field->payload_set) ? 0 : -1;
1567 }
1568
1569 static
1570 int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
1571 {
1572 int ret;
1573 struct bt_ctf_field_enumeration *enumeration;
1574
1575 if (!field) {
1576 ret = -1;
1577 goto end;
1578 }
1579
1580 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1581 parent);
1582 if (!enumeration->payload) {
1583 ret = -1;
1584 goto end;
1585 }
1586
1587 ret = bt_ctf_field_validate(enumeration->payload);
1588 end:
1589 return ret;
1590 }
1591
1592 static
1593 int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
1594 {
1595 size_t i;
1596 int ret = 0;
1597 struct bt_ctf_field_structure *structure;
1598
1599 if (!field) {
1600 ret = -1;
1601 goto end;
1602 }
1603
1604 structure = container_of(field, struct bt_ctf_field_structure, parent);
1605 for (i = 0; i < structure->fields->len; i++) {
1606 ret = bt_ctf_field_validate(structure->fields->pdata[i]);
1607 if (ret) {
1608 const char *name;
1609 struct bt_ctf_field_type *field_type =
1610 bt_ctf_field_get_type(field);
1611
1612 (void) bt_ctf_field_type_structure_get_field(field_type,
1613 &name, NULL, i);
1614 fprintf(stderr, "Field %s failed validation\n",
1615 name ? name : "NULL");
1616 bt_put(field_type);
1617 goto end;
1618 }
1619 }
1620 end:
1621 return ret;
1622 }
1623
1624 static
1625 int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
1626 {
1627 int ret = 0;
1628 struct bt_ctf_field_variant *variant;
1629
1630 if (!field) {
1631 ret = -1;
1632 goto end;
1633 }
1634
1635 variant = container_of(field, struct bt_ctf_field_variant, parent);
1636 ret = bt_ctf_field_validate(variant->payload);
1637 end:
1638 return ret;
1639 }
1640
1641 static
1642 int bt_ctf_field_array_validate(struct bt_ctf_field *field)
1643 {
1644 size_t i;
1645 int ret = 0;
1646 struct bt_ctf_field_array *array;
1647
1648 if (!field) {
1649 ret = -1;
1650 goto end;
1651 }
1652
1653 array = container_of(field, struct bt_ctf_field_array, parent);
1654 for (i = 0; i < array->elements->len; i++) {
1655 ret = bt_ctf_field_validate(array->elements->pdata[i]);
1656 if (ret) {
1657 fprintf(stderr, "Failed to validate array field #%zu\n", i);
1658 goto end;
1659 }
1660 }
1661 end:
1662 return ret;
1663 }
1664
1665 static
1666 int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
1667 {
1668 size_t i;
1669 int ret = 0;
1670 struct bt_ctf_field_sequence *sequence;
1671
1672 if (!field) {
1673 ret = -1;
1674 goto end;
1675 }
1676
1677 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1678 for (i = 0; i < sequence->elements->len; i++) {
1679 ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
1680 if (ret) {
1681 fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
1682 goto end;
1683 }
1684 }
1685 end:
1686 return ret;
1687 }
1688
1689 static
1690 int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
1691 {
1692 int ret = 0;
1693
1694 if (!field) {
1695 ret = -1;
1696 goto end;
1697 }
1698
1699 field->payload_set = 0;
1700 end:
1701 return ret;
1702 }
1703
1704 static
1705 int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
1706 {
1707 int ret = 0;
1708 struct bt_ctf_field_enumeration *enumeration;
1709
1710 if (!field) {
1711 ret = -1;
1712 goto end;
1713 }
1714
1715 enumeration = container_of(field, struct bt_ctf_field_enumeration,
1716 parent);
1717 if (!enumeration->payload) {
1718 goto end;
1719 }
1720
1721 ret = bt_ctf_field_reset(enumeration->payload);
1722 end:
1723 return ret;
1724 }
1725
1726 static
1727 int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
1728 {
1729 size_t i;
1730 int ret = 0;
1731 struct bt_ctf_field_structure *structure;
1732
1733 if (!field) {
1734 ret = -1;
1735 goto end;
1736 }
1737
1738 structure = container_of(field, struct bt_ctf_field_structure, parent);
1739 for (i = 0; i < structure->fields->len; i++) {
1740 struct bt_ctf_field *member = structure->fields->pdata[i];
1741
1742 if (!member) {
1743 /*
1744 * Structure members are lazily initialized; skip if
1745 * this member has not been allocated yet.
1746 */
1747 continue;
1748 }
1749
1750 ret = bt_ctf_field_reset(member);
1751 if (ret) {
1752 goto end;
1753 }
1754 }
1755 end:
1756 return ret;
1757 }
1758
1759 static
1760 int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
1761 {
1762 int ret = 0;
1763 struct bt_ctf_field_variant *variant;
1764
1765 if (!field) {
1766 ret = -1;
1767 goto end;
1768 }
1769
1770 variant = container_of(field, struct bt_ctf_field_variant, parent);
1771 if (variant->payload) {
1772 ret = bt_ctf_field_reset(variant->payload);
1773 }
1774 end:
1775 return ret;
1776 }
1777
1778 static
1779 int bt_ctf_field_array_reset(struct bt_ctf_field *field)
1780 {
1781 size_t i;
1782 int ret = 0;
1783 struct bt_ctf_field_array *array;
1784
1785 if (!field) {
1786 ret = -1;
1787 goto end;
1788 }
1789
1790 array = container_of(field, struct bt_ctf_field_array, parent);
1791 for (i = 0; i < array->elements->len; i++) {
1792 struct bt_ctf_field *member = array->elements->pdata[i];
1793
1794 if (!member) {
1795 /*
1796 * Array elements are lazily initialized; skip if
1797 * this member has not been allocated yet.
1798 */
1799 continue;
1800 }
1801
1802 ret = bt_ctf_field_reset(member);
1803 if (ret) {
1804 goto end;
1805 }
1806 }
1807 end:
1808 return ret;
1809 }
1810
1811 static
1812 int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
1813 {
1814 size_t i;
1815 int ret = 0;
1816 struct bt_ctf_field_sequence *sequence;
1817
1818 if (!field) {
1819 ret = -1;
1820 goto end;
1821 }
1822
1823 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
1824 for (i = 0; i < sequence->elements->len; i++) {
1825 struct bt_ctf_field *member = sequence->elements->pdata[i];
1826
1827 if (!member) {
1828 /*
1829 * Sequence elements are lazily initialized; skip if
1830 * this member has not been allocated yet.
1831 */
1832 continue;
1833 }
1834
1835 ret = bt_ctf_field_reset(member);
1836 if (ret) {
1837 goto end;
1838 }
1839 }
1840 end:
1841 return ret;
1842 }
1843
1844 static
1845 int bt_ctf_field_string_reset(struct bt_ctf_field *field)
1846 {
1847 int ret = 0;
1848 struct bt_ctf_field_string *string;
1849
1850 if (!field) {
1851 ret = -1;
1852 goto end;
1853 }
1854
1855 ret = bt_ctf_field_generic_reset(field);
1856 if (ret) {
1857 goto end;
1858 }
1859
1860 string = container_of(field, struct bt_ctf_field_string, parent);
1861 if (string->payload) {
1862 g_string_truncate(string->payload, 0);
1863 }
1864 end:
1865 return ret;
1866 }
1867
1868 static
1869 int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
1870 struct bt_ctf_stream_pos *pos,
1871 enum bt_ctf_byte_order native_byte_order)
1872 {
1873 int ret = 0;
1874 struct bt_ctf_field_integer *integer = container_of(field,
1875 struct bt_ctf_field_integer, parent);
1876
1877 if (!bt_ctf_field_generic_is_set(field)) {
1878 ret = -1;
1879 goto end;
1880 }
1881 retry:
1882 ret = bt_ctf_field_integer_write(integer, pos, native_byte_order);
1883 if (ret == -EFAULT) {
1884 /*
1885 * The field is too large to fit in the current packet's
1886 * remaining space. Bump the packet size and retry.
1887 */
1888 ret = increase_packet_size(pos);
1889 if (ret) {
1890 goto end;
1891 }
1892 goto retry;
1893 }
1894 end:
1895 return ret;
1896 }
1897
1898 static
1899 int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
1900 struct bt_ctf_stream_pos *pos,
1901 enum bt_ctf_byte_order native_byte_order)
1902 {
1903 struct bt_ctf_field_enumeration *enumeration = container_of(
1904 field, struct bt_ctf_field_enumeration, parent);
1905
1906 return bt_ctf_field_serialize(enumeration->payload, pos,
1907 native_byte_order);
1908 }
1909
1910 static
1911 int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
1912 struct bt_ctf_stream_pos *pos,
1913 enum bt_ctf_byte_order native_byte_order)
1914 {
1915 int ret = 0;
1916 struct bt_ctf_field_floating_point *floating_point = container_of(field,
1917 struct bt_ctf_field_floating_point, parent);
1918
1919 if (!bt_ctf_field_generic_is_set(field)) {
1920 ret = -1;
1921 goto end;
1922 }
1923 retry:
1924 ret = bt_ctf_field_floating_point_write(floating_point, pos,
1925 native_byte_order);
1926 if (ret == -EFAULT) {
1927 /*
1928 * The field is too large to fit in the current packet's
1929 * remaining space. Bump the packet size and retry.
1930 */
1931 ret = increase_packet_size(pos);
1932 if (ret) {
1933 goto end;
1934 }
1935 goto retry;
1936 }
1937 end:
1938 return ret;
1939 }
1940
1941 static
1942 int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
1943 struct bt_ctf_stream_pos *pos,
1944 enum bt_ctf_byte_order native_byte_order)
1945 {
1946 size_t i;
1947 int ret = 0;
1948 struct bt_ctf_field_structure *structure = container_of(
1949 field, struct bt_ctf_field_structure, parent);
1950
1951 while (!bt_ctf_stream_pos_access_ok(pos,
1952 offset_align(pos->offset, field->type->alignment))) {
1953 ret = increase_packet_size(pos);
1954 if (ret) {
1955 goto end;
1956 }
1957 }
1958
1959 if (!bt_ctf_stream_pos_align(pos, field->type->alignment)) {
1960 ret = -1;
1961 goto end;
1962 }
1963
1964 for (i = 0; i < structure->fields->len; i++) {
1965 struct bt_ctf_field *member = g_ptr_array_index(
1966 structure->fields, i);
1967
1968 ret = bt_ctf_field_serialize(member, pos, native_byte_order);
1969 if (ret) {
1970 const char *name;
1971 struct bt_ctf_field_type *structure_type =
1972 bt_ctf_field_get_type(field);
1973
1974 (void) bt_ctf_field_type_structure_get_field(
1975 structure_type, &name, NULL, i);
1976 fprintf(stderr, "Field %s failed to serialize\n",
1977 name ? name : "NULL");
1978 bt_put(structure_type);
1979 break;
1980 }
1981 }
1982 end:
1983 return ret;
1984 }
1985
1986 static
1987 int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
1988 struct bt_ctf_stream_pos *pos,
1989 enum bt_ctf_byte_order native_byte_order)
1990 {
1991 struct bt_ctf_field_variant *variant = container_of(
1992 field, struct bt_ctf_field_variant, parent);
1993
1994 return bt_ctf_field_serialize(variant->payload, pos,
1995 native_byte_order);
1996 }
1997
1998 static
1999 int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
2000 struct bt_ctf_stream_pos *pos,
2001 enum bt_ctf_byte_order native_byte_order)
2002 {
2003 size_t i;
2004 int ret = 0;
2005 struct bt_ctf_field_array *array = container_of(
2006 field, struct bt_ctf_field_array, parent);
2007
2008 for (i = 0; i < array->elements->len; i++) {
2009 ret = bt_ctf_field_serialize(
2010 g_ptr_array_index(array->elements, i), pos,
2011 native_byte_order);
2012 if (ret) {
2013 fprintf(stderr, "Failed to serialize array element #%zu\n", i);
2014 goto end;
2015 }
2016 }
2017 end:
2018 return ret;
2019 }
2020
2021 static
2022 int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
2023 struct bt_ctf_stream_pos *pos,
2024 enum bt_ctf_byte_order native_byte_order)
2025 {
2026 size_t i;
2027 int ret = 0;
2028 struct bt_ctf_field_sequence *sequence = container_of(
2029 field, struct bt_ctf_field_sequence, parent);
2030
2031 for (i = 0; i < sequence->elements->len; i++) {
2032 ret = bt_ctf_field_serialize(
2033 g_ptr_array_index(sequence->elements, i), pos,
2034 native_byte_order);
2035 if (ret) {
2036 fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
2037 goto end;
2038 }
2039 }
2040 end:
2041 return ret;
2042 }
2043
2044 static
2045 int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
2046 struct bt_ctf_stream_pos *pos,
2047 enum bt_ctf_byte_order native_byte_order)
2048 {
2049 size_t i;
2050 int ret = 0;
2051 struct bt_ctf_field_string *string = container_of(field,
2052 struct bt_ctf_field_string, parent);
2053 struct bt_ctf_field_type *character_type =
2054 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
2055 struct bt_ctf_field *character = bt_ctf_field_create(character_type);
2056
2057 for (i = 0; i < string->payload->len + 1; i++) {
2058 ret = bt_ctf_field_unsigned_integer_set_value(character,
2059 (uint64_t) string->payload->str[i]);
2060 if (ret) {
2061 goto end;
2062 }
2063
2064 ret = bt_ctf_field_integer_serialize(character, pos,
2065 native_byte_order);
2066 if (ret) {
2067 goto end;
2068 }
2069 }
2070 end:
2071 bt_put(character);
2072 bt_put(character_type);
2073 return ret;
2074 }
2075
2076 static
2077 int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
2078 struct bt_ctf_field *dst)
2079 {
2080 struct bt_ctf_field_integer *integer_src, *integer_dst;
2081
2082 integer_src = container_of(src, struct bt_ctf_field_integer, parent);
2083 integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
2084 integer_dst->payload = integer_src->payload;
2085 return 0;
2086 }
2087
2088 static
2089 int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
2090 struct bt_ctf_field *dst)
2091 {
2092 int ret = 0;
2093 struct bt_ctf_field_enumeration *enum_src, *enum_dst;
2094
2095 enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
2096 enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
2097
2098 if (enum_src->payload) {
2099 enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
2100 if (!enum_dst->payload) {
2101 ret = -1;
2102 goto end;
2103 }
2104 }
2105 end:
2106 return ret;
2107 }
2108
2109 static
2110 int bt_ctf_field_floating_point_copy(
2111 struct bt_ctf_field *src, struct bt_ctf_field *dst)
2112 {
2113 struct bt_ctf_field_floating_point *float_src, *float_dst;
2114
2115 float_src = container_of(src, struct bt_ctf_field_floating_point,
2116 parent);
2117 float_dst = container_of(dst, struct bt_ctf_field_floating_point,
2118 parent);
2119 float_dst->payload = float_src->payload;
2120 return 0;
2121 }
2122
2123 static
2124 int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
2125 struct bt_ctf_field *dst)
2126 {
2127 int ret = 0, i;
2128 struct bt_ctf_field_structure *struct_src, *struct_dst;
2129
2130 struct_src = container_of(src, struct bt_ctf_field_structure, parent);
2131 struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
2132
2133 /* This field_name_to_index HT is owned by the structure field type */
2134 struct_dst->field_name_to_index = struct_src->field_name_to_index;
2135 g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
2136
2137 for (i = 0; i < struct_src->fields->len; i++) {
2138 struct bt_ctf_field *field =
2139 g_ptr_array_index(struct_src->fields, i);
2140 struct bt_ctf_field *field_copy = NULL;
2141
2142 if (field) {
2143 field_copy = bt_ctf_field_copy(field);
2144
2145 if (!field_copy) {
2146 ret = -1;
2147 goto end;
2148 }
2149 }
2150
2151 g_ptr_array_index(struct_dst->fields, i) = field_copy;
2152 }
2153 end:
2154 return ret;
2155 }
2156
2157 static
2158 int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
2159 struct bt_ctf_field *dst)
2160 {
2161 int ret = 0;
2162 struct bt_ctf_field_variant *variant_src, *variant_dst;
2163
2164 variant_src = container_of(src, struct bt_ctf_field_variant, parent);
2165 variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
2166
2167 if (variant_src->tag) {
2168 variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
2169 if (!variant_dst->tag) {
2170 ret = -1;
2171 goto end;
2172 }
2173 }
2174 if (variant_src->payload) {
2175 variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
2176 if (!variant_dst->payload) {
2177 ret = -1;
2178 goto end;
2179 }
2180 }
2181 end:
2182 return ret;
2183 }
2184
2185 static
2186 int bt_ctf_field_array_copy(struct bt_ctf_field *src,
2187 struct bt_ctf_field *dst)
2188 {
2189 int ret = 0, i;
2190 struct bt_ctf_field_array *array_src, *array_dst;
2191
2192 array_src = container_of(src, struct bt_ctf_field_array, parent);
2193 array_dst = container_of(dst, struct bt_ctf_field_array, parent);
2194
2195 g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
2196 for (i = 0; i < array_src->elements->len; i++) {
2197 struct bt_ctf_field *field =
2198 g_ptr_array_index(array_src->elements, i);
2199 struct bt_ctf_field *field_copy = NULL;
2200
2201 if (field) {
2202 field_copy = bt_ctf_field_copy(field);
2203
2204 if (!field_copy) {
2205 ret = -1;
2206 goto end;
2207 }
2208 }
2209
2210 g_ptr_array_index(array_dst->elements, i) = field_copy;
2211 }
2212 end:
2213 return ret;
2214 }
2215
2216 static
2217 int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
2218 struct bt_ctf_field *dst)
2219 {
2220 int ret = 0, i;
2221 struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
2222 struct bt_ctf_field *src_length;
2223 struct bt_ctf_field *dst_length;
2224
2225 sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
2226 sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
2227
2228 src_length = bt_ctf_field_sequence_get_length(src);
2229
2230 if (!src_length) {
2231 /* no length set yet: keep destination sequence empty */
2232 goto end;
2233 }
2234
2235 /* copy source length */
2236 dst_length = bt_ctf_field_copy(src_length);
2237 bt_put(src_length);
2238
2239 if (!dst_length) {
2240 ret = -1;
2241 goto end;
2242 }
2243
2244 /* this will initialize the destination sequence's internal array */
2245 ret = bt_ctf_field_sequence_set_length(dst, dst_length);
2246 bt_put(dst_length);
2247
2248 if (ret) {
2249 goto end;
2250 }
2251
2252 assert(sequence_dst->elements->len == sequence_src->elements->len);
2253
2254 for (i = 0; i < sequence_src->elements->len; i++) {
2255 struct bt_ctf_field *field =
2256 g_ptr_array_index(sequence_src->elements, i);
2257 struct bt_ctf_field *field_copy = NULL;
2258
2259 if (field) {
2260 field_copy = bt_ctf_field_copy(field);
2261
2262 if (!field_copy) {
2263 ret = -1;
2264 goto end;
2265 }
2266 }
2267
2268 g_ptr_array_index(sequence_dst->elements, i) = field_copy;
2269 }
2270 end:
2271 return ret;
2272 }
2273
2274 static
2275 int bt_ctf_field_string_copy(struct bt_ctf_field *src,
2276 struct bt_ctf_field *dst)
2277 {
2278 int ret = 0;
2279 struct bt_ctf_field_string *string_src, *string_dst;
2280
2281 string_src = container_of(src, struct bt_ctf_field_string, parent);
2282 string_dst = container_of(dst, struct bt_ctf_field_string, parent);
2283
2284 if (string_src->payload) {
2285 string_dst->payload = g_string_new(string_src->payload->str);
2286 if (!string_dst->payload) {
2287 ret = -1;
2288 goto end;
2289 }
2290 }
2291 end:
2292 return ret;
2293 }
2294
2295 static
2296 int increase_packet_size(struct bt_ctf_stream_pos *pos)
2297 {
2298 int ret;
2299
2300 assert(pos);
2301 ret = munmap_align(pos->base_mma);
2302 if (ret) {
2303 goto end;
2304 }
2305
2306 pos->packet_size += PACKET_LEN_INCREMENT;
2307 do {
2308 ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
2309 pos->packet_size / CHAR_BIT);
2310 } while (ret == EINTR);
2311 if (ret) {
2312 errno = EINTR;
2313 ret = -1;
2314 goto end;
2315 }
2316
2317 pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
2318 pos->flags, pos->fd, pos->mmap_offset);
2319 if (pos->base_mma == MAP_FAILED) {
2320 ret = -1;
2321 }
2322 end:
2323 return ret;
2324 }
2325
2326 static
2327 void generic_field_freeze(struct bt_ctf_field *field)
2328 {
2329 field->frozen = 1;
2330 }
2331
2332 static
2333 void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
2334 {
2335 struct bt_ctf_field_enumeration *enum_field =
2336 container_of(field, struct bt_ctf_field_enumeration, parent);
2337
2338 bt_ctf_field_freeze(enum_field->payload);
2339 generic_field_freeze(field);
2340 }
2341
2342 static
2343 void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
2344 {
2345 int i;
2346 struct bt_ctf_field_structure *structure_field =
2347 container_of(field, struct bt_ctf_field_structure, parent);
2348
2349 for (i = 0; i < structure_field->fields->len; i++) {
2350 struct bt_ctf_field *field =
2351 g_ptr_array_index(structure_field->fields, i);
2352
2353 bt_ctf_field_freeze(field);
2354 }
2355
2356 generic_field_freeze(field);
2357 }
2358
2359 static
2360 void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
2361 {
2362 struct bt_ctf_field_variant *variant_field =
2363 container_of(field, struct bt_ctf_field_variant, parent);
2364
2365 bt_ctf_field_freeze(variant_field->tag);
2366 bt_ctf_field_freeze(variant_field->payload);
2367 generic_field_freeze(field);
2368 }
2369
2370 static
2371 void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
2372 {
2373 int i;
2374 struct bt_ctf_field_array *array_field =
2375 container_of(field, struct bt_ctf_field_array, parent);
2376
2377 for (i = 0; i < array_field->elements->len; i++) {
2378 struct bt_ctf_field *field =
2379 g_ptr_array_index(array_field->elements, i);
2380
2381 bt_ctf_field_freeze(field);
2382 }
2383
2384 generic_field_freeze(field);
2385 }
2386
2387 static
2388 void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
2389 {
2390 int i;
2391 struct bt_ctf_field_sequence *sequence_field =
2392 container_of(field, struct bt_ctf_field_sequence, parent);
2393
2394 bt_ctf_field_freeze(sequence_field->length);
2395
2396 for (i = 0; i < sequence_field->elements->len; i++) {
2397 struct bt_ctf_field *field =
2398 g_ptr_array_index(sequence_field->elements, i);
2399
2400 bt_ctf_field_freeze(field);
2401 }
2402
2403 generic_field_freeze(field);
2404 }
2405
2406 BT_HIDDEN
2407 void bt_ctf_field_freeze(struct bt_ctf_field *field)
2408 {
2409 enum bt_ctf_type_id type_id;
2410
2411 if (!field) {
2412 goto end;
2413 }
2414
2415 type_id = bt_ctf_field_get_type_id(field);
2416 if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
2417 type_id >= BT_CTF_NR_TYPE_IDS) {
2418 goto end;
2419 }
2420
2421 field_freeze_funcs[type_id](field);
2422 end:
2423 return;
2424 }
2425
2426 static
2427 bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
2428 {
2429 return field && field->payload_set;
2430 }
2431
2432 static
2433 bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
2434 {
2435 bool is_set = false;
2436 struct bt_ctf_field_enumeration *enumeration;
2437
2438 if (!field) {
2439 goto end;
2440 }
2441
2442 enumeration = container_of(field, struct bt_ctf_field_enumeration,
2443 parent);
2444 if (!enumeration->payload) {
2445 goto end;
2446 }
2447
2448 is_set = bt_ctf_field_is_set(enumeration->payload);
2449 end:
2450 return is_set;
2451 }
2452
2453 static
2454 bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
2455 {
2456 bool is_set = false;
2457 size_t i;
2458 struct bt_ctf_field_structure *structure;
2459
2460 if (!field) {
2461 goto end;
2462 }
2463
2464 structure = container_of(field, struct bt_ctf_field_structure, parent);
2465 for (i = 0; i < structure->fields->len; i++) {
2466 is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
2467 if (!is_set) {
2468 goto end;
2469 }
2470 }
2471 end:
2472 return is_set;
2473 }
2474
2475 static
2476 bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
2477 {
2478 bool is_set = false;
2479 struct bt_ctf_field_variant *variant;
2480
2481 if (!field) {
2482 goto end;
2483 }
2484
2485 variant = container_of(field, struct bt_ctf_field_variant, parent);
2486 is_set = bt_ctf_field_is_set(variant->payload);
2487 end:
2488 return is_set;
2489 }
2490
2491 static
2492 bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
2493 {
2494 size_t i;
2495 bool is_set = false;
2496 struct bt_ctf_field_array *array;
2497
2498 if (!field) {
2499 goto end;
2500 }
2501
2502 array = container_of(field, struct bt_ctf_field_array, parent);
2503 for (i = 0; i < array->elements->len; i++) {
2504 is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
2505 if (!is_set) {
2506 goto end;
2507 }
2508 }
2509 end:
2510 return is_set;
2511 }
2512
2513 static
2514 bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
2515 {
2516 size_t i;
2517 bool is_set = false;
2518 struct bt_ctf_field_sequence *sequence;
2519
2520 if (!field) {
2521 goto end;
2522 }
2523
2524 sequence = container_of(field, struct bt_ctf_field_sequence, parent);
2525 for (i = 0; i < sequence->elements->len; i++) {
2526 is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
2527 if (!is_set) {
2528 goto end;
2529 }
2530 }
2531 end:
2532 return is_set;
2533 }
This page took 0.082816 seconds and 4 git commands to generate.