preflate_rs/
preflate_input.rs1use crate::{
8 ExitCode,
9 preflate_error::{Result, err_exit_code},
10};
11
12pub struct PlainText {
15 data: Vec<u8>,
17
18 prefix_length: i32,
20
21 pos_offset: i32,
23}
24
25impl std::fmt::Debug for PlainText {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(
28 f,
29 "PlainText {{ prefix_length: {}, pos_offset:{} data: len={} }}",
30 self.prefix_length,
31 self.pos_offset,
32 self.data.len()
33 )
34 }
35}
36
37impl Clone for PlainText {
38 fn clone(&self) -> Self {
39 Self {
40 data: self.data.clone(),
41 prefix_length: self.prefix_length,
42 pos_offset: self.pos_offset,
43 }
44 }
45}
46
47impl PlainText {
48 pub fn new() -> Self {
49 Self {
50 data: Vec::new(),
51 prefix_length: 0,
52 pos_offset: 0,
53 }
54 }
55
56 pub fn shrink_to_dictionary(&mut self) {
59 self.pos_offset += self.data.len() as i32 - self.prefix_length;
61
62 let amount_to_keep = self.data.len().min(32768);
63
64 self.data.drain(..self.data.len() - amount_to_keep);
65 self.prefix_length = self.data.len() as i32;
66 }
67
68 pub fn new_with_data(data: Vec<u8>) -> Self {
69 Self {
70 data,
71 prefix_length: 0,
72 pos_offset: 0,
73 }
74 }
75
76 pub fn len(&self) -> usize {
77 self.data.len() - (self.prefix_length as usize)
78 }
79
80 pub fn total_length(&self) -> u32 {
82 self.pos_offset as u32 + self.len() as u32
83 }
84
85 pub fn text(&self) -> &[u8] {
87 &self.data[self.prefix_length as usize..]
88 }
89
90 pub fn prefix(&self) -> &[u8] {
91 &self.data[0..self.prefix_length as usize]
92 }
93
94 pub fn truncate(&mut self, len: usize) {
95 self.data.truncate(self.prefix_length as usize + len);
96 }
97
98 pub fn push(&mut self, c: u8) {
99 self.data.push(c);
100 }
101
102 pub fn append(&mut self, data: &[u8]) {
103 self.data.extend_from_slice(data);
104 }
105
106 pub fn append_iter(&mut self, data: impl Iterator<Item = u8>) {
107 self.data.extend(data);
108 }
109
110 #[inline(always)]
114 pub fn append_reference(&mut self, dist: u32, len: u32) -> Result<()> {
115 if dist as usize > self.data.len() {
116 return err_exit_code(ExitCode::InvalidDeflate, "Invalid distance in reference");
117 }
118
119 if dist == 1 {
120 let byte = self.data[self.data.len() - 1];
122 self.data.resize(self.data.len() + len as usize, byte);
123 } else if dist >= len {
124 self.data.extend_from_within(
126 self.data.len() - dist as usize..self.data.len() - dist as usize + len as usize,
127 );
128 } else {
129 let start = self.data.len() - dist as usize;
131
132 self.data.reserve(len as usize);
133
134 for i in 0..len {
135 let byte = self.data[start + i as usize];
136 self.data.push(byte);
137 }
138 }
139 Ok(())
140 }
141}
142
143#[derive(Clone, Debug)]
144pub struct PreflateInput<'a> {
145 data: &'a PlainText,
146 pos: i32,
147}
148
149impl<'a> PreflateInput<'a> {
150 pub fn new(v: &'a PlainText) -> Self {
151 PreflateInput {
152 data: v,
153 pos: v.prefix_length,
154 }
155 }
156
157 #[inline(always)]
158 pub fn pos(&self) -> u32 {
159 (self.pos + self.data.pos_offset - self.data.prefix_length) as u32
160 }
161
162 #[inline(always)]
164 pub fn total_length(&self) -> u32 {
165 self.data.total_length()
166 }
167
168 #[inline(always)]
169 pub fn cur_chars(&self, offset: i32) -> &[u8] {
170 &self.data.data[(self.pos + offset) as usize..]
171 }
172
173 #[inline(always)]
174 pub fn cur_char(&self, offset: i32) -> u8 {
175 self.data.data[(self.pos + offset) as usize]
176 }
177
178 #[inline(always)]
179 pub fn advance(&mut self, l: u32) {
180 self.pos += l as i32;
181 debug_assert!((self.pos) <= self.data.data.len() as i32);
182 }
183
184 #[inline(always)]
185 pub fn remaining(&self) -> u32 {
186 (self.data.data.len() as i32 - self.pos) as u32
187 }
188}
189
190#[test]
191fn test_length_behavior() {
192 let mut data = PlainText::new_with_data(vec![0; 10000]);
193
194 let mut input = PreflateInput::new(&data);
195 assert_eq!(input.total_length(), 10000);
196 assert_eq!(input.pos(), 0);
197 assert_eq!(input.remaining(), 10000);
198
199 input.advance(1000);
200 assert_eq!(input.total_length(), 10000);
201 assert_eq!(input.pos(), 1000);
202 assert_eq!(input.remaining(), 9000);
203
204 input.advance(9000);
205 assert_eq!(input.total_length(), 10000);
206 assert_eq!(input.pos(), 10000);
207 assert_eq!(input.remaining(), 0);
208
209 data.shrink_to_dictionary();
210 data.append(&[1; 10000]);
211
212 let mut input = PreflateInput::new(&data);
213 assert_eq!(input.total_length(), 20000);
214 assert_eq!(input.pos(), 10000);
215 assert_eq!(input.remaining(), 10000);
216 assert_eq!(input.cur_char(0), 1);
217 assert_eq!(input.cur_char(-1), 0);
218 assert_eq!(input.cur_char(-1000), 0);
219
220 input.advance(1000);
221 assert_eq!(input.total_length(), 20000);
222 assert_eq!(input.pos(), 11000);
223 assert_eq!(input.remaining(), 9000);
224
225 assert_eq!(input.cur_char(-1), 1);
226 assert_eq!(input.cur_char(-1000), 1);
227}