lib: merge common CTF IR part with the remaining implementation
[babeltrace.git] / lib / ctf-ir / fields.c
1 /*
2 * fields.c
3 *
4 * Babeltrace CTF IR - Event Fields
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 #define BT_LOG_TAG "FIELDS"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/assert-pre-internal.h>
33 #include <babeltrace/ctf-ir/fields.h>
34 #include <babeltrace/ctf-ir/fields-internal.h>
35 #include <babeltrace/ctf-ir/field-types-internal.h>
36 #include <babeltrace/object-internal.h>
37 #include <babeltrace/ref.h>
38 #include <babeltrace/compiler-internal.h>
39 #include <babeltrace/compat/fcntl-internal.h>
40 #include <babeltrace/align-internal.h>
41 #include <babeltrace/assert-internal.h>
42 #include <inttypes.h>
43
44 #define BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(_field, _name) \
45 BT_ASSERT_PRE((_field)->type->id == BT_FIELD_TYPE_ID_INTEGER || \
46 (_field)->type->id == BT_FIELD_TYPE_ID_ENUM, \
47 _name " is not an integer or an enumeration field: " \
48 "%!+f", (_field))
49
50 static
51 int bt_field_generic_validate(struct bt_field *field);
52
53 static
54 int bt_field_structure_validate_recursive(struct bt_field *field);
55
56 static
57 int bt_field_variant_validate_recursive(struct bt_field *field);
58
59 static
60 int bt_field_array_validate_recursive(struct bt_field *field);
61
62 static
63 int bt_field_sequence_validate_recursive(struct bt_field *field);
64
65 static
66 void bt_field_generic_reset(struct bt_field *field);
67
68 static
69 void bt_field_structure_reset_recursive(struct bt_field *field);
70
71 static
72 void bt_field_variant_reset_recursive(struct bt_field *field);
73
74 static
75 void bt_field_array_reset_recursive(struct bt_field *field);
76
77 static
78 void bt_field_sequence_reset_recursive(struct bt_field *field);
79
80 static
81 void bt_field_generic_set_is_frozen(struct bt_field *field,
82 bool is_frozen);
83
84 static
85 void bt_field_structure_set_is_frozen_recursive(
86 struct bt_field *field, bool is_frozen);
87
88 static
89 void bt_field_variant_set_is_frozen_recursive(
90 struct bt_field *field, bool is_frozen);
91
92 static
93 void bt_field_array_set_is_frozen_recursive(
94 struct bt_field *field, bool is_frozen);
95
96 static
97 void bt_field_sequence_set_is_frozen_recursive(
98 struct bt_field *field, bool is_frozen);
99
100 static
101 bt_bool bt_field_generic_is_set(struct bt_field *field);
102
103 static
104 bt_bool bt_field_structure_is_set_recursive(
105 struct bt_field *field);
106
107 static
108 bt_bool bt_field_variant_is_set_recursive(struct bt_field *field);
109
110 static
111 bt_bool bt_field_array_is_set_recursive(struct bt_field *field);
112
113 static
114 bt_bool bt_field_sequence_is_set_recursive(struct bt_field *field);
115
116 static struct bt_field_methods bt_field_integer_methods = {
117 .set_is_frozen = bt_field_generic_set_is_frozen,
118 .validate = bt_field_generic_validate,
119 .is_set = bt_field_generic_is_set,
120 .reset = bt_field_generic_reset,
121 };
122
123 static struct bt_field_methods bt_field_floating_point_methods = {
124 .set_is_frozen = bt_field_generic_set_is_frozen,
125 .validate = bt_field_generic_validate,
126 .is_set = bt_field_generic_is_set,
127 .reset = bt_field_generic_reset,
128 };
129
130 static struct bt_field_methods bt_field_enumeration_methods = {
131 .set_is_frozen = bt_field_generic_set_is_frozen,
132 .validate = bt_field_generic_validate,
133 .is_set = bt_field_generic_is_set,
134 .reset = bt_field_generic_reset,
135 };
136
137 static struct bt_field_methods bt_field_string_methods = {
138 .set_is_frozen = bt_field_generic_set_is_frozen,
139 .validate = bt_field_generic_validate,
140 .is_set = bt_field_generic_is_set,
141 .reset = bt_field_generic_reset,
142 };
143
144 static struct bt_field_methods bt_field_structure_methods = {
145 .set_is_frozen = bt_field_structure_set_is_frozen_recursive,
146 .validate = bt_field_structure_validate_recursive,
147 .is_set = bt_field_structure_is_set_recursive,
148 .reset = bt_field_structure_reset_recursive,
149 };
150
151 static struct bt_field_methods bt_field_sequence_methods = {
152 .set_is_frozen = bt_field_sequence_set_is_frozen_recursive,
153 .validate = bt_field_sequence_validate_recursive,
154 .is_set = bt_field_sequence_is_set_recursive,
155 .reset = bt_field_sequence_reset_recursive,
156 };
157
158 static struct bt_field_methods bt_field_array_methods = {
159 .set_is_frozen = bt_field_array_set_is_frozen_recursive,
160 .validate = bt_field_array_validate_recursive,
161 .is_set = bt_field_array_is_set_recursive,
162 .reset = bt_field_array_reset_recursive,
163 };
164
165 static struct bt_field_methods bt_field_variant_methods = {
166 .set_is_frozen = bt_field_variant_set_is_frozen_recursive,
167 .validate = bt_field_variant_validate_recursive,
168 .is_set = bt_field_variant_is_set_recursive,
169 .reset = bt_field_variant_reset_recursive,
170 };
171
172 static
173 struct bt_field *bt_field_integer_create(struct bt_field_type *);
174
175 static
176 struct bt_field *bt_field_enumeration_create(struct bt_field_type *);
177
178 static
179 struct bt_field *bt_field_floating_point_create(struct bt_field_type *);
180
181 static
182 struct bt_field *bt_field_structure_create(struct bt_field_type *);
183
184 static
185 struct bt_field *bt_field_variant_create(struct bt_field_type *);
186
187 static
188 struct bt_field *bt_field_array_create(struct bt_field_type *);
189
190 static
191 struct bt_field *bt_field_sequence_create(struct bt_field_type *);
192
193 static
194 struct bt_field *bt_field_string_create(struct bt_field_type *);
195
196 static
197 struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
198 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_create,
199 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_create,
200 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_create,
201 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_create,
202 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_create,
203 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_create,
204 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_create,
205 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_create,
206 };
207
208 static
209 void bt_field_integer_destroy(struct bt_field *field);
210
211 static
212 void bt_field_enumeration_destroy(struct bt_field *field);
213
214 static
215 void bt_field_floating_point_destroy(struct bt_field *field);
216
217 static
218 void bt_field_structure_destroy_recursive(struct bt_field *field);
219
220 static
221 void bt_field_variant_destroy_recursive(struct bt_field *field);
222
223 static
224 void bt_field_array_destroy_recursive(struct bt_field *field);
225
226 static
227 void bt_field_sequence_destroy_recursive(struct bt_field *field);
228
229 static
230 void bt_field_string_destroy(struct bt_field *field);
231
232 static
233 void (* const field_destroy_funcs[])(struct bt_field *) = {
234 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_destroy,
235 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_destroy,
236 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_destroy,
237 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_destroy_recursive,
238 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_destroy_recursive,
239 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_destroy_recursive,
240 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_destroy_recursive,
241 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_destroy,
242 };
243
244 BT_ASSERT_PRE_FUNC
245 static inline bool value_is_in_range_signed(unsigned int size, int64_t value)
246 {
247 bool ret = true;
248 int64_t min_value, max_value;
249
250 min_value = -(1ULL << (size - 1));
251 max_value = (1ULL << (size - 1)) - 1;
252 if (value < min_value || value > max_value) {
253 BT_LOGF("Value is out of bounds: value=%" PRId64 ", "
254 "min-value=%" PRId64 ", max-value=%" PRId64,
255 value, min_value, max_value);
256 ret = false;
257 }
258
259 return ret;
260 }
261
262 BT_ASSERT_PRE_FUNC
263 static inline bool value_is_in_range_unsigned(unsigned int size, uint64_t value)
264 {
265 bool ret = true;
266 int64_t max_value;
267
268 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
269 if (value > max_value) {
270 BT_LOGF("Value is out of bounds: value=%" PRIu64 ", "
271 "max-value=%" PRIu64,
272 value, max_value);
273 ret = false;
274 }
275
276 return ret;
277 }
278
279 BT_HIDDEN
280 struct bt_field *bt_field_create_recursive(struct bt_field_type *type)
281 {
282 struct bt_field *field = NULL;
283 enum bt_field_type_id type_id;
284
285 BT_ASSERT_PRE_NON_NULL(type, "Field type");
286 BT_ASSERT(bt_field_type_has_known_id((void *) type));
287 BT_ASSERT_PRE(bt_field_type_validate((void *) type) == 0,
288 "Field type is invalid: %!+F", type);
289 type_id = bt_field_type_get_type_id(type);
290 field = field_create_funcs[type_id](type);
291 if (!field) {
292 goto end;
293 }
294
295 bt_field_type_freeze(type);
296
297 end:
298 return field;
299 }
300
301 struct bt_field_type *bt_field_borrow_type(struct bt_field *field)
302 {
303 struct bt_field_type *ret = NULL;
304
305 BT_ASSERT_PRE_NON_NULL(field, "Field");
306 ret = field->type;
307 return ret;
308 }
309
310 enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
311 {
312 BT_ASSERT_PRE_NON_NULL(field, "Field");
313 return field->type->id;
314 }
315
316 int64_t bt_field_sequence_get_length(struct bt_field *field)
317 {
318 struct bt_field_sequence *sequence = (void *) field;
319
320 BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
321 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE,
322 "Field");
323 return (int64_t) sequence->length;
324 }
325
326 int bt_field_sequence_set_length(struct bt_field *field, uint64_t length)
327 {
328 int ret = 0;
329 struct bt_field_sequence *sequence = (void *) field;
330
331 BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
332 BT_ASSERT_PRE(((int64_t) length) >= 0,
333 "Invalid sequence length (too large): length=%" PRId64,
334 length);
335 BT_ASSERT_PRE_FIELD_HOT(field, "Sequence field");
336
337 if (unlikely(length > sequence->elements->len)) {
338 /* Make more room */
339 struct bt_field_type_sequence *sequence_ft;
340 uint64_t cur_len = sequence->elements->len;
341 uint64_t i;
342
343 g_ptr_array_set_size(sequence->elements, length);
344 sequence_ft = (void *) sequence->common.type;
345
346 for (i = cur_len; i < sequence->elements->len; i++) {
347 struct bt_field *elem_field =
348 bt_field_create_recursive(
349 sequence_ft->element_ft);
350
351 if (!elem_field) {
352 ret = -1;
353 goto end;
354 }
355
356 BT_ASSERT(!sequence->elements->pdata[i]);
357 sequence->elements->pdata[i] = elem_field;
358 }
359 }
360
361 sequence->length = length;
362
363 end:
364 return ret;
365 }
366
367 struct bt_field *bt_field_structure_borrow_field_by_index(
368 struct bt_field *field, uint64_t index)
369 {
370 struct bt_field_structure *structure = (void *) field;
371
372 BT_ASSERT_PRE_NON_NULL(field, "Structure field");
373 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
374 BT_FIELD_TYPE_ID_STRUCT, "Field");
375 BT_ASSERT_PRE(index < structure->fields->len,
376 "Index is out of bound: %![struct-field-]+f, "
377 "index=%" PRIu64 ", count=%u", field, index,
378 structure->fields->len);
379 return structure->fields->pdata[index];
380 }
381
382 struct bt_field *bt_field_structure_borrow_field_by_name(
383 struct bt_field *field, const char *name)
384 {
385 struct bt_field *ret = NULL;
386 GQuark field_quark;
387 struct bt_field_type_structure *structure_ft;
388 struct bt_field_structure *structure = (void *) field;
389 size_t index;
390 GHashTable *field_name_to_index;
391
392 BT_ASSERT_PRE_NON_NULL(field, "Structure field");
393 BT_ASSERT_PRE_NON_NULL(name, "Field name");
394 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
395 BT_FIELD_TYPE_ID_STRUCT, "Field");
396 structure_ft = (void *) field->type;
397 field_name_to_index = structure_ft->field_name_to_index;
398 field_quark = g_quark_from_string(name);
399 if (!g_hash_table_lookup_extended(field_name_to_index,
400 GUINT_TO_POINTER(field_quark),
401 NULL, (gpointer *) &index)) {
402 BT_LOGV("Invalid parameter: no such field in structure field's type: "
403 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
404 field, field->type, name);
405 goto error;
406 }
407
408 ret = structure->fields->pdata[index];
409 BT_ASSERT(ret);
410
411 error:
412 return ret;
413 }
414
415 struct bt_field *bt_field_array_borrow_field(
416 struct bt_field *field, uint64_t index)
417 {
418 struct bt_field_array *array = (void *) field;
419
420 BT_ASSERT_PRE_NON_NULL(field, "Array field");
421 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_ARRAY,
422 "Field");
423 BT_ASSERT_PRE(index < array->elements->len,
424 "Index is out of bound: %![array-field-]+f, "
425 "index=%" PRIu64 ", count=%u", field,
426 index, array->elements->len);
427 return array->elements->pdata[(size_t) index];
428 }
429
430 struct bt_field *bt_field_sequence_borrow_field(
431 struct bt_field *field, uint64_t index)
432 {
433 struct bt_field_sequence *sequence = (void *) field;
434
435 BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
436 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE,
437 "Field");
438 BT_ASSERT_PRE(index < sequence->length,
439 "Index is out of bound: %![seq-field-]+f, "
440 "index=%" PRIu64 ", count=%u", field, index,
441 sequence->elements->len);
442 return sequence->elements->pdata[(size_t) index];
443 }
444
445 struct bt_field *bt_field_variant_borrow_current_field(
446 struct bt_field *field)
447 {
448 struct bt_field_variant *variant = (void *) field;
449
450 BT_ASSERT_PRE_NON_NULL(field, "Variant field");
451 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
452 BT_FIELD_TYPE_ID_VARIANT, "Field");
453 BT_ASSERT_PRE(variant->current_field,
454 "Variant field has no current field: %!+f", field);
455 return variant->current_field;
456 }
457
458 static inline
459 int bt_field_variant_set_tag(struct bt_field *field,
460 uint64_t tag_uval, bool is_signed)
461 {
462 int ret = 0;
463 int64_t choice_index;
464 struct bt_field_variant *variant = (void *) field;
465
466 BT_ASSERT_PRE_NON_NULL(field, "Variant field");
467 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
468 BT_FIELD_TYPE_ID_VARIANT, "Field");
469
470 /* Find matching index in variant field's type */
471 choice_index = bt_field_type_variant_find_choice_index(
472 field->type, tag_uval, is_signed);
473 if (choice_index < 0) {
474 ret = -1;
475 goto end;
476 }
477
478 /* Select corresponding field */
479 BT_ASSERT(choice_index < variant->fields->len);
480 variant->current_field = variant->fields->pdata[choice_index];
481 variant->tag_value.u = tag_uval;
482
483 end:
484 return ret;
485 }
486
487 int bt_field_variant_set_tag_signed(struct bt_field *variant_field,
488 int64_t tag)
489 {
490 return bt_field_variant_set_tag((void *) variant_field,
491 (uint64_t) tag, true);
492 }
493
494 int bt_field_variant_set_tag_unsigned(struct bt_field *variant_field,
495 uint64_t tag)
496 {
497 return bt_field_variant_set_tag((void *) variant_field,
498 (uint64_t) tag, false);
499 }
500
501 int bt_field_variant_get_tag_signed(struct bt_field *field,
502 int64_t *tag)
503 {
504 struct bt_field_variant *variant = (void *) field;
505
506 BT_ASSERT_PRE_NON_NULL(field, "Variant field");
507 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
508 BT_FIELD_TYPE_ID_VARIANT, "Field");
509 BT_ASSERT_PRE(variant->current_field,
510 "Variant field has no current field: %!+f", field);
511 *tag = variant->tag_value.i;
512 return 0;
513 }
514
515 int bt_field_variant_get_tag_unsigned(struct bt_field *field,
516 uint64_t *tag)
517 {
518 struct bt_field_variant *variant = (void *) field;
519
520 BT_ASSERT_PRE_NON_NULL(field, "Variant field");
521 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
522 BT_FIELD_TYPE_ID_VARIANT, "Field");
523 BT_ASSERT_PRE(variant->current_field,
524 "Variant field has no current field: %!+f", field);
525 *tag = variant->tag_value.u;
526 return 0;
527 }
528
529 struct bt_field_type_enumeration_mapping_iterator *
530 bt_field_enumeration_get_mappings(struct bt_field *field)
531 {
532 struct bt_field_enumeration *enum_field = (void *) field;
533 struct bt_field_type_enumeration *enum_type = NULL;
534 struct bt_field_type_integer *integer_type = NULL;
535 struct bt_field_type_enumeration_mapping_iterator *iter = NULL;
536
537 BT_ASSERT(field);
538 BT_ASSERT(field->type->id == BT_FIELD_TYPE_ID_ENUM);
539 BT_ASSERT(field->payload_set);
540 BT_ASSERT_PRE_NON_NULL(field, "Enumeration field");
541 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID((struct bt_field *) field,
542 BT_FIELD_TYPE_ID_ENUM, "Field");
543 BT_ASSERT_PRE_FIELD_IS_SET((struct bt_field *) field,
544 "Enumeration field");
545 enum_type = (void *) field->type;
546 integer_type = enum_type->container_ft;
547
548 if (!integer_type->is_signed) {
549 iter = bt_field_type_enumeration_unsigned_find_mappings_by_value(
550 field->type,
551 enum_field->common.payload.unsignd);
552 } else {
553 iter = bt_field_type_enumeration_signed_find_mappings_by_value(
554 field->type,
555 enum_field->common.payload.signd);
556 }
557
558 return iter;
559 }
560
561 BT_ASSERT_PRE_FUNC
562 static inline
563 struct bt_field_type_integer *get_int_enum_int_ft(
564 struct bt_field *field)
565 {
566 struct bt_field_integer *int_field = (void *) field;
567 struct bt_field_type_integer *int_ft = NULL;
568
569 if (int_field->common.type->id == BT_FIELD_TYPE_ID_INTEGER) {
570 int_ft = (void *) int_field->common.type;
571 } else if (int_field->common.type->id == BT_FIELD_TYPE_ID_ENUM) {
572 struct bt_field_type_enumeration *enum_ft =
573 (void *) int_field->common.type;
574 int_ft = enum_ft->container_ft;
575 } else {
576 abort();
577 }
578
579 BT_ASSERT(int_ft);
580 return int_ft;
581 }
582
583 int bt_field_integer_signed_get_value(struct bt_field *field, int64_t *value)
584 {
585 struct bt_field_integer *integer = (void *) field;
586
587 BT_ASSERT_PRE_NON_NULL(field, "Integer/enumeration field");
588 BT_ASSERT_PRE_NON_NULL(value, "Value");
589 BT_ASSERT_PRE_FIELD_IS_SET(field,
590 "Integer/enumeration field");
591 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field");
592 BT_ASSERT_PRE(bt_field_type_integer_is_signed(
593 (void *) get_int_enum_int_ft(field)),
594 "Field's type is unsigned: %!+f", field);
595 *value = integer->payload.signd;
596 return 0;
597 }
598
599 int bt_field_integer_signed_set_value(struct bt_field *field, int64_t value)
600 {
601 int ret = 0;
602 struct bt_field_integer *integer = (void *) field;
603
604 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
605 BT_ASSERT_PRE_FIELD_HOT(field, "Integer field");
606 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field");
607 BT_ASSERT_PRE(bt_field_type_integer_is_signed(
608 (void *) get_int_enum_int_ft(field)),
609 "Field's type is unsigned: %!+f", field);
610 BT_ASSERT_PRE(value_is_in_range_signed(
611 get_int_enum_int_ft(field)->size, value),
612 "Value is out of bounds: value=%" PRId64 ", %![field-]+f",
613 value, field);
614 integer->payload.signd = value;
615 bt_field_set(field, true);
616 return ret;
617 }
618
619 int bt_field_integer_unsigned_get_value(struct bt_field *field, uint64_t *value)
620 {
621 struct bt_field_integer *integer = (void *) field;
622
623 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
624 BT_ASSERT_PRE_NON_NULL(value, "Value");
625 BT_ASSERT_PRE_FIELD_IS_SET(field, "Integer field");
626 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field");
627 BT_ASSERT_PRE(!bt_field_type_integer_is_signed(
628 (void *) get_int_enum_int_ft(field)),
629 "Field's type is signed: %!+f", field);
630 *value = integer->payload.unsignd;
631 return 0;
632 }
633
634 int bt_field_integer_unsigned_set_value(struct bt_field *field,
635 uint64_t value)
636 {
637 struct bt_field_integer *integer = (void *) field;
638
639 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
640 BT_ASSERT_PRE_FIELD_HOT(field, "Integer field");
641 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(field, "Field");
642 BT_ASSERT_PRE(!bt_field_type_integer_is_signed(
643 (void *) get_int_enum_int_ft(field)),
644 "Field's type is signed: %!+f", field);
645 BT_ASSERT_PRE(value_is_in_range_unsigned(
646 get_int_enum_int_ft(field)->size, value),
647 "Value is out of bounds: value=%" PRIu64 ", %![field-]+f",
648 value, field);
649 integer->payload.unsignd = value;
650 bt_field_set(field, true);
651 return 0;
652 }
653
654 int bt_field_floating_point_get_value(struct bt_field *field,
655 double *value)
656 {
657 struct bt_field_floating_point *floating_point = (void *) field;
658
659 BT_ASSERT_PRE_NON_NULL(field, "Floating point number field");
660 BT_ASSERT_PRE_NON_NULL(value, "Value");
661 BT_ASSERT_PRE_FIELD_IS_SET(field, "Floating point number field");
662 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
663 BT_FIELD_TYPE_ID_FLOAT, "Field");
664 *value = floating_point->payload;
665 return 0;
666 }
667
668 int bt_field_floating_point_set_value(struct bt_field *field,
669 double value)
670 {
671 struct bt_field_floating_point *floating_point = (void *) field;
672
673 BT_ASSERT_PRE_NON_NULL(field, "Floating point number field");
674 BT_ASSERT_PRE_FIELD_HOT(field, "Floating point number field");
675 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
676 BT_FIELD_TYPE_ID_FLOAT, "Field");
677 floating_point->payload = value;
678 bt_field_set(field, true);
679 return 0;
680 }
681
682 const char *bt_field_string_get_value(struct bt_field *field)
683 {
684 struct bt_field_string *string = (void *) field;
685
686 BT_ASSERT_PRE_NON_NULL(field, "String field");
687 BT_ASSERT_PRE_FIELD_IS_SET(field, "String field");
688 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
689 BT_FIELD_TYPE_ID_STRING, "Field");
690 return (const char *) string->buf->data;
691 }
692
693 int bt_field_string_set_value(struct bt_field *field, const char *value)
694 {
695 BT_ASSERT_PRE_NON_NULL(field, "String field");
696 BT_ASSERT_PRE_NON_NULL(value, "Value");
697 BT_ASSERT_PRE_FIELD_HOT(field, "String field");
698 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
699 BT_FIELD_TYPE_ID_STRING, "Field");
700 bt_field_string_clear(field);
701 return bt_field_string_append_len(field,
702 value, strlen(value));
703 }
704
705 int bt_field_string_append(struct bt_field *field, const char *value)
706 {
707 BT_ASSERT_PRE_NON_NULL(value, "Value");
708 return bt_field_string_append_len(field, value,
709 strlen(value));
710 }
711
712 int bt_field_string_append_len(struct bt_field *field,
713 const char *value, unsigned int length)
714 {
715 struct bt_field_string *string_field = (void *) field;
716 char *data;
717 size_t new_size;
718
719 BT_ASSERT_PRE_NON_NULL(field, "String field");
720 BT_ASSERT_PRE_NON_NULL(value, "Value");
721 BT_ASSERT_PRE_FIELD_HOT(field, "String field");
722 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
723 BT_FIELD_TYPE_ID_STRING, "Field");
724
725 /* Make sure no null bytes are appended */
726 BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
727 "String value to append contains a null character: "
728 "partial-value=\"%.32s\", length=%u", value, length);
729
730 new_size = string_field->size + length;
731
732 if (unlikely(new_size + 1 > string_field->buf->len)) {
733 g_array_set_size(string_field->buf, new_size + 1);
734 }
735
736 data = string_field->buf->data;
737 memcpy(data + string_field->size, value, length);
738 ((char *) string_field->buf->data)[new_size] = '\0';
739 string_field->size = new_size;
740 bt_field_set(field, true);
741 return 0;
742 }
743
744 int bt_field_string_clear(struct bt_field *field)
745 {
746 struct bt_field_string *string_field = (void *) field;
747
748 BT_ASSERT_PRE_NON_NULL(field, "String field");
749 BT_ASSERT_PRE_FIELD_HOT(field, "String field");
750 BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
751 BT_FIELD_TYPE_ID_STRING, "Field");
752 string_field->size = 0;
753 bt_field_set(field, true);
754 return 0;
755 }
756
757 static inline
758 void bt_field_finalize(struct bt_field *field)
759 {
760 BT_ASSERT(field);
761 BT_LOGD_STR("Putting field's type.");
762 bt_put(field->type);
763 }
764
765 static
766 void bt_field_integer_destroy(struct bt_field *field)
767 {
768 BT_ASSERT(field);
769 BT_LOGD("Destroying integer field object: addr=%p", field);
770 bt_field_finalize(field);
771 g_free(field);
772 }
773
774 static
775 void bt_field_floating_point_destroy(struct bt_field *field)
776 {
777 BT_ASSERT(field);
778 BT_LOGD("Destroying floating point field object: addr=%p", field);
779 bt_field_finalize(field);
780 g_free(field);
781 }
782
783 static
784 void bt_field_enumeration_destroy(struct bt_field *field)
785 {
786 BT_LOGD("Destroying enumeration field object: addr=%p", field);
787 bt_field_finalize((void *) field);
788 g_free(field);
789 }
790
791 static
792 void bt_field_structure_destroy_recursive(struct bt_field *field)
793 {
794 struct bt_field_structure *structure = (void *) field;
795
796 BT_ASSERT(field);
797 BT_LOGD("Destroying structure field object: addr=%p", field);
798 bt_field_finalize(field);
799
800 if (structure->fields) {
801 g_ptr_array_free(structure->fields, TRUE);
802 }
803
804 g_free(field);
805 }
806
807 static
808 void bt_field_variant_destroy_recursive(struct bt_field *field)
809 {
810 struct bt_field_variant *variant = (void *) field;
811
812 BT_ASSERT(field);
813 BT_LOGD("Destroying variant field object: addr=%p", field);
814 bt_field_finalize(field);
815
816 if (variant->fields) {
817 g_ptr_array_free(variant->fields, TRUE);
818 }
819
820 g_free(field);
821 }
822
823 static
824 void bt_field_array_destroy_recursive(struct bt_field *field)
825 {
826 struct bt_field_array *array = (void *) field;
827
828 BT_ASSERT(field);
829 BT_LOGD("Destroying array field object: addr=%p", field);
830 bt_field_finalize(field);
831
832 if (array->elements) {
833 g_ptr_array_free(array->elements, TRUE);
834 }
835
836 g_free(field);
837 }
838
839 static
840 void bt_field_sequence_destroy_recursive(struct bt_field *field)
841 {
842 struct bt_field_sequence *sequence = (void *) field;
843
844 BT_ASSERT(field);
845 BT_LOGD("Destroying sequence field object: addr=%p", field);
846 bt_field_finalize(field);
847
848 if (sequence->elements) {
849 g_ptr_array_free(sequence->elements, TRUE);
850 }
851 g_free(field);
852 }
853
854 static
855 void bt_field_string_destroy(struct bt_field *field)
856 {
857 struct bt_field_string *string = (void *) field;
858
859 BT_LOGD("Destroying string field object: addr=%p", field);
860 BT_ASSERT(field);
861 bt_field_finalize(field);
862
863 if (string->buf) {
864 g_array_free(string->buf, TRUE);
865 }
866
867 g_free(field);
868 }
869
870 BT_HIDDEN
871 void bt_field_destroy_recursive(struct bt_field *field)
872 {
873 if (!field) {
874 return;
875 }
876
877 BT_ASSERT(bt_field_type_has_known_id((void *) field->type));
878 field_destroy_funcs[field->type->id](field);
879 }
880
881 static inline
882 void bt_field_initialize(struct bt_field *field,
883 struct bt_field_type *ft,
884 struct bt_field_methods *methods)
885 {
886 BT_ASSERT(field);
887 BT_ASSERT(ft);
888 bt_object_init_unique(&field->base);
889 field->methods = methods;
890 field->type = bt_get(ft);
891 }
892
893 static
894 struct bt_field *bt_field_integer_create(struct bt_field_type *type)
895 {
896 struct bt_field_integer *integer =
897 g_new0(struct bt_field_integer, 1);
898
899 BT_LOGD("Creating integer field object: ft-addr=%p", type);
900
901 if (integer) {
902 bt_field_initialize((void *) integer, (void *) type,
903 &bt_field_integer_methods);
904 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
905 integer, type);
906 } else {
907 BT_LOGE_STR("Failed to allocate one integer field.");
908 }
909
910 return (void *) integer;
911 }
912
913 static
914 struct bt_field *bt_field_enumeration_create(struct bt_field_type *type)
915 {
916 struct bt_field_enumeration *enumeration = g_new0(
917 struct bt_field_enumeration, 1);
918
919 BT_LOGD("Creating enumeration field object: ft-addr=%p", type);
920
921 if (enumeration) {
922 bt_field_initialize((void *) enumeration,
923 (void *) type, &bt_field_enumeration_methods);
924 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
925 enumeration, type);
926 } else {
927 BT_LOGE_STR("Failed to allocate one enumeration field.");
928 }
929
930 return (void *) enumeration;
931 }
932
933 static
934 struct bt_field *bt_field_floating_point_create(struct bt_field_type *type)
935 {
936 struct bt_field_floating_point *floating_point;
937
938 BT_LOGD("Creating floating point number field object: ft-addr=%p", type);
939 floating_point = g_new0(struct bt_field_floating_point, 1);
940
941 if (floating_point) {
942 bt_field_initialize((void *) floating_point,
943 (void *) type, &bt_field_floating_point_methods);
944 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
945 floating_point, type);
946 } else {
947 BT_LOGE_STR("Failed to allocate one floating point number field.");
948 }
949
950 return (void *) floating_point;
951 }
952
953 static inline
954 int bt_field_structure_initialize(struct bt_field *field,
955 struct bt_field_type *type,
956 struct bt_field_methods *methods,
957 bt_field_create_func field_create_func,
958 GDestroyNotify field_release_func)
959 {
960 int ret = 0;
961 struct bt_field_type_structure *structure_type = (void *) type;
962 struct bt_field_structure *structure = (void *) field;
963 size_t i;
964
965 BT_LOGD("Initializing structure field object: ft-addr=%p", type);
966 bt_field_initialize(field, type, methods);
967 structure->fields = g_ptr_array_new_with_free_func(field_release_func);
968 g_ptr_array_set_size(structure->fields, structure_type->fields->len);
969
970 /* Create all fields contained in the structure field. */
971 for (i = 0; i < structure_type->fields->len; i++) {
972 struct bt_field *field;
973 struct bt_field_type_structure_field *struct_field =
974 BT_FIELD_TYPE_STRUCTURE_FIELD_AT_INDEX(
975 structure_type, i);
976 field = field_create_func(struct_field->type);
977 if (!field) {
978 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
979 g_quark_to_string(struct_field->name), i);
980 ret = -1;
981 goto end;
982 }
983
984 g_ptr_array_index(structure->fields, i) = field;
985 }
986
987 BT_LOGD("Initialized structure field object: addr=%p, ft-addr=%p",
988 field, type);
989
990 end:
991 return ret;
992 }
993
994 static
995 struct bt_field *bt_field_structure_create(struct bt_field_type *type)
996 {
997 struct bt_field_structure *structure = g_new0(
998 struct bt_field_structure, 1);
999 int iret;
1000
1001 BT_LOGD("Creating structure field object: ft-addr=%p", type);
1002
1003 if (!structure) {
1004 BT_LOGE_STR("Failed to allocate one structure field.");
1005 goto end;
1006 }
1007
1008 iret = bt_field_structure_initialize((void *) structure,
1009 (void *) type, &bt_field_structure_methods,
1010 (bt_field_create_func) bt_field_create_recursive,
1011 (GDestroyNotify) bt_field_destroy_recursive);
1012 if (iret) {
1013 BT_PUT(structure);
1014 goto end;
1015 }
1016
1017 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p",
1018 structure, type);
1019
1020 end:
1021 return (void *) structure;
1022 }
1023
1024 static inline
1025 int bt_field_variant_initialize(struct bt_field *field,
1026 struct bt_field_type *type,
1027 struct bt_field_methods *methods,
1028 bt_field_create_func field_create_func,
1029 GDestroyNotify field_release_func)
1030 {
1031 int ret = 0;
1032 struct bt_field_type_variant *variant_type = (void *) type;
1033 struct bt_field_variant *variant = (void *) field;
1034 size_t i;
1035
1036 BT_LOGD("Initializing variant field object: ft-addr=%p", type);
1037 bt_field_initialize(field, type, methods);
1038 ret = bt_field_type_variant_update_choices(type);
1039 if (ret) {
1040 BT_LOGE("Cannot update variant field type choices: "
1041 "ret=%d", ret);
1042 goto end;
1043 }
1044
1045 variant->fields = g_ptr_array_new_with_free_func(field_release_func);
1046 g_ptr_array_set_size(variant->fields, variant_type->choices->len);
1047
1048 /* Create all fields contained in the variant field. */
1049 for (i = 0; i < variant_type->choices->len; i++) {
1050 struct bt_field *field;
1051 struct bt_field_type_variant_choice *var_choice =
1052 BT_FIELD_TYPE_VARIANT_CHOICE_AT_INDEX(
1053 variant_type, i);
1054
1055 field = field_create_func(var_choice->type);
1056 if (!field) {
1057 BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
1058 g_quark_to_string(var_choice->name), i);
1059 ret = -1;
1060 goto end;
1061 }
1062
1063 g_ptr_array_index(variant->fields, i) = field;
1064 }
1065
1066 BT_LOGD("Initialized variant field object: addr=%p, ft-addr=%p",
1067 field, type);
1068
1069 end:
1070 return ret;
1071 }
1072
1073 static inline
1074 int bt_field_string_initialize(struct bt_field *field,
1075 struct bt_field_type *type,
1076 struct bt_field_methods *methods)
1077 {
1078 int ret = 0;
1079 struct bt_field_string *string = (void *) field;
1080
1081 BT_LOGD("Initializing string field object: ft-addr=%p", type);
1082 bt_field_initialize(field, type, methods);
1083 string->buf = g_array_sized_new(FALSE, FALSE, sizeof(char), 1);
1084 if (!string->buf) {
1085 ret = -1;
1086 goto end;
1087 }
1088
1089 g_array_index(string->buf, char, 0) = '\0';
1090 BT_LOGD("Initialized string field object: addr=%p, ft-addr=%p",
1091 field, type);
1092
1093 end:
1094 return ret;
1095 }
1096
1097 static
1098 struct bt_field *bt_field_variant_create(struct bt_field_type *type)
1099 {
1100 struct bt_field_variant *variant = g_new0(
1101 struct bt_field_variant, 1);
1102 int iret;
1103
1104 BT_LOGD("Creating variant field object: ft-addr=%p", type);
1105
1106 if (!variant) {
1107 BT_LOGE_STR("Failed to allocate one variant field.");
1108 goto end;
1109 }
1110
1111 iret = bt_field_variant_initialize((void *) variant,
1112 (void *) type, &bt_field_variant_methods,
1113 (bt_field_create_func) bt_field_create_recursive,
1114 (GDestroyNotify) bt_field_destroy_recursive);
1115 if (iret) {
1116 BT_PUT(variant);
1117 goto end;
1118 }
1119
1120 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
1121 variant, type);
1122
1123 end:
1124 return (void *) variant;
1125 }
1126
1127 static inline
1128 int bt_field_array_initialize(struct bt_field *field,
1129 struct bt_field_type *type,
1130 struct bt_field_methods *methods,
1131 bt_field_create_func field_create_func,
1132 GDestroyNotify field_destroy_func)
1133 {
1134 struct bt_field_type_array *array_type = (void *) type;
1135 struct bt_field_array *array = (void *) field;
1136 unsigned int array_length;
1137 int ret = 0;
1138 uint64_t i;
1139
1140 BT_LOGD("Initializing array field object: ft-addr=%p", type);
1141 BT_ASSERT(type);
1142 bt_field_initialize(field, type, methods);
1143 array_length = array_type->length;
1144 array->elements = g_ptr_array_sized_new(array_length);
1145 if (!array->elements) {
1146 ret = -1;
1147 goto end;
1148 }
1149
1150 g_ptr_array_set_free_func(array->elements, field_destroy_func);
1151 g_ptr_array_set_size(array->elements, array_length);
1152
1153 for (i = 0; i < array_length; i++) {
1154 array->elements->pdata[i] = field_create_func(
1155 array_type->element_ft);
1156 if (!array->elements->pdata[i]) {
1157 ret = -1;
1158 goto end;
1159 }
1160 }
1161
1162 BT_LOGD("Initialized array field object: addr=%p, ft-addr=%p",
1163 field, type);
1164
1165 end:
1166 return ret;
1167 }
1168
1169 static
1170 struct bt_field *bt_field_array_create(struct bt_field_type *type)
1171 {
1172 struct bt_field_array *array =
1173 g_new0(struct bt_field_array, 1);
1174 int ret;
1175
1176 BT_LOGD("Creating array field object: ft-addr=%p", type);
1177 BT_ASSERT(type);
1178
1179 if (!array) {
1180 BT_LOGE_STR("Failed to allocate one array field.");
1181 goto end;
1182 }
1183
1184 ret = bt_field_array_initialize((void *) array,
1185 (void *) type, &bt_field_array_methods,
1186 (bt_field_create_func) bt_field_create_recursive,
1187 (GDestroyNotify) bt_field_destroy_recursive);
1188 if (ret) {
1189 BT_PUT(array);
1190 goto end;
1191 }
1192
1193 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
1194 array, type);
1195
1196 end:
1197 return (void *) array;
1198 }
1199
1200 static inline
1201 int bt_field_sequence_initialize(struct bt_field *field,
1202 struct bt_field_type *type,
1203 struct bt_field_methods *methods,
1204 GDestroyNotify field_destroy_func)
1205 {
1206 struct bt_field_sequence *sequence = (void *) field;
1207 int ret = 0;
1208
1209 BT_LOGD("Initializing sequence field object: ft-addr=%p", type);
1210 BT_ASSERT(type);
1211 bt_field_initialize(field, type, methods);
1212 sequence->elements = g_ptr_array_new();
1213 if (!sequence->elements) {
1214 ret = -1;
1215 goto end;
1216 }
1217
1218 g_ptr_array_set_free_func(sequence->elements, field_destroy_func);
1219 BT_LOGD("Initialized sequence field object: addr=%p, ft-addr=%p",
1220 field, type);
1221
1222 end:
1223 return ret;
1224 }
1225
1226 static
1227 struct bt_field *bt_field_sequence_create(struct bt_field_type *type)
1228 {
1229 struct bt_field_sequence *sequence =
1230 g_new0(struct bt_field_sequence, 1);
1231 int ret;
1232
1233 BT_LOGD("Creating sequence field object: ft-addr=%p", type);
1234 BT_ASSERT(type);
1235
1236 if (!sequence) {
1237 BT_LOGE_STR("Failed to allocate one sequence field.");
1238 goto end;
1239 }
1240
1241 ret = bt_field_sequence_initialize((void *) sequence,
1242 (void *) type, &bt_field_sequence_methods,
1243 (GDestroyNotify) bt_field_destroy_recursive);
1244 if (ret) {
1245 BT_PUT(sequence);
1246 goto end;
1247 }
1248
1249 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
1250 sequence, type);
1251
1252 end:
1253 return (void *) sequence;
1254 }
1255
1256 static
1257 struct bt_field *bt_field_string_create(struct bt_field_type *type)
1258 {
1259 struct bt_field_string *string = g_new0(
1260 struct bt_field_string, 1);
1261
1262 BT_LOGD("Creating string field object: ft-addr=%p", type);
1263
1264 if (string) {
1265 bt_field_string_initialize((void *) string,
1266 (void *) type, &bt_field_string_methods);
1267 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
1268 string, type);
1269 } else {
1270 BT_LOGE_STR("Failed to allocate one string field.");
1271 }
1272
1273 return (void *) string;
1274 }
1275
1276 static
1277 int bt_field_generic_validate(struct bt_field *field)
1278 {
1279 return (field && field->payload_set) ? 0 : -1;
1280 }
1281
1282 static
1283 int bt_field_structure_validate_recursive(struct bt_field *field)
1284 {
1285 int64_t i;
1286 int ret = 0;
1287 struct bt_field_structure *structure = (void *) field;
1288
1289 BT_ASSERT(field);
1290
1291 for (i = 0; i < structure->fields->len; i++) {
1292 ret = bt_field_validate_recursive(
1293 (void *) structure->fields->pdata[i]);
1294
1295 if (ret) {
1296 int this_ret;
1297 const char *name;
1298
1299 this_ret = bt_field_type_structure_borrow_field_by_index(
1300 field->type, &name, NULL, i);
1301 BT_ASSERT(this_ret == 0);
1302 BT_ASSERT_PRE_MSG("Invalid structure field's field: "
1303 "%![struct-field-]+f, field-name=\"%s\", "
1304 "index=%" PRId64 ", %![field-]+f",
1305 field, name, i, structure->fields->pdata[i]);
1306 goto end;
1307 }
1308 }
1309
1310 end:
1311 return ret;
1312 }
1313
1314 static
1315 int bt_field_variant_validate_recursive(struct bt_field *field)
1316 {
1317 int ret = 0;
1318 struct bt_field_variant *variant = (void *) field;
1319
1320 BT_ASSERT(field);
1321
1322 if (!variant->current_field) {
1323 ret = -1;
1324 goto end;
1325 }
1326
1327 ret = bt_field_validate_recursive(variant->current_field);
1328
1329 end:
1330 return ret;
1331 }
1332
1333 static
1334 int bt_field_array_validate_recursive(struct bt_field *field)
1335 {
1336 int64_t i;
1337 int ret = 0;
1338 struct bt_field_array *array = (void *) field;
1339
1340 BT_ASSERT(field);
1341
1342 for (i = 0; i < array->elements->len; i++) {
1343 ret = bt_field_validate_recursive((void *) array->elements->pdata[i]);
1344 if (ret) {
1345 BT_ASSERT_PRE_MSG("Invalid array field's element field: "
1346 "%![array-field-]+f, " PRId64 ", "
1347 "%![elem-field-]+f",
1348 field, i, array->elements->pdata[i]);
1349 goto end;
1350 }
1351 }
1352
1353 end:
1354 return ret;
1355 }
1356
1357 static
1358 int bt_field_sequence_validate_recursive(struct bt_field *field)
1359 {
1360 size_t i;
1361 int ret = 0;
1362 struct bt_field_sequence *sequence = (void *) field;
1363
1364 BT_ASSERT(field);
1365
1366 for (i = 0; i < sequence->elements->len; i++) {
1367 ret = bt_field_validate_recursive(
1368 (void *) sequence->elements->pdata[i]);
1369 if (ret) {
1370 BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
1371 "%![seq-field-]+f, " PRId64 ", "
1372 "%![elem-field-]+f",
1373 field, i, sequence->elements->pdata[i]);
1374 goto end;
1375 }
1376 }
1377 end:
1378 return ret;
1379 }
1380
1381 static
1382 void bt_field_generic_reset(struct bt_field *field)
1383 {
1384 BT_ASSERT(field);
1385 field->payload_set = false;
1386 }
1387
1388 static
1389 void bt_field_structure_reset_recursive(struct bt_field *field)
1390 {
1391 int64_t i;
1392 struct bt_field_structure *structure = (void *) field;
1393
1394 BT_ASSERT(field);
1395
1396 for (i = 0; i < structure->fields->len; i++) {
1397 struct bt_field *member = structure->fields->pdata[i];
1398
1399 if (!member) {
1400 /*
1401 * Structure members are lazily initialized;
1402 * skip if this member has not been allocated
1403 * yet.
1404 */
1405 continue;
1406 }
1407
1408 bt_field_reset_recursive(member);
1409 }
1410 }
1411
1412 static
1413 void bt_field_variant_reset_recursive(struct bt_field *field)
1414 {
1415 struct bt_field_variant *variant = (void *) field;
1416
1417 BT_ASSERT(field);
1418 variant->current_field = NULL;
1419 }
1420
1421 static
1422 void bt_field_array_reset_recursive(struct bt_field *field)
1423 {
1424 size_t i;
1425 struct bt_field_array *array = (void *) field;
1426
1427 BT_ASSERT(field);
1428
1429 for (i = 0; i < array->elements->len; i++) {
1430 struct bt_field *member = array->elements->pdata[i];
1431
1432 if (!member) {
1433 /*
1434 * Array elements are lazily initialized; skip
1435 * if this member has not been allocated yet.
1436 */
1437 continue;
1438 }
1439
1440 bt_field_reset_recursive(member);
1441 }
1442 }
1443
1444 static
1445 void bt_field_sequence_reset_recursive(struct bt_field *field)
1446 {
1447 struct bt_field_sequence *sequence = (void *) field;
1448 uint64_t i;
1449
1450 BT_ASSERT(field);
1451
1452 for (i = 0; i < sequence->elements->len; i++) {
1453 if (sequence->elements->pdata[i]) {
1454 bt_field_reset_recursive(
1455 sequence->elements->pdata[i]);
1456 }
1457 }
1458
1459 sequence->length = 0;
1460 }
1461
1462 static
1463 void bt_field_generic_set_is_frozen(struct bt_field *field,
1464 bool is_frozen)
1465 {
1466 field->frozen = is_frozen;
1467 }
1468
1469 static
1470 void bt_field_structure_set_is_frozen_recursive(
1471 struct bt_field *field, bool is_frozen)
1472 {
1473 uint64_t i;
1474 struct bt_field_structure *structure_field = (void *) field;
1475
1476 BT_LOGD("Freezing structure field object: addr=%p", field);
1477
1478 for (i = 0; i < structure_field->fields->len; i++) {
1479 struct bt_field *struct_field =
1480 g_ptr_array_index(structure_field->fields, i);
1481
1482 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
1483 struct_field, i);
1484 bt_field_set_is_frozen_recursive(struct_field,
1485 is_frozen);
1486 }
1487
1488 bt_field_generic_set_is_frozen(field, is_frozen);
1489 }
1490
1491 static
1492 void bt_field_variant_set_is_frozen_recursive(
1493 struct bt_field *field, bool is_frozen)
1494 {
1495 uint64_t i;
1496 struct bt_field_variant *variant_field = (void *) field;
1497
1498 BT_LOGD("Freezing variant field object: addr=%p", field);
1499
1500 for (i = 0; i < variant_field->fields->len; i++) {
1501 struct bt_field *var_field =
1502 g_ptr_array_index(variant_field->fields, i);
1503
1504 BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64,
1505 var_field, i);
1506 bt_field_set_is_frozen_recursive(var_field, is_frozen);
1507 }
1508
1509 bt_field_generic_set_is_frozen(field, is_frozen);
1510 }
1511
1512 static
1513 void bt_field_array_set_is_frozen_recursive(
1514 struct bt_field *field, bool is_frozen)
1515 {
1516 int64_t i;
1517 struct bt_field_array *array_field = (void *) field;
1518
1519 BT_LOGD("Freezing array field object: addr=%p", field);
1520
1521 for (i = 0; i < array_field->elements->len; i++) {
1522 struct bt_field *elem_field =
1523 g_ptr_array_index(array_field->elements, i);
1524
1525 BT_LOGD("Freezing array field object's element field: "
1526 "element-field-addr=%p, index=%" PRId64,
1527 elem_field, i);
1528 bt_field_set_is_frozen_recursive(elem_field, is_frozen);
1529 }
1530
1531 bt_field_generic_set_is_frozen(field, is_frozen);
1532 }
1533
1534 static
1535 void bt_field_sequence_set_is_frozen_recursive(
1536 struct bt_field *field, bool is_frozen)
1537 {
1538 int64_t i;
1539 struct bt_field_sequence *sequence_field = (void *) field;
1540
1541 BT_LOGD("Freezing sequence field object: addr=%p", field);
1542
1543 for (i = 0; i < sequence_field->length; i++) {
1544 struct bt_field *elem_field =
1545 g_ptr_array_index(sequence_field->elements, i);
1546
1547 BT_LOGD("Freezing sequence field object's element field: "
1548 "element-field-addr=%p, index=%" PRId64,
1549 elem_field, i);
1550 bt_field_set_is_frozen_recursive(elem_field, is_frozen);
1551 }
1552
1553 bt_field_generic_set_is_frozen(field, is_frozen);
1554 }
1555
1556 BT_HIDDEN
1557 void _bt_field_set_is_frozen_recursive(struct bt_field *field,
1558 bool is_frozen)
1559 {
1560 if (!field) {
1561 goto end;
1562 }
1563
1564 BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
1565 field, is_frozen);
1566 BT_ASSERT(bt_field_type_has_known_id(field->type));
1567 BT_ASSERT(field->methods->set_is_frozen);
1568 field->methods->set_is_frozen(field, is_frozen);
1569
1570 end:
1571 return;
1572 }
1573
1574 static
1575 bt_bool bt_field_generic_is_set(struct bt_field *field)
1576 {
1577 return field && field->payload_set;
1578 }
1579
1580 static
1581 bt_bool bt_field_structure_is_set_recursive(
1582 struct bt_field *field)
1583 {
1584 bt_bool is_set = BT_FALSE;
1585 size_t i;
1586 struct bt_field_structure *structure = (void *) field;
1587
1588 BT_ASSERT(field);
1589
1590 for (i = 0; i < structure->fields->len; i++) {
1591 is_set = bt_field_is_set_recursive(
1592 structure->fields->pdata[i]);
1593 if (!is_set) {
1594 goto end;
1595 }
1596 }
1597
1598 end:
1599 return is_set;
1600 }
1601
1602 static
1603 bt_bool bt_field_variant_is_set_recursive(struct bt_field *field)
1604 {
1605 struct bt_field_variant *variant = (void *) field;
1606 bt_bool is_set = BT_FALSE;
1607
1608 BT_ASSERT(field);
1609
1610 if (variant->current_field) {
1611 is_set = bt_field_is_set_recursive(
1612 variant->current_field);
1613 }
1614
1615 return is_set;
1616 }
1617
1618 static
1619 bt_bool bt_field_array_is_set_recursive(struct bt_field *field)
1620 {
1621 size_t i;
1622 bt_bool is_set = BT_FALSE;
1623 struct bt_field_array *array = (void *) field;
1624
1625 BT_ASSERT(field);
1626
1627 for (i = 0; i < array->elements->len; i++) {
1628 is_set = bt_field_is_set_recursive(array->elements->pdata[i]);
1629 if (!is_set) {
1630 goto end;
1631 }
1632 }
1633
1634 end:
1635 return is_set;
1636 }
1637
1638 static
1639 bt_bool bt_field_sequence_is_set_recursive(struct bt_field *field)
1640 {
1641 size_t i;
1642 bt_bool is_set = BT_FALSE;
1643 struct bt_field_sequence *sequence = (void *) field;
1644
1645 BT_ASSERT(field);
1646
1647 if (!sequence->elements) {
1648 goto end;
1649 }
1650
1651 for (i = 0; i < sequence->elements->len; i++) {
1652 is_set = bt_field_is_set_recursive(
1653 sequence->elements->pdata[i]);
1654 if (!is_set) {
1655 goto end;
1656 }
1657 }
1658
1659 end:
1660 return is_set;
1661 }
This page took 0.125881 seconds and 4 git commands to generate.