cl_generic_read_buf/
lib.rs

1//! ReadBuf types and methods. See https://github.com/rust-lang/rust/issues/78485
2
3use cl_generic_vec::{raw::Storage, ArrayVec, HeapVec, SimpleVec, SliceVec};
4use std::{cmp, fmt, io, mem::MaybeUninit, ops::Deref};
5
6/// A [`Storage`] of [`u8`]s
7pub trait Bytes: Storage<Item = u8> {}
8impl<S: Storage<Item = u8>> Bytes for S {}
9
10/// A wrapper over [`io::Read`] to provide the custom read_buf* methods on stable
11pub trait Read: io::Read {
12    /// Pull some bytes from this source into the specified buffer.
13    ///
14    /// This is equivalent to the [`read`](io::Read::read) method, except that it is passed a [`ReadBufRef`] rather than `[u8]` to allow use
15    /// with uninitialized buffers. The new data will be appended to any existing contents of `buf`.
16    ///
17    /// The default implementation delegates to `read`.
18    fn read_buf(&mut self, buf: ReadBufRef<'_, impl Bytes>) -> io::Result<()> {
19        default_read_buf(|b| self.read(b), buf)
20    }
21
22    /// Read the exact number of bytes required to fill `buf`.
23    ///
24    /// This is equivalent to the [`read_exact`](io::Read::read_exact) method, except that it is passed a [`ReadBufRef`] rather than `[u8]` to
25    /// allow use with uninitialized buffers.
26    fn read_buf_exact(&mut self, mut buf: ReadBufRef<'_, impl Bytes>) -> io::Result<()> {
27        while buf.remaining() > 0 {
28            let prev_filled = buf.filled().len();
29            match Read::read_buf(self, buf.reborrow()) {
30                Ok(()) => {}
31                Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
32                Err(e) => return Err(e),
33            }
34
35            if buf.filled().len() == prev_filled {
36                return Err(io::Error::new(
37                    io::ErrorKind::UnexpectedEof,
38                    "failed to fill buffer",
39                ));
40            }
41        }
42
43        Ok(())
44    }
45}
46
47impl<R: io::Read> Read for R {}
48
49pub(crate) fn default_read_buf<F>(read: F, mut buf: ReadBufRef<'_, impl Bytes>) -> io::Result<()>
50where
51    F: FnOnce(&mut [u8]) -> io::Result<usize>,
52{
53    let n = read(buf.initialize_unfilled())?;
54    buf.add_filled(n);
55    Ok(())
56}
57
58/// A wrapper around a byte buffer that is incrementally filled and initialized.
59///
60/// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the
61/// buffer that has been logically filled with data, a region that has been initialized at some point but not yet
62/// logically filled, and a region at the end that is fully uninitialized. The filled region is guaranteed to be a
63/// subset of the initialized region.
64///
65/// In summary, the contents of the buffer can be visualized as:
66/// ```not_rust
67/// [             capacity              ]
68/// [ filled |         unfilled         ]
69/// [    initialized    | uninitialized ]
70/// ```
71pub struct ReadBuf<S: Bytes> {
72    filled: usize,
73    buf: SimpleVec<S>,
74}
75
76impl<S: Bytes> fmt::Debug for ReadBuf<S> {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        f.debug_struct("ReadBuf")
79            .field("init", &self.buf.len())
80            .field("filled", &self.filled)
81            .field("capacity", &self.buf.capacity())
82            .finish()
83    }
84}
85
86/// A [`ReadBuf`] that takes it's buffer from an existing slice
87pub type ReadSlice<'a> = ReadBuf<&'a mut [MaybeUninit<u8>]>;
88/// A [`ReadBuf`] that owns it's buffer using a [`Vec<u8>`]
89pub type ReadVec = ReadBuf<Box<[MaybeUninit<u8>]>>;
90/// A [`ReadBuf`] that owns it's buffer using a [`[MaybeUninit<u8>; N]`](array)
91pub type ReadArray<const N: usize> = ReadBuf<[MaybeUninit<u8>; N]>;
92
93impl<const N: usize> ReadArray<N> {
94    /// Create a new uninitialised [`ReadBuf`] backed by an array
95    /// Will begin with 0 filled bytes.
96    pub fn new_uninit_array() -> Self {
97        Self {
98            filled: 0,
99            buf: ArrayVec::new(),
100        }
101    }
102}
103
104/// Create a [`ReadBuf`] from a fully initialised array of bytes.
105/// Will begin with 0 filled bytes.
106impl<const N: usize> From<[u8; N]> for ReadArray<N> {
107    fn from(buf: [u8; N]) -> Self {
108        ReadBuf {
109            filled: 0,
110            buf: ArrayVec::from_array(buf),
111        }
112    }
113}
114
115/// Create a [`ReadBuf`] from a partially initialised vec of bytes.
116/// Will begin with 0 filled bytes.
117impl From<Vec<u8>> for ReadVec {
118    fn from(buf: Vec<u8>) -> Self {
119        ReadBuf {
120            filled: 0,
121            buf: buf.into(),
122        }
123    }
124}
125
126/// Create a [`ReadBuf`] from an uninitialised boxed-slice of bytes.
127/// Will begin with 0 filled bytes.
128impl From<Box<[MaybeUninit<u8>]>> for ReadVec {
129    fn from(buf: Box<[MaybeUninit<u8>]>) -> Self {
130        ReadBuf {
131            filled: 0,
132            buf: HeapVec::with_storage(buf),
133        }
134    }
135}
136
137/// Create a [`ReadBuf`] from an initialised slice of bytes.
138/// Will begin with 0 filled bytes.
139impl<'a> From<&'a mut [u8]> for ReadSlice<'a> {
140    fn from(buf: &'a mut [u8]) -> Self {
141        ReadBuf {
142            filled: 0,
143            buf: SliceVec::full(buf),
144        }
145    }
146}
147
148/// Create a [`ReadBuf`] from an uninitialised slice of bytes.
149/// Will begin with 0 filled bytes.
150impl<'a> From<&'a mut [MaybeUninit<u8>]> for ReadSlice<'a> {
151    fn from(buf: &'a mut [MaybeUninit<u8>]) -> Self {
152        ReadBuf {
153            filled: 0,
154            buf: unsafe { SliceVec::new(buf) },
155        }
156    }
157}
158
159impl<S: Bytes> ReadBuf<S> {
160    /// Extract the bytes from the [`ReadBuf`]
161    pub fn into_inner(self) -> SimpleVec<S> {
162        assert_eq!(self.filled, self.buf.len());
163        self.buf
164    }
165
166    /// Creates a new [`ReadBufRef`] referencing this `ReadBuf`.
167    #[inline]
168    pub fn borrow(&mut self) -> ReadBufRef<'_, S> {
169        ReadBufRef { read_buf: self }
170    }
171
172    /// Returns the total capacity of the buffer.
173    #[inline]
174    pub fn capacity(&self) -> usize {
175        self.buf.capacity()
176    }
177
178    /// Returns a shared reference to the filled portion of the buffer.
179    #[inline]
180    pub fn filled(&self) -> &[u8] {
181        &self.buf[..self.filled]
182    }
183
184    /// Returns a mutable reference to the filled portion of the buffer.
185    #[inline]
186    pub fn filled_mut(&mut self) -> &mut [u8] {
187        &mut self.buf[..self.filled]
188    }
189
190    /// Returns a shared reference to the initialized portion of the buffer.
191    ///
192    /// This includes the filled portion.
193    #[inline]
194    pub fn initialized(&self) -> &[u8] {
195        self.buf.as_slice()
196    }
197
198    /// Returns a mutable reference to the initialized portion of the buffer.
199    ///
200    /// This includes the filled portion.
201    #[inline]
202    pub fn initialized_mut(&mut self) -> &mut [u8] {
203        self.buf.as_mut_slice()
204    }
205
206    /// Returns a mutable reference to the unfilled part of the buffer without ensuring that it has been fully
207    /// initialized.
208    ///
209    /// # Safety
210    ///
211    /// The caller must not de-initialize portions of the buffer that have already been initialized.
212    #[inline]
213    pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
214        &mut self.buf.storage_mut().as_mut()[self.filled..]
215    }
216
217    /// Returns a mutable reference to the uninitialized part of the buffer.
218    ///
219    /// It is safe to uninitialize any of these bytes.
220    #[inline]
221    pub fn uninitialized_mut(&mut self) -> &mut [MaybeUninit<u8>] {
222        self.buf.spare_capacity_mut()
223    }
224
225    /// Returns a mutable reference to the unfilled part of the buffer, ensuring it is fully initialized.
226    ///
227    /// Since `ReadBuf` tracks the region of the buffer that has been initialized, this is effectively "free" after
228    /// the first use.
229    #[inline]
230    pub fn initialize_unfilled(&mut self) -> &mut [u8] {
231        // should optimize out the assertion
232        self.initialize_unfilled_to(self.remaining())
233    }
234
235    /// Returns a mutable reference to the first `n` bytes of the unfilled part of the buffer, ensuring it is
236    /// fully initialized.
237    ///
238    /// # Panics
239    ///
240    /// Panics if `self.remaining()` is less than `n`.
241    #[inline]
242    pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
243        assert!(self.remaining() >= n);
244
245        let extra_init = self.buf.len() - self.filled;
246        // If we don't have enough initialized, do zeroing
247        if n > extra_init {
248            let uninit = n - extra_init;
249            let unfilled = &mut self.uninitialized_mut()[0..uninit];
250
251            for byte in unfilled.iter_mut() {
252                byte.write(0);
253            }
254
255            // SAFETY: we just initialized uninit bytes, and the previous bytes were already init
256            unsafe {
257                self.assume_init(n);
258            }
259        }
260
261        let filled = self.filled;
262
263        &mut self.initialized_mut()[filled..filled + n]
264    }
265
266    /// Returns the number of bytes at the end of the slice that have not yet been filled.
267    #[inline]
268    pub fn remaining(&self) -> usize {
269        self.capacity() - self.filled
270    }
271
272    /// Clears the buffer, resetting the filled region to empty.
273    ///
274    /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
275    #[inline]
276    pub fn clear(&mut self) {
277        self.set_filled(0); // The assertion in `set_filled` is optimized out
278    }
279
280    /// Increases the size of the filled region of the buffer.
281    ///
282    /// The number of initialized bytes is not changed.
283    ///
284    /// # Panics
285    ///
286    /// Panics if the filled region of the buffer would become larger than the initialized region.
287    #[inline]
288    pub fn add_filled(&mut self, n: usize) {
289        self.set_filled(self.filled + n);
290    }
291
292    /// Sets the size of the filled region of the buffer.
293    ///
294    /// The number of initialized bytes is not changed.
295    ///
296    /// Note that this can be used to *shrink* the filled region of the buffer in addition to growing it (for
297    /// example, by a `Read` implementation that compresses data in-place).
298    ///
299    /// # Panics
300    ///
301    /// Panics if the filled region of the buffer would become larger than the initialized region.
302    #[inline]
303    pub fn set_filled(&mut self, n: usize) {
304        assert!(n <= self.buf.len());
305
306        self.filled = n;
307    }
308
309    /// Asserts that the first `n` unfilled bytes of the buffer are initialized.
310    ///
311    /// `ReadBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
312    /// bytes than are already known to be initialized.
313    ///
314    /// # Safety
315    ///
316    /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
317    #[inline]
318    pub unsafe fn assume_init(&mut self, n: usize) {
319        self.buf
320            .set_len_unchecked(cmp::max(self.buf.len(), self.filled + n));
321    }
322
323    /// Appends data to the buffer, advancing the written position and possibly also the initialized position.
324    ///
325    /// # Panics
326    ///
327    /// Panics if `self.remaining()` is less than `buf.len()`.
328    #[inline]
329    pub fn append(&mut self, buf: &[u8]) {
330        assert!(self.remaining() >= buf.len());
331
332        // SAFETY: we do not de-initialize any of the elements of the slice
333        unsafe {
334            write_slice(&mut self.unfilled_mut()[..buf.len()], buf);
335        }
336
337        // SAFETY: We just added the entire contents of buf to the filled section.
338        unsafe { self.assume_init(buf.len()) }
339        self.add_filled(buf.len());
340    }
341
342    /// Returns the amount of bytes that have been filled.
343    #[inline]
344    pub fn filled_len(&self) -> usize {
345        self.filled
346    }
347
348    /// Returns the amount of bytes that have been initialized.
349    #[inline]
350    pub fn initialized_len(&self) -> usize {
351        self.buf.len()
352    }
353}
354
355// from MaybeUninit::write_slice
356unsafe fn write_slice<T>(this: &mut [MaybeUninit<T>], src: &[T])
357where
358    T: Copy,
359{
360    // SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
361    let uninit_src: &[MaybeUninit<T>] = core::mem::transmute(src);
362
363    this.copy_from_slice(uninit_src);
364}
365
366/// A wrapper around [`&mut ReadBuf`](ReadBuf) which prevents the buffer that the [`ReadBuf`] points to from being replaced.
367#[derive(Debug)]
368pub struct ReadBufRef<'a, S: Bytes> {
369    read_buf: &'a mut ReadBuf<S>,
370}
371
372impl<'a, S: Bytes> ReadBufRef<'a, S> {
373    /// Creates a new `ReadBufRef` referencing the same `ReadBuf` as this one.
374    pub fn reborrow(&mut self) -> ReadBufRef<'_, S> {
375        ReadBufRef {
376            read_buf: self.read_buf,
377        }
378    }
379
380    /// Returns a mutable reference to the filled portion of the buffer.
381    #[inline]
382    pub fn filled_mut(&mut self) -> &mut [u8] {
383        self.read_buf.filled_mut()
384    }
385
386    /// Returns a mutable reference to the initialized portion of the buffer.
387    ///
388    /// This includes the filled portion.
389    #[inline]
390    pub fn initialized_mut(&mut self) -> &mut [u8] {
391        self.read_buf.initialized_mut()
392    }
393
394    /// Returns a mutable reference to the unfilled part of the buffer without ensuring that it has been fully
395    /// initialized.
396    ///
397    /// # Safety
398    ///
399    /// The caller must not de-initialize portions of the buffer that have already been initialized.
400    #[inline]
401    pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
402        self.read_buf.unfilled_mut()
403    }
404
405    /// Returns a mutable reference to the uninitialized part of the buffer.
406    ///
407    /// It is safe to uninitialize any of these bytes.
408    #[inline]
409    pub fn uninitialized_mut(&mut self) -> &mut [MaybeUninit<u8>] {
410        self.read_buf.uninitialized_mut()
411    }
412
413    /// Returns a mutable reference to the unfilled part of the buffer, ensuring it is fully initialized.
414    ///
415    /// Since `ReadBuf` tracks the region of the buffer that has been initialized, this is effectively "free" after
416    /// the first use.
417    #[inline]
418    pub fn initialize_unfilled(&mut self) -> &mut [u8] {
419        self.read_buf.initialize_unfilled()
420    }
421
422    /// Returns a mutable reference to the first `n` bytes of the unfilled part of the buffer, ensuring it is
423    /// fully initialized.
424    ///
425    /// # Panics
426    ///
427    /// Panics if `self.remaining()` is less than `n`.
428    #[inline]
429    pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
430        self.read_buf.initialize_unfilled_to(n)
431    }
432
433    /// Clears the buffer, resetting the filled region to empty.
434    ///
435    /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
436    #[inline]
437    pub fn clear(&mut self) {
438        self.read_buf.clear()
439    }
440
441    /// Increases the size of the filled region of the buffer.
442    ///
443    /// The number of initialized bytes is not changed.
444    ///
445    /// # Panics
446    ///
447    /// Panics if the filled region of the buffer would become larger than the initialized region.
448    #[inline]
449    pub fn add_filled(&mut self, n: usize) {
450        self.read_buf.add_filled(n)
451    }
452
453    /// Sets the size of the filled region of the buffer.
454    ///
455    /// The number of initialized bytes is not changed.
456    ///
457    /// Note that this can be used to *shrink* the filled region of the buffer in addition to growing it (for
458    /// example, by a `Read` implementation that compresses data in-place).
459    ///
460    /// # Panics
461    ///
462    /// Panics if the filled region of the buffer would become larger than the initialized region.
463    #[inline]
464    pub fn set_filled(&mut self, n: usize) {
465        self.read_buf.set_filled(n)
466    }
467
468    /// Asserts that the first `n` unfilled bytes of the buffer are initialized.
469    ///
470    /// `ReadBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
471    /// bytes than are already known to be initialized.
472    ///
473    /// # Safety
474    ///
475    /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
476    #[inline]
477    pub unsafe fn assume_init(&mut self, n: usize) {
478        self.read_buf.assume_init(n)
479    }
480
481    /// Appends data to the buffer, advancing the written position and possibly also the initialized position.
482    ///
483    /// # Panics
484    ///
485    /// Panics if `self.remaining()` is less than `buf.len()`.
486    #[inline]
487    pub fn append(&mut self, buf: &[u8]) {
488        self.read_buf.append(buf)
489    }
490}
491
492impl<'a, S: Bytes> Deref for ReadBufRef<'a, S> {
493    type Target = ReadBuf<S>;
494
495    fn deref(&self) -> &ReadBuf<S> {
496        &*self.read_buf
497    }
498}