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