use std::io::{self, Read};
use tokio::io::AsyncReadExt;
use crate::protocol::header::EOL;
pub fn read_with_std_io<R: Read>(reader: &mut R, buffer: &mut [u8]) -> io::Result<()> {
reader.read_exact(buffer)?;
Ok(())
}
pub async fn read_with_tokio_io<R: AsyncReadExt + Unpin>(
reader: &mut R,
buffer: &mut Vec<u8>,
) -> io::Result<()> {
reader.read_to_end(buffer).await?;
Ok(())
}
pub async fn read_until<T>(stream: &mut T, delimiter: Vec<u8>) -> io::Result<Vec<u8>>
where
T: AsyncReadExt + Unpin,
{
let mut result_buffer: Vec<u8> = Vec::new();
let delimiter_len = delimiter.len();
loop {
let mut byte = [0u8];
let bytes_read = stream.read(&mut byte).await?;
if bytes_read == 0 {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"Delimiter not found",
));
}
result_buffer.push(byte[0]);
if result_buffer.len() >= delimiter_len
&& result_buffer[result_buffer.len() - delimiter_len..] == delimiter[..]
{
result_buffer.truncate(result_buffer.len() - EOL.len());
return Ok(result_buffer);
}
}
}
pub async fn read_until_buffered<T>(
stream: &mut T,
delimiter: &[u8],
buf: &mut Vec<u8>,
) -> io::Result<Vec<u8>>
where
T: AsyncReadExt + Unpin,
{
let delimiter_len = delimiter.len();
loop {
if buf.len() >= delimiter_len && buf[buf.len() - delimiter_len..] == *delimiter {
let frame_len = buf.len() - delimiter_len;
let frame = buf[..frame_len].to_vec();
buf.clear();
return Ok(frame);
}
let mut byte = [0u8];
let bytes_read = stream.read(&mut byte).await?;
if bytes_read == 0 {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"Delimiter not found",
));
}
buf.push(byte[0]);
}
}