Skip to content

Commit 1125d37

Browse files
committed
Changed issues from PR comments.
1 parent cbf697e commit 1125d37

11 files changed

+47
-50
lines changed

src/legacy/huffman.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,23 @@ const HUFFMAN_LOOKUP_TABLE_BITS: u8 = 8;
1919

2020
pub struct HuffmanDecoder {
2121
/// Lookup table for fast decoding of short codewords.
22-
pub table: Vec<TableEntry>,
22+
pub table: [TableEntry; 1 << HUFFMAN_LOOKUP_TABLE_BITS],
2323
/// "Sentinel bits" value for each codeword length.
24-
pub sentinel_bits: Vec<u32>,
24+
pub sentinel_bits: [u32; MAX_HUFFMAN_BITS + 1],
2525
/// First symbol index minus first codeword mod 2**16 for each length.
26-
pub offset_first_sym_idx: Vec<u16>,
26+
pub offset_first_sym_idx: [u16; MAX_HUFFMAN_BITS + 1],
2727
/// Map from symbol index to symbol.
28-
pub syms: Vec<u16>,
28+
pub syms: [u16; MAX_HUFFMAN_SYMBOLS],
2929
// num_syms:usize
3030
}
3131

3232
impl Default for HuffmanDecoder {
3333
fn default() -> Self {
34-
let syms = vec![0; MAX_HUFFMAN_SYMBOLS];
35-
let table = vec![TableEntry::default(); 1 << HUFFMAN_LOOKUP_TABLE_BITS];
3634
Self {
37-
table,
38-
sentinel_bits: vec![0; MAX_HUFFMAN_BITS + 1],
39-
offset_first_sym_idx: vec![0; MAX_HUFFMAN_BITS + 1],
40-
syms,
35+
table: [TableEntry::default(); 1 << HUFFMAN_LOOKUP_TABLE_BITS],
36+
sentinel_bits: [0; MAX_HUFFMAN_BITS + 1],
37+
offset_first_sym_idx: [0; MAX_HUFFMAN_BITS + 1],
38+
syms: [0; MAX_HUFFMAN_SYMBOLS],
4139
}
4240
}
4341
}
@@ -157,7 +155,7 @@ impl HuffmanDecoder {
157155
MAX_HUFFMAN_BITS,
158156
);
159157

160-
for l in HUFFMAN_LOOKUP_TABLE_BITS as usize + 1..=MAX_HUFFMAN_BITS {
158+
for l in (HUFFMAN_LOOKUP_TABLE_BITS as usize + 1)..=MAX_HUFFMAN_BITS {
161159
if (bits as u32) < self.sentinel_bits[l] {
162160
bits >>= MAX_HUFFMAN_BITS - l;
163161
let sym_idx = (self.offset_first_sym_idx[l] as usize + bits as usize) & 0xFFFF;

src/legacy/implode.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::io::{self, Cursor, Error, Read, Result};
99
fn read_huffman_code<T: std::io::Read, E: Endianness>(
1010
is: &mut BitReader<T, E>,
1111
num_lens: usize,
12-
) -> std::io::Result<HuffmanDecoder> {
12+
) -> std::io::Result<Box<HuffmanDecoder>> {
1313
let mut lens = [0; 1 << 8];
1414
let mut len_count = [0; 17];
1515
// debug_assert!(num_lens <= sizeof(lens) / sizeof(lens[0]));
@@ -71,7 +71,7 @@ fn read_huffman_code<T: std::io::Read, E: Endianness>(
7171
));
7272
}
7373

74-
let mut d = HuffmanDecoder::default();
74+
let mut d = Box::new(HuffmanDecoder::default());
7575
d.init(&lens, num_lens)?;
7676
Ok(d)
7777
}
@@ -205,7 +205,7 @@ impl<R: Read> Read for ImplodeDecoder<R> {
205205
mod tests {
206206
use super::hwexplode;
207207
use std::collections::VecDeque;
208-
const HAMLET_256: &[u8; 249] = include_bytes!("../../tests/implode_hamlet_256.bin");
208+
const HAMLET_256: &[u8; 249] = include_bytes!("../../tests/data/legacy/implode_hamlet_256.bin");
209209

210210
#[test]
211211
fn test_explode_hamlet_256() {

src/legacy/reduce.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ fn read_follower_sets<T: std::io::Read, E: Endianness>(
4747
Ok(fsets)
4848
}
4949

50+
5051
/// Read the next byte from is, decoded based on prev_byte and the follower sets.
51-
/// The byte is returned in *out_byte. The function returns true on success,
52-
/// and false on bad data or end of input.
52+
/// The byte is returned in *out_byte.
53+
///
54+
/// # Returns
55+
///
56+
/// * `Ok(())` if the byte was successfully read.
57+
/// * `Err(io::Error)` on bad data or end of input.
5358
fn read_next_byte<T: std::io::Read, E: Endianness>(
5459
is: &mut BitReader<T, E>,
5560
prev_byte: u8,
@@ -215,7 +220,7 @@ mod tests {
215220
use super::hwexpand;
216221
use crate::legacy::reduce::{follower_idx_bw, lsb, max_dist};
217222
use std::collections::VecDeque;
218-
const HAMLET_2048: &[u8; 1285] = include_bytes!("../../tests/reduce_hamlet_2048.bin");
223+
const HAMLET_2048: &[u8; 1285] = include_bytes!("../../tests/data/legacy/reduce_hamlet_2048.bin");
219224

220225
#[test]
221226
fn test_lsb() {
@@ -243,7 +248,7 @@ mod tests {
243248
$ dosbox -c "mount c ." -c "c:" -c "pkzip -ea4 a.zip a" -c "exit"
244249
$ xxd -i -s 31 -l $(expr $(find A.ZIP -printf %s) - 100) A.ZIP
245250
*/
246-
const ZEROS_REDUCED: &[u8; 1297] = include_bytes!("../../tests/reduce_zero_reduced.bin");
251+
const ZEROS_REDUCED: &[u8; 1297] = include_bytes!("../../tests/data/legacy/reduce_zero_reduced.bin");
247252

248253
#[test]
249254
fn test_expand_zeros() {

src/legacy/shrink.rs

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ const UNKNOWN_LEN: u16 = u16::MAX;
1717

1818
struct CodeQueue {
1919
next_idx: usize,
20-
codes: Vec<Option<u16>>,
20+
codes: [Option<u16>; MAX_CODE - CONTROL_CODE + 1]
2121
}
2222

2323
impl CodeQueue {
2424
fn new() -> Self {
25-
let mut codes = vec![None; MAX_CODE as usize - CONTROL_CODE + 1];
25+
let mut codes = [None; MAX_CODE as usize - CONTROL_CODE + 1];
2626
for (i, code) in (CONTROL_CODE as u16 + 1..=MAX_CODE as u16).enumerate() {
2727
codes[i] = Some(code);
2828
}
@@ -151,25 +151,23 @@ fn read_code<T: std::io::Read, E: Endianness>(
151151
Ok(None)
152152
}
153153

154-
/// Output the string represented by a code into dst at dst_pos. Returns
155-
/// HWUNSHRINK_OK on success, and also updates *first_byte and *len with the
156-
/// first byte and length of the output string, respectively.
154+
/// Output the string represented by a code into dst at dst_pos.
155+
///
156+
/// # Returns
157+
/// new first byte of the string, or io::Error InvalidData on invalid prefix code.
157158
fn output_code(
158-
code: u16,
159159
dst: &mut VecDeque<u8>,
160+
code: u16,
160161
prev_code: u16,
161162
codetab: &mut [Codetab],
162-
queue: &mut CodeQueue,
163-
first_byte: &mut u8,
164-
len: &mut usize,
165-
) -> io::Result<()> {
163+
queue: &CodeQueue,
164+
first_byte: u8,
165+
) -> io::Result<u8> {
166166
debug_assert!(code <= MAX_CODE as u16 && code != CONTROL_CODE as u16);
167167
if code <= u8::MAX as u16 {
168168
// Output literal byte.
169-
*first_byte = code as u8;
170-
*len = 1;
171169
dst.push_back(code as u8);
172-
return Ok(());
170+
return Ok(code as u8);
173171
}
174172

175173
if codetab[code as usize].prefix_code.is_none()
@@ -186,9 +184,7 @@ fn output_code(
186184
for i in ct.last_dst_pos..ct.last_dst_pos + ct.len as usize {
187185
dst.push_back(dst[i]);
188186
}
189-
*first_byte = dst[ct.last_dst_pos];
190-
*len = ct.len as usize;
191-
return Ok(());
187+
return Ok(dst[ct.last_dst_pos]);
192188
}
193189

194190
// Output a string of unknown length. This happens when the prefix
@@ -208,11 +204,11 @@ fn output_code(
208204
with its first byte. */
209205
codetab[prefix_code as usize] = Codetab {
210206
prefix_code: Some(prev_code),
211-
ext_byte: *first_byte,
207+
ext_byte: first_byte,
212208
len: codetab[prev_code as usize].len + 1,
213209
last_dst_pos: codetab[prev_code as usize].last_dst_pos,
214210
};
215-
dst.push_back(*first_byte);
211+
dst.push_back(first_byte);
216212
} else if codetab[prefix_code as usize].prefix_code.is_none() {
217213
// The prefix code is still invalid.
218214
return Err(io::Error::new(
@@ -222,26 +218,26 @@ fn output_code(
222218
}
223219

224220
// Output the prefix string, then the extension byte.
225-
*len = codetab[prefix_code as usize].len as usize + 1;
221+
let len = codetab[prefix_code as usize].len as usize + 1;
226222
let last_dst_pos = dst.len();
227223
let ct = &codetab[prefix_code as usize];
228224
for i in ct.last_dst_pos..ct.last_dst_pos + ct.len as usize {
229225
dst.push_back(dst[i]);
230226
}
231227
dst.push_back(codetab[code as usize].ext_byte);
232-
*first_byte = dst[ct.last_dst_pos];
228+
let res = dst[ct.last_dst_pos];
233229

234230
// Update the code table now that the string has a length and pos.
235231
debug_assert!(prev_code != code);
236-
codetab[code as usize].len = *len as u16;
232+
codetab[code as usize].len = len as u16;
237233
codetab[code as usize].last_dst_pos = last_dst_pos;
238234

239-
Ok(())
235+
Ok(res)
240236
}
241237

242238
fn hwunshrink(src: &[u8], uncompressed_size: usize, dst: &mut VecDeque<u8>) -> io::Result<()> {
243239
let mut codetab = Codetab::create_new();
244-
let mut queue = CodeQueue::new();
240+
let mut queue = Box::new(CodeQueue::new());
245241
let mut is = BitReader::endian(src, LittleEndian);
246242

247243
let mut code_size = MIN_CODE_SIZE;
@@ -258,7 +254,7 @@ fn hwunshrink(src: &[u8], uncompressed_size: usize, dst: &mut VecDeque<u8>) -> i
258254
"the first code must be a literal",
259255
));
260256
}
261-
let mut first_byte = curr_code as u8;
257+
let first_byte = curr_code as u8;
262258
codetab[curr_code as usize].last_dst_pos = dst.len();
263259
dst.push_back(curr_code as u8);
264260

@@ -293,15 +289,13 @@ fn hwunshrink(src: &[u8], uncompressed_size: usize, dst: &mut VecDeque<u8>) -> i
293289
}
294290

295291
// Output the string represented by the current code.
296-
let mut len = 0;
297-
output_code(
298-
curr_code,
292+
let first_byte = output_code(
299293
dst,
294+
curr_code,
300295
prev_code,
301296
&mut codetab,
302297
&mut queue,
303-
&mut first_byte,
304-
&mut len,
298+
first_byte,
305299
)?;
306300

307301
// Add a new code to the string table if there's room.
File renamed without changes.
File renamed without changes.
File renamed without changes.

tests/legacy_zip.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use zip::ZipArchive;
66
#[test]
77
fn decompress_shrink() {
88
let mut v = Vec::new();
9-
v.extend_from_slice(include_bytes!("data/shrink.zip"));
9+
v.extend_from_slice(include_bytes!("data/legacy/shrink.zip"));
1010
let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
1111

1212
let mut file = archive
@@ -23,7 +23,7 @@ fn decompress_shrink() {
2323
#[test]
2424
fn decompress_reduce() {
2525
let mut v = Vec::new();
26-
v.extend_from_slice(include_bytes!("data/reduce.zip"));
26+
v.extend_from_slice(include_bytes!("data/legacy/reduce.zip"));
2727
let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
2828

2929
let mut file = archive
@@ -40,7 +40,7 @@ fn decompress_reduce() {
4040
#[test]
4141
fn decompress_implode() {
4242
let mut v = Vec::new();
43-
v.extend_from_slice(include_bytes!("data/implode.zip"));
43+
v.extend_from_slice(include_bytes!("data/legacy/implode.zip"));
4444
let mut archive = ZipArchive::new(io::Cursor::new(v)).expect("couldn't open test zip file");
4545

4646
let mut file = archive

0 commit comments

Comments
 (0)