layered_io/
read_layered.rs1use super::{Bufferable, Status};
2use std::io::{self, IoSliceMut, Read};
3
4pub trait ReadLayered: Read + Bufferable {
8 fn read_with_status(&mut self, buf: &mut [u8]) -> io::Result<(usize, Status)>;
10
11 #[inline]
13 fn read_vectored_with_status(
14 &mut self,
15 bufs: &mut [IoSliceMut<'_>],
16 ) -> io::Result<(usize, Status)> {
17 default_read_vectored_with_status(self, bufs)
18 }
19
20 #[inline]
23 fn read_exact_using_status(&mut self, buf: &mut [u8]) -> io::Result<Status> {
24 default_read_exact_using_status(self, buf)
25 }
26
27 #[inline]
29 fn minimum_buffer_size(&self) -> usize {
30 0
31 }
32}
33
34#[inline]
37pub fn default_read<Inner: ReadLayered + ?Sized>(
38 inner: &mut Inner,
39 buf: &mut [u8],
40) -> io::Result<usize> {
41 inner.read_with_status(buf).and_then(to_std_io_read_result)
42}
43
44pub fn default_read_vectored<Inner: ReadLayered + ?Sized>(
47 inner: &mut Inner,
48 bufs: &mut [IoSliceMut<'_>],
49) -> io::Result<usize> {
50 inner
51 .read_vectored_with_status(bufs)
52 .and_then(to_std_io_read_result)
53}
54
55#[allow(clippy::indexing_slicing)]
58pub fn default_read_to_end<Inner: ReadLayered + ?Sized>(
59 inner: &mut Inner,
60 buf: &mut Vec<u8>,
61) -> io::Result<usize> {
62 let start_len = buf.len();
63 let buffer_size = inner.suggested_buffer_size();
64 let mut read_len = buffer_size;
65 loop {
66 let read_pos = buf.len();
67
68 buf.resize(read_pos + read_len, 0);
74
75 match inner.read_with_status(&mut buf[read_pos..]) {
76 Ok((size, status)) => {
77 buf.resize(read_pos + size, 0);
78 match status {
79 Status::Open(_) => {
80 read_len -= size;
81 if read_len < inner.minimum_buffer_size() {
82 read_len += buffer_size;
83 }
84 }
85 Status::End => return Ok(buf.len() - start_len),
86 }
87 }
88 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
89 Err(e) => {
90 buf.resize(start_len, 0);
91 return Err(e);
92 }
93 }
94 }
95}
96
97pub fn default_read_to_string<Inner: ReadLayered + ?Sized>(
100 inner: &mut Inner,
101 buf: &mut String,
102) -> io::Result<usize> {
103 let mut vec = Vec::new();
107 let size = inner.read_to_end(&mut vec)?;
108 let new = String::from_utf8(vec).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
109 buf.push_str(&new);
110 Ok(size)
111}
112
113#[allow(clippy::indexing_slicing)]
116pub fn default_read_exact_using_status<Inner: ReadLayered + ?Sized>(
117 inner: &mut Inner,
118 mut buf: &mut [u8],
119) -> io::Result<Status> {
120 let mut result_status = Status::active();
121
122 while !buf.is_empty() {
123 match inner.read_with_status(buf) {
124 Ok((size, status)) => {
125 let t = buf;
126 buf = &mut t[size..];
127 if status.is_end() {
128 result_status = status;
129 break;
130 }
131 }
132 Err(e) => return Err(e),
133 }
134 }
135
136 if buf.is_empty() {
137 Ok(result_status)
138 } else {
139 Err(io::Error::new(
140 io::ErrorKind::UnexpectedEof,
141 "failed to fill whole buffer",
142 ))
143 }
144}
145
146pub fn default_read_vectored_with_status<Inner: ReadLayered + ?Sized>(
149 inner: &mut Inner,
150 bufs: &mut [IoSliceMut<'_>],
151) -> io::Result<(usize, Status)> {
152 let buf = bufs
153 .iter_mut()
154 .find(|b| !b.is_empty())
155 .map_or(&mut [][..], |b| &mut **b);
156 inner.read_with_status(buf)
157}
158
159#[cfg(can_vector)]
162pub fn default_is_read_vectored<Inner: ReadLayered + ?Sized>(_inner: &Inner) -> bool {
163 false
164}
165
166pub fn to_std_io_read_result(size_and_status: (usize, Status)) -> io::Result<usize> {
171 match size_and_status {
172 (0, Status::Open(_)) => Err(io::Error::new(
173 io::ErrorKind::Interrupted,
174 "read zero bytes from stream",
175 )),
176 (size, _) => Ok(size),
177 }
178}
179
180impl<R: ReadLayered> ReadLayered for Box<R> {
181 #[inline]
182 fn read_with_status(&mut self, buf: &mut [u8]) -> io::Result<(usize, Status)> {
183 self.as_mut().read_with_status(buf)
184 }
185
186 #[inline]
187 fn read_vectored_with_status(
188 &mut self,
189 bufs: &mut [IoSliceMut<'_>],
190 ) -> io::Result<(usize, Status)> {
191 self.as_mut().read_vectored_with_status(bufs)
192 }
193
194 #[inline]
195 fn minimum_buffer_size(&self) -> usize {
196 self.as_ref().minimum_buffer_size()
197 }
198}
199
200impl<R: ReadLayered> ReadLayered for &mut R {
201 #[inline]
202 fn read_with_status(&mut self, buf: &mut [u8]) -> io::Result<(usize, Status)> {
203 (**self).read_with_status(buf)
204 }
205
206 #[inline]
207 fn read_vectored_with_status(
208 &mut self,
209 bufs: &mut [IoSliceMut<'_>],
210 ) -> io::Result<(usize, Status)> {
211 (**self).read_vectored_with_status(bufs)
212 }
213
214 #[inline]
215 fn minimum_buffer_size(&self) -> usize {
216 (**self).minimum_buffer_size()
217 }
218}