use std::slice;
#[derive(Clone, Copy)]
#[repr(align(8))]
pub struct Translation {
pub utf8_offset: u32,
pub utf16_difference: u32,
}
const CHUNK_SIZE: usize = 32;
const CHUNK_ALIGNMENT: usize = align_of::<AlignedChunk>();
const _: () = {
assert!(CHUNK_SIZE >= CHUNK_ALIGNMENT);
assert!(CHUNK_SIZE.is_multiple_of(CHUNK_ALIGNMENT));
assert!(CHUNK_SIZE == size_of::<AlignedChunk>());
};
#[repr(C, align(16))]
struct AlignedChunk([u8; CHUNK_SIZE]);
impl AlignedChunk {
#[inline]
fn contains_unicode(&self) -> bool {
for index in 0..CHUNK_SIZE {
if !self.0[index].is_ascii() {
return true;
}
}
false
}
#[inline]
fn as_slice(&self) -> &[u8] {
&self.0
}
}
pub fn build_translations(source_text: &str, translations: &mut Vec<Translation>, offset: u32) {
let mut utf16_difference = offset;
let mut process_slice = |slice: &[u8], start_offset: usize| {
for (index, &byte) in slice.iter().enumerate() {
if byte >= 0xC0 {
let difference_for_this_byte = u32::from(byte >= 0xE0) + 1;
utf16_difference += difference_for_this_byte;
let bytes_in_char =
difference_for_this_byte as usize + usize::from(byte >= 0xF0) + 1;
#[expect(clippy::cast_possible_truncation)]
let utf8_offset = (start_offset + index + bytes_in_char) as u32 + offset;
translations.push(Translation { utf8_offset, utf16_difference });
}
}
};
let bytes = source_text.as_bytes();
if bytes.len() < CHUNK_SIZE {
process_slice(bytes, 0);
return;
}
let start_ptr = bytes.as_ptr();
let mut remaining_len = bytes.len();
let mut ptr = start_ptr;
let first_chunk_len = ptr.align_offset(CHUNK_ALIGNMENT);
if first_chunk_len > 0 {
let first_chunk = unsafe { slice::from_raw_parts(ptr, first_chunk_len) };
process_slice(first_chunk, 0);
ptr = unsafe { ptr.add(first_chunk_len) };
remaining_len -= first_chunk_len;
}
debug_assert!((ptr as usize).is_multiple_of(CHUNK_ALIGNMENT));
let body_len = remaining_len & !(CHUNK_SIZE - 1);
remaining_len -= body_len;
let body_end_ptr = unsafe { ptr.add(body_len) };
debug_assert!(body_end_ptr as usize <= start_ptr as usize + bytes.len());
debug_assert!((body_end_ptr as usize - ptr as usize).is_multiple_of(CHUNK_SIZE));
while ptr < body_end_ptr {
#[expect(clippy::cast_ptr_alignment)]
let chunk = unsafe { ptr.cast::<AlignedChunk>().as_ref_unchecked() };
if chunk.contains_unicode() {
let offset = unsafe { ptr.offset_from_unsigned(start_ptr) };
process_slice(chunk.as_slice(), offset);
}
ptr = unsafe { ptr.add(CHUNK_SIZE) };
}
debug_assert!(ptr == body_end_ptr);
if remaining_len > 0 {
debug_assert_eq!(ptr as usize + remaining_len, bytes.as_ptr() as usize + bytes.len());
let last_chunk = unsafe { slice::from_raw_parts(ptr, remaining_len) };
let offset = unsafe { ptr.offset_from_unsigned(start_ptr) };
process_slice(last_chunk, offset);
}
}