base64_ng/stream/
decoder_reader.rs1use super::{
2 DecoderDriver, OutputQueue, redacted_inner_state, stream_decoder_failed_error,
3 wrapped_reader_overreported_error,
4};
5use crate::{Alphabet, Engine};
6use std::io::{self, Read};
7
8pub struct DecoderReader<R, A, const PAD: bool>
23where
24 A: Alphabet,
25{
26 inner: Option<R>,
27 engine: Engine<A, PAD>,
28 driver: DecoderDriver,
29 output: OutputQueue<3>,
30 finished: bool,
31 terminal_seen: bool,
32 failed: bool,
33}
34
35impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
36where
37 A: Alphabet,
38{
39 #[must_use]
46 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
47 Self {
48 inner: Some(inner),
49 engine,
50 driver: DecoderDriver::new::<A, PAD>(),
51 output: OutputQueue::new(),
52 finished: false,
53 terminal_seen: false,
54 failed: false,
55 }
56 }
57
58 #[must_use]
60 pub fn get_ref(&self) -> &R {
61 self.inner_ref()
62 }
63
64 pub fn get_mut(&mut self) -> &mut R {
66 self.inner_mut()
67 }
68
69 #[must_use]
71 pub const fn engine(&self) -> Engine<A, PAD> {
72 self.engine
73 }
74
75 #[must_use]
77 pub const fn is_padded(&self) -> bool {
78 PAD
79 }
80
81 #[must_use]
84 pub const fn pending_len(&self) -> usize {
85 self.driver.pending_input_len()
86 }
87
88 #[must_use]
91 pub const fn has_pending_input(&self) -> bool {
92 self.pending_len() != 0
93 }
94
95 #[must_use]
100 pub const fn pending_input_needed_len(&self) -> usize {
101 if self.has_pending_input() {
102 4 - self.pending_len()
103 } else {
104 0
105 }
106 }
107
108 #[must_use]
111 pub const fn buffered_output_len(&self) -> usize {
112 self.output.len()
113 }
114
115 #[must_use]
118 pub const fn buffered_output_capacity(&self) -> usize {
119 self.output.capacity()
120 }
121
122 #[must_use]
125 pub const fn buffered_output_remaining_capacity(&self) -> usize {
126 self.output.available_capacity()
127 }
128
129 #[must_use]
132 pub const fn has_buffered_output(&self) -> bool {
133 !self.output.is_empty()
134 }
135
136 #[must_use]
143 pub const fn has_terminal_padding(&self) -> bool {
144 self.terminal_seen
145 }
146
147 #[must_use]
153 pub const fn has_finished_input(&self) -> bool {
154 self.finished
155 }
156
157 #[must_use]
160 pub const fn is_finished(&self) -> bool {
161 self.finished && self.output.is_empty()
162 }
163
164 #[must_use]
171 pub const fn is_failed(&self) -> bool {
172 self.failed
173 }
174
175 #[must_use]
178 pub const fn can_into_inner(&self) -> bool {
179 !self.is_failed() && self.is_finished()
180 }
181
182 #[must_use]
184 pub fn into_inner(mut self) -> R {
185 self.take_inner()
186 }
187
188 #[allow(clippy::result_large_err)]
196 pub fn try_into_inner(mut self) -> Result<R, Self> {
197 if !self.can_into_inner() {
198 return Err(self);
199 }
200 Ok(self.take_inner())
201 }
202
203 fn inner_ref(&self) -> &R {
204 match &self.inner {
205 Some(inner) => inner,
206 None => unreachable!("stream decoder reader inner reader was already taken"),
207 }
208 }
209
210 fn inner_mut(&mut self) -> &mut R {
211 match &mut self.inner {
212 Some(inner) => inner,
213 None => unreachable!("stream decoder reader inner reader was already taken"),
214 }
215 }
216
217 fn take_inner(&mut self) -> R {
218 match self.inner.take() {
219 Some(inner) => inner,
220 None => unreachable!("stream decoder reader inner reader was already taken"),
221 }
222 }
223
224 fn clear_pending(&mut self) {
225 self.driver.wipe();
226 }
227}
228
229impl<R, A, const PAD: bool> Drop for DecoderReader<R, A, PAD>
230where
231 A: Alphabet,
232{
233 fn drop(&mut self) {
234 self.clear_pending();
235 self.output.clear_all();
236 }
237}
238
239impl<R, A, const PAD: bool> core::fmt::Debug for DecoderReader<R, A, PAD>
240where
241 A: Alphabet,
242{
243 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
244 formatter
245 .debug_struct("DecoderReader")
246 .field("inner", &redacted_inner_state(self.inner.is_some()))
247 .field("engine", &self.engine)
248 .field("driver", &"<redacted>")
249 .field("pending", &"<redacted>")
250 .field("pending_len", &self.pending_len())
251 .field("pending_input_needed_len", &self.pending_input_needed_len())
252 .field("buffered_output_len", &self.output.len())
253 .field("buffered_output_capacity", &self.output.capacity())
254 .field(
255 "buffered_output_remaining_capacity",
256 &self.output.available_capacity(),
257 )
258 .field("can_into_inner", &self.can_into_inner())
259 .field("finished", &self.finished)
260 .field("terminal_padding", &self.terminal_seen)
261 .field("failed", &self.failed)
262 .finish()
263 }
264}
265
266impl<R, A, const PAD: bool> Read for DecoderReader<R, A, PAD>
267where
268 R: Read,
269 A: Alphabet,
270{
271 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
272 if output.is_empty() {
273 return Ok(0);
274 }
275 if self.failed {
276 return Err(stream_decoder_failed_error());
277 }
278
279 while self.output.is_empty() && !self.finished {
280 self.fill_output()?;
281 }
282
283 Ok(self.output.pop_slice(output))
284 }
285}
286
287impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
288where
289 R: Read,
290 A: Alphabet,
291{
292 fn fill_output(&mut self) -> io::Result<()> {
293 if self.failed {
294 return Err(stream_decoder_failed_error());
295 }
296 if self.terminal_seen {
297 self.finished = true;
298 return Ok(());
299 }
300
301 let mut input = [0u8; 4];
302 let available = 4 - self.pending_len();
303 let read = match self.inner_mut().read(&mut input[..available]) {
304 Ok(read) => read,
305 Err(err) => {
306 crate::wipe_bytes(&mut input);
307 return Err(err);
308 }
309 };
310 if read > available {
311 crate::wipe_bytes(&mut input);
312 self.clear_pending();
313 self.failed = true;
314 return Err(wrapped_reader_overreported_error());
315 }
316 if read == 0 {
317 crate::wipe_bytes(&mut input);
318 self.finished = true;
319 self.finish_driver()?;
320 return Ok(());
321 }
322
323 let result = self.update_driver(&input[..read]);
324 crate::wipe_bytes(&mut input);
325 result?;
326 self.terminal_seen = self.driver.has_terminal_padding();
327 if self.terminal_seen {
328 self.finished = true;
329 }
330 Ok(())
331 }
332
333 fn update_driver(&mut self, input: &[u8]) -> io::Result<()> {
334 let mut decoded = [0u8; 3];
335 let step = match self.driver.update(input, &mut decoded) {
336 Ok(step) => step,
337 Err(err) => {
338 crate::wipe_bytes(&mut decoded);
339 self.failed = true;
340 self.clear_pending();
341 return Err(err);
342 }
343 };
344 let progress = step.progress();
345 let result = if progress.input_consumed() == input.len() {
346 self.output
347 .push_slice(&decoded[..progress.output_produced()])
348 } else {
349 Err(io::Error::other(
350 "base64 stream decoder did not accept bounded reader input",
351 ))
352 };
353 crate::wipe_bytes(&mut decoded);
354 if result.is_err() {
355 self.failed = true;
356 }
357 result
358 }
359
360 fn finish_driver(&mut self) -> io::Result<()> {
361 let mut decoded = [0u8; 3];
362 let step = match self.driver.finish(&mut decoded) {
363 Ok(step) => step,
364 Err(err) => {
365 crate::wipe_bytes(&mut decoded);
366 self.failed = true;
367 self.clear_pending();
368 return Err(err);
369 }
370 };
371 let result = self
372 .output
373 .push_slice(&decoded[..step.progress().output_produced()]);
374 crate::wipe_bytes(&mut decoded);
375 if result.is_err() {
376 self.failed = true;
377 }
378 result
379 }
380}