larian_formats/
reader.rs

1use crate::{
2    error::{Error, Result},
3    format::Parser,
4};
5use std::{
6    io::{Read, Seek, SeekFrom},
7    ops::{Deref, DerefMut},
8};
9
10/// Wrapper around a readable type an the offset of where to start reading from.
11#[derive(Debug)]
12pub struct ReadSeek<R> {
13    reader: R,
14    starting_position: u64,
15}
16
17impl<R> ReadSeek<R>
18where
19    R: Read + Seek,
20{
21    pub(crate) fn read_all_bytes(&mut self) -> Result<Vec<u8>> {
22        let current_position = self.stream_position()?;
23        self.seek_starting_position()?;
24
25        let mut bytes = Vec::new();
26        self.read_to_end(&mut bytes)?;
27
28        self.seek(SeekFrom::Start(current_position))?;
29        Ok(bytes)
30    }
31
32    pub(crate) fn seek_starting_position(&mut self) -> Result<()> {
33        self.reader.seek(SeekFrom::Start(self.starting_position))?;
34        Ok(())
35    }
36
37    pub(crate) fn read_usize_from_u32_le_bytes(&mut self) -> Result<usize> {
38        let u = self.read_u32_from_le_bytes()?;
39        Ok(usize_from_u32!(u))
40    }
41
42    pub(crate) fn read_u32_from_le_bytes(&mut self) -> Result<u32> {
43        let mut bytes = [0_u8; 4];
44        self.reader.read_exact(&mut bytes)?;
45
46        Ok(u32::from_le_bytes(bytes))
47    }
48
49    pub(crate) fn read_i32_from_le_bytes(&mut self) -> Result<i32> {
50        let mut bytes = [0_u8; 4];
51        self.reader.read_exact(&mut bytes)?;
52
53        Ok(i32::from_le_bytes(bytes))
54    }
55
56    pub(crate) fn read_u64_from_le_bytes(&mut self) -> Result<u64> {
57        let mut bytes = [0_u8; 8];
58        self.reader.read_exact(&mut bytes)?;
59        Ok(u64::from_le_bytes(bytes))
60    }
61
62    pub(crate) fn read_u16_from_le_bytes(&mut self) -> Result<u16> {
63        let mut bytes = [0_u8; 2];
64        self.reader.read_exact(&mut bytes)?;
65        Ok(u16::from_le_bytes(bytes))
66    }
67}
68
69impl<R> Deref for ReadSeek<R> {
70    type Target = R;
71
72    fn deref(&self) -> &Self::Target {
73        &self.reader
74    }
75}
76
77impl<R> DerefMut for ReadSeek<R> {
78    fn deref_mut(&mut self) -> &mut Self::Target {
79        &mut self.reader
80    }
81}
82
83/// Wrapper around a readable type and a parser to read it.
84pub struct Reader<P, R> {
85    inner: ReadSeek<R>,
86    file: P,
87}
88
89impl<P, R> Reader<P, R>
90where
91    P: Parser,
92    R: Read + Seek,
93{
94    /// Creates a new reader to parse from the given source.
95    pub fn new(mut reader: R) -> Result<Self> {
96        let starting_position = reader.stream_position()?;
97
98        let mut reader = Self {
99            inner: ReadSeek {
100                reader,
101                starting_position,
102            },
103            file: P::default(),
104        };
105
106        let mut id_bytes = [0_u8; 4];
107        reader.inner.read_exact(&mut id_bytes)?;
108
109        if id_bytes != P::ID_BYTES {
110            return Err(Error::InvalidIdentifier {
111                expected_bytes: P::ID_BYTES,
112                bytes_found: id_bytes,
113            });
114        }
115
116        let version = reader.inner.read_u32_from_le_bytes()?;
117
118        if version < P::MIN_SUPPORTED_VERSION {
119            return Err(Error::UnsupportedVersion {
120                version_number_found: version,
121            });
122        }
123
124        Ok(reader)
125    }
126
127    /// Attempts the parse the source into the given format.
128    pub fn read(&mut self) -> Result<P::Output> {
129        self.inner.seek_starting_position()?;
130        self.inner.reader.seek(SeekFrom::Current(8))?;
131        self.file.read(&mut self.inner)
132    }
133}