use crate::{LINUX_FILENO as FILENO, Linux, LinuxError, LinuxResult as Result, MaybeUninit, c_int};
#[rustfmt::skip]
impl Linux {
const STACK_BUFFER_LEN: usize = 512;
fn write_all(fd: c_int, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
let n = unsafe { Linux::sys_write(fd, buf.as_ptr(), buf.len()) };
if n < 0 { return Err(LinuxError::Sys(n)); }
buf = &buf[n as usize..];
}
Ok(())
}
fn write_all_unchecked(fd: c_int, mut buf: &[u8]) {
while !buf.is_empty() {
let n = unsafe { Linux::sys_write(fd, buf.as_ptr(), buf.len()) };
if n <= 0 { panic!("write failed with return value {n}"); }
buf = &buf[n as usize..];
}
}
pub fn print(s: &str) -> Result<()> {
Self::write_all(FILENO::STDOUT, s.as_bytes())
}
pub fn print_unchecked(s: &str) { Self::write_all_unchecked(FILENO::STDOUT, s.as_bytes()); }
pub fn println(s: &str) -> Result<()> {
if s.len() <= Self::STACK_BUFFER_LEN { let mut buf = [0u8; Self::STACK_BUFFER_LEN];
let bytes = s.as_bytes();
buf[..bytes.len()].copy_from_slice(bytes);
buf[bytes.len()] = b'\n';
Self::write_all(FILENO::STDOUT, &buf[..bytes.len() + 1])
} else { Self::write_all(FILENO::STDOUT, s.as_bytes())?;
Self::write_all(FILENO::STDOUT, b"\n")
}
}
pub fn println_unchecked(s: &str) {
if s.len() <= Self::STACK_BUFFER_LEN {
let mut buf = [0u8; Self::STACK_BUFFER_LEN];
let bytes = s.as_bytes();
buf[..bytes.len()].copy_from_slice(bytes);
buf[bytes.len()] = b'\n';
Self::write_all_unchecked(FILENO::STDOUT, &buf[..bytes.len() + 1]);
} else {
Self::write_all_unchecked(FILENO::STDOUT, s.as_bytes());
Self::write_all_unchecked(FILENO::STDOUT, b"\n");
}
}
pub fn print_unchecked_fast(s: &str) {
let bytes = s.as_bytes();
let n = unsafe { Linux::sys_write(FILENO::STDOUT, bytes.as_ptr(), bytes.len()) };
if n != bytes.len() as isize {
panic!("write failed with return value {n}");
}
}
pub fn println_unchecked_fast(s: &str) {
let bytes = s.as_bytes();
let mut buf = MaybeUninit::<[u8; Self::STACK_BUFFER_LEN]>::uninit();
unsafe {
let buf_ptr = buf.as_mut_ptr() as *mut u8;
core::ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
*buf_ptr.add(bytes.len()) = b'\n'; let n = Linux::sys_write(FILENO::STDOUT, buf_ptr, bytes.len() + 1); if n != (bytes.len() + 1) as isize { panic!("write failed with return value {n}"); }
}
}
pub fn print_bytes(b: &[u8]) -> Result<()> { Self::write_all(FILENO::STDOUT, b) }
pub fn print_bytes_unchecked(b: &[u8]) { Self::write_all_unchecked(FILENO::STDOUT, b); }
pub fn eprint(s: &str) -> Result<()> { Self::write_all(FILENO::STDERR, s.as_bytes()) }
pub fn eprintln(s: &str) -> Result<()> {
if s.len() <= Self::STACK_BUFFER_LEN { let mut buf = [0u8; Self::STACK_BUFFER_LEN];
let bytes = s.as_bytes();
buf[..bytes.len()].copy_from_slice(bytes);
buf[bytes.len()] = b'\n';
Self::write_all(FILENO::STDERR, &buf[..bytes.len() + 1])
} else { Self::write_all(FILENO::STDERR, s.as_bytes())?;
Self::write_all(FILENO::STDERR, b"\n")
}
}
pub fn eprint_bytes(b: &[u8]) -> Result<()> {
Self::write_all(FILENO::STDERR, b)
}
}