@@ -9,14 +9,11 @@ use twox_hash::XxHash64;
99use core:: hash:: Hasher ;
1010
1111use super :: {
12- block_header:: BlockHeader , blocks :: compress_block , frame_header :: FrameHeader ,
12+ block_header:: BlockHeader , frame_header :: FrameHeader , levels :: * ,
1313 match_generator:: MatchGeneratorDriver , CompressionLevel , Matcher ,
1414} ;
1515
16- use crate :: {
17- common:: MAX_BLOCK_SIZE ,
18- io:: { Read , Write } ,
19- } ;
16+ use crate :: io:: { Read , Write } ;
2017
2118/// An interface for compressing arbitrary data with the ZStandard compression algorithm.
2219///
@@ -106,24 +103,25 @@ impl<R: Read, W: Write, M: Matcher> FrameCompressor<R, W, M> {
106103 /// To avoid endlessly encoding from a potentially endless source (like a network socket) you can use the
107104 /// [Read::take] function
108105 pub fn compress ( & mut self ) {
106+ // Clearing buffers to allow re-using of the compressor
109107 self . state . matcher . reset ( self . compression_level ) ;
110108 self . state . last_huff_table = None ;
111109 let source = self . uncompressed_data . as_mut ( ) . unwrap ( ) ;
112110 let drain = self . compressed_data . as_mut ( ) . unwrap ( ) ;
113-
114- let mut output = Vec :: with_capacity ( 1024 * 130 ) ;
115- let output = & mut output ;
111+ // As the frame is compressed, it's stored here
112+ let output : & mut Vec < u8 > = & mut Vec :: with_capacity ( 1024 * 130 ) ;
113+ // First write the frame header
116114 let header = FrameHeader {
117115 frame_content_size : None ,
118116 single_segment : false ,
119117 content_checksum : cfg ! ( feature = "hash" ) ,
120118 dictionary_id : None ,
121119 window_size : Some ( self . state . matcher . window_size ( ) ) ,
122120 } ;
123-
124121 header. serialize ( output) ;
125-
122+ // Now compress block by block
126123 loop {
124+ // Read a single block's worth of uncompressed data from the input
127125 let mut uncompressed_data = self . state . matcher . get_next_space ( ) ;
128126 let mut read_bytes = 0 ;
129127 let last_block;
@@ -140,6 +138,7 @@ impl<R: Read, W: Write, M: Matcher> FrameCompressor<R, W, M> {
140138 }
141139 }
142140 uncompressed_data. resize ( read_bytes, 0 ) ;
141+ // As we read, hash that data too
143142 #[ cfg( feature = "hash" ) ]
144143 self . hasher . write ( & uncompressed_data) ;
145144 // Special handling is needed for compression of a totally empty file (why you'd want to do that, I don't know)
@@ -168,42 +167,7 @@ impl<R: Read, W: Write, M: Matcher> FrameCompressor<R, W, M> {
168167 output. extend_from_slice ( & uncompressed_data) ;
169168 }
170169 CompressionLevel :: Fastest => {
171- if uncompressed_data. iter ( ) . all ( |x| uncompressed_data[ 0 ] . eq ( x) ) {
172- let rle_byte = uncompressed_data[ 0 ] ;
173- self . state . matcher . commit_space ( uncompressed_data) ;
174- self . state . matcher . skip_matching ( ) ;
175- let header = BlockHeader {
176- last_block,
177- block_type : crate :: blocks:: block:: BlockType :: RLE ,
178- block_size : read_bytes. try_into ( ) . unwrap ( ) ,
179- } ;
180- // Write the header, then the block
181- header. serialize ( output) ;
182- output. push ( rle_byte) ;
183- } else {
184- let mut compressed = Vec :: new ( ) ;
185- self . state . matcher . commit_space ( uncompressed_data) ;
186- compress_block ( & mut self . state , & mut compressed) ;
187- if compressed. len ( ) >= MAX_BLOCK_SIZE as usize {
188- let header = BlockHeader {
189- last_block,
190- block_type : crate :: blocks:: block:: BlockType :: Raw ,
191- block_size : read_bytes. try_into ( ) . unwrap ( ) ,
192- } ;
193- // Write the header, then the block
194- header. serialize ( output) ;
195- output. extend_from_slice ( self . state . matcher . get_last_space ( ) ) ;
196- } else {
197- let header = BlockHeader {
198- last_block,
199- block_type : crate :: blocks:: block:: BlockType :: Compressed ,
200- block_size : ( compressed. len ( ) ) . try_into ( ) . unwrap ( ) ,
201- } ;
202- // Write the header, then the block
203- header. serialize ( output) ;
204- output. extend ( compressed) ;
205- }
206- }
170+ compress_fastest ( & mut self . state , last_block, uncompressed_data, output)
207171 }
208172 _ => {
209173 unimplemented ! ( ) ;
0 commit comments