1use super::{Alphabet, DecodeError, EncodeError, Engine};
69use std::io::{self, Read, Write};
70
71struct OutputQueue<const CAP: usize> {
72 buffer: [u8; CAP],
73 start: usize,
74 len: usize,
75}
76
77impl<const CAP: usize> OutputQueue<CAP> {
78 const fn new() -> Self {
79 Self {
80 buffer: [0; CAP],
81 start: 0,
82 len: 0,
83 }
84 }
85
86 const fn is_empty(&self) -> bool {
87 self.len == 0
88 }
89
90 const fn len(&self) -> usize {
91 self.len
92 }
93
94 const fn capacity(&self) -> usize {
95 self.len + self.available_capacity()
96 }
97
98 fn push_slice(&mut self, input: &[u8]) -> io::Result<()> {
99 if input.len() > self.available_capacity() {
100 return Err(io::Error::other(
101 "base64 stream output queue capacity exceeded",
102 ));
103 }
104
105 let mut read = 0;
106 while read < input.len() {
107 let write = (self.start + self.len) % CAP;
108 self.buffer[write] = input[read];
109 self.len += 1;
110 read += 1;
111 }
112
113 Ok(())
114 }
115
116 fn copy_front(&self, output: &mut [u8]) -> usize {
117 let count = core::cmp::min(self.len, output.len());
118 let first = core::cmp::min(count, CAP - self.start);
119 output[..first].copy_from_slice(&self.buffer[self.start..self.start + first]);
120
121 let second = count - first;
122 if second > 0 {
123 output[first..first + second].copy_from_slice(&self.buffer[..second]);
124 }
125
126 count
127 }
128
129 fn discard_front(&mut self, count: usize) {
130 let count = core::cmp::min(count, self.len);
131 let first = core::cmp::min(count, CAP - self.start);
132 crate::wipe_bytes(&mut self.buffer[self.start..self.start + first]);
133
134 let second = count - first;
135 if second > 0 {
136 crate::wipe_bytes(&mut self.buffer[..second]);
137 }
138
139 self.start = (self.start + count) % CAP;
140 self.len -= count;
141 if self.len == 0 {
142 self.start = 0;
143 }
144 }
145
146 fn pop_slice(&mut self, output: &mut [u8]) -> usize {
147 let count = self.copy_front(output);
148 self.discard_front(count);
149 count
150 }
151
152 fn clear_all(&mut self) {
153 crate::wipe_bytes(&mut self.buffer);
154 self.start = 0;
155 self.len = 0;
156 }
157
158 const fn available_capacity(&self) -> usize {
159 CAP - self.len
160 }
161}
162
163pub struct Encoder<W, A, const PAD: bool>
171where
172 A: Alphabet,
173{
174 inner: Option<W>,
175 engine: Engine<A, PAD>,
176 pending: [u8; 2],
177 pending_len: usize,
178 output: OutputQueue<1024>,
179 finalized: bool,
180 failed: bool,
181}
182
183impl<W, A, const PAD: bool> Encoder<W, A, PAD>
184where
185 A: Alphabet,
186{
187 #[must_use]
189 pub const fn new(inner: W, engine: Engine<A, PAD>) -> Self {
190 Self {
191 inner: Some(inner),
192 engine,
193 pending: [0; 2],
194 pending_len: 0,
195 output: OutputQueue::new(),
196 finalized: false,
197 failed: false,
198 }
199 }
200
201 #[must_use]
203 pub fn get_ref(&self) -> &W {
204 self.inner_ref()
205 }
206
207 pub fn get_mut(&mut self) -> &mut W {
209 self.inner_mut()
210 }
211
212 #[must_use]
214 pub const fn engine(&self) -> Engine<A, PAD> {
215 self.engine
216 }
217
218 #[must_use]
220 pub const fn is_padded(&self) -> bool {
221 PAD
222 }
223
224 #[must_use]
227 pub const fn pending_len(&self) -> usize {
228 self.pending_len
229 }
230
231 #[must_use]
234 pub const fn has_pending_input(&self) -> bool {
235 self.pending_len != 0
236 }
237
238 #[must_use]
243 pub const fn pending_input_needed_len(&self) -> usize {
244 if self.has_pending_input() {
245 3 - self.pending_len
246 } else {
247 0
248 }
249 }
250
251 #[must_use]
254 pub const fn buffered_output_len(&self) -> usize {
255 self.output.len()
256 }
257
258 #[must_use]
261 pub const fn buffered_output_capacity(&self) -> usize {
262 self.output.capacity()
263 }
264
265 #[must_use]
268 pub const fn buffered_output_remaining_capacity(&self) -> usize {
269 self.output.available_capacity()
270 }
271
272 #[must_use]
275 pub const fn has_buffered_output(&self) -> bool {
276 !self.output.is_empty()
277 }
278
279 #[must_use]
283 pub const fn is_finalized(&self) -> bool {
284 self.finalized
285 }
286
287 #[must_use]
295 pub const fn is_failed(&self) -> bool {
296 self.failed
297 }
298
299 #[must_use]
302 pub const fn can_into_inner(&self) -> bool {
303 !self.is_failed() && !self.has_pending_input() && !self.has_buffered_output()
304 }
305
306 #[must_use]
310 pub fn into_inner(mut self) -> W {
311 self.take_inner()
312 }
313
314 #[allow(clippy::result_large_err)]
320 pub fn try_into_inner(mut self) -> Result<W, Self> {
321 if !self.can_into_inner() {
322 return Err(self);
323 }
324 Ok(self.take_inner())
325 }
326
327 fn inner_ref(&self) -> &W {
328 match &self.inner {
329 Some(inner) => inner,
330 None => unreachable!("stream encoder inner writer was already taken"),
331 }
332 }
333
334 fn inner_mut(&mut self) -> &mut W {
335 match &mut self.inner {
336 Some(inner) => inner,
337 None => unreachable!("stream encoder inner writer was already taken"),
338 }
339 }
340
341 fn take_inner(&mut self) -> W {
342 match self.inner.take() {
343 Some(inner) => inner,
344 None => unreachable!("stream encoder inner writer was already taken"),
345 }
346 }
347
348 fn clear_pending(&mut self) {
349 crate::wipe_bytes(&mut self.pending);
350 self.pending_len = 0;
351 }
352
353 fn clear_output(&mut self) {
354 self.output.clear_all();
355 }
356}
357
358impl<W, A, const PAD: bool> Drop for Encoder<W, A, PAD>
359where
360 A: Alphabet,
361{
362 fn drop(&mut self) {
363 self.clear_pending();
364 self.clear_output();
365 }
366}
367
368impl<W, A, const PAD: bool> core::fmt::Debug for Encoder<W, A, PAD>
369where
370 A: Alphabet,
371{
372 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
373 formatter
374 .debug_struct("Encoder")
375 .field("inner", &redacted_inner_state(self.inner.is_some()))
376 .field("engine", &self.engine)
377 .field("pending", &"<redacted>")
378 .field("pending_len", &self.pending_len)
379 .field("pending_input_needed_len", &self.pending_input_needed_len())
380 .field("buffered_output_len", &self.output.len())
381 .field("buffered_output_capacity", &self.output.capacity())
382 .field(
383 "buffered_output_remaining_capacity",
384 &self.output.available_capacity(),
385 )
386 .field("can_into_inner", &self.can_into_inner())
387 .field("finalized", &self.finalized)
388 .field("failed", &self.failed)
389 .finish()
390 }
391}
392
393impl<W, A, const PAD: bool> Encoder<W, A, PAD>
394where
395 W: Write,
396 A: Alphabet,
397{
398 pub fn try_finish(&mut self) -> io::Result<()> {
408 if self.failed {
409 return Err(stream_encoder_failed_error());
410 }
411 if !self.finalized {
412 self.queue_pending_final()?;
413 self.finalized = true;
414 }
415 self.flush()
416 }
417
418 pub fn finish(mut self) -> io::Result<W> {
420 self.try_finish()?;
421 Ok(self.take_inner())
422 }
423
424 fn queue_pending_final(&mut self) -> io::Result<()> {
425 if self.pending_len == 0 {
426 return Ok(());
427 }
428
429 let mut pending = [0u8; 2];
430 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
431 let pending_len = self.pending_len;
432 let mut encoded = [0u8; 4];
433 let result = self.queue_encoded_temp(&pending[..pending_len], &mut encoded);
434 crate::wipe_bytes(&mut pending);
435 result?;
436 self.clear_pending();
437 Ok(())
438 }
439
440 fn queue_encoded_temp(&mut self, input: &[u8], encoded: &mut [u8]) -> io::Result<()> {
441 let written = match self.engine.encode_slice(input, encoded) {
442 Ok(written) => written,
443 Err(err) => {
444 crate::wipe_bytes(encoded);
445 self.failed = true;
446 return Err(encode_error_to_io(err));
447 }
448 };
449
450 let result = self.output.push_slice(&encoded[..written]);
451 crate::wipe_bytes(encoded);
452 if result.is_err() {
453 self.failed = true;
454 }
455 result
456 }
457
458 fn drain_output(&mut self) -> io::Result<()> {
459 let mut chunk = [0u8; 1024];
460 while !self.output.is_empty() {
461 let pending = self.output.copy_front(&mut chunk);
462 let result = self.inner_mut().write(&chunk[..pending]);
463 crate::wipe_bytes(&mut chunk[..pending]);
464 match result {
465 Ok(0) => {
466 return Err(io::Error::new(
467 io::ErrorKind::WriteZero,
468 "base64 stream encoder could not drain buffered output",
469 ));
470 }
471 Ok(written) => {
472 if written > pending {
473 self.failed = true;
474 return Err(io::Error::new(
475 io::ErrorKind::InvalidData,
476 "wrapped writer reported more bytes than provided",
477 ));
478 }
479 self.output.discard_front(written);
480 }
481 Err(err) => return Err(err),
482 }
483 }
484
485 Ok(())
486 }
487}
488
489impl<W, A, const PAD: bool> Write for Encoder<W, A, PAD>
490where
491 W: Write,
492 A: Alphabet,
493{
494 fn write(&mut self, input: &[u8]) -> io::Result<usize> {
495 if self.failed {
496 return Err(stream_encoder_failed_error());
497 }
498 self.drain_output()?;
499 if self.finalized {
500 return Err(io::Error::new(
501 io::ErrorKind::InvalidInput,
502 "base64 stream encoder received input after finalization",
503 ));
504 }
505 if input.is_empty() {
506 return Ok(0);
507 }
508
509 let mut consumed = 0;
510 if self.pending_len > 0 {
511 let needed = 3 - self.pending_len;
512 if input.len() < needed {
513 self.pending[self.pending_len..self.pending_len + input.len()]
514 .copy_from_slice(input);
515 self.pending_len += input.len();
516 return Ok(input.len());
517 }
518
519 let mut chunk = [0u8; 3];
520 chunk[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
521 chunk[self.pending_len..].copy_from_slice(&input[..needed]);
522
523 let mut encoded = [0u8; 4];
524 let result = self.queue_encoded_temp(&chunk, &mut encoded);
525 crate::wipe_bytes(&mut chunk);
526 result?;
527 self.clear_pending();
528 consumed += needed;
529 }
530
531 let remaining = &input[consumed..];
532 let full_len = remaining.len() / 3 * 3;
533 if full_len > 0 {
534 let max_by_queue = self.output.available_capacity() / 4 * 3;
535 let mut take = core::cmp::min(full_len, core::cmp::min(768, max_by_queue));
536 take -= take % 3;
537
538 if take == 0 {
539 return Ok(consumed);
540 }
541
542 let mut encoded = [0u8; 1024];
543 self.queue_encoded_temp(&remaining[..take], &mut encoded)?;
544 consumed += take;
545
546 if take < full_len {
547 return Ok(consumed);
548 }
549 }
550
551 let tail = &input[consumed..];
552 self.pending[..tail.len()].copy_from_slice(tail);
553 self.pending_len = tail.len();
554 consumed += tail.len();
555
556 Ok(consumed)
557 }
558
559 fn flush(&mut self) -> io::Result<()> {
560 if self.failed {
561 return Err(stream_encoder_failed_error());
562 }
563 self.drain_output()?;
564 self.inner_mut().flush()
565 }
566}
567
568fn encode_error_to_io(err: EncodeError) -> io::Error {
569 io::Error::new(io::ErrorKind::InvalidInput, err)
570}
571
572pub struct Decoder<W, A, const PAD: bool>
594where
595 A: Alphabet,
596{
597 inner: Option<W>,
598 engine: Engine<A, PAD>,
599 pending: [u8; 4],
600 pending_len: usize,
601 output: OutputQueue<1024>,
602 finished: bool,
603 failed: bool,
604 finalized: bool,
605}
606
607impl<W, A, const PAD: bool> Decoder<W, A, PAD>
608where
609 A: Alphabet,
610{
611 #[must_use]
618 pub const fn new(inner: W, engine: Engine<A, PAD>) -> Self {
619 Self {
620 inner: Some(inner),
621 engine,
622 pending: [0; 4],
623 pending_len: 0,
624 output: OutputQueue::new(),
625 finished: false,
626 finalized: false,
627 failed: false,
628 }
629 }
630
631 #[must_use]
633 pub fn get_ref(&self) -> &W {
634 self.inner_ref()
635 }
636
637 pub fn get_mut(&mut self) -> &mut W {
639 self.inner_mut()
640 }
641
642 #[must_use]
644 pub const fn engine(&self) -> Engine<A, PAD> {
645 self.engine
646 }
647
648 #[must_use]
650 pub const fn is_padded(&self) -> bool {
651 PAD
652 }
653
654 #[must_use]
657 pub const fn pending_len(&self) -> usize {
658 self.pending_len
659 }
660
661 #[must_use]
664 pub const fn has_pending_input(&self) -> bool {
665 self.pending_len != 0
666 }
667
668 #[must_use]
673 pub const fn pending_input_needed_len(&self) -> usize {
674 if self.has_pending_input() {
675 4 - self.pending_len
676 } else {
677 0
678 }
679 }
680
681 #[must_use]
684 pub const fn buffered_output_len(&self) -> usize {
685 self.output.len()
686 }
687
688 #[must_use]
691 pub const fn buffered_output_capacity(&self) -> usize {
692 self.output.capacity()
693 }
694
695 #[must_use]
698 pub const fn buffered_output_remaining_capacity(&self) -> usize {
699 self.output.available_capacity()
700 }
701
702 #[must_use]
705 pub const fn has_buffered_output(&self) -> bool {
706 !self.output.is_empty()
707 }
708
709 #[must_use]
715 pub const fn has_terminal_padding(&self) -> bool {
716 self.finished
717 }
718
719 #[must_use]
723 pub const fn is_finalized(&self) -> bool {
724 self.finalized
725 }
726
727 #[must_use]
733 pub const fn is_failed(&self) -> bool {
734 self.failed
735 }
736
737 #[must_use]
740 pub const fn can_into_inner(&self) -> bool {
741 !self.is_failed() && !self.has_pending_input() && !self.has_buffered_output()
742 }
743
744 #[must_use]
748 pub fn into_inner(mut self) -> W {
749 self.take_inner()
750 }
751
752 #[allow(clippy::result_large_err)]
758 pub fn try_into_inner(mut self) -> Result<W, Self> {
759 if !self.can_into_inner() {
760 return Err(self);
761 }
762 Ok(self.take_inner())
763 }
764
765 fn inner_ref(&self) -> &W {
766 match &self.inner {
767 Some(inner) => inner,
768 None => unreachable!("stream decoder inner writer was already taken"),
769 }
770 }
771
772 fn inner_mut(&mut self) -> &mut W {
773 match &mut self.inner {
774 Some(inner) => inner,
775 None => unreachable!("stream decoder inner writer was already taken"),
776 }
777 }
778
779 fn take_inner(&mut self) -> W {
780 match self.inner.take() {
781 Some(inner) => inner,
782 None => unreachable!("stream decoder inner writer was already taken"),
783 }
784 }
785
786 fn clear_pending(&mut self) {
787 crate::wipe_bytes(&mut self.pending);
788 self.pending_len = 0;
789 }
790
791 fn clear_output(&mut self) {
792 self.output.clear_all();
793 }
794}
795
796impl<W, A, const PAD: bool> Drop for Decoder<W, A, PAD>
797where
798 A: Alphabet,
799{
800 fn drop(&mut self) {
801 self.clear_pending();
802 self.clear_output();
803 }
804}
805
806impl<W, A, const PAD: bool> core::fmt::Debug for Decoder<W, A, PAD>
807where
808 A: Alphabet,
809{
810 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
811 formatter
812 .debug_struct("Decoder")
813 .field("inner", &redacted_inner_state(self.inner.is_some()))
814 .field("engine", &self.engine)
815 .field("pending", &"<redacted>")
816 .field("pending_len", &self.pending_len)
817 .field("pending_input_needed_len", &self.pending_input_needed_len())
818 .field("buffered_output_len", &self.output.len())
819 .field("buffered_output_capacity", &self.output.capacity())
820 .field(
821 "buffered_output_remaining_capacity",
822 &self.output.available_capacity(),
823 )
824 .field("can_into_inner", &self.can_into_inner())
825 .field("terminal_padding", &self.finished)
826 .field("finalized", &self.finalized)
827 .field("failed", &self.failed)
828 .finish()
829 }
830}
831
832impl<W, A, const PAD: bool> Decoder<W, A, PAD>
833where
834 W: Write,
835 A: Alphabet,
836{
837 pub fn try_finish(&mut self) -> io::Result<()> {
847 if self.failed {
848 return Err(stream_decoder_failed_error());
849 }
850 if !self.finalized {
851 self.queue_pending_final()?;
852 self.finalized = true;
853 }
854 self.flush()
855 }
856
857 pub fn finish(mut self) -> io::Result<W> {
859 self.try_finish()?;
860 Ok(self.take_inner())
861 }
862
863 fn queue_pending_final(&mut self) -> io::Result<()> {
864 if self.pending_len == 0 {
865 return Ok(());
866 }
867
868 let mut pending = [0u8; 4];
869 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
870 let pending_len = self.pending_len;
871 let mut decoded = [0u8; 3];
872 let result = self.queue_decoded_temp(&pending[..pending_len], &mut decoded);
873 crate::wipe_bytes(&mut pending);
874 if let Err(err) = result {
875 self.clear_pending();
876 return Err(err);
877 }
878 self.clear_pending();
879 Ok(())
880 }
881
882 fn queue_full_quad(&mut self, mut input: [u8; 4]) -> io::Result<()> {
883 let mut decoded = [0u8; 3];
884 let result = self.queue_decoded_temp(&input, &mut decoded);
885 crate::wipe_bytes(&mut input);
886 let written = result?;
887 if written < 3 {
888 self.finished = true;
889 }
890 Ok(())
891 }
892
893 fn queue_decoded_temp(&mut self, input: &[u8], decoded: &mut [u8]) -> io::Result<usize> {
894 let written = match self.engine.decode_slice(input, decoded) {
895 Ok(written) => written,
896 Err(err) => {
897 crate::wipe_bytes(decoded);
898 self.failed = true;
899 return Err(decode_error_to_io(err));
900 }
901 };
902
903 let result = self.output.push_slice(&decoded[..written]);
904 crate::wipe_bytes(decoded);
905 if result.is_err() {
906 self.failed = true;
907 }
908 result?;
909 Ok(written)
910 }
911
912 fn drain_output(&mut self) -> io::Result<()> {
913 let mut chunk = [0u8; 1024];
914 while !self.output.is_empty() {
915 let pending = self.output.copy_front(&mut chunk);
916 let result = self.inner_mut().write(&chunk[..pending]);
917 crate::wipe_bytes(&mut chunk[..pending]);
918 match result {
919 Ok(0) => {
920 return Err(io::Error::new(
921 io::ErrorKind::WriteZero,
922 "base64 stream decoder could not drain buffered output",
923 ));
924 }
925 Ok(written) => {
926 if written > pending {
927 self.failed = true;
928 return Err(io::Error::new(
929 io::ErrorKind::InvalidData,
930 "wrapped writer reported more bytes than provided",
931 ));
932 }
933 self.output.discard_front(written);
934 }
935 Err(err) => return Err(err),
936 }
937 }
938
939 Ok(())
940 }
941}
942
943impl<W, A, const PAD: bool> Write for Decoder<W, A, PAD>
944where
945 W: Write,
946 A: Alphabet,
947{
948 fn write(&mut self, input: &[u8]) -> io::Result<usize> {
949 if self.failed {
950 return Err(stream_decoder_failed_error());
951 }
952 if input.is_empty() {
953 self.drain_output()?;
954 return Ok(0);
955 }
956 self.drain_output()?;
957 if self.finalized {
958 return Err(io::Error::new(
959 io::ErrorKind::InvalidInput,
960 "base64 stream decoder received input after finalization",
961 ));
962 }
963 if self.finished {
964 self.failed = true;
965 return Err(trailing_input_after_padding_error());
966 }
967
968 let mut consumed = 0;
969 if self.pending_len > 0 {
970 let needed = 4 - self.pending_len;
971 if input.len() < needed {
972 self.pending[self.pending_len..self.pending_len + input.len()]
973 .copy_from_slice(input);
974 self.pending_len += input.len();
975 return Ok(input.len());
976 }
977
978 let mut quad = [0u8; 4];
979 quad[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
980 quad[self.pending_len..].copy_from_slice(&input[..needed]);
981 let result = self.queue_full_quad(quad);
982 crate::wipe_bytes(&mut quad);
983 if let Err(err) = result {
984 self.clear_pending();
985 return Err(err);
986 }
987 self.clear_pending();
988 consumed += needed;
989
990 if self.finished {
991 return Ok(consumed);
992 }
993 }
994
995 while input.len() - consumed >= 4 {
996 if self.output.available_capacity() < 3 {
997 return Ok(consumed);
998 }
999
1000 let mut quad = [
1001 input[consumed],
1002 input[consumed + 1],
1003 input[consumed + 2],
1004 input[consumed + 3],
1005 ];
1006 let mut decoded = [0u8; 3];
1007 let written = match self.engine.decode_slice(&quad, &mut decoded) {
1008 Ok(written) => written,
1009 Err(err) => {
1010 crate::wipe_bytes(&mut quad);
1011 crate::wipe_bytes(&mut decoded);
1012 self.failed = true;
1013 if consumed > 0 {
1014 return Ok(consumed);
1015 }
1016
1017 return Err(decode_error_to_io(err));
1018 }
1019 };
1020
1021 let result = self.output.push_slice(&decoded[..written]);
1022 crate::wipe_bytes(&mut quad);
1023 crate::wipe_bytes(&mut decoded);
1024 result?;
1025 consumed += 4;
1026
1027 if written < 3 {
1028 self.finished = true;
1029 return Ok(consumed);
1030 }
1031 }
1032
1033 let tail = &input[consumed..];
1034 self.pending[..tail.len()].copy_from_slice(tail);
1035 self.pending_len = tail.len();
1036 consumed += tail.len();
1037
1038 Ok(consumed)
1039 }
1040
1041 fn flush(&mut self) -> io::Result<()> {
1042 if self.failed {
1043 return Err(stream_decoder_failed_error());
1044 }
1045 self.drain_output()?;
1046 self.inner_mut().flush()
1047 }
1048}
1049
1050fn decode_error_to_io(err: DecodeError) -> io::Error {
1051 io::Error::new(io::ErrorKind::InvalidInput, err)
1052}
1053
1054fn trailing_input_after_padding_error() -> io::Error {
1055 io::Error::new(
1056 io::ErrorKind::InvalidInput,
1057 "base64 decoder received trailing input after padding",
1058 )
1059}
1060
1061fn stream_decoder_failed_error() -> io::Error {
1062 io::Error::new(
1063 io::ErrorKind::InvalidInput,
1064 "base64 stream decoder is failed after malformed input",
1065 )
1066}
1067
1068fn stream_encoder_failed_error() -> io::Error {
1069 io::Error::new(
1070 io::ErrorKind::InvalidInput,
1071 "base64 stream encoder is failed after internal error",
1072 )
1073}
1074
1075pub struct DecoderReader<R, A, const PAD: bool>
1090where
1091 A: Alphabet,
1092{
1093 inner: Option<R>,
1094 engine: Engine<A, PAD>,
1095 pending: [u8; 4],
1096 pending_len: usize,
1097 output: OutputQueue<3>,
1098 finished: bool,
1099 terminal_seen: bool,
1100 failed: bool,
1101}
1102
1103impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
1104where
1105 A: Alphabet,
1106{
1107 #[must_use]
1114 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
1115 Self {
1116 inner: Some(inner),
1117 engine,
1118 pending: [0; 4],
1119 pending_len: 0,
1120 output: OutputQueue::new(),
1121 finished: false,
1122 terminal_seen: false,
1123 failed: false,
1124 }
1125 }
1126
1127 #[must_use]
1129 pub fn get_ref(&self) -> &R {
1130 self.inner_ref()
1131 }
1132
1133 pub fn get_mut(&mut self) -> &mut R {
1135 self.inner_mut()
1136 }
1137
1138 #[must_use]
1140 pub const fn engine(&self) -> Engine<A, PAD> {
1141 self.engine
1142 }
1143
1144 #[must_use]
1146 pub const fn is_padded(&self) -> bool {
1147 PAD
1148 }
1149
1150 #[must_use]
1153 pub const fn pending_len(&self) -> usize {
1154 self.pending_len
1155 }
1156
1157 #[must_use]
1160 pub const fn has_pending_input(&self) -> bool {
1161 self.pending_len != 0
1162 }
1163
1164 #[must_use]
1169 pub const fn pending_input_needed_len(&self) -> usize {
1170 if self.has_pending_input() {
1171 4 - self.pending_len
1172 } else {
1173 0
1174 }
1175 }
1176
1177 #[must_use]
1180 pub const fn buffered_output_len(&self) -> usize {
1181 self.output.len()
1182 }
1183
1184 #[must_use]
1187 pub const fn buffered_output_capacity(&self) -> usize {
1188 self.output.capacity()
1189 }
1190
1191 #[must_use]
1194 pub const fn buffered_output_remaining_capacity(&self) -> usize {
1195 self.output.available_capacity()
1196 }
1197
1198 #[must_use]
1201 pub const fn has_buffered_output(&self) -> bool {
1202 !self.output.is_empty()
1203 }
1204
1205 #[must_use]
1212 pub const fn has_terminal_padding(&self) -> bool {
1213 self.terminal_seen
1214 }
1215
1216 #[must_use]
1222 pub const fn has_finished_input(&self) -> bool {
1223 self.finished
1224 }
1225
1226 #[must_use]
1229 pub const fn is_finished(&self) -> bool {
1230 self.finished && self.output.is_empty()
1231 }
1232
1233 #[must_use]
1240 pub const fn is_failed(&self) -> bool {
1241 self.failed
1242 }
1243
1244 #[must_use]
1247 pub const fn can_into_inner(&self) -> bool {
1248 !self.is_failed() && self.is_finished()
1249 }
1250
1251 #[must_use]
1253 pub fn into_inner(mut self) -> R {
1254 self.take_inner()
1255 }
1256
1257 #[allow(clippy::result_large_err)]
1265 pub fn try_into_inner(mut self) -> Result<R, Self> {
1266 if !self.can_into_inner() {
1267 return Err(self);
1268 }
1269 Ok(self.take_inner())
1270 }
1271
1272 fn inner_ref(&self) -> &R {
1273 match &self.inner {
1274 Some(inner) => inner,
1275 None => unreachable!("stream decoder reader inner reader was already taken"),
1276 }
1277 }
1278
1279 fn inner_mut(&mut self) -> &mut R {
1280 match &mut self.inner {
1281 Some(inner) => inner,
1282 None => unreachable!("stream decoder reader inner reader was already taken"),
1283 }
1284 }
1285
1286 fn take_inner(&mut self) -> R {
1287 match self.inner.take() {
1288 Some(inner) => inner,
1289 None => unreachable!("stream decoder reader inner reader was already taken"),
1290 }
1291 }
1292
1293 fn clear_pending(&mut self) {
1294 crate::wipe_bytes(&mut self.pending);
1295 self.pending_len = 0;
1296 }
1297}
1298
1299impl<R, A, const PAD: bool> Drop for DecoderReader<R, A, PAD>
1300where
1301 A: Alphabet,
1302{
1303 fn drop(&mut self) {
1304 self.clear_pending();
1305 self.output.clear_all();
1306 }
1307}
1308
1309impl<R, A, const PAD: bool> core::fmt::Debug for DecoderReader<R, A, PAD>
1310where
1311 A: Alphabet,
1312{
1313 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1314 formatter
1315 .debug_struct("DecoderReader")
1316 .field("inner", &redacted_inner_state(self.inner.is_some()))
1317 .field("engine", &self.engine)
1318 .field("pending", &"<redacted>")
1319 .field("pending_len", &self.pending_len)
1320 .field("pending_input_needed_len", &self.pending_input_needed_len())
1321 .field("buffered_output_len", &self.output.len())
1322 .field("buffered_output_capacity", &self.output.capacity())
1323 .field(
1324 "buffered_output_remaining_capacity",
1325 &self.output.available_capacity(),
1326 )
1327 .field("can_into_inner", &self.can_into_inner())
1328 .field("finished", &self.finished)
1329 .field("terminal_padding", &self.terminal_seen)
1330 .field("failed", &self.failed)
1331 .finish()
1332 }
1333}
1334
1335impl<R, A, const PAD: bool> Read for DecoderReader<R, A, PAD>
1336where
1337 R: Read,
1338 A: Alphabet,
1339{
1340 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
1341 if output.is_empty() {
1342 return Ok(0);
1343 }
1344 if self.failed {
1345 return Err(stream_decoder_failed_error());
1346 }
1347
1348 while self.output.is_empty() && !self.finished {
1349 self.fill_output()?;
1350 }
1351
1352 Ok(self.output.pop_slice(output))
1353 }
1354}
1355
1356impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
1357where
1358 R: Read,
1359 A: Alphabet,
1360{
1361 fn fill_output(&mut self) -> io::Result<()> {
1362 if self.failed {
1363 return Err(stream_decoder_failed_error());
1364 }
1365 if self.terminal_seen {
1366 self.finished = true;
1367 return Ok(());
1368 }
1369
1370 let mut input = [0u8; 4];
1371 let available = 4 - self.pending_len;
1372 let read = match self.inner_mut().read(&mut input[..available]) {
1373 Ok(read) => read,
1374 Err(err) => {
1375 crate::wipe_bytes(&mut input);
1376 return Err(err);
1377 }
1378 };
1379 if read == 0 {
1380 crate::wipe_bytes(&mut input);
1381 self.finished = true;
1382 self.push_final_pending()?;
1383 return Ok(());
1384 }
1385
1386 self.pending[self.pending_len..self.pending_len + read].copy_from_slice(&input[..read]);
1387 crate::wipe_bytes(&mut input);
1388 self.pending_len += read;
1389 if self.pending_len < 4 {
1390 return Ok(());
1391 }
1392
1393 let mut quad = self.pending;
1394 self.clear_pending();
1395 let result = self.push_decoded(&quad);
1396 crate::wipe_bytes(&mut quad);
1397 result?;
1398 if self.terminal_seen {
1399 self.finished = true;
1400 }
1401 Ok(())
1402 }
1403
1404 fn push_final_pending(&mut self) -> io::Result<()> {
1405 if self.pending_len == 0 {
1406 return Ok(());
1407 }
1408
1409 let mut pending = [0u8; 4];
1410 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1411 let pending_len = self.pending_len;
1412 self.clear_pending();
1413 let result = self.push_decoded(&pending[..pending_len]);
1414 crate::wipe_bytes(&mut pending);
1415 result
1416 }
1417
1418 fn push_decoded(&mut self, input: &[u8]) -> io::Result<()> {
1419 let mut decoded = [0u8; 3];
1420 let written = match self.engine.decode_slice(input, &mut decoded) {
1421 Ok(written) => written,
1422 Err(err) => {
1423 crate::wipe_bytes(&mut decoded);
1424 self.failed = true;
1425 return Err(decode_error_to_io(err));
1426 }
1427 };
1428 let result = self.output.push_slice(&decoded[..written]);
1429 crate::wipe_bytes(&mut decoded);
1430 if result.is_err() {
1431 self.failed = true;
1432 }
1433 result?;
1434 if input.len() == 4 && written < 3 {
1435 self.terminal_seen = true;
1436 }
1437 Ok(())
1438 }
1439}
1440
1441pub struct EncoderReader<R, A, const PAD: bool>
1443where
1444 A: Alphabet,
1445{
1446 inner: Option<R>,
1447 engine: Engine<A, PAD>,
1448 pending: [u8; 2],
1449 pending_len: usize,
1450 output: OutputQueue<1024>,
1451 finished: bool,
1452 failed: bool,
1453}
1454
1455impl<R, A, const PAD: bool> EncoderReader<R, A, PAD>
1456where
1457 A: Alphabet,
1458{
1459 #[must_use]
1461 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
1462 Self {
1463 inner: Some(inner),
1464 engine,
1465 pending: [0; 2],
1466 pending_len: 0,
1467 output: OutputQueue::new(),
1468 finished: false,
1469 failed: false,
1470 }
1471 }
1472
1473 #[must_use]
1475 pub fn get_ref(&self) -> &R {
1476 self.inner_ref()
1477 }
1478
1479 pub fn get_mut(&mut self) -> &mut R {
1481 self.inner_mut()
1482 }
1483
1484 #[must_use]
1486 pub const fn engine(&self) -> Engine<A, PAD> {
1487 self.engine
1488 }
1489
1490 #[must_use]
1492 pub const fn is_padded(&self) -> bool {
1493 PAD
1494 }
1495
1496 #[must_use]
1499 pub const fn pending_len(&self) -> usize {
1500 self.pending_len
1501 }
1502
1503 #[must_use]
1506 pub const fn has_pending_input(&self) -> bool {
1507 self.pending_len != 0
1508 }
1509
1510 #[must_use]
1515 pub const fn pending_input_needed_len(&self) -> usize {
1516 if self.has_pending_input() {
1517 3 - self.pending_len
1518 } else {
1519 0
1520 }
1521 }
1522
1523 #[must_use]
1526 pub const fn buffered_output_len(&self) -> usize {
1527 self.output.len()
1528 }
1529
1530 #[must_use]
1533 pub const fn buffered_output_capacity(&self) -> usize {
1534 self.output.capacity()
1535 }
1536
1537 #[must_use]
1540 pub const fn buffered_output_remaining_capacity(&self) -> usize {
1541 self.output.available_capacity()
1542 }
1543
1544 #[must_use]
1547 pub const fn has_buffered_output(&self) -> bool {
1548 !self.output.is_empty()
1549 }
1550
1551 #[must_use]
1557 pub const fn has_finished_input(&self) -> bool {
1558 self.finished
1559 }
1560
1561 #[must_use]
1564 pub const fn is_finished(&self) -> bool {
1565 self.finished && self.output.is_empty()
1566 }
1567
1568 #[must_use]
1571 pub const fn is_failed(&self) -> bool {
1572 self.failed
1573 }
1574
1575 #[must_use]
1578 pub const fn can_into_inner(&self) -> bool {
1579 self.is_finished() && !self.failed
1580 }
1581
1582 #[must_use]
1584 pub fn into_inner(mut self) -> R {
1585 self.take_inner()
1586 }
1587
1588 #[allow(clippy::result_large_err)]
1595 pub fn try_into_inner(mut self) -> Result<R, Self> {
1596 if !self.can_into_inner() {
1597 return Err(self);
1598 }
1599 Ok(self.take_inner())
1600 }
1601
1602 fn inner_ref(&self) -> &R {
1603 match &self.inner {
1604 Some(inner) => inner,
1605 None => unreachable!("stream encoder reader inner reader was already taken"),
1606 }
1607 }
1608
1609 fn inner_mut(&mut self) -> &mut R {
1610 match &mut self.inner {
1611 Some(inner) => inner,
1612 None => unreachable!("stream encoder reader inner reader was already taken"),
1613 }
1614 }
1615
1616 fn take_inner(&mut self) -> R {
1617 match self.inner.take() {
1618 Some(inner) => inner,
1619 None => unreachable!("stream encoder reader inner reader was already taken"),
1620 }
1621 }
1622
1623 fn clear_pending(&mut self) {
1624 crate::wipe_bytes(&mut self.pending);
1625 self.pending_len = 0;
1626 }
1627}
1628
1629impl<R, A, const PAD: bool> Drop for EncoderReader<R, A, PAD>
1630where
1631 A: Alphabet,
1632{
1633 fn drop(&mut self) {
1634 self.clear_pending();
1635 self.output.clear_all();
1636 }
1637}
1638
1639impl<R, A, const PAD: bool> core::fmt::Debug for EncoderReader<R, A, PAD>
1640where
1641 A: Alphabet,
1642{
1643 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1644 formatter
1645 .debug_struct("EncoderReader")
1646 .field("inner", &redacted_inner_state(self.inner.is_some()))
1647 .field("engine", &self.engine)
1648 .field("pending", &"<redacted>")
1649 .field("pending_len", &self.pending_len)
1650 .field("pending_input_needed_len", &self.pending_input_needed_len())
1651 .field("buffered_output_len", &self.output.len())
1652 .field("buffered_output_capacity", &self.output.capacity())
1653 .field(
1654 "buffered_output_remaining_capacity",
1655 &self.output.available_capacity(),
1656 )
1657 .field("can_into_inner", &self.can_into_inner())
1658 .field("finished", &self.finished)
1659 .field("failed", &self.failed)
1660 .finish()
1661 }
1662}
1663
1664impl<R, A, const PAD: bool> Read for EncoderReader<R, A, PAD>
1665where
1666 R: Read,
1667 A: Alphabet,
1668{
1669 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
1670 if self.failed {
1671 return Err(stream_encoder_failed_error());
1672 }
1673
1674 if output.is_empty() {
1675 return Ok(0);
1676 }
1677
1678 while self.output.is_empty() && !self.finished {
1679 self.fill_output()?;
1680 }
1681
1682 Ok(self.output.pop_slice(output))
1683 }
1684}
1685
1686impl<R, A, const PAD: bool> EncoderReader<R, A, PAD>
1687where
1688 R: Read,
1689 A: Alphabet,
1690{
1691 fn fill_output(&mut self) -> io::Result<()> {
1692 let mut input = [0u8; 768];
1693 let read = match self.inner_mut().read(&mut input) {
1694 Ok(read) => read,
1695 Err(err) => {
1696 crate::wipe_bytes(&mut input);
1697 return Err(err);
1698 }
1699 };
1700 if read == 0 {
1701 crate::wipe_bytes(&mut input);
1702 self.finished = true;
1703 if let Err(err) = self.push_final_pending() {
1704 self.failed = true;
1705 return Err(err);
1706 }
1707 return Ok(());
1708 }
1709
1710 let mut consumed = 0;
1711 if self.pending_len > 0 {
1712 let needed = 3 - self.pending_len;
1713 if read < needed {
1714 self.pending[self.pending_len..self.pending_len + read]
1715 .copy_from_slice(&input[..read]);
1716 self.pending_len += read;
1717 crate::wipe_bytes(&mut input);
1718 return Ok(());
1719 }
1720
1721 let mut chunk = [0u8; 3];
1722 chunk[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1723 chunk[self.pending_len..].copy_from_slice(&input[..needed]);
1724 let result = self.push_encoded(&chunk);
1725 crate::wipe_bytes(&mut chunk);
1726 if let Err(err) = result {
1727 crate::wipe_bytes(&mut input);
1728 self.failed = true;
1729 return Err(err);
1730 }
1731 self.clear_pending();
1732 consumed += needed;
1733 }
1734
1735 let remaining = &input[consumed..read];
1736 let full_len = remaining.len() / 3 * 3;
1737 let tail_len = remaining.len() - full_len;
1738 let mut tail = [0u8; 2];
1739 tail[..tail_len].copy_from_slice(&remaining[full_len..]);
1740 let result = if full_len > 0 {
1741 self.push_encoded(&remaining[..full_len])
1742 } else {
1743 Ok(())
1744 };
1745 crate::wipe_bytes(&mut input);
1746 if let Err(err) = result {
1747 crate::wipe_bytes(&mut tail);
1748 self.failed = true;
1749 return Err(err);
1750 }
1751 self.pending[..tail_len].copy_from_slice(&tail[..tail_len]);
1752 crate::wipe_bytes(&mut tail);
1753 self.pending_len = tail_len;
1754 Ok(())
1755 }
1756
1757 fn push_final_pending(&mut self) -> io::Result<()> {
1758 if self.pending_len == 0 {
1759 return Ok(());
1760 }
1761
1762 let mut pending = [0u8; 2];
1763 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1764 let pending_len = self.pending_len;
1765 self.clear_pending();
1766 let result = self.push_encoded(&pending[..pending_len]);
1767 crate::wipe_bytes(&mut pending);
1768 result
1769 }
1770
1771 fn push_encoded(&mut self, input: &[u8]) -> io::Result<()> {
1772 let mut encoded = [0u8; 1024];
1773 let written = match self.engine.encode_slice(input, &mut encoded) {
1774 Ok(written) => written,
1775 Err(err) => {
1776 crate::wipe_bytes(&mut encoded);
1777 return Err(encode_error_to_io(err));
1778 }
1779 };
1780 let result = self.output.push_slice(&encoded[..written]);
1781 crate::wipe_bytes(&mut encoded);
1782 result
1783 }
1784}
1785
1786const fn redacted_inner_state(present: bool) -> &'static str {
1787 if present { "<present>" } else { "<taken>" }
1788}