base64_ng/stream/
decoder_reader.rs1use super::{OutputQueue, decode_error_to_io, redacted_inner_state, stream_decoder_failed_error};
2use crate::{Alphabet, Engine};
3use std::io::{self, Read};
4
5pub struct DecoderReader<R, A, const PAD: bool>
20where
21 A: Alphabet,
22{
23 inner: Option<R>,
24 engine: Engine<A, PAD>,
25 pending: [u8; 4],
26 pending_len: usize,
27 output: OutputQueue<3>,
28 finished: bool,
29 terminal_seen: bool,
30 failed: bool,
31}
32
33impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
34where
35 A: Alphabet,
36{
37 #[must_use]
44 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
45 Self {
46 inner: Some(inner),
47 engine,
48 pending: [0; 4],
49 pending_len: 0,
50 output: OutputQueue::new(),
51 finished: false,
52 terminal_seen: false,
53 failed: false,
54 }
55 }
56
57 #[must_use]
59 pub fn get_ref(&self) -> &R {
60 self.inner_ref()
61 }
62
63 pub fn get_mut(&mut self) -> &mut R {
65 self.inner_mut()
66 }
67
68 #[must_use]
70 pub const fn engine(&self) -> Engine<A, PAD> {
71 self.engine
72 }
73
74 #[must_use]
76 pub const fn is_padded(&self) -> bool {
77 PAD
78 }
79
80 #[must_use]
83 pub const fn pending_len(&self) -> usize {
84 self.pending_len
85 }
86
87 #[must_use]
90 pub const fn has_pending_input(&self) -> bool {
91 self.pending_len != 0
92 }
93
94 #[must_use]
99 pub const fn pending_input_needed_len(&self) -> usize {
100 if self.has_pending_input() {
101 4 - self.pending_len
102 } else {
103 0
104 }
105 }
106
107 #[must_use]
110 pub const fn buffered_output_len(&self) -> usize {
111 self.output.len()
112 }
113
114 #[must_use]
117 pub const fn buffered_output_capacity(&self) -> usize {
118 self.output.capacity()
119 }
120
121 #[must_use]
124 pub const fn buffered_output_remaining_capacity(&self) -> usize {
125 self.output.available_capacity()
126 }
127
128 #[must_use]
131 pub const fn has_buffered_output(&self) -> bool {
132 !self.output.is_empty()
133 }
134
135 #[must_use]
142 pub const fn has_terminal_padding(&self) -> bool {
143 self.terminal_seen
144 }
145
146 #[must_use]
152 pub const fn has_finished_input(&self) -> bool {
153 self.finished
154 }
155
156 #[must_use]
159 pub const fn is_finished(&self) -> bool {
160 self.finished && self.output.is_empty()
161 }
162
163 #[must_use]
170 pub const fn is_failed(&self) -> bool {
171 self.failed
172 }
173
174 #[must_use]
177 pub const fn can_into_inner(&self) -> bool {
178 !self.is_failed() && self.is_finished()
179 }
180
181 #[must_use]
183 pub fn into_inner(mut self) -> R {
184 self.take_inner()
185 }
186
187 #[allow(clippy::result_large_err)]
195 pub fn try_into_inner(mut self) -> Result<R, Self> {
196 if !self.can_into_inner() {
197 return Err(self);
198 }
199 Ok(self.take_inner())
200 }
201
202 fn inner_ref(&self) -> &R {
203 match &self.inner {
204 Some(inner) => inner,
205 None => unreachable!("stream decoder reader inner reader was already taken"),
206 }
207 }
208
209 fn inner_mut(&mut self) -> &mut R {
210 match &mut self.inner {
211 Some(inner) => inner,
212 None => unreachable!("stream decoder reader inner reader was already taken"),
213 }
214 }
215
216 fn take_inner(&mut self) -> R {
217 match self.inner.take() {
218 Some(inner) => inner,
219 None => unreachable!("stream decoder reader inner reader was already taken"),
220 }
221 }
222
223 fn clear_pending(&mut self) {
224 crate::wipe_bytes(&mut self.pending);
225 self.pending_len = 0;
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("pending", &"<redacted>")
249 .field("pending_len", &self.pending_len)
250 .field("pending_input_needed_len", &self.pending_input_needed_len())
251 .field("buffered_output_len", &self.output.len())
252 .field("buffered_output_capacity", &self.output.capacity())
253 .field(
254 "buffered_output_remaining_capacity",
255 &self.output.available_capacity(),
256 )
257 .field("can_into_inner", &self.can_into_inner())
258 .field("finished", &self.finished)
259 .field("terminal_padding", &self.terminal_seen)
260 .field("failed", &self.failed)
261 .finish()
262 }
263}
264
265impl<R, A, const PAD: bool> Read for DecoderReader<R, A, PAD>
266where
267 R: Read,
268 A: Alphabet,
269{
270 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
271 if output.is_empty() {
272 return Ok(0);
273 }
274 if self.failed {
275 return Err(stream_decoder_failed_error());
276 }
277
278 while self.output.is_empty() && !self.finished {
279 self.fill_output()?;
280 }
281
282 Ok(self.output.pop_slice(output))
283 }
284}
285
286impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
287where
288 R: Read,
289 A: Alphabet,
290{
291 fn fill_output(&mut self) -> io::Result<()> {
292 if self.failed {
293 return Err(stream_decoder_failed_error());
294 }
295 if self.terminal_seen {
296 self.finished = true;
297 return Ok(());
298 }
299
300 let mut input = [0u8; 4];
301 let available = 4 - self.pending_len;
302 let read = match self.inner_mut().read(&mut input[..available]) {
303 Ok(read) => read,
304 Err(err) => {
305 crate::wipe_bytes(&mut input);
306 return Err(err);
307 }
308 };
309 if read == 0 {
310 crate::wipe_bytes(&mut input);
311 self.finished = true;
312 self.push_final_pending()?;
313 return Ok(());
314 }
315
316 self.pending[self.pending_len..self.pending_len + read].copy_from_slice(&input[..read]);
317 crate::wipe_bytes(&mut input);
318 self.pending_len += read;
319 if self.pending_len < 4 {
320 return Ok(());
321 }
322
323 let mut quad = self.pending;
324 self.clear_pending();
325 let result = self.push_decoded(&quad);
326 crate::wipe_bytes(&mut quad);
327 result?;
328 if self.terminal_seen {
329 self.finished = true;
330 }
331 Ok(())
332 }
333
334 fn push_final_pending(&mut self) -> io::Result<()> {
335 if self.pending_len == 0 {
336 return Ok(());
337 }
338
339 let mut pending = [0u8; 4];
340 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
341 let pending_len = self.pending_len;
342 self.clear_pending();
343 let result = self.push_decoded(&pending[..pending_len]);
344 crate::wipe_bytes(&mut pending);
345 result
346 }
347
348 fn push_decoded(&mut self, input: &[u8]) -> io::Result<()> {
349 let mut decoded = [0u8; 3];
350 let written = match self.engine.decode_slice(input, &mut decoded) {
351 Ok(written) => written,
352 Err(err) => {
353 crate::wipe_bytes(&mut decoded);
354 self.failed = true;
355 return Err(decode_error_to_io(err));
356 }
357 };
358 let result = self.output.push_slice(&decoded[..written]);
359 crate::wipe_bytes(&mut decoded);
360 if result.is_err() {
361 self.failed = true;
362 }
363 result?;
364 if input.len() == 4 && written < 3 {
365 self.terminal_seen = true;
366 }
367 Ok(())
368 }
369}