47 lines
1.3 KiB
Rust
47 lines
1.3 KiB
Rust
|
use byteorder::{ByteOrder, BigEndian};
|
||
|
use crate::ReadError;
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
pub struct Iter<'a> {
|
||
|
data: &'a [u8],
|
||
|
pub offset: usize
|
||
|
}
|
||
|
|
||
|
impl<'a> Iter<'a> {
|
||
|
pub fn new(data: &'a [u8]) -> Iter<'a> {
|
||
|
Iter { data: data, offset: 0 }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<'a> Iterator for Iter<'a> {
|
||
|
type Item = Result<(&'a [u8], &'a [u8]), ReadError>;
|
||
|
|
||
|
fn next(&mut self) -> Option<Self::Item> {
|
||
|
let data = &self.data[self.offset..];
|
||
|
|
||
|
if data.len() < 4 {
|
||
|
return Some(Err(ReadError::Truncated { offset: self.offset }))
|
||
|
}
|
||
|
|
||
|
let record_size = BigEndian::read_u32(data) as usize;
|
||
|
if record_size == !0u32 as usize /* all ones; erased flash */ {
|
||
|
return None
|
||
|
} else if record_size < 4 || record_size > data.len() {
|
||
|
return Some(Err(ReadError::InvalidSize { offset: self.offset, size: record_size }))
|
||
|
}
|
||
|
|
||
|
let record_body = &data[4..record_size];
|
||
|
match record_body.iter().position(|&x| x == 0) {
|
||
|
None => {
|
||
|
return Some(Err(ReadError::MissingSeparator { offset: self.offset }))
|
||
|
}
|
||
|
Some(pos) => {
|
||
|
self.offset += record_size;
|
||
|
|
||
|
let (key, zero_and_value) = record_body.split_at(pos);
|
||
|
Some(Ok((key, &zero_and_value[1..])))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|