• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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