Add seek function
This commit is contained in:
parent
d756ac19c2
commit
1a2f51a7bb
71
src/main.rs
71
src/main.rs
@ -5,10 +5,18 @@ use std::{
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use tar::Archive;
|
use tar::Archive;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct OpenFile {
|
||||||
|
mount_id: usize,
|
||||||
|
file_offset: u64,
|
||||||
|
len: usize,
|
||||||
|
pos: u64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Serv {
|
struct Serv {
|
||||||
mounts: Arc<RwLock<Vec<(File, Vec<(PathBuf, u64, usize)>)>>>,
|
mounts: Arc<RwLock<Vec<(File, Vec<(PathBuf, u64, usize)>)>>>,
|
||||||
files: Arc<RwLock<Vec<(usize, u64, usize)>>>,
|
files: Arc<RwLock<Vec<OpenFile>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fs_rpc::Server for Serv {
|
impl fs_rpc::Server for Serv {
|
||||||
@ -40,48 +48,87 @@ impl fs_rpc::Server for Serv {
|
|||||||
.ok_or(())?;
|
.ok_or(())?;
|
||||||
self.files
|
self.files
|
||||||
.write()
|
.write()
|
||||||
.push((mount_id as usize, file_offset, file_size));
|
.push(OpenFile {
|
||||||
|
mount_id: mount_id as usize,
|
||||||
|
file_offset,
|
||||||
|
len: file_size,
|
||||||
|
pos: 0,
|
||||||
|
});
|
||||||
Ok((None, (self.files.read().len() - 1) as u64))
|
Ok((None, (self.files.read().len() - 1) as u64))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option<u64>, u64), ()> {
|
fn open_dir(&self, _path: &std::path::Path, _mount_id: u64) -> Result<(Option<u64>, u64), ()> {
|
||||||
// TODO
|
// TODO
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl file_rpc::Server for Serv {
|
impl file_rpc::Server for Serv {
|
||||||
fn read(&self, fd: u64, pos: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
|
fn read(&self, fd: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
|
||||||
let (mount_id, file_offset, size) = self.files.read()[fd as usize];
|
let files = self.files.read();
|
||||||
let read_len = usize::min(len, size - (pos as usize));
|
let file = &files[fd as usize];
|
||||||
|
let read_len = usize::min(len, file.len - (file.pos as usize));
|
||||||
if read_len == 0 {
|
if read_len == 0 {
|
||||||
return Ok(Vec::new().into());
|
return Ok(Vec::new().into());
|
||||||
};
|
};
|
||||||
let mounts = self.mounts.read();
|
let mounts = self.mounts.read();
|
||||||
let mount = &mounts[mount_id];
|
let mount = &mounts[file.mount_id];
|
||||||
(&mount.0)
|
(&mount.0)
|
||||||
.seek(std::io::SeekFrom::Start(file_offset + pos))
|
.seek(std::io::SeekFrom::Start(file.file_offset + file.pos))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut buf = vec![0; read_len];
|
let mut buf = vec![0; read_len];
|
||||||
let read_bytes = (&mount.0).read(&mut buf).map_err(|_| ())?;
|
let read_bytes = (&mount.0).read(&mut buf).map_err(|_| ())?;
|
||||||
buf.truncate(read_bytes);
|
buf.truncate(read_bytes);
|
||||||
|
std::mem::drop(files);
|
||||||
|
self.files.write()[fd as usize].pos += read_bytes as u64;
|
||||||
Ok(buf.into())
|
Ok(buf.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> {
|
fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&self, _fd: u64) {}
|
fn close(&self, _fd: u64) {}
|
||||||
|
|
||||||
fn size(&self, fd: u64) -> Option<u64> {
|
fn size(&self, fd: u64) -> Option<u64> {
|
||||||
let (_mount_id, _file_offset, size) = self.files.read()[fd as usize];
|
Some(self.files.read()[fd as usize].len as u64)
|
||||||
Some(size as u64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dup(&self, fd: u64) -> Option<u64> {
|
fn dup(&self, fd: u64) -> Option<u64> {
|
||||||
Some(fd)
|
let mut files = self.files.write();
|
||||||
|
let file = files[fd as usize].clone();
|
||||||
|
files.push(file);
|
||||||
|
Some((files.len() - 1) as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> u64{
|
||||||
|
let mut files = self.files.write();
|
||||||
|
let file = &mut files[fd as usize];
|
||||||
|
match pos {
|
||||||
|
file_rpc::SeekFrom::Start(offset) => {
|
||||||
|
file.pos = offset;
|
||||||
|
},
|
||||||
|
file_rpc::SeekFrom::End(offset) => {
|
||||||
|
if offset <= 0 {
|
||||||
|
file.pos = file.len as u64 - (-offset) as u64;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
file_rpc::SeekFrom::Current(offset) => {
|
||||||
|
if offset > 0 {
|
||||||
|
file.pos = u64::min(file.pos + offset as u64, file.len as u64);
|
||||||
|
} else {
|
||||||
|
let offset = (-offset) as u64;
|
||||||
|
if offset > file.pos {
|
||||||
|
file.pos = 0;
|
||||||
|
} else {
|
||||||
|
file.pos -= offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
file.pos
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
Loading…
Reference in New Issue
Block a user