1#[derive(Debug)]
6pub enum SResult<Output = (), Error = ()> {
7 Done(usize, Output),
10
11 Needed(usize),
14
15 Error(Error),
17}
18
19impl<Output, Error> SResult<Output, Error> {
20 pub fn is_done(&self) -> bool {
21 match *self {
22 SResult::Done(_, _) => true,
23 _ => false,
24 }
25 }
26
27 pub fn is_needed(&self) -> bool {
28 match *self {
29 SResult::Needed(_) => true,
30 _ => false,
31 }
32 }
33
34 pub fn is_err(&self) -> bool {
35 match *self {
36 SResult::Error(_) => true,
37 _ => false,
38 }
39 }
40
41 pub fn done(self) -> Option<(usize, Output)> {
42 match self {
43 SResult::Done(offset, out) => Some((offset, out)),
44 _ => None,
45 }
46 }
47
48 pub fn needed(self) -> Option<usize> {
49 match self {
50 SResult::Needed(bytes) => Some(bytes),
51 _ => None,
52 }
53 }
54
55 pub fn err(self) -> Option<Error> {
56 match self {
57 SResult::Error(err) => Some(err),
58 _ => None,
59 }
60 }
61}
62
63#[macro_export]
65macro_rules! stream_done {
66 ($bytes:expr, $out:expr) => {
67 return SResult::Done($bytes, $out)
68 };
69 ($bytes:expr) => {
70 stream_done!($bytes, ())
71 };
72}
73
74#[macro_export]
76macro_rules! stream_len_cond {
77 ($buf:expr, $bytes:expr) => {
78 if $buf.len() < $bytes {
79 return SResult::Needed($bytes);
80 }
81 };
82}
83
84#[macro_export]
86macro_rules! stream_err {
87 ($err:expr) => {
88 return SResult::Error($err)
89 };
90 () => {
91 stream_err!(())
92 };
93}
94
95#[macro_export]
97macro_rules! stream_cond {
98 ($cond:expr, $err:expr) => {
99 if !$cond {
100 return SResult::Error($err);
101 }
102 };
103 ($cond:expr) => {
104 stream_cond!($cond, ());
105 };
106}
107
108#[macro_export]
111macro_rules! stream_from_option {
112 ($opt:expr, $err:expr) => {
113 match $opt {
114 Some(opt) => opt,
115 None => stream_err!($err),
116 }
117 };
118 ($opt:expr) => {
119 stream_from_option!($opt, ())
120 };
121}
122
123#[macro_export]
172macro_rules! enc_try {
173 ($result:expr, $offset:expr) => {
174 match $result {
175 SResult::Done(offset, out) => ($offset + offset, out),
176 SResult::Needed(bytes) => { return SResult::Needed($offset + bytes); }
177 SResult::Error(error) => { return SResult::Error(error); }
178 }
179 };
180 ($result:expr)
181 => { enc_try!($result, 0) };
182 ($buf:expr, $offset:expr; $fun:expr)
183 => { enc_try!($fun(&mut $buf[$offset..]), $offset) };
184 ($buf:expr, $offset:expr; $fun:expr, $($args:expr),+)
185 => { enc_try!($fun(&mut $buf[$offset..], $($args),+), $offset) };
186 ($buf:expr, $offset:expr; $object:expr; $fun:ident)
187 => { enc_try!($object.$fun(&mut $buf[$offset..]), $offset) };
188 ($buf:expr, $offset:expr; $object:expr; $fun:ident, $($args:expr),+)
189 => { enc_try!($object.$fun(&mut $buf[$offset..], $($args),+), $offset) };
190 ($buf:expr; $($tts:tt)+)
191 => { enc_try!($buf, 0; $($tts)+) };
192}
193
194#[macro_export]
200macro_rules! enc_consume {
201 ($($tts:tt)*) => { {
202 let (offset, _) = enc_try!($($tts)*);
203 offset
204 } };
205}
206
207#[macro_export]
210macro_rules! dec_try {
211 ($result:expr, $offset:expr) => {
212 match $result {
213 SResult::Done(offset, out) => ($offset + offset, out),
214 SResult::Needed(bytes) => { return SResult::Needed($offset + bytes); }
215 SResult::Error(error) => { return SResult::Error(error); }
216 }
217 };
218 ($result:expr)
219 => { dec_try!($result, 0) };
220 ($buf:expr, $offset:expr; $fun:expr)
221 => { dec_try!($fun(&$buf[$offset..]), $offset) };
222 ($buf:expr, $offset:expr; $fun:expr, $($args:expr),+)
223 => { dec_try!($fun(&$buf[$offset..], $($args),+), $offset) };
224 ($buf:expr, $offset:expr; $object:expr; $fun:ident)
225 => { dec_try!($object.$fun(&$buf[$offset..]), $offset) };
226 ($buf:expr, $offset:expr; $object:expr; $fun:ident, $($args:expr),+)
227 => { dec_try!($object.$fun(&$buf[$offset..], $($args),+), $offset) };
228 ($buf:expr; $($tts:tt)+)
229 => { dec_try!($buf, 0; $($tts)+) };
230}
231
232#[macro_export]
234macro_rules! dec_consume {
235 ($($tts:tt)*) => { {
236 let (offset, _) = dec_try!($($tts)*);
237 offset
238 } };
239}
240
241pub fn encode_u8(buf: &mut [u8], b: u8) -> SResult {
242 stream_len_cond!(buf, 1);
243 buf[0] = b;
244 stream_done!(1);
245}
246
247pub fn encode_u16(buf: &mut [u8], b: u16) -> SResult {
248 stream_len_cond!(buf, 2);
249 buf[0] = (b >> 8) as u8;
250 buf[1] = b as u8;
251 stream_done!(2);
252}
253
254pub fn encode_u32(buf: &mut [u8], b: u32) -> SResult {
255 stream_len_cond!(buf, 4);
256 buf[0] = (b >> 24) as u8;
257 buf[1] = (b >> 16) as u8;
258 buf[2] = (b >> 8) as u8;
259 buf[3] = b as u8;
260 stream_done!(4);
261}
262
263pub fn encode_bytes(buf: &mut [u8], bs: &[u8]) -> SResult {
264 stream_len_cond!(buf, bs.len());
265 buf[..bs.len()].copy_from_slice(bs);
266 stream_done!(bs.len());
267}
268
269pub fn encode_bytes_be(buf: &mut [u8], bs: &[u8]) -> SResult {
271 stream_len_cond!(buf, bs.len());
272 for (i, b) in bs.iter().rev().enumerate() {
273 buf[i] = *b;
274 }
275 stream_done!(bs.len());
276}
277
278pub fn decode_u8(buf: &[u8]) -> SResult<u8> {
279 stream_len_cond!(buf, 1);
280 stream_done!(1, buf[0]);
281}
282
283pub fn decode_u16(buf: &[u8]) -> SResult<u16> {
284 stream_len_cond!(buf, 2);
285 stream_done!(2, (buf[0] as u16) << 8 | (buf[1] as u16));
286}
287
288pub fn decode_u32(buf: &[u8]) -> SResult<u32> {
289 stream_len_cond!(buf, 4);
290 let b = (buf[0] as u32) << 24 | (buf[1] as u32) << 16 | (buf[2] as u32) << 8 | (buf[3] as u32);
291 stream_done!(4, b);
292}
293
294pub fn decode_bytes(buf: &[u8], out: &mut [u8]) -> SResult {
295 stream_len_cond!(buf, out.len());
296 let len = out.len();
297 out.copy_from_slice(&buf[..len]);
298 stream_done!(out.len());
299}
300
301pub fn decode_bytes_be(buf: &[u8], out: &mut [u8]) -> SResult {
303 stream_len_cond!(buf, out.len());
304 for (i, b) in buf[..out.len()].iter().rev().enumerate() {
305 out[i] = *b;
306 }
307 stream_done!(out.len());
308}