implement iterator for parsing length + data ledger
This commit is contained in:
parent
c3279c8a00
commit
fc476ff979
|
@ -58,52 +58,50 @@ impl<'a, W: Write> EntryWriter<'a, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an escaped byte slice containing an Entry.
|
struct EntryReader<R: BufRead> {
|
||||||
fn read_entry(escaped: &[u8]) -> io::Result<Entry> {
|
reader: R,
|
||||||
let mut raw = Vec::with_capacity(escaped.len());
|
entry_bytes: Vec<u8>,
|
||||||
|
len_len: u64,
|
||||||
|
}
|
||||||
|
|
||||||
trace!("read_entry escaped = {:?}", escaped);
|
impl Iterator for EntryReader<BufRead> {
|
||||||
|
type Item = io::Result<Entry>;
|
||||||
|
|
||||||
let mut back = false;
|
fn next(&mut self) -> Option<io::Result<Entry>> {
|
||||||
for pc in escaped {
|
let mut entry_len: usize = 0;
|
||||||
let mut c = *pc;
|
|
||||||
if back {
|
let mut entry_len_bytes = [0u8; 8];
|
||||||
trace!("de-escaping '{}' to '{}'", c, c - b'\\');
|
|
||||||
back = false;
|
if let Err(e) = self.reader.read_exact(&mut entry_len_bytes[..self.len_len]) {
|
||||||
c -= b'\\';
|
None // EOF, probably
|
||||||
} else if c == b'\\' {
|
} else {
|
||||||
back = true;
|
entry_len = bincode::deserialize(&entry_len_bytes).unwrap();
|
||||||
continue;
|
|
||||||
|
if entry_len > self.entry_bytes.len() {
|
||||||
|
self.entry_bytes.resize(entry_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = self.reader.read_exact(&mut self.entry_bytes[..entry_len]) {
|
||||||
|
Some(Error::new(ErrorKind::Other, e.to_string()))
|
||||||
|
} else {
|
||||||
|
Some(
|
||||||
|
bincode::deserialize(&self.entry_bytes)
|
||||||
|
.map_err(|e| Error::new(ErrorKind::Other, e.to_string())),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
raw.push(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("read_entry raw = {:?}", raw);
|
|
||||||
|
|
||||||
bincode::deserialize(&raw[..]).map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return an iterator for all the entries in the given file.
|
/// Return an iterator for all the entries in the given file.
|
||||||
pub fn read_entries<R: BufRead>(reader: R) -> impl Iterator<Item = io::Result<Entry>> {
|
pub fn read_entries<R: BufRead>(reader: R) -> impl Iterator<Item = io::Result<Entry>> {
|
||||||
let mut entry_bytes = Vec::with_capacity(BLOB_SIZE);
|
let entry_len: usize = 0;
|
||||||
let mut entry_len: usize = 0;
|
|
||||||
let mut len_bytes = Vec::with_capacity(bincode::serialized_size(&entry_len).unwrap() as usize);
|
|
||||||
|
|
||||||
pub enum mode {
|
EntryReader {
|
||||||
Length,
|
reader,
|
||||||
Entry,
|
entry_bytes: Vec::new(),
|
||||||
|
len_len: bincode::serialized_size(&entry_len).unwrap(),
|
||||||
}
|
}
|
||||||
let mut mode = reader.bytes().map(|b| {
|
|
||||||
match mode {
|
|
||||||
Length -> {
|
|
||||||
}
|
|
||||||
Entry -> {
|
|
||||||
|
|
||||||
}
|
|
||||||
len = bincode::deserialize(&len_bytes).unwrap();
|
|
||||||
|
|
||||||
read_entry(&s?)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in New Issue