make file like implement the std::io traits instead and wrap zbox file

This commit is contained in:
Mackenzie Clark 2019-03-28 12:50:37 -07:00
parent 09642c92db
commit d9c693a31c
4 changed files with 89 additions and 46 deletions

View File

@ -1,7 +1,6 @@
use crate::vfs::file_like::{FileLike, Metadata}; use crate::vfs::file_like::{FileLike, Metadata};
use failure::Error; use failure::Error;
use std::io; use std::io;
use std::io::{Seek, Write};
pub struct Stdin; pub struct Stdin;
pub struct Stdout; pub struct Stdout;
@ -12,19 +11,27 @@ impl FileLike for Stdin {
unimplemented!() unimplemented!()
} }
fn write_file(&mut self, _buf: &[u8], _offset: usize) -> Result<usize, io::Error> {
unimplemented!()
}
fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result<usize, io::Error> {
unimplemented!()
}
fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> { fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
panic!("Cannot set length of stdin"); panic!("Cannot set length of stdin");
} }
} }
impl io::Read for Stdin {
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, io::Error> {
unimplemented!()
}
}
impl io::Write for Stdin {
fn write(&mut self, _buf: &[u8]) -> Result<usize, io::Error> {
unimplemented!()
}
fn flush(&mut self) -> Result<(), io::Error> {
unimplemented!()
}
}
impl io::Seek for Stdin { impl io::Seek for Stdin {
fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, io::Error> { fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, io::Error> {
unimplemented!() unimplemented!()
@ -36,18 +43,28 @@ impl FileLike for Stdout {
unimplemented!() unimplemented!()
} }
fn write_file(&mut self, buf: &[u8], _offset: usize) -> Result<usize, io::Error> { fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
panic!("Cannot set length of stdout");
}
}
impl io::Read for Stdout {
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, io::Error> {
unimplemented!()
}
}
impl io::Write for Stdout {
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
let stdout = io::stdout(); let stdout = io::stdout();
let mut handle = stdout.lock(); let mut handle = stdout.lock();
handle.write(buf) handle.write(buf)
} }
fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result<usize, io::Error> { fn flush(&mut self) -> Result<(), io::Error> {
unimplemented!() let stdout = io::stdout();
} let mut handle = stdout.lock();
handle.flush()
fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
panic!("Cannot set length of stdout");
} }
} }
@ -62,18 +79,28 @@ impl FileLike for Stderr {
unimplemented!() unimplemented!()
} }
fn write_file(&mut self, buf: &[u8], _offset: usize) -> Result<usize, io::Error> { fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
panic!("Cannot set length of stderr");
}
}
impl io::Read for Stderr {
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, io::Error> {
unimplemented!()
}
}
impl io::Write for Stderr {
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
let stderr = io::stderr(); let stderr = io::stderr();
let mut handle = stderr.lock(); let mut handle = stderr.lock();
handle.write(buf) handle.write(buf)
} }
fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result<usize, io::Error> { fn flush(&mut self) -> Result<(), io::Error> {
unimplemented!() let stderr = io::stderr();
} let mut handle = stderr.lock();
handle.flush()
fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
panic!("Cannot set length of stderr");
} }
} }

View File

@ -1,5 +1,3 @@
use std::io;
pub type Fd = isize; pub type Fd = isize;
#[derive(Debug)] #[derive(Debug)]
@ -8,16 +6,17 @@ pub struct Metadata {
pub is_file: bool, pub is_file: bool,
} }
pub trait FileLike: std::io::Seek { pub trait FileLike: std::io::Write + std::io::Read + std::io::Seek {
// get metadata // get metadata
fn metadata(&self) -> Result<Metadata, failure::Error>; fn metadata(&self) -> Result<Metadata, failure::Error>;
// write // write
fn write_file(&mut self, buf: &[u8], offset: usize) -> Result<usize, io::Error>; // fn write_file(&mut self, buf: &[u8]) -> Result<usize, io::Error>;
// read // read
fn read_file(&mut self, buf: &mut [u8], offset: usize) -> Result<usize, io::Error>; // fn read_file(&mut self, buf: &mut [u8]) -> Result<usize, io::Error>;
// set_file_len // set_file_len
fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error>; fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error>;
} }

View File

@ -8,6 +8,7 @@ use std::path::{Path, PathBuf};
use std::rc::Rc; use std::rc::Rc;
use tar::EntryType; use tar::EntryType;
use zbox::{init_env, OpenOptions, Repo, RepoOpener}; use zbox::{init_env, OpenOptions, Repo, RepoOpener};
use crate::vfs::virtual_file::VirtualFile;
pub struct Vfs { pub struct Vfs {
repo: Repo, repo: Repo,
@ -103,7 +104,7 @@ impl Vfs {
init_env(); init_env();
let path = convert_to_absolute_path(path); let path = convert_to_absolute_path(path);
if let Ok(file) = OpenOptions::new().write(true).open(&mut self.repo, &path) { if let Ok(file) = OpenOptions::new().write(true).open(&mut self.repo, &path) {
Some(Rc::new(RefCell::new(file))) Some(Rc::new(RefCell::new(VirtualFile::new(file))))
} else if let Some(dev_file) = self.device_files.get(&path) { } else if let Some(dev_file) = self.device_files.get(&path) {
Some(dev_file.clone()) Some(dev_file.clone())
} else { } else {

View File

@ -1,12 +1,16 @@
use failure::Error; use failure::Error;
use crate::vfs::file_like::{FileLike, Metadata}; use crate::vfs::file_like::{FileLike, Metadata};
use std::io; use std::io;
use std::io::{Read, Seek, SeekFrom, Write};
impl FileLike for zbox::File { pub struct VirtualFile(zbox::File);
impl VirtualFile {
pub fn new(file: zbox::File) -> Self { VirtualFile(file) }
}
impl FileLike for VirtualFile {
fn metadata(&self) -> Result<Metadata, Error> { fn metadata(&self) -> Result<Metadata, Error> {
self.metadata() self.0.metadata()
.map(|m| Metadata { .map(|m| Metadata {
len: m.content_len(), len: m.content_len(),
is_file: m.is_file(), is_file: m.is_file(),
@ -14,19 +18,31 @@ impl FileLike for zbox::File {
.map_err(|e: zbox::Error| e.into()) .map_err(|e: zbox::Error| e.into())
} }
fn write_file(&mut self, buf: &[u8], offset: usize) -> Result<usize, io::Error> {
self.seek(SeekFrom::Start(offset as _))?;
let result = self.write(buf);
self.finish().unwrap();
result
}
fn read_file(&mut self, buf: &mut [u8], offset: usize) -> Result<usize, io::Error> {
self.seek(io::SeekFrom::Start(offset as u64))?;
self.read(buf)
}
fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error> { fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error> {
self.set_len(len).map_err(|e| e.into()) self.0.set_len(len).map_err(|e| e.into())
}
}
impl io::Write for VirtualFile {
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
let result = self.0.write(buf)?;
self.0.finish().unwrap();
Ok(result)
}
fn flush(&mut self) -> Result<(), io::Error> {
self.0.flush()
}
}
impl io::Read for VirtualFile {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
self.0.read(buf)
}
}
impl io::Seek for VirtualFile {
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, io::Error> {
self.0.seek(pos)
} }
} }