chiark / gitweb /
introduce slip::check1
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 3 Aug 2021 17:59:17 +0000 (18:59 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 3 Aug 2021 17:59:17 +0000 (18:59 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/slip.rs

index 110fc034636bd9e3970993e79cb56ab0c2ebdcce..b179f540dc9df8d149040b714138d7f402fe1471 100644 (file)
@@ -28,57 +28,15 @@ pub fn check<AC, EH, OUT, M: SlipMime>(
   mtu: u32,
   data: &[u8],
   out: &mut OUT,
-  mut addr_chk: AC,
+  addr_chk: AC,
   mut error_handler: EH
 ) where OUT: Extend<Box<[u8]>>,
-        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::<AC,M>(mtu, packet, addr_chk) {
       Err(e) => error_handler(e),
       Ok(packet) => out.extend(iter::once(packet)),
     }
@@ -86,6 +44,57 @@ pub fn check<AC, EH, OUT, M: SlipMime>(
 //  eprintln!(" after: {:?}", DumpHex(data));
 }
 
+#[throws(PacketError)]
+pub fn check1<AC, M: SlipMime>(
+  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<u8>;
 pub type FramesData = Vec<Vec<u8>>;
 //pub type Frame = Box<[u8]>;