From: Ian Jackson Date: Tue, 3 Aug 2021 17:59:17 +0000 (+0100) Subject: introduce slip::check1 X-Git-Tag: hippotat/1.0.0~374 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=b47344addcd8ba004a6c5b5746a5f5259be878ca;p=hippotat.git introduce slip::check1 Signed-off-by: Ian Jackson --- diff --git a/src/slip.rs b/src/slip.rs index 110fc03..b179f54 100644 --- a/src/slip.rs +++ b/src/slip.rs @@ -28,57 +28,15 @@ pub fn check( mtu: u32, data: &[u8], out: &mut OUT, - mut addr_chk: AC, + addr_chk: AC, mut error_handler: EH ) where OUT: Extend>, - AC: FnMut(&[u8]) -> Result<(), PacketError>, + AC: Fn(&[u8]) -> Result<(), PacketError> + Copy, EH: FnMut(PacketError), { // eprintln!("before: {:?}", DumpHex(data)); for packet in data.split(|&c| c == SLIP_END) { - match (||{ - if packet.len() == 0 { - throw!(PacketError::Empty) - } - if packet.len() > mtu.sat() { - throw!(PacketError::MTU { len: packet.len(), mtu }); - } - - let mut packet: Box<[u8]> = packet.to_owned().into(); - let mut walk: &mut [u8] = &mut packet; - let mut header = [0u8; HEADER_FOR_ADDR]; - let mut wheader = &mut header[..]; - - while let Some((i, was_mime)) = walk.iter().enumerate().find_map( - |(i,&c)| match c { - SLIP_ESC => Some((i,false)), - SLIP_MIME_ESC if M::CONV_TO.is_some() => Some((i,true)), - _ => None, - } - ) { - let _ = wheader.write(&walk[0..i]); - if M::CONV_TO.is_some() { - walk[i] = if was_mime { SLIP_ESC } else { SLIP_MIME_ESC }; - } - if Some(was_mime) != M::CONV_TO { - let c = match walk.get(i+1) { - Some(&SLIP_ESC_ESC) => SLIP_ESC, - Some(&SLIP_ESC_END) => SLIP_END, - _ => throw!(PacketError::SLIP), - }; - let _ = wheader.write(&[c]); - walk = &mut walk[i+2 ..]; - } else { - let _ = wheader.write(&[SLIP_MIME_ESC]); - walk = &mut walk[i+1 ..]; - } - } - let _ = wheader.write(walk); - - addr_chk(&header)?; - - Ok(packet) - })() { + match check1::(mtu, packet, addr_chk) { Err(e) => error_handler(e), Ok(packet) => out.extend(iter::once(packet)), } @@ -86,6 +44,57 @@ pub fn check( // eprintln!(" after: {:?}", DumpHex(data)); } +#[throws(PacketError)] +pub fn check1( + mtu: u32, + packet: &[u8], + addr_chk: AC, +) -> Box<[u8]> +where AC: Fn(&[u8]) -> Result<(), PacketError>, +{ + if packet.len() == 0 { + throw!(PacketError::Empty) + } + if packet.len() > mtu.sat() { + throw!(PacketError::MTU { len: packet.len(), mtu }); + } + + let mut packet: Box<[u8]> = packet.to_owned().into(); + let mut walk: &mut [u8] = &mut packet; + let mut header = [0u8; HEADER_FOR_ADDR]; + let mut wheader = &mut header[..]; + + while let Some((i, was_mime)) = walk.iter().enumerate().find_map( + |(i,&c)| match c { + SLIP_ESC => Some((i,false)), + SLIP_MIME_ESC if M::CONV_TO.is_some() => Some((i,true)), + _ => None, + } + ) { + let _ = wheader.write(&walk[0..i]); + if M::CONV_TO.is_some() { + walk[i] = if was_mime { SLIP_ESC } else { SLIP_MIME_ESC }; + } + if Some(was_mime) != M::CONV_TO { + let c = match walk.get(i+1) { + Some(&SLIP_ESC_ESC) => SLIP_ESC, + Some(&SLIP_ESC_END) => SLIP_END, + _ => throw!(PacketError::SLIP), + }; + let _ = wheader.write(&[c]); + walk = &mut walk[i+2 ..]; + } else { + let _ = wheader.write(&[SLIP_MIME_ESC]); + walk = &mut walk[i+1 ..]; + } + } + let _ = wheader.write(walk); + + addr_chk(&header)?; + + packet +} + pub type Frame = Vec; pub type FramesData = Vec>; //pub type Frame = Box<[u8]>;