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