@@ -11,6 +11,7 @@ use super::platform::fs::MetadataExt as _;
11
11
// Used for `File::read` on intra-doc links
12
12
use crate :: ffi:: OsStr ;
13
13
use crate :: fs:: { self , OpenOptions , Permissions } ;
14
+ use crate :: io:: BorrowedCursor ;
14
15
use crate :: os:: unix:: io:: { AsFd , AsRawFd } ;
15
16
use crate :: path:: Path ;
16
17
use crate :: sealed:: Sealed ;
@@ -130,6 +131,94 @@ pub trait FileExt {
130
131
if !buf. is_empty ( ) { Err ( io:: Error :: READ_EXACT_EOF ) } else { Ok ( ( ) ) }
131
132
}
132
133
134
+ /// Reads some bytes starting from a given offset into the buffer.
135
+ ///
136
+ /// This equivalent to the [`read_at`](FileExt::read_at) method,
137
+ /// except that it is passed a [`BorrowedCursor`] rather than `&mut [u8]` to allow
138
+ /// use with uninitialized buffers. The new data will be appended to any
139
+ /// existing contents of `buf`.
140
+ ///
141
+ /// # Examples
142
+ ///
143
+ /// ```no_run
144
+ /// #![feature(core_io_borrowed_buf)]
145
+ /// #![feature(read_buf_at)]
146
+ ///
147
+ /// use std::io;
148
+ /// use std::io::BorrowedBuf;
149
+ /// use std::fs::File;
150
+ /// use std::mem::MaybeUninit;
151
+ /// use std::os::unix::prelude::*;
152
+ ///
153
+ /// fn main() -> io::Result<()> {
154
+ /// let mut file = File::open("pi.txt")?;
155
+ ///
156
+ /// // Read some bytes starting from offset 2
157
+ /// let mut buf: [MaybeUninit<u8>; 10] = [MaybeUninit::uninit(); 10];
158
+ /// let mut buf = BorrowedBuf::from(buf.as_mut_slice());
159
+ /// file.read_buf_at(buf.unfilled(), 2)?;
160
+ ///
161
+ /// assert!(buf.filled().starts_with(b"1"));
162
+ ///
163
+ /// Ok(())
164
+ /// }
165
+ /// ```
166
+ #[ unstable( feature = "read_buf_at" , issue = "140771" ) ]
167
+ fn read_buf_at ( & self , buf : BorrowedCursor < ' _ > , offset : u64 ) -> io:: Result < ( ) > {
168
+ io:: default_read_buf ( |b| self . read_at ( b, offset) , buf)
169
+ }
170
+
171
+ /// Reads the exact number of bytes required to fill the buffer from a given
172
+ /// offset.
173
+ ///
174
+ /// This is equivalent to the [`read_exact_at`](FileExt::read_exact_at) method,
175
+ /// except that it is passed a [`BorrowedCursor`] rather than `&mut [u8]` to allow
176
+ /// use with uninitialized buffers. The new data will be appended to any
177
+ /// existing contents of `buf`.
178
+ ///
179
+ /// # Examples
180
+ ///
181
+ /// ```no_run
182
+ /// #![feature(core_io_borrowed_buf)]
183
+ /// #![feature(read_buf_at)]
184
+ ///
185
+ /// use std::io;
186
+ /// use std::io::BorrowedBuf;
187
+ /// use std::fs::File;
188
+ /// use std::mem::MaybeUninit;
189
+ /// use std::os::unix::prelude::*;
190
+ ///
191
+ /// fn main() -> io::Result<()> {
192
+ /// let mut file = File::open("pi.txt")?;
193
+ ///
194
+ /// // Read exactly 10 bytes starting from offset 2
195
+ /// let mut buf: [MaybeUninit<u8>; 10] = [MaybeUninit::uninit(); 10];
196
+ /// let mut buf = BorrowedBuf::from(buf.as_mut_slice());
197
+ /// file.read_buf_exact_at(buf.unfilled(), 2)?;
198
+ ///
199
+ /// assert_eq!(buf.filled(), b"1415926535");
200
+ ///
201
+ /// Ok(())
202
+ /// }
203
+ /// ```
204
+ #[ unstable( feature = "read_buf_at" , issue = "140771" ) ]
205
+ fn read_buf_exact_at ( & self , mut buf : BorrowedCursor < ' _ > , mut offset : u64 ) -> io:: Result < ( ) > {
206
+ while buf. capacity ( ) > 0 {
207
+ let prev_written = buf. written ( ) ;
208
+ match self . read_buf_at ( buf. reborrow ( ) , offset) {
209
+ Ok ( ( ) ) => { }
210
+ Err ( e) if e. is_interrupted ( ) => { }
211
+ Err ( e) => return Err ( e) ,
212
+ }
213
+ let n = buf. written ( ) - prev_written;
214
+ offset += n as u64 ;
215
+ if n == 0 {
216
+ return Err ( io:: Error :: READ_EXACT_EOF ) ;
217
+ }
218
+ }
219
+ Ok ( ( ) )
220
+ }
221
+
133
222
/// Writes a number of bytes starting from a given offset.
134
223
///
135
224
/// Returns the number of bytes written.
@@ -264,6 +353,9 @@ impl FileExt for fs::File {
264
353
fn read_at ( & self , buf : & mut [ u8 ] , offset : u64 ) -> io:: Result < usize > {
265
354
self . as_inner ( ) . read_at ( buf, offset)
266
355
}
356
+ fn read_buf_at ( & self , buf : BorrowedCursor < ' _ > , offset : u64 ) -> io:: Result < ( ) > {
357
+ self . as_inner ( ) . read_buf_at ( buf, offset)
358
+ }
267
359
fn read_vectored_at ( & self , bufs : & mut [ io:: IoSliceMut < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
268
360
self . as_inner ( ) . read_vectored_at ( bufs, offset)
269
361
}
0 commit comments