1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::fs;
use std::fs::File;
use std::path::Path;

use std::io::{Error, ErrorKind, Read, Seek, SeekFrom};

use buffer::Buffer;
use reader::Reader;

#[derive(Debug)]
pub struct FileReader {
    pub filename: String,
    pub position: u64,
    pub file: Option<File>,
    pub buffer: Buffer,
}

pub fn exists(filename: &str) -> bool {
    Path::new(filename).exists()
}

impl Reader for FileReader {
    fn new() -> FileReader {
        FileReader {
            filename: "".to_string(),
            position: 0,
            file: None,
            buffer: Buffer {
                size: None,
                position: 0,
                max_end_position: None,
                buffer: vec![],
            },
        }
    }

    fn open(&mut self, filename: &str) -> Result<(), String> {
        self.filename = filename.to_string();

        match File::open(filename) {
            Err(msg) => Err(msg.to_string()),
            Ok(file) => {
                self.file = Some(file);
                Ok(())
            }
        }
    }

    fn get_position(&mut self) -> Result<u64, String> {
        Ok(self.position)
    }

    fn get_cache_size(&self) -> Option<usize> {
        self.buffer.size
    }

    fn set_cache_size(&mut self, cache_size: Option<usize>) {
        self.buffer.size = cache_size;
    }

    fn get_max_end_position(&self) -> Option<u64> {
        self.buffer.max_end_position
    }

    fn set_max_end_position(&mut self, max_end_position: Option<u64>) {
        self.buffer.max_end_position = max_end_position;
    }

    fn get_size(&mut self) -> Result<u64, String> {
        let metadata = try!(fs::metadata(self.filename.clone()).map_err(|e| e.to_string()));
        Ok(metadata.len())
    }
}

impl Read for FileReader {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
        if let Some(ref mut file_reader) = self.file {
            let readed_size = file_reader.read(buf)?;
            self.position += readed_size as u64;
            Ok(readed_size)
        } else {
            Err(Error::new(ErrorKind::Other, "No file opened"))
        }
    }
}

impl Seek for FileReader {
    fn seek(&mut self, seek_from: SeekFrom) -> Result<u64, Error> {
        if let Some(ref mut file_reader) = self.file {
            file_reader.seek(seek_from)
        } else {
            Err(Error::new(ErrorKind::Other, "No file opened"))
        }
    }
}