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