fix zip bug. impl std::Error for FsError.

master
WangRunji 7 years ago
parent ffa42fcc55
commit 9a89ed174c

@ -1,55 +1,57 @@
use std::fs; use std::fs;
use std::io::{Read, Result, Write}; use std::io::{Read, Write};
use std::mem::uninitialized; use std::mem::uninitialized;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use std::error::Error;
use rcore_fs::vfs::*; use rcore_fs::vfs::{INode, FileType, FsError};
const DEFAULT_MODE: u32 = 0o664; const DEFAULT_MODE: u32 = 0o664;
const BUF_SIZE: usize = 0x1000;
pub fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<()> { pub fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<(), Box<Error>> {
let dir = fs::read_dir(path).expect("Failed to open dir"); let dir = fs::read_dir(path)?;
for entry in dir { for entry in dir {
let entry = entry?; let entry = entry?;
let name_ = entry.file_name(); let name_ = entry.file_name();
let name = name_.to_str().unwrap(); let name = name_.to_str().unwrap();
let type_ = entry.file_type()?; let type_ = entry.file_type()?;
if type_.is_file() { if type_.is_file() {
let inode = inode.create(name, FileType::File, DEFAULT_MODE).expect("Failed to create INode"); let inode = inode.create(name, FileType::File, DEFAULT_MODE)?;
let mut file = fs::File::open(entry.path())?; let mut file = fs::File::open(entry.path())?;
inode.resize(file.metadata().unwrap().len() as usize).expect("Failed to resize INode"); inode.resize(file.metadata()?.len() as usize)?;
let mut buf: [u8; 4096] = unsafe { uninitialized() }; let mut buf: [u8; BUF_SIZE] = unsafe { uninitialized() };
let mut offset = 0usize; let mut offset = 0usize;
let mut len = 4096; let mut len = BUF_SIZE;
while len == 4096 { while len == BUF_SIZE {
len = file.read(&mut buf)?; len = file.read(&mut buf)?;
inode.write_at(offset, &buf).expect("Failed to write image"); inode.write_at(offset, &buf[..len])?;
offset += len; offset += len;
} }
} else if type_.is_dir() { } else if type_.is_dir() {
let inode = inode.create(name, FileType::Dir, DEFAULT_MODE).expect("Failed to create INode"); let inode = inode.create(name, FileType::Dir, DEFAULT_MODE)?;
zip_dir(entry.path().as_path(), inode)?; zip_dir(entry.path().as_path(), inode)?;
} }
} }
Ok(()) Ok(())
} }
pub fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<()> { pub fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<(), Box<Error>> {
let files = inode.list().expect("Failed to list files from INode"); let files = inode.list()?;
for name in files.iter().skip(2) { for name in files.iter().skip(2) {
let inode = inode.lookup(name.as_str()).expect("Failed to lookup"); let inode = inode.lookup(name.as_str())?;
let mut path = path.to_path_buf(); let mut path = path.to_path_buf();
path.push(name); path.push(name);
let info = inode.metadata().expect("Failed to get file info"); let info = inode.metadata()?;
match info.type_ { match info.type_ {
FileType::File => { FileType::File => {
let mut file = fs::File::create(&path)?; let mut file = fs::File::create(&path)?;
let mut buf: [u8; 4096] = unsafe { uninitialized() }; let mut buf: [u8; BUF_SIZE] = unsafe { uninitialized() };
let mut offset = 0usize; let mut offset = 0usize;
let mut len = 4096; let mut len = BUF_SIZE;
while len == 4096 { while len == BUF_SIZE {
len = inode.read_at(offset, buf.as_mut()).expect("Failed to read from INode"); len = inode.read_at(offset, buf.as_mut())?;
file.write(&buf[..len])?; file.write(&buf[..len])?;
offset += len; offset += len;
} }

@ -1,6 +1,7 @@
use alloc::{vec::Vec, string::String, sync::Arc}; use alloc::{vec::Vec, string::String, sync::Arc};
use core::any::Any; use core::any::Any;
use core::result; use core::result;
use core::fmt;
/// Abstract operations on a inode. /// Abstract operations on a inode.
pub trait INode: Any + Sync + Send { pub trait INode: Any + Sync + Send {
@ -170,7 +171,16 @@ pub enum FsError {
DeviceError, DeviceError,
} }
pub type Result<T> = result::Result<T,FsError>; impl fmt::Display for FsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[cfg(any(test, feature = "std"))]
impl std::error::Error for FsError {}
pub type Result<T> = result::Result<T, FsError>;
/// Abstract filesystem /// Abstract filesystem
pub trait FileSystem: Sync { pub trait FileSystem: Sync {

Loading…
Cancel
Save