1use super::{Alphabet, DecodeError, EncodeError, Engine};
36use std::io::{self, Read, Write};
37
38struct OutputQueue<const CAP: usize> {
39 buffer: [u8; CAP],
40 start: usize,
41 len: usize,
42}
43
44impl<const CAP: usize> OutputQueue<CAP> {
45 const fn new() -> Self {
46 Self {
47 buffer: [0; CAP],
48 start: 0,
49 len: 0,
50 }
51 }
52
53 const fn is_empty(&self) -> bool {
54 self.len == 0
55 }
56
57 const fn len(&self) -> usize {
58 self.len
59 }
60
61 const fn capacity(&self) -> usize {
62 self.len + self.available_capacity()
63 }
64
65 fn push_slice(&mut self, input: &[u8]) -> io::Result<()> {
66 if input.len() > self.available_capacity() {
67 return Err(io::Error::other(
68 "base64 stream output queue capacity exceeded",
69 ));
70 }
71
72 let mut read = 0;
73 while read < input.len() {
74 let write = (self.start + self.len) % CAP;
75 self.buffer[write] = input[read];
76 self.len += 1;
77 read += 1;
78 }
79
80 Ok(())
81 }
82
83 fn copy_front(&self, output: &mut [u8]) -> usize {
84 let count = core::cmp::min(self.len, output.len());
85 let first = core::cmp::min(count, CAP - self.start);
86 output[..first].copy_from_slice(&self.buffer[self.start..self.start + first]);
87
88 let second = count - first;
89 if second > 0 {
90 output[first..first + second].copy_from_slice(&self.buffer[..second]);
91 }
92
93 count
94 }
95
96 fn discard_front(&mut self, count: usize) {
97 let count = core::cmp::min(count, self.len);
98 let first = core::cmp::min(count, CAP - self.start);
99 crate::wipe_bytes(&mut self.buffer[self.start..self.start + first]);
100
101 let second = count - first;
102 if second > 0 {
103 crate::wipe_bytes(&mut self.buffer[..second]);
104 }
105
106 self.start = (self.start + count) % CAP;
107 self.len -= count;
108 if self.len == 0 {
109 self.start = 0;
110 }
111 }
112
113 fn pop_slice(&mut self, output: &mut [u8]) -> usize {
114 let count = self.copy_front(output);
115 self.discard_front(count);
116 count
117 }
118
119 fn clear_all(&mut self) {
120 crate::wipe_bytes(&mut self.buffer);
121 self.start = 0;
122 self.len = 0;
123 }
124
125 const fn available_capacity(&self) -> usize {
126 CAP - self.len
127 }
128}
129
130pub struct Encoder<W, A, const PAD: bool>
138where
139 A: Alphabet,
140{
141 inner: Option<W>,
142 engine: Engine<A, PAD>,
143 pending: [u8; 2],
144 pending_len: usize,
145 output: OutputQueue<1024>,
146 finalized: bool,
147}
148
149impl<W, A, const PAD: bool> Encoder<W, A, PAD>
150where
151 A: Alphabet,
152{
153 #[must_use]
155 pub const fn new(inner: W, engine: Engine<A, PAD>) -> Self {
156 Self {
157 inner: Some(inner),
158 engine,
159 pending: [0; 2],
160 pending_len: 0,
161 output: OutputQueue::new(),
162 finalized: false,
163 }
164 }
165
166 #[must_use]
168 pub fn get_ref(&self) -> &W {
169 self.inner_ref()
170 }
171
172 pub fn get_mut(&mut self) -> &mut W {
174 self.inner_mut()
175 }
176
177 #[must_use]
179 pub const fn engine(&self) -> Engine<A, PAD> {
180 self.engine
181 }
182
183 #[must_use]
185 pub const fn is_padded(&self) -> bool {
186 PAD
187 }
188
189 #[must_use]
192 pub const fn pending_len(&self) -> usize {
193 self.pending_len
194 }
195
196 #[must_use]
199 pub const fn has_pending_input(&self) -> bool {
200 self.pending_len != 0
201 }
202
203 #[must_use]
208 pub const fn pending_input_needed_len(&self) -> usize {
209 if self.has_pending_input() {
210 3 - self.pending_len
211 } else {
212 0
213 }
214 }
215
216 #[must_use]
219 pub const fn buffered_output_len(&self) -> usize {
220 self.output.len()
221 }
222
223 #[must_use]
226 pub const fn buffered_output_capacity(&self) -> usize {
227 self.output.capacity()
228 }
229
230 #[must_use]
233 pub const fn buffered_output_remaining_capacity(&self) -> usize {
234 self.output.available_capacity()
235 }
236
237 #[must_use]
240 pub const fn has_buffered_output(&self) -> bool {
241 !self.output.is_empty()
242 }
243
244 #[must_use]
248 pub const fn is_finalized(&self) -> bool {
249 self.finalized
250 }
251
252 #[must_use]
255 pub const fn can_into_inner(&self) -> bool {
256 !self.has_pending_input() && !self.has_buffered_output()
257 }
258
259 #[must_use]
263 pub fn into_inner(mut self) -> W {
264 self.take_inner()
265 }
266
267 #[allow(clippy::result_large_err)]
273 pub fn try_into_inner(mut self) -> Result<W, Self> {
274 if !self.can_into_inner() {
275 return Err(self);
276 }
277 Ok(self.take_inner())
278 }
279
280 fn inner_ref(&self) -> &W {
281 match &self.inner {
282 Some(inner) => inner,
283 None => unreachable!("stream encoder inner writer was already taken"),
284 }
285 }
286
287 fn inner_mut(&mut self) -> &mut W {
288 match &mut self.inner {
289 Some(inner) => inner,
290 None => unreachable!("stream encoder inner writer was already taken"),
291 }
292 }
293
294 fn take_inner(&mut self) -> W {
295 match self.inner.take() {
296 Some(inner) => inner,
297 None => unreachable!("stream encoder inner writer was already taken"),
298 }
299 }
300
301 fn clear_pending(&mut self) {
302 crate::wipe_bytes(&mut self.pending);
303 self.pending_len = 0;
304 }
305
306 fn clear_output(&mut self) {
307 self.output.clear_all();
308 }
309}
310
311impl<W, A, const PAD: bool> Drop for Encoder<W, A, PAD>
312where
313 A: Alphabet,
314{
315 fn drop(&mut self) {
316 self.clear_pending();
317 self.clear_output();
318 }
319}
320
321impl<W, A, const PAD: bool> core::fmt::Debug for Encoder<W, A, PAD>
322where
323 A: Alphabet,
324{
325 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
326 formatter
327 .debug_struct("Encoder")
328 .field("inner", &redacted_inner_state(self.inner.is_some()))
329 .field("engine", &self.engine)
330 .field("pending", &"<redacted>")
331 .field("pending_len", &self.pending_len)
332 .field("pending_input_needed_len", &self.pending_input_needed_len())
333 .field("buffered_output_len", &self.output.len())
334 .field("buffered_output_capacity", &self.output.capacity())
335 .field(
336 "buffered_output_remaining_capacity",
337 &self.output.available_capacity(),
338 )
339 .field("can_into_inner", &self.can_into_inner())
340 .field("finalized", &self.finalized)
341 .finish()
342 }
343}
344
345impl<W, A, const PAD: bool> Encoder<W, A, PAD>
346where
347 W: Write,
348 A: Alphabet,
349{
350 pub fn try_finish(&mut self) -> io::Result<()> {
360 if !self.finalized {
361 self.queue_pending_final()?;
362 self.finalized = true;
363 }
364 self.flush()
365 }
366
367 pub fn finish(mut self) -> io::Result<W> {
369 self.try_finish()?;
370 Ok(self.take_inner())
371 }
372
373 fn queue_pending_final(&mut self) -> io::Result<()> {
374 if self.pending_len == 0 {
375 return Ok(());
376 }
377
378 let mut pending = [0u8; 2];
379 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
380 let pending_len = self.pending_len;
381 let mut encoded = [0u8; 4];
382 let result = self.queue_encoded_temp(&pending[..pending_len], &mut encoded);
383 crate::wipe_bytes(&mut pending);
384 result?;
385 self.clear_pending();
386 Ok(())
387 }
388
389 fn queue_encoded_temp(&mut self, input: &[u8], encoded: &mut [u8]) -> io::Result<()> {
390 let written = match self.engine.encode_slice(input, encoded) {
391 Ok(written) => written,
392 Err(err) => {
393 crate::wipe_bytes(encoded);
394 return Err(encode_error_to_io(err));
395 }
396 };
397
398 let result = self.output.push_slice(&encoded[..written]);
399 crate::wipe_bytes(encoded);
400 result
401 }
402
403 fn drain_output(&mut self) -> io::Result<()> {
404 let mut chunk = [0u8; 1024];
405 while !self.output.is_empty() {
406 let pending = self.output.copy_front(&mut chunk);
407 let result = self.inner_mut().write(&chunk[..pending]);
408 crate::wipe_bytes(&mut chunk[..pending]);
409 match result {
410 Ok(0) => {
411 return Err(io::Error::new(
412 io::ErrorKind::WriteZero,
413 "base64 stream encoder could not drain buffered output",
414 ));
415 }
416 Ok(written) => {
417 if written > pending {
418 return Err(io::Error::new(
419 io::ErrorKind::InvalidData,
420 "wrapped writer reported more bytes than provided",
421 ));
422 }
423 self.output.discard_front(written);
424 }
425 Err(err) => return Err(err),
426 }
427 }
428
429 Ok(())
430 }
431}
432
433impl<W, A, const PAD: bool> Write for Encoder<W, A, PAD>
434where
435 W: Write,
436 A: Alphabet,
437{
438 fn write(&mut self, input: &[u8]) -> io::Result<usize> {
439 self.drain_output()?;
440 if self.finalized {
441 return Err(io::Error::new(
442 io::ErrorKind::InvalidInput,
443 "base64 stream encoder received input after finalization",
444 ));
445 }
446 if input.is_empty() {
447 return Ok(0);
448 }
449
450 let mut consumed = 0;
451 if self.pending_len > 0 {
452 let needed = 3 - self.pending_len;
453 if input.len() < needed {
454 self.pending[self.pending_len..self.pending_len + input.len()]
455 .copy_from_slice(input);
456 self.pending_len += input.len();
457 return Ok(input.len());
458 }
459
460 let mut chunk = [0u8; 3];
461 chunk[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
462 chunk[self.pending_len..].copy_from_slice(&input[..needed]);
463
464 let mut encoded = [0u8; 4];
465 let result = self.queue_encoded_temp(&chunk, &mut encoded);
466 crate::wipe_bytes(&mut chunk);
467 result?;
468 self.clear_pending();
469 consumed += needed;
470 }
471
472 let remaining = &input[consumed..];
473 let full_len = remaining.len() / 3 * 3;
474 if full_len > 0 {
475 let max_by_queue = self.output.available_capacity() / 4 * 3;
476 let mut take = core::cmp::min(full_len, core::cmp::min(768, max_by_queue));
477 take -= take % 3;
478
479 if take == 0 {
480 return Ok(consumed);
481 }
482
483 let mut encoded = [0u8; 1024];
484 self.queue_encoded_temp(&remaining[..take], &mut encoded)?;
485 consumed += take;
486
487 if take < full_len {
488 return Ok(consumed);
489 }
490 }
491
492 let tail = &input[consumed..];
493 self.pending[..tail.len()].copy_from_slice(tail);
494 self.pending_len = tail.len();
495 consumed += tail.len();
496
497 Ok(consumed)
498 }
499
500 fn flush(&mut self) -> io::Result<()> {
501 self.drain_output()?;
502 self.inner_mut().flush()
503 }
504}
505
506fn encode_error_to_io(err: EncodeError) -> io::Error {
507 io::Error::new(io::ErrorKind::InvalidInput, err)
508}
509
510pub struct Decoder<W, A, const PAD: bool>
526where
527 A: Alphabet,
528{
529 inner: Option<W>,
530 engine: Engine<A, PAD>,
531 pending: [u8; 4],
532 pending_len: usize,
533 output: OutputQueue<1024>,
534 finished: bool,
535 failed: bool,
536 finalized: bool,
537}
538
539impl<W, A, const PAD: bool> Decoder<W, A, PAD>
540where
541 A: Alphabet,
542{
543 #[must_use]
550 pub const fn new(inner: W, engine: Engine<A, PAD>) -> Self {
551 Self {
552 inner: Some(inner),
553 engine,
554 pending: [0; 4],
555 pending_len: 0,
556 output: OutputQueue::new(),
557 finished: false,
558 finalized: false,
559 failed: false,
560 }
561 }
562
563 #[must_use]
565 pub fn get_ref(&self) -> &W {
566 self.inner_ref()
567 }
568
569 pub fn get_mut(&mut self) -> &mut W {
571 self.inner_mut()
572 }
573
574 #[must_use]
576 pub const fn engine(&self) -> Engine<A, PAD> {
577 self.engine
578 }
579
580 #[must_use]
582 pub const fn is_padded(&self) -> bool {
583 PAD
584 }
585
586 #[must_use]
589 pub const fn pending_len(&self) -> usize {
590 self.pending_len
591 }
592
593 #[must_use]
596 pub const fn has_pending_input(&self) -> bool {
597 self.pending_len != 0
598 }
599
600 #[must_use]
605 pub const fn pending_input_needed_len(&self) -> usize {
606 if self.has_pending_input() {
607 4 - self.pending_len
608 } else {
609 0
610 }
611 }
612
613 #[must_use]
616 pub const fn buffered_output_len(&self) -> usize {
617 self.output.len()
618 }
619
620 #[must_use]
623 pub const fn buffered_output_capacity(&self) -> usize {
624 self.output.capacity()
625 }
626
627 #[must_use]
630 pub const fn buffered_output_remaining_capacity(&self) -> usize {
631 self.output.available_capacity()
632 }
633
634 #[must_use]
637 pub const fn has_buffered_output(&self) -> bool {
638 !self.output.is_empty()
639 }
640
641 #[must_use]
647 pub const fn has_terminal_padding(&self) -> bool {
648 self.finished
649 }
650
651 #[must_use]
655 pub const fn is_finalized(&self) -> bool {
656 self.finalized
657 }
658
659 #[must_use]
665 pub const fn is_failed(&self) -> bool {
666 self.failed
667 }
668
669 #[must_use]
672 pub const fn can_into_inner(&self) -> bool {
673 !self.is_failed() && !self.has_pending_input() && !self.has_buffered_output()
674 }
675
676 #[must_use]
680 pub fn into_inner(mut self) -> W {
681 self.take_inner()
682 }
683
684 #[allow(clippy::result_large_err)]
690 pub fn try_into_inner(mut self) -> Result<W, Self> {
691 if !self.can_into_inner() {
692 return Err(self);
693 }
694 Ok(self.take_inner())
695 }
696
697 fn inner_ref(&self) -> &W {
698 match &self.inner {
699 Some(inner) => inner,
700 None => unreachable!("stream decoder inner writer was already taken"),
701 }
702 }
703
704 fn inner_mut(&mut self) -> &mut W {
705 match &mut self.inner {
706 Some(inner) => inner,
707 None => unreachable!("stream decoder inner writer was already taken"),
708 }
709 }
710
711 fn take_inner(&mut self) -> W {
712 match self.inner.take() {
713 Some(inner) => inner,
714 None => unreachable!("stream decoder inner writer was already taken"),
715 }
716 }
717
718 fn clear_pending(&mut self) {
719 crate::wipe_bytes(&mut self.pending);
720 self.pending_len = 0;
721 }
722
723 fn clear_output(&mut self) {
724 self.output.clear_all();
725 }
726}
727
728impl<W, A, const PAD: bool> Drop for Decoder<W, A, PAD>
729where
730 A: Alphabet,
731{
732 fn drop(&mut self) {
733 self.clear_pending();
734 self.clear_output();
735 }
736}
737
738impl<W, A, const PAD: bool> core::fmt::Debug for Decoder<W, A, PAD>
739where
740 A: Alphabet,
741{
742 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
743 formatter
744 .debug_struct("Decoder")
745 .field("inner", &redacted_inner_state(self.inner.is_some()))
746 .field("engine", &self.engine)
747 .field("pending", &"<redacted>")
748 .field("pending_len", &self.pending_len)
749 .field("pending_input_needed_len", &self.pending_input_needed_len())
750 .field("buffered_output_len", &self.output.len())
751 .field("buffered_output_capacity", &self.output.capacity())
752 .field(
753 "buffered_output_remaining_capacity",
754 &self.output.available_capacity(),
755 )
756 .field("can_into_inner", &self.can_into_inner())
757 .field("terminal_padding", &self.finished)
758 .field("finalized", &self.finalized)
759 .field("failed", &self.failed)
760 .finish()
761 }
762}
763
764impl<W, A, const PAD: bool> Decoder<W, A, PAD>
765where
766 W: Write,
767 A: Alphabet,
768{
769 pub fn try_finish(&mut self) -> io::Result<()> {
779 if self.failed {
780 return Err(stream_decoder_failed_error());
781 }
782 if !self.finalized {
783 self.queue_pending_final()?;
784 self.finalized = true;
785 }
786 self.flush()
787 }
788
789 pub fn finish(mut self) -> io::Result<W> {
791 self.try_finish()?;
792 Ok(self.take_inner())
793 }
794
795 fn queue_pending_final(&mut self) -> io::Result<()> {
796 if self.pending_len == 0 {
797 return Ok(());
798 }
799
800 let mut pending = [0u8; 4];
801 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
802 let pending_len = self.pending_len;
803 let mut decoded = [0u8; 3];
804 let result = self.queue_decoded_temp(&pending[..pending_len], &mut decoded);
805 crate::wipe_bytes(&mut pending);
806 if let Err(err) = result {
807 self.clear_pending();
808 return Err(err);
809 }
810 self.clear_pending();
811 Ok(())
812 }
813
814 fn queue_full_quad(&mut self, mut input: [u8; 4]) -> io::Result<()> {
815 let mut decoded = [0u8; 3];
816 let result = self.queue_decoded_temp(&input, &mut decoded);
817 crate::wipe_bytes(&mut input);
818 let written = result?;
819 if written < 3 {
820 self.finished = true;
821 }
822 Ok(())
823 }
824
825 fn queue_decoded_temp(&mut self, input: &[u8], decoded: &mut [u8]) -> io::Result<usize> {
826 let written = match self.engine.decode_slice(input, decoded) {
827 Ok(written) => written,
828 Err(err) => {
829 crate::wipe_bytes(decoded);
830 self.failed = true;
831 return Err(decode_error_to_io(err));
832 }
833 };
834
835 let result = self.output.push_slice(&decoded[..written]);
836 crate::wipe_bytes(decoded);
837 result?;
838 Ok(written)
839 }
840
841 fn drain_output(&mut self) -> io::Result<()> {
842 let mut chunk = [0u8; 1024];
843 while !self.output.is_empty() {
844 let pending = self.output.copy_front(&mut chunk);
845 let result = self.inner_mut().write(&chunk[..pending]);
846 crate::wipe_bytes(&mut chunk[..pending]);
847 match result {
848 Ok(0) => {
849 return Err(io::Error::new(
850 io::ErrorKind::WriteZero,
851 "base64 stream decoder could not drain buffered output",
852 ));
853 }
854 Ok(written) => {
855 if written > pending {
856 return Err(io::Error::new(
857 io::ErrorKind::InvalidData,
858 "wrapped writer reported more bytes than provided",
859 ));
860 }
861 self.output.discard_front(written);
862 }
863 Err(err) => return Err(err),
864 }
865 }
866
867 Ok(())
868 }
869}
870
871impl<W, A, const PAD: bool> Write for Decoder<W, A, PAD>
872where
873 W: Write,
874 A: Alphabet,
875{
876 fn write(&mut self, input: &[u8]) -> io::Result<usize> {
877 if self.failed {
878 return Err(stream_decoder_failed_error());
879 }
880 if input.is_empty() {
881 self.drain_output()?;
882 return Ok(0);
883 }
884 self.drain_output()?;
885 if self.finalized {
886 return Err(io::Error::new(
887 io::ErrorKind::InvalidInput,
888 "base64 stream decoder received input after finalization",
889 ));
890 }
891 if self.finished {
892 self.failed = true;
893 return Err(trailing_input_after_padding_error());
894 }
895
896 let mut consumed = 0;
897 if self.pending_len > 0 {
898 let needed = 4 - self.pending_len;
899 if input.len() < needed {
900 self.pending[self.pending_len..self.pending_len + input.len()]
901 .copy_from_slice(input);
902 self.pending_len += input.len();
903 return Ok(input.len());
904 }
905
906 let mut quad = [0u8; 4];
907 quad[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
908 quad[self.pending_len..].copy_from_slice(&input[..needed]);
909 let result = self.queue_full_quad(quad);
910 crate::wipe_bytes(&mut quad);
911 if let Err(err) = result {
912 self.clear_pending();
913 return Err(err);
914 }
915 self.clear_pending();
916 consumed += needed;
917
918 if self.finished {
919 return Ok(consumed);
920 }
921 }
922
923 while input.len() - consumed >= 4 {
924 if self.output.available_capacity() < 3 {
925 return Ok(consumed);
926 }
927
928 let mut quad = [
929 input[consumed],
930 input[consumed + 1],
931 input[consumed + 2],
932 input[consumed + 3],
933 ];
934 let mut decoded = [0u8; 3];
935 let written = match self.engine.decode_slice(&quad, &mut decoded) {
936 Ok(written) => written,
937 Err(err) => {
938 crate::wipe_bytes(&mut quad);
939 crate::wipe_bytes(&mut decoded);
940 self.failed = true;
941 if consumed > 0 {
942 return Ok(consumed);
943 }
944
945 return Err(decode_error_to_io(err));
946 }
947 };
948
949 let result = self.output.push_slice(&decoded[..written]);
950 crate::wipe_bytes(&mut quad);
951 crate::wipe_bytes(&mut decoded);
952 result?;
953 consumed += 4;
954
955 if written < 3 {
956 self.finished = true;
957 return Ok(consumed);
958 }
959 }
960
961 let tail = &input[consumed..];
962 self.pending[..tail.len()].copy_from_slice(tail);
963 self.pending_len = tail.len();
964 consumed += tail.len();
965
966 Ok(consumed)
967 }
968
969 fn flush(&mut self) -> io::Result<()> {
970 if self.failed {
971 return Err(stream_decoder_failed_error());
972 }
973 self.drain_output()?;
974 self.inner_mut().flush()
975 }
976}
977
978fn decode_error_to_io(err: DecodeError) -> io::Error {
979 io::Error::new(io::ErrorKind::InvalidInput, err)
980}
981
982fn trailing_input_after_padding_error() -> io::Error {
983 io::Error::new(
984 io::ErrorKind::InvalidInput,
985 "base64 decoder received trailing input after padding",
986 )
987}
988
989fn stream_decoder_failed_error() -> io::Error {
990 io::Error::new(
991 io::ErrorKind::InvalidInput,
992 "base64 stream decoder is failed after malformed input",
993 )
994}
995
996fn stream_encoder_failed_error() -> io::Error {
997 io::Error::new(
998 io::ErrorKind::InvalidInput,
999 "base64 stream encoder is failed after internal error",
1000 )
1001}
1002
1003pub struct DecoderReader<R, A, const PAD: bool>
1018where
1019 A: Alphabet,
1020{
1021 inner: Option<R>,
1022 engine: Engine<A, PAD>,
1023 pending: [u8; 4],
1024 pending_len: usize,
1025 output: OutputQueue<3>,
1026 finished: bool,
1027 terminal_seen: bool,
1028 failed: bool,
1029}
1030
1031impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
1032where
1033 A: Alphabet,
1034{
1035 #[must_use]
1042 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
1043 Self {
1044 inner: Some(inner),
1045 engine,
1046 pending: [0; 4],
1047 pending_len: 0,
1048 output: OutputQueue::new(),
1049 finished: false,
1050 terminal_seen: false,
1051 failed: false,
1052 }
1053 }
1054
1055 #[must_use]
1057 pub fn get_ref(&self) -> &R {
1058 self.inner_ref()
1059 }
1060
1061 pub fn get_mut(&mut self) -> &mut R {
1063 self.inner_mut()
1064 }
1065
1066 #[must_use]
1068 pub const fn engine(&self) -> Engine<A, PAD> {
1069 self.engine
1070 }
1071
1072 #[must_use]
1074 pub const fn is_padded(&self) -> bool {
1075 PAD
1076 }
1077
1078 #[must_use]
1081 pub const fn pending_len(&self) -> usize {
1082 self.pending_len
1083 }
1084
1085 #[must_use]
1088 pub const fn has_pending_input(&self) -> bool {
1089 self.pending_len != 0
1090 }
1091
1092 #[must_use]
1097 pub const fn pending_input_needed_len(&self) -> usize {
1098 if self.has_pending_input() {
1099 4 - self.pending_len
1100 } else {
1101 0
1102 }
1103 }
1104
1105 #[must_use]
1108 pub const fn buffered_output_len(&self) -> usize {
1109 self.output.len()
1110 }
1111
1112 #[must_use]
1115 pub const fn buffered_output_capacity(&self) -> usize {
1116 self.output.capacity()
1117 }
1118
1119 #[must_use]
1122 pub const fn buffered_output_remaining_capacity(&self) -> usize {
1123 self.output.available_capacity()
1124 }
1125
1126 #[must_use]
1129 pub const fn has_buffered_output(&self) -> bool {
1130 !self.output.is_empty()
1131 }
1132
1133 #[must_use]
1140 pub const fn has_terminal_padding(&self) -> bool {
1141 self.terminal_seen
1142 }
1143
1144 #[must_use]
1150 pub const fn has_finished_input(&self) -> bool {
1151 self.finished
1152 }
1153
1154 #[must_use]
1157 pub const fn is_finished(&self) -> bool {
1158 self.finished && self.output.is_empty()
1159 }
1160
1161 #[must_use]
1168 pub const fn is_failed(&self) -> bool {
1169 self.failed
1170 }
1171
1172 #[must_use]
1175 pub const fn can_into_inner(&self) -> bool {
1176 !self.is_failed() && self.is_finished()
1177 }
1178
1179 #[must_use]
1181 pub fn into_inner(mut self) -> R {
1182 self.take_inner()
1183 }
1184
1185 #[allow(clippy::result_large_err)]
1193 pub fn try_into_inner(mut self) -> Result<R, Self> {
1194 if !self.can_into_inner() {
1195 return Err(self);
1196 }
1197 Ok(self.take_inner())
1198 }
1199
1200 fn inner_ref(&self) -> &R {
1201 match &self.inner {
1202 Some(inner) => inner,
1203 None => unreachable!("stream decoder reader inner reader was already taken"),
1204 }
1205 }
1206
1207 fn inner_mut(&mut self) -> &mut R {
1208 match &mut self.inner {
1209 Some(inner) => inner,
1210 None => unreachable!("stream decoder reader inner reader was already taken"),
1211 }
1212 }
1213
1214 fn take_inner(&mut self) -> R {
1215 match self.inner.take() {
1216 Some(inner) => inner,
1217 None => unreachable!("stream decoder reader inner reader was already taken"),
1218 }
1219 }
1220
1221 fn clear_pending(&mut self) {
1222 crate::wipe_bytes(&mut self.pending);
1223 self.pending_len = 0;
1224 }
1225}
1226
1227impl<R, A, const PAD: bool> Drop for DecoderReader<R, A, PAD>
1228where
1229 A: Alphabet,
1230{
1231 fn drop(&mut self) {
1232 self.clear_pending();
1233 self.output.clear_all();
1234 }
1235}
1236
1237impl<R, A, const PAD: bool> core::fmt::Debug for DecoderReader<R, A, PAD>
1238where
1239 A: Alphabet,
1240{
1241 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1242 formatter
1243 .debug_struct("DecoderReader")
1244 .field("inner", &redacted_inner_state(self.inner.is_some()))
1245 .field("engine", &self.engine)
1246 .field("pending", &"<redacted>")
1247 .field("pending_len", &self.pending_len)
1248 .field("pending_input_needed_len", &self.pending_input_needed_len())
1249 .field("buffered_output_len", &self.output.len())
1250 .field("buffered_output_capacity", &self.output.capacity())
1251 .field(
1252 "buffered_output_remaining_capacity",
1253 &self.output.available_capacity(),
1254 )
1255 .field("can_into_inner", &self.can_into_inner())
1256 .field("finished", &self.finished)
1257 .field("terminal_padding", &self.terminal_seen)
1258 .field("failed", &self.failed)
1259 .finish()
1260 }
1261}
1262
1263impl<R, A, const PAD: bool> Read for DecoderReader<R, A, PAD>
1264where
1265 R: Read,
1266 A: Alphabet,
1267{
1268 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
1269 if output.is_empty() {
1270 return Ok(0);
1271 }
1272 if self.failed {
1273 return Err(stream_decoder_failed_error());
1274 }
1275
1276 while self.output.is_empty() && !self.finished {
1277 self.fill_output()?;
1278 }
1279
1280 Ok(self.output.pop_slice(output))
1281 }
1282}
1283
1284impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
1285where
1286 R: Read,
1287 A: Alphabet,
1288{
1289 fn fill_output(&mut self) -> io::Result<()> {
1290 if self.failed {
1291 return Err(stream_decoder_failed_error());
1292 }
1293 if self.terminal_seen {
1294 self.finished = true;
1295 return Ok(());
1296 }
1297
1298 let mut input = [0u8; 4];
1299 let available = 4 - self.pending_len;
1300 let read = match self.inner_mut().read(&mut input[..available]) {
1301 Ok(read) => read,
1302 Err(err) => {
1303 crate::wipe_bytes(&mut input);
1304 return Err(err);
1305 }
1306 };
1307 if read == 0 {
1308 crate::wipe_bytes(&mut input);
1309 self.finished = true;
1310 self.push_final_pending()?;
1311 return Ok(());
1312 }
1313
1314 self.pending[self.pending_len..self.pending_len + read].copy_from_slice(&input[..read]);
1315 crate::wipe_bytes(&mut input);
1316 self.pending_len += read;
1317 if self.pending_len < 4 {
1318 return Ok(());
1319 }
1320
1321 let mut quad = self.pending;
1322 self.clear_pending();
1323 let result = self.push_decoded(&quad);
1324 crate::wipe_bytes(&mut quad);
1325 result?;
1326 if self.terminal_seen {
1327 self.finished = true;
1328 }
1329 Ok(())
1330 }
1331
1332 fn push_final_pending(&mut self) -> io::Result<()> {
1333 if self.pending_len == 0 {
1334 return Ok(());
1335 }
1336
1337 let mut pending = [0u8; 4];
1338 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1339 let pending_len = self.pending_len;
1340 self.clear_pending();
1341 let result = self.push_decoded(&pending[..pending_len]);
1342 crate::wipe_bytes(&mut pending);
1343 result
1344 }
1345
1346 fn push_decoded(&mut self, input: &[u8]) -> io::Result<()> {
1347 let mut decoded = [0u8; 3];
1348 let written = match self.engine.decode_slice(input, &mut decoded) {
1349 Ok(written) => written,
1350 Err(err) => {
1351 crate::wipe_bytes(&mut decoded);
1352 self.failed = true;
1353 return Err(decode_error_to_io(err));
1354 }
1355 };
1356 let result = self.output.push_slice(&decoded[..written]);
1357 crate::wipe_bytes(&mut decoded);
1358 result?;
1359 if input.len() == 4 && written < 3 {
1360 self.terminal_seen = true;
1361 }
1362 Ok(())
1363 }
1364}
1365
1366pub struct EncoderReader<R, A, const PAD: bool>
1368where
1369 A: Alphabet,
1370{
1371 inner: Option<R>,
1372 engine: Engine<A, PAD>,
1373 pending: [u8; 2],
1374 pending_len: usize,
1375 output: OutputQueue<1024>,
1376 finished: bool,
1377 failed: bool,
1378}
1379
1380impl<R, A, const PAD: bool> EncoderReader<R, A, PAD>
1381where
1382 A: Alphabet,
1383{
1384 #[must_use]
1386 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
1387 Self {
1388 inner: Some(inner),
1389 engine,
1390 pending: [0; 2],
1391 pending_len: 0,
1392 output: OutputQueue::new(),
1393 finished: false,
1394 failed: false,
1395 }
1396 }
1397
1398 #[must_use]
1400 pub fn get_ref(&self) -> &R {
1401 self.inner_ref()
1402 }
1403
1404 pub fn get_mut(&mut self) -> &mut R {
1406 self.inner_mut()
1407 }
1408
1409 #[must_use]
1411 pub const fn engine(&self) -> Engine<A, PAD> {
1412 self.engine
1413 }
1414
1415 #[must_use]
1417 pub const fn is_padded(&self) -> bool {
1418 PAD
1419 }
1420
1421 #[must_use]
1424 pub const fn pending_len(&self) -> usize {
1425 self.pending_len
1426 }
1427
1428 #[must_use]
1431 pub const fn has_pending_input(&self) -> bool {
1432 self.pending_len != 0
1433 }
1434
1435 #[must_use]
1440 pub const fn pending_input_needed_len(&self) -> usize {
1441 if self.has_pending_input() {
1442 3 - self.pending_len
1443 } else {
1444 0
1445 }
1446 }
1447
1448 #[must_use]
1451 pub const fn buffered_output_len(&self) -> usize {
1452 self.output.len()
1453 }
1454
1455 #[must_use]
1458 pub const fn buffered_output_capacity(&self) -> usize {
1459 self.output.capacity()
1460 }
1461
1462 #[must_use]
1465 pub const fn buffered_output_remaining_capacity(&self) -> usize {
1466 self.output.available_capacity()
1467 }
1468
1469 #[must_use]
1472 pub const fn has_buffered_output(&self) -> bool {
1473 !self.output.is_empty()
1474 }
1475
1476 #[must_use]
1482 pub const fn has_finished_input(&self) -> bool {
1483 self.finished
1484 }
1485
1486 #[must_use]
1489 pub const fn is_finished(&self) -> bool {
1490 self.finished && self.output.is_empty()
1491 }
1492
1493 #[must_use]
1496 pub const fn is_failed(&self) -> bool {
1497 self.failed
1498 }
1499
1500 #[must_use]
1503 pub const fn can_into_inner(&self) -> bool {
1504 self.is_finished() && !self.failed
1505 }
1506
1507 #[must_use]
1509 pub fn into_inner(mut self) -> R {
1510 self.take_inner()
1511 }
1512
1513 #[allow(clippy::result_large_err)]
1520 pub fn try_into_inner(mut self) -> Result<R, Self> {
1521 if !self.can_into_inner() {
1522 return Err(self);
1523 }
1524 Ok(self.take_inner())
1525 }
1526
1527 fn inner_ref(&self) -> &R {
1528 match &self.inner {
1529 Some(inner) => inner,
1530 None => unreachable!("stream encoder reader inner reader was already taken"),
1531 }
1532 }
1533
1534 fn inner_mut(&mut self) -> &mut R {
1535 match &mut self.inner {
1536 Some(inner) => inner,
1537 None => unreachable!("stream encoder reader inner reader was already taken"),
1538 }
1539 }
1540
1541 fn take_inner(&mut self) -> R {
1542 match self.inner.take() {
1543 Some(inner) => inner,
1544 None => unreachable!("stream encoder reader inner reader was already taken"),
1545 }
1546 }
1547
1548 fn clear_pending(&mut self) {
1549 crate::wipe_bytes(&mut self.pending);
1550 self.pending_len = 0;
1551 }
1552}
1553
1554impl<R, A, const PAD: bool> Drop for EncoderReader<R, A, PAD>
1555where
1556 A: Alphabet,
1557{
1558 fn drop(&mut self) {
1559 self.clear_pending();
1560 self.output.clear_all();
1561 }
1562}
1563
1564impl<R, A, const PAD: bool> core::fmt::Debug for EncoderReader<R, A, PAD>
1565where
1566 A: Alphabet,
1567{
1568 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1569 formatter
1570 .debug_struct("EncoderReader")
1571 .field("inner", &redacted_inner_state(self.inner.is_some()))
1572 .field("engine", &self.engine)
1573 .field("pending", &"<redacted>")
1574 .field("pending_len", &self.pending_len)
1575 .field("pending_input_needed_len", &self.pending_input_needed_len())
1576 .field("buffered_output_len", &self.output.len())
1577 .field("buffered_output_capacity", &self.output.capacity())
1578 .field(
1579 "buffered_output_remaining_capacity",
1580 &self.output.available_capacity(),
1581 )
1582 .field("can_into_inner", &self.can_into_inner())
1583 .field("finished", &self.finished)
1584 .field("failed", &self.failed)
1585 .finish()
1586 }
1587}
1588
1589impl<R, A, const PAD: bool> Read for EncoderReader<R, A, PAD>
1590where
1591 R: Read,
1592 A: Alphabet,
1593{
1594 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
1595 if self.failed {
1596 return Err(stream_encoder_failed_error());
1597 }
1598
1599 if output.is_empty() {
1600 return Ok(0);
1601 }
1602
1603 while self.output.is_empty() && !self.finished {
1604 self.fill_output()?;
1605 }
1606
1607 Ok(self.output.pop_slice(output))
1608 }
1609}
1610
1611impl<R, A, const PAD: bool> EncoderReader<R, A, PAD>
1612where
1613 R: Read,
1614 A: Alphabet,
1615{
1616 fn fill_output(&mut self) -> io::Result<()> {
1617 let mut input = [0u8; 768];
1618 let read = match self.inner_mut().read(&mut input) {
1619 Ok(read) => read,
1620 Err(err) => {
1621 crate::wipe_bytes(&mut input);
1622 return Err(err);
1623 }
1624 };
1625 if read == 0 {
1626 crate::wipe_bytes(&mut input);
1627 self.finished = true;
1628 if let Err(err) = self.push_final_pending() {
1629 self.failed = true;
1630 return Err(err);
1631 }
1632 return Ok(());
1633 }
1634
1635 let mut consumed = 0;
1636 if self.pending_len > 0 {
1637 let needed = 3 - self.pending_len;
1638 if read < needed {
1639 self.pending[self.pending_len..self.pending_len + read]
1640 .copy_from_slice(&input[..read]);
1641 self.pending_len += read;
1642 crate::wipe_bytes(&mut input);
1643 return Ok(());
1644 }
1645
1646 let mut chunk = [0u8; 3];
1647 chunk[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1648 chunk[self.pending_len..].copy_from_slice(&input[..needed]);
1649 let result = self.push_encoded(&chunk);
1650 crate::wipe_bytes(&mut chunk);
1651 if let Err(err) = result {
1652 crate::wipe_bytes(&mut input);
1653 self.failed = true;
1654 return Err(err);
1655 }
1656 self.clear_pending();
1657 consumed += needed;
1658 }
1659
1660 let remaining = &input[consumed..read];
1661 let full_len = remaining.len() / 3 * 3;
1662 let tail_len = remaining.len() - full_len;
1663 let mut tail = [0u8; 2];
1664 tail[..tail_len].copy_from_slice(&remaining[full_len..]);
1665 let result = if full_len > 0 {
1666 self.push_encoded(&remaining[..full_len])
1667 } else {
1668 Ok(())
1669 };
1670 crate::wipe_bytes(&mut input);
1671 if let Err(err) = result {
1672 crate::wipe_bytes(&mut tail);
1673 self.failed = true;
1674 return Err(err);
1675 }
1676 self.pending[..tail_len].copy_from_slice(&tail[..tail_len]);
1677 crate::wipe_bytes(&mut tail);
1678 self.pending_len = tail_len;
1679 Ok(())
1680 }
1681
1682 fn push_final_pending(&mut self) -> io::Result<()> {
1683 if self.pending_len == 0 {
1684 return Ok(());
1685 }
1686
1687 let mut pending = [0u8; 2];
1688 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1689 let pending_len = self.pending_len;
1690 self.clear_pending();
1691 let result = self.push_encoded(&pending[..pending_len]);
1692 crate::wipe_bytes(&mut pending);
1693 result
1694 }
1695
1696 fn push_encoded(&mut self, input: &[u8]) -> io::Result<()> {
1697 let mut encoded = [0u8; 1024];
1698 let written = match self.engine.encode_slice(input, &mut encoded) {
1699 Ok(written) => written,
1700 Err(err) => {
1701 crate::wipe_bytes(&mut encoded);
1702 return Err(encode_error_to_io(err));
1703 }
1704 };
1705 let result = self.output.push_slice(&encoded[..written]);
1706 crate::wipe_bytes(&mut encoded);
1707 result
1708 }
1709}
1710
1711const fn redacted_inner_state(present: bool) -> &'static str {
1712 if present { "<present>" } else { "<taken>" }
1713}