1 use crate::protocol::commands::ParseCommand; 2 use crate::protocol::common::hex::decode_hex; 3 use crate::protocol::packet::PacketBuf; 4 5 /// Parse the `annex` field of a qXfer packet. Used in conjunction with 6 /// `QXferBase` to cut keep qXfer packet parsing DRY. 7 pub trait ParseAnnex<'a>: Sized { from_buf(buf: &'a [u8]) -> Option<Self>8 fn from_buf(buf: &'a [u8]) -> Option<Self>; 9 } 10 11 #[derive(Debug)] 12 pub struct QXferReadBase<'a, T: ParseAnnex<'a>> { 13 pub annex: T, 14 pub offset: u64, 15 pub length: usize, 16 17 pub buf: &'a mut [u8], 18 } 19 20 impl<'a, T: ParseAnnex<'a>> ParseCommand<'a> for QXferReadBase<'a, T> { 21 #[inline(always)] from_packet(buf: PacketBuf<'a>) -> Option<Self>22 fn from_packet(buf: PacketBuf<'a>) -> Option<Self> { 23 let (buf, body_range) = buf.into_raw_buf(); 24 25 // this looks a bit wacky, but the compiler is dumb and won't elide bounds 26 // checks without it. 27 let (body, buf) = { 28 let buf = buf.get_mut(body_range.start..)?; 29 if body_range.end - body_range.start > buf.len() { 30 return None; 31 } 32 buf.split_at_mut(body_range.end - body_range.start) 33 }; 34 35 if body.is_empty() { 36 return None; 37 } 38 39 let mut body = body.split(|b| *b == b':').skip(1); 40 let annex = T::from_buf(body.next()?)?; 41 42 let mut body = body.next()?.split(|b| *b == b','); 43 let offset = decode_hex(body.next()?).ok()?; 44 let length = decode_hex(body.next()?).ok()?; 45 46 Some(QXferReadBase { 47 annex, 48 offset, 49 length, 50 buf, 51 }) 52 } 53 } 54