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}