Skip to main content

gaia_binary/
reader.rs

1use crate::{traits::BinaryFormat, TrackingReader};
2use gaia_types::GaiaError;
3use std::io::Read;
4
5/// Generic binary reader with position tracking.
6pub struct BinaryReader<R: Read, F: BinaryFormat> {
7    inner: TrackingReader<R>,
8    diagnostics: Vec<GaiaError>,
9    _marker: std::marker::PhantomData<F>,
10}
11
12impl<R: Read, F: BinaryFormat> BinaryReader<R, F> {
13    /// Create a new binary reader.
14    pub fn new(inner: R) -> Self {
15        Self { inner: TrackingReader { inner, position: 0 }, diagnostics: Vec::new(), _marker: std::marker::PhantomData }
16    }
17
18    /// Get current position.
19    pub fn position(&self) -> u64 {
20        self.inner.position
21    }
22
23    /// Get current position (alias for position).
24    pub fn get_position(&self) -> u64 {
25        self.inner.position
26    }
27
28    /// Set current position (alias for seek).
29    pub fn set_position(&mut self, pos: u64) -> std::io::Result<u64>
30    where
31        R: std::io::Seek,
32    {
33        use std::io::Seek;
34        self.seek(std::io::SeekFrom::Start(pos))
35    }
36
37    /// Get stream position.
38    pub fn stream_position(&mut self) -> std::io::Result<u64>
39    where
40        R: std::io::Seek,
41    {
42        use std::io::Seek;
43        self.inner.stream_position()
44    }
45
46    /// Add a diagnostic error.
47    pub fn add_error(&mut self, error: GaiaError) {
48        self.diagnostics.push(error);
49    }
50
51    /// Take all collected diagnostic errors.
52    pub fn take_errors(&mut self) -> Vec<GaiaError> {
53        std::mem::take(&mut self.diagnostics)
54    }
55
56    /// Read a u8 value.
57    pub fn read_u8(&mut self) -> std::io::Result<u8> {
58        let mut buf = [0u8; 1];
59        self.inner.read_exact(&mut buf)?;
60        Ok(buf[0])
61    }
62
63    /// Read a u16 value.
64    pub fn read_u16(&mut self) -> std::io::Result<u16> {
65        F::read_u16(&mut self.inner)
66    }
67
68    /// Read a u32 value.
69    pub fn read_u32(&mut self) -> std::io::Result<u32> {
70        F::read_u32(&mut self.inner)
71    }
72
73    /// Read a u64 value.
74    pub fn read_u64(&mut self) -> std::io::Result<u64> {
75        F::read_u64(&mut self.inner)
76    }
77
78    /// Read an i16 value.
79    pub fn read_i16(&mut self) -> std::io::Result<i16> {
80        F::read_i16(&mut self.inner)
81    }
82
83    /// Read an i32 value.
84    pub fn read_i32(&mut self) -> std::io::Result<i32> {
85        F::read_i32(&mut self.inner)
86    }
87
88    /// Read an i64 value.
89    pub fn read_i64(&mut self) -> std::io::Result<i64> {
90        F::read_i64(&mut self.inner)
91    }
92
93    /// Read an f32 value.
94    pub fn read_f32(&mut self) -> std::io::Result<f32> {
95        F::read_f32(&mut self.inner)
96    }
97
98    /// Read an f64 value.
99    pub fn read_f64(&mut self) -> std::io::Result<f64> {
100        F::read_f64(&mut self.inner)
101    }
102
103    /// Read raw bytes.
104    pub fn read_bytes(&mut self, len: usize) -> std::io::Result<Vec<u8>> {
105        let mut buf = vec![0u8; len];
106        self.inner.read_exact(&mut buf)?;
107        Ok(buf)
108    }
109
110    /// Read into a buffer.
111    pub fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
112        self.inner.read_exact(buf)
113    }
114
115    /// Read to end of source.
116    pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
117        self.inner.read_to_end(buf)
118    }
119}
120
121impl<R: Read + std::io::Seek, F: BinaryFormat> std::io::Seek for BinaryReader<R, F> {
122    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
123        self.inner.seek(pos)
124    }
125}
126
127impl<R: Read + std::fmt::Debug, F: BinaryFormat> std::fmt::Debug for BinaryReader<R, F> {
128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129        f.debug_struct("BinaryReader").field("inner", &self.inner).field("position", &self.position()).finish()
130    }
131}