1#[cfg(feature = "allocator_api")]
2use std::alloc::Allocator;
3use std::{io::Cursor, rc::Rc, sync::Arc};
4
5use compio_buf::{
6 BufResult, IntoInner, IoBufMut, IoBufMutExt, IoVectoredBufMut, SetLenExt, buf_try, t_alloc,
7};
8
9mod buf;
10#[macro_use]
11mod ext;
12mod managed;
13mod multi;
14
15pub use buf::*;
16pub use ext::*;
17pub use managed::*;
18pub use multi::*;
19
20use crate::util::{slice_to_buf, slice_to_uninit};
21
22pub trait AsyncRead {
26 async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B>;
39
40 async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
55 loop_read_vectored!(buf, iter, self.read(iter))
56 }
57}
58
59impl<A: AsyncRead + ?Sized> AsyncRead for &mut A {
60 #[inline(always)]
61 async fn read<T: IoBufMut>(&mut self, buf: T) -> BufResult<usize, T> {
62 (**self).read(buf).await
63 }
64
65 #[inline(always)]
66 async fn read_vectored<T: IoVectoredBufMut>(&mut self, buf: T) -> BufResult<usize, T> {
67 (**self).read_vectored(buf).await
68 }
69}
70
71impl<R: AsyncRead + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator> AsyncRead
72 for t_alloc!(Box, R, A)
73{
74 #[inline(always)]
75 async fn read<T: IoBufMut>(&mut self, buf: T) -> BufResult<usize, T> {
76 (**self).read(buf).await
77 }
78
79 #[inline(always)]
80 async fn read_vectored<T: IoVectoredBufMut>(&mut self, buf: T) -> BufResult<usize, T> {
81 (**self).read_vectored(buf).await
82 }
83}
84
85impl AsyncRead for &[u8] {
86 #[inline]
87 async fn read<T: IoBufMut>(&mut self, mut buf: T) -> BufResult<usize, T> {
88 let len = slice_to_buf(self, &mut buf);
89 *self = &self[len..];
90 BufResult(Ok(len), buf)
91 }
92
93 async fn read_vectored<T: IoVectoredBufMut>(&mut self, mut buf: T) -> BufResult<usize, T> {
94 let mut this = *self; for buf in unsafe { buf.iter_uninit_slice() } {
98 let n = slice_to_uninit(this, buf);
99 this = &this[n..];
100 if this.is_empty() {
101 break;
102 }
103 }
104
105 let len = self.len() - this.len();
106 *self = this;
107
108 unsafe {
109 buf.advance_vec_to(len);
110 }
111
112 BufResult(Ok(len), buf)
113 }
114}
115
116pub trait AsyncReadAt {
120 async fn read_at<T: IoBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T>;
122
123 async fn read_vectored_at<T: IoVectoredBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
126 loop_read_vectored!(buf, iter, self.read_at(iter, pos))
127 }
128}
129
130macro_rules! impl_read_at {
131 (@ptr $($ty:ty),*) => {
132 $(
133 impl<A: AsyncReadAt + ?Sized> AsyncReadAt for $ty {
134 async fn read_at<T: IoBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
135 (**self).read_at(buf, pos).await
136 }
137
138 async fn read_vectored_at<T: IoVectoredBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
139 (**self).read_vectored_at(buf, pos).await
140 }
141 }
142 )*
143 };
144
145 (@ptra $($ty:ident),*) => {
146 $(
147 #[cfg(feature = "allocator_api")]
148 impl<R: AsyncReadAt + ?Sized, A: Allocator> AsyncReadAt for $ty<R, A> {
149 async fn read_at<T: IoBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
150 (**self).read_at(buf, pos).await
151 }
152
153 async fn read_vectored_at<T: IoVectoredBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
154 (**self).read_vectored_at(buf, pos).await
155 }
156 }
157 #[cfg(not(feature = "allocator_api"))]
158 impl_read_at!(@ptr $ty<A>);
159 )*
160 };
161
162 (@slice $($(const $len:ident =>)? $ty:ty), *) => {
163 $(
164 impl<$(const $len: usize)?> AsyncReadAt for $ty {
165 async fn read_at<T: IoBufMut>(&self, mut buf: T, pos: u64) -> BufResult<usize, T> {
166 let pos = pos.min(self.len() as u64);
167 let len = slice_to_buf(&self[pos as usize..], &mut buf);
168 BufResult(Ok(len), buf)
169 }
170
171 async fn read_vectored_at<T:IoVectoredBufMut>(&self, mut buf: T, pos: u64) -> BufResult<usize, T> {
172 let slice = &self[pos as usize..];
173 let mut this = slice;
174
175 for buf in unsafe { buf.iter_uninit_slice() } {
177 let n = slice_to_uninit(this, buf);
178 this = &this[n..];
179 if this.is_empty() {
180 break;
181 }
182 }
183
184 let len = slice.len() - this.len();
185 unsafe {
186 buf.advance_vec_to(len);
187 }
188
189 BufResult(Ok(len), buf)
190 }
191 }
192 )*
193 }
194}
195
196impl_read_at!(@ptr &A, &mut A);
197impl_read_at!(@ptra Box, Rc, Arc);
198impl_read_at!(@slice [u8], const LEN => [u8; LEN]);
199
200impl<#[cfg(feature = "allocator_api")] A: Allocator> AsyncReadAt for t_alloc!(Vec, u8, A) {
201 async fn read_at<T: IoBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
202 self.as_slice().read_at(buf, pos).await
203 }
204
205 async fn read_vectored_at<T: IoVectoredBufMut>(&self, buf: T, pos: u64) -> BufResult<usize, T> {
206 self.as_slice().read_vectored_at(buf, pos).await
207 }
208}
209
210impl<A: AsyncReadAt> AsyncRead for Cursor<A> {
211 #[inline]
212 async fn read<T: IoBufMut>(&mut self, buf: T) -> BufResult<usize, T> {
213 let pos = self.position();
214 let (n, buf) = buf_try!(self.get_ref().read_at(buf, pos).await);
215 self.set_position(pos + n as u64);
216 BufResult(Ok(n), buf)
217 }
218
219 #[inline]
220 async fn read_vectored<T: IoVectoredBufMut>(&mut self, buf: T) -> BufResult<usize, T> {
221 let pos = self.position();
222 let (n, buf) = buf_try!(self.get_ref().read_vectored_at(buf, pos).await);
223 self.set_position(pos + n as u64);
224 BufResult(Ok(n), buf)
225 }
226}