diff --git a/import/src/block.rs b/import/src/block.rs index fb893881..fd14fada 100644 --- a/import/src/block.rs +++ b/import/src/block.rs @@ -12,12 +12,18 @@ pub struct Block { impl Deserializable for Block { fn deserialize(reader: &mut Reader) -> Result 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()?, + }) } -} +} \ No newline at end of file diff --git a/serialization/src/reader.rs b/serialization/src/reader.rs index 55d62753..1c3d3089 100644 --- a/serialization/src/reader.rs +++ b/serialization/src/reader.rs @@ -90,6 +90,24 @@ impl Reader 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) }