#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use crate::io::{ReadBytesExt, WriteBytesExt};
#[cfg(not(feature = "std"))]
use crate::io::{Read, Write};
#[cfg(feature = "std")]
use std::io::{Read, Seek, Write};
#[cfg(feature = "std")]
use std::{fs::File, io::BufReader, path::Path};
pub type SectionName = Vec<u8>;
#[derive(Debug)]
pub struct TocEntry {
pub(crate) name: SectionName,
pub(crate) pos: u64,
pub(crate) len: u64,
}
impl TocEntry {
#[must_use]
pub fn name(&self) -> &[u8] {
&self.name
}
#[must_use]
pub fn pos(&self) -> u64 {
self.pos
}
#[must_use]
#[expect(clippy::len_without_is_empty)]
pub fn len(&self) -> u64 {
self.len
}
#[doc(hidden)]
#[cfg(feature = "std")]
pub fn reader(&self, path: &Path) -> std::io::Result<impl std::io::Read> {
let mut file = File::open(path)?;
file.seek(std::io::SeekFrom::Start(self.pos))?;
Ok(file.take(self.len))
}
#[doc(hidden)]
#[cfg(feature = "std")]
pub fn buf_reader(&self, path: &Path) -> std::io::Result<impl std::io::BufRead> {
let mut file = BufReader::new(File::open(path)?);
file.seek(std::io::SeekFrom::Start(self.pos))?;
Ok(file.take(self.len))
}
pub(crate) fn write_into(&self, mut writer: impl Write) -> crate::sfa::Result<()> {
use crate::io::LE;
writer.write_u64::<LE>(self.pos())?;
writer.write_u64::<LE>(self.len())?;
let name_len =
u16::try_from(self.name().len()).map_err(|_| crate::sfa::Error::InvalidHeader)?;
writer.write_u16::<LE>(name_len)?;
writer.write_all(self.name())?;
Ok(())
}
pub(crate) fn read_from_file(reader: &mut impl Read) -> crate::sfa::Result<Self> {
use crate::io::LE;
let pos = reader.read_u64::<LE>()?;
let len = reader.read_u64::<LE>()?;
let section_name_len = reader.read_u16::<LE>()?;
let mut name = vec![0; section_name_len as usize];
reader.read_exact(&mut name)?;
Ok(Self { name, pos, len })
}
}