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