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