#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub struct YamlCharClass {
pub newlines: u32,
pub colons: u32,
pub hyphens: u32,
pub spaces: u32,
pub quotes_double: u32,
pub quotes_single: u32,
pub backslashes: u32,
pub hash: u32,
}
#[inline]
pub fn classify_yaml_chars(input: &[u8], offset: usize) -> Option<YamlCharClass> {
if offset + 16 > input.len() {
return None;
}
#[cfg(any(test, feature = "std"))]
{
if offset + 32 <= input.len() && is_x86_feature_detected!("avx2") {
return Some(unsafe { classify_yaml_chars_avx2(input, offset) });
}
}
if offset + 16 <= input.len() {
return Some(unsafe { classify_yaml_chars_sse2(input, offset) });
}
None
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn classify_yaml_chars_avx2(input: &[u8], offset: usize) -> YamlCharClass {
let chunk = _mm256_loadu_si256(input.as_ptr().add(offset) as *const __m256i);
let v_newline = _mm256_set1_epi8(b'\n' as i8);
let v_colon = _mm256_set1_epi8(b':' as i8);
let v_hyphen = _mm256_set1_epi8(b'-' as i8);
let v_space = _mm256_set1_epi8(b' ' as i8);
let v_quote_double = _mm256_set1_epi8(b'"' as i8);
let v_quote_single = _mm256_set1_epi8(b'\'' as i8);
let v_backslash = _mm256_set1_epi8(b'\\' as i8);
let v_hash = _mm256_set1_epi8(b'#' as i8);
let eq_newline = _mm256_cmpeq_epi8(chunk, v_newline);
let eq_colon = _mm256_cmpeq_epi8(chunk, v_colon);
let eq_hyphen = _mm256_cmpeq_epi8(chunk, v_hyphen);
let eq_space = _mm256_cmpeq_epi8(chunk, v_space);
let eq_quote_double = _mm256_cmpeq_epi8(chunk, v_quote_double);
let eq_quote_single = _mm256_cmpeq_epi8(chunk, v_quote_single);
let eq_backslash = _mm256_cmpeq_epi8(chunk, v_backslash);
let eq_hash = _mm256_cmpeq_epi8(chunk, v_hash);
YamlCharClass {
newlines: _mm256_movemask_epi8(eq_newline) as u32,
colons: _mm256_movemask_epi8(eq_colon) as u32,
hyphens: _mm256_movemask_epi8(eq_hyphen) as u32,
spaces: _mm256_movemask_epi8(eq_space) as u32,
quotes_double: _mm256_movemask_epi8(eq_quote_double) as u32,
quotes_single: _mm256_movemask_epi8(eq_quote_single) as u32,
backslashes: _mm256_movemask_epi8(eq_backslash) as u32,
hash: _mm256_movemask_epi8(eq_hash) as u32,
}
}
#[target_feature(enable = "sse2")]
unsafe fn classify_yaml_chars_sse2(input: &[u8], offset: usize) -> YamlCharClass {
let chunk = _mm_loadu_si128(input.as_ptr().add(offset) as *const __m128i);
let v_newline = _mm_set1_epi8(b'\n' as i8);
let v_colon = _mm_set1_epi8(b':' as i8);
let v_hyphen = _mm_set1_epi8(b'-' as i8);
let v_space = _mm_set1_epi8(b' ' as i8);
let v_quote_double = _mm_set1_epi8(b'"' as i8);
let v_quote_single = _mm_set1_epi8(b'\'' as i8);
let v_backslash = _mm_set1_epi8(b'\\' as i8);
let v_hash = _mm_set1_epi8(b'#' as i8);
let eq_newline = _mm_cmpeq_epi8(chunk, v_newline);
let eq_colon = _mm_cmpeq_epi8(chunk, v_colon);
let eq_hyphen = _mm_cmpeq_epi8(chunk, v_hyphen);
let eq_space = _mm_cmpeq_epi8(chunk, v_space);
let eq_quote_double = _mm_cmpeq_epi8(chunk, v_quote_double);
let eq_quote_single = _mm_cmpeq_epi8(chunk, v_quote_single);
let eq_backslash = _mm_cmpeq_epi8(chunk, v_backslash);
let eq_hash = _mm_cmpeq_epi8(chunk, v_hash);
YamlCharClass {
newlines: _mm_movemask_epi8(eq_newline) as u32,
colons: _mm_movemask_epi8(eq_colon) as u32,
hyphens: _mm_movemask_epi8(eq_hyphen) as u32,
spaces: _mm_movemask_epi8(eq_space) as u32,
quotes_double: _mm_movemask_epi8(eq_quote_double) as u32,
quotes_single: _mm_movemask_epi8(eq_quote_single) as u32,
backslashes: _mm_movemask_epi8(eq_backslash) as u32,
hash: _mm_movemask_epi8(eq_hash) as u32,
}
}
#[inline]
pub fn find_newline_x86(input: &[u8], start: usize) -> Option<usize> {
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { find_newline_avx2(input, start) };
}
}
unsafe { find_newline_sse2(input, start) }
}
#[target_feature(enable = "sse2")]
unsafe fn find_newline_sse2(input: &[u8], start: usize) -> Option<usize> {
let data = &input[start..];
let len = data.len();
let mut offset = 0;
let newline_vec = _mm_set1_epi8(b'\n' as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let matches = _mm_cmpeq_epi8(chunk, newline_vec);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
(offset..len).find(|&i| data[i] == b'\n')
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn find_newline_avx2(input: &[u8], start: usize) -> Option<usize> {
let data = &input[start..];
let len = data.len();
let mut offset = 0;
let newline_vec = _mm256_set1_epi8(b'\n' as i8);
while offset + 32 <= len {
let chunk = _mm256_loadu_si256(data.as_ptr().add(offset) as *const __m256i);
let matches = _mm256_cmpeq_epi8(chunk, newline_vec);
let mask = _mm256_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 32;
}
if offset + 16 <= len {
let newline_vec_sse = _mm_set1_epi8(b'\n' as i8);
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let matches = _mm_cmpeq_epi8(chunk, newline_vec_sse);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
(offset..len).find(|&i| data[i] == b'\n')
}
#[inline]
pub fn find_quote_or_escape_x86(input: &[u8], start: usize, end: usize) -> Option<usize> {
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { find_quote_or_escape_avx2(input, start, end) };
}
}
unsafe { find_quote_or_escape_sse2(input, start, end) }
}
#[inline]
pub fn find_single_quote_x86(input: &[u8], start: usize, end: usize) -> Option<usize> {
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { find_single_quote_avx2(input, start, end) };
}
}
unsafe { find_single_quote_sse2(input, start, end) }
}
#[target_feature(enable = "sse2")]
unsafe fn find_quote_or_escape_sse2(input: &[u8], start: usize, end: usize) -> Option<usize> {
let len = end - start;
let data = &input[start..end];
let mut offset = 0;
let quote_vec = _mm_set1_epi8(b'"' as i8);
let backslash_vec = _mm_set1_epi8(b'\\' as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let quotes = _mm_cmpeq_epi8(chunk, quote_vec);
let backslashes = _mm_cmpeq_epi8(chunk, backslash_vec);
let matches = _mm_or_si128(quotes, backslashes);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
(offset..len).find(|&i| {
let b = data[i];
b == b'"' || b == b'\\'
})
}
#[target_feature(enable = "sse2")]
unsafe fn find_single_quote_sse2(input: &[u8], start: usize, end: usize) -> Option<usize> {
let len = end - start;
let data = &input[start..end];
let mut offset = 0;
let quote_vec = _mm_set1_epi8(b'\'' as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let matches = _mm_cmpeq_epi8(chunk, quote_vec);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
(offset..len).find(|&i| data[i] == b'\'')
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn find_quote_or_escape_avx2(input: &[u8], start: usize, end: usize) -> Option<usize> {
let len = end - start;
let data = &input[start..end];
let mut offset = 0;
let quote_vec = _mm256_set1_epi8(b'"' as i8);
let backslash_vec = _mm256_set1_epi8(b'\\' as i8);
while offset + 32 <= len {
let chunk = _mm256_loadu_si256(data.as_ptr().add(offset) as *const __m256i);
let quotes = _mm256_cmpeq_epi8(chunk, quote_vec);
let backslashes = _mm256_cmpeq_epi8(chunk, backslash_vec);
let matches = _mm256_or_si256(quotes, backslashes);
let mask = _mm256_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 32;
}
if offset + 16 <= len {
let quote_vec_sse = _mm_set1_epi8(b'"' as i8);
let backslash_vec_sse = _mm_set1_epi8(b'\\' as i8);
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let quotes = _mm_cmpeq_epi8(chunk, quote_vec_sse);
let backslashes = _mm_cmpeq_epi8(chunk, backslash_vec_sse);
let matches = _mm_or_si128(quotes, backslashes);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
(offset..len).find(|&i| {
let b = data[i];
b == b'"' || b == b'\\'
})
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn find_single_quote_avx2(input: &[u8], start: usize, end: usize) -> Option<usize> {
let len = end - start;
let data = &input[start..end];
let mut offset = 0;
let quote_vec = _mm256_set1_epi8(b'\'' as i8);
while offset + 32 <= len {
let chunk = _mm256_loadu_si256(data.as_ptr().add(offset) as *const __m256i);
let matches = _mm256_cmpeq_epi8(chunk, quote_vec);
let mask = _mm256_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 32;
}
if offset + 16 <= len {
let quote_vec_sse = _mm_set1_epi8(b'\'' as i8);
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let matches = _mm_cmpeq_epi8(chunk, quote_vec_sse);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
(offset..len).find(|&i| data[i] == b'\'')
}
#[inline]
pub fn count_leading_spaces_x86(input: &[u8], start: usize) -> usize {
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { count_leading_spaces_avx2(input, start) };
}
}
unsafe { count_leading_spaces_sse2(input, start) }
}
#[target_feature(enable = "sse2")]
unsafe fn count_leading_spaces_sse2(input: &[u8], start: usize) -> usize {
let data = &input[start..];
let len = data.len();
let mut offset = 0;
let space_vec = _mm_set1_epi8(b' ' as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let matches = _mm_cmpeq_epi8(chunk, space_vec);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0xFFFF {
return offset + (!mask).trailing_zeros() as usize;
}
offset += 16;
}
offset + data[offset..].iter().take_while(|&&b| b == b' ').count()
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn count_leading_spaces_avx2(input: &[u8], start: usize) -> usize {
let data = &input[start..];
let len = data.len();
let mut offset = 0;
let space_vec = _mm256_set1_epi8(b' ' as i8);
while offset + 32 <= len {
let chunk = _mm256_loadu_si256(data.as_ptr().add(offset) as *const __m256i);
let matches = _mm256_cmpeq_epi8(chunk, space_vec);
let mask = _mm256_movemask_epi8(matches) as u32;
if mask != 0xFFFF_FFFF {
return offset + (!mask).trailing_zeros() as usize;
}
offset += 32;
}
if offset + 16 <= len {
let space_vec_sse = _mm_set1_epi8(b' ' as i8);
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let matches = _mm_cmpeq_epi8(chunk, space_vec_sse);
let mask = _mm_movemask_epi8(matches) as u32;
if mask != 0xFFFF {
return offset + (!mask).trailing_zeros() as usize;
}
offset += 16;
}
offset + data[offset..].iter().take_while(|&&b| b == b' ').count()
}
#[inline]
pub fn find_block_scalar_end(input: &[u8], start: usize, min_indent: usize) -> Option<usize> {
if start >= input.len() {
return Some(input.len());
}
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return Some(unsafe { find_block_scalar_end_avx2(input, start, min_indent) });
}
}
Some(unsafe { find_block_scalar_end_sse2(input, start, min_indent) })
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn find_block_scalar_end_avx2(input: &[u8], start: usize, min_indent: usize) -> usize {
let newline_vec = _mm256_set1_epi8(b'\n' as i8);
let space_vec = _mm256_set1_epi8(b' ' as i8);
let mut pos = start;
while pos + 32 < input.len() {
let chunk = _mm256_loadu_si256(input.as_ptr().add(pos) as *const __m256i);
let nl_matches = _mm256_cmpeq_epi8(chunk, newline_vec);
let mut nl_mask = _mm256_movemask_epi8(nl_matches) as u32;
if nl_mask != 0 {
while nl_mask != 0 {
let offset = nl_mask.trailing_zeros() as usize;
let line_start = pos + offset + 1;
if line_start >= input.len() {
return input.len(); }
let mut indent = 0;
let remaining = input.len() - line_start;
if remaining >= 32 {
let next_chunk =
_mm256_loadu_si256(input.as_ptr().add(line_start) as *const __m256i);
let space_matches = _mm256_cmpeq_epi8(next_chunk, space_vec);
let space_mask = _mm256_movemask_epi8(space_matches) as u32;
if space_mask != 0xFFFF_FFFF {
indent = (!space_mask).trailing_zeros() as usize;
} else {
indent = 32;
let mut check_pos = line_start + 32;
while check_pos < input.len() && input[check_pos] == b' ' {
indent += 1;
check_pos += 1;
}
}
} else {
while line_start + indent < input.len() && input[line_start + indent] == b' ' {
indent += 1;
}
}
if line_start + indent < input.len() {
let next_char = input[line_start + indent];
if next_char != b'\n' && next_char != b'\r' && indent < min_indent {
return line_start;
}
}
nl_mask &= nl_mask - 1;
}
}
pos += 32;
}
find_block_scalar_end_scalar(input, pos, min_indent)
}
#[target_feature(enable = "sse2")]
unsafe fn find_block_scalar_end_sse2(input: &[u8], start: usize, min_indent: usize) -> usize {
let newline_vec = _mm_set1_epi8(b'\n' as i8);
let space_vec = _mm_set1_epi8(b' ' as i8);
let mut pos = start;
while pos + 16 < input.len() {
let chunk = _mm_loadu_si128(input.as_ptr().add(pos) as *const __m128i);
let nl_matches = _mm_cmpeq_epi8(chunk, newline_vec);
let mut nl_mask = _mm_movemask_epi8(nl_matches) as u32;
if nl_mask != 0 {
while nl_mask != 0 {
let offset = nl_mask.trailing_zeros() as usize;
let line_start = pos + offset + 1;
if line_start >= input.len() {
return input.len();
}
let mut indent = 0;
let remaining = input.len() - line_start;
if remaining >= 16 {
let next_chunk =
_mm_loadu_si128(input.as_ptr().add(line_start) as *const __m128i);
let space_matches = _mm_cmpeq_epi8(next_chunk, space_vec);
let space_mask = _mm_movemask_epi8(space_matches) as u32;
if space_mask != 0xFFFF {
indent = (!space_mask).trailing_zeros() as usize;
} else {
indent = 16;
let mut check_pos = line_start + 16;
while check_pos < input.len() && input[check_pos] == b' ' {
indent += 1;
check_pos += 1;
}
}
} else {
while line_start + indent < input.len() && input[line_start + indent] == b' ' {
indent += 1;
}
}
if line_start + indent < input.len() {
let next_char = input[line_start + indent];
if next_char != b'\n' && next_char != b'\r' && indent < min_indent {
return line_start;
}
}
nl_mask &= nl_mask - 1;
}
}
pos += 16;
}
find_block_scalar_end_scalar(input, pos, min_indent)
}
fn find_block_scalar_end_scalar(input: &[u8], start: usize, min_indent: usize) -> usize {
let mut pos = start;
while pos < input.len() {
if input[pos] == b'\n' {
let line_start = pos + 1;
if line_start >= input.len() {
return input.len();
}
let mut indent = 0;
while line_start + indent < input.len() && input[line_start + indent] == b' ' {
indent += 1;
}
if line_start + indent < input.len() {
let next_char = input[line_start + indent];
if next_char != b'\n' && next_char != b'\r' && indent < min_indent {
return line_start;
}
}
}
pos += 1;
}
input.len()
}
#[target_feature(enable = "avx2")]
unsafe fn parse_anchor_name_avx2(input: &[u8], start: usize) -> usize {
let len = input.len();
if start >= len {
return start;
}
let mut pos = start;
let end = len;
let space = _mm256_set1_epi8(b' ' as i8);
let tab = _mm256_set1_epi8(b'\t' as i8);
let newline = _mm256_set1_epi8(b'\n' as i8);
let cr = _mm256_set1_epi8(b'\r' as i8);
let lbracket = _mm256_set1_epi8(b'[' as i8);
let rbracket = _mm256_set1_epi8(b']' as i8);
let lbrace = _mm256_set1_epi8(b'{' as i8);
let rbrace = _mm256_set1_epi8(b'}' as i8);
let comma = _mm256_set1_epi8(b',' as i8);
let colon = _mm256_set1_epi8(b':' as i8);
while pos + 32 <= end {
let chunk = _mm256_loadu_si256(input.as_ptr().add(pos) as *const __m256i);
let is_space = _mm256_cmpeq_epi8(chunk, space);
let is_tab = _mm256_cmpeq_epi8(chunk, tab);
let is_newline = _mm256_cmpeq_epi8(chunk, newline);
let is_cr = _mm256_cmpeq_epi8(chunk, cr);
let is_lbracket = _mm256_cmpeq_epi8(chunk, lbracket);
let is_rbracket = _mm256_cmpeq_epi8(chunk, rbracket);
let is_lbrace = _mm256_cmpeq_epi8(chunk, lbrace);
let is_rbrace = _mm256_cmpeq_epi8(chunk, rbrace);
let is_comma = _mm256_cmpeq_epi8(chunk, comma);
let is_colon = _mm256_cmpeq_epi8(chunk, colon);
let ws = _mm256_or_si256(is_space, is_tab);
let ws = _mm256_or_si256(ws, is_newline);
let ws = _mm256_or_si256(ws, is_cr);
let flow = _mm256_or_si256(is_lbracket, is_rbracket);
let flow = _mm256_or_si256(flow, is_lbrace);
let flow = _mm256_or_si256(flow, is_rbrace);
let flow = _mm256_or_si256(flow, is_comma);
let terminators = _mm256_or_si256(ws, flow);
let terminators = _mm256_or_si256(terminators, is_colon);
let mask = _mm256_movemask_epi8(terminators);
if mask != 0 {
let offset = mask.trailing_zeros() as usize;
return pos + offset;
}
pos += 32;
}
parse_anchor_name_scalar(input, pos)
}
fn parse_anchor_name_scalar(input: &[u8], start: usize) -> usize {
let mut pos = start;
while pos < input.len() {
let b = input[pos];
match b {
b' ' | b'\t' | b'\n' | b'\r' | b'[' | b']' | b'{' | b'}' | b',' => break,
b':' => {
if pos + 1 < input.len() {
let next = input[pos + 1];
if next == b' ' || next == b'\t' || next == b'\n' || next == b'\r' {
break;
}
}
pos += 1;
}
_ => pos += 1,
}
}
pos
}
#[cfg(any(test, feature = "std"))]
#[target_feature(enable = "avx2")]
unsafe fn find_json_escape_avx2(input: &[u8], start: usize) -> Option<usize> {
let len = input.len();
if start >= len {
return None;
}
let data = &input[start..];
let data_len = data.len();
let mut offset = 0;
let quote_vec = _mm256_set1_epi8(b'"' as i8);
let backslash_vec = _mm256_set1_epi8(b'\\' as i8);
let control_threshold = _mm256_set1_epi8(0x20);
while offset + 32 <= data_len {
let chunk = _mm256_loadu_si256(data.as_ptr().add(offset) as *const __m256i);
let is_quote = _mm256_cmpeq_epi8(chunk, quote_vec);
let is_backslash = _mm256_cmpeq_epi8(chunk, backslash_vec);
let is_control = _mm256_cmpgt_epi8(control_threshold, chunk);
let escape_mask = _mm256_or_si256(_mm256_or_si256(is_quote, is_backslash), is_control);
let mask = _mm256_movemask_epi8(escape_mask) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 32;
}
if offset + 16 <= data_len {
let quote_vec_sse = _mm_set1_epi8(b'"' as i8);
let backslash_vec_sse = _mm_set1_epi8(b'\\' as i8);
let control_threshold_sse = _mm_set1_epi8(0x20);
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let is_quote = _mm_cmpeq_epi8(chunk, quote_vec_sse);
let is_backslash = _mm_cmpeq_epi8(chunk, backslash_vec_sse);
let is_control = _mm_cmpgt_epi8(control_threshold_sse, chunk);
let escape_mask = _mm_or_si128(_mm_or_si128(is_quote, is_backslash), is_control);
let mask = _mm_movemask_epi8(escape_mask) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
for i in offset..data_len {
let b = data[i];
if b == b'"' || b == b'\\' || b < 0x20 {
return Some(i);
}
}
None
}
#[target_feature(enable = "sse2")]
unsafe fn find_json_escape_sse2(input: &[u8], start: usize) -> Option<usize> {
let len = input.len();
if start >= len {
return None;
}
let data = &input[start..];
let data_len = data.len();
let mut offset = 0;
let quote_vec = _mm_set1_epi8(b'"' as i8);
let backslash_vec = _mm_set1_epi8(b'\\' as i8);
let control_threshold = _mm_set1_epi8(0x20);
while offset + 16 <= data_len {
let chunk = _mm_loadu_si128(data.as_ptr().add(offset) as *const __m128i);
let is_quote = _mm_cmpeq_epi8(chunk, quote_vec);
let is_backslash = _mm_cmpeq_epi8(chunk, backslash_vec);
let is_control = _mm_cmpgt_epi8(control_threshold, chunk);
let escape_mask = _mm_or_si128(_mm_or_si128(is_quote, is_backslash), is_control);
let mask = _mm_movemask_epi8(escape_mask) as u32;
if mask != 0 {
return Some(offset + mask.trailing_zeros() as usize);
}
offset += 16;
}
for i in offset..data_len {
let b = data[i];
if b == b'"' || b == b'\\' || b < 0x20 {
return Some(i);
}
}
None
}
#[cfg(test)]
fn find_json_escape_scalar(input: &[u8], start: usize) -> Option<usize> {
let data = &input[start..];
for (i, &b) in data.iter().enumerate() {
if b == b'"' || b == b'\\' || b < 0x20 {
return Some(i);
}
}
None
}
#[inline]
pub fn find_json_escape_x86(input: &[u8], start: usize) -> Option<usize> {
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { find_json_escape_avx2(input, start) };
}
}
unsafe { find_json_escape_sse2(input, start) }
}
#[inline]
pub fn parse_anchor_name(input: &[u8], start: usize) -> usize {
if start + 16 <= input.len() {
#[cfg(any(test, feature = "std"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { parse_anchor_name_avx2(input, start) };
}
}
#[cfg(not(any(test, feature = "std")))]
{
return unsafe { parse_anchor_name_avx2(input, start) };
}
}
parse_anchor_name_scalar(input, start)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sse2_find_quote_basic() {
let input = b"hello\"world";
unsafe {
assert_eq!(find_quote_or_escape_sse2(input, 0, input.len()), Some(5));
}
}
#[test]
fn test_sse2_find_backslash() {
let input = b"hello\\world";
unsafe {
assert_eq!(find_quote_or_escape_sse2(input, 0, input.len()), Some(5));
}
}
#[test]
fn test_sse2_find_single_quote() {
let input = b"hello'world";
unsafe {
assert_eq!(find_single_quote_sse2(input, 0, input.len()), Some(5));
}
}
#[test]
fn test_sse2_long_string() {
let mut input = vec![b'a'; 100];
input[50] = b'"';
unsafe {
assert_eq!(find_quote_or_escape_sse2(&input, 0, input.len()), Some(50));
}
}
#[test]
fn test_dispatched_find_quote() {
let input = b"hello\"world";
assert_eq!(find_quote_or_escape_x86(input, 0, input.len()), Some(5));
}
#[test]
fn test_dispatched_find_single_quote() {
let input = b"hello'world";
assert_eq!(find_single_quote_x86(input, 0, input.len()), Some(5));
}
#[test]
fn test_sse2_count_leading_spaces_basic() {
unsafe {
assert_eq!(count_leading_spaces_sse2(b" hello", 0), 2);
assert_eq!(count_leading_spaces_sse2(b" world", 0), 4);
assert_eq!(count_leading_spaces_sse2(b"no spaces", 0), 0);
}
}
#[test]
fn test_sse2_count_leading_spaces_long() {
let mut input = vec![b' '; 50];
input.extend_from_slice(b"content");
unsafe {
assert_eq!(count_leading_spaces_sse2(&input, 0), 50);
}
}
#[test]
fn test_dispatched_count_leading_spaces() {
assert_eq!(count_leading_spaces_x86(b" hello", 0), 2);
assert_eq!(count_leading_spaces_x86(b" world", 0), 4);
assert_eq!(count_leading_spaces_x86(b"no spaces", 0), 0);
let mut input = vec![b' '; 50];
input.extend_from_slice(b"content");
assert_eq!(count_leading_spaces_x86(&input, 0), 50);
}
#[test]
fn test_classify_yaml_chars_basic() {
let input = b"key: #val-item\nmore";
let class = classify_yaml_chars(input, 0).unwrap();
assert_ne!(class.colons & (1 << 3), 0, "Colon not found at position 3");
assert_ne!(class.spaces & (1 << 4), 0, "Space not found at position 4");
assert_ne!(class.hash & (1 << 5), 0, "Hash not found at position 5");
assert_ne!(
class.hyphens & (1 << 9),
0,
"Hyphen not found at position 9"
);
assert_ne!(
class.newlines & (1 << 14),
0,
"Newline not found at position 14"
);
}
#[test]
fn test_classify_yaml_chars_quotes() {
let input = b"a: \"val\" 'x'end."; let class = classify_yaml_chars(input, 0).unwrap();
assert_ne!(
class.quotes_double & (1 << 3),
0,
"Double quote not found at position 3"
);
assert_ne!(
class.quotes_double & (1 << 7),
0,
"Double quote not found at position 7"
);
assert_ne!(
class.quotes_single & (1 << 9),
0,
"Single quote not found at position 9"
);
assert_ne!(
class.quotes_single & (1 << 11),
0,
"Single quote not found at position 11"
);
}
#[test]
fn test_classify_yaml_chars_backslash() {
let input = b"text: \"esc\\n\"ok."; let class = classify_yaml_chars(input, 0).unwrap();
assert_ne!(
class.backslashes & (1 << 10),
0,
"Backslash not found at position 10"
);
}
#[test]
fn test_find_newline_basic() {
let input = b"line1\nline2\nline3";
assert_eq!(find_newline_x86(input, 0), Some(5));
assert_eq!(find_newline_x86(input, 6), Some(5)); }
#[test]
fn test_find_newline_long() {
let mut input = vec![b'x'; 100];
input[50] = b'\n';
assert_eq!(find_newline_x86(&input, 0), Some(50));
}
#[test]
fn test_find_newline_not_found() {
let input = b"no newline here";
assert_eq!(find_newline_x86(input, 0), None);
}
#[test]
fn test_classify_context_sensitive() {
let input = b"key: val t:1:2x."; let class = classify_yaml_chars(input, 0).unwrap();
let colon_space_pattern = class.colons & (class.spaces >> 1);
assert_ne!(
colon_space_pattern & (1 << 3),
0,
"Colon-space pattern not found at position 3"
);
assert_eq!(
colon_space_pattern & (1 << 11),
0,
"False positive: colon-space at position 11"
);
assert_eq!(
colon_space_pattern & (1 << 13),
0,
"False positive: colon-space at position 13"
);
}
#[test]
fn test_classify_hyphen_space_pattern() {
let input = b"- item\nval-nosp."; let class = classify_yaml_chars(input, 0).unwrap();
let hyphen_space_pattern = class.hyphens & (class.spaces >> 1);
assert_ne!(
hyphen_space_pattern & (1 << 0),
0,
"Hyphen-space pattern not found at position 0"
);
assert_eq!(
hyphen_space_pattern & (1 << 11),
0,
"False positive: hyphen-space at position 11"
);
}
#[test]
fn test_find_json_escape_quote() {
let input = b"hello\"world";
assert_eq!(find_json_escape_x86(input, 0), Some(5));
}
#[test]
fn test_find_json_escape_backslash() {
let input = b"hello\\world";
assert_eq!(find_json_escape_x86(input, 0), Some(5));
}
#[test]
fn test_find_json_escape_control_char() {
let input = b"hello\nworld";
assert_eq!(find_json_escape_x86(input, 0), Some(5));
let input2 = b"hello\tworld";
assert_eq!(find_json_escape_x86(input2, 0), Some(5));
let input3 = b"hello\rworld";
assert_eq!(find_json_escape_x86(input3, 0), Some(5));
let input4 = b"hello\0world";
assert_eq!(find_json_escape_x86(input4, 0), Some(5));
}
#[test]
fn test_find_json_escape_none() {
let input = b"hello world";
assert_eq!(find_json_escape_x86(input, 0), None);
let input2 = b"abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
assert_eq!(find_json_escape_x86(input2, 0), None);
}
#[test]
fn test_find_json_escape_long_string() {
let mut input = vec![b'a'; 100];
input[50] = b'"';
assert_eq!(find_json_escape_x86(&input, 0), Some(50));
let mut input2 = vec![b'x'; 100];
input2[75] = b'\n';
assert_eq!(find_json_escape_x86(&input2, 0), Some(75));
}
#[test]
fn test_find_json_escape_at_boundaries() {
let mut input = vec![b'a'; 32];
input[16] = b'"';
assert_eq!(find_json_escape_x86(&input, 0), Some(16));
let mut input2 = vec![b'a'; 64];
input2[32] = b'"';
assert_eq!(find_json_escape_x86(&input2, 0), Some(32));
let mut input3 = vec![b'a'; 32];
input3[15] = b'\t';
assert_eq!(find_json_escape_x86(&input3, 0), Some(15));
}
#[test]
fn test_find_json_escape_start_offset() {
let input = b"ab\"cd\"ef";
assert_eq!(find_json_escape_x86(input, 0), Some(2));
assert_eq!(find_json_escape_x86(input, 3), Some(2));
let input2 = b"abc\ndef\nghi";
assert_eq!(find_json_escape_x86(input2, 0), Some(3));
assert_eq!(find_json_escape_x86(input2, 4), Some(3)); }
#[test]
fn test_find_json_escape_simd_matches_scalar() {
let test_cases: &[&[u8]] = &[
b"",
b"\"",
b"\\",
b"\n",
b"\t",
b"\r",
b"\0",
b"no special chars here",
b"quote at end\"",
b"\"quote at start",
b"has\\backslash",
b"has both \" and \\ chars",
b"control\x01char",
b"all control chars: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09",
&[b'x'; 100],
];
for &input in test_cases {
let scalar = find_json_escape_scalar(input, 0);
let simd = find_json_escape_x86(input, 0);
assert_eq!(
scalar,
simd,
"JSON escape mismatch for {:?}",
String::from_utf8_lossy(input)
);
}
}
#[test]
fn test_find_json_escape_all_control_chars() {
for b in 0u8..0x20 {
let input = [b'a', b'b', b'c', b, b'd', b'e'];
assert_eq!(
find_json_escape_x86(&input, 0),
Some(3),
"Control char 0x{:02x} not detected",
b
);
}
let input_space = b"abc def";
assert_eq!(find_json_escape_x86(input_space, 0), None);
}
}