use std::io;
pub fn encode_u32(n: u32) -> u32 {
assert!(n < 0x1000_0000);
let mut x: u32 = n & 0x7F | (n & 0xFFFF_FF80) << 1;
x = x & 0x7FFF | (x & 0xFFFF_8000) << 1;
x = x & 0x7F_FFFF | (x & 0xFF80_0000) << 1;
x
}
pub fn decode_u32(n: u32) -> u32 {
n & 0xFF | (n & 0xFF00) >> 1 | (n & 0xFF_0000) >> 2 | (n & 0xFF00_0000) >> 3
}
pub struct Reader<R>
where
R: io::Read,
{
reader: R,
buf: [u8; 8192],
next: usize,
available: usize,
discard_next_null_byte: bool,
}
impl<R> Reader<R>
where
R: io::Read,
{
pub fn new(reader: R) -> Reader<R> {
Reader {
reader,
buf: [0; 8192],
next: 0,
available: 0,
discard_next_null_byte: false,
}
}
}
impl<R> io::Read for Reader<R>
where
R: io::Read,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let mut i = 0;
while i < buf.len() {
assert!(self.next <= self.available);
if self.next == self.available {
self.available = self.reader.read(&mut self.buf)?;
self.next = 0;
if self.available == 0 {
break;
}
}
if self.discard_next_null_byte && self.buf[self.next] == 0x00 {
self.discard_next_null_byte = false;
self.next += 1;
continue;
}
self.discard_next_null_byte = false;
buf[i] = self.buf[self.next];
i += 1;
if self.buf[self.next] == 0xff {
self.discard_next_null_byte = true;
}
self.next += 1;
}
Ok(i)
}
}
pub fn encode_vec(buffer: &mut Vec<u8>) {
let mut repeat_next_null_byte = false;
let mut i = 0;
while i < buffer.len() {
if buffer[i] == 0x00 && repeat_next_null_byte {
buffer.insert(i, 0);
i += 1;
}
repeat_next_null_byte = buffer[i] == 0xFF;
i += 1;
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::mem;
fn decode_vec(buffer: &mut Vec<u8>) {
let buf_len = buffer.len();
let from_buf = mem::replace(buffer, Vec::with_capacity(buf_len));
let mut reader = Reader::new(io::Cursor::new(from_buf));
io::copy(&mut reader, buffer).unwrap();
}
#[test]
fn synchsafe() {
for i in 0..1 << 26 {
assert_eq!(i, decode_u32(encode_u32(i)));
}
assert_eq!(0x7f7f7f7f, encode_u32(0x0fff_ffff));
assert_eq!(0x0fff_ffff, decode_u32(0x7f7f7f7f));
}
#[test]
fn synchronization() {
let mut v = vec![66, 0, 255, 0, 255, 0, 0, 255, 66];
encode_vec(&mut v);
assert_eq!(v, [66, 0, 255, 0, 0, 255, 0, 0, 0, 255, 66]);
decode_vec(&mut v);
assert_eq!(v, [66, 0, 255, 0, 255, 0, 0, 255, 66]);
}
#[test]
fn synchronization_jpeg() {
let orig = vec![
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x02,
0x00, 0x76,
];
let mut recoded = orig.clone();
encode_vec(&mut recoded);
decode_vec(&mut recoded);
assert_eq!(orig, recoded);
}
#[test]
fn synchronization_large() {
let mut orig = Vec::new();
for i in 0..1_000_000 {
orig.push(0xff);
orig.push(i as u8);
}
let mut recoded = orig.clone();
encode_vec(&mut recoded);
decode_vec(&mut recoded);
assert_eq!(orig, recoded);
}
}