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 tar::Archive;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct OpenFile {
|
||||
mount_id: usize,
|
||||
file_offset: u64,
|
||||
len: usize,
|
||||
pos: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Serv {
|
||||
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 {
|
||||
@ -40,48 +48,87 @@ impl fs_rpc::Server for Serv {
|
||||
.ok_or(())?;
|
||||
self.files
|
||||
.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))
|
||||
}
|
||||
|
||||
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
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl file_rpc::Server for Serv {
|
||||
fn read(&self, fd: u64, pos: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
|
||||
let (mount_id, file_offset, size) = self.files.read()[fd as usize];
|
||||
let read_len = usize::min(len, size - (pos as usize));
|
||||
fn read(&self, fd: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
|
||||
let files = self.files.read();
|
||||
let file = &files[fd as usize];
|
||||
let read_len = usize::min(len, file.len - (file.pos as usize));
|
||||
if read_len == 0 {
|
||||
return Ok(Vec::new().into());
|
||||
};
|
||||
let mounts = self.mounts.read();
|
||||
let mount = &mounts[mount_id];
|
||||
let mount = &mounts[file.mount_id];
|
||||
(&mount.0)
|
||||
.seek(std::io::SeekFrom::Start(file_offset + pos))
|
||||
.seek(std::io::SeekFrom::Start(file.file_offset + file.pos))
|
||||
.unwrap();
|
||||
let mut buf = vec![0; read_len];
|
||||
let read_bytes = (&mount.0).read(&mut buf).map_err(|_| ())?;
|
||||
buf.truncate(read_bytes);
|
||||
std::mem::drop(files);
|
||||
self.files.write()[fd as usize].pos += read_bytes as u64;
|
||||
Ok(buf.into())
|
||||
}
|
||||
|
||||
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> {
|
||||
fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
fn close(&self, _fd: u64) {}
|
||||
|
||||
fn size(&self, fd: u64) -> Option<u64> {
|
||||
let (_mount_id, _file_offset, size) = self.files.read()[fd as usize];
|
||||
Some(size as u64)
|
||||
Some(self.files.read()[fd as usize].len as 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() {
|
||||
|
Loading…
Reference in New Issue
Block a user