lzma_rust2/filter/
delta.rs1#[cfg(feature = "encoder")]
4use alloc::vec::Vec;
5
6use crate::Read;
7#[cfg(feature = "encoder")]
8use crate::Write;
9
10const MAX_DISTANCE: usize = 256;
11const _MIN_DISTANCE: usize = 1;
12const DIS_MASK: usize = MAX_DISTANCE - 1;
13
14struct Delta {
15 distance: usize,
16 history: [u8; MAX_DISTANCE],
17 pos: u8,
18}
19
20impl Delta {
21 fn new(distance: usize) -> Self {
22 Self {
23 distance,
24 history: [0; MAX_DISTANCE],
25 pos: 0,
26 }
27 }
28
29 fn decode(&mut self, buf: &mut [u8]) {
30 for item in buf {
31 let pos = self.pos as usize;
32 let h = self.history[(self.distance.wrapping_add(pos)) & DIS_MASK];
33 *item = item.wrapping_add(h);
34 self.history[pos & DIS_MASK] = *item;
35 self.pos = self.pos.wrapping_sub(1);
36 }
37 }
38
39 #[cfg(feature = "encoder")]
40 fn encode(&mut self, buf: &mut [u8]) {
41 for item in buf {
42 let pos = self.pos as usize;
43 let h = self.history[(self.distance.wrapping_add(pos)) & DIS_MASK];
44 let original = *item;
45 *item = item.wrapping_sub(h);
46 self.history[pos & DIS_MASK] = original;
47 self.pos = self.pos.wrapping_sub(1);
48 }
49 }
50}
51
52pub struct DeltaReader<R> {
54 inner: R,
55 delta: Delta,
56}
57
58impl<R> DeltaReader<R> {
59 pub fn new(inner: R, distance: usize) -> Self {
61 Self {
62 inner,
63 delta: Delta::new(distance),
64 }
65 }
66
67 pub fn into_inner(self) -> R {
69 self.inner
70 }
71
72 pub fn inner(&self) -> &R {
74 &self.inner
75 }
76
77 pub fn inner_mut(&mut self) -> &mut R {
79 &mut self.inner
80 }
81}
82
83impl<R: Read> Read for DeltaReader<R> {
84 fn read(&mut self, buf: &mut [u8]) -> crate::Result<usize> {
85 let n = self.inner.read(buf)?;
86 if n == 0 {
87 return Ok(n);
88 }
89 self.delta.decode(&mut buf[..n]);
90 Ok(n)
91 }
92}
93
94#[cfg(feature = "encoder")]
95pub struct DeltaWriter<W> {
97 inner: W,
98 delta: Delta,
99 buffer: Vec<u8>,
100}
101
102#[cfg(feature = "encoder")]
103impl<W> DeltaWriter<W> {
104 pub fn new(inner: W, distance: usize) -> Self {
106 Self {
107 inner,
108 delta: Delta::new(distance),
109 buffer: Vec::with_capacity(4096),
110 }
111 }
112
113 pub fn into_inner(self) -> W {
115 self.inner
116 }
117
118 pub fn inner(&self) -> &W {
120 &self.inner
121 }
122
123 pub fn inner_mut(&mut self) -> &mut W {
125 &mut self.inner
126 }
127}
128
129#[cfg(feature = "encoder")]
130impl<W: Write> Write for DeltaWriter<W> {
131 fn write(&mut self, buf: &[u8]) -> crate::Result<usize> {
132 let data_size = buf.len();
133
134 if data_size > self.buffer.len() {
135 self.buffer.resize(data_size, 0);
136 }
137
138 self.buffer[..data_size].copy_from_slice(buf);
139 self.delta.encode(&mut self.buffer[..data_size]);
140 self.inner.write(&self.buffer[..data_size])
141 }
142
143 fn flush(&mut self) -> crate::Result<()> {
144 self.inner.flush()
145 }
146}
147
148#[cfg(all(feature = "encoder", feature = "std"))]
149#[cfg(test)]
150mod tests {
151 use std::io::Cursor;
152
153 use super::*;
154
155 #[test]
156 fn test_delta_roundtrip() {
157 let test_cases = [
158 vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
159 vec![1, 2, 3, 1, 2, 3, 1, 2, 3],
160 vec![42, 13, 255, 0, 128, 64, 32, 99, 200, 150],
161 vec![100; 20],
162 vec![0, 255, 0, 255, 0, 255, 0, 255],
163 (0..300).map(|i| (i % 256) as u8).collect(),
164 ];
165
166 let distances = vec![1, 2, 4, 8, 16, 32, 64, 128, 256];
167
168 for distance in distances {
169 for (i, original_data) in test_cases.iter().enumerate() {
170 let mut encoded_buffer = Vec::new();
171 let mut writer = DeltaWriter::new(Cursor::new(&mut encoded_buffer), distance);
172 std::io::copy(&mut original_data.as_slice(), &mut writer)
173 .expect("Failed to encode data");
174
175 let mut decoded_data = Vec::new();
176 let mut reader = DeltaReader::new(Cursor::new(&encoded_buffer), distance);
177 std::io::copy(&mut reader, &mut decoded_data).expect("Failed to decode data");
178
179 assert_eq!(
180 original_data, &decoded_data,
181 "Roundtrip failed for distance {distance} with data set {i}",
182 );
183 }
184 }
185 }
186}