Skip to main content

vsd_mp4/
reader.rs

1use std::io::{Cursor, Error, ErrorKind, Read, Result};
2
3enum Endianness {
4    Big,
5    Little,
6}
7
8/// A reader for parsing binary data of MP4 containers with support for big-endian and little-endian formats.
9pub struct Reader {
10    endian: Endianness,
11    inner: Cursor<Vec<u8>>,
12}
13
14impl Reader {
15    /// Creates a new big-endian `Reader` for the given data.
16    pub fn new_big_endian(data: &[u8]) -> Self {
17        Self {
18            endian: Endianness::Big,
19            inner: Cursor::new(data.to_vec()),
20        }
21    }
22
23    /// Creates a new little-endian `Reader` for the given data.
24    pub fn new_little_endian(data: &[u8]) -> Self {
25        Self {
26            endian: Endianness::Little,
27            inner: Cursor::new(data.to_vec()),
28        }
29    }
30
31    /// Returns a slice referencing the underlying data.
32    pub fn as_bytes(&self) -> &[u8] {
33        self.inner.get_ref()
34    }
35
36    /// Returns `true` if there is more data to be read.
37    pub fn has_more_data(&self) -> bool {
38        self.inner.position() < (self.inner.get_ref().len() as u64)
39    }
40
41    /// Returns the total length of the data in bytes.
42    pub fn get_length(&self) -> u64 {
43        self.inner.get_ref().len() as u64
44    }
45
46    /// Returns the current read position.
47    pub fn get_position(&self) -> u64 {
48        self.inner.position()
49    }
50
51    /// Skips the specified number of bytes.
52    ///
53    /// # Errors
54    ///
55    /// Returns an error if the new position exceeds the total data length.
56    pub fn skip(&mut self, bytes: u64) -> Result<()> {
57        let position = self.get_position() + bytes;
58
59        if position > self.get_length() {
60            return Err(Error::new(
61                ErrorKind::OutOfMemory,
62                "skips out of memory bounds.",
63            ));
64        }
65
66        self.inner.set_position(position);
67        Ok(())
68    }
69
70    /// Reads a 8-bit unsigned integer.
71    ///
72    /// # Errors
73    ///
74    /// Returns an error if there is not enough data left to read.
75    pub fn read_u8(&mut self) -> Result<u8> {
76        let mut buf = [0; 1];
77        self.inner.read_exact(&mut buf)?;
78        Ok(buf[0])
79    }
80
81    /// Reads a 16-bit unsigned integer according to the configured endianness.
82    ///
83    /// # Errors
84    ///
85    /// Returns an error if there is not enough data left to read.
86    pub fn read_u16(&mut self) -> Result<u16> {
87        let mut buf = [0; 2];
88        self.inner.read_exact(&mut buf)?;
89
90        match self.endian {
91            Endianness::Big => Ok(u16::from_be_bytes(buf)),
92            Endianness::Little => Ok(u16::from_le_bytes(buf)),
93        }
94    }
95
96    /// Reads a 32-bit unsigned integer according to the configured endianness.
97    ///
98    /// # Errors
99    ///
100    /// Returns an error if there is not enough data left to read.
101    pub fn read_u32(&mut self) -> Result<u32> {
102        let mut buf = [0; 4];
103        self.inner.read_exact(&mut buf)?;
104
105        match self.endian {
106            Endianness::Big => Ok(u32::from_be_bytes(buf)),
107            Endianness::Little => Ok(u32::from_le_bytes(buf)),
108        }
109    }
110
111    /// Reads a 64-bit unsigned integer according to the configured endianness.
112    ///
113    /// # Errors
114    ///
115    /// Returns an error if there is not enough data left to read.
116    pub fn read_u64(&mut self) -> Result<u64> {
117        let mut buf = [0; 8];
118        self.inner.read_exact(&mut buf)?;
119
120        match self.endian {
121            Endianness::Big => Ok(u64::from_be_bytes(buf)),
122            Endianness::Little => Ok(u64::from_le_bytes(buf)),
123        }
124    }
125
126    /// Reads the specified number of bytes into a vector.
127    ///
128    /// # Errors
129    ///
130    /// Returns an error if there is not enough data left to read.
131    pub fn read_bytes_u8(&mut self, bytes: usize) -> Result<Vec<u8>> {
132        let mut buf = vec![0; bytes];
133        self.inner.read_exact(&mut buf)?;
134        Ok(buf)
135    }
136
137    /// Reads 16-bit unsigned integers from the configured number of bytes.
138    ///
139    /// # Errors
140    ///
141    /// Returns an error if there is not enough data left to read.
142    pub fn read_bytes_u16(&mut self, bytes: usize) -> Result<Vec<u16>> {
143        Ok(self
144            .read_bytes_u8(bytes)?
145            .chunks_exact(2)
146            .map(|x| match self.endian {
147                Endianness::Big => u16::from_be_bytes([x[0], x[1]]),
148                Endianness::Little => u16::from_le_bytes([x[0], x[1]]),
149            })
150            .collect())
151    }
152
153    /// Reads a 32-bit signed integer according to the configured endianness.
154    ///
155    /// # Errors
156    ///
157    /// Returns an error if there is not enough data left to read.
158    pub fn read_i32(&mut self) -> Result<i32> {
159        let mut buf = [0; 4];
160        self.inner.read_exact(&mut buf)?;
161
162        match self.endian {
163            Endianness::Big => Ok(i32::from_be_bytes(buf)),
164            Endianness::Little => Ok(i32::from_le_bytes(buf)),
165        }
166    }
167}