use super::header::{MAGIC, SECTOR_SIZE, VERSION, VERSION_STREAM_OPT};
const DESCRIPTOR_OFFSET: u64 = 1;
const DESCRIPTOR_SECTORS: u64 = 20;
const GD_SECTOR: u64 = DESCRIPTOR_OFFSET + DESCRIPTOR_SECTORS; const RGD_SECTOR: u64 = GD_SECTOR + 1; const GT_SECTOR: u64 = RGD_SECTOR + 1; const GT_SECTORS: u64 = 4; const GRAIN_SECTOR: u64 = GT_SECTOR + GT_SECTORS;
pub const GRAIN_SIZE_SECTORS: u64 = 8;
pub const GRAIN_SIZE_BYTES: usize = GRAIN_SIZE_SECTORS as usize * SECTOR_SIZE as usize;
const NUM_GTES_PER_GT: u32 = 512;
#[cfg_attr(not(any(test, feature = "test-helpers")), allow(dead_code))]
pub fn test_sparse_vmdk(sector_data: &[u8]) -> Vec<u8> {
let mut grain = vec![0u8; GRAIN_SIZE_BYTES];
let copy_len = sector_data.len().min(GRAIN_SIZE_BYTES);
grain[..copy_len].copy_from_slice(§or_data[..copy_len]);
let mut hdr = vec![0u8; 512];
hdr[0..4].copy_from_slice(&MAGIC.to_le_bytes());
hdr[4..8].copy_from_slice(&VERSION.to_le_bytes());
hdr[8..12].copy_from_slice(&0u32.to_le_bytes()); hdr[12..20].copy_from_slice(&GRAIN_SIZE_SECTORS.to_le_bytes()); hdr[20..28].copy_from_slice(&GRAIN_SIZE_SECTORS.to_le_bytes()); hdr[28..36].copy_from_slice(&DESCRIPTOR_OFFSET.to_le_bytes());
hdr[36..44].copy_from_slice(&DESCRIPTOR_SECTORS.to_le_bytes());
hdr[44..48].copy_from_slice(&NUM_GTES_PER_GT.to_le_bytes());
hdr[48..56].copy_from_slice(&RGD_SECTOR.to_le_bytes()); hdr[56..64].copy_from_slice(&GD_SECTOR.to_le_bytes()); hdr[64..72].copy_from_slice(&GRAIN_SECTOR.to_le_bytes()); hdr[72] = 0; hdr[73] = b'\n';
hdr[74] = b' ';
hdr[75] = b'\r';
hdr[76] = b'\n';
hdr[77..79].copy_from_slice(&0u16.to_le_bytes());
let mut desc = vec![0u8; DESCRIPTOR_SECTORS as usize * SECTOR_SIZE as usize];
let s = "# Disk DescriptorFile\nversion=1\nCID=fffffffe\nparentCID=ffffffff\ncreateType=\"monolithicSparse\"\n";
let n = s.len().min(desc.len());
desc[..n].copy_from_slice(&s.as_bytes()[..n]);
let mut gd = vec![0u8; SECTOR_SIZE as usize];
gd[0..4].copy_from_slice(&(GT_SECTOR as u32).to_le_bytes());
let rgd = gd.clone();
let mut gt = vec![0u8; GT_SECTORS as usize * SECTOR_SIZE as usize];
gt[0..4].copy_from_slice(&(GRAIN_SECTOR as u32).to_le_bytes());
let mut vmdk = Vec::new();
vmdk.extend_from_slice(&hdr);
vmdk.extend_from_slice(&desc);
vmdk.extend_from_slice(&gd);
vmdk.extend_from_slice(&rgd);
vmdk.extend_from_slice(>);
vmdk.extend_from_slice(&grain);
vmdk
}
const GAE_CAPACITY: u64 = 2048; const GAE_GRAIN_SIZE: u64 = 128; const GAE_NUM_GTES: u32 = 512;
const GAE_DESC_OFFSET: u64 = 1;
const GAE_DESC_SIZE: u64 = 20;
const GAE_GT_SECTOR: u64 = 21;
const GAE_GD_SECTOR: u64 = 25; const GAE_TOTAL_SECTORS: u64 = 28;
fn write_stream_opt_hdr(h: &mut [u8; 512], gd_off: u64) {
h[0..4].copy_from_slice(&MAGIC.to_le_bytes());
h[4..8].copy_from_slice(&VERSION_STREAM_OPT.to_le_bytes());
h[8..12].copy_from_slice(&0u32.to_le_bytes()); h[12..20].copy_from_slice(&GAE_CAPACITY.to_le_bytes());
h[20..28].copy_from_slice(&GAE_GRAIN_SIZE.to_le_bytes());
h[28..36].copy_from_slice(&GAE_DESC_OFFSET.to_le_bytes());
h[36..44].copy_from_slice(&GAE_DESC_SIZE.to_le_bytes());
h[44..48].copy_from_slice(&GAE_NUM_GTES.to_le_bytes());
h[48..56].copy_from_slice(&0u64.to_le_bytes()); h[56..64].copy_from_slice(&gd_off.to_le_bytes());
h[64..72].copy_from_slice(&GAE_GD_SECTOR.to_le_bytes()); h[72] = 0; h[73] = b'\n';
h[74] = b' ';
h[75] = b'\r';
h[76] = b'\n';
h[77..79].copy_from_slice(&1u16.to_le_bytes()); }
#[cfg_attr(not(any(test, feature = "test-helpers")), allow(dead_code))]
pub fn gd_at_end_stream_opt_vmdk() -> Vec<u8> {
let total_bytes = GAE_TOTAL_SECTORS * SECTOR_SIZE;
let mut vmdk = vec![0u8; total_bytes as usize];
let mut hdr = [0u8; 512];
write_stream_opt_hdr(&mut hdr, u64::MAX);
vmdk[0..512].copy_from_slice(&hdr);
let desc = b"# Disk DescriptorFile\nversion=1\nCID=fffffffe\nparentCID=ffffffff\ncreateType=\"streamOptimized\"\n";
let desc_start = GAE_DESC_OFFSET as usize * SECTOR_SIZE as usize;
let copy_len = desc.len().min(GAE_DESC_SIZE as usize * SECTOR_SIZE as usize);
vmdk[desc_start..desc_start + copy_len].copy_from_slice(&desc[..copy_len]);
let gd_start = GAE_GD_SECTOR as usize * SECTOR_SIZE as usize;
vmdk[gd_start..gd_start + 4].copy_from_slice(&(GAE_GT_SECTOR as u32).to_le_bytes());
let footer_start = (GAE_TOTAL_SECTORS - 2) as usize * SECTOR_SIZE as usize;
let mut footer = [0u8; 512];
write_stream_opt_hdr(&mut footer, GAE_GD_SECTOR);
vmdk[footer_start..footer_start + 512].copy_from_slice(&footer);
vmdk
}