diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/net/file_loader.rs | 41 | ||||
-rw-r--r-- | src/components/util/io.rs | 22 |
2 files changed, 41 insertions, 22 deletions
diff --git a/src/components/net/file_loader.rs b/src/components/net/file_loader.rs index 379cd3e5ffb..7225fe8606f 100644 --- a/src/components/net/file_loader.rs +++ b/src/components/net/file_loader.rs @@ -2,34 +2,47 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use resource_task::{Metadata, Payload, Done, LoaderTask, start_sending}; -use servo_util::io::ignoring_eof; +use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending}; +use servo_util::io::result; -use std::rt::io; -use std::rt::io::Reader; +use std::comm::Chan; +use std::rt::io::file; +use std::rt::io::{FileStream, Reader, EndOfFile, Open, Read, ignore_io_error}; use std::task; static READ_SIZE: uint = 1024; +fn read_all(reader: &mut FileStream, progress_chan: &Chan<ProgressMsg>) + -> Result<(), ()> { + loop { + match (do result { + let data = reader.read_bytes(READ_SIZE); + progress_chan.send(Payload(data)); + }) { + Ok(()) => (), + Err(e) => match e.kind { + EndOfFile => return Ok(()), + _ => return Err(()), + } + } + } +} + pub fn factory() -> LoaderTask { let f: LoaderTask = |url, start_chan| { assert!("file" == url.scheme); let progress_chan = start_sending(start_chan, Metadata::default(url.clone())); do task::spawn { - match io::file::open(&url.path.as_slice(), io::Open, io::Read) { - Some(mut reader) => { - while !reader.eof() { - do ignoring_eof { - let data = reader.read_bytes(READ_SIZE); - progress_chan.send(Payload(data)); - } - } - progress_chan.send(Done(Ok(()))); + // ignore_io_error causes us to get None instead of a task failure. + match ignore_io_error(|| file::open(&url.path.as_slice(), Open, Read)) { + Some(ref mut reader) => { + let res = read_all(reader, &progress_chan); + progress_chan.send(Done(res)); } None => { progress_chan.send(Done(Err(()))); } - }; + } } }; f diff --git a/src/components/util/io.rs b/src/components/util/io.rs index 9fa4dda4a4f..45009723774 100644 --- a/src/components/util/io.rs +++ b/src/components/util/io.rs @@ -2,13 +2,19 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::rt::io::{io_error, EndOfFile}; +use std::rt::io::{io_error, IoError}; -/// Ignore the end-of-file condition within a block of code. -pub fn ignoring_eof<U>(cb: &fn() -> U) -> U { - io_error::cond.trap(|e| - match e.kind { - EndOfFile => (), - _ => io_error::cond.raise(e) - }).inside(cb) +/// Helper for catching an I/O error and wrapping it in a Result object. The +/// return result will be the last I/O error that happened or the result of the +/// closure if no error occurred. +/// +/// FIXME: This is a copy of std::rt::io::result which doesn't exist yet in our +/// version of Rust. We should switch after the next Rust upgrade. +pub fn result<T>(cb: &fn() -> T) -> Result<T, IoError> { + let mut err = None; + let ret = io_error::cond.trap(|e| err = Some(e)).inside(cb); + match err { + Some(e) => Err(e), + None => Ok(ret), + } } |