Skip to main content

revelo_core/
reader.rs

1//! Ergonomic byte reader — wraps [`FileAnalyze`] with a fluent, Rust-native API.
2//!
3//! Every read method returns the value directly (no out-parameters) and
4//! advances the cursor. Peek methods do not advance. All methods return
5//! `Option<T>` — `None` means buffer truncated.
6//!
7//! ```ignore
8//! let r = Reader::wrap(&mut fa);
9//! let width  = r.be_u32("Width")?;
10//! let depth  = r.be_u8("BitDepth")?;
11//! let magic  = r.fourcc("Magic")?;
12//!
13//! r.bits(|b| {
14//!     let bsid  = b.read::<u8>(5, "bsid")?;
15//!     Ok(())
16//! })?;
17//! ```
18
19use crate::file_analyze::FileAnalyze;
20
21type R<T> = Option<T>;
22
23fn ok<T>(fa: &FileAnalyze<'_>, v: T) -> R<T> {
24    if fa.truncated() { None } else { Some(v) }
25}
26
27/// Fluent byte reader over a [`FileAnalyze`] buffer.
28pub struct Reader<'a, 'b> {
29    fa: &'a mut FileAnalyze<'b>,
30}
31
32impl<'a, 'b> Reader<'a, 'b> {
33    pub fn wrap(fa: &'a mut FileAnalyze<'b>) -> Self {
34        Self { fa }
35    }
36
37    // ── raw ────────────────────────────────────────────────────
38
39    pub fn peek_raw(&self, n: usize) -> Option<&[u8]> {
40        self.fa.peek_raw(n)
41    }
42
43    pub fn peek_magic<const N: usize>(&self, magic: &[u8; N]) -> bool {
44        self.fa.peek_magic(magic)
45    }
46
47    pub fn read_raw(&mut self, n: usize) -> Option<&[u8]> {
48        let out = self.fa.read_raw(n);
49        if out.is_empty() && n > 0 { None } else { Some(out) }
50    }
51
52    pub fn skip(&mut self, n: usize) -> R<()> {
53        if self.fa.remain() < n {
54            None
55        } else {
56            self.fa.skip_hexa(n, "");
57            Some(())
58        }
59    }
60
61    pub fn remain(&self) -> usize {
62        self.fa.remain()
63    }
64
65    // ── element tree ───────────────────────────────────────────
66
67    pub fn element_begin(&mut self, name: &str) {
68        self.fa.element_begin(name);
69    }
70    pub fn element_end(&mut self) {
71        self.fa.element_end();
72    }
73    pub fn element_offset(&self) -> usize {
74        self.fa.element_offset()
75    }
76
77    // ── stream filling ─────────────────────────────────────────
78
79    pub fn stream_prepare(&mut self, kind: crate::stream::StreamKind) -> usize {
80        self.fa.stream_prepare(kind)
81    }
82    pub fn set_field(
83        &mut self,
84        kind: crate::stream::StreamKind,
85        pos: usize,
86        parameter: &str,
87        value: impl Into<revelo_util::Ztring>,
88    ) {
89        self.fa.set_field(kind, pos, parameter, value);
90    }
91    pub fn force_field(
92        &mut self,
93        kind: crate::stream::StreamKind,
94        pos: usize,
95        parameter: &str,
96        value: impl Into<revelo_util::Ztring>,
97    ) {
98        self.fa.force_field(kind, pos, parameter, value);
99    }
100
101    // ── big-endian integers ────────────────────────────────────
102
103    pub fn be_u8(&mut self, name: &str) -> R<u8> {
104        let v = self.fa.get_b1(name);
105        ok(self.fa, v)
106    }
107    pub fn be_u16(&mut self, name: &str) -> R<u16> {
108        let v = self.fa.get_b2(name);
109        ok(self.fa, v)
110    }
111    pub fn be_u24(&mut self, name: &str) -> R<u32> {
112        let v = self.fa.get_b3(name);
113        ok(self.fa, v)
114    }
115    pub fn be_u32(&mut self, name: &str) -> R<u32> {
116        let v = self.fa.get_b4(name);
117        ok(self.fa, v)
118    }
119    pub fn be_u40(&mut self, name: &str) -> R<u64> {
120        let v = self.fa.get_b5(name);
121        ok(self.fa, v)
122    }
123    pub fn be_u48(&mut self, name: &str) -> R<u64> {
124        let v = self.fa.get_b6(name);
125        ok(self.fa, v)
126    }
127    pub fn be_u56(&mut self, name: &str) -> R<u64> {
128        let v = self.fa.get_b7(name);
129        ok(self.fa, v)
130    }
131    pub fn be_u64(&mut self, name: &str) -> R<u64> {
132        let v = self.fa.get_b8(name);
133        ok(self.fa, v)
134    }
135    pub fn be_u128(&mut self, name: &str) -> R<u128> {
136        let v = self.fa.get_b16(name);
137        ok(self.fa, v)
138    }
139
140    // ── little-endian integers ─────────────────────────────────
141
142    pub fn le_u8(&mut self, name: &str) -> R<u8> {
143        let v = self.fa.get_l1(name);
144        ok(self.fa, v)
145    }
146    pub fn le_u16(&mut self, name: &str) -> R<u16> {
147        let v = self.fa.get_l2(name);
148        ok(self.fa, v)
149    }
150    pub fn le_u24(&mut self, name: &str) -> R<u32> {
151        let v = self.fa.get_l3(name);
152        ok(self.fa, v)
153    }
154    pub fn le_u32(&mut self, name: &str) -> R<u32> {
155        let v = self.fa.get_l4(name);
156        ok(self.fa, v)
157    }
158    pub fn le_u64(&mut self, name: &str) -> R<u64> {
159        let v = self.fa.get_l8(name);
160        ok(self.fa, v)
161    }
162
163    // ── peeks (non-advancing) ──────────────────────────────────
164
165    pub fn peek_be_u16(&self) -> R<u16> {
166        let v = self.fa.peek_b2();
167        ok(self.fa, v)
168    }
169    pub fn peek_be_u32(&self) -> R<u32> {
170        let v = self.fa.peek_b4();
171        ok(self.fa, v)
172    }
173    pub fn peek_be_u64(&self) -> R<u64> {
174        let v = self.fa.peek_b8();
175        ok(self.fa, v)
176    }
177    pub fn peek_le_u16(&self) -> R<u16> {
178        let v = self.fa.peek_l2();
179        ok(self.fa, v)
180    }
181    pub fn peek_le_u32(&self) -> R<u32> {
182        let v = self.fa.peek_l4();
183        ok(self.fa, v)
184    }
185
186    // ── floats ─────────────────────────────────────────────────
187
188    pub fn be_f32(&mut self, name: &str) -> R<f32> {
189        let v = self.fa.get_bf4(name);
190        ok(self.fa, v)
191    }
192    pub fn be_f64(&mut self, name: &str) -> R<f64> {
193        let v = self.fa.get_bf8(name);
194        ok(self.fa, v)
195    }
196    pub fn le_f32(&mut self, name: &str) -> R<f32> {
197        let v = self.fa.get_lf4(name);
198        ok(self.fa, v)
199    }
200    pub fn le_f64(&mut self, name: &str) -> R<f64> {
201        let v = self.fa.get_lf8(name);
202        ok(self.fa, v)
203    }
204    pub fn be_f80(&mut self, name: &str) -> R<f64> {
205        let v = self.fa.get_bf10(name);
206        ok(self.fa, v)
207    }
208
209    // ── 4CC ────────────────────────────────────────────────────
210
211    pub fn fourcc(&mut self, name: &str) -> R<u32> {
212        let v = self.fa.get_c4(name);
213        ok(self.fa, v)
214    }
215
216    // ── bitstream ──────────────────────────────────────────────
217
218    pub fn bits<F, T>(&mut self, f: F) -> R<T>
219    where
220        F: FnOnce(&mut BitReader<'_, 'b>) -> R<T>,
221    {
222        self.fa.bs_begin();
223        let mut br = BitReader { fa: &mut *self.fa };
224        let result = f(&mut br);
225        if !br.fa.truncated() {
226            br.fa.bs_end();
227        }
228        result
229    }
230}
231
232// ── bit reader ─────────────────────────────────────────────────
233
234pub struct BitReader<'a, 'b> {
235    fa: &'a mut FileAnalyze<'b>,
236}
237
238impl BitReader<'_, '_> {
239    pub fn read<T: FromBits>(&mut self, n: usize, name: &str) -> R<T> {
240        T::read_bits_be(self.fa, n, name)
241    }
242    pub fn skip(&mut self, n: usize) {
243        self.fa.skip_s1(n, "");
244    }
245}
246
247pub trait FromBits: Sized {
248    fn read_bits_be(fa: &mut FileAnalyze<'_>, n: usize, name: &str) -> R<Self>;
249}
250
251impl FromBits for u8 {
252    fn read_bits_be(fa: &mut FileAnalyze<'_>, n: usize, name: &str) -> R<Self> {
253        let v = fa.get_s1(n, name);
254        ok(fa, v)
255    }
256}
257impl FromBits for u16 {
258    fn read_bits_be(fa: &mut FileAnalyze<'_>, n: usize, name: &str) -> R<Self> {
259        let v = fa.get_s2(n, name);
260        ok(fa, v)
261    }
262}
263impl FromBits for u32 {
264    fn read_bits_be(fa: &mut FileAnalyze<'_>, n: usize, name: &str) -> R<Self> {
265        let v = fa.get_s3(n, name);
266        ok(fa, v)
267    }
268}
269impl FromBits for u64 {
270    fn read_bits_be(fa: &mut FileAnalyze<'_>, n: usize, name: &str) -> R<Self> {
271        let v = fa.get_s5(n, name);
272        ok(fa, v)
273    }
274}