virtual_fs/
buffer_file.rs

1//! Used for /dev/zero - infinitely returns zero
2//! which is useful for commands like `dd if=/dev/zero of=bigfile.img size=1G`
3
4use std::io::{self, *};
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
9
10use crate::VirtualFile;
11
12#[derive(Debug, Default)]
13pub struct BufferFile {
14    pub(crate) data: Cursor<Vec<u8>>,
15}
16
17impl AsyncSeek for BufferFile {
18    fn start_seek(mut self: Pin<&mut Self>, position: io::SeekFrom) -> io::Result<()> {
19        let data = Pin::new(&mut self.data);
20        data.start_seek(position)
21    }
22
23    fn poll_complete(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
24        let data = Pin::new(&mut self.data);
25        data.poll_complete(cx)
26    }
27}
28
29impl AsyncWrite for BufferFile {
30    fn poll_write(
31        mut self: Pin<&mut Self>,
32        cx: &mut Context<'_>,
33        buf: &[u8],
34    ) -> Poll<io::Result<usize>> {
35        let data = Pin::new(&mut self.data);
36        data.poll_write(cx, buf)
37    }
38
39    fn poll_write_vectored(
40        mut self: Pin<&mut Self>,
41        cx: &mut Context<'_>,
42        bufs: &[io::IoSlice<'_>],
43    ) -> Poll<io::Result<usize>> {
44        let data = Pin::new(&mut self.data);
45        data.poll_write_vectored(cx, bufs)
46    }
47
48    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
49        let data = Pin::new(&mut self.data);
50        data.poll_flush(cx)
51    }
52
53    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
54        let data = Pin::new(&mut self.data);
55        data.poll_shutdown(cx)
56    }
57}
58
59impl AsyncRead for BufferFile {
60    fn poll_read(
61        mut self: Pin<&mut Self>,
62        cx: &mut Context<'_>,
63        buf: &mut tokio::io::ReadBuf<'_>,
64    ) -> Poll<io::Result<()>> {
65        let data = Pin::new(&mut self.data);
66        data.poll_read(cx, buf)
67    }
68}
69
70impl VirtualFile for BufferFile {
71    fn last_accessed(&self) -> u64 {
72        1_000_000_000 // 1 second after epoch, since zero times are bad!
73    }
74    fn last_modified(&self) -> u64 {
75        1_000_000_000
76    }
77    fn created_time(&self) -> u64 {
78        1_000_000_000
79    }
80    fn size(&self) -> u64 {
81        self.data.get_ref().len() as u64
82    }
83    fn set_len(&mut self, new_size: u64) -> crate::Result<()> {
84        self.data.get_mut().resize(new_size as usize, 0);
85        Ok(())
86    }
87    fn unlink(&mut self) -> crate::Result<()> {
88        Ok(())
89    }
90    fn poll_read_ready(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
91        let cur = self.data.stream_position().unwrap_or_default();
92        let len = self.data.seek(SeekFrom::End(0)).unwrap_or_default();
93        if cur < len {
94            Poll::Ready(Ok((len - cur) as usize))
95        } else {
96            Poll::Ready(Ok(0))
97        }
98    }
99
100    fn poll_write_ready(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
101        Poll::Ready(Ok(8192))
102    }
103}