ignore zero-filled gaps in blk files
This commit is contained in:
parent
2fcfb8adbf
commit
870b892ff2
|
@ -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()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue