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