1pub trait ReadToTimeout {
11 fn read_to_timeout(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize>;
16
17 fn read_to_timeout_or_bytes(
22 &mut self,
23 buf: &mut Vec<u8>,
24 max_byte: usize,
25 ) -> std::io::Result<usize>;
26
27 fn read_to_timeout_or_pattern(
37 &mut self,
38 buf: &mut Vec<u8>,
39 pattern: &[u8],
40 ) -> std::io::Result<usize>;
41
42 #[deprecated]
47 fn read_to_pattern_or_timeout(
48 &mut self,
49 buf: &mut Vec<u8>,
50 pattern: &[u8],
51 ) -> std::io::Result<usize>;
52}
53
54impl<T: std::io::Read + ?Sized> ReadToTimeout for T {
56 fn read_to_timeout(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
57 let old_len = buf.len();
58
59 loop {
60 let mut read_buf = [0];
61 match self.read_exact(&mut read_buf) {
62 Ok(_) => {
63 buf.push(read_buf[0]);
64 }
65 Err(e) => {
66 return match e.kind() {
67 std::io::ErrorKind::TimedOut => Ok(buf.len() - old_len),
68 _ => Err(e),
69 }
70 }
71 }
72 }
73 }
74
75 fn read_to_timeout_or_bytes(
76 &mut self,
77 buf: &mut Vec<u8>,
78 max_byte: usize,
79 ) -> std::io::Result<usize> {
80 let old_len = buf.len();
81
82 loop {
83 let mut read_buf = [0];
84 match self.read_exact(&mut read_buf) {
85 Ok(_) => {
86 buf.push(read_buf[0]);
87
88 if (buf.len() - old_len) == max_byte {
89 return Ok(buf.len() - old_len);
90 }
91 }
92 Err(e) => {
93 return match e.kind() {
94 std::io::ErrorKind::TimedOut => Ok(buf.len() - old_len),
95 _ => Err(e),
96 }
97 }
98 }
99 }
100 }
101
102 fn read_to_timeout_or_pattern(
103 &mut self,
104 buf: &mut Vec<u8>,
105 pattern: &[u8],
106 ) -> std::io::Result<usize> {
107 let old_len = buf.len();
108
109 loop {
110 let mut byte = [0];
111 match self.read_exact(&mut byte) {
112 Ok(_) => {
113 buf.push(byte[0]);
114 if buf.len() >= pattern.len()
115 && &buf[(buf.len() - pattern.len())..] == pattern
116 {
117 break Ok(buf.len() - old_len);
118 }
119 }
120 Err(err) => match err.kind() {
121 std::io::ErrorKind::TimedOut => {
122 break Ok(buf.len() - old_len);
123 }
124 _ => {
125 break Err(err);
126 }
127 },
128 }
129 }
130 }
131
132 fn read_to_pattern_or_timeout(
133 &mut self,
134 buf: &mut Vec<u8>,
135 pattern: &[u8],
136 ) -> std::io::Result<usize> {
137 self.read_to_timeout_or_pattern(buf, pattern)
138 }
139}
140
141#[cfg(test)]
142mod test {
143 use crate::ReadToTimeout;
144
145 #[test]
146 fn read_pattern() {
147 let mut bytes: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1];
148
149 let mut buffer = Vec::new();
150 assert_eq!(
151 bytes.read_to_timeout_or_pattern(&mut buffer, &[7, 6]).unwrap(),
152 8
153 );
154 assert_eq!(buffer, &[1, 2, 3, 4, 5, 6, 7, 6]);
155
156 assert_eq!(bytes.read_to_timeout_or_bytes(&mut buffer, 4).unwrap(), 4);
157 assert_eq!(buffer, &[1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2]);
158 }
159}