fencryption_lib/
io.rs

1//! IO utilities.
2
3use std::io::{self, Read, Write};
4
5/// Default buffer length for io (4kb).
6pub const DEFAULT_BUF_LEN: usize = 4000;
7
8/// Transfer data from a reader to a writer.
9pub fn stream(from: &mut impl Read, to: &mut impl Write) -> io::Result<()> {
10    let mut buffer = [0u8; DEFAULT_BUF_LEN];
11    loop {
12        let read_len = from.read(&mut buffer)?;
13        to.write(&buffer[..read_len])?;
14        if read_len != DEFAULT_BUF_LEN {
15            break;
16        }
17    }
18    Ok(())
19}
20
21/// Adapter to chain two readers together.
22///
23/// It might seem the exact same as [`std::io::Chain`] but it
24/// is not. The difference is that when it reaches the end of
25/// the first reader, it fills the rest of the buffer with
26/// the first bytes from the second reader, what [`std::io::Chain`]
27/// doesn't do.
28pub struct Chain<R1: Read, R2: Read> {
29    first: Option<R1>,
30    second: R2,
31}
32
33impl<R1: Read, R2: Read> Chain<R1, R2> {
34    /// Create a Chain from the two given readers.
35    pub fn new(first: R1, second: R2) -> Self {
36        Chain {
37            first: Some(first),
38            second,
39        }
40    }
41}
42
43impl<R1: Read, R2: Read> Read for Chain<R1, R2> {
44    /// Pull some bytes from this source into the specified
45    /// buffer, returning how many bytes were read.
46    ///
47    /// Example:
48    ///
49    /// ```
50    /// use std::io::Read;
51    /// use fencryption_lib::io::Chain;
52    ///
53    /// let text = "Never gonna give you up ! Never gonna let you down !";
54    /// let mut source = Chain::new([255u8; 41].as_ref(), text.as_bytes());
55    ///
56    /// let mut buf = vec![0u8; 16];
57    /// loop {
58    ///     let read_len = source.read(&mut buf).unwrap();
59    ///     println!("{:x?} {}", &buf[..read_len], read_len);
60    ///     if read_len != buf.len() {
61    ///         break;
62    ///     }
63    /// }
64    /// ```
65    ///
66    /// Output:
67    ///
68    /// ```sh
69    /// [ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff] 16
70    /// [ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff] 16
71    /// [ff, ff, ff, ff, ff, ff, ff, ff, ff, 4e, 65, 76, 65, 72, 20, 67] 16
72    /// [6f, 6e, 6e, 61, 20, 67, 69, 76, 65, 20, 79, 6f, 75, 20, 75, 70] 16
73    /// [20, 21, 20, 4e, 65, 76, 65, 72, 20, 67, 6f, 6e, 6e, 61, 20, 6c] 16
74    /// [65, 74, 20, 79, 6f, 75, 20, 64, 6f, 77, 6e, 20, 21] 13
75    /// ```
76    fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
77        match &mut self.first {
78            Some(first) => {
79                let buf_len = buf.len();
80                match first.read(&mut buf)? {
81                    n if n < buf_len => {
82                        let mut from_second = vec![0u8; buf_len - n];
83                        let n2 = self.second.read(&mut from_second)?;
84                        buf.write(&[&buf[..n], &from_second].concat())?;
85                        self.first = None;
86                        Ok(n + n2)
87                    }
88                    n => Ok(n),
89                }
90            }
91            None => Ok(self.second.read(buf)?),
92        }
93    }
94}