@@ -119,8 +119,7 @@ pub trait FileExt {
119
119
match self . read_at ( buf, offset) {
120
120
Ok ( 0 ) => break ,
121
121
Ok ( n) => {
122
- let tmp = buf;
123
- buf = & mut tmp[ n..] ;
122
+ buf = & mut buf[ n..] ;
124
123
offset += n as u64 ;
125
124
}
126
125
Err ( ref e) if e. is_interrupted ( ) => { }
@@ -134,6 +133,61 @@ pub trait FileExt {
134
133
}
135
134
}
136
135
136
+ /// Reads a number of bytes starting from a given offset.
137
+ ///
138
+ /// This is equivalent to the [`read_at`](FileExt::read_at) method, except
139
+ /// that it is passed a [`BorrowedCursor`] rather than `[u8]` to allow use
140
+ /// with uninitialized buffers. The new data will be appended to any
141
+ /// existing contents of `buf`.
142
+ ///
143
+ /// The offset is relative to the start of the file and thus independent
144
+ /// from the current cursor.
145
+ ///
146
+ /// The current file cursor is not affected by this function.
147
+ ///
148
+ /// Note that similar to [`File::read_buf`], it is not an error to return with a
149
+ /// short read.
150
+ ///
151
+ /// [`File::read_buf`]: fs::File::read_buf
152
+ /// [`BorrowedCursor`]: io::BorrowedCursor
153
+ #[ unstable( feature = "read_buf" , issue = "78485" ) ]
154
+ fn read_buf_at ( & self , mut cursor : io:: BorrowedCursor < ' _ > , offset : u64 ) -> io:: Result < ( ) > {
155
+ let n = self . read_at ( cursor. ensure_init ( ) . init_mut ( ) , offset) ?;
156
+ cursor. advance ( n) ;
157
+ Ok ( ( ) )
158
+ }
159
+
160
+ /// Reads the exact number of bytes required to fill `buf` from the given offset.
161
+ ///
162
+ /// The offset is relative to the start of the file and thus independent
163
+ /// from the current cursor.
164
+ ///
165
+ /// The current file cursor is not affected by this function.
166
+ #[ unstable( feature = "read_buf" , issue = "78485" ) ]
167
+ fn read_buf_exact_at (
168
+ & self ,
169
+ mut cursor : io:: BorrowedCursor < ' _ > ,
170
+ mut offset : u64 ,
171
+ ) -> io:: Result < ( ) > {
172
+ while cursor. capacity ( ) > 0 {
173
+ let prev_written = cursor. written ( ) ;
174
+ match self . read_buf_at ( cursor. reborrow ( ) , offset) {
175
+ Ok ( ( ) ) => offset += ( cursor. written ( ) - prev_written) as u64 ,
176
+ Err ( e) if e. is_interrupted ( ) => continue ,
177
+ Err ( e) => return Err ( e) ,
178
+ }
179
+
180
+ if cursor. written ( ) == prev_written {
181
+ return Err ( io:: const_io_error!(
182
+ io:: ErrorKind :: UnexpectedEof ,
183
+ "failed to fill whole buffer"
184
+ ) ) ;
185
+ }
186
+ }
187
+
188
+ Ok ( ( ) )
189
+ }
190
+
137
191
/// Writes a number of bytes starting from a given offset.
138
192
///
139
193
/// Returns the number of bytes written.
@@ -271,6 +325,9 @@ impl FileExt for fs::File {
271
325
fn read_at ( & self , buf : & mut [ u8 ] , offset : u64 ) -> io:: Result < usize > {
272
326
self . as_inner ( ) . read_at ( buf, offset)
273
327
}
328
+ fn read_buf_at ( & self , cursor : io:: BorrowedCursor < ' _ > , offset : u64 ) -> io:: Result < ( ) > {
329
+ self . as_inner ( ) . read_buf_at ( cursor, offset)
330
+ }
274
331
fn read_vectored_at ( & self , bufs : & mut [ io:: IoSliceMut < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
275
332
self . as_inner ( ) . read_vectored_at ( bufs, offset)
276
333
}
0 commit comments