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::cell::UnsafeCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
use std::ops::{Deref, Range, RangeFrom, RangeTo, RangeFull};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -189,9 +190,80 @@ impl MemSlice {
|
|||||||
end: 0,
|
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)]
|
#[cfg(test)]
|
||||||
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
|
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
|
||||||
fn read_mem(&mut self, len: usize) -> io::Result<MemSlice> {
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{MemBuf};
|
use super::{MemBuf};
|
||||||
|
|
||||||
#[test]
|
#[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