base64_simd/
check.rs

1use crate::alsw::{STANDARD_ALSW_CHECK_X2, URL_SAFE_ALSW_CHECK_X2};
2use crate::decode::{decode_ascii4, decode_ascii8, decode_extra};
3use crate::decode::{STANDARD_DECODE_TABLE, URL_SAFE_DECODE_TABLE};
4use crate::{Config, Error, Kind};
5
6use vsimd::alsw::AlswLut;
7use vsimd::vector::V256;
8use vsimd::SIMD256;
9
10use core::ptr::null_mut;
11
12#[inline]
13pub(crate) unsafe fn check_fallback(mut src: *const u8, mut n: usize, config: Config) -> Result<(), Error> {
14    let kind = config.kind;
15    let forgiving = config.extra.forgiving();
16
17    let table = match kind {
18        Kind::Standard => STANDARD_DECODE_TABLE.as_ptr(),
19        Kind::UrlSafe => URL_SAFE_DECODE_TABLE.as_ptr(),
20    };
21
22    unsafe {
23        // n*3/4 >= 6+2
24        while n >= 11 {
25            decode_ascii8::<false>(src, null_mut(), table)?;
26            src = src.add(8);
27            n -= 8;
28        }
29
30        while n >= 4 {
31            decode_ascii4::<false>(src, null_mut(), table)?;
32            src = src.add(4);
33            n -= 4;
34        }
35
36        decode_extra::<false>(n, src, null_mut(), table, forgiving)
37    }
38}
39
40#[inline(always)]
41pub(crate) unsafe fn check_simd<S: SIMD256>(
42    s: S,
43    mut src: *const u8,
44    mut n: usize,
45    config: Config,
46) -> Result<(), Error> {
47    let kind = config.kind;
48
49    let check_lut = match kind {
50        Kind::Standard => STANDARD_ALSW_CHECK_X2,
51        Kind::UrlSafe => URL_SAFE_ALSW_CHECK_X2,
52    };
53
54    unsafe {
55        // n*3/4 >= 24+4
56        while n >= 38 {
57            let x = s.v256_load_unaligned(src);
58            let is_valid = check_ascii32(s, x, check_lut);
59            ensure!(is_valid);
60            src = src.add(32);
61            n -= 32;
62        }
63
64        check_fallback(src, n, config)
65    }
66}
67
68#[inline(always)]
69fn check_ascii32<S: SIMD256>(s: S, x: V256, check: AlswLut<V256>) -> bool {
70    vsimd::alsw::check_ascii_xn(s, x, check)
71}