1use std::io;
2
3use super::utilities::IdentPrefix;
4use crate::ast;
5
6pub(super) trait GenReader: IdentPrefix {
7 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;
8
9 fn gen_reader_interfaces<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
10 self.gen_reader_interfaces_internal(writer)?;
11 Ok(())
12 }
13
14 fn gen_reader_functions<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
15 self.gen_reader_function_verify(writer)?;
16 Ok(())
17 }
18
19 fn gen_reader_function_verify<W: io::Write>(&self, _writer: &mut W) -> io::Result<()> {
20 Ok(())
21 }
22}
23
24impl GenReader for ast::Option_ {
25 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
26 {
27 self.define_reader_function(
28 writer,
29 "_verify",
30 "(const mol_seg_t*, bool)",
31 "mol_errno",
32 )?;
33 }
34 {
35 self.define_reader_macro(writer, "_is_none(s)", "mol_option_is_none(s)")?;
36 }
37 Ok(())
38 }
39
40 fn gen_reader_function_verify<W: io::Write>(&self, o: &mut W) -> io::Result<()> {
41 let func_name = format!("{}_verify", self.reader_prefix());
42 let api_decorator = self.api_decorator();
43 w!(
44 o,
45 "{} mol_errno {} (const mol_seg_t *input, bool compatible) {{",
46 api_decorator,
47 func_name
48 );
49 if self.item().typ().is_byte() {
50 w!(o, " if (input->size > 1) {{ ");
51 w!(o, " return MOL_ERR; ");
52 } else {
53 let f = format!("{}_verify", self.item().typ().reader_prefix());
54 w!(o, " if (input->size != 0) {{ ");
55 w!(o, " return {}(input, compatible); ", f);
56 }
57 w!(o, " }} else {{ ");
58 w!(o, " return MOL_OK; ");
59 w!(o, " }} ");
60 w!(o, "}} ");
61 Ok(())
62 }
63}
64
65impl GenReader for ast::Union {
66 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
67 {
68 self.define_reader_function(
69 writer,
70 "_verify",
71 "(const mol_seg_t*, bool)",
72 "mol_errno",
73 )?;
74 }
75 {
76 self.define_reader_macro(writer, "_unpack(s)", "mol_union_unpack(s)")?;
77 }
78 Ok(())
79 }
80
81 fn gen_reader_function_verify<W: io::Write>(&self, o: &mut W) -> io::Result<()> {
82 let func_name = format!("{}_verify", self.reader_prefix());
83 let api_decorator = self.api_decorator();
84 w!(
85 o,
86 "{} mol_errno {} (const mol_seg_t *input, bool compatible) {{",
87 api_decorator,
88 func_name
89 );
90 w!(o, " if (input->size < MOL_NUM_T_SIZE) {{ ");
91 w!(o, " return MOL_ERR_HEADER; ");
92 w!(o, " }} ");
93 w!(o, " mol_num_t item_id = mol_unpack_number(input->ptr); ");
94 w!(o, " mol_seg_t inner; ");
95 w!(o, " inner.ptr = input->ptr + MOL_NUM_T_SIZE; ");
96 w!(o, " inner.size = input->size - MOL_NUM_T_SIZE; ");
97 w!(o, " switch(item_id) {{ ");
98 for item in self.items().iter() {
99 w!(
100 o,
101 " case {}: ",
102 item.id()
103 );
104 if item.typ().is_byte() {
105 w!(o, " return inner.size == 1 ? MOL_OK : MOL_ERR; ");
106 } else {
107 let f = format!("{}_verify", item.typ().reader_prefix());
108 w!(o, " return {}(&inner, compatible); ", f);
109 }
110 }
111 w!(o, " default: ");
112 w!(o, " return MOL_ERR_UNKNOWN_ITEM; ");
113 w!(o, " }} ");
114 w!(o, "}} ");
115 Ok(())
116 }
117}
118
119impl GenReader for ast::Array {
120 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
121 {
122 let macro_content = format!("mol_verify_fixed_size(s, {})", self.total_size());
123 self.define_reader_macro(writer, "_verify(s, c)", ¯o_content)?;
124 }
125 for i in 0..self.item_count() {
126 let macro_sig_tail = format!("_get_nth{}(s)", i);
127 let item_offset = self.item_size() * i;
128 let macro_content = format!(
129 "mol_slice_by_offset(s, {}, {})",
130 item_offset,
131 self.item_size()
132 );
133 self.define_reader_macro(writer, ¯o_sig_tail, ¯o_content)?;
134 }
135 Ok(())
136 }
137}
138
139impl GenReader for ast::Struct {
140 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
141 {
142 let macro_content = format!("mol_verify_fixed_size(s, {})", self.total_size());
143 self.define_reader_macro(writer, "_verify(s, c)", ¯o_content)?;
144 }
145 let mut field_offset = 0;
146 for (f, field_size) in self.fields().iter().zip(self.field_sizes().iter()) {
147 let macro_sig_tail = format!("_get_{}(s)", f.name());
148 let macro_content = format!("mol_slice_by_offset(s, {}, {})", field_offset, field_size);
149 self.define_reader_macro(writer, ¯o_sig_tail, ¯o_content)?;
150 field_offset += field_size;
151 }
152 Ok(())
153 }
154}
155
156impl GenReader for ast::FixVec {
157 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
158 {
159 let macro_content = format!("mol_fixvec_verify(s, {})", self.item_size());
160 self.define_reader_macro(writer, "_verify(s, c)", ¯o_content)?;
161 }
162 {
163 self.define_reader_macro(writer, "_length(s)", "mol_fixvec_length(s)")?;
164 }
165 {
166 let macro_content = format!("mol_fixvec_slice_by_index(s, {}, i)", self.item_size());
167 self.define_reader_macro(writer, "_get(s, i)", ¯o_content)?;
168 }
169 if self.item().typ().is_byte() {
170 self.define_reader_macro(writer, "_raw_bytes(s)", "mol_fixvec_slice_raw_bytes(s)")?;
171 }
172 Ok(())
173 }
174}
175
176impl GenReader for ast::DynVec {
177 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
178 {
179 self.define_reader_function(
180 writer,
181 "_verify",
182 "(const mol_seg_t*, bool)",
183 "mol_errno",
184 )?;
185 }
186 {
187 self.define_reader_macro(writer, "_length(s)", "mol_dynvec_length(s)")?;
188 }
189 {
190 self.define_reader_macro(writer, "_get(s, i)", "mol_dynvec_slice_by_index(s, i)")?;
191 }
192 Ok(())
193 }
194
195 fn gen_reader_function_verify<W: io::Write>(&self, o: &mut W) -> io::Result<()> {
196 let func_name = format!("{}_verify", self.reader_prefix());
197 let api_decorator = self.api_decorator();
198 let f = format!("{}_verify", self.item().typ().reader_prefix());
199 w!(
200 o,
201 "{} mol_errno {} (const mol_seg_t *input, bool compatible) {{",
202 api_decorator,
203 func_name
204 );
205 w!(o, " if (input->size < MOL_NUM_T_SIZE) {{ ");
206 w!(o, " return MOL_ERR_HEADER; ");
207 w!(o, " }} ");
208 w!(o, " uint8_t *ptr = input->ptr; ");
209 w!(o, " mol_num_t total_size = mol_unpack_number(ptr); ");
210 w!(o, " if (input->size != total_size) {{ ");
211 w!(o, " return MOL_ERR_TOTAL_SIZE; ");
212 w!(o, " }} ");
213 w!(o, " if (input->size == MOL_NUM_T_SIZE) {{ ");
214 w!(o, " return MOL_OK; ");
215 w!(o, " }} ");
216 w!(o, " if (input->size < MOL_NUM_T_SIZE * 2) {{ ");
217 w!(o, " return MOL_ERR_HEADER; ");
218 w!(o, " }} ");
219 w!(o, " ptr += MOL_NUM_T_SIZE; ");
220 w!(o, " mol_num_t offset = mol_unpack_number(ptr); ");
221 w!(o, " if (offset % 4 > 0 || offset < MOL_NUM_T_SIZE*2) {{");
222 w!(o, " return MOL_ERR_OFFSET; ");
223 w!(o, " }} ");
224 w!(o, " mol_num_t item_count = offset / 4 - 1; ");
225 w!(o, " if (input->size < MOL_NUM_T_SIZE*(item_count+1)) {{");
226 w!(o, " return MOL_ERR_HEADER; ");
227 w!(o, " }} ");
228 w!(o, " mol_num_t end; ");
229 w!(o, " for (mol_num_t i=1; i<item_count; i++) {{ ");
230 w!(o, " ptr += MOL_NUM_T_SIZE; ");
231 w!(o, " end = mol_unpack_number(ptr); ");
232 w!(o, " if (offset > end) {{ ");
233 w!(o, " return MOL_ERR_OFFSET; ");
234 w!(o, " }} ");
235 w!(o, " mol_seg_t inner; ");
236 w!(o, " inner.ptr = input->ptr + offset; ");
237 w!(o, " inner.size = end - offset; ");
238 w!(o, " if (mol_contained_by(&inner, input)!=MOL_OK) {{");
239 w!(o, " return MOL_ERR_OFFSET; ");
240 w!(o, " }} ");
241 w!(o, " mol_errno errno = {}(&inner, compatible); ", f);
242 w!(o, " if (errno != MOL_OK) {{ ");
243 w!(o, " return MOL_ERR_DATA; ");
244 w!(o, " }} ");
245 w!(o, " offset = end; ");
246 w!(o, " }} ");
247 w!(o, " if (offset > total_size) {{ ");
248 w!(o, " return MOL_ERR_OFFSET; ");
249 w!(o, " }} ");
250 w!(o, " mol_seg_t inner; ");
251 w!(o, " inner.ptr = input->ptr + offset; ");
252 w!(o, " inner.size = total_size - offset; ");
253 w!(o, " if (mol_contained_by(&inner, input) != MOL_OK) {{ ");
254 w!(o, " return MOL_ERR_OFFSET; ");
255 w!(o, " }} ");
256 w!(o, " return {}(&inner, compatible); ", f);
257 w!(o, "}} ");
258 Ok(())
259 }
260}
261
262impl GenReader for ast::Table {
263 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
264 {
265 self.define_reader_function(
266 writer,
267 "_verify",
268 "(const mol_seg_t*, bool)",
269 "mol_errno",
270 )?;
271 }
272 {
273 self.define_reader_macro(
274 writer,
275 "_actual_field_count(s)",
276 "mol_table_actual_field_count(s)",
277 )?;
278 }
279 {
280 let macro_content = format!("mol_table_has_extra_fields(s, {})", self.fields().len());
281 self.define_reader_macro(writer, "_has_extra_fields(s)", ¯o_content)?;
282 }
283 for (i, f) in self.fields().iter().enumerate() {
284 let macro_sig_tail = format!("_get_{}(s)", f.name());
285 let macro_content = format!("mol_table_slice_by_index(s, {})", i);
286 self.define_reader_macro(writer, ¯o_sig_tail, ¯o_content)?;
287 }
288 Ok(())
289 }
290
291 fn gen_reader_function_verify<W: io::Write>(&self, o: &mut W) -> io::Result<()> {
292 let func_name = format!("{}_verify", self.reader_prefix());
293 let api_decorator = self.api_decorator();
294 let fc = self.fields().len();
295 w!(
296 o,
297 "{} mol_errno {} (const mol_seg_t *input, bool compatible) {{",
298 api_decorator,
299 func_name
300 );
301 w!(o, " if (input->size < MOL_NUM_T_SIZE) {{ ");
302 w!(o, " return MOL_ERR_HEADER; ");
303 w!(o, " }} ");
304 w!(o, " uint8_t *ptr = input->ptr; ");
305 w!(o, " mol_num_t total_size = mol_unpack_number(ptr); ");
306 w!(o, " if (input->size != total_size) {{ ");
307 w!(o, " return MOL_ERR_TOTAL_SIZE; ");
308 w!(o, " }} ");
309 if self.fields().is_empty() {
310 w!(o, " if (input->size == MOL_NUM_T_SIZE) {{ ");
311 w!(o, " return MOL_OK; ");
312 w!(o, " }} ");
313 }
314 w!(o, " if (input->size < MOL_NUM_T_SIZE * 2) {{ ");
315 w!(o, " return MOL_ERR_HEADER; ");
316 w!(o, " }} ");
317 w!(o, " ptr += MOL_NUM_T_SIZE; ");
318 w!(o, " mol_num_t offset = mol_unpack_number(ptr); ");
319 w!(o, " if (offset % 4 > 0 || offset < MOL_NUM_T_SIZE*2) {{");
320 w!(o, " return MOL_ERR_OFFSET; ");
321 w!(o, " }} ");
322 w!(o, " mol_num_t field_count = offset / 4 - 1; ");
323 w!(o, " if (field_count < {}) {{ ", fc);
324 w!(o, " return MOL_ERR_FIELD_COUNT; ");
325 w!(o, " }} else if (!compatible && field_count > {}) {{", fc);
326 w!(o, " return MOL_ERR_FIELD_COUNT; ");
327 w!(o, " }} ");
328 w!(o, " if (input->size < MOL_NUM_T_SIZE*(field_count+1)){{");
329 w!(o, " return MOL_ERR_HEADER; ");
330 w!(o, " }} ");
331 w!(o, " mol_num_t offsets[field_count+1]; ");
332 w!(o, " offsets[0] = offset; ");
333 w!(o, " for (mol_num_t i=1; i<field_count; i++) {{ ");
334 w!(o, " ptr += MOL_NUM_T_SIZE; ");
335 w!(o, " offsets[i] = mol_unpack_number(ptr); ");
336 w!(o, " if (offsets[i-1] > offsets[i]) {{ ");
337 w!(o, " return MOL_ERR_OFFSET; ");
338 w!(o, " }} ");
339 w!(o, " }} ");
340 w!(o, " if (offsets[field_count-1] > total_size) {{ ");
341 w!(o, " return MOL_ERR_OFFSET; ");
342 w!(o, " }} ");
343 if !self.fields().is_empty() {
344 w!(o, " offsets[field_count] = total_size; ");
345 if self.fields().iter().any(|field| !field.typ().is_byte()) {
346 w!(o, " mol_seg_t inner; ");
347 w!(o, " mol_errno errno; ");
348 }
349 for (i, field) in self.fields().iter().enumerate() {
350 let j = i + 1;
351 if field.typ().is_byte() {
352 w!(o, " if (offsets[{}] - offsets[{}] != 1) {{ ", j, i);
353 w!(o, " return MOL_ERR_DATA; ");
354 w!(o, " }} ");
355 } else {
356 let f = format!("{}_verify", field.typ().reader_prefix());
357 w!(o, " inner.ptr = input->ptr + offsets[{}]; ", i);
358 w!(o, " inner.size = offsets[{}] - offsets[{}]; ", j, i);
359 w!(o, " if (mol_contained_by(&inner, input)!=MOL_OK) {{");
360 w!(o, " return MOL_ERR_OFFSET; ");
361 w!(o, " }} ");
362 w!(o, " errno = {}(&inner, compatible); ", f);
363 w!(o, " if (errno != MOL_OK) {{ ");
364 w!(o, " return MOL_ERR_DATA; ");
365 w!(o, " }} ");
366 }
367 }
368 }
369 w!(o, " return MOL_OK; ");
370 w!(o, "}} ");
371 Ok(())
372 }
373}
374
375impl GenReader for ast::TopDecl {
376 fn gen_reader_interfaces_internal<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
377 match self {
378 ast::TopDecl::Option_(ref i) => i.gen_reader_interfaces_internal(writer),
379 ast::TopDecl::Union(ref i) => i.gen_reader_interfaces_internal(writer),
380 ast::TopDecl::Array(ref i) => i.gen_reader_interfaces_internal(writer),
381 ast::TopDecl::Struct(ref i) => i.gen_reader_interfaces_internal(writer),
382 ast::TopDecl::FixVec(ref i) => i.gen_reader_interfaces_internal(writer),
383 ast::TopDecl::DynVec(ref i) => i.gen_reader_interfaces_internal(writer),
384 ast::TopDecl::Table(ref i) => i.gen_reader_interfaces_internal(writer),
385 ast::TopDecl::Primitive(_) => unreachable!(),
386 }
387 }
388
389 fn gen_reader_function_verify<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
390 match self {
391 ast::TopDecl::Option_(ref i) => i.gen_reader_function_verify(writer),
392 ast::TopDecl::Union(ref i) => i.gen_reader_function_verify(writer),
393 ast::TopDecl::Array(ref i) => i.gen_reader_function_verify(writer),
394 ast::TopDecl::Struct(ref i) => i.gen_reader_function_verify(writer),
395 ast::TopDecl::FixVec(ref i) => i.gen_reader_function_verify(writer),
396 ast::TopDecl::DynVec(ref i) => i.gen_reader_function_verify(writer),
397 ast::TopDecl::Table(ref i) => i.gen_reader_function_verify(writer),
398 ast::TopDecl::Primitive(_) => unreachable!(),
399 }
400 }
401}