1use crate::parse::Hex;
4
5use std::fs::File;
6use std::io;
7use std::path::PathBuf;
8
9use clap::StructOpt;
10
11#[derive(Debug, StructOpt)]
14pub struct InputSource {
15 #[structopt(
16 long = "bin-file",
17 short = 'b',
18 help = "path to input data, as raw binary data",
19 conflicts_with_all(&["hex-file", "code"]),
20 required_unless_present_any(&["hex-file", "code"]),
21 )]
22 bin_file: Option<PathBuf>,
23
24 #[structopt(
25 long = "hex-file",
26 short = 'x',
27 help = "path to input data, encoded in hexadecimal format",
28 conflicts_with = "code"
29 )]
30 hex_file: Option<PathBuf>,
31
32 #[structopt(
33 long = "code",
34 short = 'c',
35 help = "input data, encoded in hexadecimal format (with 0x prefix)"
36 )]
37 code: Option<Hex<Vec<u8>>>,
38}
39
40impl InputSource {
41 pub fn open(self) -> Result<impl io::Read, io::Error> {
43 let boxed: Box<dyn io::Read> = match (self.bin_file, self.hex_file, self.code) {
44 (Some(bin), None, None) => Box::new(Self::bin(bin)?),
45 (None, Some(hex), None) => Box::new(Self::hex(hex)?),
46 (None, None, Some(code)) => Box::new(Self::code(code.0)),
47 _ => unreachable!(),
48 };
49
50 Ok(boxed)
51 }
52
53 fn bin(path: PathBuf) -> Result<File, io::Error> {
54 File::open(path)
55 }
56
57 fn hex(path: PathBuf) -> Result<HexRead<File>, io::Error> {
58 Ok(HexRead::new(File::open(path)?))
59 }
60
61 fn code(code: Vec<u8>) -> io::Cursor<Vec<u8>> {
62 io::Cursor::new(code)
63 }
64}
65
66#[derive(Debug)]
69pub struct HexWrite<W> {
70 file: W,
71}
72
73impl<W> HexWrite<W> {
74 pub fn new(file: W) -> Self {
77 Self { file }
78 }
79}
80
81impl<W> io::Write for HexWrite<W>
82where
83 W: io::Write,
84{
85 fn flush(&mut self) -> Result<(), io::Error> {
86 self.file.flush()
87 }
88
89 fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
90 let encoded = hex::encode(buf);
91 let wrote = self.file.write(encoded.as_bytes())?;
92
93 if wrote % 2 != 0 {
94 Err(io::Error::from(io::ErrorKind::Other))
96 } else {
97 Ok(wrote / 2)
98 }
99 }
100}
101
102#[derive(Debug)]
103struct HexRead<R> {
104 first_read: bool,
105 file: R,
106 remainder: Option<u8>,
107}
108
109impl<R> HexRead<R> {
110 fn new(file: R) -> Self {
111 Self {
112 first_read: true,
113 remainder: None,
114 file,
115 }
116 }
117}
118
119impl<R> io::Read for HexRead<R>
120where
121 R: io::Read,
122{
123 fn read(&mut self, buffer: &mut [u8]) -> Result<usize, io::Error> {
124 if buffer.is_empty() {
129 return Ok(0);
130 }
131
132 let mut available;
133 let mut hexbuffer;
134
135 if let Some(remainder) = self.remainder {
136 available = 1;
137 hexbuffer = vec![0u8; 1 + (2 * buffer.len())];
138 hexbuffer[0] = remainder;
139 } else {
140 available = 0;
141 hexbuffer = vec![0u8; 2 * buffer.len()];
142 }
143
144 let mut hexbuffer: &mut [u8] = &mut hexbuffer;
146
147 let mut eof;
148
149 loop {
150 let read = self.file.read(&mut hexbuffer[available..])?;
151 eof = 0 == read;
152 available += read;
153
154 if self.first_read && available >= 2 {
156 self.first_read = false;
157 if b"0x" == &hexbuffer[..2] {
158 available -= 2;
159
160 if hexbuffer.len() > 2 {
161 hexbuffer = &mut hexbuffer[2..];
162 }
163 }
164 }
165
166 if eof || available > 1 {
167 break;
168 }
169 }
170
171 if eof && 1 == available {
172 if char::from(hexbuffer[0]).is_whitespace() {
173 available = 0;
174 } else {
175 let kind = io::ErrorKind::InvalidData;
176 let src = hex::FromHexError::OddLength;
177 return Err(io::Error::new(kind, src));
178 }
179 } else if available % 2 == 0 {
180 self.remainder = None;
181 } else {
182 self.remainder = Some(hexbuffer[available - 1]);
183 available -= 1;
184 }
185
186 if 0 == available {
187 return Ok(0);
188 }
189
190 let out_sz = available / 2;
191
192 hex::decode_to_slice(&mut hexbuffer[..available], &mut buffer[..out_sz])
193 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
194
195 Ok(out_sz)
196 }
197}
198
199#[cfg(test)]
200mod tests {
201 use hex_literal::hex;
202
203 use std::io::Read;
204
205 use clap::ErrorKind;
206
207 use super::*;
208
209 #[test]
210 fn input_source_at_least_one() {
211 let args: &[&str] = &[];
212 let err = InputSource::try_parse_from(args).unwrap_err();
213 assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
214 }
215
216 #[test]
217 fn input_source_bin_file_conflicts_with_hex_file() {
218 let args = &["exe", "--bin-file", "floop", "--hex-file", "whoop"];
219 let err = InputSource::try_parse_from(args).unwrap_err();
220 assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
221 }
222
223 #[test]
224 fn input_source_bin_file_conflicts_with_code() {
225 let args = &["exe", "--bin-file", "floop", "--code", "0x00"];
226 let err = InputSource::try_parse_from(args).unwrap_err();
227 assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
228 }
229
230 #[test]
231 fn input_source_hex_file_conflicts_with_code() {
232 let args = &["exe", "--hex-file", "floop", "--code", "0x00"];
233 let err = InputSource::try_parse_from(args).unwrap_err();
234 assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
235 }
236
237 #[test]
238 fn hex_read_with_prefix_empty() {
239 let data = b"0x";
240 let mut decoder = HexRead::new(&data[..]);
241
242 let mut buf = [0u8; 10];
243 let sz = decoder.read(&mut buf).unwrap();
244 assert_eq!(sz, 0);
245 }
246
247 #[test]
248 fn hex_read_no_prefix_empty() {
249 let data = b"";
250 let mut decoder = HexRead::new(&data[..]);
251
252 let mut buf = [0u8; 10];
253 let sz = decoder.read(&mut buf).unwrap();
254 assert_eq!(sz, 0);
255 }
256
257 #[test]
258 fn hex_read_with_prefix_odd_length() {
259 let data = b"0xabcdef012345678";
260 let mut decoder = HexRead::new(&data[..]);
261 let err = decoder.read_to_end(&mut vec![]).unwrap_err();
262 assert_eq!(err.kind(), io::ErrorKind::InvalidData);
263 }
264
265 #[test]
266 fn hex_read_no_prefix_odd_length() {
267 let data = b"abcdef012345678";
268 let mut decoder = HexRead::new(&data[..]);
269 let err = decoder.read_to_end(&mut vec![]).unwrap_err();
270 assert_eq!(err.kind(), io::ErrorKind::InvalidData);
271 }
272
273 #[test]
274 fn hex_read_with_prefix_big_buffer() {
275 let data = b"0xabcdef0123456789";
276 let mut decoder = HexRead::new(&data[..]);
277
278 let mut buf = vec![0u8; data.len()];
279 let sz = decoder.read(&mut buf).unwrap();
280 assert_eq!(sz, 8);
281
282 let actual = &buf[..sz];
283 assert_eq!(actual, hex!("abcdef0123456789"));
284
285 let sz = decoder.read(&mut buf).unwrap();
286 assert_eq!(sz, 0);
287 }
288
289 #[test]
290 fn hex_read_no_prefix_big_buffer() {
291 let data = b"abcdef0123456789";
292 let mut decoder = HexRead::new(&data[..]);
293
294 let mut buf = vec![0u8; data.len()];
295 let sz = decoder.read(&mut buf).unwrap();
296 assert_eq!(sz, 8);
297
298 let actual = &buf[..sz];
299 assert_eq!(actual, hex!("abcdef0123456789"));
300
301 let sz = decoder.read(&mut buf).unwrap();
302 assert_eq!(sz, 0);
303 }
304
305 #[test]
306 fn hex_read_with_prefix_tiny_buffer() {
307 let data = b"0xabcdef0123456789";
308 let mut decoder = HexRead::new(&data[..]);
309
310 let mut buf = [0u8];
311
312 let sz = decoder.read(&mut buf).unwrap();
313 assert_eq!(sz, 1);
314 assert_eq!(buf[0], 0xab);
315
316 let sz = decoder.read(&mut buf).unwrap();
317 assert_eq!(sz, 1);
318 assert_eq!(buf[0], 0xcd);
319
320 let sz = decoder.read(&mut buf).unwrap();
321 assert_eq!(sz, 1);
322 assert_eq!(buf[0], 0xef);
323
324 let sz = decoder.read(&mut buf).unwrap();
325 assert_eq!(sz, 1);
326 assert_eq!(buf[0], 0x01);
327
328 let sz = decoder.read(&mut buf).unwrap();
329 assert_eq!(sz, 1);
330 assert_eq!(buf[0], 0x23);
331
332 let sz = decoder.read(&mut buf).unwrap();
333 assert_eq!(sz, 1);
334 assert_eq!(buf[0], 0x45);
335
336 let sz = decoder.read(&mut buf).unwrap();
337 assert_eq!(sz, 1);
338 assert_eq!(buf[0], 0x67);
339
340 let sz = decoder.read(&mut buf).unwrap();
341 assert_eq!(sz, 1);
342 assert_eq!(buf[0], 0x89);
343 }
344
345 #[test]
346 fn hex_read_no_prefix_tiny_buffer() {
347 let data = b"abcdef0123456789";
348 let mut decoder = HexRead::new(&data[..]);
349
350 let mut buf = [0u8];
351
352 let sz = decoder.read(&mut buf).unwrap();
353 assert_eq!(sz, 1);
354 assert_eq!(buf[0], 0xab);
355
356 let sz = decoder.read(&mut buf).unwrap();
357 assert_eq!(sz, 1);
358 assert_eq!(buf[0], 0xcd);
359
360 let sz = decoder.read(&mut buf).unwrap();
361 assert_eq!(sz, 1);
362 assert_eq!(buf[0], 0xef);
363
364 let sz = decoder.read(&mut buf).unwrap();
365 assert_eq!(sz, 1);
366 assert_eq!(buf[0], 0x01);
367
368 let sz = decoder.read(&mut buf).unwrap();
369 assert_eq!(sz, 1);
370 assert_eq!(buf[0], 0x23);
371
372 let sz = decoder.read(&mut buf).unwrap();
373 assert_eq!(sz, 1);
374 assert_eq!(buf[0], 0x45);
375
376 let sz = decoder.read(&mut buf).unwrap();
377 assert_eq!(sz, 1);
378 assert_eq!(buf[0], 0x67);
379
380 let sz = decoder.read(&mut buf).unwrap();
381 assert_eq!(sz, 1);
382 assert_eq!(buf[0], 0x89);
383
384 let sz = decoder.read(&mut buf).unwrap();
385 assert_eq!(sz, 0);
386 }
387}