|
| 1 | +use super::prelude::*; |
| 2 | + |
| 3 | +#[derive(Debug)] |
| 4 | +pub struct x<'a> { |
| 5 | + pub addr: &'a [u8], |
| 6 | + pub len: usize, |
| 7 | + |
| 8 | + /// Reuse PacketBuf underlying buffer to read the binary data into it |
| 9 | + pub buf: &'a mut [u8], |
| 10 | +} |
| 11 | + |
| 12 | +impl<'a> ParseCommand<'a> for x<'a> { |
| 13 | + #[inline(always)] |
| 14 | + fn from_packet(buf: PacketBuf<'a>) -> Option<Self> { |
| 15 | + // the total packet buffer currently looks like: |
| 16 | + // |
| 17 | + // +------+--------------------+-------------------+-------+-----------------+ |
| 18 | + // | "$x" | addr (hex-encoded) | len (hex-encoded) | "#XX" | empty space ... | |
| 19 | + // +------+--------------------+-------------------+-------+-----------------+ |
| 20 | + // |
| 21 | + // Unfortunately, while `len` can be hex-decoded right here and now into a |
| 22 | + // `usize`, `addr` corresponds to a Target::Arch::Usize, which requires holding |
| 23 | + // on to a valid &[u8] reference into the buffer. |
| 24 | + // |
| 25 | + // While it's not _perfectly_ efficient, simply leaving the decoded addr in |
| 26 | + // place and wasting a couple bytes is probably the easiest way to tackle this |
| 27 | + // problem: |
| 28 | + // |
| 29 | + // +------+------------------+------------------------------------------------+ |
| 30 | + // | "$x" | addr (raw bytes) | usable buffer ... | |
| 31 | + // +------+------------------+------------------------------------------------+ |
| 32 | + |
| 33 | + let (buf, body_range) = buf.into_raw_buf(); |
| 34 | + let body = buf.get_mut(body_range.start..body_range.end)?; |
| 35 | + |
| 36 | + let mut body = body.split_mut(|b| *b == b','); |
| 37 | + |
| 38 | + let addr = decode_hex_buf(body.next()?).ok()?; |
| 39 | + let addr_len = addr.len(); |
| 40 | + let len = decode_hex(body.next()?).ok()?; |
| 41 | + |
| 42 | + // ensures that `split_at_mut` doesn't panic |
| 43 | + if buf.len() < body_range.start + addr_len { |
| 44 | + return None; |
| 45 | + } |
| 46 | + |
| 47 | + let (addr, buf) = buf.split_at_mut(body_range.start + addr_len); |
| 48 | + let addr = addr.get(b"$x".len()..)?; |
| 49 | + |
| 50 | + Some(x { addr, len, buf }) |
| 51 | + } |
| 52 | +} |
0 commit comments