1use std::{
2 cmp,
3 io::{self, Read, Write},
4 ptr,
5};
6
7use pool::Reset;
8
9#[derive(Debug, PartialEq, Eq, Clone)]
10pub struct Buffer {
11 memory: Vec<u8>,
12 capacity: usize,
13 position: usize,
14 end: usize,
15}
16
17impl Buffer {
18 pub fn with_capacity(capacity: usize) -> Buffer {
19 Buffer {
20 memory: vec![0; capacity],
21 capacity,
22 position: 0,
23 end: 0,
24 }
25 }
26
27 pub fn from_slice(sl: &[u8]) -> Buffer {
28 Buffer {
29 memory: Vec::from(sl),
30 capacity: sl.len(),
31 position: 0,
32 end: sl.len(),
33 }
34 }
35
36 pub fn grow(&mut self, new_size: usize) -> bool {
37 if self.capacity >= new_size {
38 return false;
39 }
40
41 self.memory.resize(new_size, 0);
42 self.capacity = new_size;
43 true
44 }
45
46 pub fn available_data(&self) -> usize {
47 self.end - self.position
48 }
49
50 pub fn available_space(&self) -> usize {
51 self.capacity - self.end
52 }
53
54 pub fn capacity(&self) -> usize {
55 self.capacity
56 }
57
58 pub fn empty(&self) -> bool {
59 self.position == self.end
60 }
61
62 pub fn consume(&mut self, count: usize) -> usize {
63 let cnt = cmp::min(count, self.available_data());
64 self.position += cnt;
65 if self.position > self.capacity / 2 {
66 self.shift();
68 }
69 cnt
70 }
71
72 pub fn fill(&mut self, count: usize) -> usize {
74 let cnt = cmp::min(count, self.available_space());
75 self.end += cnt;
76 if self.available_space() < self.available_data() + cnt {
77 self.shift();
79 }
80
81 cnt
82 }
83
84 pub fn reset(&mut self) {
85 self.position = 0;
86 self.end = 0;
87 }
88
89 pub fn data(&self) -> &[u8] {
90 &self.memory[self.position..self.end]
91 }
92
93 pub fn space(&mut self) -> &mut [u8] {
94 &mut self.memory[self.end..self.capacity]
95 }
96
97 pub fn shift(&mut self) {
98 if self.position > 0 {
99 unsafe {
100 let length = self.end - self.position;
101 ptr::copy(
102 self.memory[self.position..self.end].as_ptr(),
103 self.memory[..length].as_mut_ptr(),
104 length,
105 );
106 self.position = 0;
107 self.end = length;
108 }
109 }
110 }
111
112 pub fn delete_slice(&mut self, start: usize, length: usize) -> Option<usize> {
113 if start + length >= self.available_data() {
114 return None;
115 }
116
117 unsafe {
118 let begin = self.position + start;
119 let next_end = self.end - length;
120 ptr::copy(
121 self.memory[begin + length..self.end].as_ptr(),
122 self.memory[begin..next_end].as_mut_ptr(),
123 self.end - (begin + length),
124 );
125 self.end = next_end;
126 }
127 Some(self.available_data())
128 }
129
130 pub fn replace_slice(&mut self, data: &[u8], start: usize, length: usize) -> Option<usize> {
131 let data_len = data.len();
132 if start + length > self.available_data()
133 || self.position + start + data_len > self.capacity
134 {
135 return None;
136 }
137
138 unsafe {
139 let begin = self.position + start;
140 let slice_end = begin + data_len;
141 if data_len < length {
143 ptr::copy(
144 data.as_ptr(),
145 self.memory[begin..slice_end].as_mut_ptr(),
146 data_len,
147 );
148
149 ptr::copy(
150 self.memory[start + length..self.end].as_ptr(),
151 self.memory[slice_end..].as_mut_ptr(),
152 self.end - (start + length),
153 );
154 self.end -= length - data_len;
155
156 } else {
158 ptr::copy(
159 self.memory[start + length..self.end].as_ptr(),
160 self.memory[start + data_len..].as_mut_ptr(),
161 self.end - (start + length),
162 );
163 ptr::copy(
164 data.as_ptr(),
165 self.memory[begin..slice_end].as_mut_ptr(),
166 data_len,
167 );
168 self.end += data_len - length;
169 }
170 }
171 Some(self.available_data())
172 }
173
174 pub fn insert_slice(&mut self, data: &[u8], start: usize) -> Option<usize> {
175 let data_len = data.len();
176 if start > self.available_data() || self.position + self.end + data_len > self.capacity {
177 return None;
178 }
179
180 unsafe {
181 let begin = self.position + start;
182 let slice_end = begin + data_len;
183 ptr::copy(
184 self.memory[start..self.end].as_ptr(),
185 self.memory[start + data_len..].as_mut_ptr(),
186 self.end - start,
187 );
188 ptr::copy(
189 data.as_ptr(),
190 self.memory[begin..slice_end].as_mut_ptr(),
191 data_len,
192 );
193 self.end += data_len;
194 }
195 Some(self.available_data())
196 }
197}
198
199impl Write for Buffer {
200 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
201 match self.space().write(buf) {
202 Ok(size) => {
203 self.fill(size);
204 Ok(size)
205 }
206 err => err,
207 }
208 }
209
210 fn flush(&mut self) -> io::Result<()> {
211 Ok(())
212 }
213}
214
215impl Read for Buffer {
216 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
217 let len = cmp::min(self.available_data(), buf.len());
218 unsafe {
219 ptr::copy(
220 self.memory[self.position..self.position + len].as_ptr(),
221 buf.as_mut_ptr(),
222 len,
223 );
224 self.position += len;
225 }
226 Ok(len)
227 }
228}
229
230impl Reset for Buffer {
231 fn reset(&mut self) {
232 self.reset();
233 }
234}
235
236#[cfg(test)]
237mod tests {
238 use super::*;
239 use std::io::Write;
240
241 #[test]
242 fn fill_and_consume() {
243 let mut b = Buffer::with_capacity(10);
244 assert_eq!(b.available_data(), 0);
245 assert_eq!(b.available_space(), 10);
246 let res = b.write(&b"abcd"[..]);
247 assert_eq!(res.ok(), Some(4));
248 assert_eq!(b.available_data(), 4);
249 assert_eq!(b.available_space(), 6);
250
251 assert_eq!(b.data(), &b"abcd"[..]);
252
253 b.consume(2);
254 assert_eq!(b.available_data(), 2);
255 assert_eq!(b.available_space(), 6);
256 assert_eq!(b.data(), &b"cd"[..]);
257
258 b.shift();
259 assert_eq!(b.available_data(), 2);
260 assert_eq!(b.available_space(), 8);
261 assert_eq!(b.data(), &b"cd"[..]);
262
263 assert_eq!(b.write(&b"efghijklmnop"[..]).ok(), Some(8));
264 assert_eq!(b.available_data(), 10);
265 assert_eq!(b.available_space(), 0);
266 assert_eq!(b.data(), &b"cdefghijkl"[..]);
267 b.shift();
268 assert_eq!(b.available_data(), 10);
269 assert_eq!(b.available_space(), 0);
270 assert_eq!(b.data(), &b"cdefghijkl"[..]);
271 }
272
273 #[test]
274 fn delete() {
275 let mut b = Buffer::with_capacity(10);
276 let _ = b.write(&b"abcdefgh"[..]).expect("should write");
277 assert_eq!(b.available_data(), 8);
278 assert_eq!(b.available_space(), 2);
279
280 assert_eq!(b.delete_slice(2, 3), Some(5));
281 assert_eq!(b.available_data(), 5);
282 assert_eq!(b.available_space(), 5);
283 assert_eq!(b.data(), &b"abfgh"[..]);
284
285 assert_eq!(b.delete_slice(5, 2), None);
286 assert_eq!(b.delete_slice(4, 2), None);
287 }
288
289 #[test]
290 fn replace() {
291 let mut b = Buffer::with_capacity(10);
292 let _ = b.write(&b"abcdefgh"[..]).expect("should write");
293 assert_eq!(b.available_data(), 8);
294 assert_eq!(b.available_space(), 2);
295
296 assert_eq!(b.replace_slice(&b"ABC"[..], 2, 3), Some(8));
297 assert_eq!(b.available_data(), 8);
298 assert_eq!(b.available_space(), 2);
299 assert_eq!(b.data(), &b"abABCfgh"[..]);
300
301 assert_eq!(b.replace_slice(&b"XYZ"[..], 8, 3), None);
302 assert_eq!(b.replace_slice(&b"XYZ"[..], 6, 3), None);
303
304 assert_eq!(b.replace_slice(&b"XYZ"[..], 2, 4), Some(7));
305 assert_eq!(b.available_data(), 7);
306 assert_eq!(b.available_space(), 3);
307 assert_eq!(b.data(), &b"abXYZgh"[..]);
308
309 assert_eq!(b.replace_slice(&b"123"[..], 2, 2), Some(8));
310 assert_eq!(b.available_data(), 8);
311 assert_eq!(b.available_space(), 2);
312 assert_eq!(b.data(), &b"ab123Zgh"[..]);
313 }
314}