implement BufMut for Buffer
This commit is contained in:
parent
8d9566dbb8
commit
0a9c9ab1e2
|
@ -17,3 +17,4 @@ include = [
|
|||
]
|
||||
|
||||
[dependencies]
|
||||
bytes = "1.8.0"
|
||||
|
|
106
src/lib.rs
106
src/lib.rs
|
@ -47,14 +47,17 @@
|
|||
//! assert_eq!(b.data(), &b"cd"[..]);
|
||||
//! }
|
||||
//!
|
||||
use std::{cmp, ptr};
|
||||
use std::io::{self,Write,Read};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::iter::repeat;
|
||||
use std::{cmp, ptr};
|
||||
|
||||
extern crate bytes;
|
||||
use bytes::BufMut;
|
||||
|
||||
/// the Buffer contains the underlying memory and data positions
|
||||
///
|
||||
/// In all cases, `0 ≤ position ≤ end ≤ capacity` should be true
|
||||
#[derive(Debug,PartialEq,Clone)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Buffer {
|
||||
/// the Vec containing the data
|
||||
memory: Vec<u8>,
|
||||
|
@ -64,7 +67,7 @@ pub struct Buffer {
|
|||
position: usize,
|
||||
/// the current end of the available data
|
||||
/// and beginning of the available space
|
||||
end: usize
|
||||
end: usize,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
|
@ -76,7 +79,7 @@ impl Buffer {
|
|||
memory: v,
|
||||
capacity: capacity,
|
||||
position: 0,
|
||||
end: 0
|
||||
end: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +91,7 @@ impl Buffer {
|
|||
memory: Vec::from(data),
|
||||
capacity: data.len(),
|
||||
position: 0,
|
||||
end: data.len()
|
||||
end: data.len(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +207,7 @@ impl Buffer {
|
|||
|
||||
/// returns a mutable slice with all the available space to
|
||||
/// write to
|
||||
pub fn space(&mut self) -> &mut[u8] {
|
||||
pub fn space(&mut self) -> &mut [u8] {
|
||||
&mut self.memory[self.end..self.capacity]
|
||||
}
|
||||
|
||||
|
@ -215,7 +218,11 @@ impl Buffer {
|
|||
if self.position > 0 {
|
||||
unsafe {
|
||||
let length = self.end - self.position;
|
||||
ptr::copy( (&self.memory[self.position..self.end]).as_ptr(), (&mut self.memory[..length]).as_mut_ptr(), length);
|
||||
ptr::copy(
|
||||
(&self.memory[self.position..self.end]).as_ptr(),
|
||||
(&mut self.memory[..length]).as_mut_ptr(),
|
||||
length,
|
||||
);
|
||||
self.position = 0;
|
||||
self.end = length;
|
||||
}
|
||||
|
@ -226,16 +233,16 @@ impl Buffer {
|
|||
#[doc(hidden)]
|
||||
pub fn delete_slice(&mut self, start: usize, length: usize) -> Option<usize> {
|
||||
if start + length >= self.available_data() {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let begin = self.position + start;
|
||||
let next_end = self.end - length;
|
||||
ptr::copy(
|
||||
(&self.memory[begin+length..self.end]).as_ptr(),
|
||||
(&self.memory[begin + length..self.end]).as_ptr(),
|
||||
(&mut self.memory[begin..next_end]).as_mut_ptr(),
|
||||
self.end - (begin+length)
|
||||
self.end - (begin + length),
|
||||
);
|
||||
self.end = next_end;
|
||||
}
|
||||
|
@ -246,9 +253,10 @@ impl Buffer {
|
|||
#[doc(hidden)]
|
||||
pub fn replace_slice(&mut self, data: &[u8], start: usize, length: usize) -> Option<usize> {
|
||||
let data_len = data.len();
|
||||
if start + length > self.available_data() ||
|
||||
self.position + start + data_len > self.capacity {
|
||||
return None
|
||||
if start + length > self.available_data()
|
||||
|| self.position + start + data_len > self.capacity
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -256,15 +264,31 @@ impl Buffer {
|
|||
let slice_end = begin + data_len;
|
||||
// we reduced the data size
|
||||
if data_len < length {
|
||||
ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len);
|
||||
ptr::copy(
|
||||
data.as_ptr(),
|
||||
(&mut self.memory[begin..slice_end]).as_mut_ptr(),
|
||||
data_len,
|
||||
);
|
||||
|
||||
ptr::copy((&self.memory[start+length..self.end]).as_ptr(), (&mut self.memory[slice_end..]).as_mut_ptr(), self.end - (start + length));
|
||||
ptr::copy(
|
||||
(&self.memory[start + length..self.end]).as_ptr(),
|
||||
(&mut self.memory[slice_end..]).as_mut_ptr(),
|
||||
self.end - (start + length),
|
||||
);
|
||||
self.end = self.end - (length - data_len);
|
||||
|
||||
// we put more data in the buffer
|
||||
} else {
|
||||
ptr::copy((&self.memory[start+length..self.end]).as_ptr(), (&mut self.memory[start+data_len..]).as_mut_ptr(), self.end - (start + length));
|
||||
ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len);
|
||||
ptr::copy(
|
||||
(&self.memory[start + length..self.end]).as_ptr(),
|
||||
(&mut self.memory[start + data_len..]).as_mut_ptr(),
|
||||
self.end - (start + length),
|
||||
);
|
||||
ptr::copy(
|
||||
data.as_ptr(),
|
||||
(&mut self.memory[begin..slice_end]).as_mut_ptr(),
|
||||
data_len,
|
||||
);
|
||||
self.end = self.end + data_len - length;
|
||||
}
|
||||
}
|
||||
|
@ -275,16 +299,23 @@ impl Buffer {
|
|||
#[doc(hidden)]
|
||||
pub fn insert_slice(&mut self, data: &[u8], start: usize) -> Option<usize> {
|
||||
let data_len = data.len();
|
||||
if start > self.available_data() ||
|
||||
self.position + self.end + data_len > self.capacity {
|
||||
return None
|
||||
if start > self.available_data() || self.position + self.end + data_len > self.capacity {
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let begin = self.position + start;
|
||||
let slice_end = begin + data_len;
|
||||
ptr::copy((&self.memory[start..self.end]).as_ptr(), (&mut self.memory[start+data_len..]).as_mut_ptr(), self.end - start);
|
||||
ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len);
|
||||
ptr::copy(
|
||||
(&self.memory[start..self.end]).as_ptr(),
|
||||
(&mut self.memory[start + data_len..]).as_mut_ptr(),
|
||||
self.end - start,
|
||||
);
|
||||
ptr::copy(
|
||||
data.as_ptr(),
|
||||
(&mut self.memory[begin..slice_end]).as_mut_ptr(),
|
||||
data_len,
|
||||
);
|
||||
self.end = self.end + data_len;
|
||||
}
|
||||
Some(self.available_data())
|
||||
|
@ -294,8 +325,11 @@ impl Buffer {
|
|||
impl Write for Buffer {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match self.space().write(buf) {
|
||||
Ok(size) => { self.fill(size); Ok(size) },
|
||||
err => err
|
||||
Ok(size) => {
|
||||
self.fill(size);
|
||||
Ok(size)
|
||||
}
|
||||
err => err,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,13 +342,31 @@ impl Read for Buffer {
|
|||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(self.available_data(), buf.len());
|
||||
unsafe {
|
||||
ptr::copy((&self.memory[self.position..self.position+len]).as_ptr(), buf.as_mut_ptr(), len);
|
||||
ptr::copy(
|
||||
(&self.memory[self.position..self.position + len]).as_ptr(),
|
||||
buf.as_mut_ptr(),
|
||||
len,
|
||||
);
|
||||
self.position += len;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl BufMut for Buffer {
|
||||
fn remaining_mut(&self) -> usize {
|
||||
self.available_space()
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
self.fill(cnt);
|
||||
}
|
||||
|
||||
fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
|
||||
self.space().into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -397,7 +449,7 @@ mod tests {
|
|||
use std::str;
|
||||
#[test]
|
||||
fn set_position() {
|
||||
let mut output = [0;5];
|
||||
let mut output = [0; 5];
|
||||
let mut b = Buffer::with_capacity(10);
|
||||
let _ = b.write(&b"abcdefgh"[..]);
|
||||
let _ = b.read(&mut output);
|
||||
|
|
Loading…
Reference in New Issue