Skip to main content

zon_lib/
reader.rs

1use crate::header::{ZonHeader, ZON_MAGIC};
2use std::str;
3
4pub struct ZonReader<'a> {
5    buffer: &'a [u8],
6}
7
8impl<'a> ZonReader<'a> {
9    pub fn new(buffer: &'a [u8]) -> Result<Self, &'static str> {
10        if buffer.len() < std::mem::size_of::<ZonHeader>() {
11            return Err("Buffer too small for ZonHeader");
12        }
13
14        // check magic number (offset 0..4)
15        // manual check to avoid casting requirement, though casting header is usually fine for read
16        // but let's stick to safe slice checks as requested by "Verification"
17        let magic_slice = &buffer[0..4];
18        let magic = u32::from_le_bytes(magic_slice.try_into().unwrap());
19        if magic != ZON_MAGIC {
20            return Err("Invalid Magic Number");
21        }
22
23        Ok(Self { buffer })
24    }
25
26    pub fn read_u32(&self, offset: u32) -> Result<u32, &'static str> {
27        let start = offset as usize;
28        let end = start + 4;
29        if end > self.buffer.len() {
30            return Err("Read out of bounds");
31        }
32        let slice = &self.buffer[start..end];
33        Ok(u32::from_le_bytes(slice.try_into().unwrap()))
34    }
35
36    pub fn read_string(&self, offset: u32) -> Result<&'a str, &'static str> {
37        // read length
38        let len_offset = offset;
39        let len = self.read_u32(len_offset)?;
40        
41        let start = (offset + 4) as usize;
42        let end = start + len as usize;
43        
44        if end > self.buffer.len() {
45             return Err("String read out of bounds");
46        }
47        
48        let str_bytes = &self.buffer[start..end];
49        str::from_utf8(str_bytes).map_err(|_| "Invalid UTF-8")
50    }
51}