1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: AGPL-3.0-or-later
3 // There is NO WARRANTY.
7 pub static SLIP_END_SLICE: &[u8] = &[SLIP_END];
10 pub fn check_checkmtu_mimeswap<const TO_MIME: bool>
11 (mtu: u32, data: &mut [u8])
13 // eprintln!("before: {:?}", DumpHex(data));
15 for mut packet in data.split_mut(|&c| c == SLIP_END) {
16 if packet.len() > mtu.sat() {
17 throw!(anyhow!("mtu exceeded ({} > {})", packet.len(), mtu));
20 while let Some((i, _)) = packet.iter().enumerate().find(
21 |(_,&c)| c == if TO_MIME { SLIP_ESC } else { SLIP_MIME_ESC }
23 packet[i] = if TO_MIME { SLIP_MIME_ESC } else { SLIP_ESC };
24 match packet.get(i+1) {
26 Some(&SLIP_ESC_ESC) => Ok(()),
27 _ => Err(anyhow!("SLIP escape not followed by ESC_END or ESC_ESC")),
29 packet = &mut packet[i+2 ..];
33 // eprintln!(" after: {:?}", DumpHex(data));
36 pub type Frame = Vec<u8>;
37 pub type FramesData = Vec<Vec<u8>>;
45 impl Debug for Frames {
47 fn fmt(&self, f: &mut fmt::Formatter) {
48 write!(f, "Frames{{n={},len={}}}", &self.frames.len(), &self.total_len)?;
54 pub fn add(&mut self, max: u32, frame: Frame) {
55 if frame.len() == 0 { return }
56 let new_total = self.total_len + frame.len() + 1;
57 if new_total > max.sat() { throw!(frame) }
58 self.total_len = new_total;
59 self.frames.push(frame);
63 impl From<Frames> for FramesData {
64 fn from(frames: Frames) -> FramesData { frames.frames }
67 pub struct DumpHex<'b>(pub &'b [u8]);
68 impl Debug for DumpHex<'_> {
70 fn fmt(&self, f: &mut fmt::Formatter) {
71 for v in self.0 { write!(f, "{:02x}", v)?; }
76 fn mime_slip_to_mime() {
77 fn chk(i: &[u8], exp: Result<&[u8], &str>) {
78 let mut p = i.to_owned();
79 match (exp, check_checkmtu_mimeswap::<true>(10, p.as_mut())) {
80 (Ok(exp), Ok(())) => assert_eq!( exp, &p ),
81 (Err(exp), Err(got)) => assert!( got.to_string().contains(exp) ),
82 x => panic!("? {:?}", x),
86 chk( &[ SLIP_END, SLIP_ESC, SLIP_ESC_END, b'-', b'X' ],
87 Ok(&[ SLIP_END, b'-', SLIP_ESC_END, SLIP_ESC, b'X' ]) );
89 chk( &[ SLIP_END, SLIP_ESC, b'y' ], Err("SLIP escape") );