2020-12-05 09:51:34 +00:00
|
|
|
use endian_trait::Endian;
|
|
|
|
|
2021-09-13 09:54:24 +00:00
|
|
|
use crate::MediaContentHeader;
|
2020-12-05 09:51:34 +00:00
|
|
|
|
|
|
|
/// Write trait for tape devices
|
|
|
|
///
|
|
|
|
/// The 'write_all' function returns if the drive reached the Logical
|
|
|
|
/// End Of Media (early warning).
|
|
|
|
///
|
|
|
|
/// It is mandatory to call 'finish' before closing the stream to mark it
|
|
|
|
/// as correctly written.
|
|
|
|
///
|
|
|
|
/// Please note that there is no flush method. Tapes flush there internal
|
|
|
|
/// buffer when they write an EOF marker.
|
|
|
|
pub trait TapeWrite {
|
|
|
|
/// writes all data, returns true on LEOM
|
|
|
|
fn write_all(&mut self, data: &[u8]) -> Result<bool, std::io::Error>;
|
|
|
|
|
|
|
|
/// Returns how many bytes (raw data on tape) have been written
|
|
|
|
fn bytes_written(&self) -> usize;
|
|
|
|
|
|
|
|
/// flush last block, write file end mark
|
|
|
|
///
|
|
|
|
/// The incomplete flag is used to mark multivolume stream.
|
|
|
|
fn finish(&mut self, incomplete: bool) -> Result<bool, std::io::Error>;
|
|
|
|
|
|
|
|
/// Returns true if the writer already detected the logical end of media
|
|
|
|
fn logical_end_of_media(&self) -> bool;
|
|
|
|
|
|
|
|
/// writes header and data, returns true on LEOM
|
|
|
|
fn write_header(
|
|
|
|
&mut self,
|
|
|
|
header: &MediaContentHeader,
|
|
|
|
data: &[u8],
|
|
|
|
) -> Result<bool, std::io::Error> {
|
|
|
|
if header.size as usize != data.len() {
|
2022-02-21 10:39:18 +00:00
|
|
|
proxmox_lang::io_bail!("write_header with wrong size - internal error");
|
2020-12-05 09:51:34 +00:00
|
|
|
}
|
|
|
|
let header = header.to_le();
|
|
|
|
|
2022-04-06 15:00:29 +00:00
|
|
|
let res = self.write_all(unsafe {
|
|
|
|
std::slice::from_raw_parts(
|
|
|
|
&header as *const MediaContentHeader as *const u8,
|
|
|
|
std::mem::size_of::<MediaContentHeader>(),
|
|
|
|
)
|
|
|
|
})?;
|
2020-12-05 09:51:34 +00:00
|
|
|
|
2022-04-06 15:00:29 +00:00
|
|
|
if data.is_empty() {
|
|
|
|
return Ok(res);
|
|
|
|
}
|
2020-12-05 09:51:34 +00:00
|
|
|
|
|
|
|
self.write_all(data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-29 10:52:26 +00:00
|
|
|
/// Write streams of blocks
|
|
|
|
pub trait BlockWrite {
|
|
|
|
/// Write a data block
|
|
|
|
///
|
|
|
|
/// Returns true if the drive reached the Logical End Of Media
|
|
|
|
/// (early warning)
|
|
|
|
fn write_block(&mut self, buffer: &[u8]) -> Result<bool, std::io::Error>;
|
2020-12-05 09:51:34 +00:00
|
|
|
|
2021-03-29 10:52:26 +00:00
|
|
|
/// Write a filemark
|
|
|
|
fn write_filemark(&mut self) -> Result<(), std::io::Error>;
|
2020-12-05 09:51:34 +00:00
|
|
|
}
|