feat(doit): optimizations and simplification; seek

* MultiPartReader is using match to handle state, reducing unnecessary
  calls to 0 in that regard.
* Fixed seek() calls on readers, assuring they are reset to start each
  time the loop is done.
* both media-parameters now use `ReadSeek` streams.
* Use `seek()` to figure out size, simplifying the interface.

Closes #17
This commit is contained in:
Sebastian Thiel
2015-03-19 07:30:43 +01:00
parent 6b2301351f
commit 9d401f5486
4 changed files with 47 additions and 41 deletions

View File

@@ -183,22 +183,28 @@ impl<'a> MultiPartReader<'a> {
impl<'a> Read for MultiPartReader<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if self.last_part_boundary.is_some() {
let br = self.last_part_boundary.as_mut().unwrap().read(buf).unwrap_or(0);
if br < buf.len() {
self.last_part_boundary = None;
match (self.raw_parts.len(),
self.current_part.is_none(),
self.last_part_boundary.is_none()) {
(_, _, false) => {
let br = self.last_part_boundary.as_mut().unwrap().read(buf).unwrap_or(0);
if br < buf.len() {
self.last_part_boundary = None;
}
return Ok(br)
},
(0, true, true) => return Ok(0),
(n, true, _) if n > 0 => {
let (headers, reader) = self.raw_parts.remove(0);
let mut c = Cursor::new(Vec::<u8>::new());
write!(&mut c, "{}--{}{}{}{}", LINE_ENDING, BOUNDARY, LINE_ENDING,
headers, LINE_ENDING).unwrap();
c.seek(SeekFrom::Start(0)).unwrap();
self.current_part = Some((c, reader));
}
return Ok(br)
} else if self.is_depleted() {
return Ok(0)
} else if self.raw_parts.len() > 0 && self.current_part.is_none() {
let (headers, reader) = self.raw_parts.remove(0);
let mut c = Cursor::new(Vec::<u8>::new());
write!(&mut c, "{}--{}{}{}{}", LINE_ENDING, BOUNDARY, LINE_ENDING,
headers, LINE_ENDING).unwrap();
c.seek(SeekFrom::Start(0)).unwrap();
self.current_part = Some((c, reader));
_ => {},
}
// read headers as long as possible
let (hb, rr) = {
let &mut (ref mut c, ref mut reader) = self.current_part.as_mut().unwrap();

View File

@@ -17,6 +17,7 @@ mod tests {
use self::hyper_mock::*;
use std::io::Read;
use std::default::Default;
use std::old_path::BytesContainer;
const EXPECTED: &'static str =
"\r\n--MDuXWGyeE33QFXGchb2VFWc4Z7945d\r\n\