1use crate::error::MyResult;
2use std::io::Read;
3
4pub fn read_until(
5 file: &mut dyn Read,
6 buffer: &mut Vec<u8>,
7 size: usize,
8) -> MyResult<usize> {
9 if let Some(size) = size.checked_sub(buffer.len()) {
10 if size > 0 {
11 file.take(size as u64).read_to_end(buffer)?;
12 }
13 }
14 Ok(buffer.len())
15}
16
17#[cfg(test)]
18mod tests {
19 use crate::error::MyResult;
20 use crate::util::file::read_until;
21 use googletest::prelude::*;
22 use std::io::Cursor;
23
24 #[gtest]
25 fn test_zero_bytes_are_not_read() -> MyResult<()> {
26 let (count, buffer) = read_until_multi(vec![0])?;
27 expect_eq!(count, 0);
28 expect_eq!(&buffer, b"");
29 Ok(())
30 }
31
32 #[gtest]
33 fn test_counted_bytes_are_partly_read() -> MyResult<()> {
34 let (count, buffer) = read_until_multi(vec![4])?;
35 expect_eq!(count, 4);
36 expect_eq!(&buffer, b"ABCD");
37 Ok(())
38 }
39
40 #[gtest]
41 fn test_counted_bytes_are_fully_read() -> MyResult<()> {
42 let (count, buffer) = read_until_multi(vec![12])?;
43 expect_eq!(count, 10);
44 expect_eq!(&buffer, b"ABCDEFGHIJ");
45 Ok(())
46 }
47
48 #[gtest]
49 fn test_counted_bytes_are_partly_and_partly_read() -> MyResult<()> {
50 let (count, buffer) = read_until_multi(vec![8, 4])?;
51 expect_eq!(count, 8);
52 expect_eq!(&buffer, b"ABCDEFGH");
53 Ok(())
54 }
55
56 #[gtest]
57 fn test_counted_bytes_are_partly_and_fully_read() -> MyResult<()> {
58 let (count, buffer) = read_until_multi(vec![4, 12])?;
59 expect_eq!(count, 10);
60 expect_eq!(&buffer, b"ABCDEFGHIJ");
61 Ok(())
62 }
63
64 fn read_until_multi(sizes: Vec<usize>) -> MyResult<(usize, Vec<u8>)> {
65 let mut file = Cursor::new(b"ABCDEFGHIJ".to_vec());
66 let mut buffer = Vec::new();
67 let mut count = 0;
68 for size in sizes {
69 count = read_until(&mut file, &mut buffer, size)?;
70 }
71 Ok((count, buffer))
72 }
73}