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