use std::{
fs::File,
io::{self, Seek, Write},
path::Path,
};
use byteorder::{BigEndian, ByteOrder};
use crate::MultiFilePackWriteError;
pub struct MultiFilePackWriteStream {
file: File,
file_count: u64,
current_write_index: u64,
current_write_pt: u64,
}
impl MultiFilePackWriteStream {
pub fn new<P>(file_path: P, file_count: u64) -> Result<MultiFilePackWriteStream, io::Error>
where
P: AsRef<Path>,
{
let mut file = File::create(file_path)?;
let mut buf: [u8; 8] = [0; 8];
BigEndian::write_u64(&mut buf, file_count);
file.write_all(&buf)?;
let buf_file_index: [u8; 16] = [0; 16];
for _i in 0..file_count {
file.write_all(&buf_file_index)?;
}
Ok(MultiFilePackWriteStream {
file,
file_count,
current_write_index: 0,
current_write_pt: 8 + (16 * file_count),
})
}
pub fn write_file(&mut self, data: &[u8]) -> Result<(), MultiFilePackWriteError> {
if self.current_write_index >= self.file_count {
return Err(MultiFilePackWriteError::ExceededFileCount);
}
let file_size = data.len() as u64;
let mut buf_file_index: [u8; 16] = [0; 16];
BigEndian::write_u64(&mut buf_file_index[0..8], self.current_write_pt); BigEndian::write_u64(&mut buf_file_index[8..16], file_size);
self.file
.seek(io::SeekFrom::Start(8 + self.current_write_index * 16))?;
self.file.write_all(&buf_file_index)?;
self.file.seek(io::SeekFrom::Start(self.current_write_pt))?;
self.file.write_all(data)?;
self.current_write_index += 1;
self.current_write_pt += file_size;
Ok(())
}
pub fn close(self) {}
}