diff --git a/src/decode.rs b/src/decode.rs index 528b30f..8af12ce 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -49,32 +49,26 @@ fn group(chars: [u8; 4]) -> u32 { /// Sixteen characters go through each step of the main loop, which measured /// a third cheaper in fuel per character than four at a time. fn groups(chars: &[u8], out: &mut [u8]) -> u32 { - let wide = chars.chunks_exact(16); - let (wide_out, rest_out) = out.split_at_mut(chars.len() / 16 * 12); - let rest = wide.remainder().chunks_exact(4); + let (wide, rest) = chars.as_chunks::<16>(); + let (rest, _) = rest.as_chunks::<4>(); + let (wide_out, rest_out) = out.split_at_mut(wide.len() * 12); + let (wide_out, _) = wide_out.as_chunks_mut::<12>(); + let (rest_out, _) = rest_out.as_chunks_mut::<3>(); let mut flags = 0; - for (chars, bytes) in wide.zip(wide_out.chunks_exact_mut(12)) { - let (Some(low), Some(high)) = - (chars.first_chunk::<8>(), chars.last_chunk::<8>()) - else { - continue; - }; - let low = u64::from_le_bytes(*low); - let high = u64::from_le_bytes(*high); - let [a, b, c, d] = [low, low >> 32, high, high >> 32] - .map(|half| group((half as u32).to_le_bytes())); + for (chars, bytes) in wide.iter().zip(wide_out) { + let chars = u128::from_le_bytes(*chars); + let [a, b, c, d] = [0, 32, 64, 96] + .map(|shift| group(((chars >> shift) as u32).to_le_bytes())); flags |= a | b | c | d; let front = u64::from(a) | u64::from(b) << 24 | u64::from(c) << 48; let back = c >> 16 | d << 8; bytes[..8].copy_from_slice(&front.to_le_bytes()); bytes[8..].copy_from_slice(&back.to_le_bytes()); } - for (chars, bytes) in rest.zip(rest_out.chunks_exact_mut(3)) { - if let Some(chars) = chars.first_chunk::<4>() { - let word = group(*chars); - flags |= word; - bytes.copy_from_slice(&word.to_le_bytes()[..3]); - } + for (chars, bytes) in rest.iter().zip(rest_out) { + let word = group(*chars); + flags |= word; + bytes.copy_from_slice(&word.to_le_bytes()[..3]); } flags }