1 extern crate bitstream_io;
2 use bitstream_io::huffman::{compile_read_tree, compile_write_tree, HuffmanTreeError};
3
4 #[test]
test_huffman_errors()5 fn test_huffman_errors() {
6 use bitstream_io::BE;
7
8 let empty: Vec<(i32, Vec<u8>)> = Vec::new();
9 assert!(if let Err(err) = compile_read_tree::<BE, i32>(empty) {
10 err == HuffmanTreeError::MissingLeaf
11 } else {
12 false
13 });
14
15 assert!(
16 if let Err(err) = compile_read_tree::<BE, u32>(vec![(0u32, vec![0, 1, 2])]) {
17 err == HuffmanTreeError::InvalidBit
18 } else {
19 false
20 }
21 );
22
23 assert!(if let Err(err) =
24 compile_read_tree::<BE, u32>(vec![(0u32, vec![1]), (1u32, vec![0, 1])])
25 {
26 err == HuffmanTreeError::MissingLeaf
27 } else {
28 false
29 });
30
31 assert!(if let Err(err) = compile_read_tree::<BE, u32>(vec![
32 (0u32, vec![1]),
33 (1u32, vec![0, 1]),
34 (2u32, vec![0, 0]),
35 (3u32, vec![0, 0]),
36 ]) {
37 err == HuffmanTreeError::DuplicateLeaf
38 } else {
39 false
40 });
41
42 assert!(if let Err(err) = compile_read_tree::<BE, u32>(vec![
43 (0u32, vec![1]),
44 (1u32, vec![0]),
45 (2u32, vec![0, 0]),
46 (3u32, vec![0, 1]),
47 ]) {
48 err == HuffmanTreeError::OrphanedLeaf
49 } else {
50 false
51 });
52
53 assert!(
54 if let Err(err) = compile_write_tree::<BE, u32>(vec![(0, vec![1, 1, 2])]) {
55 err == HuffmanTreeError::InvalidBit
56 } else {
57 false
58 }
59 );
60 }
61
62 #[test]
test_huffman_values()63 fn test_huffman_values() {
64 use bitstream_io::huffman::compile_read_tree;
65 use bitstream_io::{BigEndian, BitReader, HuffmanRead};
66 use std::io::Cursor;
67 use std::ops::Deref;
68 use std::rc::Rc;
69
70 let data = [0xB1, 0xED];
71
72 // we can lookup values that aren't just integers also
73 let tree = compile_read_tree(vec![
74 (Some(0), vec![0]),
75 (Some(1), vec![1, 0]),
76 (Some(2), vec![1, 1, 0]),
77 (None, vec![1, 1, 1]),
78 ])
79 .unwrap();
80 let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
81 assert_eq!(r.read_huffman(&tree).unwrap(), Some(1));
82 assert_eq!(r.read_huffman(&tree).unwrap(), Some(2));
83 assert_eq!(r.read_huffman(&tree).unwrap(), Some(0));
84 assert_eq!(r.read_huffman(&tree).unwrap(), Some(0));
85 assert_eq!(r.read_huffman(&tree).unwrap(), None);
86
87 // we can even lookup potentially large values,
88 // preferably using Rc to avoid making copies of each one
89 let tree = compile_read_tree(vec![
90 (Rc::new("foo".to_owned()), vec![0]),
91 (Rc::new("bar".to_owned()), vec![1, 0]),
92 (Rc::new("baz".to_owned()), vec![1, 1, 0]),
93 (Rc::new("kelp".to_owned()), vec![1, 1, 1]),
94 ])
95 .unwrap();
96 let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
97 assert_eq!(r.read_huffman(&tree).unwrap().deref(), "bar");
98 assert_eq!(r.read_huffman(&tree).unwrap().deref(), "baz");
99 assert_eq!(r.read_huffman(&tree).unwrap().deref(), "foo");
100 assert_eq!(r.read_huffman(&tree).unwrap().deref(), "foo");
101 assert_eq!(r.read_huffman(&tree).unwrap().deref(), "kelp");
102 }
103
104 #[test]
test_lengthy_huffman_values()105 fn test_lengthy_huffman_values() {
106 use bitstream_io::huffman::{compile_read_tree, compile_write_tree};
107 use bitstream_io::{BitReader, BitWrite, BitWriter, HuffmanRead, HuffmanWrite, BE, LE};
108 use std::io::Cursor;
109
110 let max_bits = 70;
111 let mut spec = Vec::new();
112 for bits in 0..max_bits {
113 let mut entry = Vec::new();
114 for _ in 0..bits {
115 entry.push(0);
116 }
117 entry.push(1);
118 spec.push((Some(bits), entry));
119 }
120 let mut entry = Vec::new();
121 for _ in 0..max_bits {
122 entry.push(0);
123 }
124 spec.push((None, entry));
125
126 let read_tree_be = compile_read_tree::<BE, Option<i32>>(spec.clone()).unwrap();
127 let write_tree_be = compile_write_tree::<BE, Option<i32>>(spec.clone()).unwrap();
128 let read_tree_le = compile_read_tree::<LE, Option<i32>>(spec.clone()).unwrap();
129 let write_tree_le = compile_write_tree::<LE, Option<i32>>(spec).unwrap();
130
131 let mut data_be = Vec::new();
132 let mut data_le = Vec::new();
133 {
134 let mut writer_be = BitWriter::new(&mut data_be);
135 let mut writer_le = BitWriter::new(&mut data_le);
136 for _ in 0..20 {
137 for bits in 0..max_bits {
138 writer_be.write_huffman(&write_tree_be, Some(bits)).unwrap();
139 writer_le.write_huffman(&write_tree_le, Some(bits)).unwrap();
140 }
141 }
142 writer_be.byte_align().unwrap();
143 writer_le.byte_align().unwrap();
144 }
145 {
146 let mut cursor_be = Cursor::new(&data_be);
147 let mut cursor_le = Cursor::new(&data_le);
148 let mut reader_be = BitReader::new(&mut cursor_be);
149 let mut reader_le = BitReader::new(&mut cursor_le);
150 for _ in 0..20 {
151 for bits in 0..max_bits {
152 assert_eq!(reader_be.read_huffman(&read_tree_be).unwrap(), Some(bits));
153 assert_eq!(reader_le.read_huffman(&read_tree_le).unwrap(), Some(bits));
154 }
155 }
156 }
157 }
158