sfkv/src/iter.rs

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 None;
}
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..])))
}
}
}
}