lib: add internal object pool API and use it; adapt plugins/tests
[babeltrace.git] / lib / ctf-writer / field-types.c
1 /*
2 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 #define BT_LOG_TAG "CTF-WRITER-FIELD-TYPES"
26 #include <babeltrace/lib-logging-internal.h>
27
28 #include <babeltrace/assert-pre-internal.h>
29 #include <babeltrace/ctf-ir/field-types-internal.h>
30 #include <babeltrace/ctf-ir/utils-internal.h>
31 #include <babeltrace/ctf-ir/utils.h>
32 #include <babeltrace/ctf-ir/field-path-internal.h>
33 #include <babeltrace/ctf-writer/field-types.h>
34 #include <babeltrace/ctf-writer/field-types-internal.h>
35 #include <babeltrace/ctf-writer/fields.h>
36 #include <babeltrace/ctf-writer/fields-internal.h>
37 #include <babeltrace/ctf-writer/clock-internal.h>
38 #include <babeltrace/object-internal.h>
39 #include <babeltrace/ref.h>
40 #include <babeltrace/compiler-internal.h>
41 #include <babeltrace/endian-internal.h>
42 #include <babeltrace/assert-internal.h>
43 #include <float.h>
44 #include <inttypes.h>
45 #include <stdlib.h>
46
47 static
48 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
49 struct bt_ctf_field_type *ft);
50
51 static
52 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy_recursive(
53 struct bt_ctf_field_type *ft);
54
55 static
56 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
57 struct bt_ctf_field_type *ft);
58
59 static
60 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy_recursive(
61 struct bt_ctf_field_type *ft);
62
63 static
64 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy_recursive(
65 struct bt_ctf_field_type *ft);
66
67 static
68 struct bt_ctf_field_type *bt_ctf_field_type_array_copy_recursive(
69 struct bt_ctf_field_type *ft);
70
71 static
72 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy_recursive(
73 struct bt_ctf_field_type *type);
74
75 static
76 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
77 struct bt_ctf_field_type *type);
78
79 static struct bt_field_type_common_methods bt_ctf_field_type_integer_methods = {
80 .freeze = bt_field_type_common_generic_freeze,
81 .validate = bt_field_type_common_integer_validate,
82 .set_byte_order = bt_field_type_common_integer_set_byte_order,
83 .copy = (bt_field_type_common_method_copy)
84 bt_ctf_field_type_integer_copy,
85 .compare = bt_field_type_common_integer_compare,
86 };
87
88 static struct bt_field_type_common_methods bt_ctf_field_type_floating_point_methods = {
89 .freeze = bt_field_type_common_generic_freeze,
90 .validate = NULL,
91 .set_byte_order = bt_field_type_common_floating_point_set_byte_order,
92 .copy = (bt_field_type_common_method_copy)
93 bt_ctf_field_type_floating_point_copy,
94 .compare = bt_field_type_common_floating_point_compare,
95 };
96
97 static struct bt_field_type_common_methods bt_ctf_field_type_enumeration_methods = {
98 .freeze = bt_field_type_common_enumeration_freeze_recursive,
99 .validate = bt_field_type_common_enumeration_validate_recursive,
100 .set_byte_order = bt_field_type_common_enumeration_set_byte_order_recursive,
101 .copy = (bt_field_type_common_method_copy)
102 bt_ctf_field_type_enumeration_copy_recursive,
103 .compare = bt_field_type_common_enumeration_compare_recursive,
104 };
105
106 static struct bt_field_type_common_methods bt_ctf_field_type_string_methods = {
107 .freeze = bt_field_type_common_generic_freeze,
108 .validate = NULL,
109 .set_byte_order = NULL,
110 .copy = (bt_field_type_common_method_copy)
111 bt_ctf_field_type_string_copy,
112 .compare = bt_field_type_common_string_compare,
113 };
114
115 static struct bt_field_type_common_methods bt_ctf_field_type_array_methods = {
116 .freeze = bt_field_type_common_array_freeze_recursive,
117 .validate = bt_field_type_common_array_validate_recursive,
118 .set_byte_order = bt_field_type_common_array_set_byte_order_recursive,
119 .copy = (bt_field_type_common_method_copy)
120 bt_ctf_field_type_array_copy_recursive,
121 .compare = bt_field_type_common_array_compare_recursive,
122 };
123
124 static struct bt_field_type_common_methods bt_ctf_field_type_sequence_methods = {
125 .freeze = bt_field_type_common_sequence_freeze_recursive,
126 .validate = bt_field_type_common_sequence_validate_recursive,
127 .set_byte_order = bt_field_type_common_sequence_set_byte_order_recursive,
128 .copy = (bt_field_type_common_method_copy)
129 bt_ctf_field_type_sequence_copy_recursive,
130 .compare = bt_field_type_common_sequence_compare_recursive,
131 };
132
133 static struct bt_field_type_common_methods bt_ctf_field_type_structure_methods = {
134 .freeze = bt_field_type_common_structure_freeze_recursive,
135 .validate = bt_field_type_common_structure_validate_recursive,
136 .set_byte_order = bt_field_type_common_structure_set_byte_order_recursive,
137 .copy = (bt_field_type_common_method_copy)
138 bt_ctf_field_type_structure_copy_recursive,
139 .compare = bt_field_type_common_structure_compare_recursive,
140 };
141
142 static struct bt_field_type_common_methods bt_ctf_field_type_variant_methods = {
143 .freeze = bt_field_type_common_variant_freeze_recursive,
144 .validate = bt_field_type_common_variant_validate_recursive,
145 .set_byte_order = bt_field_type_common_variant_set_byte_order_recursive,
146 .copy = (bt_field_type_common_method_copy)
147 bt_ctf_field_type_variant_copy_recursive,
148 .compare = bt_field_type_common_variant_compare_recursive,
149 };
150
151 typedef int (*bt_ctf_field_type_serialize_func)(struct bt_field_type_common *,
152 struct metadata_context *);
153
154 BT_HIDDEN
155 int bt_ctf_field_type_serialize_recursive(struct bt_ctf_field_type *type,
156 struct metadata_context *context)
157 {
158 int ret;
159 struct bt_field_type_common *type_common = (void *) type;
160 bt_ctf_field_type_serialize_func serialize_func;
161
162 BT_ASSERT(type);
163 BT_ASSERT(context);
164
165 /* Make sure field type is valid before serializing it */
166 ret = bt_field_type_common_validate((void *) type);
167 if (ret) {
168 BT_LOGW("Cannot serialize field type's metadata: field type is invalid: "
169 "addr=%p", type);
170 goto end;
171 }
172
173 serialize_func = type_common->spec.writer.serialize_func;
174 ret = serialize_func((void *) type, context);
175
176 end:
177 return ret;
178 }
179
180 static
181 const char *get_encoding_string(enum bt_string_encoding encoding)
182 {
183 const char *encoding_string;
184
185 switch (encoding) {
186 case BT_STRING_ENCODING_NONE:
187 encoding_string = "none";
188 break;
189 case BT_STRING_ENCODING_ASCII:
190 encoding_string = "ASCII";
191 break;
192 case BT_STRING_ENCODING_UTF8:
193 encoding_string = "UTF8";
194 break;
195 default:
196 encoding_string = "unknown";
197 break;
198 }
199
200 return encoding_string;
201 }
202
203 static
204 const char *get_integer_base_string(enum bt_integer_base base)
205 {
206 const char *base_string;
207
208 switch (base) {
209 case BT_INTEGER_BASE_DECIMAL:
210 case BT_INTEGER_BASE_UNSPECIFIED:
211 base_string = "decimal";
212 break;
213 case BT_INTEGER_BASE_HEXADECIMAL:
214 base_string = "hexadecimal";
215 break;
216 case BT_INTEGER_BASE_OCTAL:
217 base_string = "octal";
218 break;
219 case BT_INTEGER_BASE_BINARY:
220 base_string = "binary";
221 break;
222 default:
223 base_string = "unknown";
224 break;
225 }
226
227 return base_string;
228 }
229
230 static
231 void append_field_name(struct metadata_context *context,
232 const char *name)
233 {
234 g_string_append_c(context->string, ' ');
235
236 if (!bt_identifier_is_valid(name) || *name == '_') {
237 g_string_append_c(context->string, '_');
238 }
239
240 g_string_append(context->string, name);
241 }
242
243 static
244 int bt_ctf_field_type_integer_serialize(struct bt_field_type_common *type,
245 struct metadata_context *context)
246 {
247 struct bt_field_type_common_integer *integer = BT_FROM_COMMON(type);
248 int ret = 0;
249
250 BT_LOGD("Serializing CTF writer integer field type's metadata: "
251 "ft-addr=%p, metadata-context-addr=%p", type, context);
252 g_string_append_printf(context->string,
253 "integer { size = %u; align = %u; signed = %s; encoding = %s; base = %s; byte_order = %s",
254 integer->size, type->alignment,
255 (integer->is_signed ? "true" : "false"),
256 get_encoding_string(integer->encoding),
257 get_integer_base_string(integer->base),
258 get_byte_order_string(integer->user_byte_order));
259 if (integer->mapped_clock_class) {
260 const char *clock_name = bt_clock_class_get_name(
261 integer->mapped_clock_class);
262
263 BT_ASSERT(clock_name);
264 g_string_append_printf(context->string,
265 "; map = clock.%s.value", clock_name);
266 }
267
268 g_string_append(context->string, "; }");
269 return ret;
270 }
271
272 static
273 int bt_ctf_field_type_enumeration_serialize_recursive(
274 struct bt_field_type_common *type,
275 struct metadata_context *context)
276 {
277 size_t entry;
278 int ret;
279 struct bt_field_type_common_enumeration *enumeration =
280 BT_FROM_COMMON(type);
281 struct bt_field_type_common *container_type;
282 int container_signed;
283
284 BT_LOGD("Serializing CTF writer enumeration field type's metadata: "
285 "ft-addr=%p, metadata-context-addr=%p", type, context);
286 container_type =
287 bt_field_type_common_enumeration_borrow_container_field_type(type);
288 BT_ASSERT(container_type);
289 container_signed = bt_field_type_common_integer_is_signed(
290 container_type);
291 BT_ASSERT(container_signed >= 0);
292 g_string_append(context->string, "enum : ");
293 BT_LOGD_STR("Serializing CTF writer enumeration field type's container field type's metadata.");
294 ret = bt_ctf_field_type_serialize_recursive(
295 (void *) enumeration->container_ft, context);
296 if (ret) {
297 BT_LOGW("Cannot serialize CTF writer enumeration field type's container field type's metadata: "
298 "container-ft-addr=%p", enumeration->container_ft);
299 goto end;
300 }
301
302 g_string_append(context->string, " { ");
303 for (entry = 0; entry < enumeration->entries->len; entry++) {
304 struct enumeration_mapping *mapping =
305 enumeration->entries->pdata[entry];
306 const char *label = g_quark_to_string(mapping->string);
307
308 g_string_append(context->string, "\"");
309
310 if (!bt_identifier_is_valid(label) || label[0] == '_') {
311 g_string_append(context->string, "_");
312 }
313
314 g_string_append_printf(context->string, "%s\" = ", label);
315
316 if (container_signed) {
317 if (mapping->range_start._signed ==
318 mapping->range_end._signed) {
319 g_string_append_printf(context->string,
320 "%" PRId64,
321 mapping->range_start._signed);
322 } else {
323 g_string_append_printf(context->string,
324 "%" PRId64 " ... %" PRId64,
325 mapping->range_start._signed,
326 mapping->range_end._signed);
327 }
328 } else {
329 if (mapping->range_start._unsigned ==
330 mapping->range_end._unsigned) {
331 g_string_append_printf(context->string,
332 "%" PRIu64,
333 mapping->range_start._unsigned);
334 } else {
335 g_string_append_printf(context->string,
336 "%" PRIu64 " ... %" PRIu64,
337 mapping->range_start._unsigned,
338 mapping->range_end._unsigned);
339 }
340 }
341
342 g_string_append(context->string,
343 ((entry != (enumeration->entries->len - 1)) ?
344 ", " : " }"));
345 }
346
347 if (context->field_name->len) {
348 append_field_name(context,
349 context->field_name->str);
350 g_string_assign(context->field_name, "");
351 }
352
353 end:
354 return ret;
355 }
356
357 static
358 int bt_ctf_field_type_floating_point_serialize(struct bt_field_type_common *type,
359 struct metadata_context *context)
360 {
361 struct bt_field_type_common_floating_point *floating_point =
362 BT_FROM_COMMON(type);
363
364 BT_LOGD("Serializing CTF writer floating point number field type's metadata: "
365 "ft-addr=%p, metadata-context-addr=%p", type, context);
366 g_string_append_printf(context->string,
367 "floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
368 floating_point->exp_dig,
369 floating_point->mant_dig,
370 get_byte_order_string(floating_point->user_byte_order),
371 type->alignment);
372 return 0;
373 }
374
375 static
376 int bt_ctf_field_type_structure_serialize_recursive(
377 struct bt_field_type_common *type,
378 struct metadata_context *context)
379 {
380 size_t i;
381 unsigned int indent;
382 int ret = 0;
383 struct bt_field_type_common_structure *structure = BT_FROM_COMMON(type);
384 GString *structure_field_name = context->field_name;
385
386 BT_LOGD("Serializing CTF writer structure field type's metadata: "
387 "ft-addr=%p, metadata-context-addr=%p", type, context);
388 context->field_name = g_string_new("");
389
390 context->current_indentation_level++;
391 g_string_append(context->string, "struct {\n");
392
393 for (i = 0; i < structure->fields->len; i++) {
394 struct bt_field_type_common_structure_field *field =
395 BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
396 structure, i);
397
398 BT_LOGD("Serializing CTF writer structure field type's field metadata: "
399 "index=%zu, "
400 "field-ft-addr=%p, field-name=\"%s\"",
401 i, field, g_quark_to_string(field->name));
402
403 for (indent = 0; indent < context->current_indentation_level;
404 indent++) {
405 g_string_append_c(context->string, '\t');
406 }
407
408 g_string_assign(context->field_name,
409 g_quark_to_string(field->name));
410 ret = bt_ctf_field_type_serialize_recursive(
411 (void *) field->type, context);
412 if (ret) {
413 BT_LOGW("Cannot serialize CTF writer structure field type's field's metadata: "
414 "index=%zu, "
415 "field-ft-addr=%p, field-name=\"%s\"",
416 i, field->type,
417 g_quark_to_string(field->name));
418 goto end;
419 }
420
421 if (context->field_name->len) {
422 append_field_name(context,
423 context->field_name->str);
424 }
425 g_string_append(context->string, ";\n");
426 }
427
428 context->current_indentation_level--;
429 for (indent = 0; indent < context->current_indentation_level;
430 indent++) {
431 g_string_append_c(context->string, '\t');
432 }
433
434 g_string_append_printf(context->string, "} align(%u)",
435 type->alignment);
436
437 end:
438 g_string_free(context->field_name, TRUE);
439 context->field_name = structure_field_name;
440 return ret;
441 }
442
443 static
444 int bt_ctf_field_type_variant_serialize_recursive(
445 struct bt_field_type_common *type,
446 struct metadata_context *context)
447 {
448 size_t i;
449 unsigned int indent;
450 int ret = 0;
451 struct bt_field_type_common_variant *variant = BT_FROM_COMMON(type);
452 GString *variant_field_name = context->field_name;
453
454 BT_LOGD("Serializing CTF writer variant field type's metadata: "
455 "ft-addr=%p, metadata-context-addr=%p", type, context);
456 context->field_name = g_string_new("");
457 if (variant->tag_name->len > 0) {
458 g_string_append(context->string, "variant <");
459 append_field_name(context, variant->tag_name->str);
460 g_string_append(context->string, "> {\n");
461 } else {
462 g_string_append(context->string, "variant {\n");
463 }
464
465 context->current_indentation_level++;
466 for (i = 0; i < variant->choices->len; i++) {
467 struct bt_field_type_common_variant_choice *field =
468 BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
469 variant, i);
470
471 BT_LOGD("Serializing CTF writer variant field type's field metadata: "
472 "index=%zu, "
473 "field-ft-addr=%p, field-name=\"%s\"",
474 i, field, g_quark_to_string(field->name));
475
476 g_string_assign(context->field_name,
477 g_quark_to_string(field->name));
478 for (indent = 0; indent < context->current_indentation_level;
479 indent++) {
480 g_string_append_c(context->string, '\t');
481 }
482
483 g_string_assign(context->field_name,
484 g_quark_to_string(field->name));
485 ret = bt_ctf_field_type_serialize_recursive(
486 (void *) field->type, context);
487 if (ret) {
488 BT_LOGW("Cannot serialize CTF writer variant field type's field's metadata: "
489 "index=%zu, "
490 "field-ft-addr=%p, field-name=\"%s\"",
491 i, field->type,
492 g_quark_to_string(field->name));
493 goto end;
494 }
495
496 if (context->field_name->len) {
497 append_field_name(context,
498 context->field_name->str);
499 g_string_append_c(context->string, ';');
500 }
501
502 g_string_append_c(context->string, '\n');
503 }
504
505 context->current_indentation_level--;
506 for (indent = 0; indent < context->current_indentation_level;
507 indent++) {
508 g_string_append_c(context->string, '\t');
509 }
510
511 g_string_append(context->string, "}");
512
513 end:
514 g_string_free(context->field_name, TRUE);
515 context->field_name = variant_field_name;
516 return ret;
517 }
518
519 static
520 int bt_ctf_field_type_array_serialize_recursive(
521 struct bt_field_type_common *type,
522 struct metadata_context *context)
523 {
524 int ret = 0;
525 struct bt_field_type_common_array *array = BT_FROM_COMMON(type);
526
527 BT_LOGD("Serializing CTF writer array field type's metadata: "
528 "ft-addr=%p, metadata-context-addr=%p", type, context);
529 BT_LOGD_STR("Serializing CTF writer array field type's element field type's metadata.");
530 ret = bt_ctf_field_type_serialize_recursive(
531 (void *) array->element_ft, context);
532 if (ret) {
533 BT_LOGW("Cannot serialize CTF writer array field type's element field type's metadata: "
534 "element-ft-addr=%p", array->element_ft);
535 goto end;
536 }
537
538 if (context->field_name->len) {
539 append_field_name(context,
540 context->field_name->str);
541
542 g_string_append_printf(context->string, "[%u]", array->length);
543 g_string_assign(context->field_name, "");
544 } else {
545 g_string_append_printf(context->string, "[%u]", array->length);
546 }
547
548 end:
549 return ret;
550 }
551
552 static
553 int bt_ctf_field_type_sequence_serialize_recursive(
554 struct bt_field_type_common *type,
555 struct metadata_context *context)
556 {
557 int ret = 0;
558 struct bt_field_type_common_sequence *sequence = BT_FROM_COMMON(type);
559
560 BT_LOGD("Serializing CTF writer sequence field type's metadata: "
561 "ft-addr=%p, metadata-context-addr=%p", type, context);
562 BT_LOGD_STR("Serializing CTF writer sequence field type's element field type's metadata.");
563 ret = bt_ctf_field_type_serialize_recursive(
564 (void *) sequence->element_ft, context);
565 if (ret) {
566 BT_LOGW("Cannot serialize CTF writer sequence field type's element field type's metadata: "
567 "element-ft-addr=%p", sequence->element_ft);
568 goto end;
569 }
570
571 if (context->field_name->len) {
572 append_field_name(context, context->field_name->str);
573 g_string_assign(context->field_name, "");
574 }
575 g_string_append(context->string, "[");
576 append_field_name(context, sequence->length_field_name->str);
577 g_string_append(context->string, "]");
578
579 end:
580 return ret;
581 }
582
583 static
584 int bt_ctf_field_type_string_serialize(struct bt_field_type_common *type,
585 struct metadata_context *context)
586 {
587 struct bt_field_type_common_string *string = BT_FROM_COMMON(type);
588
589 BT_LOGD("Serializing CTF writer string field type's metadata: "
590 "ft-addr=%p, metadata-context-addr=%p", type, context);
591 g_string_append_printf(context->string,
592 "string { encoding = %s; }",
593 get_encoding_string(string->encoding));
594 return 0;
595 }
596
597 struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
598 {
599 struct bt_field_type_common_integer *integer = NULL;
600
601 BT_LOGD("Creating CTF writer integer field type object: size=%u", size);
602
603 if (size == 0 || size > 64) {
604 BT_LOGW("Invalid parameter: size must be between 1 and 64: "
605 "size=%u", size);
606 goto error;
607 }
608
609 integer = g_new0(struct bt_field_type_common_integer, 1);
610 if (!integer) {
611 BT_LOGE_STR("Failed to allocate one integer field type.");
612 goto error;
613 }
614
615 bt_field_type_common_integer_initialize(BT_TO_COMMON(integer),
616 size, bt_field_type_common_integer_destroy,
617 &bt_ctf_field_type_integer_methods);
618 integer->common.spec.writer.serialize_func =
619 bt_ctf_field_type_integer_serialize;
620 BT_LOGD("Created CTF writer integer field type object: addr=%p, size=%u",
621 integer, size);
622 goto end;
623
624 error:
625 BT_PUT(integer);
626
627 end:
628 return (void *) integer;
629 }
630
631 int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *ft)
632 {
633 return bt_field_type_common_integer_get_size((void *) ft);
634 }
635
636 bt_bool bt_ctf_field_type_integer_is_signed(struct bt_ctf_field_type *ft)
637 {
638 return bt_field_type_common_integer_is_signed((void *) ft);
639 }
640
641 int bt_ctf_field_type_integer_set_is_signed(struct bt_ctf_field_type *ft,
642 bt_bool is_signed)
643 {
644 return bt_field_type_common_integer_set_is_signed((void *) ft,
645 is_signed);
646 }
647
648 int bt_ctf_field_type_integer_set_size(struct bt_ctf_field_type *ft,
649 unsigned int size)
650 {
651 return bt_field_type_common_integer_set_size((void *) ft, size);
652 }
653
654 enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
655 struct bt_ctf_field_type *ft)
656 {
657 return (int) bt_field_type_common_integer_get_base((void *) ft);
658 }
659
660 int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *ft,
661 enum bt_ctf_integer_base base)
662 {
663 return bt_field_type_common_integer_set_base((void *) ft,
664 (int) base);
665 }
666
667 enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
668 struct bt_ctf_field_type *ft)
669 {
670 return (int) bt_field_type_common_integer_get_encoding((void *) ft);
671 }
672
673 int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *ft,
674 enum bt_ctf_string_encoding encoding)
675 {
676 return bt_field_type_common_integer_set_encoding((void *) ft,
677 (int) encoding);
678 }
679
680 struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
681 struct bt_ctf_field_type *ft)
682 {
683 return bt_get(bt_field_type_common_integer_borrow_mapped_clock_class(
684 (void *) ft));
685 }
686
687 int bt_ctf_field_type_integer_set_mapped_clock_class(
688 struct bt_ctf_field_type *ft,
689 struct bt_ctf_clock_class *clock_class)
690 {
691 return bt_field_type_common_integer_set_mapped_clock_class((void *) ft,
692 BT_TO_COMMON(clock_class));
693 }
694
695 int bt_ctf_field_type_enumeration_signed_get_mapping_by_index(
696 struct bt_ctf_field_type *ft, uint64_t index,
697 const char **mapping_name, int64_t *range_begin,
698 int64_t *range_end)
699 {
700 return bt_field_type_common_enumeration_signed_get_mapping_by_index(
701 (void *) ft, index, mapping_name, range_begin, range_end);
702 }
703
704 int bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(
705 struct bt_ctf_field_type *ft, uint64_t index,
706 const char **mapping_name, uint64_t *range_begin,
707 uint64_t *range_end)
708 {
709 return bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
710 (void *) ft, index, mapping_name, range_begin, range_end);
711 }
712
713 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
714 struct bt_ctf_field_type *container_ft)
715 {
716 struct bt_field_type_common_enumeration *enumeration = NULL;
717 struct bt_field_type_common *int_ft = (void *) container_ft;
718
719 BT_LOGD("Creating CTF writer enumeration field type object: int-ft-addr=%p",
720 container_ft);
721
722 if (!container_ft) {
723 BT_LOGW_STR("Invalid parameter: field type is NULL.");
724 goto error;
725 }
726
727 if (int_ft->id != BT_FIELD_TYPE_ID_INTEGER) {
728 BT_LOGW("Invalid parameter: container field type is not an integer field type: "
729 "container-ft-addr=%p, container-ft-id=%s",
730 container_ft, bt_common_field_type_id_string(int_ft->id));
731 goto error;
732 }
733
734 enumeration = g_new0(struct bt_field_type_common_enumeration, 1);
735 if (!enumeration) {
736 BT_LOGE_STR("Failed to allocate one enumeration field type.");
737 goto error;
738 }
739
740 bt_field_type_common_enumeration_initialize(BT_TO_COMMON(enumeration),
741 int_ft, bt_field_type_common_enumeration_destroy_recursive,
742 &bt_ctf_field_type_enumeration_methods);
743 enumeration->common.spec.writer.serialize_func =
744 bt_ctf_field_type_enumeration_serialize_recursive;
745 BT_LOGD("Created CTF writer enumeration field type object: addr=%p, "
746 "int-ft-addr=%p, int-ft-size=%u",
747 enumeration, container_ft,
748 bt_ctf_field_type_integer_get_size(container_ft));
749 goto end;
750
751 error:
752 BT_PUT(enumeration);
753
754 end:
755 return (void *) enumeration;
756 }
757
758 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_field_type(
759 struct bt_ctf_field_type *ft)
760 {
761 return bt_get(
762 bt_field_type_common_enumeration_borrow_container_field_type(
763 (void *) ft));
764 }
765
766 int bt_ctf_field_type_enumeration_signed_add_mapping(
767 struct bt_ctf_field_type *ft, const char *string,
768 int64_t range_start, int64_t range_end)
769 {
770 return bt_field_type_common_enumeration_signed_add_mapping(
771 (void *) ft, string, range_start, range_end);
772 }
773
774 int bt_ctf_field_type_enumeration_unsigned_add_mapping(
775 struct bt_ctf_field_type *ft, const char *string,
776 uint64_t range_start, uint64_t range_end)
777 {
778 return bt_field_type_common_enumeration_unsigned_add_mapping(
779 (void *) ft, string, range_start, range_end);
780 }
781
782 int64_t bt_ctf_field_type_enumeration_get_mapping_count(
783 struct bt_ctf_field_type *ft)
784 {
785 return bt_field_type_common_enumeration_get_mapping_count((void *) ft);
786 }
787
788 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
789 {
790 struct bt_field_type_common_floating_point *floating_point =
791 g_new0(struct bt_field_type_common_floating_point, 1);
792
793 BT_LOGD_STR("Creating CTF writer floating point number field type object.");
794
795 if (!floating_point) {
796 BT_LOGE_STR("Failed to allocate one floating point number field type.");
797 goto end;
798 }
799
800 bt_field_type_common_floating_point_initialize(
801 BT_TO_COMMON(floating_point),
802 bt_field_type_common_floating_point_destroy,
803 &bt_ctf_field_type_floating_point_methods);
804 floating_point->common.spec.writer.serialize_func =
805 bt_ctf_field_type_floating_point_serialize;
806 BT_LOGD("Created CTF writer floating point number field type object: addr=%p, "
807 "exp-size=%u, mant-size=%u", floating_point,
808 floating_point->exp_dig, floating_point->mant_dig);
809
810 end:
811 return (void *) floating_point;
812 }
813
814 int bt_ctf_field_type_floating_point_get_exponent_digits(
815 struct bt_ctf_field_type *ft)
816 {
817 return bt_field_type_common_floating_point_get_exponent_digits(
818 (void *) ft);
819 }
820
821 int bt_ctf_field_type_floating_point_set_exponent_digits(
822 struct bt_ctf_field_type *ft, unsigned int exponent_digits)
823 {
824 return bt_field_type_common_floating_point_set_exponent_digits(
825 (void *) ft, exponent_digits);
826 }
827
828 int bt_ctf_field_type_floating_point_get_mantissa_digits(
829 struct bt_ctf_field_type *ft)
830 {
831 return bt_field_type_common_floating_point_get_mantissa_digits(
832 (void *) ft);
833 }
834
835 int bt_ctf_field_type_floating_point_set_mantissa_digits(
836 struct bt_ctf_field_type *ft, unsigned int mantissa_digits)
837 {
838 return bt_field_type_common_floating_point_set_mantissa_digits(
839 (void *) ft, mantissa_digits);
840 }
841
842 struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
843 {
844 struct bt_field_type_common_structure *structure =
845 g_new0(struct bt_field_type_common_structure, 1);
846
847 BT_LOGD_STR("Creating CTF writer structure field type object.");
848
849 if (!structure) {
850 BT_LOGE_STR("Failed to allocate one structure field type.");
851 goto error;
852 }
853
854 bt_field_type_common_structure_initialize(BT_TO_COMMON(structure),
855 bt_field_type_common_structure_destroy_recursive,
856 &bt_ctf_field_type_structure_methods);
857 structure->common.spec.writer.serialize_func =
858 bt_ctf_field_type_structure_serialize_recursive;
859 BT_LOGD("Created CTF writer structure field type object: addr=%p",
860 structure);
861 goto end;
862
863 error:
864 BT_PUT(structure);
865
866 end:
867 return (void *) structure;
868 }
869
870 int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *ft,
871 struct bt_ctf_field_type *field_type,
872 const char *field_name)
873 {
874 return bt_field_type_common_structure_add_field((void *) ft,
875 (void *) field_type, field_name);
876 }
877
878 int64_t bt_ctf_field_type_structure_get_field_count(struct bt_ctf_field_type *ft)
879 {
880 return bt_field_type_common_structure_get_field_count((void *) ft);
881 }
882
883 int bt_ctf_field_type_structure_get_field_by_index(
884 struct bt_ctf_field_type *ft,
885 const char **field_name,
886 struct bt_ctf_field_type **field_type, uint64_t index)
887 {
888 int ret = bt_field_type_common_structure_borrow_field_by_index(
889 (void *) ft, field_name, (void *) field_type, index);
890
891 if (ret == 0 && field_type) {
892 bt_get(*field_type);
893 }
894
895 return ret;
896 }
897
898 struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
899 struct bt_ctf_field_type *ft, const char *name)
900 {
901 return bt_get(bt_field_type_common_structure_borrow_field_type_by_name(
902 (void *) ft, name));
903 }
904
905 struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
906 struct bt_ctf_field_type *tag_ft, const char *tag_name)
907 {
908 struct bt_field_type_common_variant *var_ft = NULL;
909
910 BT_LOGD("Creating CTF writer variant field type object: "
911 "tag-ft-addr=%p, tag-field-name=\"%s\"",
912 tag_ft, tag_name);
913
914 if (tag_name && !bt_identifier_is_valid(tag_name)) {
915 BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
916 "tag-ft-addr=%p, tag-field-name=\"%s\"",
917 tag_ft, tag_name);
918 goto error;
919 }
920
921 var_ft = g_new0(struct bt_field_type_common_variant, 1);
922 if (!var_ft) {
923 BT_LOGE_STR("Failed to allocate one variant field type.");
924 goto error;
925 }
926
927 bt_field_type_common_variant_initialize(BT_TO_COMMON(var_ft),
928 (void *) tag_ft, tag_name,
929 bt_field_type_common_variant_destroy_recursive,
930 &bt_ctf_field_type_variant_methods);
931 var_ft->common.spec.writer.serialize_func =
932 bt_ctf_field_type_variant_serialize_recursive;
933 BT_LOGD("Created CTF writer variant field type object: addr=%p, "
934 "tag-ft-addr=%p, tag-field-name=\"%s\"",
935 var_ft, tag_ft, tag_name);
936 goto end;
937
938 error:
939 BT_PUT(var_ft);
940
941 end:
942 return (void *) var_ft;
943 }
944
945 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_field_type(
946 struct bt_ctf_field_type *ft)
947 {
948 return bt_get(bt_field_type_common_variant_borrow_tag_field_type(
949 (void *) ft));
950 }
951
952 const char *bt_ctf_field_type_variant_get_tag_name(struct bt_ctf_field_type *ft)
953 {
954 return bt_field_type_common_variant_get_tag_name((void *) ft);
955 }
956
957 int bt_ctf_field_type_variant_set_tag_name(
958 struct bt_ctf_field_type *ft, const char *name)
959 {
960 return bt_field_type_common_variant_set_tag_name((void *) ft, name);
961 }
962
963 int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *ft,
964 struct bt_ctf_field_type *field_type,
965 const char *field_name)
966 {
967 return bt_field_type_common_variant_add_field((void *) ft,
968 (void *) field_type, field_name);
969 }
970
971 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
972 struct bt_ctf_field_type *ft,
973 const char *field_name)
974 {
975 return bt_get(bt_field_type_common_variant_borrow_field_type_by_name(
976 (void *) ft, field_name));
977 }
978
979 struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
980 struct bt_ctf_field_type *ft,
981 struct bt_ctf_field *tag_field)
982 {
983 int ret;
984 int64_t choice_index;
985 struct bt_ctf_field *container;
986 struct bt_field_type_common_variant *var_ft = (void *) ft;
987 struct bt_ctf_field_type *ret_ft = NULL;
988
989 BT_ASSERT_PRE_NON_NULL(ft, "Field type");
990 BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT,
991 "Field type");
992 BT_ASSERT_PRE_NON_NULL(tag_field, "Tag field");
993 BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(
994 (struct bt_field_common *) tag_field,
995 BT_CTF_FIELD_TYPE_ID_ENUM, "Tag field");
996 BT_ASSERT_PRE_FIELD_COMMON_IS_SET((struct bt_field_common *) tag_field,
997 "Tag field");
998
999 container = bt_ctf_field_enumeration_borrow_container(tag_field);
1000 BT_ASSERT(container);
1001
1002 if (var_ft->tag_ft->container_ft->is_signed) {
1003 int64_t val;
1004
1005 ret = bt_ctf_field_integer_signed_get_value(container,
1006 &val);
1007 BT_ASSERT(ret == 0);
1008 choice_index = bt_field_type_common_variant_find_choice_index(
1009 (void *) ft, (uint64_t) val, true);
1010 } else {
1011 uint64_t val;
1012
1013 ret = bt_ctf_field_integer_unsigned_get_value(container,
1014 &val);
1015 BT_ASSERT(ret == 0);
1016 choice_index = bt_field_type_common_variant_find_choice_index(
1017 (void *) ft, val, false);
1018 }
1019
1020 if (choice_index < 0) {
1021 BT_LIB_LOGW("Cannot find variant field type's field: "
1022 "%![var-ft-]+wF, %![tag-field-]+wf", ft, tag_field);
1023 goto end;
1024 }
1025
1026 ret = bt_ctf_field_type_variant_get_field_by_index(ft, NULL,
1027 &ret_ft, choice_index);
1028 BT_ASSERT(ret == 0);
1029
1030 end:
1031 return ret_ft;
1032 }
1033
1034 int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *ft)
1035 {
1036 return bt_field_type_common_variant_get_field_count((void *) ft);
1037 }
1038
1039 int bt_ctf_field_type_variant_get_field_by_index(struct bt_ctf_field_type *ft,
1040 const char **field_name, struct bt_ctf_field_type **field_type,
1041 uint64_t index)
1042 {
1043 int ret = bt_field_type_common_variant_borrow_field_by_index(
1044 (void *) ft, field_name, (void *) field_type, index);
1045
1046 if (ret == 0 && field_type) {
1047 bt_get(*field_type);
1048 }
1049
1050 return ret;
1051 }
1052
1053 struct bt_ctf_field_type *bt_ctf_field_type_array_create(
1054 struct bt_ctf_field_type *element_ft, unsigned int length)
1055 {
1056 struct bt_field_type_common_array *array = NULL;
1057
1058 BT_LOGD("Creating CTF writer array field type object: element-ft-addr=%p, "
1059 "length=%u", element_ft, length);
1060
1061 if (!element_ft) {
1062 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
1063 goto error;
1064 }
1065
1066 if (length == 0) {
1067 BT_LOGW_STR("Invalid parameter: length is zero.");
1068 goto error;
1069 }
1070
1071 array = g_new0(struct bt_field_type_common_array, 1);
1072 if (!array) {
1073 BT_LOGE_STR("Failed to allocate one array field type.");
1074 goto error;
1075 }
1076
1077 bt_field_type_common_array_initialize(BT_TO_COMMON(array),
1078 (void *) element_ft, length,
1079 bt_field_type_common_array_destroy_recursive,
1080 &bt_ctf_field_type_array_methods);
1081 array->common.spec.writer.serialize_func =
1082 bt_ctf_field_type_array_serialize_recursive;
1083 BT_LOGD("Created CTF writer array field type object: addr=%p, "
1084 "element-ft-addr=%p, length=%u",
1085 array, element_ft, length);
1086 goto end;
1087
1088 error:
1089 BT_PUT(array);
1090
1091 end:
1092 return (void *) array;
1093 }
1094
1095 struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_field_type(
1096 struct bt_ctf_field_type *ft)
1097 {
1098 return bt_get(bt_field_type_common_array_borrow_element_field_type(
1099 (void *) ft));
1100 }
1101
1102 int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *ft)
1103 {
1104 return bt_field_type_common_array_get_length((void *) ft);
1105 }
1106
1107 struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
1108 struct bt_ctf_field_type *element_ft,
1109 const char *length_field_name)
1110 {
1111 struct bt_field_type_common_sequence *sequence = NULL;
1112
1113 BT_LOGD("Creating CTF writer sequence field type object: element-ft-addr=%p, "
1114 "length-field-name=\"%s\"", element_ft, length_field_name);
1115
1116 if (!element_ft) {
1117 BT_LOGW_STR("Invalid parameter: element field type is NULL.");
1118 goto error;
1119 }
1120
1121 if (!bt_identifier_is_valid(length_field_name)) {
1122 BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
1123 "length-field-name=\"%s\"", length_field_name);
1124 goto error;
1125 }
1126
1127 sequence = g_new0(struct bt_field_type_common_sequence, 1);
1128 if (!sequence) {
1129 BT_LOGE_STR("Failed to allocate one sequence field type.");
1130 goto error;
1131 }
1132
1133 bt_field_type_common_sequence_initialize(BT_TO_COMMON(sequence),
1134 (void *) element_ft, length_field_name,
1135 bt_field_type_common_sequence_destroy_recursive,
1136 &bt_ctf_field_type_sequence_methods);
1137 sequence->common.spec.writer.serialize_func =
1138 bt_ctf_field_type_sequence_serialize_recursive;
1139 BT_LOGD("Created CTF writer sequence field type object: addr=%p, "
1140 "element-ft-addr=%p, length-field-name=\"%s\"",
1141 sequence, element_ft, length_field_name);
1142 goto end;
1143
1144 error:
1145 BT_PUT(sequence);
1146
1147 end:
1148 return (void *) sequence;
1149 }
1150
1151 struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_field_type(
1152 struct bt_ctf_field_type *ft)
1153 {
1154 return bt_get(bt_field_type_common_sequence_borrow_element_field_type(
1155 (void *) ft));
1156 }
1157
1158 const char *bt_ctf_field_type_sequence_get_length_field_name(
1159 struct bt_ctf_field_type *ft)
1160 {
1161 return bt_field_type_common_sequence_get_length_field_name((void *) ft);
1162 }
1163
1164 struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
1165 {
1166 struct bt_field_type_common_string *string =
1167 g_new0(struct bt_field_type_common_string, 1);
1168
1169 BT_LOGD_STR("Creating CTF writer string field type object.");
1170
1171 if (!string) {
1172 BT_LOGE_STR("Failed to allocate one string field type.");
1173 return NULL;
1174 }
1175
1176 bt_field_type_common_string_initialize(BT_TO_COMMON(string),
1177 bt_field_type_common_string_destroy,
1178 &bt_ctf_field_type_string_methods);
1179 string->common.spec.writer.serialize_func =
1180 bt_ctf_field_type_string_serialize;
1181 BT_LOGD("Created CTF writer string field type object: addr=%p", string);
1182 return (void *) string;
1183 }
1184
1185 enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
1186 struct bt_ctf_field_type *ft)
1187 {
1188 return (int) bt_field_type_common_string_get_encoding((void *) ft);
1189 }
1190
1191 int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *ft,
1192 enum bt_ctf_string_encoding encoding)
1193 {
1194 return bt_field_type_common_string_set_encoding((void *) ft,
1195 (int) encoding);
1196 }
1197
1198 int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *ft)
1199 {
1200 return bt_field_type_common_get_alignment((void *) ft);
1201 }
1202
1203 int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *ft,
1204 unsigned int alignment)
1205 {
1206 return bt_field_type_common_set_alignment((void *) ft, alignment);
1207 }
1208
1209 enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
1210 struct bt_ctf_field_type *ft)
1211 {
1212 return (int) bt_field_type_common_get_byte_order((void *) ft);
1213 }
1214
1215 int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *ft,
1216 enum bt_ctf_byte_order byte_order)
1217 {
1218 return bt_field_type_common_set_byte_order((void *) ft,
1219 (int) byte_order);
1220 }
1221
1222 enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
1223 struct bt_ctf_field_type *ft)
1224 {
1225 return (int) bt_field_type_common_get_type_id((void *) ft);
1226 }
1227
1228 BT_HIDDEN
1229 struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *ft)
1230 {
1231 return (void *) bt_field_type_common_copy((void *) ft);
1232 }
1233
1234 static
1235 struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
1236 struct bt_ctf_field_type *ft)
1237 {
1238 struct bt_field_type_common_integer *int_ft = (void *) ft;
1239 struct bt_field_type_common_integer *copy_ft;
1240
1241 BT_LOGD("Copying CTF writer integer field type's: addr=%p", ft);
1242 copy_ft = (void *) bt_ctf_field_type_integer_create(int_ft->size);
1243 if (!copy_ft) {
1244 BT_LOGE_STR("Cannot create CTF writer integer field type.");
1245 goto end;
1246 }
1247
1248 copy_ft->mapped_clock_class = bt_get(int_ft->mapped_clock_class);
1249 copy_ft->user_byte_order = int_ft->user_byte_order;
1250 copy_ft->is_signed = int_ft->is_signed;
1251 copy_ft->size = int_ft->size;
1252 copy_ft->base = int_ft->base;
1253 copy_ft->encoding = int_ft->encoding;
1254 BT_LOGD("Copied CTF writer integer field type: original-ft-addr=%p, copy-ft-addr=%p",
1255 ft, copy_ft);
1256
1257 end:
1258 return (void *) copy_ft;
1259 }
1260
1261 static
1262 struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy_recursive(
1263 struct bt_ctf_field_type *ft)
1264 {
1265 size_t i;
1266 struct bt_field_type_common_enumeration *enum_ft = (void *) ft;
1267 struct bt_field_type_common_enumeration *copy_ft = NULL;
1268 struct bt_field_type_common_enumeration *container_copy_ft;
1269
1270 BT_LOGD("Copying CTF writer enumeration field type's: addr=%p", ft);
1271
1272 /* Copy the source enumeration's container */
1273 BT_LOGD_STR("Copying CTF writer enumeration field type's container field type.");
1274 container_copy_ft = BT_FROM_COMMON(bt_field_type_common_copy(
1275 BT_TO_COMMON(enum_ft->container_ft)));
1276 if (!container_copy_ft) {
1277 BT_LOGE_STR("Cannot copy CTF writer enumeration field type's container field type.");
1278 goto end;
1279 }
1280
1281 copy_ft = (void *) bt_ctf_field_type_enumeration_create(
1282 (void *) container_copy_ft);
1283 if (!copy_ft) {
1284 BT_LOGE_STR("Cannot create CTF writer enumeration field type.");
1285 goto end;
1286 }
1287
1288 /* Copy all enumaration entries */
1289 for (i = 0; i < enum_ft->entries->len; i++) {
1290 struct enumeration_mapping *mapping = g_ptr_array_index(
1291 enum_ft->entries, i);
1292 struct enumeration_mapping *copy_mapping = g_new0(
1293 struct enumeration_mapping, 1);
1294
1295 if (!copy_mapping) {
1296 BT_LOGE_STR("Failed to allocate one enumeration mapping.");
1297 goto error;
1298 }
1299
1300 *copy_mapping = *mapping;
1301 g_ptr_array_add(copy_ft->entries, copy_mapping);
1302 }
1303
1304 BT_LOGD("Copied CTF writer enumeration field type: original-ft-addr=%p, copy-ft-addr=%p",
1305 ft, copy_ft);
1306
1307 end:
1308 bt_put(container_copy_ft);
1309 return (void *) copy_ft;
1310
1311 error:
1312 bt_put(container_copy_ft);
1313 BT_PUT(copy_ft);
1314 return (void *) copy_ft;
1315 }
1316
1317 static
1318 struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
1319 struct bt_ctf_field_type *ft)
1320 {
1321 struct bt_field_type_common_floating_point *flt_ft = BT_FROM_COMMON(ft);
1322 struct bt_field_type_common_floating_point *copy_ft;
1323
1324 BT_LOGD("Copying CTF writer floating point number field type's: addr=%p", ft);
1325 copy_ft = (void *) bt_ctf_field_type_floating_point_create();
1326 if (!copy_ft) {
1327 BT_LOGE_STR("Cannot create CTF writer floating point number field type.");
1328 goto end;
1329 }
1330
1331 copy_ft->user_byte_order = flt_ft->user_byte_order;
1332 copy_ft->exp_dig = flt_ft->exp_dig;
1333 copy_ft->mant_dig = flt_ft->mant_dig;
1334 BT_LOGD("Copied CTF writer floating point number field type: original-ft-addr=%p, copy-ft-addr=%p",
1335 ft, copy_ft);
1336
1337 end:
1338 return (void *) copy_ft;
1339 }
1340
1341 static
1342 struct bt_ctf_field_type *bt_ctf_field_type_structure_copy_recursive(
1343 struct bt_ctf_field_type *ft)
1344 {
1345 int64_t i;
1346 GHashTableIter iter;
1347 gpointer key, value;
1348 struct bt_field_type_common_structure *struct_ft = (void *) ft;
1349 struct bt_field_type_common_structure *copy_ft;
1350
1351 BT_LOGD("Copying CTF writer structure field type's: addr=%p", ft);
1352 copy_ft = (void *) bt_ctf_field_type_structure_create();
1353 if (!copy_ft) {
1354 BT_LOGE_STR("Cannot create CTF writer structure field type.");
1355 goto end;
1356 }
1357
1358 /* Copy field_name_to_index */
1359 g_hash_table_iter_init(&iter, struct_ft->field_name_to_index);
1360 while (g_hash_table_iter_next(&iter, &key, &value)) {
1361 g_hash_table_insert(copy_ft->field_name_to_index,
1362 key, value);
1363 }
1364
1365 g_array_set_size(copy_ft->fields, struct_ft->fields->len);
1366
1367 for (i = 0; i < struct_ft->fields->len; i++) {
1368 struct bt_field_type_common_structure_field *entry, *copy_entry;
1369 struct bt_field_type_common *field_ft_copy;
1370
1371 entry = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
1372 struct_ft, i);
1373 copy_entry = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
1374 copy_ft, i);
1375 BT_LOGD("Copying CTF writer structure field type's field: "
1376 "index=%" PRId64 ", "
1377 "field-ft-addr=%p, field-name=\"%s\"",
1378 i, entry, g_quark_to_string(entry->name));
1379
1380 field_ft_copy = (void *) bt_ctf_field_type_copy(
1381 (void *) entry->type);
1382 if (!field_ft_copy) {
1383 BT_LOGE("Cannot copy CTF writer structure field type's field: "
1384 "index=%" PRId64 ", "
1385 "field-ft-addr=%p, field-name=\"%s\"",
1386 i, entry, g_quark_to_string(entry->name));
1387 goto error;
1388 }
1389
1390 copy_entry->name = entry->name;
1391 copy_entry->type = field_ft_copy;
1392 }
1393
1394 BT_LOGD("Copied CTF writer structure field type: original-ft-addr=%p, copy-ft-addr=%p",
1395 ft, copy_ft);
1396
1397 end:
1398 return (void *) copy_ft;
1399
1400 error:
1401 BT_PUT(copy_ft);
1402 return NULL;
1403 }
1404
1405 static
1406 struct bt_ctf_field_type *bt_ctf_field_type_variant_copy_recursive(
1407 struct bt_ctf_field_type *ft)
1408 {
1409 int64_t i;
1410 GHashTableIter iter;
1411 gpointer key, value;
1412 struct bt_field_type_common *tag_ft_copy = NULL;
1413 struct bt_field_type_common_variant *var_ft = (void *) ft;
1414 struct bt_field_type_common_variant *copy_ft = NULL;
1415
1416 BT_LOGD("Copying CTF writer variant field type's: addr=%p", ft);
1417 if (var_ft->tag_ft) {
1418 BT_LOGD_STR("Copying CTF writer variant field type's tag field type.");
1419 tag_ft_copy = bt_field_type_common_copy(
1420 BT_TO_COMMON(var_ft->tag_ft));
1421 if (!tag_ft_copy) {
1422 BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field type.");
1423 goto end;
1424 }
1425 }
1426
1427 copy_ft = (void *) bt_ctf_field_type_variant_create(
1428 (void *) tag_ft_copy,
1429 var_ft->tag_name->len ? var_ft->tag_name->str : NULL);
1430 if (!copy_ft) {
1431 BT_LOGE_STR("Cannot create CTF writer variant field type.");
1432 goto end;
1433 }
1434
1435 /* Copy field_name_to_index */
1436 g_hash_table_iter_init(&iter, var_ft->choice_name_to_index);
1437 while (g_hash_table_iter_next(&iter, &key, &value)) {
1438 g_hash_table_insert(copy_ft->choice_name_to_index,
1439 key, value);
1440 }
1441
1442 g_array_set_size(copy_ft->choices, var_ft->choices->len);
1443
1444 for (i = 0; i < var_ft->choices->len; i++) {
1445 struct bt_field_type_common_variant_choice *entry, *copy_entry;
1446 struct bt_field_type_common *field_ft_copy;
1447 uint64_t range_i;
1448
1449 entry = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, i);
1450 copy_entry = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
1451 copy_ft, i);
1452 BT_LOGD("Copying CTF writer variant field type's field: "
1453 "index=%" PRId64 ", "
1454 "field-ft-addr=%p, field-name=\"%s\"",
1455 i, entry, g_quark_to_string(entry->name));
1456
1457 field_ft_copy = (void *) bt_ctf_field_type_copy(
1458 (void *) entry->type);
1459 if (!field_ft_copy) {
1460 BT_LOGE("Cannot copy CTF writer variant field type's field: "
1461 "index=%" PRId64 ", "
1462 "field-ft-addr=%p, field-name=\"%s\"",
1463 i, entry, g_quark_to_string(entry->name));
1464 g_free(copy_entry);
1465 goto error;
1466 }
1467
1468 copy_entry->name = entry->name;
1469 copy_entry->type = field_ft_copy;
1470
1471 /* Copy ranges */
1472 copy_entry->ranges = g_array_new(FALSE, TRUE,
1473 sizeof(struct bt_field_type_common_variant_choice_range));
1474 BT_ASSERT(copy_entry->ranges);
1475 g_array_set_size(copy_entry->ranges, entry->ranges->len);
1476
1477 for (range_i = 0; range_i < entry->ranges->len; range_i++) {
1478 copy_entry->ranges[range_i] = entry->ranges[range_i];
1479 }
1480 }
1481
1482 if (var_ft->tag_field_path) {
1483 BT_LOGD_STR("Copying CTF writer variant field type's tag field path.");
1484 copy_ft->tag_field_path = bt_field_path_copy(
1485 var_ft->tag_field_path);
1486 if (!copy_ft->tag_field_path) {
1487 BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field path.");
1488 goto error;
1489 }
1490 }
1491
1492 copy_ft->choices_up_to_date = var_ft->choices_up_to_date;
1493 BT_LOGD("Copied CTF writer variant field type: original-ft-addr=%p, copy-ft-addr=%p",
1494 ft, copy_ft);
1495
1496 end:
1497 bt_put(tag_ft_copy);
1498 return (void *) copy_ft;
1499
1500 error:
1501 bt_put(tag_ft_copy);
1502 BT_PUT(copy_ft);
1503 return NULL;
1504 }
1505
1506 static
1507 struct bt_ctf_field_type *bt_ctf_field_type_array_copy_recursive(
1508 struct bt_ctf_field_type *ft)
1509 {
1510 struct bt_field_type_common *container_ft_copy = NULL;
1511 struct bt_field_type_common_array *array_ft = (void *) ft;
1512 struct bt_field_type_common_array *copy_ft = NULL;
1513
1514 BT_LOGD("Copying CTF writer array field type's: addr=%p", ft);
1515 BT_LOGD_STR("Copying CTF writer array field type's element field type.");
1516 container_ft_copy = bt_field_type_common_copy(array_ft->element_ft);
1517 if (!container_ft_copy) {
1518 BT_LOGE_STR("Cannot copy CTF writer array field type's element field type.");
1519 goto end;
1520 }
1521
1522 copy_ft = (void *) bt_ctf_field_type_array_create(
1523 (void *) container_ft_copy, array_ft->length);
1524 if (!copy_ft) {
1525 BT_LOGE_STR("Cannot create CTF writer array field type.");
1526 goto end;
1527 }
1528
1529 BT_LOGD("Copied CTF writer array field type: original-ft-addr=%p, copy-ft-addr=%p",
1530 ft, copy_ft);
1531
1532 end:
1533 bt_put(container_ft_copy);
1534 return (void *) copy_ft;
1535 }
1536
1537 static
1538 struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy_recursive(
1539 struct bt_ctf_field_type *ft)
1540 {
1541 struct bt_field_type_common *container_ft_copy = NULL;
1542 struct bt_field_type_common_sequence *seq_ft = (void *) ft;
1543 struct bt_field_type_common_sequence *copy_ft = NULL;
1544
1545 BT_LOGD("Copying CTF writer sequence field type's: addr=%p", ft);
1546 BT_LOGD_STR("Copying CTF writer sequence field type's element field type.");
1547 container_ft_copy = bt_field_type_common_copy(seq_ft->element_ft);
1548 if (!container_ft_copy) {
1549 BT_LOGE_STR("Cannot copy CTF writer sequence field type's element field type.");
1550 goto end;
1551 }
1552
1553 copy_ft = (void *) bt_ctf_field_type_sequence_create(
1554 (void *) container_ft_copy,
1555 seq_ft->length_field_name->len ?
1556 seq_ft->length_field_name->str : NULL);
1557 if (!copy_ft) {
1558 BT_LOGE_STR("Cannot create CTF writer sequence field type.");
1559 goto end;
1560 }
1561
1562 if (seq_ft->length_field_path) {
1563 BT_LOGD_STR("Copying CTF writer sequence field type's length field path.");
1564 copy_ft->length_field_path = bt_field_path_copy(
1565 seq_ft->length_field_path);
1566 if (!copy_ft->length_field_path) {
1567 BT_LOGE_STR("Cannot copy CTF writer sequence field type's length field path.");
1568 goto error;
1569 }
1570 }
1571
1572 BT_LOGD("Copied CTF writer sequence field type: original-ft-addr=%p, copy-ft-addr=%p",
1573 ft, copy_ft);
1574
1575 end:
1576 bt_put(container_ft_copy);
1577 return (void *) copy_ft;
1578 error:
1579 bt_put(container_ft_copy);
1580 BT_PUT(copy_ft);
1581 return NULL;
1582 }
1583
1584 static
1585 struct bt_ctf_field_type *bt_ctf_field_type_string_copy(struct bt_ctf_field_type *ft)
1586 {
1587 struct bt_field_type_common_string *string_ft = (void *) ft;
1588 struct bt_field_type_common_string *copy_ft = NULL;
1589
1590 BT_LOGD("Copying CTF writer string field type's: addr=%p", ft);
1591 copy_ft = (void *) bt_ctf_field_type_string_create();
1592 if (!copy_ft) {
1593 BT_LOGE_STR("Cannot create CTF writer string field type.");
1594 goto end;
1595 }
1596
1597 copy_ft->encoding = string_ft->encoding;
1598 BT_LOGD("Copied CTF writer string field type: original-ft-addr=%p, copy-ft-addr=%p",
1599 ft, copy_ft);
1600
1601 end:
1602 return (void *) copy_ft;
1603 }
This page took 0.061254 seconds and 4 git commands to generate.