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}