lib: update and simplify the `bt_object` API
[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-internal.h>
34 #include <babeltrace/ctf-ir/field-types-internal.h>
35 #include <babeltrace/object-internal.h>
36 #include <babeltrace/ref.h>
37 #include <babeltrace/compiler-internal.h>
38 #include <babeltrace/compat/fcntl-internal.h>
39 #include <babeltrace/align-internal.h>
40 #include <babeltrace/assert-internal.h>
41 #include <inttypes.h>
42
43 #define BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(_field, _name) \
44 BT_ASSERT_PRE((_field)->type->id == BT_FIELD_TYPE_ID_INTEGER || \
45 (_field)->type->id == BT_FIELD_TYPE_ID_ENUM, \
46 _name " is not an integer or an enumeration field: " \
47 "%!+f", (_field))
48
49 static struct bt_field_common_methods bt_field_integer_methods = {
50 .set_is_frozen = bt_field_common_generic_set_is_frozen,
51 .validate = bt_field_common_generic_validate,
52 .copy = NULL,
53 .is_set = bt_field_common_generic_is_set,
54 .reset = bt_field_common_generic_reset,
55 };
56
57 static struct bt_field_common_methods bt_field_floating_point_methods = {
58 .set_is_frozen = bt_field_common_generic_set_is_frozen,
59 .validate = bt_field_common_generic_validate,
60 .copy = NULL,
61 .is_set = bt_field_common_generic_is_set,
62 .reset = bt_field_common_generic_reset,
63 };
64
65 static struct bt_field_common_methods bt_field_enumeration_methods = {
66 .set_is_frozen = bt_field_common_generic_set_is_frozen,
67 .validate = bt_field_common_generic_validate,
68 .copy = NULL,
69 .is_set = bt_field_common_generic_is_set,
70 .reset = bt_field_common_generic_reset,
71 };
72
73 static struct bt_field_common_methods bt_field_string_methods = {
74 .set_is_frozen = bt_field_common_generic_set_is_frozen,
75 .validate = bt_field_common_generic_validate,
76 .copy = NULL,
77 .is_set = bt_field_common_generic_is_set,
78 .reset = bt_field_common_generic_reset,
79 };
80
81 static struct bt_field_common_methods bt_field_structure_methods = {
82 .set_is_frozen = bt_field_common_structure_set_is_frozen_recursive,
83 .validate = bt_field_common_structure_validate_recursive,
84 .copy = NULL,
85 .is_set = bt_field_common_structure_is_set_recursive,
86 .reset = bt_field_common_structure_reset_recursive,
87 };
88
89 static struct bt_field_common_methods bt_field_sequence_methods = {
90 .set_is_frozen = bt_field_common_sequence_set_is_frozen_recursive,
91 .validate = bt_field_common_sequence_validate_recursive,
92 .copy = NULL,
93 .is_set = bt_field_common_sequence_is_set_recursive,
94 .reset = bt_field_common_sequence_reset_recursive,
95 };
96
97 static struct bt_field_common_methods bt_field_array_methods = {
98 .set_is_frozen = bt_field_common_array_set_is_frozen_recursive,
99 .validate = bt_field_common_array_validate_recursive,
100 .copy = NULL,
101 .is_set = bt_field_common_array_is_set_recursive,
102 .reset = bt_field_common_array_reset_recursive,
103 };
104
105 static struct bt_field_common_methods bt_field_variant_methods = {
106 .set_is_frozen = bt_field_common_variant_set_is_frozen_recursive,
107 .validate = bt_field_common_variant_validate_recursive,
108 .copy = NULL,
109 .is_set = bt_field_common_variant_is_set_recursive,
110 .reset = bt_field_common_variant_reset_recursive,
111 };
112
113 static
114 struct bt_field *bt_field_integer_create(struct bt_field_type *);
115
116 static
117 struct bt_field *bt_field_enumeration_create(struct bt_field_type *);
118
119 static
120 struct bt_field *bt_field_floating_point_create(struct bt_field_type *);
121
122 static
123 struct bt_field *bt_field_structure_create(struct bt_field_type *);
124
125 static
126 struct bt_field *bt_field_variant_create(struct bt_field_type *);
127
128 static
129 struct bt_field *bt_field_array_create(struct bt_field_type *);
130
131 static
132 struct bt_field *bt_field_sequence_create(struct bt_field_type *);
133
134 static
135 struct bt_field *bt_field_string_create(struct bt_field_type *);
136
137 static
138 struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
139 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_create,
140 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_create,
141 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_create,
142 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_create,
143 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_create,
144 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_create,
145 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_create,
146 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_create,
147 };
148
149 static
150 void bt_field_integer_destroy(struct bt_field *field);
151
152 static
153 void bt_field_enumeration_destroy(struct bt_field *field);
154
155 static
156 void bt_field_floating_point_destroy(struct bt_field *field);
157
158 static
159 void bt_field_structure_destroy_recursive(struct bt_field *field);
160
161 static
162 void bt_field_variant_destroy_recursive(struct bt_field *field);
163
164 static
165 void bt_field_array_destroy_recursive(struct bt_field *field);
166
167 static
168 void bt_field_sequence_destroy_recursive(struct bt_field *field);
169
170 static
171 void bt_field_string_destroy(struct bt_field *field);
172
173 static
174 void (* const field_destroy_funcs[])(struct bt_field *) = {
175 [BT_FIELD_TYPE_ID_INTEGER] = bt_field_integer_destroy,
176 [BT_FIELD_TYPE_ID_ENUM] = bt_field_enumeration_destroy,
177 [BT_FIELD_TYPE_ID_FLOAT] = bt_field_floating_point_destroy,
178 [BT_FIELD_TYPE_ID_STRUCT] = bt_field_structure_destroy_recursive,
179 [BT_FIELD_TYPE_ID_VARIANT] = bt_field_variant_destroy_recursive,
180 [BT_FIELD_TYPE_ID_ARRAY] = bt_field_array_destroy_recursive,
181 [BT_FIELD_TYPE_ID_SEQUENCE] = bt_field_sequence_destroy_recursive,
182 [BT_FIELD_TYPE_ID_STRING] = bt_field_string_destroy,
183 };
184
185 BT_HIDDEN
186 struct bt_field *bt_field_create_recursive(struct bt_field_type *type)
187 {
188 struct bt_field *field = NULL;
189 enum bt_field_type_id type_id;
190
191 BT_ASSERT_PRE_NON_NULL(type, "Field type");
192 BT_ASSERT(field_type_common_has_known_id((void *) type));
193 BT_ASSERT_PRE(bt_field_type_common_validate((void *) type) == 0,
194 "Field type is invalid: %!+F", type);
195 type_id = bt_field_type_get_type_id(type);
196 field = field_create_funcs[type_id](type);
197 if (!field) {
198 goto end;
199 }
200
201 bt_field_type_freeze(type);
202
203 end:
204 return field;
205 }
206
207 struct bt_field_type *bt_field_borrow_type(struct bt_field *field)
208 {
209 return (void *) bt_field_common_borrow_type((void *) field);
210 }
211
212 enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
213 {
214 struct bt_field_common *field_common = (void *) field;
215
216 BT_ASSERT_PRE_NON_NULL(field, "Field");
217 return field_common->type->id;
218 }
219
220 bt_bool bt_field_is_integer(struct bt_field *field)
221 {
222 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_INTEGER;
223 }
224
225 bt_bool bt_field_is_floating_point(struct bt_field *field)
226 {
227 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_FLOAT;
228 }
229
230 bt_bool bt_field_is_enumeration(struct bt_field *field)
231 {
232 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ENUM;
233 }
234
235 bt_bool bt_field_is_string(struct bt_field *field)
236 {
237 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRING;
238 }
239
240 bt_bool bt_field_is_structure(struct bt_field *field)
241 {
242 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_STRUCT;
243 }
244
245 bt_bool bt_field_is_array(struct bt_field *field)
246 {
247 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_ARRAY;
248 }
249
250 bt_bool bt_field_is_sequence(struct bt_field *field)
251 {
252 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_SEQUENCE;
253 }
254
255 bt_bool bt_field_is_variant(struct bt_field *field)
256 {
257 return bt_field_get_type_id(field) == BT_FIELD_TYPE_ID_VARIANT;
258 }
259
260 int64_t bt_field_sequence_get_length(struct bt_field *field)
261 {
262 return bt_field_common_sequence_get_length((void *) field);
263 }
264
265 int bt_field_sequence_set_length(struct bt_field *field, uint64_t length)
266 {
267 return bt_field_common_sequence_set_length((void *) field,
268 length, (bt_field_common_create_func) bt_field_create_recursive);
269 }
270
271 struct bt_field *bt_field_structure_borrow_field_by_index(
272 struct bt_field *field, uint64_t index)
273 {
274 return (void *) bt_field_common_structure_borrow_field_by_index(
275 (void *) field, index);
276 }
277
278 struct bt_field *bt_field_structure_borrow_field_by_name(
279 struct bt_field *field, const char *name)
280 {
281 return (void *) bt_field_common_structure_borrow_field_by_name(
282 (void *) field, name);
283 }
284
285 struct bt_field *bt_field_array_borrow_field(
286 struct bt_field *field, uint64_t index)
287 {
288 return (void *) bt_field_common_array_borrow_field((void *) field,
289 index);
290 }
291
292 struct bt_field *bt_field_sequence_borrow_field(
293 struct bt_field *field, uint64_t index)
294 {
295 return (void *) bt_field_common_sequence_borrow_field((void *) field,
296 index);
297 }
298
299 struct bt_field *bt_field_variant_borrow_current_field(
300 struct bt_field *variant_field)
301 {
302 return (void *) bt_field_common_variant_borrow_current_field(
303 (void *) variant_field);
304 }
305
306 int bt_field_variant_set_tag_signed(struct bt_field *variant_field,
307 int64_t tag)
308 {
309 return bt_field_variant_common_set_tag((void *) variant_field,
310 (uint64_t) tag, true);
311 }
312
313 int bt_field_variant_set_tag_unsigned(struct bt_field *variant_field,
314 uint64_t tag)
315 {
316 return bt_field_variant_common_set_tag((void *) variant_field,
317 (uint64_t) tag, false);
318 }
319
320 int bt_field_variant_get_tag_signed(struct bt_field *variant_field,
321 int64_t *tag)
322 {
323 return bt_field_common_variant_get_tag_signed((void *) variant_field, tag);
324 }
325
326 int bt_field_variant_get_tag_unsigned(struct bt_field *variant_field,
327 uint64_t *tag)
328 {
329 return bt_field_common_variant_get_tag_unsigned((void *) variant_field, tag);
330 }
331
332 struct bt_field_type_enumeration_mapping_iterator *
333 bt_field_enumeration_get_mappings(struct bt_field *field)
334 {
335 struct bt_field_enumeration *enum_field = (void *) field;
336
337 BT_ASSERT_PRE_NON_NULL(field, "Enumeration field");
338 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID((struct bt_field_common *) field,
339 BT_FIELD_TYPE_ID_ENUM, "Field");
340 BT_ASSERT_PRE_FIELD_COMMON_IS_SET((struct bt_field_common *) field,
341 "Enumeration field");
342 return bt_field_common_enumeration_get_mappings((void *) field,
343 (bt_field_common_create_func) bt_field_create_recursive,
344 enum_field->common.payload.unsignd);
345 }
346
347 BT_ASSERT_PRE_FUNC
348 static inline
349 struct bt_field_type_common_integer *get_int_enum_int_ft(
350 struct bt_field *field)
351 {
352 struct bt_field_common_integer *int_field = (void *) field;
353 struct bt_field_type_common_integer *int_ft = NULL;
354
355 if (int_field->common.type->id == BT_FIELD_TYPE_ID_INTEGER) {
356 int_ft = BT_FROM_COMMON(int_field->common.type);
357 } else if (int_field->common.type->id == BT_FIELD_TYPE_ID_ENUM) {
358 struct bt_field_type_common_enumeration *enum_ft =
359 BT_FROM_COMMON(int_field->common.type);
360 int_ft = enum_ft->container_ft;
361 }
362
363 BT_ASSERT(int_ft);
364 return int_ft;
365 }
366
367 int bt_field_integer_signed_get_value(struct bt_field *field, int64_t *value)
368 {
369 struct bt_field_common_integer *integer = (void *) field;
370
371 BT_ASSERT_PRE_NON_NULL(field, "Integer/enumeration field");
372 BT_ASSERT_PRE_NON_NULL(value, "Value");
373 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(BT_TO_COMMON(integer),
374 "Integer/enumeration field");
375 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(BT_TO_COMMON(integer), "Field");
376 BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(
377 BT_TO_COMMON(get_int_enum_int_ft(field))),
378 "Field's type is unsigned: %!+f", field);
379 *value = integer->payload.signd;
380 return 0;
381 }
382
383 int bt_field_integer_signed_set_value(struct bt_field *field, int64_t value)
384 {
385 int ret = 0;
386 struct bt_field_common_integer *integer = (void *) field;
387
388 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
389 BT_ASSERT_PRE_FIELD_COMMON_HOT(BT_TO_COMMON(integer), "Integer field");
390 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(BT_TO_COMMON(integer), "Field");
391 BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(
392 BT_FROM_COMMON(get_int_enum_int_ft(field))),
393 "Field's type is unsigned: %!+f", field);
394 BT_ASSERT_PRE(value_is_in_range_signed(
395 get_int_enum_int_ft(field)->size, value),
396 "Value is out of bounds: value=%" PRId64 ", %![field-]+f",
397 value, field);
398 integer->payload.signd = value;
399 bt_field_set(field, true);
400 return ret;
401 }
402
403 int bt_field_integer_unsigned_get_value(struct bt_field *field, uint64_t *value)
404 {
405 struct bt_field_common_integer *integer = (void *) field;
406
407 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
408 BT_ASSERT_PRE_NON_NULL(value, "Value");
409 BT_ASSERT_PRE_FIELD_COMMON_IS_SET(BT_TO_COMMON(integer), "Integer field");
410 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(BT_TO_COMMON(integer), "Field");
411 BT_ASSERT_PRE(!bt_field_type_common_integer_is_signed(
412 BT_FROM_COMMON(get_int_enum_int_ft(field))),
413 "Field's type is signed: %!+f", field);
414 *value = integer->payload.unsignd;
415 return 0;
416 }
417
418 int bt_field_integer_unsigned_set_value(struct bt_field *field,
419 uint64_t value)
420 {
421 struct bt_field_common_integer *integer = (void *) field;
422
423 BT_ASSERT_PRE_NON_NULL(field, "Integer field");
424 BT_ASSERT_PRE_FIELD_COMMON_HOT(BT_TO_COMMON(integer), "Integer field");
425 BT_ASSERT_PRE_FIELD_IS_INT_OR_ENUM(BT_TO_COMMON(integer), "Field");
426 BT_ASSERT_PRE(!bt_field_type_common_integer_is_signed(
427 BT_FROM_COMMON(get_int_enum_int_ft(field))),
428 "Field's type is signed: %!+f", field);
429 BT_ASSERT_PRE(value_is_in_range_unsigned(
430 get_int_enum_int_ft(field)->size, value),
431 "Value is out of bounds: value=%" PRIu64 ", %![field-]+f",
432 value, field);
433 integer->payload.unsignd = value;
434 bt_field_set(field, true);
435 return 0;
436 }
437
438 int bt_field_floating_point_get_value(struct bt_field *field,
439 double *value)
440 {
441 return bt_field_common_floating_point_get_value((void *) field, value);
442 }
443
444 int bt_field_floating_point_set_value(struct bt_field *field,
445 double value)
446 {
447 return bt_field_common_floating_point_set_value((void *) field, value);
448 }
449
450 const char *bt_field_string_get_value(struct bt_field *field)
451 {
452 return bt_field_common_string_get_value((void *) field);
453 }
454
455 int bt_field_string_set_value(struct bt_field *field, const char *value)
456 {
457 return bt_field_common_string_set_value((void *) field, value);
458 }
459
460 int bt_field_string_append(struct bt_field *field, const char *value)
461 {
462 return bt_field_common_string_append((void *) field, value);
463 }
464
465 int bt_field_string_append_len(struct bt_field *field,
466 const char *value, unsigned int length)
467 {
468 return bt_field_common_string_append_len((void *) field, value, length);
469 }
470
471 int bt_field_string_clear(struct bt_field *string_field)
472 {
473 return bt_field_common_string_clear((void *) string_field);
474 }
475
476 BT_HIDDEN
477 struct bt_field_common *bt_field_common_copy(struct bt_field_common *field)
478 {
479 struct bt_field_common *copy = NULL;
480
481 BT_ASSERT_PRE_NON_NULL(field, "Field");
482 BT_ASSERT(field_type_common_has_known_id(field->type));
483 BT_ASSERT(field->methods->copy);
484 copy = field->methods->copy(field);
485 if (!copy) {
486 BT_LOGW("Cannot create field: ft-addr=%p", field->type);
487 goto end;
488 }
489
490 bt_field_common_set(copy, field->payload_set);
491
492 end:
493 return copy;
494 }
495
496 static
497 void bt_field_integer_destroy(struct bt_field *field)
498 {
499 BT_LOGD("Destroying integer field object: addr=%p", field);
500 bt_field_common_integer_finalize((void *) field);
501 g_free(field);
502 }
503
504 static
505 void bt_field_floating_point_destroy(struct bt_field *field)
506 {
507 BT_LOGD("Destroying floating point field object: addr=%p", field);
508 bt_field_common_floating_point_finalize((void *) field);
509 g_free(field);
510 }
511
512 static
513 void bt_field_enumeration_destroy(struct bt_field *field)
514 {
515 BT_LOGD("Destroying enumeration field object: addr=%p", field);
516 bt_field_common_finalize((void *) field);
517 g_free(field);
518 }
519
520 static
521 void bt_field_structure_destroy_recursive(struct bt_field *field)
522 {
523 BT_LOGD("Destroying structure field object: addr=%p", field);
524 bt_field_common_structure_finalize_recursive((void *) field);
525 g_free(field);
526 }
527
528 static
529 void bt_field_variant_destroy_recursive(struct bt_field *field)
530 {
531 BT_LOGD("Destroying variant field object: addr=%p", field);
532 bt_field_common_variant_finalize_recursive((void *) field);
533 g_free(field);
534 }
535
536 static
537 void bt_field_array_destroy_recursive(struct bt_field *field)
538 {
539 BT_LOGD("Destroying array field object: addr=%p", field);
540 bt_field_common_array_finalize_recursive((void *) field);
541 g_free(field);
542 }
543
544 static
545 void bt_field_sequence_destroy_recursive(struct bt_field *field)
546 {
547 BT_LOGD("Destroying sequence field object: addr=%p", field);
548 bt_field_common_sequence_finalize_recursive((void *) field);
549 g_free(field);
550 }
551
552 static
553 void bt_field_string_destroy(struct bt_field *field)
554 {
555 BT_LOGD("Destroying string field object: addr=%p", field);
556 bt_field_common_string_finalize((void *) field);
557 g_free(field);
558 }
559
560 BT_HIDDEN
561 void bt_field_destroy_recursive(struct bt_field *field)
562 {
563 struct bt_field_common *field_common = (void *) field;
564
565 if (!field) {
566 return;
567 }
568
569 BT_ASSERT(field_type_common_has_known_id((void *) field_common->type));
570 field_destroy_funcs[field_common->type->id](field);
571 }
572
573 static
574 struct bt_field *bt_field_integer_create(struct bt_field_type *type)
575 {
576 struct bt_field_common_integer *integer =
577 g_new0(struct bt_field_common_integer, 1);
578
579 BT_LOGD("Creating integer field object: ft-addr=%p", type);
580
581 if (integer) {
582 bt_field_common_initialize(BT_TO_COMMON(integer), (void *) type,
583 false, NULL, &bt_field_integer_methods);
584 BT_LOGD("Created integer field object: addr=%p, ft-addr=%p",
585 integer, type);
586 } else {
587 BT_LOGE_STR("Failed to allocate one integer field.");
588 }
589
590 return (void *) integer;
591 }
592
593 static
594 struct bt_field *bt_field_enumeration_create(struct bt_field_type *type)
595 {
596 struct bt_field_enumeration *enumeration = g_new0(
597 struct bt_field_enumeration, 1);
598
599 BT_LOGD("Creating enumeration field object: ft-addr=%p", type);
600
601 if (enumeration) {
602 bt_field_common_initialize(
603 BT_TO_COMMON(BT_TO_COMMON(enumeration)),
604 (void *) type, false, NULL,
605 &bt_field_enumeration_methods);
606 BT_LOGD("Created enumeration field object: addr=%p, ft-addr=%p",
607 enumeration, type);
608 } else {
609 BT_LOGE_STR("Failed to allocate one enumeration field.");
610 }
611
612 return (void *) enumeration;
613 }
614
615 static
616 struct bt_field *bt_field_floating_point_create(struct bt_field_type *type)
617 {
618 struct bt_field_common_floating_point *floating_point;
619
620 BT_LOGD("Creating floating point number field object: ft-addr=%p", type);
621 floating_point = g_new0(struct bt_field_common_floating_point, 1);
622
623 if (floating_point) {
624 bt_field_common_initialize(BT_TO_COMMON(floating_point),
625 (void *) type, false, NULL,
626 &bt_field_floating_point_methods);
627 BT_LOGD("Created floating point number field object: addr=%p, ft-addr=%p",
628 floating_point, type);
629 } else {
630 BT_LOGE_STR("Failed to allocate one floating point number field.");
631 }
632
633 return (void *) floating_point;
634 }
635
636 BT_HIDDEN
637 int bt_field_common_structure_initialize(struct bt_field_common *field,
638 struct bt_field_type_common *type,
639 bool is_shared, bt_object_release_func release_func,
640 struct bt_field_common_methods *methods,
641 bt_field_common_create_func field_create_func,
642 GDestroyNotify field_release_func)
643 {
644 int ret = 0;
645 struct bt_field_type_common_structure *structure_type =
646 BT_FROM_COMMON(type);
647 struct bt_field_common_structure *structure = BT_FROM_COMMON(field);
648 size_t i;
649
650 BT_LOGD("Initializing common structure field object: ft-addr=%p", type);
651 bt_field_common_initialize(field, type, is_shared,
652 release_func, methods);
653 structure->fields = g_ptr_array_new_with_free_func(field_release_func);
654 g_ptr_array_set_size(structure->fields, structure_type->fields->len);
655
656 /* Create all fields contained in the structure field. */
657 for (i = 0; i < structure_type->fields->len; i++) {
658 struct bt_field_common *field;
659 struct bt_field_type_common_structure_field *struct_field =
660 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
661 structure_type, i);
662 field = field_create_func(struct_field->type);
663 if (!field) {
664 BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
665 g_quark_to_string(struct_field->name), i);
666 ret = -1;
667 goto end;
668 }
669
670 g_ptr_array_index(structure->fields, i) = field;
671 }
672
673 BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
674 field, type);
675
676 end:
677 return ret;
678 }
679
680 static
681 struct bt_field *bt_field_structure_create(struct bt_field_type *type)
682 {
683 struct bt_field_common_structure *structure = g_new0(
684 struct bt_field_common_structure, 1);
685 int iret;
686
687 BT_LOGD("Creating structure field object: ft-addr=%p", type);
688
689 if (!structure) {
690 BT_LOGE_STR("Failed to allocate one structure field.");
691 goto end;
692 }
693
694 iret = bt_field_common_structure_initialize(BT_TO_COMMON(structure),
695 (void *) type, false, NULL, &bt_field_structure_methods,
696 (bt_field_common_create_func) bt_field_create_recursive,
697 (GDestroyNotify) bt_field_destroy_recursive);
698 if (iret) {
699 BT_PUT(structure);
700 goto end;
701 }
702
703 BT_LOGD("Created structure field object: addr=%p, ft-addr=%p",
704 structure, type);
705
706 end:
707 return (void *) structure;
708 }
709
710 BT_HIDDEN
711 int bt_field_common_variant_initialize(struct bt_field_common *field,
712 struct bt_field_type_common *type,
713 bool is_shared, bt_object_release_func release_func,
714 struct bt_field_common_methods *methods,
715 bt_field_common_create_func field_create_func,
716 GDestroyNotify field_release_func)
717 {
718 int ret = 0;
719 struct bt_field_type_common_variant *variant_type =
720 BT_FROM_COMMON(type);
721 struct bt_field_common_variant *variant = BT_FROM_COMMON(field);
722 size_t i;
723
724 BT_LOGD("Initializing common variant field object: ft-addr=%p", type);
725 bt_field_common_initialize(field, type, is_shared,
726 release_func, methods);
727 ret = bt_field_type_common_variant_update_choices(type);
728 if (ret) {
729 BT_LOGE("Cannot update common variant field type choices: "
730 "ret=%d", ret);
731 goto end;
732 }
733
734 variant->fields = g_ptr_array_new_with_free_func(field_release_func);
735 g_ptr_array_set_size(variant->fields, variant_type->choices->len);
736
737 /* Create all fields contained in the variant field. */
738 for (i = 0; i < variant_type->choices->len; i++) {
739 struct bt_field_common *field;
740 struct bt_field_type_common_variant_choice *var_choice =
741 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
742 variant_type, i);
743
744 field = field_create_func(var_choice->type);
745 if (!field) {
746 BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
747 g_quark_to_string(var_choice->name), i);
748 ret = -1;
749 goto end;
750 }
751
752 g_ptr_array_index(variant->fields, i) = field;
753 }
754
755 BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
756 field, type);
757
758 end:
759 return ret;
760 }
761
762 BT_HIDDEN
763 int bt_field_common_string_initialize(struct bt_field_common *field,
764 struct bt_field_type_common *type,
765 bool is_shared, bt_object_release_func release_func,
766 struct bt_field_common_methods *methods)
767 {
768 int ret = 0;
769 struct bt_field_common_string *string = BT_FROM_COMMON(field);
770
771 BT_LOGD("Initializing common string field object: ft-addr=%p", type);
772 bt_field_common_initialize(field, type, is_shared,
773 release_func, methods);
774 string->buf = g_array_sized_new(FALSE, FALSE, sizeof(char), 1);
775 if (!string->buf) {
776 ret = -1;
777 goto end;
778 }
779
780 g_array_index(string->buf, char, 0) = '\0';
781 BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
782 field, type);
783
784 end:
785 return ret;
786 }
787
788 static
789 struct bt_field *bt_field_variant_create(struct bt_field_type *type)
790 {
791 struct bt_field_common_variant *variant = g_new0(
792 struct bt_field_common_variant, 1);
793 int iret;
794
795 BT_LOGD("Creating variant field object: ft-addr=%p", type);
796
797 if (!variant) {
798 BT_LOGE_STR("Failed to allocate one variant field.");
799 goto end;
800 }
801
802 iret = bt_field_common_variant_initialize(BT_TO_COMMON(variant),
803 (void *) type, false, NULL, &bt_field_variant_methods,
804 (bt_field_common_create_func) bt_field_create_recursive,
805 (GDestroyNotify) bt_field_destroy_recursive);
806 if (iret) {
807 BT_PUT(variant);
808 goto end;
809 }
810
811 BT_LOGD("Created variant field object: addr=%p, ft-addr=%p",
812 variant, type);
813
814 end:
815 return (void *) variant;
816 }
817
818 BT_HIDDEN
819 int bt_field_common_array_initialize(struct bt_field_common *field,
820 struct bt_field_type_common *type,
821 bool is_shared, bt_object_release_func release_func,
822 struct bt_field_common_methods *methods,
823 bt_field_common_create_func field_create_func,
824 GDestroyNotify field_destroy_func)
825 {
826 struct bt_field_type_common_array *array_type = BT_FROM_COMMON(type);
827 struct bt_field_common_array *array = BT_FROM_COMMON(field);
828 unsigned int array_length;
829 int ret = 0;
830 uint64_t i;
831
832 BT_LOGD("Initializing common array field object: ft-addr=%p", type);
833 BT_ASSERT(type);
834 bt_field_common_initialize(field, type, is_shared,
835 release_func, methods);
836 array_length = array_type->length;
837 array->elements = g_ptr_array_sized_new(array_length);
838 if (!array->elements) {
839 ret = -1;
840 goto end;
841 }
842
843 g_ptr_array_set_free_func(array->elements, field_destroy_func);
844 g_ptr_array_set_size(array->elements, array_length);
845
846 for (i = 0; i < array_length; i++) {
847 array->elements->pdata[i] = field_create_func(
848 array_type->element_ft);
849 if (!array->elements->pdata[i]) {
850 ret = -1;
851 goto end;
852 }
853 }
854
855 BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
856 field, type);
857
858 end:
859 return ret;
860 }
861
862 static
863 struct bt_field *bt_field_array_create(struct bt_field_type *type)
864 {
865 struct bt_field_common_array *array =
866 g_new0(struct bt_field_common_array, 1);
867 int ret;
868
869 BT_LOGD("Creating array field object: ft-addr=%p", type);
870 BT_ASSERT(type);
871
872 if (!array) {
873 BT_LOGE_STR("Failed to allocate one array field.");
874 goto end;
875 }
876
877 ret = bt_field_common_array_initialize(BT_TO_COMMON(array),
878 (void *) type, false, NULL, &bt_field_array_methods,
879 (bt_field_common_create_func) bt_field_create_recursive,
880 (GDestroyNotify) bt_field_destroy_recursive);
881 if (ret) {
882 BT_PUT(array);
883 goto end;
884 }
885
886 BT_LOGD("Created array field object: addr=%p, ft-addr=%p",
887 array, type);
888
889 end:
890 return (void *) array;
891 }
892
893 BT_HIDDEN
894 int bt_field_common_sequence_initialize(struct bt_field_common *field,
895 struct bt_field_type_common *type,
896 bool is_shared, bt_object_release_func release_func,
897 struct bt_field_common_methods *methods,
898 GDestroyNotify field_destroy_func)
899 {
900 struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field);
901 int ret = 0;
902
903 BT_LOGD("Initializing common sequence field object: ft-addr=%p", type);
904 BT_ASSERT(type);
905 bt_field_common_initialize(field, type, is_shared,
906 release_func, methods);
907 sequence->elements = g_ptr_array_new();
908 if (!sequence->elements) {
909 ret = -1;
910 goto end;
911 }
912
913 g_ptr_array_set_free_func(sequence->elements, field_destroy_func);
914 BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
915 field, type);
916
917 end:
918 return ret;
919 }
920
921 static
922 struct bt_field *bt_field_sequence_create(struct bt_field_type *type)
923 {
924 struct bt_field_common_sequence *sequence =
925 g_new0(struct bt_field_common_sequence, 1);
926 int ret;
927
928 BT_LOGD("Creating sequence field object: ft-addr=%p", type);
929 BT_ASSERT(type);
930
931 if (!sequence) {
932 BT_LOGE_STR("Failed to allocate one sequence field.");
933 goto end;
934 }
935
936 ret = bt_field_common_sequence_initialize(BT_TO_COMMON(sequence),
937 (void *) type, false, NULL, &bt_field_sequence_methods,
938 (GDestroyNotify) bt_field_destroy_recursive);
939 if (ret) {
940 BT_PUT(sequence);
941 goto end;
942 }
943
944 BT_LOGD("Created sequence field object: addr=%p, ft-addr=%p",
945 sequence, type);
946
947 end:
948 return (void *) sequence;
949 }
950
951 static
952 struct bt_field *bt_field_string_create(struct bt_field_type *type)
953 {
954 struct bt_field_common_string *string = g_new0(
955 struct bt_field_common_string, 1);
956
957 BT_LOGD("Creating string field object: ft-addr=%p", type);
958
959 if (string) {
960 bt_field_common_string_initialize(BT_TO_COMMON(string),
961 (void *) type, false, NULL, &bt_field_string_methods);
962 BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
963 string, type);
964 } else {
965 BT_LOGE_STR("Failed to allocate one string field.");
966 }
967
968 return (void *) string;
969 }
970
971 BT_HIDDEN
972 int bt_field_common_generic_validate(struct bt_field_common *field)
973 {
974 return (field && field->payload_set) ? 0 : -1;
975 }
976
977 BT_HIDDEN
978 int bt_field_common_structure_validate_recursive(struct bt_field_common *field)
979 {
980 int64_t i;
981 int ret = 0;
982 struct bt_field_common_structure *structure = BT_FROM_COMMON(field);
983
984 BT_ASSERT(field);
985
986 for (i = 0; i < structure->fields->len; i++) {
987 ret = bt_field_common_validate_recursive(
988 (void *) structure->fields->pdata[i]);
989
990 if (ret) {
991 int this_ret;
992 const char *name;
993
994 this_ret = bt_field_type_common_structure_borrow_field_by_index(
995 field->type, &name, NULL, i);
996 BT_ASSERT(this_ret == 0);
997 BT_ASSERT_PRE_MSG("Invalid structure field's field: "
998 "%![struct-field-]+_f, field-name=\"%s\", "
999 "index=%" PRId64 ", %![field-]+_f",
1000 field, name, i, structure->fields->pdata[i]);
1001 goto end;
1002 }
1003 }
1004
1005 end:
1006 return ret;
1007 }
1008
1009 BT_HIDDEN
1010 int bt_field_common_variant_validate_recursive(struct bt_field_common *field)
1011 {
1012 int ret = 0;
1013 struct bt_field_common_variant *variant = BT_FROM_COMMON(field);
1014
1015 BT_ASSERT(field);
1016
1017 if (!variant->current_field) {
1018 ret = -1;
1019 goto end;
1020 }
1021
1022 ret = bt_field_common_validate_recursive(variant->current_field);
1023
1024 end:
1025 return ret;
1026 }
1027
1028 BT_HIDDEN
1029 int bt_field_common_array_validate_recursive(struct bt_field_common *field)
1030 {
1031 int64_t i;
1032 int ret = 0;
1033 struct bt_field_common_array *array = BT_FROM_COMMON(field);
1034
1035 BT_ASSERT(field);
1036
1037 for (i = 0; i < array->elements->len; i++) {
1038 ret = bt_field_common_validate_recursive((void *) array->elements->pdata[i]);
1039 if (ret) {
1040 BT_ASSERT_PRE_MSG("Invalid array field's element field: "
1041 "%![array-field-]+_f, " PRId64 ", "
1042 "%![elem-field-]+_f",
1043 field, i, array->elements->pdata[i]);
1044 goto end;
1045 }
1046 }
1047
1048 end:
1049 return ret;
1050 }
1051
1052 BT_HIDDEN
1053 int bt_field_common_sequence_validate_recursive(struct bt_field_common *field)
1054 {
1055 size_t i;
1056 int ret = 0;
1057 struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field);
1058
1059 BT_ASSERT(field);
1060
1061 for (i = 0; i < sequence->elements->len; i++) {
1062 ret = bt_field_common_validate_recursive(
1063 (void *) sequence->elements->pdata[i]);
1064 if (ret) {
1065 BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
1066 "%![seq-field-]+_f, " PRId64 ", "
1067 "%![elem-field-]+_f",
1068 field, i, sequence->elements->pdata[i]);
1069 goto end;
1070 }
1071 }
1072 end:
1073 return ret;
1074 }
1075
1076 BT_HIDDEN
1077 void bt_field_common_generic_reset(struct bt_field_common *field)
1078 {
1079 BT_ASSERT(field);
1080 field->payload_set = false;
1081 }
1082
1083 BT_HIDDEN
1084 void bt_field_common_structure_reset_recursive(struct bt_field_common *field)
1085 {
1086 int64_t i;
1087 struct bt_field_common_structure *structure = BT_FROM_COMMON(field);
1088
1089 BT_ASSERT(field);
1090
1091 for (i = 0; i < structure->fields->len; i++) {
1092 struct bt_field_common *member = structure->fields->pdata[i];
1093
1094 if (!member) {
1095 /*
1096 * Structure members are lazily initialized;
1097 * skip if this member has not been allocated
1098 * yet.
1099 */
1100 continue;
1101 }
1102
1103 bt_field_common_reset_recursive(member);
1104 }
1105 }
1106
1107 BT_HIDDEN
1108 void bt_field_common_variant_reset_recursive(struct bt_field_common *field)
1109 {
1110 struct bt_field_common_variant *variant = BT_FROM_COMMON(field);
1111
1112 BT_ASSERT(field);
1113 variant->current_field = NULL;
1114 }
1115
1116 BT_HIDDEN
1117 void bt_field_common_array_reset_recursive(struct bt_field_common *field)
1118 {
1119 size_t i;
1120 struct bt_field_common_array *array = BT_FROM_COMMON(field);
1121
1122 BT_ASSERT(field);
1123
1124 for (i = 0; i < array->elements->len; i++) {
1125 struct bt_field_common *member = array->elements->pdata[i];
1126
1127 if (!member) {
1128 /*
1129 * Array elements are lazily initialized; skip
1130 * if this member has not been allocated yet.
1131 */
1132 continue;
1133 }
1134
1135 bt_field_common_reset_recursive(member);
1136 }
1137 }
1138
1139 BT_HIDDEN
1140 void bt_field_common_sequence_reset_recursive(struct bt_field_common *field)
1141 {
1142 struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field);
1143 uint64_t i;
1144
1145 BT_ASSERT(field);
1146
1147 for (i = 0; i < sequence->elements->len; i++) {
1148 if (sequence->elements->pdata[i]) {
1149 bt_field_common_reset_recursive(
1150 sequence->elements->pdata[i]);
1151 }
1152 }
1153
1154 sequence->length = 0;
1155 }
1156
1157 BT_HIDDEN
1158 void bt_field_common_generic_set_is_frozen(struct bt_field_common *field,
1159 bool is_frozen)
1160 {
1161 field->frozen = is_frozen;
1162 }
1163
1164 BT_HIDDEN
1165 void bt_field_common_structure_set_is_frozen_recursive(
1166 struct bt_field_common *field, bool is_frozen)
1167 {
1168 uint64_t i;
1169 struct bt_field_common_structure *structure_field =
1170 BT_FROM_COMMON(field);
1171
1172 BT_LOGD("Freezing structure field object: addr=%p", field);
1173
1174 for (i = 0; i < structure_field->fields->len; i++) {
1175 struct bt_field_common *struct_field =
1176 g_ptr_array_index(structure_field->fields, i);
1177
1178 BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
1179 struct_field, i);
1180 bt_field_common_set_is_frozen_recursive(struct_field,
1181 is_frozen);
1182 }
1183
1184 bt_field_common_generic_set_is_frozen(field, is_frozen);
1185 }
1186
1187 BT_HIDDEN
1188 void bt_field_common_variant_set_is_frozen_recursive(
1189 struct bt_field_common *field, bool is_frozen)
1190 {
1191 uint64_t i;
1192 struct bt_field_common_variant *variant_field = BT_FROM_COMMON(field);
1193
1194 BT_LOGD("Freezing variant field object: addr=%p", field);
1195
1196 for (i = 0; i < variant_field->fields->len; i++) {
1197 struct bt_field_common *var_field =
1198 g_ptr_array_index(variant_field->fields, i);
1199
1200 BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64,
1201 var_field, i);
1202 bt_field_common_set_is_frozen_recursive(var_field, is_frozen);
1203 }
1204
1205 bt_field_common_generic_set_is_frozen(field, is_frozen);
1206 }
1207
1208 BT_HIDDEN
1209 void bt_field_common_array_set_is_frozen_recursive(
1210 struct bt_field_common *field, bool is_frozen)
1211 {
1212 int64_t i;
1213 struct bt_field_common_array *array_field = BT_FROM_COMMON(field);
1214
1215 BT_LOGD("Freezing array field object: addr=%p", field);
1216
1217 for (i = 0; i < array_field->elements->len; i++) {
1218 struct bt_field_common *elem_field =
1219 g_ptr_array_index(array_field->elements, i);
1220
1221 BT_LOGD("Freezing array field object's element field: "
1222 "element-field-addr=%p, index=%" PRId64,
1223 elem_field, i);
1224 bt_field_common_set_is_frozen_recursive(elem_field, is_frozen);
1225 }
1226
1227 bt_field_common_generic_set_is_frozen(field, is_frozen);
1228 }
1229
1230 BT_HIDDEN
1231 void bt_field_common_sequence_set_is_frozen_recursive(
1232 struct bt_field_common *field, bool is_frozen)
1233 {
1234 int64_t i;
1235 struct bt_field_common_sequence *sequence_field =
1236 BT_FROM_COMMON(field);
1237
1238 BT_LOGD("Freezing sequence field object: addr=%p", field);
1239
1240 for (i = 0; i < sequence_field->length; i++) {
1241 struct bt_field_common *elem_field =
1242 g_ptr_array_index(sequence_field->elements, i);
1243
1244 BT_LOGD("Freezing sequence field object's element field: "
1245 "element-field-addr=%p, index=%" PRId64,
1246 elem_field, i);
1247 bt_field_common_set_is_frozen_recursive(elem_field, is_frozen);
1248 }
1249
1250 bt_field_common_generic_set_is_frozen(field, is_frozen);
1251 }
1252
1253 BT_HIDDEN
1254 void _bt_field_common_set_is_frozen_recursive(struct bt_field_common *field,
1255 bool is_frozen)
1256 {
1257 if (!field) {
1258 goto end;
1259 }
1260
1261 if (field->frozen) {
1262 goto end;
1263 }
1264
1265 BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
1266 field, is_frozen);
1267 BT_ASSERT(field_type_common_has_known_id(field->type));
1268 BT_ASSERT(field->methods->set_is_frozen);
1269 field->methods->set_is_frozen(field, is_frozen);
1270
1271 end:
1272 return;
1273 }
1274
1275 BT_HIDDEN
1276 bt_bool bt_field_common_generic_is_set(struct bt_field_common *field)
1277 {
1278 return field && field->payload_set;
1279 }
1280
1281 BT_HIDDEN
1282 bt_bool bt_field_common_structure_is_set_recursive(
1283 struct bt_field_common *field)
1284 {
1285 bt_bool is_set = BT_FALSE;
1286 size_t i;
1287 struct bt_field_common_structure *structure = BT_FROM_COMMON(field);
1288
1289 BT_ASSERT(field);
1290
1291 for (i = 0; i < structure->fields->len; i++) {
1292 is_set = bt_field_common_is_set_recursive(
1293 structure->fields->pdata[i]);
1294 if (!is_set) {
1295 goto end;
1296 }
1297 }
1298
1299 end:
1300 return is_set;
1301 }
1302
1303 BT_HIDDEN
1304 bt_bool bt_field_common_variant_is_set_recursive(struct bt_field_common *field)
1305 {
1306 struct bt_field_common_variant *variant = BT_FROM_COMMON(field);
1307 bt_bool is_set = BT_FALSE;
1308
1309 BT_ASSERT(field);
1310
1311 if (variant->current_field) {
1312 is_set = bt_field_common_is_set_recursive(
1313 variant->current_field);
1314 }
1315
1316 return is_set;
1317 }
1318
1319 BT_HIDDEN
1320 bt_bool bt_field_common_array_is_set_recursive(struct bt_field_common *field)
1321 {
1322 size_t i;
1323 bt_bool is_set = BT_FALSE;
1324 struct bt_field_common_array *array = BT_FROM_COMMON(field);
1325
1326 BT_ASSERT(field);
1327
1328 for (i = 0; i < array->elements->len; i++) {
1329 is_set = bt_field_common_is_set_recursive(array->elements->pdata[i]);
1330 if (!is_set) {
1331 goto end;
1332 }
1333 }
1334
1335 end:
1336 return is_set;
1337 }
1338
1339 BT_HIDDEN
1340 bt_bool bt_field_common_sequence_is_set_recursive(struct bt_field_common *field)
1341 {
1342 size_t i;
1343 bt_bool is_set = BT_FALSE;
1344 struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field);
1345
1346 BT_ASSERT(field);
1347
1348 if (!sequence->elements) {
1349 goto end;
1350 }
1351
1352 for (i = 0; i < sequence->elements->len; i++) {
1353 is_set = bt_field_common_is_set_recursive(
1354 sequence->elements->pdata[i]);
1355 if (!is_set) {
1356 goto end;
1357 }
1358 }
1359
1360 end:
1361 return is_set;
1362 }
This page took 0.084119 seconds and 4 git commands to generate.