weakauras_codec_base64/encode/arch/x86_64/
mod.rs

1// Copyright 2020-2025 Velithris
2// SPDX-License-Identifier: MIT
3
4pub mod avx2;
5pub mod ssse3;
6
7#[allow(unused_imports)]
8use crate::{encode::scalar, macros::unsafe_runtime_dispatch};
9#[allow(unused_imports)]
10use core::mem::MaybeUninit;
11
12#[cfg(target_feature = "avx2")]
13pub use avx2::encode_into_unchecked;
14
15// Refer to the reexport for documentation, crate::encode::encode_into_unchecked.
16#[cfg(all(target_feature = "ssse3", not(target_feature = "avx2")))]
17#[inline(always)]
18pub unsafe fn encode_into_unchecked(input: &[u8], output: &mut [MaybeUninit<u8>]) -> usize {
19    unsafe_runtime_dispatch!(
20        encode_into_unchecked,
21        usize,
22        input,
23        output,
24        is_x86_feature_detected,
25        ("avx2", avx2),
26        ssse3,
27    )
28}
29
30// Refer to the reexport for documentation, crate::encode::encode_into_unchecked.
31#[cfg(not(any(target_feature = "ssse3", target_feature = "avx2")))]
32#[inline(always)]
33pub unsafe fn encode_into_unchecked(input: &[u8], output: &mut [MaybeUninit<u8>]) -> usize {
34    unsafe_runtime_dispatch!(
35        encode_into_unchecked,
36        usize,
37        input,
38        output,
39        is_x86_feature_detected,
40        ("avx2", avx2),
41        ("ssse3", ssse3),
42        scalar,
43    )
44}
45
46#[cfg(test)]
47mod tests {
48    #![allow(unused_imports)]
49    use super::*;
50    use crate::encode::tests::*;
51
52    use alloc::{string::String, vec::Vec};
53
54    #[test]
55    #[cfg(target_feature = "ssse3")]
56    fn scalar_and_ssse3_return_same_values() {
57        let data: Vec<u8> = (0..=255).cycle().take(1024 * 30 + 3).collect();
58
59        let capacity = (data.len() * 4 + 2) / 3;
60        let mut buf1 = String::with_capacity(capacity);
61        let mut buf2 = String::with_capacity(capacity);
62
63        unsafe {
64            base64_encode!(&data, buf1, scalar);
65            base64_encode!(&data, buf2, ssse3);
66        }
67
68        assert_eq!(buf1, buf2);
69    }
70
71    #[test]
72    #[cfg(target_feature = "avx2")]
73    fn scalar_and_avx2_return_same_values() {
74        let data: Vec<u8> = (0..=255).cycle().take(1024 * 30 + 3).collect();
75
76        let capacity = (data.len() * 4 + 2) / 3;
77        let mut buf1 = String::with_capacity(capacity);
78        let mut buf2 = String::with_capacity(capacity);
79
80        unsafe {
81            base64_encode!(&data, buf1, scalar);
82            base64_encode!(&data, buf2, avx2);
83        }
84
85        assert_eq!(buf1, buf2);
86    }
87}