miniz_oxide/deflate/
stream.rs
1use std::convert::{AsMut, AsRef};
7
8use crate::deflate::core::{compress, CompressorOxide, TDEFLFlush, TDEFLStatus};
9use crate::{MZError, MZFlush, MZStatus, StreamResult};
10
11pub fn deflate(
21 compressor: &mut CompressorOxide,
22 input: &[u8],
23 output: &mut [u8],
24 flush: MZFlush,
25) -> StreamResult {
26 if output.is_empty() {
27 return StreamResult::error(MZError::Buf);
28 }
29
30 if compressor.prev_return_status() == TDEFLStatus::Done {
31 return if flush == MZFlush::Finish {
32 StreamResult {
33 bytes_written: 0,
34 bytes_consumed: 0,
35 status: Ok(MZStatus::StreamEnd),
36 }
37 } else {
38 StreamResult::error(MZError::Buf)
39 };
40 }
41
42 let mut bytes_written = 0;
43 let mut bytes_consumed = 0;
44
45 let mut next_in = input.as_ref();
46 let mut next_out = output.as_mut();
47
48 let status = loop {
49 let in_bytes;
50 let out_bytes;
51 let defl_status = {
52 let res = compress(compressor, next_in, next_out, TDEFLFlush::from(flush));
53 in_bytes = res.1;
54 out_bytes = res.2;
55 res.0
56 };
57
58 next_in = &next_in[in_bytes..];
59 next_out = &mut next_out[out_bytes..];
60 bytes_consumed += in_bytes;
61 bytes_written += out_bytes;
62
63 match defl_status {
65 TDEFLStatus::BadParam => break Err(MZError::Param),
66 TDEFLStatus::PutBufFailed => break Err(MZError::Stream),
68 TDEFLStatus::Done => break Ok(MZStatus::StreamEnd),
69 _ => (),
70 };
71
72 if next_out.is_empty() {
74 break Ok(MZStatus::Ok);
75 }
76
77 if next_in.is_empty() && (flush != MZFlush::Finish) {
78 let total_changed = bytes_written > 0 || bytes_consumed > 0;
79
80 break if (flush != MZFlush::None) || total_changed {
81 Ok(MZStatus::Ok)
83 } else {
84 Err(MZError::Buf)
87 };
88 }
89 };
90 StreamResult {
91 bytes_consumed,
92 bytes_written,
93 status,
94 }
95}
96
97#[cfg(test)]
98mod test {
99 use super::deflate;
100 use crate::deflate::CompressorOxide;
101 use crate::inflate::decompress_to_vec_zlib;
102 use crate::{MZFlush, MZStatus};
103 #[test]
104 fn test_state() {
105 let data = b"Hello zlib!";
106 let mut compressed = vec![0; 50];
107 let mut compressor = Box::<CompressorOxide>::default();
108 let res = deflate(&mut compressor, data, &mut compressed, MZFlush::Finish);
109 let status = res.status.expect("Failed to compress!");
110 let decomp =
111 decompress_to_vec_zlib(&compressed).expect("Failed to decompress compressed data");
112 assert_eq!(status, MZStatus::StreamEnd);
113 assert_eq!(decomp[..], data[..]);
114 assert_eq!(res.bytes_consumed, data.len());
115 }
116}