Commit | Line | Data |
---|---|---|
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> | |
312c056a | 36 | #include <babeltrace/ctf-writer/fields-internal.h> |
3dca2276 PP |
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 = | |
094ff7c0 | 287 | bt_field_type_common_enumeration_borrow_container_field_type(type); |
3dca2276 PP |
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: | |
3dca2276 PP |
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++) { | |
312c056a PP |
394 | struct bt_field_type_common_structure_field *field = |
395 | BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX( | |
396 | structure, i); | |
3dca2276 PP |
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++; | |
312c056a PP |
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); | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
683 | return bt_get(bt_field_type_common_integer_borrow_mapped_clock_class( |
684 | (void *) ft)); | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
761 | return bt_get( |
762 | bt_field_type_common_enumeration_borrow_container_field_type( | |
763 | (void *) ft)); | |
3dca2276 PP |
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 | { | |
094ff7c0 | 888 | int ret = bt_field_type_common_structure_borrow_field_by_index( |
3dca2276 | 889 | (void *) ft, field_name, (void *) field_type, index); |
094ff7c0 PP |
890 | |
891 | if (ret == 0 && field_type) { | |
892 | bt_get(*field_type); | |
893 | } | |
894 | ||
895 | return ret; | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
901 | return bt_get(bt_field_type_common_structure_borrow_field_type_by_name( |
902 | (void *) ft, name)); | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
948 | return bt_get(bt_field_type_common_variant_borrow_tag_field_type( |
949 | (void *) ft)); | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
975 | return bt_get(bt_field_type_common_variant_borrow_field_type_by_name( |
976 | (void *) ft, field_name)); | |
3dca2276 PP |
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 | { | |
312c056a PP |
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; | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
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; | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
1098 | return bt_get(bt_field_type_common_array_borrow_element_field_type( |
1099 | (void *) ft)); | |
3dca2276 PP |
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 | { | |
094ff7c0 PP |
1154 | return bt_get(bt_field_type_common_sequence_borrow_element_field_type( |
1155 | (void *) ft)); | |
3dca2276 PP |
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 | ||
312c056a PP |
1365 | g_array_set_size(copy_ft->fields, struct_ft->fields->len); |
1366 | ||
3dca2276 | 1367 | for (i = 0; i < struct_ft->fields->len; i++) { |
312c056a | 1368 | struct bt_field_type_common_structure_field *entry, *copy_entry; |
3dca2276 PP |
1369 | struct bt_field_type_common *field_ft_copy; |
1370 | ||
312c056a PP |
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); | |
3dca2276 PP |
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)); | |
3dca2276 PP |
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)); | |
3dca2276 PP |
1387 | goto error; |
1388 | } | |
1389 | ||
1390 | copy_entry->name = entry->name; | |
1391 | copy_entry->type = field_ft_copy; | |
3dca2276 PP |
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 */ | |
312c056a | 1436 | g_hash_table_iter_init(&iter, var_ft->choice_name_to_index); |
3dca2276 | 1437 | while (g_hash_table_iter_next(&iter, &key, &value)) { |
312c056a | 1438 | g_hash_table_insert(copy_ft->choice_name_to_index, |
3dca2276 PP |
1439 | key, value); |
1440 | } | |
1441 | ||
312c056a PP |
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; | |
3dca2276 | 1446 | struct bt_field_type_common *field_ft_copy; |
312c056a | 1447 | uint64_t range_i; |
3dca2276 | 1448 | |
312c056a PP |
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); | |
3dca2276 PP |
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)); | |
3dca2276 PP |
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; | |
312c056a PP |
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 | } | |
3dca2276 PP |
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 | ||
312c056a PP |
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", | |
3dca2276 PP |
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 | } |