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
//! IO utilities.
use std::io::{self, Read, Write};
/// Default buffer length for io (4kb).
pub const DEFAULT_BUF_LEN: usize = 4000;
/// Transfer data from a reader to a writer.
pub fn stream(from: &mut impl Read, to: &mut impl Write) -> io::Result<()> {
let mut buffer = [0u8; DEFAULT_BUF_LEN];
loop {
let read_len = from.read(&mut buffer)?;
to.write(&buffer[..read_len])?;
if read_len != DEFAULT_BUF_LEN {
break;
}
}
Ok(())
}
/// Adapter to chain two readers together.
///
/// It might seem the exact same as [`std::io::Chain`] but it
/// is not. The difference is that when it reaches the end of
/// the first reader, it fills the rest of the buffer with
/// the first bytes from the second reader, what [`std::io::Chain`]
/// doesn't do.
pub struct Chain<R1: Read, R2: Read> {
first: Option<R1>,
second: R2,
}
impl<R1: Read, R2: Read> Chain<R1, R2> {
/// Create a Chain from the two given readers.
pub fn new(first: R1, second: R2) -> Self {
Chain {
first: Some(first),
second,
}
}
}
impl<R1: Read, R2: Read> Read for Chain<R1, R2> {
/// Pull some bytes from this source into the specified
/// buffer, returning how many bytes were read.
///
/// Example:
///
/// ```
/// use std::io::Read;
/// use fencryption_lib::io::Chain;
///
/// let text = "Never gonna give you up ! Never gonna let you down !";
/// let mut source = Chain::new([255u8; 41].as_ref(), text.as_bytes());
///
/// let mut buf = vec![0u8; 16];
/// loop {
/// let read_len = source.read(&mut buf).unwrap();
/// println!("{:x?} {}", &buf[..read_len], read_len);
/// if read_len != buf.len() {
/// break;
/// }
/// }
/// ```
///
/// Output:
///
/// ```sh
/// [ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff] 16
/// [ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff] 16
/// [ff, ff, ff, ff, ff, ff, ff, ff, ff, 4e, 65, 76, 65, 72, 20, 67] 16
/// [6f, 6e, 6e, 61, 20, 67, 69, 76, 65, 20, 79, 6f, 75, 20, 75, 70] 16
/// [20, 21, 20, 4e, 65, 76, 65, 72, 20, 67, 6f, 6e, 6e, 61, 20, 6c] 16
/// [65, 74, 20, 79, 6f, 75, 20, 64, 6f, 77, 6e, 20, 21] 13
/// ```
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
match &mut self.first {
Some(first) => {
let buf_len = buf.len();
match first.read(&mut buf)? {
n if n < buf_len => {
let mut from_second = vec![0u8; buf_len - n];
let n2 = self.second.read(&mut from_second)?;
buf.write(&[&buf[..n], &from_second].concat())?;
self.first = None;
Ok(n + n2)
}
n => Ok(n),
}
}
None => Ok(self.second.read(buf)?),
}
}
}