use crate::{
result::{Result},
lmem,
util::{
data::{d8},
error::{DeviceFull, NoError},
},
};
use core::{mem, fmt};
pub trait Read {
fn scatter_read(&mut self, buf: &mut [&mut [d8]]) -> Result<usize>;
fn read(&mut self, buf: &mut [d8]) -> Result<usize> {
self.scatter_read(&mut [buf])
}
fn read_all(&mut self, mut buf: &mut [d8]) -> Result<usize> {
let mut read = 0;
while buf.len() > 0 {
match self.read(buf) {
e @ Err(_) => return e,
Ok(0) => break,
Ok(n) => {
read += n;
buf = &mut buf[n..];
}
}
}
Ok(read)
}
}
pub trait BufRead : Read {
fn copy_until<W: Write>(&mut self, dst: &mut W, b: u8) -> Result<usize>;
fn consume(&mut self, num: usize) -> usize;
}
pub trait Write {
fn gather_write(&mut self, buf: &[&[u8]]) -> Result<usize>;
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.gather_write(&[buf])
}
fn flush(&mut self) -> Result<()>;
fn write_all(&mut self, mut buf: &[u8]) -> Result<usize> {
let mut written = 0;
while buf.len() > 0 {
match self.write(buf) {
e @ Err(_) => return e,
Ok(0) => return Err(DeviceFull),
Ok(n) => {
written += n;
buf = &buf[n..];
}
}
}
Ok(written)
}
fn write_str(&mut self, buf: &str) -> Result<usize> {
self.write(buf.as_bytes())
}
fn write_fmt_linux(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
struct Adaptor<'a, T: ?Sized + 'a> {
inner: &'a mut T,
error: Result<()>,
}
impl<T: Write + ?Sized> fmt::Write for Adaptor<'_, T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
match self.inner.write_all(s.as_bytes()) {
Ok(_) => Ok(()),
Err(e) => {
self.error = Err(e);
Err(fmt::Error)
}
}
}
}
let mut output = Adaptor { inner: self, error: Ok(()) };
match fmt::write(&mut output, fmt) {
Ok(()) => Ok(()),
Err(..) => {
if output.error.is_err() {
output.error
} else {
Err(NoError)
}
}
}
}
}
pub trait BufWrite : Write {
fn read_to_eof<R>(&mut self, r: R) -> Result<usize>
where R: Read;
fn read<R>(&mut self, r: R, n: usize) -> Result<usize>
where R: Read;
}
impl<'a> Read for &'a [u8] {
fn scatter_read(&mut self, mut buf: &mut [&mut [d8]]) -> Result<usize> {
let mut sum = 0;
while self.len() > 0 && buf.len() > 0 {
sum += self.read(&mut buf[0])?;
let b = buf;
buf = &mut b[1..];
}
Ok(sum)
}
fn read(&mut self, buf: &mut [d8]) -> Result<usize> {
let n = lmem::copy(buf, d8::from_byte_slice(*self));
*self = &self[n..];
Ok(n)
}
}
impl<'a> BufRead for &'a [u8] {
fn copy_until<W: Write+?Sized>(&mut self, dst: &mut W, b: u8) -> Result<usize> {
let mut len = match memchr::memchr(b, self) {
Some(pos) => pos + 1,
_ => self.len(),
};
let total = len;
while len > 0 {
let consumed = match dst.write(&self[..len])? {
0 => break,
n => n,
};
len -= consumed;
self.consume(consumed);
}
Ok(total - len)
}
fn consume(&mut self, num: usize) -> usize {
let num = num.min(self.len());
*self = &self[num..];
num
}
}
impl<'a> Write for &'a mut [u8] {
fn gather_write(&mut self, mut buf: &[&[u8]]) -> Result<usize> {
let mut sum = 0;
while self.len() > 0 && buf.len() > 0 {
sum += self.write(&buf[0])?;
buf = &buf[1..];
}
Ok(sum)
}
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let n = lmem::copy(*self, buf);
unsafe {
*self = mem::transmute::<&mut [u8], &'a mut [u8]>(&mut self[n..]);
}
Ok(n)
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl<'a> Write for &'a mut [d8] {
fn gather_write(&mut self, mut buf: &[&[u8]]) -> Result<usize> {
let mut sum = 0;
while self.len() > 0 && buf.len() > 0 {
sum += self.write(&buf[0])?;
buf = &buf[1..];
}
Ok(sum)
}
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let n = lmem::copy(*self, d8::from_byte_slice(buf));
unsafe {
*self = mem::transmute::<&mut [d8], &'a mut [d8]>(&mut self[n..]);
}
Ok(n)
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl<'a, T: Read+?Sized> Read for &'a mut T {
fn scatter_read(&mut self, buf: &mut [&mut [d8]]) -> Result<usize> {
(**self).scatter_read(buf)
}
fn read(&mut self, buf: &mut [d8]) -> Result<usize> {
(**self).read(buf)
}
fn read_all(&mut self, mut buf: &mut [d8]) -> Result<usize> {
(**self).read_all(buf)
}
}
impl<'a, T: Write+?Sized> Write for &'a mut T {
fn gather_write(&mut self, buf: &[&[u8]]) -> Result<usize> {
(**self).gather_write(buf)
}
fn write(&mut self, buf: &[u8]) -> Result<usize> {
(**self).write(buf)
}
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
fn write_all(&mut self, buf: &[u8]) -> Result<usize> {
(**self).write_all(buf)
}
fn write_str(&mut self, buf: &str) -> Result<usize> {
(**self).write_str(buf)
}
}