bytebufrs/
lib.rs

1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 */
6
7#![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
19/// A fixed sized buffer connected end-to-end.
20///
21/// # Examples
22///
23/// ```
24/// use std::io::{Read, Write};
25///
26/// use bytebufrs::RingBuf;
27///
28/// let mut rb = RingBuf::with_capacity(5);
29///
30/// rb.write(&[3, 2, 1]).unwrap();
31/// assert_eq!(rb.len(), 3);
32///
33/// let mut buf = [0u8; 10];
34/// rb.read(&mut buf).unwrap();
35/// assert_eq!(rb.len(), 0);
36/// assert_eq!(buf, [3, 2, 1, 0, 0, 0, 0, 0, 0, 0]);
37///
38/// rb.write(&[4, 5, 6, 7, 8]).unwrap();
39/// assert_eq!(rb.len(), 5);
40/// ```
41pub struct RingBuf {
42    data: Box<[u8]>,
43    read_pos: usize,
44    write_pos: usize
45}
46
47impl RingBuf {
48    /// Constructs a new, empty `RingBuf` with the specified capacity.
49    /// The underlying buffer will be of length `capacity + 1`;
50    ///
51    /// # Examples
52    ///
53    /// ```
54    /// use bytebufrs::RingBuf;
55    ///
56    /// let mut rb = RingBuf::with_capacity(10);
57    ///
58    /// assert_eq!(rb.capacity(), 10);
59    /// assert_eq!(rb.len(), 0);
60    /// assert!(rb.is_empty());
61    /// ```
62    pub fn with_capacity(capacity: usize) -> Self {
63        vec!(0; capacity + 1).into_boxed_slice().into()
64    }
65
66    /// Returns the number of bytes the ring buffer can hold.
67    ///
68    //// # Examples
69    ///
70    /// ```
71    /// use bytebufrs::RingBuf;
72    ///
73    /// let rb = RingBuf::with_capacity(10);
74    /// assert_eq!(rb.capacity(), 10);
75    /// ```
76    pub fn capacity(&self) -> usize {
77        check_valid!(self);
78
79        self.data.len() - 1
80    }
81
82    /// Clears the ring buffer, resetting the read and write position to 0.
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// use bytebufrs::RingBuf;
88    ///
89    /// let mut rb: RingBuf = vec![0, 1, 2, 3, 4].into();
90    ///
91    /// rb.clear();
92    ///
93    /// assert_eq!(rb.len(), 0);
94    /// assert!(rb.is_empty());
95    /// ```
96    pub fn clear(&mut self) {
97        check_valid!(self);
98
99        self.read_pos = 0;
100        self.write_pos = 0;
101    }
102
103    /// Returns the number of bytes in the ring buffer, also referred to
104    /// as its 'length'.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use bytebufrs::RingBuf;
110    ///
111    /// let rb: RingBuf = vec![1, 2, 3].into();
112    /// assert_eq!(rb.len(), 3);
113    /// ```
114    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    /// Returns `true` if the ring buffer doesn't contain any bytes.
126    ///
127    /// # Examples
128    ///
129    /// ```
130    /// use std::io::Write;
131    ///
132    /// use bytebufrs::RingBuf;
133    ///
134    /// let mut rb = RingBuf::with_capacity(10);
135    /// assert!(rb.is_empty());
136    ///
137    /// rb.write(&[0, 1, 2, 3]).unwrap();
138    /// assert!(!rb.is_empty());
139    /// ```
140    pub fn is_empty(&self) -> bool {
141        check_valid!(self);
142
143        self.read_pos == self.write_pos
144    }
145
146    /// Advances the read position by count.
147    /// The read position can't go past the write position.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// use bytebufrs::RingBuf;
153    ///
154    /// let mut rb: RingBuf = vec![0, 1, 2].into();
155    /// assert_eq!(rb.len(), 3);
156    /// rb.advance_read_pos(3).unwrap();
157    /// assert_eq!(rb.len(), 0);
158    /// ```
159    ///
160    /// Trying to set the read position past the write position will fail:
161    ///
162    /// ```should_panic
163    /// use bytebufrs::RingBuf;
164    ///
165    /// let mut rb = RingBuf::with_capacity(10);
166    /// rb.advance_read_pos(1).unwrap(); // Will panic!
167    /// ```
168    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    /// Reads from the ring buffer without advancing the read position.
184    /// On success,returns the number of bytes peeked.
185    ///
186    /// # Examples
187    ///
188    /// ```
189    /// use bytebufrs::RingBuf;
190    ///
191    /// let mut rb: RingBuf = vec![0, 1, 2].into();
192    /// assert_eq!(rb.len(), 3);
193    ///
194    /// let mut buf = [0u8; 10];
195    /// rb.peek(&mut buf).unwrap();
196    /// assert_eq!(buf, [0, 1, 2, 0, 0, 0, 0, 0, 0, 0]);
197    /// assert_eq!(rb.len(), 3);
198    /// ```
199    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    /// Creates a ring buffer with the given slice as backing buffer.
218    /// Note that the ring buffer capacity will be 1 byte less then the length of the slice.
219    ///
220    /// # Examples
221    ///
222    /// ```
223    /// use bytebufrs::RingBuf;
224    ///
225    /// let rb: RingBuf = vec![0u8; 5].into_boxed_slice().into();
226    /// assert_eq!(rb.capacity(), 4);
227    /// ```
228    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    /// Creates a ring buffer from the given vector.
239    /// The capacity and length of the ring buffer will be equal to the length of the vector
240    /// i.e. the ring buffer will be full.
241    ///
242    /// # Examples
243    ///
244    /// ```
245    /// use bytebufrs::RingBuf;
246    ///
247    /// let rb: RingBuf = vec![0, 1, 2, 3, 4].into();
248    /// assert_eq!(rb.capacity(), 5);
249    /// assert_eq!(rb.len(), 5);
250    /// assert!(!rb.is_empty());
251    /// ```
252    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}