1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use crate::{END, ESC, ESC_END, ESC_ESC};

pub fn encode(buf: &[u8], sink: &mut dyn std::io::Write) -> std::io::Result<usize> {
    let mut len = sink.write(&[END])?;

    for value in buf.iter() {
        match *value {
            END => {
                len += sink.write(&[ESC, ESC_END])?;
            }
            ESC => {
                len += sink.write(&[ESC, ESC_ESC])?;
            }
            _ => {
                len += sink.write(&[*value])?;
            }
        }
    }

    len += sink.write(&[END])?;

    Ok(len)
}

/// SLIP encoder context
pub struct Encoder {}

impl Encoder {
    /// Creates a new encoder context
    pub fn new() -> Self {
        Self {}
    }

    /// Encodes the given buffer in a SLIP frame and forwards it to the sink.
    ///
    /// # Arguments
    ///
    /// * `buf` - input data buffer for encoding
    /// * `sink` - output object implementing the std::io::Write trait
    ///
    /// Returns the number of bytes written to the sink.
    ///
    pub fn encode(&mut self, buf: &[u8], sink: &mut dyn std::io::Write) -> std::io::Result<usize> {
        encode(buf, sink)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn empty_encode() {
        const EXPECTED: [u8; 2] = [0xc0, 0xc0];
        let mut output = Vec::<u8>::new();

        let mut slip = Encoder::new();
        let len = slip.encode(&[0; 0], &mut output).unwrap();
        assert_eq!(EXPECTED.len(), len);
        assert_eq!(&EXPECTED, output.as_slice());
    }

    #[test]
    fn encode_esc_esc_sequence() {
        const INPUT: [u8; 3] = [0x01, ESC, 0x03];
        const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_ESC, 0x03, 0xc0];
        let mut output = Vec::<u8>::new();

        let mut slip = Encoder::new();
        let len = slip.encode(&INPUT, &mut output).unwrap();
        assert_eq!(EXPECTED.len(), len);
        assert_eq!(&EXPECTED, output.as_slice());
    }

    #[test]
    fn encode_end_esc_sequence() {
        const INPUT: [u8; 3] = [0x01, END, 0x03];
        const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_END, 0x03, 0xc0];
        let mut output = Vec::<u8>::new();

        let mut slip = Encoder::new();
        let len = slip.encode(&INPUT, &mut output).unwrap();
        assert_eq!(EXPECTED.len(), len);
        assert_eq!(&EXPECTED, output.as_slice());
    }
}