base64_ng/engine/encode_in_place.rs
1use crate::{Alphabet, EncodeError, Engine, encode_backend, wipe_bytes, wipe_tail};
2
3impl<A, const PAD: bool> Engine<A, PAD>
4where
5 A: Alphabet,
6{
7 /// Encodes the first `input_len` bytes of `buffer` in place.
8 ///
9 /// The buffer must have enough spare capacity for the encoded output. The
10 /// implementation writes from right to left, so unread input bytes are not
11 /// overwritten before they are encoded.
12 ///
13 /// # Panics
14 ///
15 /// Panics only if an internal right-to-left encode invariant is violated.
16 /// This indicates a bug in `base64-ng`; valid or malformed caller input is
17 /// reported through [`EncodeError`] instead.
18 ///
19 /// # Examples
20 ///
21 /// ```
22 /// use base64_ng::STANDARD;
23 ///
24 /// let mut buffer = [0u8; 8];
25 /// buffer[..5].copy_from_slice(b"hello");
26 /// let encoded = STANDARD.encode_in_place(&mut buffer, 5).unwrap();
27 /// assert_eq!(encoded, b"aGVsbG8=");
28 /// ```
29 pub fn encode_in_place<'a>(
30 &self,
31 buffer: &'a mut [u8],
32 input_len: usize,
33 ) -> Result<&'a mut [u8], EncodeError> {
34 let len = encode_backend::encode_in_place::<A, PAD>(buffer, input_len)?;
35 Ok(&mut buffer[..len])
36 }
37
38 /// Encodes the first `input_len` bytes of `buffer` in place and clears all
39 /// bytes after the encoded prefix.
40 ///
41 /// If encoding fails because `input_len` is too large, the output buffer is
42 /// too small, or the encoded length overflows `usize`, the entire buffer is
43 /// cleared before the error is returned. This includes the original
44 /// plaintext in `buffer[..input_len]`; keep another copy before calling
45 /// this method if recovery of the original input is required after an
46 /// error.
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use base64_ng::STANDARD;
52 ///
53 /// let mut buffer = [0xff; 12];
54 /// buffer[..5].copy_from_slice(b"hello");
55 /// let encoded = STANDARD.encode_in_place_clear_tail(&mut buffer, 5).unwrap();
56 /// assert_eq!(encoded, b"aGVsbG8=");
57 /// ```
58 pub fn encode_in_place_clear_tail<'a>(
59 &self,
60 buffer: &'a mut [u8],
61 input_len: usize,
62 ) -> Result<&'a mut [u8], EncodeError> {
63 let len = match self.encode_in_place(buffer, input_len) {
64 Ok(encoded) => encoded.len(),
65 Err(err) => {
66 wipe_bytes(buffer);
67 return Err(err);
68 }
69 };
70 wipe_tail(buffer, len);
71 Ok(&mut buffer[..len])
72 }
73}