bzip2_rs/decoder/reader.rs
1use std::io::{self, Read, Result};
2
3use super::{Decoder, ReadState, WriteState};
4
5/// A high-level decoder that wraps a [`Read`] and implements [`Read`], yielding decompressed bytes
6///
7/// ```rust
8/// use std::fs::File;
9/// use std::io;
10///
11/// use bzip2_rs::DecoderReader;
12///
13/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
14/// let mut compressed_file = File::open("tests/samplefiles/sample1.bz2")?;
15/// # fn no_run() -> Result<(), Box<dyn std::error::Error>> {
16/// let mut output = File::create("output.ref")?;
17/// # Ok(())
18/// # }
19/// # let mut output = Vec::new();
20///
21/// let mut reader = DecoderReader::new(compressed_file);
22/// io::copy(&mut reader, &mut output)?;
23/// #
24/// # let expected = std::fs::read("tests/samplefiles/sample1.ref")?;
25/// # assert_eq!(expected, output);
26/// #
27/// # Ok(())
28/// # }
29/// ```
30pub struct DecoderReader<R> {
31 decoder: Decoder,
32
33 reader: R,
34}
35
36impl<R> DecoderReader<R> {
37 /// Construct a new decoder from something implementing [`Read`]
38 pub fn new(reader: R) -> Self {
39 Self {
40 decoder: Decoder::new(),
41
42 reader,
43 }
44 }
45}
46
47impl<R: Read> Read for DecoderReader<R> {
48 /// Decompress bzip2 data from the underlying reader
49 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
50 let mut read_zero = false;
51 let mut tmp_buf = [0; 1024];
52
53 loop {
54 match self.decoder.read(buf)? {
55 ReadState::NeedsWrite(space) => {
56 let read = self.reader.read(&mut tmp_buf[..space.min(1024)])?;
57
58 if read_zero && self.decoder.header_block.is_none() {
59 return Err(io::Error::new(
60 io::ErrorKind::UnexpectedEof,
61 "The reader is empty?",
62 ));
63 }
64 read_zero = read == 0;
65
66 match self.decoder.write(&tmp_buf[..read])? {
67 WriteState::NeedsRead => unreachable!(),
68 WriteState::Written(written) => assert_eq!(written, read),
69 };
70 }
71 ReadState::Read(n) => return Ok(n),
72 ReadState::Eof => return Ok(0),
73 }
74 }
75 }
76}