Skip to main content

qubit_io/std_io/ext/
read_ext.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! Extension operations for standard byte readers.
10
11use std::io::{
12    ErrorKind,
13    Read,
14    Result,
15    Write,
16    copy as copy_all,
17};
18
19use crate::Streams;
20use crate::std_io::ext::internal::read_ext_impl;
21use crate::util::{
22    SliceRange,
23    UncheckedSlice,
24};
25use crate::util::{
26    allocation_error,
27    try_reserve_string,
28};
29
30/// Default stack buffer size used by discard operations.
31const DISCARD_BUFFER_SIZE: usize = 8 * 1024;
32
33/// Extension methods for [`Read`] values.
34///
35/// `ReadExt` fills small semantic gaps in the standard [`Read`] trait while
36/// keeping the same blocking and error model. The methods are implemented for
37/// every type that implements [`Read`], including `dyn Read` trait objects.
38///
39/// # Examples
40/// ```
41/// use qubit_io::std_io::ext::ReadExt;
42/// use std::io::Cursor;
43///
44/// let mut input = Cursor::new(b"abcdef".to_vec());
45/// let header = input.read_exact_array::<2>()?;
46/// let payload = input.read_exact_vec_limited(4, 16)?;
47///
48/// assert_eq!(*b"ab", header);
49/// assert_eq!(b"cdef", payload.as_slice());
50/// # Ok::<(), std::io::Error>(())
51/// ```
52pub trait ReadExt: Read {
53    /// Reads bytes into a range of `buffer` without checking the range bounds
54    /// in release builds.
55    ///
56    /// This method delegates to [`Read::read`] after creating the target slice
57    /// with raw pointer arithmetic. It performs at most one read operation and
58    /// returns the number of bytes read, keeping the same short-read and error
59    /// behavior as [`Read::read`].
60    ///
61    /// # Parameters
62    /// - `buffer`: Destination buffer.
63    /// - `start_index`: Start offset inside `buffer`.
64    /// - `count`: Maximum number of bytes to read.
65    ///
66    /// # Returns
67    /// The number of bytes written into `buffer[start_index..start_index +
68    /// count]`. The value is in `0..=count`.
69    ///
70    /// # Errors
71    /// Returns the error reported by [`Read::read`].
72    ///
73    /// # Panics
74    /// Panics in debug builds if the requested destination range does not fit.
75    ///
76    /// # Safety
77    /// The caller must guarantee that `start_index..start_index + count` is a
78    /// valid range within `buffer` and that `start_index + count` does not
79    /// overflow `usize`.
80    unsafe fn read_unchecked(
81        &mut self,
82        buffer: &mut [u8],
83        start_index: usize,
84        count: usize,
85    ) -> Result<usize>;
86
87    /// Reads exactly `count` bytes into a range of `buffer` without checking
88    /// the range bounds in release builds.
89    ///
90    /// This method delegates to [`Read::read_exact`] after creating the target
91    /// slice with raw pointer arithmetic. It keeps the same blocking and error
92    /// behavior as [`Read::read_exact`].
93    ///
94    /// # Parameters
95    /// - `buffer`: Destination buffer.
96    /// - `start_index`: Start offset inside `buffer`.
97    /// - `count`: Number of bytes to read.
98    ///
99    /// # Returns
100    /// `Ok(())` after the requested range has been filled.
101    ///
102    /// # Errors
103    /// Returns the error reported by [`Read::read_exact`], including
104    /// [`ErrorKind::UnexpectedEof`] when EOF is reached before `count` bytes
105    /// are read.
106    ///
107    /// # Panics
108    /// Panics in debug builds if the requested destination range does not fit.
109    ///
110    /// # Safety
111    /// The caller must guarantee that `start_index..start_index + count` is a
112    /// valid range within `buffer` and that `start_index + count` does not
113    /// overflow `usize`.
114    unsafe fn read_exact_unchecked(
115        &mut self,
116        buffer: &mut [u8],
117        start_index: usize,
118        count: usize,
119    ) -> Result<()>;
120
121    /// Reads bytes into a range of `buffer` until that range is full or EOF is
122    /// reached, without checking the range bounds in release builds.
123    ///
124    /// This method has the same EOF and retry behavior as
125    /// [`ReadExt::read_exact_or_eof`], but writes into
126    /// `buffer[start_index..start_index + count]` using raw pointer
127    /// arithmetic.
128    ///
129    /// # Parameters
130    /// - `buffer`: Destination buffer.
131    /// - `start_index`: Start offset inside `buffer`.
132    /// - `count`: Number of bytes to try to read.
133    ///
134    /// # Returns
135    /// The number of bytes written into `buffer[start_index..start_index +
136    /// count]`. The value is in `0..=count`.
137    ///
138    /// # Errors
139    /// Returns the first non-[`ErrorKind::Interrupted`] error reported by the
140    /// underlying reader. Interrupted reads are retried.
141    ///
142    /// # Panics
143    /// Panics in debug builds if the requested destination range does not fit.
144    ///
145    /// # Safety
146    /// The caller must guarantee that `start_index..start_index + count` is a
147    /// valid range within `buffer` and that `start_index + count` does not
148    /// overflow `usize`.
149    unsafe fn read_exact_or_eof_unchecked(
150        &mut self,
151        buffer: &mut [u8],
152        start_index: usize,
153        count: usize,
154    ) -> Result<usize>;
155
156    /// Reads bytes until `buffer` is full or EOF is reached.
157    ///
158    /// This method differs from [`Read::read_exact`] by treating EOF as a
159    /// successful partial result. It keeps retrying short reads until the
160    /// caller-provided buffer is full, EOF is reached, or a non-interrupted
161    /// I/O error occurs.
162    ///
163    /// # Parameters
164    /// - `buffer`: Destination buffer to fill.
165    ///
166    /// # Returns
167    /// The number of bytes written into `buffer`. The value is in
168    /// `0..=buffer.len()`.
169    ///
170    /// # Errors
171    /// Returns the first non-[`ErrorKind::Interrupted`] error reported by the
172    /// underlying reader. Interrupted reads are retried.
173    fn read_exact_or_eof(&mut self, buffer: &mut [u8]) -> Result<usize>;
174
175    /// Reads exactly `N` bytes into a stack-allocated array.
176    ///
177    /// This method uses [`Read::read_exact`] and therefore requires the reader
178    /// to provide exactly `N` bytes before EOF.
179    ///
180    /// # Type Parameters
181    /// - `N`: Number of bytes in the returned array.
182    ///
183    /// # Returns
184    /// An array containing exactly `N` bytes read from this reader.
185    ///
186    /// # Errors
187    /// Returns the error reported by [`Read::read_exact`], including
188    /// [`ErrorKind::UnexpectedEof`] when EOF is reached before the array is
189    /// full.
190    fn read_exact_array<const N: usize>(&mut self) -> Result<[u8; N]>;
191
192    /// Reads exactly `len` bytes into a new vector after checking a limit.
193    ///
194    /// If `len` is greater than `max_len`, this method returns
195    /// [`ErrorKind::InvalidData`] before reading any bytes.
196    ///
197    /// # Parameters
198    /// - `len`: Exact number of bytes to read.
199    /// - `max_len`: Maximum accepted exact read length.
200    ///
201    /// # Returns
202    /// A vector containing exactly `len` bytes.
203    ///
204    /// # Errors
205    /// Returns [`ErrorKind::InvalidData`] when `len > max_len`. Returns the
206    /// [`ErrorKind::OutOfMemory`] error when the result vector cannot be
207    /// allocated. Returns the error reported by [`Read::read_exact`], including
208    /// [`ErrorKind::UnexpectedEof`] when EOF is reached before `len` bytes are
209    /// read.
210    fn read_exact_vec_limited(
211        &mut self,
212        len: usize,
213        max_len: usize,
214    ) -> Result<Vec<u8>>;
215
216    /// Reads exactly `len` bytes and appends them to `output`.
217    ///
218    /// If `len` is greater than `max_len`, this method returns
219    /// [`ErrorKind::InvalidData`] before reading any bytes and leaves `output`
220    /// unchanged. On a read error, `output` is truncated back to its original
221    /// length. The underlying reader may still have consumed bytes before the
222    /// error because [`Read`] does not provide rollback.
223    ///
224    /// # Parameters
225    /// - `output`: Destination vector to append to.
226    /// - `len`: Exact number of bytes to read.
227    /// - `max_len`: Maximum accepted exact read length.
228    ///
229    /// # Returns
230    /// `Ok(())` after exactly `len` bytes have been appended to `output`.
231    ///
232    /// # Errors
233    /// Returns [`ErrorKind::InvalidData`] when `len > max_len`,
234    /// [`ErrorKind::InvalidInput`] when `output.len() + len` overflows, or
235    /// [`ErrorKind::OutOfMemory`] when `output` cannot reserve the appended
236    /// bytes. Returns the error reported by [`Read::read_exact`], including
237    /// [`ErrorKind::UnexpectedEof`] when EOF is reached before `len` bytes are
238    /// read.
239    fn read_exact_vec_limited_into(
240        &mut self,
241        output: &mut Vec<u8>,
242        len: usize,
243        max_len: usize,
244    ) -> Result<()>;
245
246    /// Discards up to `bytes` bytes from this reader.
247    ///
248    /// The method repeatedly reads into an internal stack buffer until the
249    /// requested number of bytes has been consumed or EOF is reached. It does
250    /// not allocate and does not require seeking support.
251    ///
252    /// # Parameters
253    /// - `bytes`: Maximum number of bytes to discard.
254    ///
255    /// # Returns
256    /// The number of bytes actually discarded. The value may be smaller than
257    /// `bytes` when EOF is reached first.
258    ///
259    /// # Errors
260    /// Returns the first non-[`ErrorKind::Interrupted`] error reported by the
261    /// underlying reader. Interrupted reads are retried.
262    fn discard_exact_or_eof(&mut self, bytes: u64) -> Result<u64>;
263
264    /// Copies all remaining bytes from this reader into `writer`.
265    ///
266    /// This method is a method-style wrapper around [`std::io::copy`]. It
267    /// copies from the current reader position until EOF and does not close or
268    /// flush either stream.
269    ///
270    /// # Parameters
271    /// - `writer`: Destination writer.
272    ///
273    /// # Returns
274    /// The number of bytes copied.
275    ///
276    /// # Errors
277    /// Returns the first read or write error reported by the underlying
278    /// streams, using the same error behavior as [`std::io::copy`].
279    fn copy_to(&mut self, writer: &mut dyn Write) -> Result<u64>;
280
281    /// Copies at most `max_bytes` bytes from this reader into `writer`.
282    ///
283    /// This method stops successfully when either EOF is reached or
284    /// `max_bytes` bytes have been copied. It does not close or flush either
285    /// stream.
286    ///
287    /// # Parameters
288    /// - `writer`: Destination writer.
289    /// - `max_bytes`: Maximum number of bytes to copy.
290    ///
291    /// # Returns
292    /// The number of bytes copied.
293    ///
294    /// # Errors
295    /// Returns [`ErrorKind::OutOfMemory`] if the temporary copy buffer cannot
296    /// be allocated. Returns the first non-[`ErrorKind::Interrupted`] read
297    /// error or write error reported by the underlying streams. Interrupted
298    /// reads are retried.
299    fn copy_to_at_most(
300        &mut self,
301        writer: &mut dyn Write,
302        max_bytes: u64,
303    ) -> Result<u64>;
304
305    /// Copies the remaining input if its total length is at most `max_bytes`.
306    ///
307    /// This method copies from the current reader position until EOF. If EOF is
308    /// not reached within `max_bytes` bytes, it returns
309    /// [`ErrorKind::InvalidData`]. Detecting oversized input consumes one
310    /// excess byte from this reader; that excess byte is not written to
311    /// `writer`.
312    ///
313    /// Unlike bounded reads into in-memory collections, this method cannot roll
314    /// back bytes already accepted by `writer` when the limit is exceeded
315    /// because [`Write`] does not provide truncation. On
316    /// [`ErrorKind::InvalidData`], up to `max_bytes` bytes may remain in
317    /// `writer`.
318    ///
319    /// # Parameters
320    /// - `writer`: Destination writer.
321    /// - `max_bytes`: Maximum accepted number of bytes in the remaining input.
322    ///
323    /// # Returns
324    /// The number of bytes copied when EOF is reached within the limit.
325    ///
326    /// # Errors
327    /// Returns [`ErrorKind::InvalidData`] when the remaining input is longer
328    /// than `max_bytes`. Returns [`ErrorKind::OutOfMemory`] if the temporary
329    /// copy buffer cannot be allocated. Returns the first
330    /// non-[`ErrorKind::Interrupted`] read error or write error reported by the
331    /// underlying streams. Interrupted reads are retried.
332    fn copy_to_end_limited(
333        &mut self,
334        writer: &mut dyn Write,
335        max_bytes: u64,
336    ) -> Result<u64>;
337
338    /// Reads the remaining bytes into a vector with a maximum accepted length.
339    ///
340    /// This method consumes bytes from the current reader position until EOF is
341    /// reached. If the stream contains more than `max_len` bytes, it returns
342    /// [`ErrorKind::InvalidData`] after detecting the first excess byte. No
343    /// vector is returned on failure.
344    ///
345    /// # Parameters
346    /// - `max_len`: Maximum number of bytes accepted in the returned vector.
347    ///
348    /// # Returns
349    /// A vector containing all remaining bytes when the stream length is within
350    /// the limit.
351    ///
352    /// # Errors
353    /// Returns [`ErrorKind::InvalidData`] when the stream contains more than
354    /// `max_len` bytes. Returns [`ErrorKind::OutOfMemory`] when the result
355    /// vector cannot grow. Returns the first non-[`ErrorKind::Interrupted`]
356    /// error reported by the underlying reader; interrupted reads are
357    /// retried.
358    fn read_to_end_limited(&mut self, max_len: usize) -> Result<Vec<u8>>;
359
360    /// Reads the remaining bytes into `output` with a maximum accepted length.
361    ///
362    /// This method appends at most `max_len` bytes from the current reader
363    /// position to `output`. If the stream contains more than `max_len` bytes,
364    /// it returns [`ErrorKind::InvalidData`] after detecting the first excess
365    /// byte and truncates `output` back to its original length. The underlying
366    /// reader may still have consumed bytes before the error because [`Read`]
367    /// does not provide rollback.
368    ///
369    /// # Parameters
370    /// - `output`: Destination vector to append to.
371    /// - `max_len`: Maximum number of bytes accepted from this reader.
372    ///
373    /// # Returns
374    /// The number of bytes appended to `output`.
375    ///
376    /// # Errors
377    /// Returns [`ErrorKind::InvalidData`] when the stream contains more than
378    /// `max_len` bytes. Returns [`ErrorKind::OutOfMemory`] when `output` cannot
379    /// grow. Returns the first non-[`ErrorKind::Interrupted`] error reported by
380    /// the underlying reader; interrupted reads are retried.
381    fn read_to_end_limited_into(
382        &mut self,
383        output: &mut Vec<u8>,
384        max_len: usize,
385    ) -> Result<usize>;
386
387    /// Reads the remaining bytes as UTF-8 text with a maximum accepted length.
388    ///
389    /// This method has the same size limit and read semantics as
390    /// [`ReadExt::read_to_end_limited`], then validates the collected bytes as
391    /// UTF-8.
392    ///
393    /// # Parameters
394    /// - `max_len`: Maximum number of bytes accepted before UTF-8 decoding.
395    ///
396    /// # Returns
397    /// The decoded UTF-8 string.
398    ///
399    /// # Errors
400    /// Returns [`ErrorKind::InvalidData`] when the stream contains more than
401    /// `max_len` bytes or when the collected bytes are not valid UTF-8. Returns
402    /// [`ErrorKind::OutOfMemory`] when the result buffer cannot grow. Returns
403    /// the first non-[`ErrorKind::Interrupted`] error reported by the
404    /// underlying reader; interrupted reads are retried.
405    fn read_to_string_limited(&mut self, max_len: usize) -> Result<String>;
406
407    /// Reads the remaining bytes as UTF-8 text and appends to `output`.
408    ///
409    /// This method accepts at most `max_len` bytes from the current reader
410    /// position, validates them as UTF-8, and appends the decoded text to
411    /// `output`. If the input is oversized or invalid UTF-8, `output` is
412    /// truncated back to its original length. Oversized input may still consume
413    /// up to `max_len + 1` bytes from the reader while detecting the limit
414    /// violation.
415    ///
416    /// # Parameters
417    /// - `output`: Destination string to append to.
418    /// - `max_len`: Maximum number of bytes accepted before UTF-8 decoding.
419    ///
420    /// # Returns
421    /// The number of bytes appended to `output`.
422    ///
423    /// # Errors
424    /// Returns [`ErrorKind::InvalidData`] when the stream contains more than
425    /// `max_len` bytes or when the collected bytes are not valid UTF-8. Returns
426    /// [`ErrorKind::OutOfMemory`] when the temporary byte buffer or `output`
427    /// cannot grow. Returns the first non-[`ErrorKind::Interrupted`] error
428    /// reported by the underlying reader; interrupted reads are retried.
429    fn read_to_string_limited_into(
430        &mut self,
431        output: &mut String,
432        max_len: usize,
433    ) -> Result<usize>;
434}
435
436/// Reads an indexed range to EOF through a type-erased reader.
437///
438/// # Parameters
439/// - `reader`: Reader that supplies the bytes.
440/// - `buffer`: Destination buffer.
441/// - `start_index`: Start offset inside `buffer`.
442/// - `count`: Number of bytes to try to read.
443///
444/// # Returns
445/// The number of bytes written into the requested range.
446///
447/// # Errors
448/// Returns the first non-interrupted read error.
449///
450/// # Panics
451/// Panics in debug builds if the requested output range does not fit.
452///
453/// # Safety
454/// The caller must guarantee that `start_index..start_index + count` is valid
455/// inside `buffer` and that the addition does not overflow.
456unsafe fn read_exact_or_eof_unchecked_impl(
457    reader: &mut dyn Read,
458    buffer: &mut [u8],
459    start_index: usize,
460    count: usize,
461) -> Result<usize> {
462    debug_assert!(
463        SliceRange::range_fits(buffer.len(), start_index, count),
464        "unchecked read range exceeds buffer"
465    );
466    let mut total = 0;
467    while total < count {
468        // SAFETY: The caller guarantees that `start_index..start_index + count`
469        // is valid for `buffer`; `total < count`, so this suffix is valid.
470        let target = unsafe {
471            UncheckedSlice::subslice_mut(
472                buffer,
473                start_index + total,
474                count - total,
475            )
476        };
477        match reader.read(target) {
478            Ok(0) => break,
479            Ok(read) => total += read,
480            Err(error) => {
481                if error.kind() == ErrorKind::Interrupted {
482                    continue;
483                }
484                return Err(error);
485            }
486        }
487    }
488    Ok(total)
489}
490
491/// Reads a fixed-size byte array through a type-erased reader.
492///
493/// # Type Parameters
494/// - `N`: Number of bytes in the returned array.
495///
496/// # Parameters
497/// - `reader`: Reader that supplies the bytes.
498///
499/// # Returns
500/// An array containing exactly `N` bytes.
501///
502/// # Errors
503/// Returns the error reported by [`Read::read_exact`].
504#[inline]
505fn read_exact_array_impl<const N: usize>(
506    reader: &mut dyn Read,
507) -> Result<[u8; N]> {
508    let mut buffer = [0; N];
509    reader.read_exact(&mut buffer)?;
510    Ok(buffer)
511}
512
513/// Reads an exactly sized bounded vector through a type-erased reader.
514///
515/// # Parameters
516/// - `reader`: Reader that supplies the bytes.
517/// - `len`: Exact number of bytes to read.
518/// - `max_len`: Maximum accepted exact read length.
519///
520/// # Returns
521/// A vector containing exactly `len` bytes.
522///
523/// # Errors
524/// Returns [`ErrorKind::OutOfMemory`] if the result vector cannot be allocated,
525/// a read error, or [`ErrorKind::InvalidData`] when `len > max_len`.
526#[inline]
527fn read_exact_vec_limited_impl(
528    reader: &mut dyn Read,
529    len: usize,
530    max_len: usize,
531) -> Result<Vec<u8>> {
532    let mut output = Vec::new();
533    read_ext_impl::read_exact_vec_limited_into(
534        reader,
535        &mut output,
536        len,
537        max_len,
538    )?;
539    Ok(output)
540}
541
542/// Discards a bounded byte count through a type-erased reader.
543///
544/// # Parameters
545/// - `reader`: Reader whose bytes are discarded.
546/// - `bytes`: Maximum number of bytes to discard.
547///
548/// # Returns
549/// The number of bytes discarded before the limit or EOF was reached.
550///
551/// # Errors
552/// Returns the first non-interrupted read error.
553fn discard_exact_or_eof_impl(reader: &mut dyn Read, bytes: u64) -> Result<u64> {
554    let mut buffer = [0; DISCARD_BUFFER_SIZE];
555    let mut remaining = bytes;
556    let mut discarded = 0;
557    while remaining > 0 {
558        let requested = remaining.min(DISCARD_BUFFER_SIZE as u64) as usize;
559        match reader.read(&mut buffer[..requested]) {
560            Ok(0) => break,
561            Ok(count) => {
562                let count = count as u64;
563                remaining -= count;
564                discarded += count;
565            }
566            Err(error) => {
567                if error.kind() == ErrorKind::Interrupted {
568                    continue;
569                }
570                return Err(error);
571            }
572        }
573    }
574    Ok(discarded)
575}
576
577/// Reads bounded UTF-8 text through a type-erased reader.
578///
579/// # Parameters
580/// - `reader`: Reader that supplies the text bytes.
581/// - `max_len`: Maximum accepted byte length.
582///
583/// # Returns
584/// The decoded UTF-8 string.
585///
586/// # Errors
587/// Returns [`ErrorKind::OutOfMemory`] if the result buffer cannot grow, a read
588/// error, or [`ErrorKind::InvalidData`] when the input exceeds `max_len` or is
589/// not valid UTF-8.
590#[inline]
591fn read_to_string_limited_impl(
592    reader: &mut dyn Read,
593    max_len: usize,
594) -> Result<String> {
595    let bytes = read_ext_impl::read_to_end_limited(reader, max_len)?;
596    String::from_utf8(bytes).map_err(read_ext_impl::invalid_utf8_error)
597}
598
599/// Appends bounded UTF-8 text read through a type-erased reader.
600///
601/// # Parameters
602/// - `reader`: Reader that supplies the text bytes.
603/// - `output`: String that receives the decoded text.
604/// - `max_len`: Maximum accepted byte length.
605///
606/// # Returns
607/// The number of bytes appended to `output`.
608///
609/// # Errors
610/// Returns [`ErrorKind::OutOfMemory`] if the temporary byte buffer or `output`
611/// cannot grow, a read error, or [`ErrorKind::InvalidData`] when the input
612/// exceeds `max_len` or is not valid UTF-8.
613#[inline]
614fn read_to_string_limited_into_impl(
615    reader: &mut dyn Read,
616    output: &mut String,
617    max_len: usize,
618) -> Result<usize> {
619    let bytes = read_ext_impl::read_to_end_limited(reader, max_len)?;
620    let text =
621        String::from_utf8(bytes).map_err(read_ext_impl::invalid_utf8_error)?;
622    let count = text.len();
623    try_reserve_string(output, count).map_err(allocation_error)?;
624    output.push_str(&text);
625    Ok(count)
626}
627
628impl<T> ReadExt for T
629where
630    T: Read + ?Sized,
631{
632    /// Reads bytes from an unchecked range into a standard [`Read`] value.
633    ///
634    /// # Parameters
635    /// - `buffer`: Destination buffer.
636    /// - `start_index`: Start offset inside `buffer`.
637    /// - `count`: Maximum number of bytes to read.
638    ///
639    /// # Returns
640    /// The number of bytes read into the requested range.
641    ///
642    /// # Errors
643    /// Returns the error reported by [`Read::read`].
644    ///
645    /// # Panics
646    /// Panics in debug builds if the requested output range does not fit.
647    ///
648    /// # Safety
649    /// The caller must guarantee that `start_index..start_index + count` is
650    /// valid inside `buffer` and that the addition does not overflow.
651    #[inline(always)]
652    unsafe fn read_unchecked(
653        &mut self,
654        buffer: &mut [u8],
655        start_index: usize,
656        count: usize,
657    ) -> Result<usize> {
658        // SAFETY: The caller guarantees that the requested range is valid for
659        // `buffer`.
660        let target =
661            unsafe { UncheckedSlice::subslice_mut(buffer, start_index, count) };
662        self.read(target)
663    }
664
665    /// Reads an unchecked range until it is full or EOF is reached.
666    ///
667    /// # Parameters
668    /// - `buffer`: Destination buffer.
669    /// - `start_index`: Start offset inside `buffer`.
670    /// - `count`: Number of bytes to try to read.
671    ///
672    /// # Returns
673    /// The number of bytes read into the requested range.
674    ///
675    /// # Errors
676    /// Returns the first non-interrupted read error.
677    ///
678    /// # Panics
679    /// Panics in debug builds if the requested output range does not fit.
680    ///
681    /// # Safety
682    /// The caller must guarantee that `start_index..start_index + count` is
683    /// valid inside `buffer` and that the addition does not overflow.
684    #[inline(always)]
685    unsafe fn read_exact_or_eof_unchecked(
686        &mut self,
687        buffer: &mut [u8],
688        start_index: usize,
689        count: usize,
690    ) -> Result<usize> {
691        let mut reader = self;
692        // SAFETY: Forwarded from the trait caller.
693        unsafe {
694            read_exact_or_eof_unchecked_impl(
695                &mut reader,
696                buffer,
697                start_index,
698                count,
699            )
700        }
701    }
702
703    /// Reads exactly the requested unchecked range.
704    ///
705    /// # Parameters
706    /// - `buffer`: Destination buffer.
707    /// - `start_index`: Start offset inside `buffer`.
708    /// - `count`: Number of bytes to read.
709    ///
710    /// # Returns
711    /// `Ok(())` after the requested range has been filled.
712    ///
713    /// # Errors
714    /// Returns the error reported by [`Read::read_exact`].
715    ///
716    /// # Panics
717    /// Panics in debug builds if the requested output range does not fit.
718    ///
719    /// # Safety
720    /// The caller must guarantee that `start_index..start_index + count` is
721    /// valid inside `buffer` and that the addition does not overflow.
722    #[inline(always)]
723    unsafe fn read_exact_unchecked(
724        &mut self,
725        buffer: &mut [u8],
726        start_index: usize,
727        count: usize,
728    ) -> Result<()> {
729        // SAFETY: The caller guarantees that the requested range is valid for
730        // `buffer`.
731        let target =
732            unsafe { UncheckedSlice::subslice_mut(buffer, start_index, count) };
733        self.read_exact(target)
734    }
735
736    /// Reads the destination until it is full or EOF is reached.
737    ///
738    /// # Parameters
739    /// - `buffer`: Destination buffer.
740    ///
741    /// # Returns
742    /// The number of bytes read into `buffer`.
743    ///
744    /// # Errors
745    /// Returns the first non-interrupted read error.
746    #[inline(always)]
747    fn read_exact_or_eof(&mut self, buffer: &mut [u8]) -> Result<usize> {
748        let mut reader = self;
749        read_ext_impl::read_exact_or_eof(&mut reader, buffer)
750    }
751
752    /// Reads exactly `N` bytes into an array.
753    ///
754    /// # Type Parameters
755    /// - `N`: Number of bytes in the returned array.
756    ///
757    /// # Returns
758    /// An array containing exactly `N` bytes.
759    ///
760    /// # Errors
761    /// Returns the error reported by [`Read::read_exact`].
762    #[inline(always)]
763    fn read_exact_array<const N: usize>(&mut self) -> Result<[u8; N]> {
764        let mut reader = self;
765        read_exact_array_impl(&mut reader)
766    }
767
768    /// Reads an exactly sized vector within a configured limit.
769    ///
770    /// # Parameters
771    /// - `len`: Exact number of bytes to read.
772    /// - `max_len`: Maximum accepted exact read length.
773    ///
774    /// # Returns
775    /// A vector containing exactly `len` bytes.
776    ///
777    /// # Errors
778    /// Returns [`ErrorKind::OutOfMemory`] if the result vector cannot be
779    /// allocated, a read error, or [`ErrorKind::InvalidData`] when
780    /// `len > max_len`.
781    #[inline(always)]
782    fn read_exact_vec_limited(
783        &mut self,
784        len: usize,
785        max_len: usize,
786    ) -> Result<Vec<u8>> {
787        let mut reader = self;
788        read_exact_vec_limited_impl(&mut reader, len, max_len)
789    }
790
791    /// Reads exactly `len` bytes and appends them to a vector.
792    ///
793    /// # Parameters
794    /// - `output`: Destination vector.
795    /// - `len`: Exact number of bytes to read.
796    /// - `max_len`: Maximum accepted exact read length.
797    ///
798    /// # Returns
799    /// `Ok(())` after exactly `len` bytes have been appended.
800    ///
801    /// # Errors
802    /// Returns [`ErrorKind::OutOfMemory`] if `output` cannot grow, a read
803    /// error, [`ErrorKind::InvalidData`] when `len > max_len`, or
804    /// [`ErrorKind::InvalidInput`] when `output.len() + len` overflows.
805    #[inline(always)]
806    fn read_exact_vec_limited_into(
807        &mut self,
808        output: &mut Vec<u8>,
809        len: usize,
810        max_len: usize,
811    ) -> Result<()> {
812        let mut reader = self;
813        read_ext_impl::read_exact_vec_limited_into(
814            &mut reader,
815            output,
816            len,
817            max_len,
818        )
819    }
820
821    /// Discards at most the requested number of bytes.
822    ///
823    /// # Parameters
824    /// - `bytes`: Maximum number of bytes to discard.
825    ///
826    /// # Returns
827    /// The number of bytes discarded before the limit or EOF was reached.
828    ///
829    /// # Errors
830    /// Returns the first non-interrupted read error.
831    #[inline(always)]
832    fn discard_exact_or_eof(&mut self, bytes: u64) -> Result<u64> {
833        let mut reader = self;
834        discard_exact_or_eof_impl(&mut reader, bytes)
835    }
836
837    /// Copies all remaining bytes to a writer.
838    ///
839    /// # Parameters
840    /// - `writer`: Destination writer.
841    ///
842    /// # Returns
843    /// The number of bytes copied.
844    ///
845    /// # Errors
846    /// Returns the first read or write error.
847    #[inline(always)]
848    fn copy_to(&mut self, writer: &mut dyn Write) -> Result<u64> {
849        copy_all(self, writer)
850    }
851
852    /// Copies at most the requested number of bytes to a writer.
853    ///
854    /// # Parameters
855    /// - `writer`: Destination writer.
856    /// - `max_bytes`: Maximum number of bytes to copy.
857    ///
858    /// # Returns
859    /// The number of bytes copied.
860    ///
861    /// # Errors
862    /// Returns [`ErrorKind::OutOfMemory`] if the temporary copy buffer cannot
863    /// be allocated, or the first non-interrupted read error or write error.
864    #[inline(always)]
865    fn copy_to_at_most(
866        &mut self,
867        writer: &mut dyn Write,
868        max_bytes: u64,
869    ) -> Result<u64> {
870        let mut reader = self;
871        Streams::copy_at_most(&mut reader, writer, max_bytes)
872    }
873
874    /// Copies the remaining input when it fits within a configured limit.
875    ///
876    /// # Parameters
877    /// - `writer`: Destination writer.
878    /// - `max_bytes`: Maximum accepted remaining byte count.
879    ///
880    /// # Returns
881    /// The number of bytes copied.
882    ///
883    /// # Errors
884    /// Returns [`ErrorKind::OutOfMemory`] if the temporary copy buffer cannot
885    /// be allocated, a read or write error, or [`ErrorKind::InvalidData`] when
886    /// the remaining input exceeds `max_bytes`.
887    #[inline(always)]
888    fn copy_to_end_limited(
889        &mut self,
890        writer: &mut dyn Write,
891        max_bytes: u64,
892    ) -> Result<u64> {
893        let mut reader = self;
894        Streams::copy_to_end_limited(&mut reader, writer, max_bytes)
895    }
896
897    /// Reads the remaining bytes into a bounded vector.
898    ///
899    /// # Parameters
900    /// - `max_len`: Maximum accepted remaining byte count.
901    ///
902    /// # Returns
903    /// A vector containing all remaining bytes.
904    ///
905    /// # Errors
906    /// Returns [`ErrorKind::OutOfMemory`] if the result vector cannot grow, a
907    /// read error, or [`ErrorKind::InvalidData`] when the remaining input
908    /// exceeds `max_len`.
909    #[inline(always)]
910    fn read_to_end_limited(&mut self, max_len: usize) -> Result<Vec<u8>> {
911        let mut reader = self;
912        read_ext_impl::read_to_end_limited(&mut reader, max_len)
913    }
914
915    /// Appends the remaining bytes to a bounded vector.
916    ///
917    /// # Parameters
918    /// - `output`: Destination vector.
919    /// - `max_len`: Maximum accepted remaining byte count.
920    ///
921    /// # Returns
922    /// The number of bytes appended to `output`.
923    ///
924    /// # Errors
925    /// Returns [`ErrorKind::OutOfMemory`] if `output` cannot grow, a read
926    /// error, or [`ErrorKind::InvalidData`] when the remaining input
927    /// exceeds `max_len`.
928    #[inline(always)]
929    fn read_to_end_limited_into(
930        &mut self,
931        output: &mut Vec<u8>,
932        max_len: usize,
933    ) -> Result<usize> {
934        let mut reader = self;
935        read_ext_impl::read_to_end_limited_into(&mut reader, output, max_len)
936    }
937
938    /// Reads the remaining bytes as bounded UTF-8 text.
939    ///
940    /// # Parameters
941    /// - `max_len`: Maximum accepted remaining byte count.
942    ///
943    /// # Returns
944    /// The decoded UTF-8 string.
945    ///
946    /// # Errors
947    /// Returns [`ErrorKind::OutOfMemory`] if the result buffer cannot grow, a
948    /// read error, or [`ErrorKind::InvalidData`] when the input exceeds
949    /// `max_len` or is not valid UTF-8.
950    #[inline(always)]
951    fn read_to_string_limited(&mut self, max_len: usize) -> Result<String> {
952        let mut reader = self;
953        read_to_string_limited_impl(&mut reader, max_len)
954    }
955
956    /// Appends the remaining bounded UTF-8 text to a string.
957    ///
958    /// # Parameters
959    /// - `output`: Destination string.
960    /// - `max_len`: Maximum accepted remaining byte count.
961    ///
962    /// # Returns
963    /// The number of bytes appended to `output`.
964    ///
965    /// # Errors
966    /// Returns [`ErrorKind::OutOfMemory`] if the temporary byte buffer or
967    /// `output` cannot grow, a read error, or [`ErrorKind::InvalidData`] when
968    /// the input exceeds `max_len` or is not valid UTF-8.
969    #[inline(always)]
970    fn read_to_string_limited_into(
971        &mut self,
972        output: &mut String,
973        max_len: usize,
974    ) -> Result<usize> {
975        let mut reader = self;
976        read_to_string_limited_into_impl(&mut reader, output, max_len)
977    }
978}