use super::Inner;
use crate::wad::{
BuildError,
Builder,
LumpDescriptor,
LumpType,
};
use crate::wad::ffi::{doom, halflife, quake};
use oct::IntoOctets;
impl Builder {
pub fn with_lump<'a>(&mut self, desc: LumpDescriptor<'a>) -> Result<(), BuildError<'a>> {
let filepos = size_of::<doom::wadinfo_t>() + self.data.len();
let Ok(filepos) = i32::try_from(filepos) else {
return Err(BuildError::large_size(filepos));
};
let Ok(disksize) = i32::try_from(desc.data.len()) else {
return Err(BuildError::large_size(desc.data.len()));
};
if desc.name.contains('\0') {
return Err(BuildError::null_lump_name(desc.name));
}
if let Inner::Wad { ref mut directory, .. } = self.inner {
if desc.name.len() > 8 {
return Err(BuildError::long_lump_name(desc.name));
}
let mut raw_name = [0_i8; _];
raw_name.as_octets_mut()[..desc.name.len()].copy_from_slice(desc.name.as_bytes());
let lump = doom::filelump_t {
filepos,
size: disksize,
name: raw_name,
};
directory.push(lump);
} else {
if desc.name.len() > 16 {
return Err(BuildError::long_lump_name(desc.name));
}
let mut raw_name = [0_i8; _];
raw_name.as_octets_mut()[..desc.name.len()].copy_from_slice(desc.name.as_bytes());
let size = disksize;
let r#type = desc.lump_type.map(LumpType::to_i8)
.unwrap_or_default();
let compression = quake::CMP_NONE;
match self.inner {
Inner::Wad2 { ref mut directory, .. } => {
let lump = quake::lumpinfo_t {
filepos,
disksize,
size,
r#type,
compression,
name: raw_name,
..Default::default()
};
directory.push(lump);
}
Inner::Wad3 { ref mut directory, .. } => {
let lump = halflife::lumpinfo_t {
filepos,
disksize,
size,
r#type,
compression,
name: raw_name,
..Default::default()
};
directory.push(lump);
}
_ => unreachable!(),
}
}
self.data.extend_from_slice(desc.data);
Ok(())
}
}