Skip to main content

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}