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}