1 //! Extra streaming compression functionality.
3 //! As of now this is mainly intended for use to build a higher-level wrapper.
5 //! There is no DeflateState as the needed state is contained in the compressor struct itself.
7 use crate::deflate
::core
::{compress, CompressorOxide, TDEFLFlush, TDEFLStatus}
;
8 use crate::{MZError, MZFlush, MZStatus, StreamResult}
;
10 /// Try to compress from input to output with the given [`CompressorOxide`].
14 /// Returns [`MZError::Buf`] If the size of the `output` slice is empty or no progress was made due
15 /// to lack of expected input data, or if called without [`MZFlush::Finish`] after the compression
16 /// was already finished.
18 /// Returns [`MZError::Param`] if the compressor parameters are set wrong.
20 /// Returns [`MZError::Stream`] when lower-level decompressor returns a
21 /// [`TDEFLStatus::PutBufFailed`]; may not actually be possible.
23 compressor
: &mut CompressorOxide
,
28 if output
.is_empty() {
29 return StreamResult
::error(MZError
::Buf
);
32 if compressor
.prev_return_status() == TDEFLStatus
::Done
{
33 return if flush
== MZFlush
::Finish
{
37 status
: Ok(MZStatus
::StreamEnd
),
40 StreamResult
::error(MZError
::Buf
)
44 let mut bytes_written
= 0;
45 let mut bytes_consumed
= 0;
47 let mut next_in
= input
;
48 let mut next_out
= output
;
54 let res
= compress(compressor
, next_in
, next_out
, TDEFLFlush
::from(flush
));
60 next_in
= &next_in
[in_bytes
..];
61 next_out
= &mut next_out
[out_bytes
..];
62 bytes_consumed
+= in_bytes
;
63 bytes_written
+= out_bytes
;
65 // Check if we are done, or compression failed.
67 TDEFLStatus
::BadParam
=> break Err(MZError
::Param
),
68 // Don't think this can happen as we're not using a custom callback.
69 TDEFLStatus
::PutBufFailed
=> break Err(MZError
::Stream
),
70 TDEFLStatus
::Done
=> break Ok(MZStatus
::StreamEnd
),
74 // All the output space was used, so wait for more.
75 if next_out
.is_empty() {
76 break Ok(MZStatus
::Ok
);
79 if next_in
.is_empty() && (flush
!= MZFlush
::Finish
) {
80 let total_changed
= bytes_written
> 0 || bytes_consumed
> 0;
82 break if (flush
!= MZFlush
::None
) || total_changed
{
83 // We wrote or consumed something, and/or did a flush (sync/partial etc.).
86 // No more input data, not flushing, and nothing was consumed or written,
87 // so couldn't make any progress.
102 use crate::deflate
::CompressorOxide
;
103 use crate::inflate
::decompress_to_vec_zlib
;
104 use crate::{MZFlush, MZStatus}
;
105 use alloc
::boxed
::Box
;
110 let data
= b
"Hello zlib!";
111 let mut compressed
= vec
![0; 50];
112 let mut compressor
= Box
::<CompressorOxide
>::default();
113 let res
= deflate(&mut compressor
, data
, &mut compressed
, MZFlush
::Finish
);
114 let status
= res
.status
.expect("Failed to compress!");
116 decompress_to_vec_zlib(&compressed
).expect("Failed to decompress compressed data");
117 assert_eq
!(status
, MZStatus
::StreamEnd
);
118 assert_eq
!(decomp
[..], data
[..]);
119 assert_eq
!(res
.bytes_consumed
, data
.len());