hff_std/read/
std_reader.rs

1use crate::ReadSeek;
2use hff_core::{ContentInfo, Error, Result};
3
4/// Implements a std reader wrapper around the source.
5pub struct StdReader {
6    source: std::sync::Mutex<Box<dyn ReadSeek>>,
7}
8
9impl std::fmt::Debug for StdReader {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        write!(f, "ReadSeek")
12    }
13}
14
15impl StdReader {
16    /// Create a new std reader type.
17    pub fn new(source: impl ReadSeek + 'static) -> Self {
18        Self {
19            source: std::sync::Mutex::new(Box::new(source)),
20        }
21    }
22
23    /// Get the content of the given item.
24    pub fn get(&self, content: &dyn ContentInfo) -> Result<Vec<u8>> {
25        let mut source = self
26            .source
27            .lock()
28            .map_err(|e| Error::Invalid(e.to_string()))?;
29        source.seek(std::io::SeekFrom::Start(content.offset()))?;
30
31        let mut result = vec![0; content.len() as usize];
32        source.read_exact(&mut result)?;
33        Ok(result)
34    }
35
36    /// Read the content into the provided slice.
37    pub fn read_exact(&self, content: &dyn ContentInfo, buffer: &mut [u8]) -> Result<()> {
38        let mut source = self
39            .source
40            .lock()
41            .map_err(|e| Error::Invalid(e.to_string()))?;
42        source.seek(std::io::SeekFrom::Start(content.offset()))?;
43
44        source.read_exact(buffer)?;
45        Ok(())
46    }
47
48    /// Get the slice of data representing the content requested.
49    pub fn read(
50        &self,
51        content: &dyn ContentInfo,
52    ) -> Result<std::sync::MutexGuard<'_, Box<dyn ReadSeek>>> {
53        let mut source = self
54            .source
55            .lock()
56            .map_err(|e| Error::Invalid(e.to_string()))?;
57        source.seek(std::io::SeekFrom::Start(content.offset()))?;
58        Ok(source)
59    }
60}