1#![forbid(unsafe_code)]
8
9use std::cmp::min;
10use std::io::{Error, ErrorKind, Read, Result, Write};
11
12macro_rules! check_valid {
13 ($self:ident) => {
14 debug_assert!($self.read_pos < $self.data.len());
15 debug_assert!($self.write_pos < $self.data.len());
16 }
17}
18
19pub struct RingBuf {
42 data: Box<[u8]>,
43 read_pos: usize,
44 write_pos: usize
45}
46
47impl RingBuf {
48 pub fn with_capacity(capacity: usize) -> Self {
63 vec!(0; capacity + 1).into_boxed_slice().into()
64 }
65
66 pub fn capacity(&self) -> usize {
77 check_valid!(self);
78
79 self.data.len() - 1
80 }
81
82 pub fn clear(&mut self) {
97 check_valid!(self);
98
99 self.read_pos = 0;
100 self.write_pos = 0;
101 }
102
103 pub fn len(&self) -> usize {
115 check_valid!(self);
116
117 if self.read_pos > self.write_pos {
118 self.data.len() - self.read_pos + self.write_pos
119 }
120 else {
121 self.write_pos - self.read_pos
122 }
123 }
124
125 pub fn is_empty(&self) -> bool {
141 check_valid!(self);
142
143 self.read_pos == self.write_pos
144 }
145
146 pub fn advance_read_pos(&mut self, count: usize) -> Result<()> {
169 check_valid!(self);
170
171 if count > self.len() {
172 return Err(Error::new(ErrorKind::InvalidInput, "Can't seek past write pos."));
173 }
174
175 self.read_pos += count;
176 if self.read_pos >= self.data.len() {
177 self.read_pos -= self.data.len();
178 }
179
180 Ok(())
181 }
182
183 pub fn peek(&self, buf: &mut [u8]) -> Result<usize> {
200 check_valid!(self);
201
202 let to_read = min(self.len(), buf.len());
203 let bytes_until_end = self.data.len() - self.read_pos;
204 if bytes_until_end <= to_read {
205 buf[..bytes_until_end].copy_from_slice(&self.data[self.read_pos..]);
206 buf[bytes_until_end..to_read].copy_from_slice(&self.data[..to_read - bytes_until_end]);
207 }
208 else {
209 buf[..to_read].copy_from_slice(&self.data[self.read_pos..self.read_pos + to_read]);
210 }
211
212 Ok(to_read)
213 }
214}
215
216impl From<Box<[u8]>> for RingBuf {
217 fn from(s: Box<[u8]>) -> Self {
229 RingBuf {
230 data: s,
231 read_pos: 0,
232 write_pos: 0
233 }
234 }
235}
236
237impl From<Vec<u8>> for RingBuf {
238 fn from(mut s: Vec<u8>) -> Self {
253 s.push(0);
254 let write_pos = s.len() - 1;
255 RingBuf {
256 data: s.into_boxed_slice(),
257 read_pos: 0,
258 write_pos
259 }
260 }
261}
262
263impl Read for RingBuf {
264 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
265 check_valid!(self);
266
267 let bytes_read = self.peek(buf)?;
268 self.advance_read_pos(bytes_read)?;
269 Ok(bytes_read)
270 }
271}
272
273impl Write for RingBuf {
274 fn write(&mut self, buf: &[u8]) -> Result<usize> {
275 check_valid!(self);
276
277 let to_write = min(self.capacity() - self.len(), buf.len());
278 let bytes_until_end = self.data.len() - self.write_pos;
279 if bytes_until_end <= to_write {
280 self.data[self.write_pos..].copy_from_slice(&buf[..bytes_until_end]);
281 self.data[..to_write - bytes_until_end].copy_from_slice(&buf[bytes_until_end..to_write]);
282 self.write_pos = to_write - bytes_until_end;
283 }
284 else {
285 self.data[self.write_pos..self.write_pos + to_write].copy_from_slice(&buf[..to_write]);
286 self.write_pos += to_write;
287 }
288
289 Ok(to_write)
290 }
291
292 fn flush(&mut self) -> Result<()> {
293 check_valid!(self);
294
295 Ok(())
296 }
297}
298
299#[cfg(test)]
300mod tests {
301 use std::io::{Read, Write};
302
303 use crate::RingBuf;
304
305 #[test]
306 fn ringbuf_with_capacity() {
307 let rb = RingBuf::with_capacity(4);
308
309 assert_eq!(rb.capacity(), 4);
310 assert_eq!(rb.len(), 0);
311 assert!(rb.is_empty());
312 }
313
314 #[test]
315 fn ringbuf_from_vec() {
316 let mut rb: RingBuf = vec![5, 4, 3, 2, 1].into();
317
318 assert_eq!(rb.capacity(), 5);
319 assert_eq!(rb.len(), 5);
320 assert!(!rb.is_empty());
321
322 let mut buf = [0u8; 10];
323 assert_eq!(rb.peek(&mut buf).unwrap(), 5);
324 assert_eq!(buf, [5, 4, 3, 2, 1, 0, 0, 0, 0, 0]);
325
326 assert_eq!(rb.capacity(), 5);
327 assert_eq!(rb.len(), 5);
328 assert!(!rb.is_empty());
329
330 buf = [0u8; 10];
331 assert_eq!(rb.read(&mut buf).unwrap(), 5);
332 assert_eq!(buf, [5, 4, 3, 2, 1, 0, 0, 0, 0, 0]);
333
334 assert_eq!(rb.capacity(), 5);
335 assert_eq!(rb.len(), 0);
336 assert!(rb.is_empty());
337
338 buf = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
339 assert_eq!(rb.write(&buf).unwrap(), 5);
340
341 assert_eq!(rb.capacity(), 5);
342 assert_eq!(rb.len(), 5);
343 assert!(!rb.is_empty());
344
345 buf = [0u8; 10];
346 assert_eq!(rb.read(&mut buf).unwrap(), 5);
347 assert_eq!(buf, [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
348
349 assert_eq!(rb.capacity(), 5);
350 assert_eq!(rb.len(), 0);
351 assert!(rb.is_empty());
352 }
353
354 #[test]
355 fn ringbuf_wrapped_read_write() {
356 let mut rb = RingBuf::with_capacity(5);
357
358 assert_eq!(rb.capacity(), 5);
359 assert_eq!(rb.len(), 0);
360 assert!(rb.is_empty());
361
362 let mut buf = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
363 assert_eq!(rb.write(&mut buf).unwrap(), 5);
364
365 assert_eq!(rb.capacity(), 5);
366 assert_eq!(rb.len(), 5);
367 assert!(!rb.is_empty());
368
369 let mut buf = [0u8; 3];
370
371 assert_eq!(rb.peek(&mut buf).unwrap(), 3);
372 assert_eq!(buf, [0, 1, 2]);
373
374 assert_eq!(rb.capacity(), 5);
375 assert_eq!(rb.len(), 5);
376 assert!(!rb.is_empty());
377
378 buf = [0u8; 3];
379 assert_eq!(rb.read(&mut buf).unwrap(), 3);
380 assert_eq!(buf, [0, 1, 2]);
381
382 assert_eq!(rb.capacity(), 5);
383 assert_eq!(rb.len(), 2);
384 assert!(!rb.is_empty());
385
386 let mut buf = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
387 assert_eq!(rb.write(&mut buf).unwrap(), 3);
388
389 assert_eq!(rb.capacity(), 5);
390 assert_eq!(rb.len(), 5);
391 assert!(!rb.is_empty());
392
393 buf = [0u8; 10];
394 assert_eq!(rb.peek(&mut buf).unwrap(), 5);
395 assert_eq!(buf, [3, 4, 9, 8, 7, 0, 0, 0, 0, 0]);
396
397 assert_eq!(rb.capacity(), 5);
398 assert_eq!(rb.len(), 5);
399 assert!(!rb.is_empty());
400
401 buf = [0u8; 10];
402 assert_eq!(rb.read(&mut buf).unwrap(), 5);
403 assert_eq!(buf, [3, 4, 9, 8, 7, 0, 0, 0, 0, 0]);
404
405 assert_eq!(rb.capacity(), 5);
406 assert_eq!(rb.len(), 0);
407 assert!(rb.is_empty());
408 }
409
410 #[test]
411 fn ringbuf_clear() {
412 let mut rb: RingBuf = vec![5, 4, 3, 2, 1].into();
413
414 assert_eq!(rb.capacity(), 5);
415 assert_eq!(rb.len(), 5);
416 assert!(!rb.is_empty());
417
418 rb.clear();
419
420 assert_eq!(rb.capacity(), 5);
421 assert_eq!(rb.len(), 0);
422 assert!(rb.is_empty());
423 }
424
425 #[test]
426 fn ringbuf_peek_read_empty() {
427 let mut rb = RingBuf::with_capacity(10);
428
429 let mut buf = [0u8; 10];
430 assert_eq!(rb.peek(&mut buf).unwrap(), 0);
431 assert_eq!(rb.read(&mut buf).unwrap(), 0);
432 }
433
434 #[test]
435 fn ringbuf_peek_read_0_len_buf() {
436 let mut rb: RingBuf = vec![0, 1, 2].into();
437
438 let mut buf = [0u8; 0];
439 assert_eq!(rb.peek(&mut buf).unwrap(), 0);
440 assert_eq!(rb.read(&mut buf).unwrap(), 0);
441 }
442
443 #[test]
444 fn ringbuf_read_write_larger_then_capacity() {
445 let mut rb = RingBuf::with_capacity(5);
446
447 assert_eq!(rb.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).unwrap(), 5);
448
449 let mut buf = [0u8; 10];
450 assert_eq!(rb.read(&mut buf).unwrap(), 5);
451 assert_eq!(buf, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]);
452
453 assert_eq!(rb.write(&[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]).unwrap(), 5);
454 assert_eq!(rb.read(&mut buf).unwrap(), 5);
455 assert_eq!(buf, [6, 7, 8, 9, 10, 0, 0, 0, 0, 0]);
456 assert_eq!(rb.len(), 0);
457 assert!(rb.is_empty());
458 }
459
460 #[test]
461 fn ringbuf_read_write_buf_end() {
462 let mut rb = RingBuf::with_capacity(5);
463
464 assert_eq!(rb.write(&[1]).unwrap(), 1);
465
466 let mut buf = [0u8; 10];
467 assert_eq!(rb.read(&mut buf).unwrap(), 1);
468 assert_eq!(buf, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
469
470 assert_eq!(rb.write(&[0, 1, 2, 3, 4]).unwrap(), 5);
471 assert_eq!(rb.read(&mut buf).unwrap(), 5);
472 assert_eq!(buf, [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
473 assert_eq!(rb.read_pos, 0);
474 assert_eq!(rb.write_pos, 0);
475 assert_eq!(rb.len(), 0);
476 assert!(rb.is_empty());
477 }
478}