cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / plugins / ctf / common / src / metadata / tsdl / ctf-meta-update-alignments.cpp
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2020 Philippe Proulx <pproulx@efficios.com>
5 */
6
7 #include <stdint.h>
8
9 #include "ctf-meta-visitors.hpp"
10
11 static inline int set_alignments(struct ctf_field_class *fc)
12 {
13 int ret = 0;
14 uint64_t i;
15
16 if (!fc) {
17 goto end;
18 }
19
20 switch (fc->type) {
21 case CTF_FIELD_CLASS_TYPE_STRUCT:
22 {
23 struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc);
24
25 for (i = 0; i < struct_fc->members->len; i++) {
26 struct ctf_named_field_class *named_fc =
27 ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
28
29 ret = set_alignments(named_fc->fc);
30 if (ret) {
31 goto end;
32 }
33
34 if (named_fc->fc->alignment > fc->alignment) {
35 fc->alignment = named_fc->fc->alignment;
36 }
37 }
38
39 break;
40 }
41 case CTF_FIELD_CLASS_TYPE_VARIANT:
42 {
43 struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc);
44
45 for (i = 0; i < var_fc->options->len; i++) {
46 struct ctf_named_field_class *named_fc =
47 ctf_field_class_variant_borrow_option_by_index(var_fc, i);
48
49 ret = set_alignments(named_fc->fc);
50 if (ret) {
51 goto end;
52 }
53 }
54
55 break;
56 }
57 case CTF_FIELD_CLASS_TYPE_ARRAY:
58 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
59 {
60 struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc);
61
62 ret = set_alignments(array_fc->elem_fc);
63 if (ret) {
64 goto end;
65 }
66
67 /*
68 * Use the alignment of the array/sequence field class's
69 * element FC as its own alignment.
70 *
71 * This is especially important when the array/sequence
72 * field's effective length is zero: as per CTF 1.8, the
73 * stream data decoding process still needs to align the
74 * cursor using the element's alignment [1]:
75 *
76 * > Arrays are always aligned on their element
77 * > alignment requirement.
78 *
79 * For example:
80 *
81 * struct {
82 * integer { size = 8; } a;
83 * integer { size = 8; align = 16; } b[0];
84 * integer { size = 8; } c;
85 * };
86 *
87 * When using this to decode the bytes 1, 2, and 3, then
88 * the decoded values are:
89 *
90 * `a`: 1
91 * `b`: []
92 * `c`: 3
93 *
94 * [1]: https://diamon.org/ctf/#spec4.2.3
95 */
96 array_fc->base.alignment = array_fc->elem_fc->alignment;
97 break;
98 }
99 default:
100 break;
101 }
102
103 end:
104 return ret;
105 }
106
107 int ctf_trace_class_update_alignments(struct ctf_trace_class *ctf_tc)
108 {
109 int ret = 0;
110 uint64_t i;
111
112 if (!ctf_tc->is_translated) {
113 ret = set_alignments(ctf_tc->packet_header_fc);
114 if (ret) {
115 goto end;
116 }
117 }
118
119 for (i = 0; i < ctf_tc->stream_classes->len; i++) {
120 ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i];
121 uint64_t j;
122
123 if (!sc->is_translated) {
124 ret = set_alignments(sc->packet_context_fc);
125 if (ret) {
126 goto end;
127 }
128
129 ret = set_alignments(sc->event_header_fc);
130 if (ret) {
131 goto end;
132 }
133
134 ret = set_alignments(sc->event_common_context_fc);
135 if (ret) {
136 goto end;
137 }
138 }
139
140 for (j = 0; j < sc->event_classes->len; j++) {
141 struct ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j];
142
143 if (ec->is_translated) {
144 continue;
145 }
146
147 ret = set_alignments(ec->spec_context_fc);
148 if (ret) {
149 goto end;
150 }
151
152 ret = set_alignments(ec->payload_fc);
153 if (ret) {
154 goto end;
155 }
156 }
157 }
158
159 end:
160 return ret;
161 }
This page took 0.032333 seconds and 4 git commands to generate.