async_compression/generic/bufread/
decoder.rs1use crate::{
2 codecs::DecodeV2,
3 core::util::{PartialBuffer, WriteBuffer},
4};
5use std::{io::Result, ops::ControlFlow, panic::AssertUnwindSafe};
6
7#[derive(Debug)]
8enum State {
9 Decoding,
10 Flushing,
11 Done,
12 Next,
13 Error(AssertUnwindSafe<std::io::Error>),
14}
15
16#[derive(Debug)]
17pub struct Decoder {
18 state: State,
19 multiple_members: bool,
20}
21
22impl Default for Decoder {
23 fn default() -> Self {
24 Self {
25 state: State::Decoding,
26 multiple_members: false,
27 }
28 }
29}
30
31impl Decoder {
32 pub fn multiple_members(&mut self, enabled: bool) {
33 self.multiple_members = enabled;
34 }
35
36 pub fn do_poll_read(
37 &mut self,
38 output: &mut WriteBuffer<'_>,
39 decoder: &mut dyn DecodeV2,
40 input: &mut PartialBuffer<&[u8]>,
41 mut first: bool,
42 ) -> ControlFlow<Result<()>> {
43 loop {
44 self.state = match self.state {
45 State::Decoding => {
46 if input.unwritten().is_empty() && !first {
47 self.multiple_members = false;
50
51 State::Flushing
52 } else {
53 match decoder.decode(input, output) {
54 Ok(true) => State::Flushing,
55 Err(err) if !first => {
58 self.state = State::Error(AssertUnwindSafe(err));
59 if output.written_len() > 0 {
60 return ControlFlow::Break(Ok(()));
61 } else {
62 continue;
63 }
64 }
65 _ => break,
67 }
68 }
69 }
70
71 State::Flushing => {
72 match decoder.finish(output) {
73 Ok(true) => {
74 if self.multiple_members {
75 if let Err(err) = decoder.reinit() {
76 self.state = State::Error(AssertUnwindSafe(err));
77 if output.written_len() > 0 {
78 return ControlFlow::Break(Ok(()));
79 } else {
80 continue;
81 }
82 }
83
84 first = input.unwritten().is_empty();
86 State::Next
87 } else {
88 State::Done
89 }
90 }
91 Ok(false) => State::Flushing,
92 Err(err) => {
93 self.state = State::Error(AssertUnwindSafe(err));
94 if output.written_len() > 0 {
95 return ControlFlow::Break(Ok(()));
96 } else {
97 continue;
98 }
99 }
100 }
101 }
102
103 State::Done => return ControlFlow::Break(Ok(())),
104
105 State::Next => {
106 if input.unwritten().is_empty() {
107 if first {
108 break;
110 }
111 State::Done
112 } else {
113 State::Decoding
114 }
115 }
116
117 State::Error(_) => {
118 let State::Error(err) = std::mem::replace(&mut self.state, State::Done) else {
119 unreachable!()
120 };
121 return ControlFlow::Break(Err(err.0));
122 }
123 };
124
125 if output.has_no_spare_space() {
126 return ControlFlow::Break(Ok(()));
127 }
128 }
129
130 if output.has_no_spare_space() {
131 ControlFlow::Break(Ok(()))
132 } else {
133 ControlFlow::Continue(())
134 }
135 }
136}
137
138macro_rules! impl_decoder {
139 () => {
140 use crate::generic::bufread::Decoder as GenericDecoder;
141
142 use std::{ops::ControlFlow, task::ready};
143
144 use pin_project_lite::pin_project;
145
146 pin_project! {
147 #[derive(Debug)]
148 pub struct Decoder<R, D> {
149 #[pin]
150 reader: R,
151 decoder: D,
152 inner: GenericDecoder,
153 }
154 }
155
156 impl<R: AsyncBufRead, D: DecodeV2> Decoder<R, D> {
157 pub fn new(reader: R, decoder: D) -> Self {
158 Self {
159 reader,
160 decoder,
161 inner: GenericDecoder::default(),
162 }
163 }
164 }
165
166 impl<R, D> Decoder<R, D> {
167 pub fn get_ref(&self) -> &R {
168 &self.reader
169 }
170
171 pub fn get_mut(&mut self) -> &mut R {
172 &mut self.reader
173 }
174
175 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut R> {
176 self.project().reader
177 }
178
179 pub fn into_inner(self) -> R {
180 self.reader
181 }
182
183 pub fn multiple_members(&mut self, enabled: bool) {
184 self.inner.multiple_members(enabled);
185 }
186 }
187
188 fn do_poll_read(
189 inner: &mut GenericDecoder,
190 decoder: &mut dyn DecodeV2,
191 mut reader: Pin<&mut dyn AsyncBufRead>,
192 cx: &mut Context<'_>,
193 output: &mut WriteBuffer<'_>,
194 ) -> Poll<Result<()>> {
195 if let ControlFlow::Break(res) =
196 inner.do_poll_read(output, decoder, &mut PartialBuffer::new(&[][..]), true)
197 {
198 return Poll::Ready(res);
199 }
200
201 loop {
202 let mut input = PartialBuffer::new(match reader.as_mut().poll_fill_buf(cx)? {
203 Poll::Ready(input) => input,
204 Poll::Pending if output.written().is_empty() => return Poll::Pending,
205 _ => return Poll::Ready(Ok(())),
206 });
207
208 let control_flow = inner.do_poll_read(output, decoder, &mut input, false);
209
210 let bytes_read = input.written().len();
211 reader.as_mut().consume(bytes_read);
212
213 if let ControlFlow::Break(res) = control_flow {
214 break Poll::Ready(res);
215 }
216 }
217 }
218
219 impl<R: AsyncBufRead, D: DecodeV2> Decoder<R, D> {
220 fn do_poll_read(
221 self: Pin<&mut Self>,
222 cx: &mut Context<'_>,
223 output: &mut WriteBuffer<'_>,
224 ) -> Poll<Result<()>> {
225 let this = self.project();
226
227 do_poll_read(this.inner, this.decoder, this.reader, cx, output)
228 }
229 }
230 };
231}
232pub(crate) use impl_decoder;