use std::{
fs::File,
io::{Read, Result, Seek, SeekFrom, Write}
};
use crate::section::SectionData;
const READ_BLOCK_SIZE: usize = 8192;
pub struct FileBasedSection
{
data: File,
buffer: [u8; READ_BLOCK_SIZE],
written: usize,
cursor: usize,
cur_size: usize,
seek_ptr: u64
}
impl FileBasedSection
{
pub fn new(data: File) -> FileBasedSection
{
return FileBasedSection {
data: data,
buffer: [0; READ_BLOCK_SIZE],
written: 0,
cursor: usize::MAX,
cur_size: 0,
seek_ptr: 0
};
}
}
impl Read for FileBasedSection
{
fn read(&mut self, data: &mut [u8]) -> Result<usize>
{
let mut cnt: usize = 0;
for i in 0..data.len() {
if self.cursor >= self.written {
self.cursor = 0;
self.written = self.data.read(&mut self.buffer)?;
}
if self.cursor < self.written {
data[i] = self.buffer[self.cursor];
self.cursor += 1;
cnt += 1;
}
}
return Ok(cnt);
}
}
impl Write for FileBasedSection
{
fn write(&mut self, data: &[u8]) -> Result<usize>
{
let len = self.data.write(data)?;
if self.seek_ptr >= self.cur_size as u64 {
self.cur_size += len;
self.seek_ptr += len as u64;
}
return Ok(len);
}
fn flush(&mut self) -> Result<()>
{
self.data.seek(SeekFrom::Current(self.cursor as i64))?;
self.cursor = usize::MAX;
return self.data.flush();
}
}
impl Seek for FileBasedSection
{
fn seek(&mut self, state: SeekFrom) -> Result<u64>
{
self.seek_ptr = self.data.seek(state)?;
return Ok(self.seek_ptr);
}
}
impl SectionData for FileBasedSection
{
fn load_in_memory(&mut self) -> Result<Vec<u8>>
{
let mut data: Vec<u8> = Vec::new();
self.data.read_to_end(&mut data)?;
return Ok(data);
}
fn size(&self) -> usize
{
return self.cur_size;
}
}