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::Read;
12use std::io::Result;
13use std::io::Write;
14use std::io::copy as copy_all;
15
16use crate::Streams;
17use crate::std_io::ext::internal::read_ext_impl;
18use crate::util::UncheckedSlice;
19
20/// Extension methods for [`Read`] values.
21///
22/// `ReadExt` fills small semantic gaps in the standard [`Read`] trait while
23/// keeping the same blocking and error model. The methods are implemented for
24/// every type that implements [`Read`], including `dyn Read` trait objects.
25///
26/// # Examples
27/// ```
28/// use qubit_io::std_io::ext::ReadExt;
29/// use std::io::Cursor;
30///
31/// let mut input = Cursor::new(b"abcdef".to_vec());
32/// let header = input.read_exact_array::<2>()?;
33/// let payload = input.read_exact_vec_limited(4, 16)?;
34///
35/// assert_eq!(*b"ab", header);
36/// assert_eq!(b"cdef", payload.as_slice());
37/// # Ok::<(), std::io::Error>(())
38/// ```
39pub trait ReadExt: Read {
40    /// Reads bytes into a range of `buffer` without checking the range bounds
41    /// in release builds.
42    ///
43    /// This method delegates to [`Read::read`] after creating the target slice
44    /// with raw pointer arithmetic. It performs at most one read operation and
45    /// returns the number of bytes read, keeping the same short-read and error
46    /// behavior as [`Read::read`].
47    ///
48    /// # Parameters
49    /// - `buffer`: Destination buffer.
50    /// - `start_index`: Start offset inside `buffer`.
51    /// - `count`: Maximum number of bytes to read.
52    ///
53    /// # Returns
54    /// The number of bytes written into `buffer[start_index..start_index +
55    /// count]`. The value is in `0..=count`.
56    ///
57    /// # Errors
58    /// Returns the error reported by [`Read::read`].
59    ///
60    /// # Panics
61    /// Panics in debug builds if the requested destination range does not fit.
62    ///
63    /// # Safety
64    /// The caller must guarantee that `start_index..start_index + count` is a
65    /// valid range within `buffer` and that `start_index + count` does not
66    /// overflow `usize`.
67    unsafe fn read_unchecked(&mut self, buffer: &mut [u8], start_index: usize, count: usize) -> Result<usize>;
68
69    /// Reads exactly `count` bytes into a range of `buffer` without checking
70    /// the range bounds in release builds.
71    ///
72    /// This method delegates to [`Read::read_exact`] after creating the target
73    /// slice with raw pointer arithmetic. It keeps the same blocking and error
74    /// behavior as [`Read::read_exact`].
75    ///
76    /// # Parameters
77    /// - `buffer`: Destination buffer.
78    /// - `start_index`: Start offset inside `buffer`.
79    /// - `count`: Number of bytes to read.
80    ///
81    /// # Returns
82    /// `Ok(())` after the requested range has been filled.
83    ///
84    /// # Errors
85    /// Returns the error reported by [`Read::read_exact`], including
86    /// [`std::io::ErrorKind::UnexpectedEof`] when EOF is reached before `count`
87    /// bytes are read.
88    ///
89    /// # Panics
90    /// Panics in debug builds if the requested destination range does not fit.
91    ///
92    /// # Safety
93    /// The caller must guarantee that `start_index..start_index + count` is a
94    /// valid range within `buffer` and that `start_index + count` does not
95    /// overflow `usize`.
96    unsafe fn read_exact_unchecked(&mut self, buffer: &mut [u8], start_index: usize, count: usize) -> Result<()>;
97
98    /// Reads bytes into a range of `buffer` until that range is full or EOF is
99    /// reached, without checking the range bounds in release builds.
100    ///
101    /// This method has the same EOF and retry behavior as
102    /// [`ReadExt::read_exact_or_eof`], but writes into
103    /// `buffer[start_index..start_index + count]` using raw pointer
104    /// arithmetic.
105    ///
106    /// # Parameters
107    /// - `buffer`: Destination buffer.
108    /// - `start_index`: Start offset inside `buffer`.
109    /// - `count`: Number of bytes to try to read.
110    ///
111    /// # Returns
112    /// The number of bytes written into `buffer[start_index..start_index +
113    /// count]`. The value is in `0..=count`.
114    ///
115    /// # Errors
116    /// Returns the first non-[`std::io::ErrorKind::Interrupted`] error reported
117    /// by the underlying reader. Interrupted reads are retried. Returns
118    /// [`std::io::ErrorKind::InvalidData`] if the reader reports more bytes
119    /// than requested.
120    ///
121    /// # Panics
122    /// Panics in debug builds if the requested destination range does not fit.
123    ///
124    /// # Safety
125    /// The caller must guarantee that `start_index..start_index + count` is a
126    /// valid range within `buffer` and that `start_index + count` does not
127    /// overflow `usize`.
128    unsafe fn read_exact_or_eof_unchecked(
129        &mut self,
130        buffer: &mut [u8],
131        start_index: usize,
132        count: usize,
133    ) -> Result<usize>;
134
135    /// Reads bytes until `buffer` is full or EOF is reached.
136    ///
137    /// This method differs from [`Read::read_exact`] by treating EOF as a
138    /// successful partial result. It keeps retrying short reads until the
139    /// caller-provided buffer is full, EOF is reached, or a non-interrupted
140    /// I/O error occurs.
141    ///
142    /// # Parameters
143    /// - `buffer`: Destination buffer to fill.
144    ///
145    /// # Returns
146    /// The number of bytes written into `buffer`. The value is in
147    /// `0..=buffer.len()`.
148    ///
149    /// # Errors
150    /// Returns the first non-[`std::io::ErrorKind::Interrupted`] error reported
151    /// by the underlying reader. Interrupted reads are retried. Returns
152    /// [`std::io::ErrorKind::InvalidData`] if the reader reports more bytes
153    /// than requested.
154    fn read_exact_or_eof(&mut self, buffer: &mut [u8]) -> Result<usize>;
155
156    /// Reads exactly `N` bytes into a stack-allocated array.
157    ///
158    /// This method uses [`Read::read_exact`] and therefore requires the reader
159    /// to provide exactly `N` bytes before EOF.
160    ///
161    /// # Type Parameters
162    /// - `N`: Number of bytes in the returned array.
163    ///
164    /// # Returns
165    /// An array containing exactly `N` bytes read from this reader.
166    ///
167    /// # Errors
168    /// Returns the error reported by [`Read::read_exact`], including
169    /// [`std::io::ErrorKind::UnexpectedEof`] when EOF is reached before the
170    /// array is full.
171    fn read_exact_array<const N: usize>(&mut self) -> Result<[u8; N]>;
172
173    /// Reads exactly `len` bytes into a new vector after checking a limit.
174    ///
175    /// If `len` is greater than `max_len`, this method returns
176    /// [`std::io::ErrorKind::InvalidData`] before reading any bytes.
177    ///
178    /// # Parameters
179    /// - `len`: Exact number of bytes to read.
180    /// - `max_len`: Maximum accepted exact read length.
181    ///
182    /// # Returns
183    /// A vector containing exactly `len` bytes.
184    ///
185    /// # Errors
186    /// Returns [`std::io::ErrorKind::InvalidData`] when `len > max_len`.
187    /// Returns the [`std::io::ErrorKind::OutOfMemory`] error when the
188    /// result vector cannot be allocated. Returns the error reported by
189    /// [`Read::read_exact`], including
190    /// [`std::io::ErrorKind::UnexpectedEof`] when EOF is reached before `len`
191    /// bytes are read.
192    fn read_exact_vec_limited(&mut self, len: usize, max_len: usize) -> Result<Vec<u8>>;
193
194    /// Reads exactly `len` bytes and appends them to `output`.
195    ///
196    /// If `len` is greater than `max_len`, this method returns
197    /// [`std::io::ErrorKind::InvalidData`] before reading any bytes and leaves
198    /// `output` unchanged. On a read error, `output` is truncated back to
199    /// its original length. The underlying reader may still have consumed
200    /// bytes before the error because [`Read`] does not provide rollback.
201    ///
202    /// # Parameters
203    /// - `output`: Destination vector to append to.
204    /// - `len`: Exact number of bytes to read.
205    /// - `max_len`: Maximum accepted exact read length.
206    ///
207    /// # Returns
208    /// `Ok(())` after exactly `len` bytes have been appended to `output`.
209    ///
210    /// # Errors
211    /// Returns [`std::io::ErrorKind::InvalidData`] when `len > max_len`,
212    /// [`std::io::ErrorKind::InvalidInput`] when `output.len() + len`
213    /// overflows, or [`std::io::ErrorKind::OutOfMemory`] when `output`
214    /// cannot reserve the appended bytes. Returns the error reported by
215    /// [`Read::read_exact`], including
216    /// [`std::io::ErrorKind::UnexpectedEof`] when EOF is reached before `len`
217    /// bytes are read.
218    fn read_exact_vec_limited_into(&mut self, output: &mut Vec<u8>, len: usize, max_len: usize) -> Result<()>;
219
220    /// Discards up to `bytes` bytes from this reader.
221    ///
222    /// The method repeatedly reads into an internal stack buffer until the
223    /// requested number of bytes has been consumed or EOF is reached. It does
224    /// not allocate and does not require seeking support.
225    ///
226    /// # Parameters
227    /// - `bytes`: Maximum number of bytes to discard.
228    ///
229    /// # Returns
230    /// The number of bytes actually discarded. The value may be smaller than
231    /// `bytes` when EOF is reached first.
232    ///
233    /// # Errors
234    /// Returns the first non-[`std::io::ErrorKind::Interrupted`] error reported
235    /// by the underlying reader. Interrupted reads are retried. Returns
236    /// [`std::io::ErrorKind::InvalidData`] if the reader reports more bytes
237    /// than requested.
238    fn discard_exact_or_eof(&mut self, bytes: u64) -> Result<u64>;
239
240    /// Copies all remaining bytes from this reader into `writer`.
241    ///
242    /// This method is a method-style wrapper around [`std::io::copy`]. It
243    /// copies from the current reader position until EOF and does not close or
244    /// flush either stream.
245    ///
246    /// # Parameters
247    /// - `writer`: Destination writer.
248    ///
249    /// # Returns
250    /// The number of bytes copied.
251    ///
252    /// # Errors
253    /// Returns the first read or write error reported by the underlying
254    /// streams, using the same error behavior as [`std::io::copy`].
255    fn copy_to(&mut self, writer: &mut dyn Write) -> Result<u64>;
256
257    /// Copies at most `max_bytes` bytes from this reader into `writer`.
258    ///
259    /// This method stops successfully when either EOF is reached or
260    /// `max_bytes` bytes have been copied. It does not close or flush either
261    /// stream.
262    ///
263    /// # Parameters
264    /// - `writer`: Destination writer.
265    /// - `max_bytes`: Maximum number of bytes to copy.
266    ///
267    /// # Returns
268    /// The number of bytes copied.
269    ///
270    /// # Errors
271    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the temporary copy buffer
272    /// cannot be allocated. Returns the first
273    /// non-[`std::io::ErrorKind::Interrupted`] read error or write error
274    /// reported by the underlying streams. Interrupted reads are retried.
275    fn copy_to_at_most(&mut self, writer: &mut dyn Write, max_bytes: u64) -> Result<u64>;
276
277    /// Copies the remaining input if its total length is at most `max_bytes`.
278    ///
279    /// This method copies from the current reader position until EOF. If EOF is
280    /// not reached within `max_bytes` bytes, it returns
281    /// [`std::io::ErrorKind::InvalidData`]. Detecting oversized input consumes
282    /// one excess byte from this reader; that excess byte is not written to
283    /// `writer`.
284    ///
285    /// Unlike bounded reads into in-memory collections, this method cannot roll
286    /// back bytes already accepted by `writer` when the limit is exceeded
287    /// because [`Write`] does not provide truncation. On
288    /// [`std::io::ErrorKind::InvalidData`], up to `max_bytes` bytes may remain
289    /// in `writer`.
290    ///
291    /// # Parameters
292    /// - `writer`: Destination writer.
293    /// - `max_bytes`: Maximum accepted number of bytes in the remaining input.
294    ///
295    /// # Returns
296    /// The number of bytes copied when EOF is reached within the limit.
297    ///
298    /// # Errors
299    /// Returns [`std::io::ErrorKind::InvalidData`] when the remaining input is
300    /// longer than `max_bytes`. Returns [`std::io::ErrorKind::OutOfMemory`]
301    /// if the temporary copy buffer cannot be allocated. Returns the first
302    /// non-[`std::io::ErrorKind::Interrupted`] read error or write error
303    /// reported by the underlying streams. Interrupted reads are retried.
304    fn copy_to_end_limited(&mut self, writer: &mut dyn Write, max_bytes: u64) -> Result<u64>;
305
306    /// Reads the remaining bytes into a vector with a maximum accepted length.
307    ///
308    /// This method consumes bytes from the current reader position until EOF is
309    /// reached. If the stream contains more than `max_len` bytes, it returns
310    /// [`std::io::ErrorKind::InvalidData`] after detecting the first excess
311    /// byte. No vector is returned on failure.
312    ///
313    /// # Parameters
314    /// - `max_len`: Maximum number of bytes accepted in the returned vector.
315    ///
316    /// # Returns
317    /// A vector containing all remaining bytes when the stream length is within
318    /// the limit.
319    ///
320    /// # Errors
321    /// Returns [`std::io::ErrorKind::InvalidData`] when the stream contains
322    /// more than `max_len` bytes. Returns
323    /// [`std::io::ErrorKind::OutOfMemory`] when the result vector cannot
324    /// grow. Returns the first non-[`std::io::ErrorKind::Interrupted`]
325    /// error reported by the underlying reader; interrupted reads are
326    /// retried. Returns [`std::io::ErrorKind::InvalidData`] if the reader
327    /// reports more bytes than requested.
328    fn read_to_end_limited(&mut self, max_len: usize) -> Result<Vec<u8>>;
329
330    /// Reads the remaining bytes into `output` with a maximum accepted length.
331    ///
332    /// This method appends at most `max_len` bytes from the current reader
333    /// position to `output`. If the stream contains more than `max_len` bytes,
334    /// it returns [`std::io::ErrorKind::InvalidData`] after detecting the first
335    /// excess byte and truncates `output` back to its original length. The
336    /// underlying reader may still have consumed bytes before the error
337    /// because [`Read`] does not provide rollback.
338    ///
339    /// # Parameters
340    /// - `output`: Destination vector to append to.
341    /// - `max_len`: Maximum number of bytes accepted from this reader.
342    ///
343    /// # Returns
344    /// The number of bytes appended to `output`.
345    ///
346    /// # Errors
347    /// Returns [`std::io::ErrorKind::InvalidData`] when the stream contains
348    /// more than `max_len` bytes. Returns
349    /// [`std::io::ErrorKind::OutOfMemory`] when `output` cannot
350    /// grow. Returns the first non-[`std::io::ErrorKind::Interrupted`] error
351    /// reported by the underlying reader; interrupted reads are retried.
352    /// Returns [`std::io::ErrorKind::InvalidData`] if the reader reports
353    /// more bytes than requested.
354    fn read_to_end_limited_into(&mut self, output: &mut Vec<u8>, max_len: usize) -> Result<usize>;
355
356    /// Reads the remaining bytes as UTF-8 text with a maximum accepted length.
357    ///
358    /// This method has the same size limit and read semantics as
359    /// [`ReadExt::read_to_end_limited`], then validates the collected bytes as
360    /// UTF-8.
361    ///
362    /// # Parameters
363    /// - `max_len`: Maximum number of bytes accepted before UTF-8 decoding.
364    ///
365    /// # Returns
366    /// The decoded UTF-8 string.
367    ///
368    /// # Errors
369    /// Returns [`std::io::ErrorKind::InvalidData`] when the stream contains
370    /// more than `max_len` bytes or when the collected bytes are not valid
371    /// UTF-8. Returns [`std::io::ErrorKind::OutOfMemory`] when the result
372    /// buffer cannot grow. Returns
373    /// the first non-[`std::io::ErrorKind::Interrupted`] error reported by the
374    /// underlying reader; interrupted reads are retried.
375    fn read_to_string_limited(&mut self, max_len: usize) -> Result<String>;
376
377    /// Reads the remaining bytes as UTF-8 text and appends to `output`.
378    ///
379    /// This method accepts at most `max_len` bytes from the current reader
380    /// position, validates them as UTF-8, and appends the decoded text to
381    /// `output`. If the input is oversized or invalid UTF-8, `output` is
382    /// truncated back to its original length. Oversized input may still consume
383    /// up to `max_len + 1` bytes from the reader while detecting the limit
384    /// violation.
385    ///
386    /// # Parameters
387    /// - `output`: Destination string to append to.
388    /// - `max_len`: Maximum number of bytes accepted before UTF-8 decoding.
389    ///
390    /// # Returns
391    /// The number of bytes appended to `output`.
392    ///
393    /// # Errors
394    /// Returns [`std::io::ErrorKind::InvalidData`] when the stream contains
395    /// more than `max_len` bytes or when the collected bytes are not valid
396    /// UTF-8. Returns [`std::io::ErrorKind::OutOfMemory`] when the
397    /// temporary byte buffer or `output` cannot grow. Returns the first
398    /// non-[`std::io::ErrorKind::Interrupted`] error reported by the
399    /// underlying reader; interrupted reads are retried.
400    fn read_to_string_limited_into(&mut self, output: &mut String, max_len: usize) -> Result<usize>;
401}
402
403impl<T> ReadExt for T
404where
405    T: Read + ?Sized,
406{
407    /// Reads bytes from an unchecked range into a standard [`Read`] value.
408    ///
409    /// # Parameters
410    /// - `buffer`: Destination buffer.
411    /// - `start_index`: Start offset inside `buffer`.
412    /// - `count`: Maximum number of bytes to read.
413    ///
414    /// # Returns
415    /// The number of bytes read into the requested range.
416    ///
417    /// # Errors
418    /// Returns the error reported by [`Read::read`].
419    ///
420    /// # Panics
421    /// Panics in debug builds if the requested output range does not fit.
422    ///
423    /// # Safety
424    /// The caller must guarantee that `start_index..start_index + count` is
425    /// valid inside `buffer` and that the addition does not overflow.
426    #[inline(always)]
427    unsafe fn read_unchecked(&mut self, buffer: &mut [u8], start_index: usize, count: usize) -> Result<usize> {
428        // SAFETY: The caller guarantees that the requested range is valid for
429        // `buffer`.
430        let target = unsafe { UncheckedSlice::subslice_mut(buffer, start_index, count) };
431        self.read(target)
432    }
433
434    /// Reads an unchecked range until it is full or EOF is reached.
435    ///
436    /// # Parameters
437    /// - `buffer`: Destination buffer.
438    /// - `start_index`: Start offset inside `buffer`.
439    /// - `count`: Number of bytes to try to read.
440    ///
441    /// # Returns
442    /// The number of bytes read into the requested range.
443    ///
444    /// # Errors
445    /// Returns the first non-interrupted read error, or
446    /// [`std::io::ErrorKind::InvalidData`] if the reader reports more bytes
447    /// than requested.
448    ///
449    /// # Panics
450    /// Panics in debug builds if the requested output range does not fit.
451    ///
452    /// # Safety
453    /// The caller must guarantee that `start_index..start_index + count` is
454    /// valid inside `buffer` and that the addition does not overflow.
455    #[inline(always)]
456    unsafe fn read_exact_or_eof_unchecked(
457        &mut self,
458        buffer: &mut [u8],
459        start_index: usize,
460        count: usize,
461    ) -> Result<usize> {
462        let mut reader = self;
463        // SAFETY: Forwarded from the trait caller.
464        unsafe { read_ext_impl::read_exact_or_eof_unchecked_impl(&mut reader, buffer, start_index, count) }
465    }
466
467    /// Reads exactly the requested unchecked range.
468    ///
469    /// # Parameters
470    /// - `buffer`: Destination buffer.
471    /// - `start_index`: Start offset inside `buffer`.
472    /// - `count`: Number of bytes to read.
473    ///
474    /// # Returns
475    /// `Ok(())` after the requested range has been filled.
476    ///
477    /// # Errors
478    /// Returns the error reported by [`Read::read_exact`].
479    ///
480    /// # Panics
481    /// Panics in debug builds if the requested output range does not fit.
482    ///
483    /// # Safety
484    /// The caller must guarantee that `start_index..start_index + count` is
485    /// valid inside `buffer` and that the addition does not overflow.
486    #[inline(always)]
487    unsafe fn read_exact_unchecked(&mut self, buffer: &mut [u8], start_index: usize, count: usize) -> Result<()> {
488        // SAFETY: The caller guarantees that the requested range is valid for
489        // `buffer`.
490        let target = unsafe { UncheckedSlice::subslice_mut(buffer, start_index, count) };
491        self.read_exact(target)
492    }
493
494    /// Reads the destination until it is full or EOF is reached.
495    ///
496    /// # Parameters
497    /// - `buffer`: Destination buffer.
498    ///
499    /// # Returns
500    /// The number of bytes read into `buffer`.
501    ///
502    /// # Errors
503    /// Returns the first non-interrupted read error, or
504    /// [`std::io::ErrorKind::InvalidData`] if the reader reports more bytes
505    /// than requested.
506    #[inline(always)]
507    fn read_exact_or_eof(&mut self, buffer: &mut [u8]) -> Result<usize> {
508        let mut reader = self;
509        read_ext_impl::read_exact_or_eof(&mut reader, buffer)
510    }
511
512    /// Reads exactly `N` bytes into an array.
513    ///
514    /// # Type Parameters
515    /// - `N`: Number of bytes in the returned array.
516    ///
517    /// # Returns
518    /// An array containing exactly `N` bytes.
519    ///
520    /// # Errors
521    /// Returns the error reported by [`Read::read_exact`].
522    #[inline(always)]
523    fn read_exact_array<const N: usize>(&mut self) -> Result<[u8; N]> {
524        let mut reader = self;
525        read_ext_impl::read_exact_array_impl(&mut reader)
526    }
527
528    /// Reads an exactly sized vector within a configured limit.
529    ///
530    /// # Parameters
531    /// - `len`: Exact number of bytes to read.
532    /// - `max_len`: Maximum accepted exact read length.
533    ///
534    /// # Returns
535    /// A vector containing exactly `len` bytes.
536    ///
537    /// # Errors
538    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the result vector cannot
539    /// be allocated, a read error, or [`std::io::ErrorKind::InvalidData`]
540    /// when `len > max_len`.
541    #[inline(always)]
542    fn read_exact_vec_limited(&mut self, len: usize, max_len: usize) -> Result<Vec<u8>> {
543        let mut reader = self;
544        read_ext_impl::read_exact_vec_limited_impl(&mut reader, len, max_len)
545    }
546
547    /// Reads exactly `len` bytes and appends them to a vector.
548    ///
549    /// # Parameters
550    /// - `output`: Destination vector.
551    /// - `len`: Exact number of bytes to read.
552    /// - `max_len`: Maximum accepted exact read length.
553    ///
554    /// # Returns
555    /// `Ok(())` after exactly `len` bytes have been appended.
556    ///
557    /// # Errors
558    /// Returns [`std::io::ErrorKind::OutOfMemory`] if `output` cannot grow, a
559    /// read error, [`std::io::ErrorKind::InvalidData`] when `len >
560    /// max_len`, or [`std::io::ErrorKind::InvalidInput`] when `output.len()
561    /// + len` overflows.
562    #[inline(always)]
563    fn read_exact_vec_limited_into(&mut self, output: &mut Vec<u8>, len: usize, max_len: usize) -> Result<()> {
564        let mut reader = self;
565        read_ext_impl::read_exact_vec_limited_into(&mut reader, output, len, max_len)
566    }
567
568    /// Discards at most the requested number of bytes.
569    ///
570    /// # Parameters
571    /// - `bytes`: Maximum number of bytes to discard.
572    ///
573    /// # Returns
574    /// The number of bytes discarded before the limit or EOF was reached.
575    ///
576    /// # Errors
577    /// Returns the first non-interrupted read error.
578    #[inline(always)]
579    fn discard_exact_or_eof(&mut self, bytes: u64) -> Result<u64> {
580        let mut reader = self;
581        read_ext_impl::discard_exact_or_eof_impl(&mut reader, bytes)
582    }
583
584    /// Copies all remaining bytes to a writer.
585    ///
586    /// # Parameters
587    /// - `writer`: Destination writer.
588    ///
589    /// # Returns
590    /// The number of bytes copied.
591    ///
592    /// # Errors
593    /// Returns the first read or write error.
594    #[inline(always)]
595    fn copy_to(&mut self, writer: &mut dyn Write) -> Result<u64> {
596        copy_all(self, writer)
597    }
598
599    /// Copies at most the requested number of bytes to a writer.
600    ///
601    /// # Parameters
602    /// - `writer`: Destination writer.
603    /// - `max_bytes`: Maximum number of bytes to copy.
604    ///
605    /// # Returns
606    /// The number of bytes copied.
607    ///
608    /// # Errors
609    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the temporary copy buffer
610    /// cannot be allocated, or the first non-interrupted read error or
611    /// write error. Returns [`std::io::ErrorKind::InvalidData`] if the
612    /// reader reports more bytes than requested. Bytes from that invalid
613    /// read are not written; previously copied bytes are not rolled back.
614    #[inline(always)]
615    fn copy_to_at_most(&mut self, writer: &mut dyn Write, max_bytes: u64) -> Result<u64> {
616        let mut reader = self;
617        Streams::copy_at_most(&mut reader, writer, max_bytes)
618    }
619
620    /// Copies the remaining input when it fits within a configured limit.
621    ///
622    /// # Parameters
623    /// - `writer`: Destination writer.
624    /// - `max_bytes`: Maximum accepted remaining byte count.
625    ///
626    /// # Returns
627    /// The number of bytes copied.
628    ///
629    /// # Errors
630    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the temporary copy buffer
631    /// cannot be allocated, a read or write error, or
632    /// [`std::io::ErrorKind::InvalidData`] when the remaining input exceeds
633    /// `max_bytes` or the reader reports more bytes than requested. Bytes
634    /// from an invalid read are not written; previously copied bytes are
635    /// not rolled back.
636    #[inline(always)]
637    fn copy_to_end_limited(&mut self, writer: &mut dyn Write, max_bytes: u64) -> Result<u64> {
638        let mut reader = self;
639        Streams::copy_to_end_limited(&mut reader, writer, max_bytes)
640    }
641
642    /// Reads the remaining bytes into a bounded vector.
643    ///
644    /// # Parameters
645    /// - `max_len`: Maximum accepted remaining byte count.
646    ///
647    /// # Returns
648    /// A vector containing all remaining bytes.
649    ///
650    /// # Errors
651    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the result vector cannot
652    /// grow, a read error, or [`std::io::ErrorKind::InvalidData`] when the
653    /// remaining input exceeds `max_len` or the reader reports more bytes
654    /// than requested.
655    #[inline(always)]
656    fn read_to_end_limited(&mut self, max_len: usize) -> Result<Vec<u8>> {
657        let mut reader = self;
658        read_ext_impl::read_to_end_limited(&mut reader, max_len)
659    }
660
661    /// Appends the remaining bytes to a bounded vector.
662    ///
663    /// # Parameters
664    /// - `output`: Destination vector.
665    /// - `max_len`: Maximum accepted remaining byte count.
666    ///
667    /// # Returns
668    /// The number of bytes appended to `output`.
669    ///
670    /// # Errors
671    /// Returns [`std::io::ErrorKind::OutOfMemory`] if `output` cannot grow, a
672    /// read error, or [`std::io::ErrorKind::InvalidData`] when the
673    /// remaining input exceeds `max_len` or the reader reports more bytes
674    /// than requested.
675    #[inline(always)]
676    fn read_to_end_limited_into(&mut self, output: &mut Vec<u8>, max_len: usize) -> Result<usize> {
677        let mut reader = self;
678        read_ext_impl::read_to_end_limited_into(&mut reader, output, max_len)
679    }
680
681    /// Reads the remaining bytes as bounded UTF-8 text.
682    ///
683    /// # Parameters
684    /// - `max_len`: Maximum accepted remaining byte count.
685    ///
686    /// # Returns
687    /// The decoded UTF-8 string.
688    ///
689    /// # Errors
690    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the result buffer cannot
691    /// grow, a read error, or [`std::io::ErrorKind::InvalidData`] when the
692    /// input exceeds `max_len` or is not valid UTF-8.
693    #[inline(always)]
694    fn read_to_string_limited(&mut self, max_len: usize) -> Result<String> {
695        let mut reader = self;
696        read_ext_impl::read_to_string_limited_impl(&mut reader, max_len)
697    }
698
699    /// Appends the remaining bounded UTF-8 text to a string.
700    ///
701    /// # Parameters
702    /// - `output`: Destination string.
703    /// - `max_len`: Maximum accepted remaining byte count.
704    ///
705    /// # Returns
706    /// The number of bytes appended to `output`.
707    ///
708    /// # Errors
709    /// Returns [`std::io::ErrorKind::OutOfMemory`] if the temporary byte buffer
710    /// or `output` cannot grow, a read error, or
711    /// [`std::io::ErrorKind::InvalidData`] when the input exceeds `max_len`
712    /// or is not valid UTF-8.
713    #[inline(always)]
714    fn read_to_string_limited_into(&mut self, output: &mut String, max_len: usize) -> Result<usize> {
715        let mut reader = self;
716        read_ext_impl::read_to_string_limited_into_impl(&mut reader, output, max_len)
717    }
718}