1
use crate::{ Error, Result };
2

            
3
use std::io::Read;
4

            
5
#[derive(Debug)]
6
pub struct File {
7
    path:	std::path::PathBuf,
8
    file:	Option<std::fs::File>,
9
    is_eof:	bool,
10
}
11

            
12
impl File {
13
    pub fn new(path: &std::path::Path) -> Self {
14
	Self {
15
	    path:	path.into(),
16
	    file:	None,
17
	    is_eof:	false,
18
	}
19
    }
20

            
21
    pub fn open(&mut self) -> Result<()> {
22
	if self.file.is_some() {
23
	    return Err(Error::Internal("file already opened"));
24
	}
25

            
26
	self.file = match std::fs::File::open(&self.path) {
27
	    Err(e) if e.kind() == std::io::ErrorKind::NotFound	=> return Err(Error::FileMissing),
28
	    Err(e)	=> return Err(Error::Io(e)),
29
	    Ok(f)	=> Some(f),
30
	};
31

            
32
	Ok(())
33
    }
34

            
35
    pub fn is_mmaped(&self) -> bool {
36
	false
37
    }
38

            
39
    pub fn get_size(&self) -> Option<u64> {
40
	let file = self.file.as_ref().unwrap();
41

            
42
	file.metadata().ok().map(|v| v.len())
43
    }
44

            
45
    pub async fn read(&mut self, buf: &mut [u8]) -> crate::Result<usize>
46
    {
47
	assert!(!self.is_eof());
48

            
49
	let mut file = self.file.as_ref().unwrap();
50
	let mut len = buf.len();
51
	let mut pos = 0;
52

            
53
	while len > 0 {
54
	    let sz = file.read(&mut buf[pos..])?;
55

            
56
	    if sz == 0 {
57
		trace!("eof reached");
58
		self.is_eof = true;
59
		break;
60
	    }
61

            
62
	    len -= sz;
63
	    pos += sz;
64
	}
65

            
66
	Ok(pos)
67
    }
68

            
69
    pub fn read_mmap(&mut self, _cnt: usize) -> crate::Result<&[u8]>
70
    {
71
	Err(Error::Internal("File::read_mmap() not implemented"))
72
    }
73

            
74
    pub fn is_eof(&self) -> bool
75
    {
76
	self.is_eof
77
    }
78
}