ignore zero-filled gaps in blk files

This commit is contained in:
Svyatoslav Nikolsky 2019-04-11 14:14:38 +03:00
parent 2fcfb8adbf
commit 870b892ff2
2 changed files with 31 additions and 7 deletions

View File

@ -12,12 +12,18 @@ pub struct Block {
impl Deserializable for Block {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let block = Block {
magic: try!(reader.read()),
block_size: try!(reader.read()),
block: try!(reader.read()),
};
// We never knew how to parse blocks index file => we were assuming that blocks are stored
// in the *.blk files next to each other, without any gaps.
// It seems that this isn't true && there are (sometimes) zero-filled (always???) gaps between
// adjacent blocks.
// The straightforward soultion is to skip zero bytes. This will work because magic is designed
// not to have zero bytes in it AND block is always prefixed with magic.
reader.skip_while(&|byte| byte == 0)?;
Ok(block)
Ok(Block {
magic: reader.read()?,
block_size: reader.read()?,
block: reader.read()?,
})
}
}

View File

@ -90,6 +90,24 @@ impl<R> Reader<R> where R: io::Read {
T::deserialize(&mut reader)
}
pub fn skip_while(&mut self, predicate: &Fn(u8) -> bool) -> Result<(), Error> {
let mut next_buffer = [0u8];
loop {
let next = match self.peeked.take() {
Some(peeked) => peeked,
None => match self.buffer.read(&mut next_buffer)? {
0 => return Ok(()),
_ => next_buffer[0],
},
};
if !predicate(next) {
self.peeked = Some(next);
return Ok(());
}
}
}
pub fn read_slice(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
io::Read::read_exact(self, bytes).map_err(|_| Error::UnexpectedEnd)
}