use crate::tokio::io::AsyncReadExt;
use crate::data::data_stream::DataStream;
use crate::data::{ByteUnit, StreamReader};
pub const PEEK_BYTES: usize = 512;
pub struct Data<'r> {
buffer: Vec<u8>,
is_complete: bool,
stream: StreamReader<'r>,
}
impl<'r> Data<'r> {
pub(crate) fn from<S: Into<StreamReader<'r>>>(stream: S) -> Data<'r> {
let stream = stream.into();
let buffer = Vec::with_capacity(PEEK_BYTES / 8);
Data { buffer, stream, is_complete: false }
}
#[inline]
pub(crate) fn local(data: Vec<u8>) -> Data<'r> {
Data {
buffer: data,
stream: StreamReader::empty(),
is_complete: true,
}
}
pub fn open(self, limit: ByteUnit) -> DataStream<'r> {
DataStream::new(self.buffer, self.stream, limit.into())
}
pub async fn peek(&mut self, num: usize) -> &[u8] {
let num = std::cmp::min(PEEK_BYTES, num);
let mut len = self.buffer.len();
if len >= num {
return &self.buffer[..num];
}
while len < num {
match self.stream.read_buf(&mut self.buffer).await {
Ok(0) => { self.is_complete = true; break },
Ok(n) => len += n,
Err(e) => {
error_!("Failed to read into peek buffer: {:?}.", e);
break;
}
}
}
&self.buffer[..std::cmp::min(len, num)]
}
#[inline(always)]
pub fn peek_complete(&self) -> bool {
self.is_complete
}
}