in shed/netstring/src/decode.rs [59:125]
fn decode_buf<'a>(&mut self, buf: &'a [u8]) -> Result<(usize, Option<(bool, Slice)>)> {
let mut consumed = 0;
loop {
let state = self
.state
.take()
.ok_or(ErrorKind::NetstringDecode("bad state"))?;
let buf = &buf[consumed..];
let (next, ret): (State, Option<Option<(bool, Slice)>>) = match state {
State::Num(mut cur) => {
let mut next = None;
for (idx, inp) in buf.iter().enumerate() {
match *inp {
digit @ b'0'..=b'9' => cur = cur * 10 + ((digit - b'0') as usize),
b':' => {
next = Some((idx + 1, State::Body(cur)));
break;
}
_ => bail!(ErrorKind::NetstringDecode("Bad character in payload size")),
}
}
if let Some((eaten, next)) = next {
// We got a complete length, so we can continue without returning
// anything.
consumed += eaten;
(next, None)
} else {
// Partial input number - consume what we have then return indicating
// we need more.
consumed += buf.len();
(State::Num(cur), Some(None))
}
}
State::Body(len) => {
// length of payload + ','
if buf.len() > len {
// We have up to the end of the buffer, so we can return it and
// start expecting the next buffer.
let v = Slice::new(consumed, len);
ensure!(buf[len] == b',', ErrorKind::NetstringDecode("missing ','"));
consumed += len + 1;
(State::Num(0), Some(Some((true, v))))
} else {
// Consume as much of the input as we can, and leave the state set up
// to handle the rest as it arrives.
let v = Slice::new(consumed, buf.len());
consumed += v.len();
(State::Body(len - v.len()), Some(Some((false, v))))
}
}
};
self.state = Some(next);
if let Some(ret) = ret {
return Ok((consumed, ret));
}
}
}