#![allow(clippy::unwrap_used, clippy::expect_used)]
pub(crate) const BS: usize = 512;
pub(crate) const ROOT_FE: u32 = 4;
pub(crate) const SUBDIR_FE: u32 = 5;
pub(crate) const INLINE_FILE_FE: u32 = 6;
pub(crate) const SHORT_FILE_FE: u32 = 7;
pub(crate) const LONG_FILE_FE: u32 = 10;
pub(crate) const UTF16_FILE_FE: u32 = 12;
pub(crate) const BROKEN_DIR_FE: u32 = 13;
pub(crate) const SHORT_FILE_LEN: u64 = 600;
pub(crate) const LONG_FILE_LEN: u64 = 300;
fn w16(img: &mut [u8], o: usize, v: u16) {
img[o..o + 2].copy_from_slice(&v.to_le_bytes());
}
fn w32(img: &mut [u8], o: usize, v: u32) {
img[o..o + 4].copy_from_slice(&v.to_le_bytes());
}
fn w64(img: &mut [u8], o: usize, v: u64) {
img[o..o + 8].copy_from_slice(&v.to_le_bytes());
}
fn fid(child_lbn: u32, is_dir: bool, is_parent: bool, name: &[u8]) -> Vec<u8> {
let mut chars = 0u8;
if is_dir {
chars |= 0x02;
}
if is_parent {
chars |= 0x08;
}
let name_len = name.len();
let body_len = 1 + 1 + 16 + 2 + name_len;
let advance = (16 + body_len + 3) & !3;
let mut f = vec![0u8; advance];
w16(&mut f, 0, 257); w16(&mut f, 10, body_len as u16); f[16] = chars;
f[17] = name_len as u8;
w32(&mut f, 22, child_lbn); f[36..36 + name_len].copy_from_slice(name);
f
}
fn stamp_fe(img: &mut [u8], lba: u32, file_type: u8, alloc: u16, info_len: u64, ad: &[u8]) {
let o = lba as usize * BS;
w16(img, o, 260); img[o + 27] = file_type; w16(img, o + 34, alloc); w64(img, o + 56, info_len);
w32(img, o + 168, 0); w32(img, o + 172, ad.len() as u32); img[o + 176..o + 176 + ad.len()].copy_from_slice(ad);
}
fn short_ad(len: u32, pos: u32) -> [u8; 8] {
let mut a = [0u8; 8];
a[0..4].copy_from_slice(&len.to_le_bytes()); a[4..8].copy_from_slice(&pos.to_le_bytes()); a
}
fn long_ad(len: u32, lbn: u32) -> [u8; 16] {
let mut a = [0u8; 16];
a[0..4].copy_from_slice(&len.to_le_bytes());
a[4..8].copy_from_slice(&lbn.to_le_bytes());
a
}
pub(crate) fn image() -> Vec<u8> {
let mut img = vec![0u8; BS * 264];
let avdp = 256 * BS;
w16(&mut img, avdp, 2); w32(&mut img, avdp + 12, 256); w32(&mut img, avdp + 16, (4 * BS) as u32); w32(&mut img, avdp + 20, 260);
let pd = 260 * BS;
w16(&mut img, pd, 5); w16(&mut img, pd + 22, 0); w32(&mut img, pd + 188, 0);
let lvd = 261 * BS;
w16(&mut img, lvd, 6); w32(&mut img, lvd + 252, 3); w16(&mut img, lvd + 256, 0); w32(&mut img, lvd + 264, 6); w32(&mut img, lvd + 268, 1); img[lvd + 440] = 1; img[lvd + 441] = 6; w16(&mut img, lvd + 444, 0);
let fsd = 3 * BS;
w16(&mut img, fsd, 256); w32(&mut img, fsd + 404, 4);
let mut dir = Vec::new();
dir.extend_from_slice(&fid(ROOT_FE, true, true, b"")); dir.extend_from_slice(&fid(SUBDIR_FE, true, false, b"\x08sub"));
dir.extend_from_slice(&fid(INLINE_FILE_FE, false, false, b"\x08inline.txt"));
dir.extend_from_slice(&fid(SHORT_FILE_FE, false, false, b"\x08short.bin"));
dir.extend_from_slice(&fid(LONG_FILE_FE, false, false, b"\x08long.bin"));
dir.extend_from_slice(&fid(UTF16_FILE_FE, false, false, &[16, 0x00, b'U'])); dir.extend_from_slice(&fid(BROKEN_DIR_FE, true, false, b"\x08bd"));
stamp_fe(&mut img, ROOT_FE, 4, 3, dir.len() as u64, &dir);
stamp_fe(&mut img, SUBDIR_FE, 4, 3, 0, &[]);
stamp_fe(&mut img, INLINE_FILE_FE, 5, 3, 4, b"abcd");
stamp_fe(
&mut img,
SHORT_FILE_FE,
5,
0,
SHORT_FILE_LEN,
&short_ad(SHORT_FILE_LEN as u32, 8),
);
img[8 * BS..9 * BS].fill(0x41);
img[9 * BS..9 * BS + 88].fill(0x42);
stamp_fe(
&mut img,
LONG_FILE_FE,
5,
1,
LONG_FILE_LEN,
&long_ad(LONG_FILE_LEN as u32, 11),
);
img[11 * BS..11 * BS + LONG_FILE_LEN as usize].fill(0x43);
stamp_fe(&mut img, UTF16_FILE_FE, 5, 3, 4, b"wxyz");
let o = BROKEN_DIR_FE as usize * BS;
w16(&mut img, o, 260);
img[o + 27] = 4; w16(&mut img, o + 34, 0); w64(&mut img, o + 56, 0);
w32(&mut img, o + 168, 0); w32(&mut img, o + 172, 1000);
img
}