1use super::{Alphabet, DecodeError, EncodeError, Engine};
60use std::io::{self, Read, Write};
61
62struct OutputQueue<const CAP: usize> {
63 buffer: [u8; CAP],
64 start: usize,
65 len: usize,
66}
67
68impl<const CAP: usize> OutputQueue<CAP> {
69 const fn new() -> Self {
70 Self {
71 buffer: [0; CAP],
72 start: 0,
73 len: 0,
74 }
75 }
76
77 const fn is_empty(&self) -> bool {
78 self.len == 0
79 }
80
81 const fn len(&self) -> usize {
82 self.len
83 }
84
85 const fn capacity(&self) -> usize {
86 self.len + self.available_capacity()
87 }
88
89 fn push_slice(&mut self, input: &[u8]) -> io::Result<()> {
90 if input.len() > self.available_capacity() {
91 return Err(io::Error::other(
92 "base64 stream output queue capacity exceeded",
93 ));
94 }
95
96 let mut read = 0;
97 while read < input.len() {
98 let write = (self.start + self.len) % CAP;
99 self.buffer[write] = input[read];
100 self.len += 1;
101 read += 1;
102 }
103
104 Ok(())
105 }
106
107 fn copy_front(&self, output: &mut [u8]) -> usize {
108 let count = core::cmp::min(self.len, output.len());
109 let first = core::cmp::min(count, CAP - self.start);
110 output[..first].copy_from_slice(&self.buffer[self.start..self.start + first]);
111
112 let second = count - first;
113 if second > 0 {
114 output[first..first + second].copy_from_slice(&self.buffer[..second]);
115 }
116
117 count
118 }
119
120 fn discard_front(&mut self, count: usize) {
121 let count = core::cmp::min(count, self.len);
122 let first = core::cmp::min(count, CAP - self.start);
123 crate::wipe_bytes(&mut self.buffer[self.start..self.start + first]);
124
125 let second = count - first;
126 if second > 0 {
127 crate::wipe_bytes(&mut self.buffer[..second]);
128 }
129
130 self.start = (self.start + count) % CAP;
131 self.len -= count;
132 if self.len == 0 {
133 self.start = 0;
134 }
135 }
136
137 fn pop_slice(&mut self, output: &mut [u8]) -> usize {
138 let count = self.copy_front(output);
139 self.discard_front(count);
140 count
141 }
142
143 fn clear_all(&mut self) {
144 crate::wipe_bytes(&mut self.buffer);
145 self.start = 0;
146 self.len = 0;
147 }
148
149 const fn available_capacity(&self) -> usize {
150 CAP - self.len
151 }
152}
153
154pub struct Encoder<W, A, const PAD: bool>
162where
163 A: Alphabet,
164{
165 inner: Option<W>,
166 engine: Engine<A, PAD>,
167 pending: [u8; 2],
168 pending_len: usize,
169 output: OutputQueue<1024>,
170 finalized: bool,
171 failed: bool,
172}
173
174impl<W, A, const PAD: bool> Encoder<W, A, PAD>
175where
176 A: Alphabet,
177{
178 #[must_use]
180 pub const fn new(inner: W, engine: Engine<A, PAD>) -> Self {
181 Self {
182 inner: Some(inner),
183 engine,
184 pending: [0; 2],
185 pending_len: 0,
186 output: OutputQueue::new(),
187 finalized: false,
188 failed: false,
189 }
190 }
191
192 #[must_use]
194 pub fn get_ref(&self) -> &W {
195 self.inner_ref()
196 }
197
198 pub fn get_mut(&mut self) -> &mut W {
200 self.inner_mut()
201 }
202
203 #[must_use]
205 pub const fn engine(&self) -> Engine<A, PAD> {
206 self.engine
207 }
208
209 #[must_use]
211 pub const fn is_padded(&self) -> bool {
212 PAD
213 }
214
215 #[must_use]
218 pub const fn pending_len(&self) -> usize {
219 self.pending_len
220 }
221
222 #[must_use]
225 pub const fn has_pending_input(&self) -> bool {
226 self.pending_len != 0
227 }
228
229 #[must_use]
234 pub const fn pending_input_needed_len(&self) -> usize {
235 if self.has_pending_input() {
236 3 - self.pending_len
237 } else {
238 0
239 }
240 }
241
242 #[must_use]
245 pub const fn buffered_output_len(&self) -> usize {
246 self.output.len()
247 }
248
249 #[must_use]
252 pub const fn buffered_output_capacity(&self) -> usize {
253 self.output.capacity()
254 }
255
256 #[must_use]
259 pub const fn buffered_output_remaining_capacity(&self) -> usize {
260 self.output.available_capacity()
261 }
262
263 #[must_use]
266 pub const fn has_buffered_output(&self) -> bool {
267 !self.output.is_empty()
268 }
269
270 #[must_use]
274 pub const fn is_finalized(&self) -> bool {
275 self.finalized
276 }
277
278 #[must_use]
286 pub const fn is_failed(&self) -> bool {
287 self.failed
288 }
289
290 #[must_use]
293 pub const fn can_into_inner(&self) -> bool {
294 !self.is_failed() && !self.has_pending_input() && !self.has_buffered_output()
295 }
296
297 #[must_use]
301 pub fn into_inner(mut self) -> W {
302 self.take_inner()
303 }
304
305 #[allow(clippy::result_large_err)]
311 pub fn try_into_inner(mut self) -> Result<W, Self> {
312 if !self.can_into_inner() {
313 return Err(self);
314 }
315 Ok(self.take_inner())
316 }
317
318 fn inner_ref(&self) -> &W {
319 match &self.inner {
320 Some(inner) => inner,
321 None => unreachable!("stream encoder inner writer was already taken"),
322 }
323 }
324
325 fn inner_mut(&mut self) -> &mut W {
326 match &mut self.inner {
327 Some(inner) => inner,
328 None => unreachable!("stream encoder inner writer was already taken"),
329 }
330 }
331
332 fn take_inner(&mut self) -> W {
333 match self.inner.take() {
334 Some(inner) => inner,
335 None => unreachable!("stream encoder inner writer was already taken"),
336 }
337 }
338
339 fn clear_pending(&mut self) {
340 crate::wipe_bytes(&mut self.pending);
341 self.pending_len = 0;
342 }
343
344 fn clear_output(&mut self) {
345 self.output.clear_all();
346 }
347}
348
349impl<W, A, const PAD: bool> Drop for Encoder<W, A, PAD>
350where
351 A: Alphabet,
352{
353 fn drop(&mut self) {
354 self.clear_pending();
355 self.clear_output();
356 }
357}
358
359impl<W, A, const PAD: bool> core::fmt::Debug for Encoder<W, A, PAD>
360where
361 A: Alphabet,
362{
363 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
364 formatter
365 .debug_struct("Encoder")
366 .field("inner", &redacted_inner_state(self.inner.is_some()))
367 .field("engine", &self.engine)
368 .field("pending", &"<redacted>")
369 .field("pending_len", &self.pending_len)
370 .field("pending_input_needed_len", &self.pending_input_needed_len())
371 .field("buffered_output_len", &self.output.len())
372 .field("buffered_output_capacity", &self.output.capacity())
373 .field(
374 "buffered_output_remaining_capacity",
375 &self.output.available_capacity(),
376 )
377 .field("can_into_inner", &self.can_into_inner())
378 .field("finalized", &self.finalized)
379 .field("failed", &self.failed)
380 .finish()
381 }
382}
383
384impl<W, A, const PAD: bool> Encoder<W, A, PAD>
385where
386 W: Write,
387 A: Alphabet,
388{
389 pub fn try_finish(&mut self) -> io::Result<()> {
399 if self.failed {
400 return Err(stream_encoder_failed_error());
401 }
402 if !self.finalized {
403 self.queue_pending_final()?;
404 self.finalized = true;
405 }
406 self.flush()
407 }
408
409 pub fn finish(mut self) -> io::Result<W> {
411 self.try_finish()?;
412 Ok(self.take_inner())
413 }
414
415 fn queue_pending_final(&mut self) -> io::Result<()> {
416 if self.pending_len == 0 {
417 return Ok(());
418 }
419
420 let mut pending = [0u8; 2];
421 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
422 let pending_len = self.pending_len;
423 let mut encoded = [0u8; 4];
424 let result = self.queue_encoded_temp(&pending[..pending_len], &mut encoded);
425 crate::wipe_bytes(&mut pending);
426 result?;
427 self.clear_pending();
428 Ok(())
429 }
430
431 fn queue_encoded_temp(&mut self, input: &[u8], encoded: &mut [u8]) -> io::Result<()> {
432 let written = match self.engine.encode_slice(input, encoded) {
433 Ok(written) => written,
434 Err(err) => {
435 crate::wipe_bytes(encoded);
436 self.failed = true;
437 return Err(encode_error_to_io(err));
438 }
439 };
440
441 let result = self.output.push_slice(&encoded[..written]);
442 crate::wipe_bytes(encoded);
443 if result.is_err() {
444 self.failed = true;
445 }
446 result
447 }
448
449 fn drain_output(&mut self) -> io::Result<()> {
450 let mut chunk = [0u8; 1024];
451 while !self.output.is_empty() {
452 let pending = self.output.copy_front(&mut chunk);
453 let result = self.inner_mut().write(&chunk[..pending]);
454 crate::wipe_bytes(&mut chunk[..pending]);
455 match result {
456 Ok(0) => {
457 return Err(io::Error::new(
458 io::ErrorKind::WriteZero,
459 "base64 stream encoder could not drain buffered output",
460 ));
461 }
462 Ok(written) => {
463 if written > pending {
464 self.failed = true;
465 return Err(io::Error::new(
466 io::ErrorKind::InvalidData,
467 "wrapped writer reported more bytes than provided",
468 ));
469 }
470 self.output.discard_front(written);
471 }
472 Err(err) => return Err(err),
473 }
474 }
475
476 Ok(())
477 }
478}
479
480impl<W, A, const PAD: bool> Write for Encoder<W, A, PAD>
481where
482 W: Write,
483 A: Alphabet,
484{
485 fn write(&mut self, input: &[u8]) -> io::Result<usize> {
486 if self.failed {
487 return Err(stream_encoder_failed_error());
488 }
489 self.drain_output()?;
490 if self.finalized {
491 return Err(io::Error::new(
492 io::ErrorKind::InvalidInput,
493 "base64 stream encoder received input after finalization",
494 ));
495 }
496 if input.is_empty() {
497 return Ok(0);
498 }
499
500 let mut consumed = 0;
501 if self.pending_len > 0 {
502 let needed = 3 - self.pending_len;
503 if input.len() < needed {
504 self.pending[self.pending_len..self.pending_len + input.len()]
505 .copy_from_slice(input);
506 self.pending_len += input.len();
507 return Ok(input.len());
508 }
509
510 let mut chunk = [0u8; 3];
511 chunk[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
512 chunk[self.pending_len..].copy_from_slice(&input[..needed]);
513
514 let mut encoded = [0u8; 4];
515 let result = self.queue_encoded_temp(&chunk, &mut encoded);
516 crate::wipe_bytes(&mut chunk);
517 result?;
518 self.clear_pending();
519 consumed += needed;
520 }
521
522 let remaining = &input[consumed..];
523 let full_len = remaining.len() / 3 * 3;
524 if full_len > 0 {
525 let max_by_queue = self.output.available_capacity() / 4 * 3;
526 let mut take = core::cmp::min(full_len, core::cmp::min(768, max_by_queue));
527 take -= take % 3;
528
529 if take == 0 {
530 return Ok(consumed);
531 }
532
533 let mut encoded = [0u8; 1024];
534 self.queue_encoded_temp(&remaining[..take], &mut encoded)?;
535 consumed += take;
536
537 if take < full_len {
538 return Ok(consumed);
539 }
540 }
541
542 let tail = &input[consumed..];
543 self.pending[..tail.len()].copy_from_slice(tail);
544 self.pending_len = tail.len();
545 consumed += tail.len();
546
547 Ok(consumed)
548 }
549
550 fn flush(&mut self) -> io::Result<()> {
551 if self.failed {
552 return Err(stream_encoder_failed_error());
553 }
554 self.drain_output()?;
555 self.inner_mut().flush()
556 }
557}
558
559fn encode_error_to_io(err: EncodeError) -> io::Error {
560 io::Error::new(io::ErrorKind::InvalidInput, err)
561}
562
563pub struct Decoder<W, A, const PAD: bool>
579where
580 A: Alphabet,
581{
582 inner: Option<W>,
583 engine: Engine<A, PAD>,
584 pending: [u8; 4],
585 pending_len: usize,
586 output: OutputQueue<1024>,
587 finished: bool,
588 failed: bool,
589 finalized: bool,
590}
591
592impl<W, A, const PAD: bool> Decoder<W, A, PAD>
593where
594 A: Alphabet,
595{
596 #[must_use]
603 pub const fn new(inner: W, engine: Engine<A, PAD>) -> Self {
604 Self {
605 inner: Some(inner),
606 engine,
607 pending: [0; 4],
608 pending_len: 0,
609 output: OutputQueue::new(),
610 finished: false,
611 finalized: false,
612 failed: false,
613 }
614 }
615
616 #[must_use]
618 pub fn get_ref(&self) -> &W {
619 self.inner_ref()
620 }
621
622 pub fn get_mut(&mut self) -> &mut W {
624 self.inner_mut()
625 }
626
627 #[must_use]
629 pub const fn engine(&self) -> Engine<A, PAD> {
630 self.engine
631 }
632
633 #[must_use]
635 pub const fn is_padded(&self) -> bool {
636 PAD
637 }
638
639 #[must_use]
642 pub const fn pending_len(&self) -> usize {
643 self.pending_len
644 }
645
646 #[must_use]
649 pub const fn has_pending_input(&self) -> bool {
650 self.pending_len != 0
651 }
652
653 #[must_use]
658 pub const fn pending_input_needed_len(&self) -> usize {
659 if self.has_pending_input() {
660 4 - self.pending_len
661 } else {
662 0
663 }
664 }
665
666 #[must_use]
669 pub const fn buffered_output_len(&self) -> usize {
670 self.output.len()
671 }
672
673 #[must_use]
676 pub const fn buffered_output_capacity(&self) -> usize {
677 self.output.capacity()
678 }
679
680 #[must_use]
683 pub const fn buffered_output_remaining_capacity(&self) -> usize {
684 self.output.available_capacity()
685 }
686
687 #[must_use]
690 pub const fn has_buffered_output(&self) -> bool {
691 !self.output.is_empty()
692 }
693
694 #[must_use]
700 pub const fn has_terminal_padding(&self) -> bool {
701 self.finished
702 }
703
704 #[must_use]
708 pub const fn is_finalized(&self) -> bool {
709 self.finalized
710 }
711
712 #[must_use]
718 pub const fn is_failed(&self) -> bool {
719 self.failed
720 }
721
722 #[must_use]
725 pub const fn can_into_inner(&self) -> bool {
726 !self.is_failed() && !self.has_pending_input() && !self.has_buffered_output()
727 }
728
729 #[must_use]
733 pub fn into_inner(mut self) -> W {
734 self.take_inner()
735 }
736
737 #[allow(clippy::result_large_err)]
743 pub fn try_into_inner(mut self) -> Result<W, Self> {
744 if !self.can_into_inner() {
745 return Err(self);
746 }
747 Ok(self.take_inner())
748 }
749
750 fn inner_ref(&self) -> &W {
751 match &self.inner {
752 Some(inner) => inner,
753 None => unreachable!("stream decoder inner writer was already taken"),
754 }
755 }
756
757 fn inner_mut(&mut self) -> &mut W {
758 match &mut self.inner {
759 Some(inner) => inner,
760 None => unreachable!("stream decoder inner writer was already taken"),
761 }
762 }
763
764 fn take_inner(&mut self) -> W {
765 match self.inner.take() {
766 Some(inner) => inner,
767 None => unreachable!("stream decoder inner writer was already taken"),
768 }
769 }
770
771 fn clear_pending(&mut self) {
772 crate::wipe_bytes(&mut self.pending);
773 self.pending_len = 0;
774 }
775
776 fn clear_output(&mut self) {
777 self.output.clear_all();
778 }
779}
780
781impl<W, A, const PAD: bool> Drop for Decoder<W, A, PAD>
782where
783 A: Alphabet,
784{
785 fn drop(&mut self) {
786 self.clear_pending();
787 self.clear_output();
788 }
789}
790
791impl<W, A, const PAD: bool> core::fmt::Debug for Decoder<W, A, PAD>
792where
793 A: Alphabet,
794{
795 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
796 formatter
797 .debug_struct("Decoder")
798 .field("inner", &redacted_inner_state(self.inner.is_some()))
799 .field("engine", &self.engine)
800 .field("pending", &"<redacted>")
801 .field("pending_len", &self.pending_len)
802 .field("pending_input_needed_len", &self.pending_input_needed_len())
803 .field("buffered_output_len", &self.output.len())
804 .field("buffered_output_capacity", &self.output.capacity())
805 .field(
806 "buffered_output_remaining_capacity",
807 &self.output.available_capacity(),
808 )
809 .field("can_into_inner", &self.can_into_inner())
810 .field("terminal_padding", &self.finished)
811 .field("finalized", &self.finalized)
812 .field("failed", &self.failed)
813 .finish()
814 }
815}
816
817impl<W, A, const PAD: bool> Decoder<W, A, PAD>
818where
819 W: Write,
820 A: Alphabet,
821{
822 pub fn try_finish(&mut self) -> io::Result<()> {
832 if self.failed {
833 return Err(stream_decoder_failed_error());
834 }
835 if !self.finalized {
836 self.queue_pending_final()?;
837 self.finalized = true;
838 }
839 self.flush()
840 }
841
842 pub fn finish(mut self) -> io::Result<W> {
844 self.try_finish()?;
845 Ok(self.take_inner())
846 }
847
848 fn queue_pending_final(&mut self) -> io::Result<()> {
849 if self.pending_len == 0 {
850 return Ok(());
851 }
852
853 let mut pending = [0u8; 4];
854 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
855 let pending_len = self.pending_len;
856 let mut decoded = [0u8; 3];
857 let result = self.queue_decoded_temp(&pending[..pending_len], &mut decoded);
858 crate::wipe_bytes(&mut pending);
859 if let Err(err) = result {
860 self.clear_pending();
861 return Err(err);
862 }
863 self.clear_pending();
864 Ok(())
865 }
866
867 fn queue_full_quad(&mut self, mut input: [u8; 4]) -> io::Result<()> {
868 let mut decoded = [0u8; 3];
869 let result = self.queue_decoded_temp(&input, &mut decoded);
870 crate::wipe_bytes(&mut input);
871 let written = result?;
872 if written < 3 {
873 self.finished = true;
874 }
875 Ok(())
876 }
877
878 fn queue_decoded_temp(&mut self, input: &[u8], decoded: &mut [u8]) -> io::Result<usize> {
879 let written = match self.engine.decode_slice(input, decoded) {
880 Ok(written) => written,
881 Err(err) => {
882 crate::wipe_bytes(decoded);
883 self.failed = true;
884 return Err(decode_error_to_io(err));
885 }
886 };
887
888 let result = self.output.push_slice(&decoded[..written]);
889 crate::wipe_bytes(decoded);
890 result?;
891 Ok(written)
892 }
893
894 fn drain_output(&mut self) -> io::Result<()> {
895 let mut chunk = [0u8; 1024];
896 while !self.output.is_empty() {
897 let pending = self.output.copy_front(&mut chunk);
898 let result = self.inner_mut().write(&chunk[..pending]);
899 crate::wipe_bytes(&mut chunk[..pending]);
900 match result {
901 Ok(0) => {
902 return Err(io::Error::new(
903 io::ErrorKind::WriteZero,
904 "base64 stream decoder could not drain buffered output",
905 ));
906 }
907 Ok(written) => {
908 if written > pending {
909 self.failed = true;
910 return Err(io::Error::new(
911 io::ErrorKind::InvalidData,
912 "wrapped writer reported more bytes than provided",
913 ));
914 }
915 self.output.discard_front(written);
916 }
917 Err(err) => return Err(err),
918 }
919 }
920
921 Ok(())
922 }
923}
924
925impl<W, A, const PAD: bool> Write for Decoder<W, A, PAD>
926where
927 W: Write,
928 A: Alphabet,
929{
930 fn write(&mut self, input: &[u8]) -> io::Result<usize> {
931 if self.failed {
932 return Err(stream_decoder_failed_error());
933 }
934 if input.is_empty() {
935 self.drain_output()?;
936 return Ok(0);
937 }
938 self.drain_output()?;
939 if self.finalized {
940 return Err(io::Error::new(
941 io::ErrorKind::InvalidInput,
942 "base64 stream decoder received input after finalization",
943 ));
944 }
945 if self.finished {
946 self.failed = true;
947 return Err(trailing_input_after_padding_error());
948 }
949
950 let mut consumed = 0;
951 if self.pending_len > 0 {
952 let needed = 4 - self.pending_len;
953 if input.len() < needed {
954 self.pending[self.pending_len..self.pending_len + input.len()]
955 .copy_from_slice(input);
956 self.pending_len += input.len();
957 return Ok(input.len());
958 }
959
960 let mut quad = [0u8; 4];
961 quad[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
962 quad[self.pending_len..].copy_from_slice(&input[..needed]);
963 let result = self.queue_full_quad(quad);
964 crate::wipe_bytes(&mut quad);
965 if let Err(err) = result {
966 self.clear_pending();
967 return Err(err);
968 }
969 self.clear_pending();
970 consumed += needed;
971
972 if self.finished {
973 return Ok(consumed);
974 }
975 }
976
977 while input.len() - consumed >= 4 {
978 if self.output.available_capacity() < 3 {
979 return Ok(consumed);
980 }
981
982 let mut quad = [
983 input[consumed],
984 input[consumed + 1],
985 input[consumed + 2],
986 input[consumed + 3],
987 ];
988 let mut decoded = [0u8; 3];
989 let written = match self.engine.decode_slice(&quad, &mut decoded) {
990 Ok(written) => written,
991 Err(err) => {
992 crate::wipe_bytes(&mut quad);
993 crate::wipe_bytes(&mut decoded);
994 self.failed = true;
995 if consumed > 0 {
996 return Ok(consumed);
997 }
998
999 return Err(decode_error_to_io(err));
1000 }
1001 };
1002
1003 let result = self.output.push_slice(&decoded[..written]);
1004 crate::wipe_bytes(&mut quad);
1005 crate::wipe_bytes(&mut decoded);
1006 result?;
1007 consumed += 4;
1008
1009 if written < 3 {
1010 self.finished = true;
1011 return Ok(consumed);
1012 }
1013 }
1014
1015 let tail = &input[consumed..];
1016 self.pending[..tail.len()].copy_from_slice(tail);
1017 self.pending_len = tail.len();
1018 consumed += tail.len();
1019
1020 Ok(consumed)
1021 }
1022
1023 fn flush(&mut self) -> io::Result<()> {
1024 if self.failed {
1025 return Err(stream_decoder_failed_error());
1026 }
1027 self.drain_output()?;
1028 self.inner_mut().flush()
1029 }
1030}
1031
1032fn decode_error_to_io(err: DecodeError) -> io::Error {
1033 io::Error::new(io::ErrorKind::InvalidInput, err)
1034}
1035
1036fn trailing_input_after_padding_error() -> io::Error {
1037 io::Error::new(
1038 io::ErrorKind::InvalidInput,
1039 "base64 decoder received trailing input after padding",
1040 )
1041}
1042
1043fn stream_decoder_failed_error() -> io::Error {
1044 io::Error::new(
1045 io::ErrorKind::InvalidInput,
1046 "base64 stream decoder is failed after malformed input",
1047 )
1048}
1049
1050fn stream_encoder_failed_error() -> io::Error {
1051 io::Error::new(
1052 io::ErrorKind::InvalidInput,
1053 "base64 stream encoder is failed after internal error",
1054 )
1055}
1056
1057pub struct DecoderReader<R, A, const PAD: bool>
1072where
1073 A: Alphabet,
1074{
1075 inner: Option<R>,
1076 engine: Engine<A, PAD>,
1077 pending: [u8; 4],
1078 pending_len: usize,
1079 output: OutputQueue<3>,
1080 finished: bool,
1081 terminal_seen: bool,
1082 failed: bool,
1083}
1084
1085impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
1086where
1087 A: Alphabet,
1088{
1089 #[must_use]
1096 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
1097 Self {
1098 inner: Some(inner),
1099 engine,
1100 pending: [0; 4],
1101 pending_len: 0,
1102 output: OutputQueue::new(),
1103 finished: false,
1104 terminal_seen: false,
1105 failed: false,
1106 }
1107 }
1108
1109 #[must_use]
1111 pub fn get_ref(&self) -> &R {
1112 self.inner_ref()
1113 }
1114
1115 pub fn get_mut(&mut self) -> &mut R {
1117 self.inner_mut()
1118 }
1119
1120 #[must_use]
1122 pub const fn engine(&self) -> Engine<A, PAD> {
1123 self.engine
1124 }
1125
1126 #[must_use]
1128 pub const fn is_padded(&self) -> bool {
1129 PAD
1130 }
1131
1132 #[must_use]
1135 pub const fn pending_len(&self) -> usize {
1136 self.pending_len
1137 }
1138
1139 #[must_use]
1142 pub const fn has_pending_input(&self) -> bool {
1143 self.pending_len != 0
1144 }
1145
1146 #[must_use]
1151 pub const fn pending_input_needed_len(&self) -> usize {
1152 if self.has_pending_input() {
1153 4 - self.pending_len
1154 } else {
1155 0
1156 }
1157 }
1158
1159 #[must_use]
1162 pub const fn buffered_output_len(&self) -> usize {
1163 self.output.len()
1164 }
1165
1166 #[must_use]
1169 pub const fn buffered_output_capacity(&self) -> usize {
1170 self.output.capacity()
1171 }
1172
1173 #[must_use]
1176 pub const fn buffered_output_remaining_capacity(&self) -> usize {
1177 self.output.available_capacity()
1178 }
1179
1180 #[must_use]
1183 pub const fn has_buffered_output(&self) -> bool {
1184 !self.output.is_empty()
1185 }
1186
1187 #[must_use]
1194 pub const fn has_terminal_padding(&self) -> bool {
1195 self.terminal_seen
1196 }
1197
1198 #[must_use]
1204 pub const fn has_finished_input(&self) -> bool {
1205 self.finished
1206 }
1207
1208 #[must_use]
1211 pub const fn is_finished(&self) -> bool {
1212 self.finished && self.output.is_empty()
1213 }
1214
1215 #[must_use]
1222 pub const fn is_failed(&self) -> bool {
1223 self.failed
1224 }
1225
1226 #[must_use]
1229 pub const fn can_into_inner(&self) -> bool {
1230 !self.is_failed() && self.is_finished()
1231 }
1232
1233 #[must_use]
1235 pub fn into_inner(mut self) -> R {
1236 self.take_inner()
1237 }
1238
1239 #[allow(clippy::result_large_err)]
1247 pub fn try_into_inner(mut self) -> Result<R, Self> {
1248 if !self.can_into_inner() {
1249 return Err(self);
1250 }
1251 Ok(self.take_inner())
1252 }
1253
1254 fn inner_ref(&self) -> &R {
1255 match &self.inner {
1256 Some(inner) => inner,
1257 None => unreachable!("stream decoder reader inner reader was already taken"),
1258 }
1259 }
1260
1261 fn inner_mut(&mut self) -> &mut R {
1262 match &mut self.inner {
1263 Some(inner) => inner,
1264 None => unreachable!("stream decoder reader inner reader was already taken"),
1265 }
1266 }
1267
1268 fn take_inner(&mut self) -> R {
1269 match self.inner.take() {
1270 Some(inner) => inner,
1271 None => unreachable!("stream decoder reader inner reader was already taken"),
1272 }
1273 }
1274
1275 fn clear_pending(&mut self) {
1276 crate::wipe_bytes(&mut self.pending);
1277 self.pending_len = 0;
1278 }
1279}
1280
1281impl<R, A, const PAD: bool> Drop for DecoderReader<R, A, PAD>
1282where
1283 A: Alphabet,
1284{
1285 fn drop(&mut self) {
1286 self.clear_pending();
1287 self.output.clear_all();
1288 }
1289}
1290
1291impl<R, A, const PAD: bool> core::fmt::Debug for DecoderReader<R, A, PAD>
1292where
1293 A: Alphabet,
1294{
1295 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1296 formatter
1297 .debug_struct("DecoderReader")
1298 .field("inner", &redacted_inner_state(self.inner.is_some()))
1299 .field("engine", &self.engine)
1300 .field("pending", &"<redacted>")
1301 .field("pending_len", &self.pending_len)
1302 .field("pending_input_needed_len", &self.pending_input_needed_len())
1303 .field("buffered_output_len", &self.output.len())
1304 .field("buffered_output_capacity", &self.output.capacity())
1305 .field(
1306 "buffered_output_remaining_capacity",
1307 &self.output.available_capacity(),
1308 )
1309 .field("can_into_inner", &self.can_into_inner())
1310 .field("finished", &self.finished)
1311 .field("terminal_padding", &self.terminal_seen)
1312 .field("failed", &self.failed)
1313 .finish()
1314 }
1315}
1316
1317impl<R, A, const PAD: bool> Read for DecoderReader<R, A, PAD>
1318where
1319 R: Read,
1320 A: Alphabet,
1321{
1322 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
1323 if output.is_empty() {
1324 return Ok(0);
1325 }
1326 if self.failed {
1327 return Err(stream_decoder_failed_error());
1328 }
1329
1330 while self.output.is_empty() && !self.finished {
1331 self.fill_output()?;
1332 }
1333
1334 Ok(self.output.pop_slice(output))
1335 }
1336}
1337
1338impl<R, A, const PAD: bool> DecoderReader<R, A, PAD>
1339where
1340 R: Read,
1341 A: Alphabet,
1342{
1343 fn fill_output(&mut self) -> io::Result<()> {
1344 if self.failed {
1345 return Err(stream_decoder_failed_error());
1346 }
1347 if self.terminal_seen {
1348 self.finished = true;
1349 return Ok(());
1350 }
1351
1352 let mut input = [0u8; 4];
1353 let available = 4 - self.pending_len;
1354 let read = match self.inner_mut().read(&mut input[..available]) {
1355 Ok(read) => read,
1356 Err(err) => {
1357 crate::wipe_bytes(&mut input);
1358 return Err(err);
1359 }
1360 };
1361 if read == 0 {
1362 crate::wipe_bytes(&mut input);
1363 self.finished = true;
1364 self.push_final_pending()?;
1365 return Ok(());
1366 }
1367
1368 self.pending[self.pending_len..self.pending_len + read].copy_from_slice(&input[..read]);
1369 crate::wipe_bytes(&mut input);
1370 self.pending_len += read;
1371 if self.pending_len < 4 {
1372 return Ok(());
1373 }
1374
1375 let mut quad = self.pending;
1376 self.clear_pending();
1377 let result = self.push_decoded(&quad);
1378 crate::wipe_bytes(&mut quad);
1379 result?;
1380 if self.terminal_seen {
1381 self.finished = true;
1382 }
1383 Ok(())
1384 }
1385
1386 fn push_final_pending(&mut self) -> io::Result<()> {
1387 if self.pending_len == 0 {
1388 return Ok(());
1389 }
1390
1391 let mut pending = [0u8; 4];
1392 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1393 let pending_len = self.pending_len;
1394 self.clear_pending();
1395 let result = self.push_decoded(&pending[..pending_len]);
1396 crate::wipe_bytes(&mut pending);
1397 result
1398 }
1399
1400 fn push_decoded(&mut self, input: &[u8]) -> io::Result<()> {
1401 let mut decoded = [0u8; 3];
1402 let written = match self.engine.decode_slice(input, &mut decoded) {
1403 Ok(written) => written,
1404 Err(err) => {
1405 crate::wipe_bytes(&mut decoded);
1406 self.failed = true;
1407 return Err(decode_error_to_io(err));
1408 }
1409 };
1410 let result = self.output.push_slice(&decoded[..written]);
1411 crate::wipe_bytes(&mut decoded);
1412 result?;
1413 if input.len() == 4 && written < 3 {
1414 self.terminal_seen = true;
1415 }
1416 Ok(())
1417 }
1418}
1419
1420pub struct EncoderReader<R, A, const PAD: bool>
1422where
1423 A: Alphabet,
1424{
1425 inner: Option<R>,
1426 engine: Engine<A, PAD>,
1427 pending: [u8; 2],
1428 pending_len: usize,
1429 output: OutputQueue<1024>,
1430 finished: bool,
1431 failed: bool,
1432}
1433
1434impl<R, A, const PAD: bool> EncoderReader<R, A, PAD>
1435where
1436 A: Alphabet,
1437{
1438 #[must_use]
1440 pub fn new(inner: R, engine: Engine<A, PAD>) -> Self {
1441 Self {
1442 inner: Some(inner),
1443 engine,
1444 pending: [0; 2],
1445 pending_len: 0,
1446 output: OutputQueue::new(),
1447 finished: false,
1448 failed: false,
1449 }
1450 }
1451
1452 #[must_use]
1454 pub fn get_ref(&self) -> &R {
1455 self.inner_ref()
1456 }
1457
1458 pub fn get_mut(&mut self) -> &mut R {
1460 self.inner_mut()
1461 }
1462
1463 #[must_use]
1465 pub const fn engine(&self) -> Engine<A, PAD> {
1466 self.engine
1467 }
1468
1469 #[must_use]
1471 pub const fn is_padded(&self) -> bool {
1472 PAD
1473 }
1474
1475 #[must_use]
1478 pub const fn pending_len(&self) -> usize {
1479 self.pending_len
1480 }
1481
1482 #[must_use]
1485 pub const fn has_pending_input(&self) -> bool {
1486 self.pending_len != 0
1487 }
1488
1489 #[must_use]
1494 pub const fn pending_input_needed_len(&self) -> usize {
1495 if self.has_pending_input() {
1496 3 - self.pending_len
1497 } else {
1498 0
1499 }
1500 }
1501
1502 #[must_use]
1505 pub const fn buffered_output_len(&self) -> usize {
1506 self.output.len()
1507 }
1508
1509 #[must_use]
1512 pub const fn buffered_output_capacity(&self) -> usize {
1513 self.output.capacity()
1514 }
1515
1516 #[must_use]
1519 pub const fn buffered_output_remaining_capacity(&self) -> usize {
1520 self.output.available_capacity()
1521 }
1522
1523 #[must_use]
1526 pub const fn has_buffered_output(&self) -> bool {
1527 !self.output.is_empty()
1528 }
1529
1530 #[must_use]
1536 pub const fn has_finished_input(&self) -> bool {
1537 self.finished
1538 }
1539
1540 #[must_use]
1543 pub const fn is_finished(&self) -> bool {
1544 self.finished && self.output.is_empty()
1545 }
1546
1547 #[must_use]
1550 pub const fn is_failed(&self) -> bool {
1551 self.failed
1552 }
1553
1554 #[must_use]
1557 pub const fn can_into_inner(&self) -> bool {
1558 self.is_finished() && !self.failed
1559 }
1560
1561 #[must_use]
1563 pub fn into_inner(mut self) -> R {
1564 self.take_inner()
1565 }
1566
1567 #[allow(clippy::result_large_err)]
1574 pub fn try_into_inner(mut self) -> Result<R, Self> {
1575 if !self.can_into_inner() {
1576 return Err(self);
1577 }
1578 Ok(self.take_inner())
1579 }
1580
1581 fn inner_ref(&self) -> &R {
1582 match &self.inner {
1583 Some(inner) => inner,
1584 None => unreachable!("stream encoder reader inner reader was already taken"),
1585 }
1586 }
1587
1588 fn inner_mut(&mut self) -> &mut R {
1589 match &mut self.inner {
1590 Some(inner) => inner,
1591 None => unreachable!("stream encoder reader inner reader was already taken"),
1592 }
1593 }
1594
1595 fn take_inner(&mut self) -> R {
1596 match self.inner.take() {
1597 Some(inner) => inner,
1598 None => unreachable!("stream encoder reader inner reader was already taken"),
1599 }
1600 }
1601
1602 fn clear_pending(&mut self) {
1603 crate::wipe_bytes(&mut self.pending);
1604 self.pending_len = 0;
1605 }
1606}
1607
1608impl<R, A, const PAD: bool> Drop for EncoderReader<R, A, PAD>
1609where
1610 A: Alphabet,
1611{
1612 fn drop(&mut self) {
1613 self.clear_pending();
1614 self.output.clear_all();
1615 }
1616}
1617
1618impl<R, A, const PAD: bool> core::fmt::Debug for EncoderReader<R, A, PAD>
1619where
1620 A: Alphabet,
1621{
1622 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1623 formatter
1624 .debug_struct("EncoderReader")
1625 .field("inner", &redacted_inner_state(self.inner.is_some()))
1626 .field("engine", &self.engine)
1627 .field("pending", &"<redacted>")
1628 .field("pending_len", &self.pending_len)
1629 .field("pending_input_needed_len", &self.pending_input_needed_len())
1630 .field("buffered_output_len", &self.output.len())
1631 .field("buffered_output_capacity", &self.output.capacity())
1632 .field(
1633 "buffered_output_remaining_capacity",
1634 &self.output.available_capacity(),
1635 )
1636 .field("can_into_inner", &self.can_into_inner())
1637 .field("finished", &self.finished)
1638 .field("failed", &self.failed)
1639 .finish()
1640 }
1641}
1642
1643impl<R, A, const PAD: bool> Read for EncoderReader<R, A, PAD>
1644where
1645 R: Read,
1646 A: Alphabet,
1647{
1648 fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
1649 if self.failed {
1650 return Err(stream_encoder_failed_error());
1651 }
1652
1653 if output.is_empty() {
1654 return Ok(0);
1655 }
1656
1657 while self.output.is_empty() && !self.finished {
1658 self.fill_output()?;
1659 }
1660
1661 Ok(self.output.pop_slice(output))
1662 }
1663}
1664
1665impl<R, A, const PAD: bool> EncoderReader<R, A, PAD>
1666where
1667 R: Read,
1668 A: Alphabet,
1669{
1670 fn fill_output(&mut self) -> io::Result<()> {
1671 let mut input = [0u8; 768];
1672 let read = match self.inner_mut().read(&mut input) {
1673 Ok(read) => read,
1674 Err(err) => {
1675 crate::wipe_bytes(&mut input);
1676 return Err(err);
1677 }
1678 };
1679 if read == 0 {
1680 crate::wipe_bytes(&mut input);
1681 self.finished = true;
1682 if let Err(err) = self.push_final_pending() {
1683 self.failed = true;
1684 return Err(err);
1685 }
1686 return Ok(());
1687 }
1688
1689 let mut consumed = 0;
1690 if self.pending_len > 0 {
1691 let needed = 3 - self.pending_len;
1692 if read < needed {
1693 self.pending[self.pending_len..self.pending_len + read]
1694 .copy_from_slice(&input[..read]);
1695 self.pending_len += read;
1696 crate::wipe_bytes(&mut input);
1697 return Ok(());
1698 }
1699
1700 let mut chunk = [0u8; 3];
1701 chunk[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1702 chunk[self.pending_len..].copy_from_slice(&input[..needed]);
1703 let result = self.push_encoded(&chunk);
1704 crate::wipe_bytes(&mut chunk);
1705 if let Err(err) = result {
1706 crate::wipe_bytes(&mut input);
1707 self.failed = true;
1708 return Err(err);
1709 }
1710 self.clear_pending();
1711 consumed += needed;
1712 }
1713
1714 let remaining = &input[consumed..read];
1715 let full_len = remaining.len() / 3 * 3;
1716 let tail_len = remaining.len() - full_len;
1717 let mut tail = [0u8; 2];
1718 tail[..tail_len].copy_from_slice(&remaining[full_len..]);
1719 let result = if full_len > 0 {
1720 self.push_encoded(&remaining[..full_len])
1721 } else {
1722 Ok(())
1723 };
1724 crate::wipe_bytes(&mut input);
1725 if let Err(err) = result {
1726 crate::wipe_bytes(&mut tail);
1727 self.failed = true;
1728 return Err(err);
1729 }
1730 self.pending[..tail_len].copy_from_slice(&tail[..tail_len]);
1731 crate::wipe_bytes(&mut tail);
1732 self.pending_len = tail_len;
1733 Ok(())
1734 }
1735
1736 fn push_final_pending(&mut self) -> io::Result<()> {
1737 if self.pending_len == 0 {
1738 return Ok(());
1739 }
1740
1741 let mut pending = [0u8; 2];
1742 pending[..self.pending_len].copy_from_slice(&self.pending[..self.pending_len]);
1743 let pending_len = self.pending_len;
1744 self.clear_pending();
1745 let result = self.push_encoded(&pending[..pending_len]);
1746 crate::wipe_bytes(&mut pending);
1747 result
1748 }
1749
1750 fn push_encoded(&mut self, input: &[u8]) -> io::Result<()> {
1751 let mut encoded = [0u8; 1024];
1752 let written = match self.engine.encode_slice(input, &mut encoded) {
1753 Ok(written) => written,
1754 Err(err) => {
1755 crate::wipe_bytes(&mut encoded);
1756 return Err(encode_error_to_io(err));
1757 }
1758 };
1759 let result = self.output.push_slice(&encoded[..written]);
1760 crate::wipe_bytes(&mut encoded);
1761 result
1762 }
1763}
1764
1765const fn redacted_inner_state(present: bool) -> &'static str {
1766 if present { "<present>" } else { "<taken>" }
1767}