@@ -11,6 +11,7 @@ use super::platform::fs::MetadataExt as _;
1111// Used for `File::read` on intra-doc links
1212use crate :: ffi:: OsStr ;
1313use crate :: fs:: { self , OpenOptions , Permissions } ;
14+ use crate :: io:: BorrowedCursor ;
1415use crate :: os:: unix:: io:: { AsFd , AsRawFd } ;
1516use crate :: path:: Path ;
1617use crate :: sealed:: Sealed ;
@@ -130,6 +131,94 @@ pub trait FileExt {
130131 if !buf. is_empty ( ) { Err ( io:: Error :: READ_EXACT_EOF ) } else { Ok ( ( ) ) }
131132 }
132133
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+
133222 /// Writes a number of bytes starting from a given offset.
134223 ///
135224 /// Returns the number of bytes written.
@@ -264,6 +353,9 @@ impl FileExt for fs::File {
264353 fn read_at ( & self , buf : & mut [ u8 ] , offset : u64 ) -> io:: Result < usize > {
265354 self . as_inner ( ) . read_at ( buf, offset)
266355 }
356+ fn read_buf_at ( & self , buf : BorrowedCursor < ' _ > , offset : u64 ) -> io:: Result < ( ) > {
357+ self . as_inner ( ) . read_buf_at ( buf, offset)
358+ }
267359 fn read_vectored_at ( & self , bufs : & mut [ io:: IoSliceMut < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
268360 self . as_inner ( ) . read_vectored_at ( bufs, offset)
269361 }
0 commit comments