瀏覽代碼

Add RingBuffer::{read_allocated,write_unallocated}.

whitequark 7 年之前
父節點
當前提交
7b29dfee2e
共有 1 個文件被更改,包括 76 次插入0 次删除
  1. 76 0
      src/storage/ring_buffer.rs

+ 76 - 0
src/storage/ring_buffer.rs

@@ -250,6 +250,26 @@ impl<'a, T: 'a> RingBuffer<'a, T> {
         &mut self.storage[start_at..start_at + size]
     }
 
+    /// Write as many elements from the given slice into unallocated buffer elements
+    /// starting at the given offset past the last allocated element, and return
+    /// the amount written.
+    pub fn write_unallocated(&mut self, offset: usize, data: &[T]) -> usize
+            where T: Copy {
+        let (size_1, offset, data) = {
+            let slice = self.get_unallocated(offset, data.len());
+            let slice_len = slice.len();
+            slice.copy_from_slice(&data[..slice_len]);
+            (slice_len, offset + slice_len, &data[slice_len..])
+        };
+        let size_2 = {
+            let slice = self.get_unallocated(offset, data.len());
+            let slice_len = slice.len();
+            slice.copy_from_slice(&data[..slice_len]);
+            slice_len
+        };
+        size_1 + size_2
+    }
+
     /// Return the largest contiguous slice of allocated buffer elements starting
     /// at the given offset past the first allocated element, and up to the given size.
     pub fn get_allocated(&self, offset: usize, mut size: usize) -> &[T] {
@@ -265,6 +285,24 @@ impl<'a, T: 'a> RingBuffer<'a, T> {
 
         &self.storage[start_at..start_at + size]
     }
+
+    /// Read as many elements from allocated buffer elements into the given slice
+    /// starting at the given offset past the first allocated element, and return
+    /// the amount read.
+    pub fn read_allocated(&mut self, offset: usize, data: &mut [T]) -> usize
+            where T: Copy {
+        let (size_1, offset, data) = {
+            let slice = self.get_allocated(offset, data.len());
+            data[..slice.len()].copy_from_slice(slice);
+            (slice.len(), offset + slice.len(), &mut data[slice.len()..])
+        };
+        let size_2 = {
+            let slice = self.get_allocated(offset, data.len());
+            data[..slice.len()].copy_from_slice(slice);
+            slice.len()
+        };
+        size_1 + size_2
+    }
 }
 
 impl<'a, T: 'a> From<ManagedSlice<'a, T>> for RingBuffer<'a, T> {
@@ -560,6 +598,22 @@ mod test {
         assert_eq!(&ring.storage[..], b"ABCDEFGHIJKL");
     }
 
+    #[test]
+    fn test_buffer_write_unallocated() {
+        let mut ring = RingBuffer::new(vec![b'.'; 12]);
+        ring.enqueue_many(6).copy_from_slice(b"abcdef");
+        ring.dequeue_many(6).copy_from_slice(b"ABCDEF");
+
+        assert_eq!(ring.write_unallocated(0, b"ghi"), 3);
+        assert_eq!(&ring.storage[..], b"ABCDEFghi...");
+
+        assert_eq!(ring.write_unallocated(3, b"jklmno"), 6);
+        assert_eq!(&ring.storage[..], b"mnoDEFghijkl");
+
+        assert_eq!(ring.write_unallocated(9, b"pqrstu"), 3);
+        assert_eq!(&ring.storage[..], b"mnopqrghijkl");
+    }
+
     #[test]
     fn test_buffer_get_allocated() {
         let mut ring = RingBuffer::new(vec![b'.'; 12]);;
@@ -577,4 +631,26 @@ mod test {
         ring.enqueue_slice(b"abcd");
         assert_eq!(ring.get_allocated(4, 8), b"ijkl");
     }
+
+    #[test]
+    fn test_buffer_read_allocated() {
+        let mut ring = RingBuffer::new(vec![b'.'; 12]);
+        ring.enqueue_many(12).copy_from_slice(b"abcdefghijkl");
+
+        let mut data = [0; 6];
+        assert_eq!(ring.read_allocated(0, &mut data[..]), 6);
+        assert_eq!(&data[..], b"abcdef");
+
+        ring.dequeue_many(6).copy_from_slice(b"ABCDEF");
+        ring.enqueue_many(3).copy_from_slice(b"mno");
+
+        let mut data = [0; 6];
+        assert_eq!(ring.read_allocated(3, &mut data[..]), 6);
+        assert_eq!(&data[..], b"jklmno");
+
+        let mut data = [0; 6];
+        assert_eq!(ring.read_allocated(6, &mut data[..]), 3);
+        assert_eq!(&data[..], b"mno\x00\x00\x00");
+
+    }
 }