1#![stable(feature = "rust1", since = "1.0.0")]
296
297#[cfg(test)]
298mod tests;
299
300#[unstable(feature = "read_buf", issue = "78485")]
301pub use core::io::{BorrowedBuf, BorrowedCursor};
302use core::slice::memchr;
303
304#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
305pub use self::buffered::WriterPanicked;
306#[unstable(feature = "raw_os_error_ty", issue = "107792")]
307pub use self::error::RawOsError;
308#[doc(hidden)]
309#[unstable(feature = "io_const_error_internals", issue = "none")]
310pub use self::error::SimpleMessage;
311#[unstable(feature = "io_const_error", issue = "133448")]
312pub use self::error::const_error;
313#[stable(feature = "anonymous_pipe", since = "1.87.0")]
314pub use self::pipe::{PipeReader, PipeWriter, pipe};
315#[stable(feature = "is_terminal", since = "1.70.0")]
316pub use self::stdio::IsTerminal;
317pub(crate) use self::stdio::attempt_print_to_stderr;
318#[unstable(feature = "print_internals", issue = "none")]
319#[doc(hidden)]
320pub use self::stdio::{_eprint, _print};
321#[unstable(feature = "internal_output_capture", issue = "none")]
322#[doc(no_inline, hidden)]
323pub use self::stdio::{set_output_capture, try_set_output_capture};
324#[stable(feature = "rust1", since = "1.0.0")]
325pub use self::{
326 buffered::{BufReader, BufWriter, IntoInnerError, LineWriter},
327 copy::copy,
328 cursor::Cursor,
329 error::{Error, ErrorKind, Result},
330 stdio::{Stderr, StderrLock, Stdin, StdinLock, Stdout, StdoutLock, stderr, stdin, stdout},
331 util::{Empty, Repeat, Sink, empty, repeat, sink},
332};
333use crate::mem::take;
334use crate::ops::{Deref, DerefMut};
335use crate::{cmp, fmt, slice, str, sys};
336
337mod buffered;
338pub(crate) mod copy;
339mod cursor;
340mod error;
341mod impls;
342mod pipe;
343pub mod prelude;
344mod stdio;
345mod util;
346
347const DEFAULT_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
348
349pub(crate) use stdio::cleanup;
350
351struct Guard<'a> {
352 buf: &'a mut Vec<u8>,
353 len: usize,
354}
355
356impl Drop for Guard<'_> {
357 fn drop(&mut self) {
358 unsafe {
359 self.buf.set_len(self.len);
360 }
361 }
362}
363
364pub(crate) unsafe fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
384where
385 F: FnOnce(&mut Vec<u8>) -> Result<usize>,
386{
387 let mut g = Guard { len: buf.len(), buf: unsafe { buf.as_mut_vec() } };
388 let ret = f(g.buf);
389
390 let appended = unsafe { g.buf.get_unchecked(g.len..) };
392 if str::from_utf8(appended).is_err() {
393 ret.and_then(|_| Err(Error::INVALID_UTF8))
394 } else {
395 g.len = g.buf.len();
396 ret
397 }
398}
399
400pub(crate) fn default_read_to_end<R: Read + ?Sized>(
410 r: &mut R,
411 buf: &mut Vec<u8>,
412 size_hint: Option<usize>,
413) -> Result<usize> {
414 let start_len = buf.len();
415 let start_cap = buf.capacity();
416 let mut max_read_size = size_hint
419 .and_then(|s| s.checked_add(1024)?.checked_next_multiple_of(DEFAULT_BUF_SIZE))
420 .unwrap_or(DEFAULT_BUF_SIZE);
421
422 let mut initialized = 0; const PROBE_SIZE: usize = 32;
425
426 fn small_probe_read<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
427 let mut probe = [0u8; PROBE_SIZE];
428
429 loop {
430 match r.read(&mut probe) {
431 Ok(n) => {
432 buf.extend_from_slice(&probe[..n]);
435 return Ok(n);
436 }
437 Err(ref e) if e.is_interrupted() => continue,
438 Err(e) => return Err(e),
439 }
440 }
441 }
442
443 if (size_hint.is_none() || size_hint == Some(0)) && buf.capacity() - buf.len() < PROBE_SIZE {
445 let read = small_probe_read(r, buf)?;
446
447 if read == 0 {
448 return Ok(0);
449 }
450 }
451
452 let mut consecutive_short_reads = 0;
453
454 loop {
455 if buf.len() == buf.capacity() && buf.capacity() == start_cap {
456 let read = small_probe_read(r, buf)?;
461
462 if read == 0 {
463 return Ok(buf.len() - start_len);
464 }
465 }
466
467 if buf.len() == buf.capacity() {
468 buf.try_reserve(PROBE_SIZE)?;
470 }
471
472 let mut spare = buf.spare_capacity_mut();
473 let buf_len = cmp::min(spare.len(), max_read_size);
474 spare = &mut spare[..buf_len];
475 let mut read_buf: BorrowedBuf<'_> = spare.into();
476
477 unsafe {
479 read_buf.set_init(initialized);
480 }
481
482 let mut cursor = read_buf.unfilled();
483 let result = loop {
484 match r.read_buf(cursor.reborrow()) {
485 Err(e) if e.is_interrupted() => continue,
486 res => break res,
489 }
490 };
491
492 let unfilled_but_initialized = cursor.init_mut().len();
493 let bytes_read = cursor.written();
494 let was_fully_initialized = read_buf.init_len() == buf_len;
495
496 unsafe {
498 let new_len = bytes_read + buf.len();
499 buf.set_len(new_len);
500 }
501
502 result?;
504
505 if bytes_read == 0 {
506 return Ok(buf.len() - start_len);
507 }
508
509 if bytes_read < buf_len {
510 consecutive_short_reads += 1;
511 } else {
512 consecutive_short_reads = 0;
513 }
514
515 initialized = unfilled_but_initialized;
517
518 if size_hint.is_none() {
520 if !was_fully_initialized && consecutive_short_reads > 1 {
527 max_read_size = usize::MAX;
528 }
529
530 if buf_len >= max_read_size && bytes_read == buf_len {
533 max_read_size = max_read_size.saturating_mul(2);
534 }
535 }
536 }
537}
538
539pub(crate) fn default_read_to_string<R: Read + ?Sized>(
540 r: &mut R,
541 buf: &mut String,
542 size_hint: Option<usize>,
543) -> Result<usize> {
544 unsafe { append_to_string(buf, |b| default_read_to_end(r, b, size_hint)) }
554}
555
556pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>
557where
558 F: FnOnce(&mut [u8]) -> Result<usize>,
559{
560 let buf = bufs.iter_mut().find(|b| !b.is_empty()).map_or(&mut [][..], |b| &mut **b);
561 read(buf)
562}
563
564pub(crate) fn default_write_vectored<F>(write: F, bufs: &[IoSlice<'_>]) -> Result<usize>
565where
566 F: FnOnce(&[u8]) -> Result<usize>,
567{
568 let buf = bufs.iter().find(|b| !b.is_empty()).map_or(&[][..], |b| &**b);
569 write(buf)
570}
571
572pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [u8]) -> Result<()> {
573 while !buf.is_empty() {
574 match this.read(buf) {
575 Ok(0) => break,
576 Ok(n) => {
577 buf = &mut buf[n..];
578 }
579 Err(ref e) if e.is_interrupted() => {}
580 Err(e) => return Err(e),
581 }
582 }
583 if !buf.is_empty() { Err(Error::READ_EXACT_EOF) } else { Ok(()) }
584}
585
586pub(crate) fn default_read_buf<F>(read: F, mut cursor: BorrowedCursor<'_>) -> Result<()>
587where
588 F: FnOnce(&mut [u8]) -> Result<usize>,
589{
590 let n = read(cursor.ensure_init().init_mut())?;
591 cursor.advance(n);
592 Ok(())
593}
594
595pub(crate) fn default_read_buf_exact<R: Read + ?Sized>(
596 this: &mut R,
597 mut cursor: BorrowedCursor<'_>,
598) -> Result<()> {
599 while cursor.capacity() > 0 {
600 let prev_written = cursor.written();
601 match this.read_buf(cursor.reborrow()) {
602 Ok(()) => {}
603 Err(e) if e.is_interrupted() => continue,
604 Err(e) => return Err(e),
605 }
606
607 if cursor.written() == prev_written {
608 return Err(Error::READ_EXACT_EOF);
609 }
610 }
611
612 Ok(())
613}
614
615pub(crate) fn default_write_fmt<W: Write + ?Sized>(
616 this: &mut W,
617 args: fmt::Arguments<'_>,
618) -> Result<()> {
619 struct Adapter<'a, T: ?Sized + 'a> {
622 inner: &'a mut T,
623 error: Result<()>,
624 }
625
626 impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
627 fn write_str(&mut self, s: &str) -> fmt::Result {
628 match self.inner.write_all(s.as_bytes()) {
629 Ok(()) => Ok(()),
630 Err(e) => {
631 self.error = Err(e);
632 Err(fmt::Error)
633 }
634 }
635 }
636 }
637
638 let mut output = Adapter { inner: this, error: Ok(()) };
639 match fmt::write(&mut output, args) {
640 Ok(()) => Ok(()),
641 Err(..) => {
642 if output.error.is_err() {
644 output.error
645 } else {
646 panic!(
649 "a formatting trait implementation returned an error when the underlying stream did not"
650 );
651 }
652 }
653 }
654}
655
656#[stable(feature = "rust1", since = "1.0.0")]
730#[doc(notable_trait)]
731#[cfg_attr(not(test), rustc_diagnostic_item = "IoRead")]
732pub trait Read {
733 #[stable(feature = "rust1", since = "1.0.0")]
813 fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
814
815 #[stable(feature = "iovec", since = "1.36.0")]
825 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
826 default_read_vectored(|b| self.read(b), bufs)
827 }
828
829 #[unstable(feature = "can_vector", issue = "69941")]
838 fn is_read_vectored(&self) -> bool {
839 false
840 }
841
842 #[stable(feature = "rust1", since = "1.0.0")]
935 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
936 default_read_to_end(self, buf, None)
937 }
938
939 #[stable(feature = "rust1", since = "1.0.0")]
991 fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
992 default_read_to_string(self, buf, None)
993 }
994
995 #[stable(feature = "read_exact", since = "1.6.0")]
1044 fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
1045 default_read_exact(self, buf)
1046 }
1047
1048 #[unstable(feature = "read_buf", issue = "78485")]
1057 fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {
1058 default_read_buf(|b| self.read(b), buf)
1059 }
1060
1061 #[unstable(feature = "read_buf", issue = "78485")]
1080 fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> {
1081 default_read_buf_exact(self, cursor)
1082 }
1083
1084 #[stable(feature = "rust1", since = "1.0.0")]
1119 fn by_ref(&mut self) -> &mut Self
1120 where
1121 Self: Sized,
1122 {
1123 self
1124 }
1125
1126 #[stable(feature = "rust1", since = "1.0.0")]
1162 fn bytes(self) -> Bytes<Self>
1163 where
1164 Self: Sized,
1165 {
1166 Bytes { inner: self }
1167 }
1168
1169 #[stable(feature = "rust1", since = "1.0.0")]
1200 fn chain<R: Read>(self, next: R) -> Chain<Self, R>
1201 where
1202 Self: Sized,
1203 {
1204 Chain { first: self, second: next, done_first: false }
1205 }
1206
1207 #[stable(feature = "rust1", since = "1.0.0")]
1239 fn take(self, limit: u64) -> Take<Self>
1240 where
1241 Self: Sized,
1242 {
1243 Take { inner: self, len: limit, limit }
1244 }
1245}
1246
1247#[stable(feature = "io_read_to_string", since = "1.65.0")]
1306pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
1307 let mut buf = String::new();
1308 reader.read_to_string(&mut buf)?;
1309 Ok(buf)
1310}
1311
1312#[stable(feature = "iovec", since = "1.36.0")]
1318#[repr(transparent)]
1319pub struct IoSliceMut<'a>(sys::io::IoSliceMut<'a>);
1320
1321#[stable(feature = "iovec_send_sync", since = "1.44.0")]
1322unsafe impl<'a> Send for IoSliceMut<'a> {}
1323
1324#[stable(feature = "iovec_send_sync", since = "1.44.0")]
1325unsafe impl<'a> Sync for IoSliceMut<'a> {}
1326
1327#[stable(feature = "iovec", since = "1.36.0")]
1328impl<'a> fmt::Debug for IoSliceMut<'a> {
1329 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1330 fmt::Debug::fmt(self.0.as_slice(), fmt)
1331 }
1332}
1333
1334impl<'a> IoSliceMut<'a> {
1335 #[stable(feature = "iovec", since = "1.36.0")]
1341 #[inline]
1342 pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
1343 IoSliceMut(sys::io::IoSliceMut::new(buf))
1344 }
1345
1346 #[stable(feature = "io_slice_advance", since = "1.81.0")]
1369 #[inline]
1370 pub fn advance(&mut self, n: usize) {
1371 self.0.advance(n)
1372 }
1373
1374 #[stable(feature = "io_slice_advance", since = "1.81.0")]
1408 #[inline]
1409 pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) {
1410 let mut remove = 0;
1412 let mut left = n;
1414 for buf in bufs.iter() {
1415 if let Some(remainder) = left.checked_sub(buf.len()) {
1416 left = remainder;
1417 remove += 1;
1418 } else {
1419 break;
1420 }
1421 }
1422
1423 *bufs = &mut take(bufs)[remove..];
1424 if bufs.is_empty() {
1425 assert!(left == 0, "advancing io slices beyond their length");
1426 } else {
1427 bufs[0].advance(left);
1428 }
1429 }
1430
1431 #[unstable(feature = "io_slice_as_bytes", issue = "132818")]
1446 pub const fn into_slice(self) -> &'a mut [u8] {
1447 self.0.into_slice()
1448 }
1449}
1450
1451#[stable(feature = "iovec", since = "1.36.0")]
1452impl<'a> Deref for IoSliceMut<'a> {
1453 type Target = [u8];
1454
1455 #[inline]
1456 fn deref(&self) -> &[u8] {
1457 self.0.as_slice()
1458 }
1459}
1460
1461#[stable(feature = "iovec", since = "1.36.0")]
1462impl<'a> DerefMut for IoSliceMut<'a> {
1463 #[inline]
1464 fn deref_mut(&mut self) -> &mut [u8] {
1465 self.0.as_mut_slice()
1466 }
1467}
1468
1469#[stable(feature = "iovec", since = "1.36.0")]
1475#[derive(Copy, Clone)]
1476#[repr(transparent)]
1477pub struct IoSlice<'a>(sys::io::IoSlice<'a>);
1478
1479#[stable(feature = "iovec_send_sync", since = "1.44.0")]
1480unsafe impl<'a> Send for IoSlice<'a> {}
1481
1482#[stable(feature = "iovec_send_sync", since = "1.44.0")]
1483unsafe impl<'a> Sync for IoSlice<'a> {}
1484
1485#[stable(feature = "iovec", since = "1.36.0")]
1486impl<'a> fmt::Debug for IoSlice<'a> {
1487 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1488 fmt::Debug::fmt(self.0.as_slice(), fmt)
1489 }
1490}
1491
1492impl<'a> IoSlice<'a> {
1493 #[stable(feature = "iovec", since = "1.36.0")]
1499 #[must_use]
1500 #[inline]
1501 pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
1502 IoSlice(sys::io::IoSlice::new(buf))
1503 }
1504
1505 #[stable(feature = "io_slice_advance", since = "1.81.0")]
1528 #[inline]
1529 pub fn advance(&mut self, n: usize) {
1530 self.0.advance(n)
1531 }
1532
1533 #[stable(feature = "io_slice_advance", since = "1.81.0")]
1566 #[inline]
1567 pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) {
1568 let mut remove = 0;
1570 let mut left = n;
1575 for buf in bufs.iter() {
1576 if let Some(remainder) = left.checked_sub(buf.len()) {
1577 left = remainder;
1578 remove += 1;
1579 } else {
1580 break;
1581 }
1582 }
1583
1584 *bufs = &mut take(bufs)[remove..];
1585 if bufs.is_empty() {
1586 assert!(left == 0, "advancing io slices beyond their length");
1587 } else {
1588 bufs[0].advance(left);
1589 }
1590 }
1591
1592 #[unstable(feature = "io_slice_as_bytes", issue = "132818")]
1614 pub const fn as_slice(self) -> &'a [u8] {
1615 self.0.as_slice()
1616 }
1617}
1618
1619#[stable(feature = "iovec", since = "1.36.0")]
1620impl<'a> Deref for IoSlice<'a> {
1621 type Target = [u8];
1622
1623 #[inline]
1624 fn deref(&self) -> &[u8] {
1625 self.0.as_slice()
1626 }
1627}
1628
1629#[stable(feature = "rust1", since = "1.0.0")]
1675#[doc(notable_trait)]
1676#[cfg_attr(not(test), rustc_diagnostic_item = "IoWrite")]
1677pub trait Write {
1678 #[stable(feature = "rust1", since = "1.0.0")]
1724 fn write(&mut self, buf: &[u8]) -> Result<usize>;
1725
1726 #[stable(feature = "iovec", since = "1.36.0")]
1758 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
1759 default_write_vectored(|b| self.write(b), bufs)
1760 }
1761
1762 #[unstable(feature = "can_vector", issue = "69941")]
1773 fn is_write_vectored(&self) -> bool {
1774 false
1775 }
1776
1777 #[stable(feature = "rust1", since = "1.0.0")]
1801 fn flush(&mut self) -> Result<()>;
1802
1803 #[stable(feature = "rust1", since = "1.0.0")]
1835 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
1836 while !buf.is_empty() {
1837 match self.write(buf) {
1838 Ok(0) => {
1839 return Err(Error::WRITE_ALL_EOF);
1840 }
1841 Ok(n) => buf = &buf[n..],
1842 Err(ref e) if e.is_interrupted() => {}
1843 Err(e) => return Err(e),
1844 }
1845 }
1846 Ok(())
1847 }
1848
1849 #[unstable(feature = "write_all_vectored", issue = "70436")]
1897 fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
1898 IoSlice::advance_slices(&mut bufs, 0);
1901 while !bufs.is_empty() {
1902 match self.write_vectored(bufs) {
1903 Ok(0) => {
1904 return Err(Error::WRITE_ALL_EOF);
1905 }
1906 Ok(n) => IoSlice::advance_slices(&mut bufs, n),
1907 Err(ref e) if e.is_interrupted() => {}
1908 Err(e) => return Err(e),
1909 }
1910 }
1911 Ok(())
1912 }
1913
1914 #[stable(feature = "rust1", since = "1.0.0")]
1950 fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<()> {
1951 if let Some(s) = args.as_statically_known_str() {
1952 self.write_all(s.as_bytes())
1953 } else {
1954 default_write_fmt(self, args)
1955 }
1956 }
1957
1958 #[stable(feature = "rust1", since = "1.0.0")]
1980 fn by_ref(&mut self) -> &mut Self
1981 where
1982 Self: Sized,
1983 {
1984 self
1985 }
1986}
1987
1988#[stable(feature = "rust1", since = "1.0.0")]
2015#[cfg_attr(not(test), rustc_diagnostic_item = "IoSeek")]
2016pub trait Seek {
2017 #[stable(feature = "rust1", since = "1.0.0")]
2032 fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
2033
2034 #[stable(feature = "seek_rewind", since = "1.55.0")]
2064 fn rewind(&mut self) -> Result<()> {
2065 self.seek(SeekFrom::Start(0))?;
2066 Ok(())
2067 }
2068
2069 #[unstable(feature = "seek_stream_len", issue = "59359")]
2104 fn stream_len(&mut self) -> Result<u64> {
2105 stream_len_default(self)
2106 }
2107
2108 #[stable(feature = "seek_convenience", since = "1.51.0")]
2132 fn stream_position(&mut self) -> Result<u64> {
2133 self.seek(SeekFrom::Current(0))
2134 }
2135
2136 #[stable(feature = "seek_seek_relative", since = "1.80.0")]
2160 fn seek_relative(&mut self, offset: i64) -> Result<()> {
2161 self.seek(SeekFrom::Current(offset))?;
2162 Ok(())
2163 }
2164}
2165
2166pub(crate) fn stream_len_default<T: Seek + ?Sized>(self_: &mut T) -> Result<u64> {
2167 let old_pos = self_.stream_position()?;
2168 let len = self_.seek(SeekFrom::End(0))?;
2169
2170 if old_pos != len {
2173 self_.seek(SeekFrom::Start(old_pos))?;
2174 }
2175
2176 Ok(len)
2177}
2178
2179#[derive(Copy, PartialEq, Eq, Clone, Debug)]
2183#[stable(feature = "rust1", since = "1.0.0")]
2184#[cfg_attr(not(test), rustc_diagnostic_item = "SeekFrom")]
2185pub enum SeekFrom {
2186 #[stable(feature = "rust1", since = "1.0.0")]
2188 Start(#[stable(feature = "rust1", since = "1.0.0")] u64),
2189
2190 #[stable(feature = "rust1", since = "1.0.0")]
2196 End(#[stable(feature = "rust1", since = "1.0.0")] i64),
2197
2198 #[stable(feature = "rust1", since = "1.0.0")]
2204 Current(#[stable(feature = "rust1", since = "1.0.0")] i64),
2205}
2206
2207fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> Result<usize> {
2208 let mut read = 0;
2209 loop {
2210 let (done, used) = {
2211 let available = match r.fill_buf() {
2212 Ok(n) => n,
2213 Err(ref e) if e.is_interrupted() => continue,
2214 Err(e) => return Err(e),
2215 };
2216 match memchr::memchr(delim, available) {
2217 Some(i) => {
2218 buf.extend_from_slice(&available[..=i]);
2219 (true, i + 1)
2220 }
2221 None => {
2222 buf.extend_from_slice(available);
2223 (false, available.len())
2224 }
2225 }
2226 };
2227 r.consume(used);
2228 read += used;
2229 if done || used == 0 {
2230 return Ok(read);
2231 }
2232 }
2233}
2234
2235fn skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize> {
2236 let mut read = 0;
2237 loop {
2238 let (done, used) = {
2239 let available = match r.fill_buf() {
2240 Ok(n) => n,
2241 Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
2242 Err(e) => return Err(e),
2243 };
2244 match memchr::memchr(delim, available) {
2245 Some(i) => (true, i + 1),
2246 None => (false, available.len()),
2247 }
2248 };
2249 r.consume(used);
2250 read += used;
2251 if done || used == 0 {
2252 return Ok(read);
2253 }
2254 }
2255}
2256
2257#[stable(feature = "rust1", since = "1.0.0")]
2307#[cfg_attr(not(test), rustc_diagnostic_item = "IoBufRead")]
2308pub trait BufRead: Read {
2309 #[stable(feature = "rust1", since = "1.0.0")]
2344 fn fill_buf(&mut self) -> Result<&[u8]>;
2345
2346 #[stable(feature = "rust1", since = "1.0.0")]
2361 fn consume(&mut self, amount: usize);
2362
2363 #[unstable(feature = "buf_read_has_data_left", reason = "recently added", issue = "86423")]
2395 fn has_data_left(&mut self) -> Result<bool> {
2396 self.fill_buf().map(|b| !b.is_empty())
2397 }
2398
2399 #[stable(feature = "rust1", since = "1.0.0")]
2454 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
2455 read_until(self, byte, buf)
2456 }
2457
2458 #[stable(feature = "bufread_skip_until", since = "1.83.0")]
2514 fn skip_until(&mut self, byte: u8) -> Result<usize> {
2515 skip_until(self, byte)
2516 }
2517
2518 #[stable(feature = "rust1", since = "1.0.0")]
2582 fn read_line(&mut self, buf: &mut String) -> Result<usize> {
2583 unsafe { append_to_string(buf, |b| read_until(self, b'\n', b)) }
2587 }
2588
2589 #[stable(feature = "rust1", since = "1.0.0")]
2620 fn split(self, byte: u8) -> Split<Self>
2621 where
2622 Self: Sized,
2623 {
2624 Split { buf: self, delim: byte }
2625 }
2626
2627 #[stable(feature = "rust1", since = "1.0.0")]
2657 fn lines(self) -> Lines<Self>
2658 where
2659 Self: Sized,
2660 {
2661 Lines { buf: self }
2662 }
2663}
2664
2665#[stable(feature = "rust1", since = "1.0.0")]
2672#[derive(Debug)]
2673pub struct Chain<T, U> {
2674 first: T,
2675 second: U,
2676 done_first: bool,
2677}
2678
2679impl<T, U> Chain<T, U> {
2680 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
2699 pub fn into_inner(self) -> (T, U) {
2700 (self.first, self.second)
2701 }
2702
2703 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
2726 pub fn get_ref(&self) -> (&T, &U) {
2727 (&self.first, &self.second)
2728 }
2729
2730 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
2753 pub fn get_mut(&mut self) -> (&mut T, &mut U) {
2754 (&mut self.first, &mut self.second)
2755 }
2756}
2757
2758#[stable(feature = "rust1", since = "1.0.0")]
2759impl<T: Read, U: Read> Read for Chain<T, U> {
2760 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
2761 if !self.done_first {
2762 match self.first.read(buf)? {
2763 0 if !buf.is_empty() => self.done_first = true,
2764 n => return Ok(n),
2765 }
2766 }
2767 self.second.read(buf)
2768 }
2769
2770 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
2771 if !self.done_first {
2772 match self.first.read_vectored(bufs)? {
2773 0 if bufs.iter().any(|b| !b.is_empty()) => self.done_first = true,
2774 n => return Ok(n),
2775 }
2776 }
2777 self.second.read_vectored(bufs)
2778 }
2779
2780 #[inline]
2781 fn is_read_vectored(&self) -> bool {
2782 self.first.is_read_vectored() || self.second.is_read_vectored()
2783 }
2784
2785 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
2786 let mut read = 0;
2787 if !self.done_first {
2788 read += self.first.read_to_end(buf)?;
2789 self.done_first = true;
2790 }
2791 read += self.second.read_to_end(buf)?;
2792 Ok(read)
2793 }
2794
2795 fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> Result<()> {
2799 if buf.capacity() == 0 {
2800 return Ok(());
2801 }
2802
2803 if !self.done_first {
2804 let old_len = buf.written();
2805 self.first.read_buf(buf.reborrow())?;
2806
2807 if buf.written() != old_len {
2808 return Ok(());
2809 } else {
2810 self.done_first = true;
2811 }
2812 }
2813 self.second.read_buf(buf)
2814 }
2815}
2816
2817#[stable(feature = "chain_bufread", since = "1.9.0")]
2818impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
2819 fn fill_buf(&mut self) -> Result<&[u8]> {
2820 if !self.done_first {
2821 match self.first.fill_buf()? {
2822 buf if buf.is_empty() => self.done_first = true,
2823 buf => return Ok(buf),
2824 }
2825 }
2826 self.second.fill_buf()
2827 }
2828
2829 fn consume(&mut self, amt: usize) {
2830 if !self.done_first { self.first.consume(amt) } else { self.second.consume(amt) }
2831 }
2832
2833 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
2834 let mut read = 0;
2835 if !self.done_first {
2836 let n = self.first.read_until(byte, buf)?;
2837 read += n;
2838
2839 match buf.last() {
2840 Some(b) if *b == byte && n != 0 => return Ok(read),
2841 _ => self.done_first = true,
2842 }
2843 }
2844 read += self.second.read_until(byte, buf)?;
2845 Ok(read)
2846 }
2847
2848 }
2851
2852impl<T, U> SizeHint for Chain<T, U> {
2853 #[inline]
2854 fn lower_bound(&self) -> usize {
2855 SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
2856 }
2857
2858 #[inline]
2859 fn upper_bound(&self) -> Option<usize> {
2860 match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
2861 (Some(first), Some(second)) => first.checked_add(second),
2862 _ => None,
2863 }
2864 }
2865}
2866
2867#[stable(feature = "rust1", since = "1.0.0")]
2874#[derive(Debug)]
2875pub struct Take<T> {
2876 inner: T,
2877 len: u64,
2878 limit: u64,
2879}
2880
2881impl<T> Take<T> {
2882 #[stable(feature = "rust1", since = "1.0.0")]
2908 pub fn limit(&self) -> u64 {
2909 self.limit
2910 }
2911
2912 #[unstable(feature = "seek_io_take_position", issue = "97227")]
2914 pub fn position(&self) -> u64 {
2915 self.len - self.limit
2916 }
2917
2918 #[stable(feature = "take_set_limit", since = "1.27.0")]
2942 pub fn set_limit(&mut self, limit: u64) {
2943 self.len = limit;
2944 self.limit = limit;
2945 }
2946
2947 #[stable(feature = "io_take_into_inner", since = "1.15.0")]
2968 pub fn into_inner(self) -> T {
2969 self.inner
2970 }
2971
2972 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
2997 pub fn get_ref(&self) -> &T {
2998 &self.inner
2999 }
3000
3001 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
3026 pub fn get_mut(&mut self) -> &mut T {
3027 &mut self.inner
3028 }
3029}
3030
3031#[stable(feature = "rust1", since = "1.0.0")]
3032impl<T: Read> Read for Take<T> {
3033 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
3034 if self.limit == 0 {
3036 return Ok(0);
3037 }
3038
3039 let max = cmp::min(buf.len() as u64, self.limit) as usize;
3040 let n = self.inner.read(&mut buf[..max])?;
3041 assert!(n as u64 <= self.limit, "number of read bytes exceeds limit");
3042 self.limit -= n as u64;
3043 Ok(n)
3044 }
3045
3046 fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> Result<()> {
3047 if self.limit == 0 {
3049 return Ok(());
3050 }
3051
3052 if self.limit < buf.capacity() as u64 {
3053 let limit = self.limit as usize;
3055
3056 let extra_init = cmp::min(limit, buf.init_mut().len());
3057
3058 let ibuf = unsafe { &mut buf.as_mut()[..limit] };
3060
3061 let mut sliced_buf: BorrowedBuf<'_> = ibuf.into();
3062
3063 unsafe {
3065 sliced_buf.set_init(extra_init);
3066 }
3067
3068 let mut cursor = sliced_buf.unfilled();
3069 let result = self.inner.read_buf(cursor.reborrow());
3070
3071 let new_init = cursor.init_mut().len();
3072 let filled = sliced_buf.len();
3073
3074 unsafe {
3077 buf.advance_unchecked(filled);
3079 buf.set_init(new_init);
3081 }
3082
3083 self.limit -= filled as u64;
3084
3085 result
3086 } else {
3087 let written = buf.written();
3088 let result = self.inner.read_buf(buf.reborrow());
3089 self.limit -= (buf.written() - written) as u64;
3090 result
3091 }
3092 }
3093}
3094
3095#[stable(feature = "rust1", since = "1.0.0")]
3096impl<T: BufRead> BufRead for Take<T> {
3097 fn fill_buf(&mut self) -> Result<&[u8]> {
3098 if self.limit == 0 {
3100 return Ok(&[]);
3101 }
3102
3103 let buf = self.inner.fill_buf()?;
3104 let cap = cmp::min(buf.len() as u64, self.limit) as usize;
3105 Ok(&buf[..cap])
3106 }
3107
3108 fn consume(&mut self, amt: usize) {
3109 let amt = cmp::min(amt as u64, self.limit) as usize;
3111 self.limit -= amt as u64;
3112 self.inner.consume(amt);
3113 }
3114}
3115
3116impl<T> SizeHint for Take<T> {
3117 #[inline]
3118 fn lower_bound(&self) -> usize {
3119 cmp::min(SizeHint::lower_bound(&self.inner) as u64, self.limit) as usize
3120 }
3121
3122 #[inline]
3123 fn upper_bound(&self) -> Option<usize> {
3124 match SizeHint::upper_bound(&self.inner) {
3125 Some(upper_bound) => Some(cmp::min(upper_bound as u64, self.limit) as usize),
3126 None => self.limit.try_into().ok(),
3127 }
3128 }
3129}
3130
3131#[stable(feature = "seek_io_take", since = "1.89.0")]
3132impl<T: Seek> Seek for Take<T> {
3133 fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
3134 let new_position = match pos {
3135 SeekFrom::Start(v) => Some(v),
3136 SeekFrom::Current(v) => self.position().checked_add_signed(v),
3137 SeekFrom::End(v) => self.len.checked_add_signed(v),
3138 };
3139 let new_position = match new_position {
3140 Some(v) if v <= self.len => v,
3141 _ => return Err(ErrorKind::InvalidInput.into()),
3142 };
3143 while new_position != self.position() {
3144 if let Some(offset) = new_position.checked_signed_diff(self.position()) {
3145 self.inner.seek_relative(offset)?;
3146 self.limit = self.limit.wrapping_sub(offset as u64);
3147 break;
3148 }
3149 let offset = if new_position > self.position() { i64::MAX } else { i64::MIN };
3150 self.inner.seek_relative(offset)?;
3151 self.limit = self.limit.wrapping_sub(offset as u64);
3152 }
3153 Ok(new_position)
3154 }
3155
3156 fn stream_len(&mut self) -> Result<u64> {
3157 Ok(self.len)
3158 }
3159
3160 fn stream_position(&mut self) -> Result<u64> {
3161 Ok(self.position())
3162 }
3163
3164 fn seek_relative(&mut self, offset: i64) -> Result<()> {
3165 if !self.position().checked_add_signed(offset).is_some_and(|p| p <= self.len) {
3166 return Err(ErrorKind::InvalidInput.into());
3167 }
3168 self.inner.seek_relative(offset)?;
3169 self.limit = self.limit.wrapping_sub(offset as u64);
3170 Ok(())
3171 }
3172}
3173
3174#[stable(feature = "rust1", since = "1.0.0")]
3181#[derive(Debug)]
3182pub struct Bytes<R> {
3183 inner: R,
3184}
3185
3186#[stable(feature = "rust1", since = "1.0.0")]
3187impl<R: Read> Iterator for Bytes<R> {
3188 type Item = Result<u8>;
3189
3190 fn next(&mut self) -> Option<Result<u8>> {
3193 SpecReadByte::spec_read_byte(&mut self.inner)
3194 }
3195
3196 #[inline]
3197 fn size_hint(&self) -> (usize, Option<usize>) {
3198 SizeHint::size_hint(&self.inner)
3199 }
3200}
3201
3202trait SpecReadByte {
3204 fn spec_read_byte(&mut self) -> Option<Result<u8>>;
3205}
3206
3207impl<R> SpecReadByte for R
3208where
3209 Self: Read,
3210{
3211 #[inline]
3212 default fn spec_read_byte(&mut self) -> Option<Result<u8>> {
3213 inlined_slow_read_byte(self)
3214 }
3215}
3216
3217#[inline]
3220fn inlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> {
3221 let mut byte = 0;
3222 loop {
3223 return match reader.read(slice::from_mut(&mut byte)) {
3224 Ok(0) => None,
3225 Ok(..) => Some(Ok(byte)),
3226 Err(ref e) if e.is_interrupted() => continue,
3227 Err(e) => Some(Err(e)),
3228 };
3229 }
3230}
3231
3232#[inline(never)]
3235fn uninlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> {
3236 inlined_slow_read_byte(reader)
3237}
3238
3239trait SizeHint {
3240 fn lower_bound(&self) -> usize;
3241
3242 fn upper_bound(&self) -> Option<usize>;
3243
3244 fn size_hint(&self) -> (usize, Option<usize>) {
3245 (self.lower_bound(), self.upper_bound())
3246 }
3247}
3248
3249impl<T: ?Sized> SizeHint for T {
3250 #[inline]
3251 default fn lower_bound(&self) -> usize {
3252 0
3253 }
3254
3255 #[inline]
3256 default fn upper_bound(&self) -> Option<usize> {
3257 None
3258 }
3259}
3260
3261impl<T> SizeHint for &mut T {
3262 #[inline]
3263 fn lower_bound(&self) -> usize {
3264 SizeHint::lower_bound(*self)
3265 }
3266
3267 #[inline]
3268 fn upper_bound(&self) -> Option<usize> {
3269 SizeHint::upper_bound(*self)
3270 }
3271}
3272
3273impl<T> SizeHint for Box<T> {
3274 #[inline]
3275 fn lower_bound(&self) -> usize {
3276 SizeHint::lower_bound(&**self)
3277 }
3278
3279 #[inline]
3280 fn upper_bound(&self) -> Option<usize> {
3281 SizeHint::upper_bound(&**self)
3282 }
3283}
3284
3285impl SizeHint for &[u8] {
3286 #[inline]
3287 fn lower_bound(&self) -> usize {
3288 self.len()
3289 }
3290
3291 #[inline]
3292 fn upper_bound(&self) -> Option<usize> {
3293 Some(self.len())
3294 }
3295}
3296
3297#[stable(feature = "rust1", since = "1.0.0")]
3305#[derive(Debug)]
3306pub struct Split<B> {
3307 buf: B,
3308 delim: u8,
3309}
3310
3311#[stable(feature = "rust1", since = "1.0.0")]
3312impl<B: BufRead> Iterator for Split<B> {
3313 type Item = Result<Vec<u8>>;
3314
3315 fn next(&mut self) -> Option<Result<Vec<u8>>> {
3316 let mut buf = Vec::new();
3317 match self.buf.read_until(self.delim, &mut buf) {
3318 Ok(0) => None,
3319 Ok(_n) => {
3320 if buf[buf.len() - 1] == self.delim {
3321 buf.pop();
3322 }
3323 Some(Ok(buf))
3324 }
3325 Err(e) => Some(Err(e)),
3326 }
3327 }
3328}
3329
3330#[stable(feature = "rust1", since = "1.0.0")]
3337#[derive(Debug)]
3338#[cfg_attr(not(test), rustc_diagnostic_item = "IoLines")]
3339pub struct Lines<B> {
3340 buf: B,
3341}
3342
3343#[stable(feature = "rust1", since = "1.0.0")]
3344impl<B: BufRead> Iterator for Lines<B> {
3345 type Item = Result<String>;
3346
3347 fn next(&mut self) -> Option<Result<String>> {
3348 let mut buf = String::new();
3349 match self.buf.read_line(&mut buf) {
3350 Ok(0) => None,
3351 Ok(_n) => {
3352 if buf.ends_with('\n') {
3353 buf.pop();
3354 if buf.ends_with('\r') {
3355 buf.pop();
3356 }
3357 }
3358 Some(Ok(buf))
3359 }
3360 Err(e) => Some(Err(e)),
3361 }
3362 }
3363}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4