extern crate bitstream_io;
use bitstream_io::huffman::{compile_read_tree,
compile_write_tree,
HuffmanTreeError};
#[test]
fn test_huffman_errors() {
use bitstream_io::BE;
let empty: Vec<(i32, Vec<u8>)> = Vec::new();
assert!(
if let Err(err) = compile_read_tree::<BE,i32>(empty) {
err == HuffmanTreeError::MissingLeaf
} else {false}
);
assert!(
if let Err(err) = compile_read_tree::<BE,u32>(
vec![(0u32, vec![0,1,2])]) {
err == HuffmanTreeError::InvalidBit
} else {false}
);
assert!(
if let Err(err) = compile_read_tree::<BE,u32>(
vec![(0u32, vec![1]), (1u32, vec![0, 1])]) {
err == HuffmanTreeError::MissingLeaf
} else {false}
);
assert!(
if let Err(err) = compile_read_tree::<BE,u32>(
vec![(0u32, vec![1]),
(1u32, vec![0, 1]),
(2u32, vec![0, 0]),
(3u32, vec![0, 0])]) {
err == HuffmanTreeError::DuplicateLeaf
} else {false}
);
assert!(
if let Err(err) = compile_read_tree::<BE,u32>(
vec![(0u32, vec![1]),
(1u32, vec![0]),
(2u32, vec![0, 0]),
(3u32, vec![0, 1])]) {
err == HuffmanTreeError::OrphanedLeaf
} else {false}
);
assert!(
if let Err(err) = compile_write_tree::<BE,u32>(
vec![(0, vec![1,1,2])]) {
err == HuffmanTreeError::InvalidBit
} else {false}
);
}
#[test]
fn test_huffman_values() {
use std::io::Cursor;
use std::ops::Deref;
use std::rc::Rc;
use bitstream_io::{BE, BitReader};
use bitstream_io::huffman::compile_read_tree;
let data = [0xB1, 0xED];
{
let tree = compile_read_tree(
vec![(Some(0), vec![0]),
(Some(1), vec![1, 0]),
(Some(2), vec![1, 1, 0]),
(None, vec![1, 1, 1])]).unwrap();
let mut c = Cursor::new(&data);
let mut r = BitReader::<BE>::new(&mut c);
assert_eq!(r.read_huffman(&tree).unwrap(), Some(1));
assert_eq!(r.read_huffman(&tree).unwrap(), Some(2));
assert_eq!(r.read_huffman(&tree).unwrap(), Some(0));
assert_eq!(r.read_huffman(&tree).unwrap(), Some(0));
assert_eq!(r.read_huffman(&tree).unwrap(), None);
}
{
let tree = compile_read_tree(
vec![(Rc::new("foo".to_owned()), vec![0]),
(Rc::new("bar".to_owned()), vec![1, 0]),
(Rc::new("baz".to_owned()), vec![1, 1, 0]),
(Rc::new("kelp".to_owned()), vec![1, 1, 1])]).unwrap();
let mut c = Cursor::new(&data);
let mut r = BitReader::<BE>::new(&mut c);
assert_eq!(r.read_huffman(&tree).unwrap().deref(), "bar");
assert_eq!(r.read_huffman(&tree).unwrap().deref(), "baz");
assert_eq!(r.read_huffman(&tree).unwrap().deref(), "foo");
assert_eq!(r.read_huffman(&tree).unwrap().deref(), "foo");
assert_eq!(r.read_huffman(&tree).unwrap().deref(), "kelp");
}
}
#[test]
fn test_lengthy_huffman_values() {
use std::io::Cursor;
use bitstream_io::{BE, LE, BitReader, BitWriter};
use bitstream_io::huffman::{compile_read_tree, compile_write_tree};
let max_bits = 70;
let mut spec = Vec::new();
for bits in 0..max_bits {
let mut entry = Vec::new();
for _ in 0..bits {
entry.push(0);
}
entry.push(1);
spec.push((Some(bits), entry));
}
let mut entry = Vec::new();
for _ in 0..max_bits {
entry.push(0);
}
spec.push((None, entry));
let read_tree_be =
compile_read_tree::<BE,Option<i32>>(spec.clone()).unwrap();
let write_tree_be =
compile_write_tree::<BE,Option<i32>>(spec.clone()).unwrap();
let read_tree_le =
compile_read_tree::<LE,Option<i32>>(spec.clone()).unwrap();
let write_tree_le =
compile_write_tree::<LE,Option<i32>>(spec).unwrap();
let mut data_be = Vec::new();
let mut data_le = Vec::new();
{
let mut writer_be = BitWriter::new(&mut data_be);
let mut writer_le = BitWriter::new(&mut data_le);
for _ in 0..20 {
for bits in 0..max_bits {
writer_be.write_huffman(&write_tree_be, Some(bits)).unwrap();
writer_le.write_huffman(&write_tree_le, Some(bits)).unwrap();
}
}
writer_be.byte_align().unwrap();
writer_le.byte_align().unwrap();
}
{
let mut cursor_be = Cursor::new(&data_be);
let mut cursor_le = Cursor::new(&data_le);
let mut reader_be = BitReader::new(&mut cursor_be);
let mut reader_le = BitReader::new(&mut cursor_le);
for _ in 0..20 {
for bits in 0..max_bits {
assert_eq!(reader_be.read_huffman(&read_tree_be).unwrap(),
Some(bits));
assert_eq!(reader_le.read_huffman(&read_tree_le).unwrap(),
Some(bits));
}
}
}
}