@@ -66,7 +66,7 @@ impl DeflateWriter {
66
66
DeflateHuffmanType :: Static { .. } => {
67
67
self . bitwriter . write ( 1 , 2 , & mut self . output ) ;
68
68
let huffman_writer = HuffmanWriter :: start_fixed_huffman_table ( ) ;
69
- self . encode_block_with_decoder ( tokens, & huffman_writer) ;
69
+ self . encode_huffman ( tokens, & huffman_writer) ;
70
70
}
71
71
DeflateHuffmanType :: Dynamic {
72
72
huffman_encoding, ..
@@ -77,7 +77,7 @@ impl DeflateWriter {
77
77
& mut self . output ,
78
78
) ?;
79
79
80
- self . encode_block_with_decoder ( tokens, & huffman_writer) ;
80
+ self . encode_huffman ( tokens, & huffman_writer) ;
81
81
}
82
82
} ,
83
83
}
@@ -90,11 +90,7 @@ impl DeflateWriter {
90
90
self . bitwriter . flush_whole_bytes ( & mut self . output ) ;
91
91
}
92
92
93
- fn encode_block_with_decoder (
94
- & mut self ,
95
- tokens : & Vec < DeflateToken > ,
96
- huffman_writer : & HuffmanWriter ,
97
- ) {
93
+ fn encode_huffman ( & mut self , tokens : & Vec < DeflateToken > , huffman_writer : & HuffmanWriter ) {
98
94
for token in tokens {
99
95
match token {
100
96
DeflateToken :: Literal ( lit) => {
@@ -111,7 +107,7 @@ impl DeflateWriter {
111
107
& mut self . output ,
112
108
LITLEN_CODE_COUNT as u16 - 2 ,
113
109
) ;
114
- self . bitwriter . write ( 5 , 31 , & mut self . output ) ;
110
+ self . bitwriter . write ( 31 , 5 , & mut self . output ) ;
115
111
} else {
116
112
let lencode = quantize_length ( reference. len ( ) ) ;
117
113
huffman_writer. write_literal (
@@ -128,22 +124,22 @@ impl DeflateWriter {
128
124
& mut self . output ,
129
125
) ;
130
126
}
127
+ }
131
128
132
- let distcode = quantize_distance ( reference. dist ( ) ) ;
133
- huffman_writer. write_distance (
134
- & mut self . bitwriter ,
129
+ let distcode = quantize_distance ( reference. dist ( ) ) ;
130
+ huffman_writer. write_distance (
131
+ & mut self . bitwriter ,
132
+ & mut self . output ,
133
+ distcode as u16 ,
134
+ ) ;
135
+
136
+ let distextra = DIST_EXTRA_TABLE [ distcode] ;
137
+ if distextra > 0 {
138
+ self . bitwriter . write (
139
+ reference. dist ( ) - 1 - DIST_BASE_TABLE [ distcode] as u32 ,
140
+ distextra. into ( ) ,
135
141
& mut self . output ,
136
- distcode as u16 ,
137
142
) ;
138
-
139
- let distextra = DIST_EXTRA_TABLE [ distcode] ;
140
- if distextra > 0 {
141
- self . bitwriter . write (
142
- reference. dist ( ) - 1 - DIST_BASE_TABLE [ distcode] as u32 ,
143
- distextra. into ( ) ,
144
- & mut self . output ,
145
- ) ;
146
- }
147
143
}
148
144
}
149
145
}
@@ -152,3 +148,56 @@ impl DeflateWriter {
152
148
huffman_writer. write_literal ( & mut self . bitwriter , & mut self . output , 256 ) ;
153
149
}
154
150
}
151
+
152
+ /// Create a set of blocks and read them back to see if they are identical
153
+ #[ test]
154
+ fn roundtrip_deflate_writer ( ) {
155
+ use super :: deflate_reader:: DeflateReader ;
156
+ use std:: io:: Cursor ;
157
+
158
+ let mut w = DeflateWriter :: new ( ) ;
159
+
160
+ let blocks = [
161
+ DeflateTokenBlock :: Huffman {
162
+ tokens : vec ! [ DeflateToken :: Literal ( 0 ) , DeflateToken :: Literal ( 1 ) ] ,
163
+ huffman_type : DeflateHuffmanType :: Static { incomplete : false } ,
164
+ } ,
165
+ DeflateTokenBlock :: Stored {
166
+ uncompressed : vec ! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ,
167
+ padding_bits : 0b101 , // there are 3 bits of padding
168
+ } ,
169
+ DeflateTokenBlock :: Huffman {
170
+ tokens : vec ! [
171
+ DeflateToken :: Literal ( 0 ) ,
172
+ DeflateToken :: Literal ( 1 ) ,
173
+ DeflateToken :: new_ref( 100 , 1 , false ) ,
174
+ DeflateToken :: new_ref( 258 , 1 , true ) ,
175
+ DeflateToken :: Literal ( 3 ) ,
176
+ ] ,
177
+ huffman_type : DeflateHuffmanType :: Static { incomplete : false } ,
178
+ } ,
179
+ ] ;
180
+
181
+ for i in 0 ..blocks. len ( ) {
182
+ w. encode_block ( & blocks[ i] , i == blocks. len ( ) - 1 ) . unwrap ( ) ;
183
+ }
184
+ w. flush_with_padding ( 0 ) ;
185
+
186
+ let output = w. detach_output ( ) ;
187
+
188
+ let mut r = DeflateReader :: new ( Cursor :: new ( output) ) ;
189
+
190
+ let mut newcontent = Vec :: new ( ) ;
191
+ loop {
192
+ let mut last = false ;
193
+ newcontent. push ( r. read_block ( & mut last) . unwrap ( ) ) ;
194
+ if last {
195
+ break ;
196
+ }
197
+ }
198
+
199
+ assert_eq ! ( blocks. len( ) , newcontent. len( ) ) ;
200
+ for i in 0 ..blocks. len ( ) {
201
+ assert_eq ! ( blocks[ i] , newcontent[ i] , "block {}" , i) ;
202
+ }
203
+ }
0 commit comments