base122/
lib.rs

1#[macro_use]
2extern crate log;
3
4#[cfg(test)]
5mod test;
6
7pub const HEADER: u8 = 0b00001111;
8const SHORTENED: u8 = 0b01000000;
9
10const DEFAULT_MIME: &'static str = "image/jpg";
11const ILLEGALS: [u8; 6] = [0, 10, 13, 34, 38, 92];
12
13pub struct Encoder<'a> {
14    data: &'a [u8],
15    bit_index: usize,
16    byte_index: usize,
17}
18
19fn is_illegal(byte: u8) -> Option<u8> {
20    for (index, illegal_byte) in ILLEGALS.iter().enumerate() {
21        if *illegal_byte == byte {
22            return Some(index as u8);
23        }
24    }
25
26    None
27}
28
29fn fmt_buf(data: &[u8]) -> String {
30    let mut s = String::with_capacity(data.len() * 8);
31    for byte in data.iter() {
32        s.push_str(&format!("{:08b}", byte));
33    }
34    s
35}
36
37impl<'a> Encoder<'a> {
38    pub fn new(data: &[u8]) -> Encoder {
39        Encoder {
40            data: data,
41            bit_index: 0,
42            byte_index: 0,
43        }
44    }
45
46    fn get7(&mut self) -> Result<u8, ()> {
47        if self.byte_index < self.data.len() {
48            let first_byte = self.data[self.byte_index];
49            let first_part = (((0b11111110 >> self.bit_index) & first_byte) << self.bit_index) >> 1;
50
51            self.bit_index += 7;
52            if self.bit_index < 8 {
53                Ok(first_part)
54            } else {
55                self.bit_index -= 8;
56                self.byte_index += 1;
57
58                if self.byte_index >= self.data.len() {
59                    Ok(first_part)
60                } else {
61                    let second_byte = self.data[self.byte_index];
62                    let second_part = (((0xFF00u16 >> self.bit_index) as u8 & second_byte) &
63                                       0xFF) >>
64                                      8 - self.bit_index;
65
66                    Ok(first_part | second_part)
67                }
68            }
69        } else {
70            Err(())
71        }
72    }
73
74    pub fn encode(&mut self) -> Vec<u8> {
75        let mut buf = Vec::new();
76        let mut header = HEADER;
77        buf.push(header);
78
79        while let Ok(bits) = self.get7() {
80            if let Some(illegal_index) = is_illegal(bits) {
81                debug!("Handle illegal sequence: {:08b}", bits);
82                let mut b1: u8 = 0b11000010 | (0b111 & illegal_index) << 2;
83                let mut b2: u8 = 0b10000000;
84                if let Ok(next_bits) = self.get7() {
85                    debug!("Additional bits to two - byte character {:08b}", next_bits);
86
87                    let first_bit: u8 = if (next_bits & 0b01000000) > 0 { 1 } else { 0 };
88                    b1 |= first_bit;
89                    b2 |= next_bits & 0b00111111;
90                } else {
91                    debug!("Last seven bits are an illegal sequence, and there are no more bits \
92                            left");
93
94                    header |= SHORTENED;
95                }
96                debug!("Adding to buffer: {:08b}{:08b}", b1, b2);
97                buf.push(b1);
98                buf.push(b2);
99            } else {
100                debug!("Adding to buffer: {:08b}", bits);
101                buf.push(bits);
102            }
103        }
104
105        debug!("Adding header to buffer: {:08b}", header);
106        buf[0] = header;
107
108        debug!("Returning buffer: {}", fmt_buf(&buf));
109        buf
110    }
111}