1
1
#[ cfg( feature = "allocator_api" ) ]
2
2
use std:: alloc:: Allocator ;
3
3
4
- use compio_buf:: { BufResult , IntoInner , IoBuf , IoBufMut , IoVectoredBufMut , t_alloc} ;
4
+ use compio_buf:: { BufResult , IntoInner , IoBuf , IoBufMut , IoVectoredBufMut , SetBufInit , t_alloc} ;
5
5
6
- use crate :: { AsyncRead , AsyncReadAt , IoResult , util:: Take } ;
6
+ use crate :: { AsyncRead , AsyncReadAt , IoResult , util:: Take , vectored :: VectoredWrap } ;
7
7
8
8
/// Shared code for read a scalar value from the underlying reader.
9
9
macro_rules! read_scalar {
@@ -36,63 +36,35 @@ macro_rules! read_scalar {
36
36
37
37
/// Shared code for loop reading until reaching a certain length.
38
38
macro_rules! loop_read_exact {
39
- ( $buf: ident, $len: expr, $tracker: ident, loop $read_expr: expr) => {
40
- let mut $tracker = 0 ;
39
+ ( $buf: ident, $len: expr, $tracker: ident, $read_expr: expr , $update_expr : expr , $buf_expr : expr) => {
40
+ let mut $tracker = 0usize ;
41
41
let len = $len;
42
-
43
42
while $tracker < len {
44
- match $read_expr. await . into_inner( ) {
45
- BufResult ( Ok ( 0 ) , buf) => {
43
+ let BufResult ( res, buf) = $read_expr;
44
+ $buf = buf;
45
+ match res {
46
+ Ok ( 0 ) => {
46
47
return BufResult (
47
48
Err ( :: std:: io:: Error :: new(
48
49
:: std:: io:: ErrorKind :: UnexpectedEof ,
49
50
"failed to fill whole buffer" ,
50
51
) ) ,
51
- buf ,
52
+ $buf_expr ,
52
53
) ;
53
54
}
54
- BufResult ( Ok ( n) , buf) => {
55
- $tracker += n;
56
- $buf = buf;
57
- }
58
- BufResult ( Err ( ref e) , buf) if e. kind( ) == :: std:: io:: ErrorKind :: Interrupted => {
59
- $buf = buf;
55
+ Ok ( n) => {
56
+ $tracker += n as usize ;
57
+ $update_expr;
60
58
}
61
- BufResult ( Err ( e) , buf) => return BufResult ( Err ( e) , buf) ,
59
+ Err ( ref e) if e. kind( ) == :: std:: io:: ErrorKind :: Interrupted => { }
60
+ Err ( e) => return BufResult ( Err ( e) , $buf_expr) ,
62
61
}
63
62
}
64
- return BufResult ( Ok ( ( ) ) , $buf )
63
+ return BufResult ( Ok ( ( ) ) , $buf_expr )
65
64
} ;
66
65
}
67
66
68
67
macro_rules! loop_read_vectored {
69
- ( $buf: ident, $tracker: ident : $tracker_ty: ty, $iter: ident, loop $read_expr: expr) => { {
70
- use :: compio_buf:: OwnedIterator ;
71
-
72
- let mut $iter = match $buf. owned_iter( ) {
73
- Ok ( buf) => buf,
74
- Err ( buf) => return BufResult ( Ok ( ( ) ) , buf) ,
75
- } ;
76
- let mut $tracker: $tracker_ty = 0 ;
77
-
78
- loop {
79
- let len = $iter. buf_capacity( ) ;
80
- if len > 0 {
81
- match $read_expr. await {
82
- BufResult ( Ok ( ( ) ) , ret) => {
83
- $iter = ret;
84
- $tracker += len as $tracker_ty;
85
- }
86
- BufResult ( Err ( e) , $iter) => return BufResult ( Err ( e) , $iter. into_inner( ) ) ,
87
- } ;
88
- }
89
-
90
- match $iter. next( ) {
91
- Ok ( next) => $iter = next,
92
- Err ( buf) => return BufResult ( Ok ( ( ) ) , buf) ,
93
- }
94
- }
95
- } } ;
96
68
( $buf: ident, $iter: ident, $read_expr: expr) => { {
97
69
use :: compio_buf:: OwnedIterator ;
98
70
@@ -158,7 +130,14 @@ pub trait AsyncReadExt: AsyncRead {
158
130
159
131
/// Read the exact number of bytes required to fill the buf.
160
132
async fn read_exact < T : IoBufMut > ( & mut self , mut buf : T ) -> BufResult < ( ) , T > {
161
- loop_read_exact ! ( buf, buf. buf_capacity( ) , read, loop self . read( buf. slice( read..) ) ) ;
133
+ loop_read_exact ! (
134
+ buf,
135
+ buf. buf_capacity( ) ,
136
+ read,
137
+ self . read( buf. slice( read..) ) . await . into_inner( ) ,
138
+ { } ,
139
+ buf
140
+ ) ;
162
141
}
163
142
164
143
/// Read all bytes until underlying reader reaches `EOF`.
@@ -171,7 +150,15 @@ pub trait AsyncReadExt: AsyncRead {
171
150
172
151
/// Read the exact number of bytes required to fill the vectored buf.
173
152
async fn read_vectored_exact < T : IoVectoredBufMut > ( & mut self , buf : T ) -> BufResult < ( ) , T > {
174
- loop_read_vectored ! ( buf, _total: usize , iter, loop self . read_exact( iter) )
153
+ let mut buf = VectoredWrap :: new ( buf) ;
154
+ loop_read_exact ! (
155
+ buf,
156
+ buf. capacity( ) ,
157
+ read,
158
+ self . read_vectored( buf) . await ,
159
+ unsafe { buf. set_buf_init( read) } ,
160
+ buf. into_inner( )
161
+ ) ;
175
162
}
176
163
177
164
/// Creates an adaptor which reads at most `limit` bytes from it.
@@ -234,7 +221,11 @@ pub trait AsyncReadAtExt: AsyncReadAt {
234
221
buf,
235
222
buf. buf_capacity( ) ,
236
223
read,
237
- loop self . read_at( buf. slice( read..) , pos + read as u64 )
224
+ self . read_at( buf. slice( read..) , pos + read as u64 )
225
+ . await
226
+ . into_inner( ) ,
227
+ { } ,
228
+ buf
238
229
) ;
239
230
}
240
231
@@ -262,7 +253,15 @@ pub trait AsyncReadAtExt: AsyncReadAt {
262
253
buf : T ,
263
254
pos : u64 ,
264
255
) -> BufResult < ( ) , T > {
265
- loop_read_vectored ! ( buf, total: u64 , iter, loop self . read_exact_at( iter, pos + total) )
256
+ let mut buf = VectoredWrap :: new ( buf) ;
257
+ loop_read_exact ! (
258
+ buf,
259
+ buf. capacity( ) ,
260
+ read,
261
+ self . read_vectored_at( buf, pos + read as u64 ) . await ,
262
+ unsafe { buf. set_buf_init( read) } ,
263
+ buf. into_inner( )
264
+ ) ;
266
265
}
267
266
}
268
267
0 commit comments