pub use bytes::*;
pub use xitca_unsafe_collection::bytes::{BytesStr, EitherBuf, PagedBytesMut};
use core::fmt;
use std::io;
pub struct BufMutWriter<'a, B>(pub &'a mut B);
impl<B: BufMut> io::Write for BufMutWriter<'_, B> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.put_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl<B: BufMut> fmt::Write for BufMutWriter<'_, B> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.0.put_slice(s.as_bytes());
Ok(())
}
}
pub trait BufInterest {
fn want_write_buf(&self) -> bool;
fn want_write_io(&self) -> bool;
}
pub trait BufRead: BufInterest {
fn do_io<Io: io::Read>(&mut self, io: &mut Io) -> io::Result<()>;
}
pub trait BufWrite: BufInterest {
fn write_buf<F, T, E>(&mut self, func: F) -> Result<T, E>
where
F: FnOnce(&mut BytesMut) -> Result<T, E>;
fn do_io<Io: io::Write>(&mut self, io: &mut Io) -> io::Result<()>;
}
impl BufInterest for BytesMut {
#[inline]
fn want_write_buf(&self) -> bool {
true
}
#[inline]
fn want_write_io(&self) -> bool {
!self.is_empty()
}
}
impl BufRead for BytesMut {
#[inline]
fn do_io<Io: io::Read>(&mut self, io: &mut Io) -> io::Result<()> {
buf_read(self, io)
}
}
impl BufWrite for BytesMut {
#[inline]
fn write_buf<F, T, E>(&mut self, func: F) -> Result<T, E>
where
F: FnOnce(&mut Self) -> Result<T, E>,
{
let len = self.len();
func(self).map_err(|e| {
self.truncate(len);
e
})
}
#[cold]
#[inline(never)]
fn do_io<Io: io::Write>(&mut self, _: &mut Io) -> io::Result<()> {
unimplemented!()
}
}
pub struct WriteBuf {
buf: BytesMut,
want_flush: bool,
}
impl WriteBuf {
#[inline]
pub fn new() -> Self {
Self {
buf: BytesMut::new(),
want_flush: false,
}
}
#[inline]
pub fn len(&self) -> usize {
self.buf.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.buf.is_empty()
}
#[inline]
pub fn into_inner(self) -> BytesMut {
self.buf
}
#[inline]
pub fn clear(&mut self) {
self.buf.clear();
self.want_flush = false;
}
#[inline]
pub fn buf(&self) -> &[u8] {
&self.buf
}
}
impl Default for WriteBuf {
fn default() -> Self {
Self::new()
}
}
impl BufInterest for WriteBuf {
#[inline]
fn want_write_buf(&self) -> bool {
self.buf.want_write_buf()
}
#[inline]
fn want_write_io(&self) -> bool {
self.buf.want_write_io() || self.want_flush
}
}
impl BufWrite for WriteBuf {
#[inline]
fn write_buf<F, T, E>(&mut self, func: F) -> Result<T, E>
where
F: FnOnce(&mut BytesMut) -> Result<T, E>,
{
self.buf.write_buf(func).map(|t| {
self.want_flush = false;
t
})
}
fn do_io<Io: io::Write>(&mut self, io: &mut Io) -> io::Result<()> {
loop {
if self.want_flush {
match io::Write::flush(io) {
Ok(_) => self.want_flush = false,
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => return Err(e),
}
break;
}
match io::Write::write(io, &self.buf) {
Ok(0) => return Err(io::ErrorKind::WriteZero.into()),
Ok(n) => {
self.buf.advance(n);
self.want_flush = self.buf.is_empty();
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => break,
Err(e) => return Err(e),
}
}
Ok(())
}
}
impl<const P: usize> BufInterest for PagedBytesMut<P> {
#[inline]
fn want_write_buf(&self) -> bool {
self.get_ref().want_write_buf()
}
#[inline]
fn want_write_io(&self) -> bool {
self.get_ref().want_write_io()
}
}
impl<const P: usize> BufRead for PagedBytesMut<P> {
#[inline]
fn do_io<Io: io::Read>(&mut self, io: &mut Io) -> io::Result<()> {
buf_read(self, io)
}
}
fn buf_read<B, Io>(buf: &mut B, io: &mut Io) -> io::Result<()>
where
Io: io::Read,
B: Buf + BufMut,
{
let len = buf.remaining();
loop {
match xitca_unsafe_collection::bytes::read_buf(io, buf) {
Ok(0) => {
if buf.remaining() == len {
return Err(io::ErrorKind::UnexpectedEof.into());
};
break;
}
Ok(_) => {}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => break,
Err(e) => {
if buf.remaining() == len {
return Err(e);
}
break;
}
}
}
Ok(())
}
impl<L, R> BufInterest for EitherBuf<L, R>
where
L: BufInterest,
R: BufInterest,
{
#[inline]
fn want_write_buf(&self) -> bool {
match *self {
Self::Left(ref l) => l.want_write_buf(),
Self::Right(ref r) => r.want_write_buf(),
}
}
#[inline]
fn want_write_io(&self) -> bool {
match *self {
Self::Left(ref l) => l.want_write_io(),
Self::Right(ref r) => r.want_write_io(),
}
}
}
impl<L, R> BufWrite for EitherBuf<L, R>
where
L: BufWrite,
R: BufWrite,
{
#[inline]
fn write_buf<F, T, E>(&mut self, func: F) -> Result<T, E>
where
F: FnOnce(&mut BytesMut) -> Result<T, E>,
{
match *self {
Self::Left(ref mut l) => l.write_buf(func),
Self::Right(ref mut r) => r.write_buf(func),
}
}
#[inline]
fn do_io<Io>(&mut self, io: &mut Io) -> io::Result<()>
where
Io: io::Write,
{
match *self {
Self::Left(ref mut l) => l.do_io(io),
Self::Right(ref mut r) => r.do_io(io),
}
}
}