#[cfg(feature = "alloc")]
use crate::{IoError, Vec};
use crate::{IoErrorKind, IoRead, IoResult, IoSeek, IoSeekFrom, IoWrite, impl_trait, sf};
pub(crate) fn io_copy<R, W, const LEN: usize>(reader: &mut R, writer: &mut W) -> IoResult<u64>
where
R: ?Sized + IoRead,
W: ?Sized + IoWrite,
{
#[cfg(any(feature = "safe_io", not(feature = "unsafe_array")))]
let mut buf = [0u8; LEN];
#[cfg(all(not(feature = "safe_io"), feature = "unsafe_array"))]
let mut buf = crate::MaybeUninit::<[u8; LEN]>::uninit();
let mut written = 0;
loop {
let len = match reader.read({
#[cfg(any(feature = "safe_io", not(feature = "unsafe_array")))]
sf! { &mut buf }
#[cfg(all(not(feature = "safe_io"), feature = "unsafe_array"))]
sf! { unsafe { &mut *buf.as_mut_ptr() } }
}) {
Ok(0) => return Ok(written),
Ok(len) => len,
Err(ref e) if e.kind() == IoErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
#[cfg(any(feature = "safe_io", not(feature = "unsafe_array")))]
writer.write_all(&buf[..len])?;
#[cfg(all(not(feature = "safe_io"), feature = "unsafe_array"))]
writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?;
written += len as u64;
}
}
#[doc = crate::_tags!(io)]
#[non_exhaustive]
#[derive(Copy, Clone, Debug, Default)]
pub struct IoEmpty;
sf! {
pub(crate) const fn io_empty() -> IoEmpty { IoEmpty }
impl IoRead for IoEmpty {
fn read(&mut self, _buf: &mut [u8]) -> IoResult<usize> { Ok(0) }
}
impl IoWrite for IoEmpty {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> { Ok(buf.len()) }
fn flush(&mut self) -> IoResult<()> { Ok(()) }
}
impl IoWrite for &IoEmpty {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> { Ok(buf.len()) }
fn flush(&mut self) -> IoResult<()> { Ok(()) }
}
impl IoSeek for IoEmpty {
fn seek(&mut self, _pos: IoSeekFrom) -> IoResult<u64> { Ok(0) }
}
}
#[doc = crate::_tags!(io)]
pub struct IoRepeat {
byte: u8,
}
impl_trait![fmt::Debug for IoRepeat |self, f| f.debug_struct("IoRepeat").finish_non_exhaustive()];
sf! {
pub(crate) const fn io_repeat(byte: u8) -> IoRepeat { IoRepeat { byte } }
impl IoRead for IoRepeat {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
for slot in &mut *buf { *slot = self.byte; }
Ok(buf.len())
}
#[cfg(feature = "alloc")]
#[cfg_attr(nightly_doc, doc(cfg(feature = "alloc")))]
fn read_to_end(&mut self, _: &mut Vec<u8>) -> IoResult<usize> {
Err(IoError::from(IoErrorKind::OutOfMemory))
}
}
}