1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use crate::{Base64, Error, OutBuf};

#[cfg(feature = "alloc")]
use alloc::boxed::Box;

#[cfg(feature = "alloc")]
use simd_abstraction::tools::alloc_uninit_bytes;

impl Base64 {
    /// Encodes `src` and returns [`Box<str>`]
    #[cfg(feature = "alloc")]
    pub fn encode_to_boxed_str(&self, src: &[u8]) -> Box<str> {
        use core::{slice, str};

        if src.is_empty() {
            return Box::from("");
        }

        unsafe {
            let m = Self::encoded_length_unchecked(src.len(), self.padding);
            let mut uninit_buf = alloc_uninit_bytes(m);
            Self::encode(self, src, OutBuf::from_uninit_mut(&mut *uninit_buf)).unwrap();

            let ptr = Box::into_raw(uninit_buf).cast::<u8>();
            let buf = slice::from_raw_parts_mut(ptr, m);
            Box::from_raw(str::from_utf8_unchecked_mut(buf))
        }
    }

    /// Decodes `src` and returns [`Box<[u8]>`](Box)
    ///
    /// # Errors
    /// This function returns `Err` if:
    ///
    /// + The content of `src` is invalid.
    #[cfg(feature = "alloc")]
    pub fn decode_to_boxed_bytes(&self, src: &[u8]) -> Result<Box<[u8]>, Error> {
        use core::slice;
        if src.is_empty() {
            return Ok(Box::from([]));
        }
        unsafe {
            let (_, m) = Self::decoded_length_unchecked(src, self.padding)?;
            let mut uninit_buf = alloc_uninit_bytes(m);
            Self::decode(self, src, OutBuf::from_uninit_mut(&mut *uninit_buf))?;

            let ptr = Box::into_raw(uninit_buf).cast::<u8>();
            let buf = slice::from_raw_parts_mut(ptr, m);
            Ok(Box::from_raw(buf))
        }
    }
}