use bytes::BytesMut;
use std::io::Read;
use std::sync::Arc;
use crate::io::buffer_pool::{BytesPool, PooledBuffer};
pub trait ReadBytesExt: Read {
fn read_into_bytes(&mut self, buf: &mut BytesMut, max_len: usize) -> std::io::Result<usize>;
fn read_exact_into_bytes(&mut self, len: usize) -> std::io::Result<BytesMut>;
fn read_byte(&mut self) -> std::io::Result<Option<u8>>;
fn read_pooled_buffer(
&mut self,
pool: &Arc<BytesPool>,
max_len: usize,
) -> std::io::Result<Option<PooledBuffer>>;
}
impl<R: Read> ReadBytesExt for R {
fn read_into_bytes(&mut self, buf: &mut BytesMut, max_len: usize) -> std::io::Result<usize> {
if max_len == 0 {
return Ok(0);
}
let start = buf.len();
buf.resize(start + max_len, 0);
match Read::read(self, &mut buf[start..]) {
Ok(n) => {
buf.truncate(start + n);
Ok(n)
}
Err(err) => {
buf.truncate(start);
Err(err)
}
}
}
fn read_exact_into_bytes(&mut self, len: usize) -> std::io::Result<BytesMut> {
let mut buf = BytesMut::with_capacity(len);
buf.resize(len, 0);
self.read_exact(&mut buf)?;
Ok(buf)
}
fn read_byte(&mut self) -> std::io::Result<Option<u8>> {
let mut byte = [0u8; 1];
match self.read(&mut byte)? {
0 => Ok(None),
_ => Ok(Some(byte[0])),
}
}
fn read_pooled_buffer(
&mut self,
pool: &Arc<BytesPool>,
max_len: usize,
) -> std::io::Result<Option<PooledBuffer>> {
let mut buf = pool.acquire_with_capacity(max_len);
buf.resize(max_len, 0);
let n = self.read(&mut buf)?;
if n == 0 {
return Ok(None);
}
buf.truncate(n);
Ok(Some(buf))
}
}