liblzma/write/
auto_finish.rs

1use crate::write::{XzDecoder, XzEncoder};
2use std::io;
3use std::io::Write;
4
5/// A compression stream which will have uncompressed data written to it and
6/// will write compressed data to an output stream.
7/// [AutoFinishXzEncoder] impl [Drop] trait, so automatically calls [XzEncoder::try_finish] method when exiting the scope.
8/// However, it is not guaranteed that `try_finish` will complete successfully, and it is recommended to call `try_finish` manually if you want to ensure that the process is successful.
9pub struct AutoFinishXzEncoder<W: Write>(pub(super) XzEncoder<W>);
10
11impl<W: Write> AutoFinishXzEncoder<W> {
12    /// Acquires a reference to the underlying writer.
13    #[inline]
14    pub fn get_ref(&self) -> &W {
15        self.0.get_ref()
16    }
17
18    /// Acquires a mutable reference to the underlying writer.
19    ///
20    /// Note that mutating the output/input state of the stream may corrupt this
21    /// object, so care must be taken when using this method.
22    #[inline]
23    pub fn get_mut(&mut self) -> &mut W {
24        self.0.get_mut()
25    }
26
27    /// Attempt to finish this output stream, writing out final chunks of data.
28    ///
29    /// Note that this function can only be used once data has finished being
30    /// written to the output stream. After this function is called then further
31    /// calls to `write` may result in a panic.
32    ///
33    /// # Panics
34    ///
35    /// Attempts to write data to this stream may result in a panic after this
36    /// function is called.
37    #[inline]
38    pub fn try_finish(&mut self) -> io::Result<()> {
39        self.0.try_finish()
40    }
41
42    /// Consumes this encoder, flushing the output stream.
43    ///
44    /// This will flush the underlying data stream and then return the contained
45    /// writer if the flush succeeded.
46    ///
47    /// Note that this function may not be suitable to call in a situation where
48    /// the underlying stream is an asynchronous I/O stream. To finish a stream
49    /// the `try_finish` method should be used instead. To
50    /// re-acquire ownership of a stream it is safe to call this method after
51    /// `try_finish` has returned `Ok`.
52    #[inline]
53    pub fn finish(mut self) -> io::Result<W> {
54        self.try_finish()?;
55        Ok(self.0.obj.take().unwrap())
56    }
57
58    /// Returns the number of bytes produced by the compressor
59    ///
60    /// Note that, due to buffering, this only bears any relation to
61    /// `total_in()` after a call to `flush()`.  At that point,
62    /// `total_out() / total_in()` is the compression ratio.
63    #[inline]
64    pub fn total_out(&self) -> u64 {
65        self.0.total_out()
66    }
67
68    /// Returns the number of bytes consumed by the compressor
69    /// (e.g. the number of bytes written to this stream.)
70    #[inline]
71    pub fn total_in(&self) -> u64 {
72        self.0.total_out()
73    }
74}
75
76impl<W: Write> Write for AutoFinishXzEncoder<W> {
77    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
78        self.0.write(buf)
79    }
80
81    fn flush(&mut self) -> io::Result<()> {
82        self.0.flush()
83    }
84}
85
86impl<W: Write> Drop for AutoFinishXzEncoder<W> {
87    #[inline]
88    fn drop(&mut self) {
89        if self.0.obj.is_some() {
90            let _ = self.0.try_finish();
91        }
92    }
93}
94
95/// A compression stream which will have compressed data written to it and
96/// will write uncompressed data to an output stream.
97/// [AutoFinishXzDecoder] impl [Drop] trait, so automatically calls [XzDecoder::try_finish] method when exiting the scope.
98/// However, it is not guaranteed that `try_finish` will complete successfully, and it is recommended to call `try_finish` manually if you want to ensure that the process is successful.
99pub struct AutoFinishXzDecoder<W: Write>(pub(super) XzDecoder<W>);
100
101impl<W: Write> AutoFinishXzDecoder<W> {
102    /// Acquires a reference to the underlying writer.
103    #[inline]
104    pub fn get_ref(&self) -> &W {
105        self.0.get_ref()
106    }
107
108    /// Acquires a mutable reference to the underlying writer.
109    ///
110    /// Note that mutating the output/input state of the stream may corrupt this
111    /// object, so care must be taken when using this method.
112    #[inline]
113    pub fn get_mut(&mut self) -> &mut W {
114        self.0.get_mut()
115    }
116
117    /// Attempt to finish this output stream, writing out final chunks of data.
118    ///
119    /// Note that this function can only be used once data has finished being
120    /// written to the output stream. After this function is called then further
121    /// calls to `write` may result in a panic.
122    ///
123    /// # Panics
124    ///
125    /// Attempts to write data to this stream may result in a panic after this
126    /// function is called.
127    #[inline]
128    pub fn try_finish(&mut self) -> io::Result<()> {
129        self.0.try_finish()
130    }
131
132    /// Consumes this decoder, flushing the output stream.
133    ///
134    /// This will flush the underlying data stream and then return the contained
135    /// writer if the flush succeeded.
136    ///
137    /// Note that this function may not be suitable to call in a situation where
138    /// the underlying stream is an asynchronous I/O stream. To finish a stream
139    /// the `try_finish` method should be used instead. To
140    /// re-acquire ownership of a stream it is safe to call this method after
141    /// `try_finish` has returned `Ok`.
142    #[inline]
143    pub fn finish(mut self) -> io::Result<W> {
144        self.try_finish()?;
145        Ok(self.0.obj.take().unwrap())
146    }
147
148    /// Returns the number of bytes produced by the decompressor
149    ///
150    /// Note that, due to buffering, this only bears any relation to
151    /// `total_in()` after a call to `flush()`.  At that point,
152    /// `total_in() / total_out()` is the compression ratio.
153    #[inline]
154    pub fn total_out(&self) -> u64 {
155        self.0.total_out()
156    }
157
158    /// Returns the number of bytes consumed by the decompressor
159    /// (e.g. the number of bytes written to this stream.)
160    #[inline]
161    pub fn total_in(&self) -> u64 {
162        self.0.total_in()
163    }
164}
165
166impl<W: Write> Write for AutoFinishXzDecoder<W> {
167    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
168        self.0.write(buf)
169    }
170
171    fn flush(&mut self) -> io::Result<()> {
172        self.0.flush()
173    }
174}
175
176impl<W: Write> Drop for AutoFinishXzDecoder<W> {
177    #[inline]
178    fn drop(&mut self) {
179        if self.0.obj.is_some() {
180            let _ = self.0.try_finish();
181        }
182    }
183}