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