1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
use byteorder::{LittleEndian, ReadBytesExt}; use integer_encoding::VarIntReader; use std::{ cmp::min, io::{self, ErrorKind, Read, Seek, SeekFrom}, }; use thiserror::Error; pub const MAGIC: u32 = 0xB1DF; pub const VERSION: u32 = 0x1000; #[derive(Error, Debug)] pub enum DecodeError { #[error("I/O error")] IO(#[from] io::Error), #[error("wrong magic: expected `{:X}`, got `{0:X}`", MAGIC)] WrongMagic(u32), #[error("wrong magic: expected `{:X}`, got `{0:X}`", VERSION)] WrongVersion(u32), } pub struct Reader<R, RS> where R: Read, RS: Read + Seek, { patch: R, old: RS, state: ReaderState, buf: Vec<u8>, } #[derive(Debug)] enum ReaderState { Initial, Add(usize), Copy(usize), Final, } impl<R, RS> Reader<R, RS> where R: Read, RS: Read + Seek, { pub fn new(mut patch: R, old: RS) -> Result<Self, DecodeError> { let magic = patch.read_u32::<LittleEndian>()?; if magic != MAGIC { return Err(DecodeError::WrongMagic(magic)); } let version = patch.read_u32::<LittleEndian>()?; if version != VERSION { return Err(DecodeError::WrongMagic(version)); } Ok(Self { patch, old, state: ReaderState::Initial, buf: vec![0u8; 4096], }) } } impl<R, RS> Read for Reader<R, RS> where R: Read, RS: Read + Seek, { fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> { let mut read: usize = 0; while !buf.is_empty() { let processed = match self.state { ReaderState::Initial => match self.patch.read_varint() { Ok(add_len) => { self.state = ReaderState::Add(add_len); 0 } Err(e) => match e.kind() { ErrorKind::UnexpectedEof => { self.state = ReaderState::Final; 0 } _ => { return Err(e); } }, }, ReaderState::Add(add_len) => { let n = min(min(add_len, buf.len()), self.buf.len()); let out = &mut buf[..n]; self.old.read_exact(out)?; let dif = &mut self.buf[..n]; self.patch.read_exact(dif)?; for i in 0..n { out[i] = out[i].wrapping_add(dif[i]); } if add_len == n { let copy_len: usize = self.patch.read_varint()?; self.state = ReaderState::Copy(copy_len) } else { self.state = ReaderState::Add(add_len - n); } n } ReaderState::Copy(copy_len) => { let n = min(copy_len, buf.len()); let out = &mut buf[..n]; self.patch.read_exact(out)?; if copy_len == n { let seek: i64 = self.patch.read_varint()?; self.old.seek(SeekFrom::Current(seek))?; self.state = ReaderState::Initial; } else { self.state = ReaderState::Copy(copy_len - n); } n } ReaderState::Final => { break; } }; read += processed; buf = &mut buf[processed..]; } Ok(read) } }