realm_io/
mem_copy.rs

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
37/// Copy data bidirectionally between two streams with userspace buffer.
38pub 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    /// Get current buffer size.
53    #[inline]
54    pub fn buf_size() -> usize {
55        unsafe { BUF_SIZE }
56    }
57
58    /// Set current buffer size.
59    #[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};