22
33use crate :: fmt:: { self , Debug , Formatter } ;
44use crate :: mem:: { self , MaybeUninit } ;
5- use crate :: { cmp, ptr} ;
65
7- /// A borrowed byte buffer which is incrementally filled and initialized .
6+ /// A borrowed buffer of initially uninitialized bytes, which is incrementally filled.
87///
9- /// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the
10- /// buffer that has been logically filled with data, a region that has been initialized at some point but not yet
11- /// logically filled, and a region at the end that is fully uninitialized. The filled region is guaranteed to be a
12- /// subset of the initialized region.
8+ /// This type makes it safer to work with `MaybeUninit` buffers, such as to read into a buffer
9+ /// without having to initialize it first. It tracks the region of bytes that have been filled and
10+ /// the region that remains uninitialized.
1311///
14- /// In summary, the contents of the buffer can be visualized as:
12+ /// The contents of the buffer can be visualized as:
1513/// ```not_rust
16- /// [ capacity ]
17- /// [ filled | unfilled ]
18- /// [ initialized | uninitialized ]
14+ /// [ capacity ]
15+ /// [ len: filled and initialized | capacity - len: uninitialized ]
1916/// ```
2017///
21- /// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference
22- /// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be
23- /// directly written. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
24- /// has write-only access to the unfilled portion of the buffer (you can think of it as a
25- /// write-only iterator).
18+ /// Note that `BorrowedBuf` does not distinguish between uninitialized data and data that was
19+ /// previously initialized but no longer contains valid data.
20+ ///
21+ /// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique
22+ /// reference (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_len`), but
23+ /// cannot be directly written. To write into the buffer, use `unfilled` to create a
24+ /// `BorrowedCursor`. The cursor has write-only access to the unfilled portion of the buffer.
2625///
2726/// The lifetime `'data` is a bound on the lifetime of the underlying data.
2827pub struct BorrowedBuf < ' data > {
2928 /// The buffer's underlying data.
3029 buf : & ' data mut [ MaybeUninit < u8 > ] ,
3130 /// The length of `self.buf` which is known to be filled.
3231 filled : usize ,
33- /// The length of `self.buf` which is known to be initialized.
34- init : usize ,
3532}
3633
3734impl Debug for BorrowedBuf < ' _ > {
3835 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
3936 f. debug_struct ( "BorrowedBuf" )
40- . field ( "init" , & self . init )
4137 . field ( "filled" , & self . filled )
4238 . field ( "capacity" , & self . capacity ( ) )
4339 . finish ( )
@@ -48,24 +44,22 @@ impl Debug for BorrowedBuf<'_> {
4844impl < ' data > From < & ' data mut [ u8 ] > for BorrowedBuf < ' data > {
4945 #[ inline]
5046 fn from ( slice : & ' data mut [ u8 ] ) -> BorrowedBuf < ' data > {
51- let len = slice. len ( ) ;
52-
5347 BorrowedBuf {
54- // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
48+ // SAFETY: Always in bounds. We treat the buffer as uninitialized, even though it's
49+ // already initialized.
5550 buf : unsafe { ( slice as * mut [ u8 ] ) . as_uninit_slice_mut ( ) . unwrap ( ) } ,
5651 filled : 0 ,
57- init : len,
5852 }
5953 }
6054}
6155
6256/// Creates a new `BorrowedBuf` from an uninitialized buffer.
6357///
64- /// Use `set_init ` if part of the buffer is known to be already initialized .
58+ /// Use `set_filled ` if part of the buffer is known to be already filled .
6559impl < ' data > From < & ' data mut [ MaybeUninit < u8 > ] > for BorrowedBuf < ' data > {
6660 #[ inline]
6761 fn from ( buf : & ' data mut [ MaybeUninit < u8 > ] ) -> BorrowedBuf < ' data > {
68- BorrowedBuf { buf, filled : 0 , init : 0 }
62+ BorrowedBuf { buf, filled : 0 }
6963 }
7064}
7165
@@ -74,14 +68,11 @@ impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
7468/// Use `BorrowedCursor::with_unfilled_buf` instead for a safer alternative.
7569impl < ' data > From < BorrowedCursor < ' data > > for BorrowedBuf < ' data > {
7670 #[ inline]
77- fn from ( mut buf : BorrowedCursor < ' data > ) -> BorrowedBuf < ' data > {
78- let init = buf. init_mut ( ) . len ( ) ;
71+ fn from ( buf : BorrowedCursor < ' data > ) -> BorrowedBuf < ' data > {
7972 BorrowedBuf {
80- // SAFETY: no initialized byte is ever uninitialized as per
81- // `BorrowedBuf`'s invariant
73+ // SAFETY: Always in bounds. We treat the buffer as uninitialized.
8274 buf : unsafe { buf. buf . buf . get_unchecked_mut ( buf. buf . filled ..) } ,
8375 filled : 0 ,
84- init,
8576 }
8677 }
8778}
@@ -99,12 +90,6 @@ impl<'data> BorrowedBuf<'data> {
9990 self . filled
10091 }
10192
102- /// Returns the length of the initialized part of the buffer.
103- #[ inline]
104- pub fn init_len ( & self ) -> usize {
105- self . init
106- }
107-
10893 /// Returns a shared reference to the filled portion of the buffer.
10994 #[ inline]
11095 pub fn filled ( & self ) -> & [ u8 ] {
@@ -159,33 +144,16 @@ impl<'data> BorrowedBuf<'data> {
159144
160145 /// Clears the buffer, resetting the filled region to empty.
161146 ///
162- /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
147+ /// The contents of the buffer are not modified.
163148 #[ inline]
164149 pub fn clear ( & mut self ) -> & mut Self {
165150 self . filled = 0 ;
166151 self
167152 }
168-
169- /// Asserts that the first `n` bytes of the buffer are initialized.
170- ///
171- /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
172- /// bytes than are already known to be initialized.
173- ///
174- /// # Safety
175- ///
176- /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
177- #[ inline]
178- pub unsafe fn set_init ( & mut self , n : usize ) -> & mut Self {
179- self . init = cmp:: max ( self . init , n) ;
180- self
181- }
182153}
183154
184155/// A writeable view of the unfilled portion of a [`BorrowedBuf`].
185156///
186- /// The unfilled portion consists of an initialized and an uninitialized part; see [`BorrowedBuf`]
187- /// for details.
188- ///
189157/// Data can be written directly to the cursor by using [`append`](BorrowedCursor::append) or
190158/// indirectly by getting a slice of part or all of the cursor and writing into the slice. In the
191159/// indirect case, the caller must call [`advance`](BorrowedCursor::advance) after writing to inform
@@ -238,48 +206,13 @@ impl<'a> BorrowedCursor<'a> {
238206 self . buf . filled
239207 }
240208
241- /// Returns a mutable reference to the initialized portion of the cursor.
242- #[ inline]
243- pub fn init_mut ( & mut self ) -> & mut [ u8 ] {
244- // SAFETY: We only slice the initialized part of the buffer, which is always valid
245- unsafe {
246- let buf = self . buf . buf . get_unchecked_mut ( self . buf . filled ..self . buf . init ) ;
247- buf. assume_init_mut ( )
248- }
249- }
250-
251209 /// Returns a mutable reference to the whole cursor.
252- ///
253- /// # Safety
254- ///
255- /// The caller must not uninitialize any bytes in the initialized portion of the cursor.
256210 #[ inline]
257- pub unsafe fn as_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] {
211+ pub fn as_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] {
258212 // SAFETY: always in bounds
259213 unsafe { self . buf . buf . get_unchecked_mut ( self . buf . filled ..) }
260214 }
261215
262- /// Advances the cursor by asserting that `n` bytes have been filled.
263- ///
264- /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be
265- /// accessed via the underlying buffer. I.e., the buffer's filled portion grows by `n` elements
266- /// and its unfilled portion (and the capacity of this cursor) shrinks by `n` elements.
267- ///
268- /// If less than `n` bytes initialized (by the cursor's point of view), `set_init` should be
269- /// called first.
270- ///
271- /// # Panics
272- ///
273- /// Panics if there are less than `n` bytes initialized.
274- #[ inline]
275- pub fn advance ( & mut self , n : usize ) -> & mut Self {
276- // The subtraction cannot underflow by invariant of this type.
277- assert ! ( n <= self . buf. init - self . buf. filled) ;
278-
279- self . buf . filled += n;
280- self
281- }
282-
283216 /// Advances the cursor by asserting that `n` bytes have been filled.
284217 ///
285218 /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be
@@ -288,42 +221,11 @@ impl<'a> BorrowedCursor<'a> {
288221 ///
289222 /// # Safety
290223 ///
291- /// The caller must ensure that the first `n` bytes of the cursor have been properly
292- /// initialised .
224+ /// The caller must ensure that the first `n` bytes of the cursor have been initialized. `n`
225+ /// must not exceed the remaining capacity of this cursor .
293226 #[ inline]
294- pub unsafe fn advance_unchecked ( & mut self , n : usize ) -> & mut Self {
227+ pub unsafe fn advance ( & mut self , n : usize ) -> & mut Self {
295228 self . buf . filled += n;
296- self . buf . init = cmp:: max ( self . buf . init , self . buf . filled ) ;
297- self
298- }
299-
300- /// Initializes all bytes in the cursor.
301- #[ inline]
302- pub fn ensure_init ( & mut self ) -> & mut Self {
303- // SAFETY: always in bounds and we never uninitialize these bytes.
304- let uninit = unsafe { self . buf . buf . get_unchecked_mut ( self . buf . init ..) } ;
305-
306- // SAFETY: 0 is a valid value for MaybeUninit<u8> and the length matches the allocation
307- // since it is comes from a slice reference.
308- unsafe {
309- ptr:: write_bytes ( uninit. as_mut_ptr ( ) , 0 , uninit. len ( ) ) ;
310- }
311- self . buf . init = self . buf . capacity ( ) ;
312-
313- self
314- }
315-
316- /// Asserts that the first `n` unfilled bytes of the cursor are initialized.
317- ///
318- /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when
319- /// called with fewer bytes than are already known to be initialized.
320- ///
321- /// # Safety
322- ///
323- /// The caller must ensure that the first `n` bytes of the buffer have already been initialized.
324- #[ inline]
325- pub unsafe fn set_init ( & mut self , n : usize ) -> & mut Self {
326- self . buf . init = cmp:: max ( self . buf . init , self . buf . filled + n) ;
327229 self
328230 }
329231
@@ -335,16 +237,7 @@ impl<'a> BorrowedCursor<'a> {
335237 #[ inline]
336238 pub fn append ( & mut self , buf : & [ u8 ] ) {
337239 assert ! ( self . capacity( ) >= buf. len( ) ) ;
338-
339- // SAFETY: we do not de-initialize any of the elements of the slice
340- unsafe {
341- self . as_mut ( ) [ ..buf. len ( ) ] . write_copy_of_slice ( buf) ;
342- }
343-
344- // SAFETY: We just added the entire contents of buf to the filled section.
345- unsafe {
346- self . set_init ( buf. len ( ) ) ;
347- }
240+ self . as_mut ( ) [ ..buf. len ( ) ] . write_copy_of_slice ( buf) ;
348241 self . buf . filled += buf. len ( ) ;
349242 }
350243
@@ -367,17 +260,9 @@ impl<'a> BorrowedCursor<'a> {
367260 // there, one could mark some bytes as initialized even though there aren't.
368261 assert ! ( core:: ptr:: addr_eq( prev_ptr, buf. buf) ) ;
369262
370- let filled = buf. filled ;
371- let init = buf. init ;
372-
373- // Update `init` and `filled` fields with what was written to the buffer.
374- // `self.buf.filled` was the starting length of the `BorrowedBuf`.
375- //
376- // SAFETY: These amounts of bytes were initialized/filled in the `BorrowedBuf`,
377- // and therefore they are initialized/filled in the cursor too, because the
378- // buffer wasn't replaced.
379- self . buf . init = self . buf . filled + init;
380- self . buf . filled += filled;
263+ // SAFETY: These bytes were filled in the `BorrowedBuf`, so they're filled in the cursor
264+ // too, because the buffer wasn't replaced.
265+ self . buf . filled += buf. filled ;
381266
382267 res
383268 }
0 commit comments