1use bytes::{Buf, BufMut, BytesMut};
25use std::io::{self, BufRead, Read};
26use xz2::write::XzDecoder;
27
28use crate::io::*;
29
30pub struct XzStreamDecoder<R: BufRead> {
31 source: R,
32 decompressor: XzDecoder<bytes::buf::Writer<BytesMut>>,
33}
34
35impl<R: BufRead> XzStreamDecoder<R> {
36 pub fn new(source: R) -> Self {
37 Self {
38 source,
39 decompressor: XzDecoder::new(BytesMut::new().writer()),
40 }
41 }
42
43 pub fn get_mut(&mut self) -> &mut R {
44 &mut self.source
45 }
46
47 pub fn into_inner(self) -> R {
48 self.source
49 }
50}
51
52impl<R: BufRead> Read for XzStreamDecoder<R> {
53 fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
54 if out.is_empty() {
55 return Ok(0);
56 }
57 loop {
58 let buf = self.decompressor.get_mut().get_mut();
59 if !buf.is_empty() {
60 let count = buf.len().min(out.len());
61 buf.copy_to_slice(&mut out[..count]);
62 return Ok(count);
63 }
64 let in_ = self.source.fill_buf()?;
65 if in_.is_empty() {
66 self.decompressor.finish()?;
68 return Ok(0);
69 }
70 let count = self.decompressor.write(in_)?;
71 if count == 0 {
72 return Ok(0);
74 }
75 self.source.consume(count);
76 self.decompressor.flush()?;
79 }
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use std::io::BufReader;
87 use xz2::read::XzDecoder;
88
89 #[test]
90 fn small_decode() {
91 let mut compressed = Vec::new();
92 compressed.extend(include_bytes!("../../fixtures/verify/1M.xz"));
93 let mut uncompressed = Vec::new();
94 XzDecoder::new(&*compressed)
95 .read_to_end(&mut uncompressed)
96 .unwrap();
97 compressed.extend(b"abcdefg");
98
99 let mut d = XzStreamDecoder::new(BufReader::with_capacity(1, &*compressed));
100 let mut out = Vec::new();
101 let mut buf = [0u8];
102 loop {
103 match d.read(&mut buf).unwrap() {
104 0 => break,
105 1 => out.push(buf[0]),
106 _ => unreachable!(),
107 }
108 }
109 assert_eq!(&out, &uncompressed);
110 let mut remainder = Vec::new();
111 d.into_inner().read_to_end(&mut remainder).unwrap();
112 assert_eq!(&remainder, b"abcdefg");
113 }
114}