basekit 0.5.0

Universal library for encoding in various bases
Documentation
use core::ptr;

use super::super::config::Base64EncodeConfig;
use super::super::error::Base64Error;

/// Encodes the remaining 1–2 input bytes of a base64 stream.
///
/// Writes padding characters when `config.padding` is set.
#[inline(always)]
#[allow(unsafe_op_in_unsafe_fn)]
pub(crate) unsafe fn encode_tail_into(
    config: &Base64EncodeConfig,
    dst: &mut [u8],
    src: &[u8],
) -> Result<usize, Base64Error> {
    debug_assert!(
        src.len() == 1 || src.len() == 2,
        "src length must be 1 or 2"
    );

    let output_len = match (src.len(), config.padding.is_some()) {
        (1, true) => 4,
        (1, false) => 2,
        (2, true) => 4,
        (2, false) => 3,
        _ => unreachable!(),
    };

    if dst.len() < output_len {
        return Err(Base64Error::DestinationBufferTooSmall {
            needed: output_len,
            provided: dst.len(),
        });
    }

    let alphabet_ptr = config.alphabet.as_ptr();
    let ptr = dst.as_mut_ptr();

    match src.len() {
        1 => {
            let triple = (src[0] as u32) << 16;
            let c0 = ((triple >> 18) & 0x3F) as usize;
            let c1 = ((triple >> 12) & 0x3F) as usize;

            ptr.write(ptr::read_unaligned(alphabet_ptr.add(c0)));
            ptr.offset(1)
                .write(ptr::read_unaligned(alphabet_ptr.add(c1)));

            if let Some(padding) = config.padding {
                ptr.offset(2).write(padding);
                ptr.offset(3).write(padding);
                Ok(4)
            } else {
                Ok(2)
            }
        }
        2 => {
            let triple = ((src[0] as u32) << 16) | ((src[1] as u32) << 8);
            let c0 = ((triple >> 18) & 0x3F) as usize;
            let c1 = ((triple >> 12) & 0x3F) as usize;
            let c2 = ((triple >> 6) & 0x3F) as usize;

            ptr.write(ptr::read_unaligned(alphabet_ptr.add(c0)));
            ptr.offset(1)
                .write(ptr::read_unaligned(alphabet_ptr.add(c1)));
            ptr.offset(2)
                .write(ptr::read_unaligned(alphabet_ptr.add(c2)));

            if let Some(padding) = config.padding {
                ptr.offset(3).write(padding);
                Ok(4)
            } else {
                Ok(3)
            }
        }
        0 => Ok(0),
        _ => unreachable!(),
    }
}