#[inline]
pub fn copy_match(output: &mut Vec<u8>, offset: usize, length: usize) {
debug_assert!(offset > 0, "offset must be positive");
debug_assert!(offset <= output.len(), "offset exceeds buffer");
let start = output.len() - offset;
if offset >= length {
output.reserve(length);
unsafe {
let ptr = output.as_ptr().add(start);
let dst = output.as_mut_ptr().add(output.len());
std::ptr::copy_nonoverlapping(ptr, dst, length);
output.set_len(output.len() + length);
}
} else {
output.reserve(length);
if offset == 1 {
let byte = output[start];
output.extend(std::iter::repeat_n(byte, length));
} else if offset < 8 {
for i in 0..length {
let byte = output[start + (i % offset)];
output.push(byte);
}
} else {
let mut remaining = length;
while remaining > 0 {
let copy_len = remaining.min(offset);
let src_start = output.len() - offset;
output.reserve(copy_len);
unsafe {
let ptr = output.as_ptr().add(src_start);
let dst = output.as_mut_ptr().add(output.len());
std::ptr::copy_nonoverlapping(ptr, dst, copy_len);
output.set_len(output.len() + copy_len);
}
remaining -= copy_len;
}
}
}
}
#[inline]
pub fn fill_repeat(output: &mut Vec<u8>, pattern: &[u8], count: usize) {
if pattern.is_empty() || count == 0 {
return;
}
let total_len = pattern.len() * count;
output.reserve(total_len);
if pattern.len() == 1 {
output.extend(std::iter::repeat_n(pattern[0], count));
} else {
for _ in 0..count {
output.extend_from_slice(pattern);
}
}
}
#[inline]
pub fn copy_within_extend(output: &mut Vec<u8>, src_start: usize, length: usize) {
output.reserve(length);
let offset = output.len() - src_start;
if offset >= length {
unsafe {
let ptr = output.as_ptr().add(src_start);
let dst = output.as_mut_ptr().add(output.len());
std::ptr::copy_nonoverlapping(ptr, dst, length);
output.set_len(output.len() + length);
}
} else {
let mut copied = 0;
while copied < length {
let chunk = (length - copied).min(offset);
unsafe {
let ptr = output.as_ptr().add(src_start + (copied % offset));
let dst = output.as_mut_ptr().add(output.len());
std::ptr::copy_nonoverlapping(ptr, dst, chunk);
output.set_len(output.len() + chunk);
}
copied += chunk;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_copy_match_non_overlapping() {
let mut output = vec![1, 2, 3, 4, 5];
copy_match(&mut output, 5, 3);
assert_eq!(output, vec![1, 2, 3, 4, 5, 1, 2, 3]);
}
#[test]
fn test_copy_match_overlapping() {
let mut output = vec![b'A', b'B', b'C'];
copy_match(&mut output, 2, 6);
assert_eq!(output, b"ABCBCBCBC");
}
#[test]
fn test_copy_match_rle() {
let mut output = vec![b'X'];
copy_match(&mut output, 1, 5);
assert_eq!(output, b"XXXXXX");
}
#[test]
fn test_copy_match_offset_3() {
let mut output = vec![b'A', b'B', b'C'];
copy_match(&mut output, 3, 9);
assert_eq!(output, b"ABCABCABCABC");
}
#[test]
fn test_fill_repeat_single() {
let mut output = Vec::new();
fill_repeat(&mut output, b"X", 5);
assert_eq!(output, b"XXXXX");
}
#[test]
fn test_fill_repeat_pattern() {
let mut output = Vec::new();
fill_repeat(&mut output, b"AB", 4);
assert_eq!(output, b"ABABABAB");
}
#[test]
fn test_fill_repeat_empty() {
let mut output = Vec::new();
fill_repeat(&mut output, b"", 5);
assert!(output.is_empty());
fill_repeat(&mut output, b"X", 0);
assert!(output.is_empty());
}
#[test]
fn test_copy_match_medium_offset() {
let mut output: Vec<u8> = (0..20).collect();
let original_len = output.len();
copy_match(&mut output, 10, 25);
assert_eq!(
&output[original_len..original_len + 10],
&(10..20).collect::<Vec<u8>>()
);
assert_eq!(output.len(), original_len + 25);
}
#[test]
fn test_copy_within_extend_non_overlapping() {
let mut output = vec![1, 2, 3, 4, 5];
copy_within_extend(&mut output, 0, 3);
assert_eq!(output, vec![1, 2, 3, 4, 5, 1, 2, 3]);
}
#[test]
fn test_copy_within_extend_overlapping() {
let mut output = vec![1, 2, 3];
copy_within_extend(&mut output, 1, 5);
assert_eq!(output, vec![1, 2, 3, 2, 3, 2, 3, 2]);
}
}