1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use std::io::Write;
use std::{cmp, io, mem};
use crate::compress::Flush;
use crate::compression_options::{CompressionOptions, MAX_HASH_CHECKS};
use crate::encoder_state::EncoderState;
pub use crate::huffman_table::MAX_MATCH;
use crate::huffman_table::NUM_LITERALS_AND_LENGTHS;
use crate::input_buffer::InputBuffer;
use crate::length_encode::{EncodedLength, LeafVec};
use crate::lz77::LZ77State;
use crate::output_writer::DynamicWriter;
#[derive(Default)]
pub struct DebugCounter {
#[cfg(debug_assertions)]
count: u64,
}
impl DebugCounter {
#[cfg(debug_assertions)]
pub fn get(&self) -> u64 {
self.count
}
#[cfg(not(debug_assertions))]
pub fn get(&self) -> u64 {
0
}
#[cfg(debug_assertions)]
pub fn reset(&mut self) {
self.count = 0;
}
#[cfg(not(debug_assertions))]
pub fn reset(&self) {}
#[cfg(debug_assertions)]
pub fn add(&mut self, val: u64) {
self.count += val;
}
#[cfg(not(debug_assertions))]
pub fn add(&self, _: u64) {}
}
pub struct LengthBuffers {
pub leaf_buf: LeafVec,
pub length_buf: Vec<EncodedLength>,
}
impl LengthBuffers {
#[inline]
fn new() -> LengthBuffers {
LengthBuffers {
leaf_buf: Vec::with_capacity(NUM_LITERALS_AND_LENGTHS),
length_buf: Vec::with_capacity(19),
}
}
}
pub struct DeflateState<W: Write> {
pub lz77_state: LZ77State,
pub input_buffer: InputBuffer,
pub compression_options: CompressionOptions,
pub encoder_state: EncoderState,
pub lz77_writer: DynamicWriter,
pub length_buffers: LengthBuffers,
pub bytes_written: u64,
pub inner: Option<W>,
pub output_buf_pos: usize,
pub flush_mode: Flush,
pub needs_flush: bool,
pub bytes_written_control: DebugCounter,
}
impl<W: Write> DeflateState<W> {
pub fn new(compression_options: CompressionOptions, writer: W) -> DeflateState<W> {
DeflateState {
input_buffer: InputBuffer::empty(),
lz77_state: LZ77State::new(
compression_options.max_hash_checks,
cmp::min(compression_options.lazy_if_less_than, MAX_HASH_CHECKS),
compression_options.matching_type,
),
encoder_state: EncoderState::new(Vec::with_capacity(1024 * 32)),
lz77_writer: DynamicWriter::new(),
length_buffers: LengthBuffers::new(),
compression_options,
bytes_written: 0,
inner: Some(writer),
output_buf_pos: 0,
flush_mode: Flush::None,
needs_flush: false,
bytes_written_control: DebugCounter::default(),
}
}
#[inline]
pub fn output_buf(&mut self) -> &mut Vec<u8> {
self.encoder_state.inner_vec()
}
pub fn reset(&mut self, writer: W) -> io::Result<W> {
self.encoder_state.flush();
self.inner
.as_mut()
.expect("Missing writer!")
.write_all(self.encoder_state.inner_vec())?;
self.encoder_state.inner_vec().clear();
self.input_buffer = InputBuffer::empty();
self.lz77_writer.clear();
self.lz77_state.reset();
self.bytes_written = 0;
self.output_buf_pos = 0;
self.flush_mode = Flush::None;
self.needs_flush = false;
if cfg!(debug_assertions) {
self.bytes_written_control.reset();
}
mem::replace(&mut self.inner, Some(writer))
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Missing writer"))
}
}