use crate::util::ReadSeek;
use futures::StreamExt;
use futures::stream::BoxStream;
use log::warn;
use tokio::sync::mpsc::channel;
use tokio_stream::wrappers::ReceiverStream;
const BUFFER_LEN: usize = 2880 * 64;
const BLOCKS_IN_FLIGHT: usize = 100;
pub fn read_bytes_async(
mut reader: Box<dyn ReadSeek>,
bytes_to_read: u64,
) -> BoxStream<'static, Vec<u8>> {
let (sender, receiver) = channel(BLOCKS_IN_FLIGHT);
tokio::task::spawn_blocking(move || {
let mut buffer = [0_u8; BUFFER_LEN];
let mut bytes_read = 0;
while bytes_read < bytes_to_read {
let wanted = (bytes_to_read - bytes_read).min(BUFFER_LEN as u64) as usize;
let bytes = match reader.read(&mut buffer[..wanted]) {
Ok(0) => {
warn!(
"Expected {} bytes of data but the file ended after {}",
bytes_to_read, bytes_read
);
return;
}
Ok(bytes) => bytes,
Err(error) => {
warn!(
"Failed to read data after {} of {} bytes: {}",
bytes_read, bytes_to_read, error
);
return;
}
};
bytes_read += bytes as u64;
if sender.blocking_send(buffer[..bytes].to_vec()).is_err() {
return;
}
}
});
ReceiverStream::new(receiver).boxed()
}