2021-03-29 08:09:49 +00:00
|
|
|
use std::io::Read;
|
2020-12-06 08:41:16 +00:00
|
|
|
|
2021-03-29 08:09:49 +00:00
|
|
|
use proxmox::tools::io::ReadExt;
|
|
|
|
|
|
|
|
use crate::tape::{
|
|
|
|
BlockRead,
|
|
|
|
BlockReadStatus,
|
|
|
|
file_formats::PROXMOX_TAPE_BLOCK_SIZE,
|
|
|
|
};
|
2020-12-06 08:41:16 +00:00
|
|
|
|
|
|
|
/// Emulate tape read behavior on a normal Reader
|
|
|
|
///
|
|
|
|
/// Tapes reads are always return one whole block PROXMOX_TAPE_BLOCK_SIZE.
|
2021-03-29 08:09:49 +00:00
|
|
|
pub struct EmulateTapeReader<R: Read> {
|
2020-12-06 08:41:16 +00:00
|
|
|
reader: R,
|
2021-03-29 08:09:49 +00:00
|
|
|
got_eof: bool,
|
2020-12-06 08:41:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl <R: Read> EmulateTapeReader<R> {
|
|
|
|
|
|
|
|
pub fn new(reader: R) -> Self {
|
2021-03-29 08:09:49 +00:00
|
|
|
Self { reader, got_eof: false }
|
2020-12-06 08:41:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-29 08:09:49 +00:00
|
|
|
impl <R: Read> BlockRead for EmulateTapeReader<R> {
|
|
|
|
fn read_block(&mut self, buffer: &mut [u8]) -> Result<BlockReadStatus, std::io::Error> {
|
|
|
|
if self.got_eof {
|
|
|
|
proxmox::io_bail!("detected read after EOF!");
|
|
|
|
}
|
|
|
|
match self.reader.read_exact_or_eof(buffer)? {
|
|
|
|
false => {
|
|
|
|
self.got_eof = true;
|
|
|
|
Ok(BlockReadStatus::EndOfFile)
|
|
|
|
}
|
|
|
|
true => {
|
|
|
|
// test buffer len after EOF test (to allow EOF test with small buffers in BufferedReader)
|
|
|
|
if buffer.len() != PROXMOX_TAPE_BLOCK_SIZE {
|
|
|
|
proxmox::io_bail!("EmulateTapeReader: read_block with wrong block size ({} != {})",
|
|
|
|
buffer.len(), PROXMOX_TAPE_BLOCK_SIZE);
|
2020-12-06 08:41:16 +00:00
|
|
|
}
|
2021-03-29 08:09:49 +00:00
|
|
|
Ok(BlockReadStatus::Ok(buffer.len()))
|
2020-12-06 08:41:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|