diff --git a/src/de/mod.rs b/src/de/mod.rs index bbba6c4..b98be7e 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,4 +1,3 @@ -use std::cmp; use std::io::Read; use std::marker::PhantomData; @@ -12,8 +11,6 @@ use self::read::BincodeRead; pub mod read; -const BLOCK_SIZE: usize = 65536; - /// A Deserializer that reads bytes from a buffer. /// /// This struct should rarely be used. @@ -53,22 +50,9 @@ impl<'de, R: BincodeRead<'de>, E: ByteOrder, S: SizeLimit> Deserializer } fn read_vec(&mut self) -> Result> { - let mut len: usize = try!(serde::Deserialize::deserialize(&mut *self)); - - let mut result = Vec::new(); - let mut off = 0; - while len > 0 { - let reserve = cmp::min(len, BLOCK_SIZE); - try!(self.read_bytes(reserve as u64)); - unsafe { - result.reserve(reserve); - result.set_len(off + reserve); - } - try!(self.reader.read_exact(&mut result[off..])); - len -= reserve; - off += reserve; - } - Ok(result) + let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); + self.read_bytes(len as u64)?; + self.reader.get_byte_buffer(len) } fn read_string(&mut self) -> Result { diff --git a/src/de/read.rs b/src/de/read.rs index 68ee1c5..c22ee23 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -10,7 +10,10 @@ pub trait BincodeRead<'storage>: IoRead { where V: serde::de::Visitor<'storage>; #[doc(hidden)] - fn forward_read_bytes>(&mut self, length: usize, visitor: V) -> Result + fn get_byte_buffer(&mut self, length: usize) -> Result>; + + #[doc(hidden)] + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result where V: serde::de::Visitor<'storage>; } @@ -56,11 +59,18 @@ impl IoRead for IoReadReader { } } +impl <'storage> SliceReader<'storage> { + fn unexpected_eof() -> Box<::ErrorKind> { + return Box::new(::ErrorKind::IoError(IoError::new(IoErrorKind::UnexpectedEof, ""))); + } +} + impl <'storage> BincodeRead<'storage> for SliceReader<'storage> { - fn forward_read_str>(&mut self, length: usize, visitor: V) -> Result { + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where V: serde::de::Visitor<'storage> { use ::ErrorKind; if length > self.slice.len() { - return Err(Box::new(ErrorKind::IoError(IoError::new(IoErrorKind::UnexpectedEof, "")))); + return Err(SliceReader::unexpected_eof()); } let string = match ::std::str::from_utf8(&self.slice[..length]) { @@ -74,10 +84,21 @@ impl <'storage> BincodeRead<'storage> for SliceReader<'storage> { self.slice = &self.slice[length..]; r } - fn forward_read_bytes>(&mut self, length: usize, visitor: V) -> Result { - use ::ErrorKind; + + fn get_byte_buffer(&mut self, length: usize) -> Result> { if length > self.slice.len() { - return Err(Box::new(ErrorKind::IoError(IoError::new(IoErrorKind::UnexpectedEof, "")))); + return Err(SliceReader::unexpected_eof()); + } + + let r = &self.slice[..length]; + self.slice = &self.slice[length..]; + Ok(r.to_vec()) + } + + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where V: serde::de::Visitor<'storage> { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); } let r = visitor.visit_borrowed_bytes(&self.slice[..length]); @@ -86,18 +107,27 @@ impl <'storage> BincodeRead<'storage> for SliceReader<'storage> { } } -impl BincodeRead<'static> for IoReadReader where R: IoRead { - fn forward_read_str>(&mut self, length: usize, visitor: V) -> Result { - use ::ErrorKind; +impl IoReadReader where R: IoRead { + fn fill_buffer(&mut self, length: usize) -> Result<()> { let current_length = self.temp_buffer.len(); if length > current_length{ self.temp_buffer.reserve_exact(length - current_length); + unsafe { self.temp_buffer.set_len(length); } } self.reader.read_exact(&mut self.temp_buffer[..length])?; + Ok(()) + } +} + +impl BincodeRead<'static> for IoReadReader where R: IoRead { + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where V: serde::de::Visitor<'static> { + self.fill_buffer(length)?; + let string = match ::std::str::from_utf8(&self.temp_buffer[..length]) { Ok(s) => s, - Err(_) => return Err(Box::new(ErrorKind::InvalidEncoding { + Err(_) => return Err(Box::new(::ErrorKind::InvalidEncoding { desc: "string was not valid utf8", detail: None, })), @@ -106,14 +136,15 @@ impl BincodeRead<'static> for IoReadReader where R: IoRead { let r = visitor.visit_str(string); r } - fn forward_read_bytes>(&mut self, length: usize, visitor: V) -> Result { - let current_length = self.temp_buffer.len(); - if length > current_length{ - self.temp_buffer.reserve_exact(length - current_length); - } - self.reader.read_exact(&mut self.temp_buffer[..length])?; + fn get_byte_buffer(&mut self, length: usize) -> Result> { + self.fill_buffer(length)?; + Ok(self.temp_buffer[..length].to_vec()) + } + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where V: serde::de::Visitor<'static> { + self.fill_buffer(length)?; let r = visitor.visit_bytes(&self.temp_buffer[..length]); r }