diff --git a/src/http/buf.rs b/src/http/buf.rs index 646231ae..6e21bcd3 100644 --- a/src/http/buf.rs +++ b/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(&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 { + 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 { + 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 { + 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 ::http::io::MemRead for ::mock::AsyncIo { fn read_mem(&mut self, len: usize) -> io::Result { @@ -206,30 +278,26 @@ impl ::http::io::MemRead for ::mock::AsyncIo { } } -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); + } + } + } } -*/