1use std::io::Result;
2use std::pin::Pin;
3use std::task::{Poll, Context};
4
5use tokio::io::ReadBuf;
6use tokio::io::{AsyncRead, AsyncWrite};
7
8use super::{CopyBuffer, AsyncIOBuf};
9use super::bidi_copy_buf;
10
11impl<B, SR, SW> AsyncIOBuf for CopyBuffer<B, SR, SW>
12where
13 B: AsMut<[u8]>,
14 SR: AsyncRead + AsyncWrite + Unpin,
15 SW: AsyncRead + AsyncWrite + Unpin,
16{
17 type StreamR = SR;
18 type StreamW = SW;
19
20 #[inline]
21 fn poll_read_buf(&mut self, cx: &mut Context<'_>, stream: &mut Self::StreamR) -> Poll<Result<usize>> {
22 let mut buf = ReadBuf::new(self.buf.as_mut());
23 Pin::new(stream).poll_read(cx, &mut buf).map_ok(|_| buf.filled().len())
24 }
25
26 #[inline]
27 fn poll_write_buf(&mut self, cx: &mut Context<'_>, stream: &mut Self::StreamW) -> Poll<Result<usize>> {
28 Pin::new(stream).poll_write(cx, &self.buf.as_mut()[self.pos..self.cap])
29 }
30
31 #[inline]
32 fn poll_flush_buf(&mut self, cx: &mut Context<'_>, stream: &mut Self::StreamW) -> Poll<Result<()>> {
33 Pin::new(stream).poll_flush(cx)
34 }
35}
36
37pub async fn bidi_copy<A, B>(a: &mut A, b: &mut B) -> Result<(u64, u64)>
39where
40 A: AsyncRead + AsyncWrite + Unpin,
41 B: AsyncRead + AsyncWrite + Unpin,
42{
43 let a_to_b_buf = CopyBuffer::new(vec![0u8; buf_size()].into_boxed_slice());
44 let b_to_a_buf = CopyBuffer::new(vec![0u8; buf_size()].into_boxed_slice());
45 bidi_copy_buf(a, b, a_to_b_buf, b_to_a_buf).await
46}
47
48mod buf_ctl {
49 pub const DF_BUF_SIZE: usize = 0x2000;
50 static mut BUF_SIZE: usize = DF_BUF_SIZE;
51
52 #[inline]
54 pub fn buf_size() -> usize {
55 unsafe { BUF_SIZE }
56 }
57
58 #[inline]
60 pub fn set_buf_size(n: usize) {
61 unsafe { BUF_SIZE = n }
62 }
63}
64
65pub use buf_ctl::{buf_size, set_buf_size};