Skip to main content

speck_core/util/
io.rs

1//! I/O utilities for no-std environments
2
3use alloc::vec::Vec;
4use crate::error::Result;
5
6/// Streaming reader for memory-efficient parsing
7pub struct StreamingReader<'a> {
8    data: &'a [u8],
9    position: usize,
10}
11
12impl<'a> StreamingReader<'a> {
13    /// Create new reader
14    pub fn new(data: &'a [u8]) -> Self {
15        Self { data, position: 0 }
16    }
17    
18    /// Read exact number of bytes
19    pub fn read_exact(&mut self, len: usize) -> Result<&'a [u8]> {
20        if self.position + len > self.data.len() {
21            return Err(crate::Error::invalid_format("unexpected EOF"));
22        }
23        let result = &self.data[self.position..self.position + len];
24        self.position += len;
25        Ok(result)
26    }
27    
28    /// Read u32 in little-endian
29    pub fn read_u32_le(&mut self) -> Result<u32> {
30        let bytes = self.read_exact(4)?;
31        Ok(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
32    }
33    
34    /// Read u64 in little-endian
35    pub fn read_u64_le(&mut self) -> Result<u64> {
36        let bytes = self.read_exact(8)?;
37        Ok(u64::from_le_bytes([
38            bytes[0], bytes[1], bytes[2], bytes[3],
39            bytes[4], bytes[5], bytes[6], bytes[7],
40        ]))
41    }
42    
43    /// Remaining bytes
44    pub fn remaining(&self) -> usize {
45        self.data.len() - self.position
46    }
47    
48    /// Check if exhausted
49    pub fn is_empty(&self) -> bool {
50        self.position >= self.data.len()
51    }
52}