1#![no_std]
19
20use core::ptr;
21use core::ops;
22extern crate alloc;
23use alloc::vec::Vec;
24
25#[inline(always)]
35pub fn rle_decode<T>(
36 buffer: &mut Vec<T>,
37 mut lookbehind_length: usize,
38 mut fill_length: usize,
39) where T: Copy {
40 if lookbehind_length == 0 {
41 lookbehind_length_fail();
42 }
43
44 let copy_fragment_start = buffer.len()
45 .checked_sub(lookbehind_length)
46 .expect("attempt to repeat fragment larger than buffer size");
47
48 buffer.reserve(fill_length);
50
51 while fill_length >= lookbehind_length {{}
52 append_from_within(
53 buffer,
54 copy_fragment_start..(copy_fragment_start + lookbehind_length),
55 );
56 fill_length -= lookbehind_length;
57 lookbehind_length *= 2;
58 }
59
60 append_from_within(
62 buffer,
63 copy_fragment_start..(copy_fragment_start + fill_length),
64 );
65}
66
67
68#[inline(always)]
76fn append_from_within<T>(seif: &mut Vec<T>, src: ops::Range<usize>) where T: Copy, {
77 assert!(src.start <= src.end, "src end is before src start");
78 assert!(src.end <= seif.len(), "src is out of bounds");
79 let count = src.end - src.start;
80 seif.reserve(count);
81 let vec_len = seif.len();
82 unsafe {
83 let ptr = seif.as_mut_ptr();
87 let src_ptr = ptr.add(src.start);
88 let dest_ptr = ptr.add(vec_len);
89 ptr::copy_nonoverlapping(src_ptr, dest_ptr, count);
90 seif.set_len(vec_len + count);
91 }
92}
93
94#[inline(never)]
95#[cold]
96fn lookbehind_length_fail() -> ! {
97 panic!("attempt to repeat fragment of size 0");
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use alloc::vec;
104
105 #[test]
106 fn test_basic() {
107 let mut buf = vec![1, 2, 3, 4, 5];
108 rle_decode(&mut buf, 3, 10);
109 assert_eq!(buf, &[1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3]);
110 }
111
112 #[test]
113 fn test_zero_repeat() {
114 let mut buf = vec![1, 2, 3, 4, 5];
115 rle_decode(&mut buf, 3, 0);
116 assert_eq!(buf, &[1, 2, 3, 4, 5]);
117 }
118
119 #[test]
120 #[should_panic]
121 fn test_zero_fragment() {
122 let mut buf = vec![1, 2, 3, 4, 5];
123 rle_decode(&mut buf, 0, 10);
124 }
125
126 #[test]
127 #[should_panic]
128 fn test_zero_fragment_and_repeat() {
129 let mut buf = vec![1, 2, 3, 4, 5];
130 rle_decode(&mut buf, 0, 0);
131 }
132
133 #[test]
134 #[should_panic]
135 fn test_overflow_fragment() {
136 let mut buf = vec![1, 2, 3, 4, 5];
137 rle_decode(&mut buf, 10, 10);
138 }
139
140 #[test]
141 #[should_panic]
142 fn test_overflow_buf_size() {
143 let mut buf = vec![1, 2, 3, 4, 5];
144 rle_decode(&mut buf, 4, usize::max_value());
145 }
146}