Clean-up: Remove unecessary line break
[babeltrace.git] / formats / ctf / ir / event-types.c
CommitLineData
273b65be
JG
1/*
2 * event-types.c
3 *
4 * Babeltrace CTF Writer
5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <babeltrace/ctf-writer/event-types.h>
adc315b8 30#include <babeltrace/ctf-ir/event-types-internal.h>
273b65be
JG
31#include <babeltrace/ctf-writer/writer-internal.h>
32#include <babeltrace/compiler.h>
33#include <babeltrace/endian.h>
34#include <float.h>
35#include <inttypes.h>
a39fa057 36#include <stdlib.h>
273b65be
JG
37
38struct range_overlap_query {
39 int64_t range_start, range_end;
40 int overlaps;
41 GQuark mapping_name;
42};
43
44static
45void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *);
46static
47void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *);
48static
49void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *);
50static
51void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *);
52static
53void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *);
54static
55void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *);
56static
57void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *);
58static
59void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *);
60
61static
62void (* const type_destroy_funcs[])(struct bt_ctf_ref *) = {
63 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_destroy,
64 [CTF_TYPE_ENUM] =
65 bt_ctf_field_type_enumeration_destroy,
66 [CTF_TYPE_FLOAT] =
67 bt_ctf_field_type_floating_point_destroy,
68 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_destroy,
69 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_destroy,
70 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_destroy,
71 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
72 [CTF_TYPE_STRING] = bt_ctf_field_type_string_destroy,
73};
74
75static
76void generic_field_type_freeze(struct bt_ctf_field_type *);
77static
78void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
79static
80void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
81static
82void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
83static
84void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
85static
86void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
87
88static
89type_freeze_func const type_freeze_funcs[] = {
90 [CTF_TYPE_INTEGER] = generic_field_type_freeze,
91 [CTF_TYPE_ENUM] = bt_ctf_field_type_enumeration_freeze,
92 [CTF_TYPE_FLOAT] = generic_field_type_freeze,
93 [CTF_TYPE_STRUCT] = bt_ctf_field_type_structure_freeze,
94 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_freeze,
95 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_freeze,
96 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
97 [CTF_TYPE_STRING] = generic_field_type_freeze,
98};
99
100static
101int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
102 struct metadata_context *);
103static
104int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
105 struct metadata_context *);
106static
107int bt_ctf_field_type_floating_point_serialize(
108 struct bt_ctf_field_type *, struct metadata_context *);
109static
110int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
111 struct metadata_context *);
112static
113int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
114 struct metadata_context *);
115static
116int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
117 struct metadata_context *);
118static
119int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
120 struct metadata_context *);
121static
122int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
123 struct metadata_context *);
124
125static
126type_serialize_func const type_serialize_funcs[] = {
127 [CTF_TYPE_INTEGER] = bt_ctf_field_type_integer_serialize,
128 [CTF_TYPE_ENUM] =
129 bt_ctf_field_type_enumeration_serialize,
130 [CTF_TYPE_FLOAT] =
131 bt_ctf_field_type_floating_point_serialize,
132 [CTF_TYPE_STRUCT] =
133 bt_ctf_field_type_structure_serialize,
134 [CTF_TYPE_VARIANT] = bt_ctf_field_type_variant_serialize,
135 [CTF_TYPE_ARRAY] = bt_ctf_field_type_array_serialize,
136 [CTF_TYPE_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
137 [CTF_TYPE_STRING] = bt_ctf_field_type_string_serialize,
138};
139
140static
141void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
142 int byte_order);
143static
144void bt_ctf_field_type_floating_point_set_byte_order(
145 struct bt_ctf_field_type *, int byte_order);
146
147static
148void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
149 int) = {
150 [CTF_TYPE_INTEGER] =
151 bt_ctf_field_type_integer_set_byte_order,
152 [CTF_TYPE_FLOAT] =
153 bt_ctf_field_type_floating_point_set_byte_order,
154 [CTF_TYPE_ENUM ... CTF_TYPE_SEQUENCE] = NULL,
155};
156
157
158static
159void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
160{
161 g_free(mapping);
162}
163
164static
165void destroy_structure_field(struct structure_field *field)
166{
167 if (field->type) {
168 bt_ctf_field_type_put(field->type);
169 }
170
171 g_free(field);
172}
173
174static
175void check_ranges_overlap(gpointer element, gpointer query)
176{
177 struct enumeration_mapping *mapping = element;
178 struct range_overlap_query *overlap_query = query;
179
180 if (mapping->range_start <= overlap_query->range_end
181 && overlap_query->range_start <= mapping->range_end) {
182 overlap_query->overlaps = 1;
183 overlap_query->mapping_name = mapping->string;
184 }
185
186 overlap_query->overlaps |=
187 mapping->string == overlap_query->mapping_name;
188}
189
190static
191void bt_ctf_field_type_init(struct bt_ctf_field_type *type)
192{
193 enum ctf_type_id type_id = type->declaration->id;
c4e511df 194 int ret;
273b65be
JG
195
196 assert(type && (type_id > CTF_TYPE_UNKNOWN) &&
197 (type_id < NR_CTF_TYPES));
198
199 bt_ctf_ref_init(&type->ref_count);
200 type->freeze = type_freeze_funcs[type_id];
201 type->serialize = type_serialize_funcs[type_id];
c4e511df
MD
202 ret = bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_NATIVE);
203 assert(!ret);
273b65be
JG
204 type->declaration->alignment = 1;
205}
206
207static
208int add_structure_field(GPtrArray *fields,
209 GHashTable *field_name_to_index,
210 struct bt_ctf_field_type *field_type,
211 const char *field_name)
212{
213 int ret = 0;
214 GQuark name_quark = g_quark_from_string(field_name);
215 struct structure_field *field;
216
217 /* Make sure structure does not contain a field of the same name */
fe0fe95c
JG
218 if (g_hash_table_lookup_extended(field_name_to_index,
219 GUINT_TO_POINTER(name_quark), NULL, NULL)) {
273b65be
JG
220 ret = -1;
221 goto end;
222 }
223
224 field = g_new0(struct structure_field, 1);
225 if (!field) {
226 ret = -1;
227 goto end;
228 }
229
230 bt_ctf_field_type_get(field_type);
231 field->name = name_quark;
232 field->type = field_type;
233 g_hash_table_insert(field_name_to_index,
234 (gpointer) (unsigned long) name_quark,
235 (gpointer) (unsigned long) fields->len);
236 g_ptr_array_add(fields, field);
237 bt_ctf_field_type_freeze(field_type);
238end:
239 return ret;
240}
241
9ce21c30
JG
242BT_HIDDEN
243int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
244{
245 int ret = 0;
246
247 if (!type) {
248 ret = -1;
249 goto end;
250 }
251
252 if (type->declaration->id == CTF_TYPE_ENUM) {
253 struct bt_ctf_field_type_enumeration *enumeration =
254 container_of(type, struct bt_ctf_field_type_enumeration,
255 parent);
256
257 ret = enumeration->entries->len ? 0 : -1;
258 }
259end:
260 return ret;
261}
262
273b65be
JG
263struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
264{
265 struct bt_ctf_field_type_integer *integer =
266 g_new0(struct bt_ctf_field_type_integer, 1);
267
268 if (!integer || size > 64) {
269 return NULL;
270 }
271
272 integer->parent.declaration = &integer->declaration.p;
273 integer->parent.declaration->id = CTF_TYPE_INTEGER;
274 integer->declaration.len = size;
275 integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
276 integer->declaration.encoding = CTF_STRING_NONE;
277 bt_ctf_field_type_init(&integer->parent);
278 return &integer->parent;
279}
280
281int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
282 int is_signed)
283{
284 int ret = 0;
285 struct bt_ctf_field_type_integer *integer;
286
287 if (!type || type->frozen ||
288 type->declaration->id != CTF_TYPE_INTEGER) {
289 ret = -1;
290 goto end;
291 }
292
293 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
294 if (is_signed && integer->declaration.len <= 1) {
295 ret = -1;
296 goto end;
297 }
298
299 integer->declaration.signedness = !!is_signed;
300end:
301 return ret;
302}
303
304int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
305 enum bt_ctf_integer_base base)
306{
307 int ret = 0;
308
309 if (!type || type->frozen ||
310 type->declaration->id != CTF_TYPE_INTEGER) {
311 ret = -1;
312 goto end;
313 }
314
315 switch (base) {
316 case BT_CTF_INTEGER_BASE_BINARY:
317 case BT_CTF_INTEGER_BASE_OCTAL:
318 case BT_CTF_INTEGER_BASE_DECIMAL:
319 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
320 {
321 struct bt_ctf_field_type_integer *integer = container_of(type,
322 struct bt_ctf_field_type_integer, parent);
323 integer->declaration.base = base;
324 break;
325 }
326 default:
327 ret = -1;
328 }
329end:
330 return ret;
331}
332
333int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
334 enum ctf_string_encoding encoding)
335{
336 int ret = 0;
337 struct bt_ctf_field_type_integer *integer;
338
339 if (!type || type->frozen ||
340 (type->declaration->id != CTF_TYPE_INTEGER) ||
341 (encoding < CTF_STRING_NONE) ||
342 (encoding >= CTF_STRING_UNKNOWN)) {
343 ret = -1;
344 goto end;
345 }
346
347 integer = container_of(type, struct bt_ctf_field_type_integer, parent);
348 integer->declaration.encoding = encoding;
349end:
350 return ret;
351}
352
353struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
354 struct bt_ctf_field_type *integer_container_type)
355{
356 struct bt_ctf_field_type_enumeration *enumeration = NULL;
357
358 if (!integer_container_type) {
359 goto error;
360 }
361
2a610bb7
JG
362 if (integer_container_type->declaration->id != CTF_TYPE_INTEGER) {
363 goto error;
364 }
365
273b65be
JG
366 enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
367 if (!enumeration) {
368 goto error;
369 }
370
371 enumeration->parent.declaration = &enumeration->declaration.p;
372 enumeration->parent.declaration->id = CTF_TYPE_ENUM;
373 bt_ctf_field_type_get(integer_container_type);
374 enumeration->container = integer_container_type;
375 enumeration->entries = g_ptr_array_new_with_free_func(
376 (GDestroyNotify)destroy_enumeration_mapping);
377 bt_ctf_field_type_init(&enumeration->parent);
378 return &enumeration->parent;
379error:
380 g_free(enumeration);
381 return NULL;
382}
383
384int bt_ctf_field_type_enumeration_add_mapping(
385 struct bt_ctf_field_type *type, const char *string,
386 int64_t range_start, int64_t range_end)
387{
388 int ret = 0;
389 GQuark mapping_name;
390 struct enumeration_mapping *mapping;
391 struct bt_ctf_field_type_enumeration *enumeration;
392 struct range_overlap_query query;
a39fa057 393 char *escaped_string;
273b65be
JG
394
395 if (!type || (type->declaration->id != CTF_TYPE_ENUM) ||
396 type->frozen ||
397 (range_end < range_start)) {
398 ret = -1;
399 goto end;
400 }
401
a39fa057 402 if (!string || strlen(string) == 0) {
273b65be
JG
403 ret = -1;
404 goto end;
405 }
406
a39fa057
JG
407 escaped_string = g_strescape(string, NULL);
408 if (!escaped_string) {
409 ret = -1;
410 goto end;
411 }
412
413 mapping_name = g_quark_from_string(escaped_string);
273b65be
JG
414 query = (struct range_overlap_query) { .range_start = range_start,
415 .range_end = range_end,
416 .mapping_name = mapping_name,
417 .overlaps = 0 };
418 enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
419 parent);
420
421 /* Check that the range does not overlap with one already present */
422 g_ptr_array_foreach(enumeration->entries, check_ranges_overlap, &query);
423 if (query.overlaps) {
424 ret = -1;
a39fa057 425 goto error_free;
273b65be
JG
426 }
427
428 mapping = g_new(struct enumeration_mapping, 1);
429 if (!mapping) {
430 ret = -1;
a39fa057 431 goto error_free;
273b65be
JG
432 }
433
434 *mapping = (struct enumeration_mapping) {.range_start = range_start,
435 .range_end = range_end, .string = mapping_name};
436 g_ptr_array_add(enumeration->entries, mapping);
a39fa057
JG
437error_free:
438 free(escaped_string);
273b65be
JG
439end:
440 return ret;
441}
442
e5958c30
JG
443const char *bt_ctf_field_type_enumeration_get_mapping_name_unsigned(
444 struct bt_ctf_field_type_enumeration *enumeration_type,
445 uint64_t value)
446{
447 const char *name = NULL;
448 struct range_overlap_query query =
449 (struct range_overlap_query) {
450 /* FIXME: should not need a cast */
451 .range_start = (int64_t) value,
452 .range_end = (int64_t) value,
453 .overlaps = 0 };
454
455 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
456 &query);
457 if (!query.overlaps) {
458 goto end;
459 }
460
461 name = g_quark_to_string(query.mapping_name);
462end:
463 return name;
464}
465
466const char *bt_ctf_field_type_enumeration_get_mapping_name_signed(
467 struct bt_ctf_field_type_enumeration *enumeration_type,
468 int64_t value)
469{
470 const char *name = NULL;
471 struct range_overlap_query query =
472 (struct range_overlap_query) {
473 .range_start = value,
474 .range_end = value,
475 .overlaps = 0 };
476
477 g_ptr_array_foreach(enumeration_type->entries, check_ranges_overlap,
478 &query);
479 if (!query.overlaps) {
480 goto end;
481 }
482
483 name = g_quark_to_string(query.mapping_name);
484end:
485 return name;
486}
487
273b65be
JG
488struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
489{
490 struct bt_ctf_field_type_floating_point *floating_point =
491 g_new0(struct bt_ctf_field_type_floating_point, 1);
492
493 if (!floating_point) {
494 goto end;
495 }
496
497 floating_point->declaration.sign = &floating_point->sign;
498 floating_point->declaration.mantissa = &floating_point->mantissa;
499 floating_point->declaration.exp = &floating_point->exp;
500 floating_point->sign.len = 1;
501 floating_point->parent.declaration = &floating_point->declaration.p;
502 floating_point->parent.declaration->id = CTF_TYPE_FLOAT;
503 floating_point->declaration.exp->len =
504 sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
505 floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
506 floating_point->sign.p.alignment = 1;
507 floating_point->mantissa.p.alignment = 1;
508 floating_point->exp.p.alignment = 1;
509
510 bt_ctf_field_type_init(&floating_point->parent);
511end:
512 return floating_point ? &floating_point->parent : NULL;
513}
514
515int bt_ctf_field_type_floating_point_set_exponent_digits(
516 struct bt_ctf_field_type *type,
517 unsigned int exponent_digits)
518{
519 int ret = 0;
520 struct bt_ctf_field_type_floating_point *floating_point;
521
522 if (!type || type->frozen ||
523 (type->declaration->id != CTF_TYPE_FLOAT)) {
524 ret = -1;
525 goto end;
526 }
527
528 floating_point = container_of(type,
529 struct bt_ctf_field_type_floating_point, parent);
530 if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
531 (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
532 (exponent_digits !=
533 sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
534 ret = -1;
535 goto end;
536 }
537
538 floating_point->declaration.exp->len = exponent_digits;
539end:
540 return ret;
541}
542
543int bt_ctf_field_type_floating_point_set_mantissa_digits(
544 struct bt_ctf_field_type *type,
545 unsigned int mantissa_digits)
546{
547 int ret = 0;
548 struct bt_ctf_field_type_floating_point *floating_point;
549
550 if (!type || type->frozen ||
551 (type->declaration->id != CTF_TYPE_FLOAT)) {
552 ret = -1;
553 goto end;
554 }
555
556 floating_point = container_of(type,
557 struct bt_ctf_field_type_floating_point, parent);
558
559 if ((mantissa_digits != FLT_MANT_DIG) &&
560 (mantissa_digits != DBL_MANT_DIG) &&
561 (mantissa_digits != LDBL_MANT_DIG)) {
562 ret = -1;
563 goto end;
564 }
565
566 floating_point->declaration.mantissa->len = mantissa_digits - 1;
567end:
568 return ret;
569}
570
571struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
572{
573 struct bt_ctf_field_type_structure *structure =
574 g_new0(struct bt_ctf_field_type_structure, 1);
575
576 if (!structure) {
577 goto error;
578 }
579
580 structure->parent.declaration = &structure->declaration.p;
581 structure->parent.declaration->id = CTF_TYPE_STRUCT;
582 bt_ctf_field_type_init(&structure->parent);
583 structure->fields = g_ptr_array_new_with_free_func(
584 (GDestroyNotify)destroy_structure_field);
585 structure->field_name_to_index = g_hash_table_new(NULL, NULL);
586 return &structure->parent;
587error:
588 return NULL;
589}
590
591int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
592 struct bt_ctf_field_type *field_type,
593 const char *field_name)
594{
595 int ret = 0;
596 struct bt_ctf_field_type_structure *structure;
597
598 if (!type || !field_type || type->frozen ||
599 validate_identifier(field_name) ||
9ce21c30
JG
600 (type->declaration->id != CTF_TYPE_STRUCT) ||
601 bt_ctf_field_type_validate(field_type)) {
273b65be
JG
602 goto end;
603 }
604
605 structure = container_of(type,
606 struct bt_ctf_field_type_structure, parent);
607 if (add_structure_field(structure->fields,
608 structure->field_name_to_index, field_type, field_name)) {
609 ret = -1;
610 goto end;
611 }
612
613 if (type->declaration->alignment < field_type->declaration->alignment) {
614 type->declaration->alignment =
615 field_type->declaration->alignment;
616 }
617end:
618 return ret;
619}
620
621struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
622 struct bt_ctf_field_type *enum_tag, const char *tag_name)
623{
624 struct bt_ctf_field_type_variant *variant = NULL;
625
626 if (!enum_tag || validate_identifier(tag_name) ||
627 (enum_tag->declaration->id != CTF_TYPE_ENUM)) {
628 goto error;
629 }
630
631 variant = g_new0(struct bt_ctf_field_type_variant, 1);
632 if (!variant) {
633 goto error;
634 }
635
636 variant->parent.declaration = &variant->declaration.p;
637 variant->parent.declaration->id = CTF_TYPE_VARIANT;
638 variant->tag_name = g_string_new(tag_name);
639 bt_ctf_field_type_init(&variant->parent);
640 variant->field_name_to_index = g_hash_table_new(NULL, NULL);
641 variant->fields = g_ptr_array_new_with_free_func(
642 (GDestroyNotify)destroy_structure_field);
643 bt_ctf_field_type_get(enum_tag);
644 variant->tag = container_of(enum_tag,
645 struct bt_ctf_field_type_enumeration, parent);
646 return &variant->parent;
647error:
648 return NULL;
649}
650
651int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
652 struct bt_ctf_field_type *field_type,
653 const char *field_name)
654{
655 size_t i;
656 int ret = 0;
657 int name_found = 0;
658 struct bt_ctf_field_type_variant *variant;
659 GQuark field_name_quark = g_quark_from_string(field_name);
660
661 if (!type || !field_type || type->frozen ||
662 validate_identifier(field_name) ||
9ce21c30
JG
663 (type->declaration->id != CTF_TYPE_VARIANT) ||
664 bt_ctf_field_type_validate(field_type)) {
273b65be
JG
665 ret = -1;
666 goto end;
667 }
668
669 variant = container_of(type, struct bt_ctf_field_type_variant, parent);
670 /* Make sure this name is present in the enum tag */
671 for (i = 0; i < variant->tag->entries->len; i++) {
672 struct enumeration_mapping *mapping =
673 g_ptr_array_index(variant->tag->entries, i);
674
675 if (mapping->string == field_name_quark) {
676 name_found = 1;
677 break;
678 }
679 }
680
681 if (!name_found || add_structure_field(variant->fields,
682 variant->field_name_to_index, field_type, field_name)) {
683 ret = -1;
684 goto end;
685 }
686end:
687 return ret;
688}
689
690struct bt_ctf_field_type *bt_ctf_field_type_array_create(
691 struct bt_ctf_field_type *element_type,
692 unsigned int length)
693{
694 struct bt_ctf_field_type_array *array = NULL;
695
9ce21c30
JG
696 if (!element_type || length == 0 ||
697 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
698 goto error;
699 }
700
701 array = g_new0(struct bt_ctf_field_type_array, 1);
702 if (!array) {
703 goto error;
704 }
705
706 array->parent.declaration = &array->declaration.p;
707 array->parent.declaration->id = CTF_TYPE_ARRAY;
708 bt_ctf_field_type_init(&array->parent);
709 bt_ctf_field_type_get(element_type);
710 array->element_type = element_type;
711 array->length = length;
712 array->parent.declaration->alignment =
713 element_type->declaration->alignment;
714 return &array->parent;
715error:
716 return NULL;
717}
718
719struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
720 struct bt_ctf_field_type *element_type,
721 const char *length_field_name)
722{
723 struct bt_ctf_field_type_sequence *sequence = NULL;
724
9ce21c30
JG
725 if (!element_type || validate_identifier(length_field_name) ||
726 bt_ctf_field_type_validate(element_type)) {
273b65be
JG
727 goto error;
728 }
729
730 sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
731 if (!sequence) {
732 goto error;
733 }
734
735 sequence->parent.declaration = &sequence->declaration.p;
736 sequence->parent.declaration->id = CTF_TYPE_SEQUENCE;
737 bt_ctf_field_type_init(&sequence->parent);
738 bt_ctf_field_type_get(element_type);
739 sequence->element_type = element_type;
740 sequence->length_field_name = g_string_new(length_field_name);
741 sequence->parent.declaration->alignment =
742 element_type->declaration->alignment;
743 return &sequence->parent;
744error:
745 return NULL;
746}
747
748struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
749{
750 struct bt_ctf_field_type_string *string =
751 g_new0(struct bt_ctf_field_type_string, 1);
752
753 if (!string) {
754 return NULL;
755 }
756
757 string->parent.declaration = &string->declaration.p;
758 string->parent.declaration->id = CTF_TYPE_STRING;
759 bt_ctf_field_type_init(&string->parent);
760 string->declaration.encoding = CTF_STRING_UTF8;
761 string->parent.declaration->alignment = CHAR_BIT;
762 return &string->parent;
763}
764
765int bt_ctf_field_type_string_set_encoding(
766 struct bt_ctf_field_type *type,
767 enum ctf_string_encoding encoding)
768{
769 int ret = 0;
770 struct bt_ctf_field_type_string *string;
771
772 if (!type || type->declaration->id != CTF_TYPE_STRING ||
773 (encoding != CTF_STRING_UTF8 &&
774 encoding != CTF_STRING_ASCII)) {
775 ret = -1;
776 goto end;
777 }
778
779 string = container_of(type, struct bt_ctf_field_type_string, parent);
780 string->declaration.encoding = encoding;
781end:
782 return ret;
783}
784
785int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
786 unsigned int alignment)
787{
788 int ret = 0;
789
790 /* Alignment must be bit-aligned (1) or byte aligned */
791 if (!type || type->frozen || (alignment != 1 && (alignment & 0x7))) {
792 ret = -1;
793 goto end;
794 }
795
796 if (type->declaration->id == CTF_TYPE_STRING &&
797 alignment != CHAR_BIT) {
798 ret = -1;
799 goto end;
800 }
801
802 type->declaration->alignment = alignment;
803 ret = 0;
804end:
805 return ret;
806}
807
808int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
809 enum bt_ctf_byte_order byte_order)
810{
811 int ret = 0;
812 int internal_byte_order;
813 enum ctf_type_id type_id;
814
815 if (!type || type->frozen) {
816 ret = -1;
817 goto end;
818 }
819
820 type_id = type->declaration->id;
821 switch (byte_order) {
822 case BT_CTF_BYTE_ORDER_NATIVE:
823 internal_byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN ?
824 LITTLE_ENDIAN : BIG_ENDIAN);
825 break;
826 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
827 internal_byte_order = LITTLE_ENDIAN;
828 break;
829 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
830 case BT_CTF_BYTE_ORDER_NETWORK:
831 internal_byte_order = BIG_ENDIAN;
832 break;
833 default:
834 ret = -1;
835 goto end;
836 }
837
838 if (set_byte_order_funcs[type_id]) {
839 set_byte_order_funcs[type_id](type, internal_byte_order);
840 }
841end:
842 return ret;
843}
844
845void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
846{
847 if (!type) {
848 return;
849 }
850
851 bt_ctf_ref_get(&type->ref_count);
852}
853
854void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
855{
856 enum ctf_type_id type_id;
857
858 if (!type) {
859 return;
860 }
861
862 type_id = type->declaration->id;
863 assert(type_id > CTF_TYPE_UNKNOWN && type_id < NR_CTF_TYPES);
864 bt_ctf_ref_put(&type->ref_count, type_destroy_funcs[type_id]);
865}
866
867BT_HIDDEN
868void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
869{
870 if (!type) {
871 return;
872 }
873
874 type->freeze(type);
875}
876
877BT_HIDDEN
878enum ctf_type_id bt_ctf_field_type_get_type_id(
879 struct bt_ctf_field_type *type)
880{
881 if (!type) {
882 return CTF_TYPE_UNKNOWN;
883 }
884
885 return type->declaration->id;
886}
887
888BT_HIDDEN
889struct bt_ctf_field_type *bt_ctf_field_type_structure_get_type(
890 struct bt_ctf_field_type_structure *structure,
891 const char *name)
892{
893 struct bt_ctf_field_type *type = NULL;
894 struct structure_field *field;
895 GQuark name_quark = g_quark_try_string(name);
896 size_t index;
897
898 if (!name_quark) {
899 goto end;
900 }
901
902 if (!g_hash_table_lookup_extended(structure->field_name_to_index,
903 GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
904 goto end;
905 }
906
907 field = structure->fields->pdata[index];
908 type = field->type;
909end:
910 return type;
911}
912
913BT_HIDDEN
914struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
915 struct bt_ctf_field_type_array *array)
916{
917 assert(array);
918 return array->element_type;
919}
920
921BT_HIDDEN
922struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
923 struct bt_ctf_field_type_sequence *sequence)
924{
925 assert(sequence);
926 return sequence->element_type;
927}
928
929BT_HIDDEN
930struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type(
931 struct bt_ctf_field_type_variant *variant,
932 int64_t tag_value)
933{
934 struct bt_ctf_field_type *type = NULL;
935 GQuark field_name_quark;
936 gpointer index;
937 struct structure_field *field_entry;
938 struct range_overlap_query query = {.range_start = tag_value,
939 .range_end = tag_value, .mapping_name = 0, .overlaps = 0};
940
941 g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
942 &query);
943 if (!query.overlaps) {
944 goto end;
945 }
946
947 field_name_quark = query.mapping_name;
948 if (!g_hash_table_lookup_extended(variant->field_name_to_index,
949 GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
950 goto end;
951 }
952
953 field_entry = g_ptr_array_index(variant->fields, (size_t)index);
954 type = field_entry->type;
955end:
956 return type;
957}
958
959BT_HIDDEN
960int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
961 struct metadata_context *context)
962{
963 int ret;
964
965 if (!type || !context) {
966 ret = -1;
967 goto end;
968 }
969
970 ret = type->serialize(type, context);
971end:
972 return ret;
973}
974
975static
976void bt_ctf_field_type_integer_destroy(struct bt_ctf_ref *ref)
977{
978 struct bt_ctf_field_type_integer *integer;
979
980 if (!ref) {
981 return;
982 }
983
984 integer = container_of(
985 container_of(ref, struct bt_ctf_field_type, ref_count),
986 struct bt_ctf_field_type_integer, parent);
987 g_free(integer);
988}
989
990static
991void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_ref *ref)
992{
993 struct bt_ctf_field_type_enumeration *enumeration;
994
995 if (!ref) {
996 return;
997 }
998
999 enumeration = container_of(
1000 container_of(ref, struct bt_ctf_field_type, ref_count),
1001 struct bt_ctf_field_type_enumeration, parent);
1002 g_ptr_array_free(enumeration->entries, TRUE);
1003 bt_ctf_field_type_put(enumeration->container);
1004 g_free(enumeration);
1005}
1006
1007static
1008void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_ref *ref)
1009{
1010 struct bt_ctf_field_type_floating_point *floating_point;
1011
1012 if (!ref) {
1013 return;
1014 }
1015
1016 floating_point = container_of(
1017 container_of(ref, struct bt_ctf_field_type, ref_count),
1018 struct bt_ctf_field_type_floating_point, parent);
1019 g_free(floating_point);
1020}
1021
1022static
1023void bt_ctf_field_type_structure_destroy(struct bt_ctf_ref *ref)
1024{
1025 struct bt_ctf_field_type_structure *structure;
1026
1027 if (!ref) {
1028 return;
1029 }
1030
1031 structure = container_of(
1032 container_of(ref, struct bt_ctf_field_type, ref_count),
1033 struct bt_ctf_field_type_structure, parent);
1034 g_ptr_array_free(structure->fields, TRUE);
1035 g_hash_table_destroy(structure->field_name_to_index);
1036 g_free(structure);
1037}
1038
1039static
1040void bt_ctf_field_type_variant_destroy(struct bt_ctf_ref *ref)
1041{
1042 struct bt_ctf_field_type_variant *variant;
1043
1044 if (!ref) {
1045 return;
1046 }
1047
1048 variant = container_of(
1049 container_of(ref, struct bt_ctf_field_type, ref_count),
1050 struct bt_ctf_field_type_variant, parent);
1051 g_ptr_array_free(variant->fields, TRUE);
1052 g_hash_table_destroy(variant->field_name_to_index);
1053 g_string_free(variant->tag_name, TRUE);
1054 bt_ctf_field_type_put(&variant->tag->parent);
1055 g_free(variant);
1056}
1057
1058static
1059void bt_ctf_field_type_array_destroy(struct bt_ctf_ref *ref)
1060{
1061 struct bt_ctf_field_type_array *array;
1062
1063 if (!ref) {
1064 return;
1065 }
1066
1067 array = container_of(
1068 container_of(ref, struct bt_ctf_field_type, ref_count),
1069 struct bt_ctf_field_type_array, parent);
1070 bt_ctf_field_type_put(array->element_type);
1071 g_free(array);
1072}
1073
1074static
1075void bt_ctf_field_type_sequence_destroy(struct bt_ctf_ref *ref)
1076{
1077 struct bt_ctf_field_type_sequence *sequence;
1078
1079 if (!ref) {
1080 return;
1081 }
1082
1083 sequence = container_of(
1084 container_of(ref, struct bt_ctf_field_type, ref_count),
1085 struct bt_ctf_field_type_sequence, parent);
1086 bt_ctf_field_type_put(sequence->element_type);
1087 g_string_free(sequence->length_field_name, TRUE);
1088 g_free(sequence);
1089}
1090
1091static
1092void bt_ctf_field_type_string_destroy(struct bt_ctf_ref *ref)
1093{
1094 struct bt_ctf_field_type_string *string;
1095
1096 if (!ref) {
1097 return;
1098 }
1099
1100 string = container_of(
1101 container_of(ref, struct bt_ctf_field_type, ref_count),
1102 struct bt_ctf_field_type_string, parent);
1103 g_free(string);
1104}
1105
1106static
1107void generic_field_type_freeze(struct bt_ctf_field_type *type)
1108{
1109 type->frozen = 1;
1110}
1111
1112static
1113void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
1114{
1115 struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
1116 type, struct bt_ctf_field_type_enumeration, parent);
1117
1118 generic_field_type_freeze(type);
1119 bt_ctf_field_type_freeze(enumeration_type->container);
1120}
1121
1122static
1123void freeze_structure_field(struct structure_field *field)
1124{
1125 bt_ctf_field_type_freeze(field->type);
1126}
1127
1128static
1129void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
1130{
1131 struct bt_ctf_field_type_structure *structure_type = container_of(
1132 type, struct bt_ctf_field_type_structure, parent);
1133
1134 generic_field_type_freeze(type);
1135 g_ptr_array_foreach(structure_type->fields, (GFunc)freeze_structure_field,
1136 NULL);
1137}
1138
1139static
1140void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
1141{
1142 struct bt_ctf_field_type_variant *variant_type = container_of(
1143 type, struct bt_ctf_field_type_variant, parent);
1144
1145 generic_field_type_freeze(type);
1146 g_ptr_array_foreach(variant_type->fields, (GFunc)freeze_structure_field,
1147 NULL);
1148}
1149
1150static
1151void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
1152{
1153 struct bt_ctf_field_type_array *array_type = container_of(
1154 type, struct bt_ctf_field_type_array, parent);
1155
1156 generic_field_type_freeze(type);
1157 bt_ctf_field_type_freeze(array_type->element_type);
1158}
1159
1160static
1161void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
1162{
1163 struct bt_ctf_field_type_sequence *sequence_type = container_of(
1164 type, struct bt_ctf_field_type_sequence, parent);
1165
1166 generic_field_type_freeze(type);
1167 bt_ctf_field_type_freeze(sequence_type->element_type);
1168}
1169
1170static
1171const char *get_encoding_string(enum ctf_string_encoding encoding)
1172{
1173 const char *encoding_string;
1174
1175 switch (encoding) {
1176 case CTF_STRING_NONE:
1177 encoding_string = "none";
1178 break;
1179 case CTF_STRING_ASCII:
1180 encoding_string = "ASCII";
1181 break;
1182 case CTF_STRING_UTF8:
1183 encoding_string = "UTF8";
1184 break;
1185 default:
1186 encoding_string = "unknown";
1187 break;
1188 }
1189
1190 return encoding_string;
1191}
1192
1193static
1194const char *get_integer_base_string(enum bt_ctf_integer_base base)
1195{
1196 const char *base_string;
1197
1198 switch (base) {
1199 case BT_CTF_INTEGER_BASE_DECIMAL:
1200 base_string = "decimal";
1201 break;
1202 case BT_CTF_INTEGER_BASE_HEXADECIMAL:
1203 base_string = "hexadecimal";
1204 break;
1205 case BT_CTF_INTEGER_BASE_OCTAL:
1206 base_string = "octal";
1207 break;
1208 case BT_CTF_INTEGER_BASE_BINARY:
1209 base_string = "binary";
1210 break;
1211 default:
1212 base_string = "unknown";
1213 break;
1214 }
1215
1216 return base_string;
1217}
1218
1219static
1220int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
1221 struct metadata_context *context)
1222{
1223 struct bt_ctf_field_type_integer *integer = container_of(type,
1224 struct bt_ctf_field_type_integer, parent);
1225
1226 g_string_append_printf(context->string,
1227 "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s; }",
1228 integer->declaration.len, type->declaration->alignment,
1229 (integer->declaration.signedness ? "true" : "false"),
1230 get_encoding_string(integer->declaration.encoding),
1231 get_integer_base_string(integer->declaration.base),
1232 get_byte_order_string(integer->declaration.byte_order));
1233 return 0;
1234}
1235
1236static
1237int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
1238 struct metadata_context *context)
1239{
1240 size_t entry;
9ce21c30 1241 int ret;
273b65be
JG
1242 struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
1243 struct bt_ctf_field_type_enumeration, parent);
1244
9ce21c30
JG
1245 ret = bt_ctf_field_type_validate(type);
1246 if (ret) {
1247 goto end;
1248 }
1249
273b65be
JG
1250 g_string_append(context->string, "enum : ");
1251 ret = bt_ctf_field_type_serialize(enumeration->container, context);
1252 if (ret) {
1253 goto end;
1254 }
1255
1256 g_string_append(context->string, " { ");
1257 for (entry = 0; entry < enumeration->entries->len; entry++) {
1258 struct enumeration_mapping *mapping =
1259 enumeration->entries->pdata[entry];
1260
1261 if (mapping->range_start == mapping->range_end) {
a39fa057
JG
1262 g_string_append_printf(context->string,
1263 "\"%s\" = %" PRId64,
273b65be
JG
1264 g_quark_to_string(mapping->string),
1265 mapping->range_start);
1266 } else {
1267 g_string_append_printf(context->string,
a39fa057 1268 "\"%s\" = %" PRId64 " ... %" PRId64,
273b65be
JG
1269 g_quark_to_string(mapping->string),
1270 mapping->range_start, mapping->range_end);
1271 }
1272
1273 g_string_append(context->string,
1274 ((entry != (enumeration->entries->len - 1)) ?
1275 ", " : " }"));
1276 }
1277
1278 if (context->field_name->len) {
1279 g_string_append_printf(context->string, " %s",
1280 context->field_name->str);
1281 g_string_assign(context->field_name, "");
1282 }
1283end:
1284 return ret;
1285}
1286
1287static
1288int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
1289 struct metadata_context *context)
1290{
1291 struct bt_ctf_field_type_floating_point *floating_point = container_of(
1292 type, struct bt_ctf_field_type_floating_point, parent);
1293
1294 g_string_append_printf(context->string,
1295 "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
1296 floating_point->declaration.exp->len,
1297 floating_point->declaration.mantissa->len + 1,
1298 get_byte_order_string(floating_point->declaration.byte_order),
1299 type->declaration->alignment);
1300 return 0;
1301}
1302
1303static
1304int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
1305 struct metadata_context *context)
1306{
1307 size_t i;
1308 unsigned int indent;
1309 int ret = 0;
1310 struct bt_ctf_field_type_structure *structure = container_of(type,
1311 struct bt_ctf_field_type_structure, parent);
1312 GString *structure_field_name = context->field_name;
1313
1314 context->field_name = g_string_new("");
1315
1316 context->current_indentation_level++;
1317 g_string_append(context->string, "struct {\n");
1318
1319 for (i = 0; i < structure->fields->len; i++) {
1320 struct structure_field *field;
1321
1322 for (indent = 0; indent < context->current_indentation_level;
1323 indent++) {
1324 g_string_append_c(context->string, '\t');
1325 }
1326
1327 field = structure->fields->pdata[i];
1328 g_string_assign(context->field_name,
1329 g_quark_to_string(field->name));
1330 ret = bt_ctf_field_type_serialize(field->type, context);
1331 if (ret) {
1332 goto end;
1333 }
1334
1335 if (context->field_name->len) {
1336 g_string_append_printf(context->string, " %s",
1337 context->field_name->str);
1338 }
1339 g_string_append(context->string, ";\n");
1340 }
1341
1342 context->current_indentation_level--;
1343 for (indent = 0; indent < context->current_indentation_level;
1344 indent++) {
1345 g_string_append_c(context->string, '\t');
1346 }
1347
1348 g_string_append_printf(context->string, "} align(%zu)",
1349 type->declaration->alignment);
1350end:
1351 g_string_free(context->field_name, TRUE);
1352 context->field_name = structure_field_name;
1353 return ret;
1354}
1355
1356static
1357int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
1358 struct metadata_context *context)
1359{
1360 size_t i;
1361 unsigned int indent;
1362 int ret = 0;
1363 struct bt_ctf_field_type_variant *variant = container_of(
1364 type, struct bt_ctf_field_type_variant, parent);
1365 GString *variant_field_name = context->field_name;
1366
1367 context->field_name = g_string_new("");
1368 g_string_append_printf(context->string,
1369 "variant <%s> {\n", variant->tag_name->str);
1370 context->current_indentation_level++;
1371 for (i = 0; i < variant->fields->len; i++) {
1372 struct structure_field *field = variant->fields->pdata[i];
1373
1374 g_string_assign(context->field_name,
1375 g_quark_to_string(field->name));
1376 for (indent = 0; indent < context->current_indentation_level;
1377 indent++) {
1378 g_string_append_c(context->string, '\t');
1379 }
1380
1381 g_string_assign(context->field_name,
1382 g_quark_to_string(field->name));
1383 ret = bt_ctf_field_type_serialize(field->type, context);
1384 if (ret) {
1385 goto end;
1386 }
1387
1388 if (context->field_name->len) {
1389 g_string_append_printf(context->string, " %s;",
1390 context->field_name->str);
1391 }
1392
1393 g_string_append_c(context->string, '\n');
1394 }
1395
1396 context->current_indentation_level--;
1397 for (indent = 0; indent < context->current_indentation_level;
1398 indent++) {
1399 g_string_append_c(context->string, '\t');
1400 }
1401
1402 g_string_append(context->string, "}");
1403end:
1404 g_string_free(context->field_name, TRUE);
1405 context->field_name = variant_field_name;
1406 return ret;
1407}
1408
1409static
1410int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
1411 struct metadata_context *context)
1412{
1413 int ret = 0;
1414 struct bt_ctf_field_type_array *array = container_of(type,
1415 struct bt_ctf_field_type_array, parent);
1416
1417 ret = bt_ctf_field_type_serialize(array->element_type, context);
1418 if (ret) {
1419 goto end;
1420 }
1421
1422 if (context->field_name->len) {
1423 g_string_append_printf(context->string, " %s[%u]",
1424 context->field_name->str, array->length);
1425 g_string_assign(context->field_name, "");
1426 } else {
1427 g_string_append_printf(context->string, "[%u]", array->length);
1428 }
1429end:
1430 return ret;
1431}
1432
1433static
1434int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
1435 struct metadata_context *context)
1436{
1437 int ret = 0;
1438 struct bt_ctf_field_type_sequence *sequence = container_of(
1439 type, struct bt_ctf_field_type_sequence, parent);
1440
1441 ret = bt_ctf_field_type_serialize(sequence->element_type, context);
1442 if (ret) {
1443 goto end;
1444 }
1445
1446 if (context->field_name->len) {
1447 g_string_append_printf(context->string, " %s[%s]",
1448 context->field_name->str,
1449 sequence->length_field_name->str);
1450 g_string_assign(context->field_name, "");
1451 } else {
1452 g_string_append_printf(context->string, "[%s]",
1453 sequence->length_field_name->str);
1454 }
1455end:
1456 return ret;
1457}
1458
1459static
1460int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
1461 struct metadata_context *context)
1462{
1463 struct bt_ctf_field_type_string *string = container_of(
1464 type, struct bt_ctf_field_type_string, parent);
1465
1466 g_string_append_printf(context->string,
1467 "string { encoding = %s; }",
1468 get_encoding_string(string->declaration.encoding));
1469 return 0;
1470}
1471
1472static
1473void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
1474 int byte_order)
1475{
1476 struct bt_ctf_field_type_integer *integer_type = container_of(type,
1477 struct bt_ctf_field_type_integer, parent);
1478
1479 integer_type->declaration.byte_order = byte_order;
1480}
1481
1482static
1483void bt_ctf_field_type_floating_point_set_byte_order(
1484 struct bt_ctf_field_type *type, int byte_order)
1485{
1486 struct bt_ctf_field_type_floating_point *floating_point_type =
1487 container_of(type, struct bt_ctf_field_type_floating_point,
1488 parent);
1489
1490 floating_point_type->declaration.byte_order = byte_order;
1491 floating_point_type->sign.byte_order = byte_order;
1492 floating_point_type->mantissa.byte_order = byte_order;
1493 floating_point_type->exp.byte_order = byte_order;
1494}
This page took 0.078081 seconds and 4 git commands to generate.