refactor(http): allow MemSlice to be sliced to make copies
This commit is contained in:
110
src/http/buf.rs
110
src/http/buf.rs
@@ -1,6 +1,7 @@
|
||||
use std::cell::UnsafeCell;
|
||||
use std::fmt;
|
||||
use std::io::{self, Read};
|
||||
use std::ops::{Deref, Range, RangeFrom, RangeTo, RangeFull};
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -189,9 +190,80 @@ impl MemSlice {
|
||||
end: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slice<S: Slice>(&self, range: S) -> MemSlice {
|
||||
range.slice(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Debug for MemSlice {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(&**self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for MemSlice {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
&(*self.buf.get())[self.start..self.end]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Slice {
|
||||
fn slice(self, subject: &MemSlice) -> MemSlice;
|
||||
}
|
||||
|
||||
|
||||
impl Slice for Range<usize> {
|
||||
fn slice(self, subject: &MemSlice) -> MemSlice {
|
||||
assert!(subject.start + self.start <= subject.end);
|
||||
assert!(subject.start + self.end <= subject.end);
|
||||
MemSlice {
|
||||
buf: subject.buf.clone(),
|
||||
start: subject.start + self.start,
|
||||
end: subject.start + self.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice for RangeFrom<usize> {
|
||||
fn slice(self, subject: &MemSlice) -> MemSlice {
|
||||
assert!(subject.start + self.start <= subject.end);
|
||||
MemSlice {
|
||||
buf: subject.buf.clone(),
|
||||
start: subject.start + self.start,
|
||||
end: subject.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice for RangeTo<usize> {
|
||||
fn slice(self, subject: &MemSlice) -> MemSlice {
|
||||
assert!(subject.start + self.end <= subject.end);
|
||||
MemSlice {
|
||||
buf: subject.buf.clone(),
|
||||
start: subject.start,
|
||||
end: subject.start + self.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice for RangeFull {
|
||||
fn slice(self, subject: &MemSlice) -> MemSlice {
|
||||
MemSlice {
|
||||
buf: subject.buf.clone(),
|
||||
start: subject.start,
|
||||
end: subject.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for MemBuf {}
|
||||
unsafe impl Send for MemSlice {}
|
||||
|
||||
#[cfg(test)]
|
||||
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
|
||||
fn read_mem(&mut self, len: usize) -> io::Result<MemSlice> {
|
||||
@@ -206,30 +278,26 @@ impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for MemSlice {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(&**self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for MemSlice {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
&(*self.buf.get())[self.start..self.end]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for MemBuf {}
|
||||
unsafe impl Send for MemSlice {}
|
||||
|
||||
/*
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{MemBuf};
|
||||
|
||||
#[test]
|
||||
fn test_
|
||||
fn test_mem_slice_slice() {
|
||||
let mut buf = MemBuf::with_capacity(32);
|
||||
buf.read_from(&mut &b"Hello World"[..]).unwrap();
|
||||
|
||||
let len = buf.len();
|
||||
let full = buf.slice(len);
|
||||
|
||||
assert_eq!(&*full, b"Hello World");
|
||||
assert_eq!(&*full.slice(6..), b"World");
|
||||
assert_eq!(&*full.slice(..5), b"Hello");
|
||||
assert_eq!(&*full.slice(..), b"Hello World");
|
||||
for a in 0..len {
|
||||
for b in a..len {
|
||||
assert_eq!(&*full.slice(a..b), &b"Hello World"[a..b], "{}..{}", a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user