implement BufMut for Buffer

This commit is contained in:
cel 🌸 2024-11-10 14:41:28 +00:00
parent 8d9566dbb8
commit 0a9c9ab1e2
2 changed files with 364 additions and 311 deletions

View File

@ -17,3 +17,4 @@ include = [
] ]
[dependencies] [dependencies]
bytes = "1.8.0"

View File

@ -47,9 +47,12 @@
//! assert_eq!(b.data(), &b"cd"[..]); //! assert_eq!(b.data(), &b"cd"[..]);
//! } //! }
//! //!
use std::{cmp, ptr}; use std::io::{self, Read, Write};
use std::io::{self,Write,Read};
use std::iter::repeat; use std::iter::repeat;
use std::{cmp, ptr};
extern crate bytes;
use bytes::BufMut;
/// the Buffer contains the underlying memory and data positions /// the Buffer contains the underlying memory and data positions
/// ///
@ -64,7 +67,7 @@ pub struct Buffer {
position: usize, position: usize,
/// the current end of the available data /// the current end of the available data
/// and beginning of the available space /// and beginning of the available space
end: usize end: usize,
} }
impl Buffer { impl Buffer {
@ -76,7 +79,7 @@ impl Buffer {
memory: v, memory: v,
capacity: capacity, capacity: capacity,
position: 0, position: 0,
end: 0 end: 0,
} }
} }
@ -88,7 +91,7 @@ impl Buffer {
memory: Vec::from(data), memory: Vec::from(data),
capacity: data.len(), capacity: data.len(),
position: 0, position: 0,
end: data.len() end: data.len(),
} }
} }
@ -215,7 +218,11 @@ impl Buffer {
if self.position > 0 { if self.position > 0 {
unsafe { unsafe {
let length = self.end - self.position; 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.position = 0;
self.end = length; self.end = length;
} }
@ -226,7 +233,7 @@ impl Buffer {
#[doc(hidden)] #[doc(hidden)]
pub fn delete_slice(&mut self, start: usize, length: usize) -> Option<usize> { pub fn delete_slice(&mut self, start: usize, length: usize) -> Option<usize> {
if start + length >= self.available_data() { if start + length >= self.available_data() {
return None return None;
} }
unsafe { unsafe {
@ -235,7 +242,7 @@ impl Buffer {
ptr::copy( 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(), (&mut self.memory[begin..next_end]).as_mut_ptr(),
self.end - (begin+length) self.end - (begin + length),
); );
self.end = next_end; self.end = next_end;
} }
@ -246,9 +253,10 @@ impl Buffer {
#[doc(hidden)] #[doc(hidden)]
pub fn replace_slice(&mut self, data: &[u8], start: usize, length: usize) -> Option<usize> { pub fn replace_slice(&mut self, data: &[u8], start: usize, length: usize) -> Option<usize> {
let data_len = data.len(); let data_len = data.len();
if start + length > self.available_data() || if start + length > self.available_data()
self.position + start + data_len > self.capacity { || self.position + start + data_len > self.capacity
return None {
return None;
} }
unsafe { unsafe {
@ -256,15 +264,31 @@ impl Buffer {
let slice_end = begin + data_len; let slice_end = begin + data_len;
// we reduced the data size // we reduced the data size
if data_len < length { 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); self.end = self.end - (length - data_len);
// we put more data in the buffer // we put more data in the buffer
} else { } 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(
ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len); (&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; self.end = self.end + data_len - length;
} }
} }
@ -275,16 +299,23 @@ impl Buffer {
#[doc(hidden)] #[doc(hidden)]
pub fn insert_slice(&mut self, data: &[u8], start: usize) -> Option<usize> { pub fn insert_slice(&mut self, data: &[u8], start: usize) -> Option<usize> {
let data_len = data.len(); let data_len = data.len();
if start > self.available_data() || if start > self.available_data() || self.position + self.end + data_len > self.capacity {
self.position + self.end + data_len > self.capacity { return None;
return None
} }
unsafe { unsafe {
let begin = self.position + start; let begin = self.position + start;
let slice_end = begin + data_len; 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(
ptr::copy(data.as_ptr(), (&mut self.memory[begin..slice_end]).as_mut_ptr(), data_len); (&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; self.end = self.end + data_len;
} }
Some(self.available_data()) Some(self.available_data())
@ -294,8 +325,11 @@ impl Buffer {
impl Write for Buffer { impl Write for Buffer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self.space().write(buf) { match self.space().write(buf) {
Ok(size) => { self.fill(size); Ok(size) }, Ok(size) => {
err => err 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> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let len = cmp::min(self.available_data(), buf.len()); let len = cmp::min(self.available_data(), buf.len());
unsafe { 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; self.position += len;
} }
Ok(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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;