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