1use std::{cmp, ptr};
51use std::io::{self,Write,Read};
52use std::iter::repeat;
53
54#[derive(Debug,PartialEq,Clone)]
58pub struct Buffer {
59 memory: Vec<u8>,
61 capacity: usize,
63 position: usize,
65 end: usize
68}
69
70impl Buffer {
71 pub fn with_capacity(capacity: usize) -> Buffer {
73 let mut v = Vec::with_capacity(capacity);
74 v.extend(repeat(0).take(capacity));
75 Buffer {
76 memory: v,
77 capacity: capacity,
78 position: 0,
79 end: 0
80 }
81 }
82
83 pub fn from_slice(data: &[u8]) -> Buffer {
87 Buffer {
88 memory: Vec::from(data),
89 capacity: data.len(),
90 position: 0,
91 end: data.len()
92 }
93 }
94
95 pub fn grow(&mut self, new_size: usize) -> bool {
99 if self.capacity >= new_size {
100 return false;
101 }
102
103 self.memory.resize(new_size, 0);
104 self.capacity = new_size;
105 true
106 }
107
108 pub fn available_data(&self) -> usize {
110 self.end - self.position
111 }
112
113 pub fn available_space(&self) -> usize {
115 self.capacity - self.end
116 }
117
118 pub fn capacity(&self) -> usize {
120 self.capacity
121 }
122
123 pub fn empty(&self) -> bool {
125 self.position == self.end
126 }
127
128 pub fn consume(&mut self, count: usize) -> usize {
134 let cnt = cmp::min(count, self.available_data());
135 self.position += cnt;
136 if self.position > self.capacity / 2 {
137 self.shift();
139 }
140 cnt
141 }
142
143 pub fn consume_noshift(&mut self, count: usize) -> usize {
148 let cnt = cmp::min(count, self.available_data());
149 self.position += cnt;
150 cnt
151 }
152
153 pub fn fill(&mut self, count: usize) -> usize {
160 let cnt = cmp::min(count, self.available_space());
161 self.end += cnt;
162 if self.available_space() < self.available_data() + cnt {
163 self.shift();
165 }
166
167 cnt
168 }
169
170 pub fn position(&self) -> usize {
190 self.position
191 }
192
193 pub fn reset(&mut self) {
196 self.position = 0;
197 self.end = 0;
198 }
199
200 pub fn data(&self) -> &[u8] {
202 &self.memory[self.position..self.end]
203 }
204
205 pub fn space(&mut self) -> &mut[u8] {
208 &mut self.memory[self.end..self.capacity]
209 }
210
211 pub fn shift(&mut self) {
215 if self.position > 0 {
216 unsafe {
217 let length = self.end - self.position;
218 ptr::copy( (&self.memory[self.position..self.end]).as_ptr(), (&mut self.memory[..length]).as_mut_ptr(), length);
219 self.position = 0;
220 self.end = length;
221 }
222 }
223 }
224
225 #[doc(hidden)]
227 pub fn delete_slice(&mut self, start: usize, length: usize) -> Option<usize> {
228 if start + length >= self.available_data() {
229 return None
230 }
231
232 unsafe {
233 let begin = self.position + start;
234 let next_end = self.end - length;
235 ptr::copy(
236 (&self.memory[begin+length..self.end]).as_ptr(),
237 (&mut self.memory[begin..next_end]).as_mut_ptr(),
238 self.end - (begin+length)
239 );
240 self.end = next_end;
241 }
242 Some(self.available_data())
243 }
244
245 #[doc(hidden)]
247 pub fn replace_slice(&mut self, data: &[u8], start: usize, length: usize) -> Option<usize> {
248 let data_len = data.len();
249 if start + length > self.available_data() ||
250 self.position + start + data_len > self.capacity {
251 return None
252 }
253
254 unsafe {
255 let begin = self.position + start;
256 let slice_end = begin + data_len;
257 if data_len < length {
259 ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len);
260
261 ptr::copy((&self.memory[start+length..self.end]).as_ptr(), (&mut self.memory[slice_end..]).as_mut_ptr(), self.end - (start + length));
262 self.end = self.end - (length - data_len);
263
264 } else {
266 ptr::copy((&self.memory[start+length..self.end]).as_ptr(), (&mut self.memory[start+data_len..]).as_mut_ptr(), self.end - (start + length));
267 ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len);
268 self.end = self.end + data_len - length;
269 }
270 }
271 Some(self.available_data())
272 }
273
274 #[doc(hidden)]
276 pub fn insert_slice(&mut self, data: &[u8], start: usize) -> Option<usize> {
277 let data_len = data.len();
278 if start > self.available_data() ||
279 self.position + self.end + data_len > self.capacity {
280 return None
281 }
282
283 unsafe {
284 let begin = self.position + start;
285 let slice_end = begin + data_len;
286 ptr::copy((&self.memory[start..self.end]).as_ptr(), (&mut self.memory[start+data_len..]).as_mut_ptr(), self.end - start);
287 ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len);
288 self.end = self.end + data_len;
289 }
290 Some(self.available_data())
291 }
292}
293
294impl Write for Buffer {
295 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
296 match self.space().write(buf) {
297 Ok(size) => { self.fill(size); Ok(size) },
298 err => err
299 }
300 }
301
302 fn flush(&mut self) -> io::Result<()> {
303 Ok(())
304 }
305}
306
307impl Read for Buffer {
308 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
309 let len = cmp::min(self.available_data(), buf.len());
310 unsafe {
311 ptr::copy((&self.memory[self.position..self.position+len]).as_ptr(), buf.as_mut_ptr(), len);
312 self.position += len;
313 }
314 Ok(len)
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use super::*;
321 use std::io::Write;
322
323 #[test]
324 fn fill_and_consume() {
325 let mut b = Buffer::with_capacity(10);
326 assert_eq!(b.available_data(), 0);
327 assert_eq!(b.available_space(), 10);
328 let res = b.write(&b"abcd"[..]);
329 assert_eq!(res.ok(), Some(4));
330 assert_eq!(b.available_data(), 4);
331 assert_eq!(b.available_space(), 6);
332
333 assert_eq!(b.data(), &b"abcd"[..]);
334
335 b.consume(2);
336 assert_eq!(b.available_data(), 2);
337 assert_eq!(b.available_space(), 6);
338 assert_eq!(b.data(), &b"cd"[..]);
339
340 b.shift();
341 assert_eq!(b.available_data(), 2);
342 assert_eq!(b.available_space(), 8);
343 assert_eq!(b.data(), &b"cd"[..]);
344
345 assert_eq!(b.write(&b"efghijklmnop"[..]).ok(), Some(8));
346 assert_eq!(b.available_data(), 10);
347 assert_eq!(b.available_space(), 0);
348 assert_eq!(b.data(), &b"cdefghijkl"[..]);
349 b.shift();
350 assert_eq!(b.available_data(), 10);
351 assert_eq!(b.available_space(), 0);
352 assert_eq!(b.data(), &b"cdefghijkl"[..]);
353 }
354
355 #[test]
356 fn delete() {
357 let mut b = Buffer::with_capacity(10);
358 let _ = b.write(&b"abcdefgh"[..]);
359 assert_eq!(b.available_data(), 8);
360 assert_eq!(b.available_space(), 2);
361
362 assert_eq!(b.delete_slice(2, 3), Some(5));
363 assert_eq!(b.available_data(), 5);
364 assert_eq!(b.available_space(), 5);
365 assert_eq!(b.data(), &b"abfgh"[..]);
366
367 assert_eq!(b.delete_slice(5, 2), None);
368 assert_eq!(b.delete_slice(4, 2), None);
369 }
370
371 #[test]
372 fn replace() {
373 let mut b = Buffer::with_capacity(10);
374 let _ = b.write(&b"abcdefgh"[..]);
375 assert_eq!(b.available_data(), 8);
376 assert_eq!(b.available_space(), 2);
377
378 assert_eq!(b.replace_slice(&b"ABC"[..], 2, 3), Some(8));
379 assert_eq!(b.available_data(), 8);
380 assert_eq!(b.available_space(), 2);
381 assert_eq!(b.data(), &b"abABCfgh"[..]);
382
383 assert_eq!(b.replace_slice(&b"XYZ"[..], 8, 3), None);
384 assert_eq!(b.replace_slice(&b"XYZ"[..], 6, 3), None);
385
386 assert_eq!(b.replace_slice(&b"XYZ"[..], 2, 4), Some(7));
387 assert_eq!(b.available_data(), 7);
388 assert_eq!(b.available_space(), 3);
389 assert_eq!(b.data(), &b"abXYZgh"[..]);
390
391 assert_eq!(b.replace_slice(&b"123"[..], 2, 2), Some(8));
392 assert_eq!(b.available_data(), 8);
393 assert_eq!(b.available_space(), 2);
394 assert_eq!(b.data(), &b"ab123Zgh"[..]);
395 }
396
397 use std::str;
398 #[test]
399 fn set_position() {
400 let mut output = [0;5];
401 let mut b = Buffer::with_capacity(10);
402 let _ = b.write(&b"abcdefgh"[..]);
403 let _ = b.read(&mut output);
404 assert_eq!(b.available_data(), 3);
405 println!("{:?}", b.position());
406 }
407
408 #[test]
409 fn consume_without_shift() {
410 let mut b = Buffer::with_capacity(10);
411 let _ = b.write(&b"abcdefgh"[..]);
412 b.consume_noshift(6);
413 assert_eq!(b.position(), 6);
414 }
415}