1use core::pin::Pin;
5use core::task::{Context, Poll, ready};
6use std::io::{self, IoSlice, SeekFrom};
7
8use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite};
9
10const DEFAULT_CAPACITY: usize = 8 * 1024;
12
13#[derive(Debug)]
17pub struct BufReader<R> {
18 inner: R,
19 buf: Box<[u8]>,
20 pos: usize,
21 cap: usize,
22}
23
24impl<R> BufReader<R> {
25 pub fn new(inner: R) -> Self {
27 Self::with_capacity(DEFAULT_CAPACITY, inner)
28 }
29
30 pub fn with_capacity(capacity: usize, inner: R) -> Self {
32 Self {
33 inner,
34 buf: vec![0; capacity].into_boxed_slice(),
35 pos: 0,
36 cap: 0,
37 }
38 }
39
40 pub fn get_ref(&self) -> &R {
42 &self.inner
43 }
44
45 pub fn get_mut(&mut self) -> &mut R {
48 &mut self.inner
49 }
50
51 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut R>
53 where
54 R: Unpin,
55 {
56 Pin::new(&mut self.get_mut().inner)
57 }
58
59 pub fn into_inner(self) -> R {
61 self.inner
62 }
63
64 pub fn buffer(&self) -> &[u8] {
66 &self.buf[self.pos..self.cap]
67 }
68
69 fn discard_buffer(&mut self) {
70 self.pos = 0;
71 self.cap = 0;
72 }
73}
74
75impl<R: AsyncRead + Unpin> AsyncRead for BufReader<R> {
76 fn poll_read(
77 self: Pin<&mut Self>,
78 cx: &mut Context<'_>,
79 out: &mut [u8],
80 ) -> Poll<io::Result<usize>> {
81 let this = self.get_mut();
82 if this.pos == this.cap && out.len() >= this.buf.len() {
85 let n = ready!(Pin::new(&mut this.inner).poll_read(cx, out))?;
86 this.discard_buffer();
87 return Poll::Ready(Ok(n));
88 }
89 let available = ready!(Pin::new(&mut *this).poll_fill_buf(cx))?;
90 let n = available.len().min(out.len());
91 out[..n].copy_from_slice(&available[..n]);
92 Pin::new(this).consume(n);
93 Poll::Ready(Ok(n))
94 }
95}
96
97impl<R: AsyncRead + Unpin> AsyncBufRead for BufReader<R> {
98 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
99 let this = self.get_mut();
100 if this.pos >= this.cap {
101 let n = ready!(Pin::new(&mut this.inner).poll_read(cx, &mut this.buf))?;
102 this.cap = n;
103 this.pos = 0;
104 }
105 Poll::Ready(Ok(&this.buf[this.pos..this.cap]))
106 }
107
108 fn consume(self: Pin<&mut Self>, amount: usize) {
109 let this = self.get_mut();
110 this.pos = (this.pos + amount).min(this.cap);
111 }
112}
113
114impl<R: AsyncRead + AsyncSeek + Unpin> AsyncSeek for BufReader<R> {
115 fn poll_seek(
119 self: Pin<&mut Self>,
120 cx: &mut Context<'_>,
121 pos: SeekFrom,
122 ) -> Poll<io::Result<u64>> {
123 let this = self.get_mut();
124 let pos = match pos {
125 SeekFrom::Current(n) => {
126 let buffered = (this.cap - this.pos) as i64;
127 match n.checked_sub(buffered) {
128 Some(n) => SeekFrom::Current(n),
129 None => {
130 ready!(
132 Pin::new(&mut this.inner).poll_seek(cx, SeekFrom::Current(-buffered))
133 )?;
134 this.discard_buffer();
135 SeekFrom::Current(n)
136 }
137 }
138 }
139 other => other,
140 };
141 let at = ready!(Pin::new(&mut this.inner).poll_seek(cx, pos))?;
142 this.discard_buffer();
143 Poll::Ready(Ok(at))
144 }
145}
146
147impl<R: AsyncWrite + Unpin> AsyncWrite for BufReader<R> {
148 fn poll_write(
149 self: Pin<&mut Self>,
150 cx: &mut Context<'_>,
151 buf: &[u8],
152 ) -> Poll<io::Result<usize>> {
153 Pin::new(&mut self.get_mut().inner).poll_write(cx, buf)
154 }
155
156 fn poll_write_vectored(
157 self: Pin<&mut Self>,
158 cx: &mut Context<'_>,
159 bufs: &[IoSlice<'_>],
160 ) -> Poll<io::Result<usize>> {
161 Pin::new(&mut self.get_mut().inner).poll_write_vectored(cx, bufs)
162 }
163
164 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
165 Pin::new(&mut self.get_mut().inner).poll_flush(cx)
166 }
167
168 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
169 Pin::new(&mut self.get_mut().inner).poll_close(cx)
170 }
171}
172
173#[derive(Debug)]
178pub struct BufWriter<W> {
179 inner: W,
180 buf: Vec<u8>,
181 written: usize,
182}
183
184impl<W> BufWriter<W> {
185 pub fn new(inner: W) -> Self {
187 Self::with_capacity(DEFAULT_CAPACITY, inner)
188 }
189
190 pub fn with_capacity(capacity: usize, inner: W) -> Self {
192 Self {
193 inner,
194 buf: Vec::with_capacity(capacity),
195 written: 0,
196 }
197 }
198
199 pub fn get_ref(&self) -> &W {
201 &self.inner
202 }
203
204 pub fn get_mut(&mut self) -> &mut W {
207 &mut self.inner
208 }
209
210 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut W>
212 where
213 W: Unpin,
214 {
215 Pin::new(&mut self.get_mut().inner)
216 }
217
218 pub fn into_inner(self) -> W {
220 self.inner
221 }
222
223 pub fn buffer(&self) -> &[u8] {
225 &self.buf[self.written..]
226 }
227}
228
229impl<W: AsyncWrite + Unpin> BufWriter<W> {
230 fn flush_buf(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
232 while self.written < self.buf.len() {
233 let n = ready!(Pin::new(&mut self.inner).poll_write(cx, &self.buf[self.written..]))?;
234 if n == 0 {
235 return Poll::Ready(Err(io::Error::new(
236 io::ErrorKind::WriteZero,
237 "the writer took no more of the buffered bytes",
238 )));
239 }
240 self.written += n;
241 }
242 self.buf.clear();
243 self.written = 0;
244 Poll::Ready(Ok(()))
245 }
246}
247
248impl<W: AsyncWrite + Unpin> AsyncWrite for BufWriter<W> {
249 fn poll_write(
250 self: Pin<&mut Self>,
251 cx: &mut Context<'_>,
252 buf: &[u8],
253 ) -> Poll<io::Result<usize>> {
254 let this = self.get_mut();
255 if this.buf.len() + buf.len() > this.buf.capacity() {
256 ready!(this.flush_buf(cx))?;
257 }
258 if buf.len() >= this.buf.capacity() {
259 return Pin::new(&mut this.inner).poll_write(cx, buf);
261 }
262 this.buf.extend_from_slice(buf);
263 Poll::Ready(Ok(buf.len()))
264 }
265
266 fn poll_write_vectored(
267 self: Pin<&mut Self>,
268 cx: &mut Context<'_>,
269 bufs: &[IoSlice<'_>],
270 ) -> Poll<io::Result<usize>> {
271 let this = self.get_mut();
272 let total: usize = bufs.iter().map(|b| b.len()).sum();
273 if this.buf.len() + total > this.buf.capacity() {
274 ready!(this.flush_buf(cx))?;
275 }
276 if total >= this.buf.capacity() {
277 return Pin::new(&mut this.inner).poll_write_vectored(cx, bufs);
278 }
279 for b in bufs {
280 this.buf.extend_from_slice(b);
281 }
282 Poll::Ready(Ok(total))
283 }
284
285 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
286 let this = self.get_mut();
287 ready!(this.flush_buf(cx))?;
288 Pin::new(&mut this.inner).poll_flush(cx)
289 }
290
291 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
292 let this = self.get_mut();
293 ready!(this.flush_buf(cx))?;
294 Pin::new(&mut this.inner).poll_close(cx)
295 }
296}
297
298impl<W: AsyncRead + Unpin> AsyncRead for BufWriter<W> {
299 fn poll_read(
300 self: Pin<&mut Self>,
301 cx: &mut Context<'_>,
302 buf: &mut [u8],
303 ) -> Poll<io::Result<usize>> {
304 Pin::new(&mut self.get_mut().inner).poll_read(cx, buf)
305 }
306}
307
308impl<W: AsyncBufRead + Unpin> AsyncBufRead for BufWriter<W> {
309 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
310 Pin::new(&mut self.get_mut().inner).poll_fill_buf(cx)
311 }
312
313 fn consume(self: Pin<&mut Self>, amount: usize) {
314 Pin::new(&mut self.get_mut().inner).consume(amount);
315 }
316}
317
318impl<W: AsyncWrite + AsyncSeek + Unpin> AsyncSeek for BufWriter<W> {
319 fn poll_seek(
321 self: Pin<&mut Self>,
322 cx: &mut Context<'_>,
323 pos: SeekFrom,
324 ) -> Poll<io::Result<u64>> {
325 let this = self.get_mut();
326 ready!(this.flush_buf(cx))?;
327 Pin::new(&mut this.inner).poll_seek(cx, pos)
328 }
329}
330
331#[derive(Debug)]
334pub struct BufStream<S> {
335 inner: BufReader<BufWriter<S>>,
336}
337
338impl<S> BufStream<S> {
339 pub fn new(stream: S) -> Self {
341 Self {
342 inner: BufReader::new(BufWriter::new(stream)),
343 }
344 }
345
346 pub fn with_capacity(read: usize, write: usize, stream: S) -> Self {
349 Self {
350 inner: BufReader::with_capacity(read, BufWriter::with_capacity(write, stream)),
351 }
352 }
353
354 pub fn get_ref(&self) -> &S {
356 self.inner.get_ref().get_ref()
357 }
358
359 pub fn get_mut(&mut self) -> &mut S {
361 self.inner.get_mut().get_mut()
362 }
363
364 pub fn into_inner(self) -> S {
366 self.inner.into_inner().into_inner()
367 }
368}
369
370impl<S: AsyncRead + AsyncWrite + Unpin> AsyncRead for BufStream<S> {
371 fn poll_read(
372 self: Pin<&mut Self>,
373 cx: &mut Context<'_>,
374 buf: &mut [u8],
375 ) -> Poll<io::Result<usize>> {
376 Pin::new(&mut self.get_mut().inner).poll_read(cx, buf)
377 }
378}
379
380impl<S: AsyncRead + AsyncWrite + Unpin> AsyncBufRead for BufStream<S> {
381 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
382 Pin::new(&mut self.get_mut().inner).poll_fill_buf(cx)
383 }
384
385 fn consume(self: Pin<&mut Self>, amount: usize) {
386 Pin::new(&mut self.get_mut().inner).consume(amount);
387 }
388}
389
390impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for BufStream<S> {
391 fn poll_write(
392 self: Pin<&mut Self>,
393 cx: &mut Context<'_>,
394 buf: &[u8],
395 ) -> Poll<io::Result<usize>> {
396 Pin::new(&mut self.get_mut().inner).poll_write(cx, buf)
397 }
398
399 fn poll_write_vectored(
400 self: Pin<&mut Self>,
401 cx: &mut Context<'_>,
402 bufs: &[IoSlice<'_>],
403 ) -> Poll<io::Result<usize>> {
404 Pin::new(&mut self.get_mut().inner).poll_write_vectored(cx, bufs)
405 }
406
407 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
408 Pin::new(&mut self.get_mut().inner).poll_flush(cx)
409 }
410
411 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
412 Pin::new(&mut self.get_mut().inner).poll_close(cx)
413 }
414}