use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use crate::common::error::{MutagenError, Result};
pub fn insert_bytes(fobj: &mut File, size: u64, offset: u64) -> Result<()> {
if size == 0 {
return Ok(());
}
let file_len = fobj.metadata()?.len();
if offset > file_len {
return Err(MutagenError::ValueError("offset beyond end of file".into()));
}
fobj.seek(SeekFrom::Start(offset))?;
let mut trailing = Vec::new();
fobj.read_to_end(&mut trailing)?;
fobj.set_len(file_len + size)?;
fobj.seek(SeekFrom::Start(offset))?;
let zeros = vec![0u8; size as usize];
fobj.write_all(&zeros)?;
fobj.write_all(&trailing)?;
fobj.flush()?;
Ok(())
}
pub fn delete_bytes(fobj: &mut File, size: u64, offset: u64) -> Result<()> {
if size == 0 {
return Ok(());
}
let file_len = fobj.metadata()?.len();
if offset + size > file_len {
return Err(MutagenError::ValueError("delete beyond end of file".into()));
}
fobj.seek(SeekFrom::Start(offset + size))?;
let mut trailing = Vec::new();
fobj.read_to_end(&mut trailing)?;
fobj.seek(SeekFrom::Start(offset))?;
fobj.write_all(&trailing)?;
fobj.flush()?;
fobj.set_len(file_len - size)?;
Ok(())
}
pub fn open_rw(path: &str) -> Result<File> {
Ok(OpenOptions::new()
.read(true)
.write(true)
.open(path)?)
}
pub fn open_ro(path: &str) -> Result<File> {
Ok(File::open(path)?)
}