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