use sha2::Digest;
mod utils;
static TEST_DAT_SHA256_SUM: &[u8] =
b"\x59\xe3\x46\x8e\x3b\xef\x8b\xfe\x37\xe6\x0a\x82\x21\xa1\x89\x6e\x10\x5b\x80\xa6\x1a\x23\x63\x76\x12\xac\x8c\xd2\x4c\xa0\x4a\x75";
#[test]
fn read_file_512_blocks() {
let time_source = utils::make_time_source();
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
let volume_mgr = embedded_sdmmc::VolumeManager::new(disk, time_source);
let fat16_volume = volume_mgr
.open_raw_volume(embedded_sdmmc::VolumeIdx(0))
.expect("open volume 0");
let root_dir = volume_mgr
.open_root_dir(fat16_volume)
.expect("open root dir");
let test_dir = volume_mgr
.open_dir(root_dir, "TEST")
.expect("Open test dir");
let test_file = volume_mgr
.open_file_in_dir(test_dir, "TEST.DAT", embedded_sdmmc::Mode::ReadOnly)
.expect("open test file");
let mut contents = Vec::new();
let mut partial = false;
while !volume_mgr.file_eof(test_file).expect("check eof") {
let mut buffer = [0u8; 512];
let len = volume_mgr.read(test_file, &mut buffer).expect("read data");
if len != buffer.len() {
if partial {
panic!("Two partial reads!");
} else {
partial = true;
}
}
contents.extend(&buffer[0..len]);
}
let mut hasher = sha2::Sha256::new();
hasher.update(contents);
let hash = hasher.finalize();
assert_eq!(&hash[..], TEST_DAT_SHA256_SUM);
}
#[test]
fn read_file_all() {
let time_source = utils::make_time_source();
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
let volume_mgr = embedded_sdmmc::VolumeManager::new(disk, time_source);
let fat16_volume = volume_mgr
.open_raw_volume(embedded_sdmmc::VolumeIdx(0))
.expect("open volume 0");
let root_dir = volume_mgr
.open_root_dir(fat16_volume)
.expect("open root dir");
let test_dir = volume_mgr
.open_dir(root_dir, "TEST")
.expect("Open test dir");
let test_file = volume_mgr
.open_file_in_dir(test_dir, "TEST.DAT", embedded_sdmmc::Mode::ReadOnly)
.expect("open test file");
let mut contents = vec![0u8; 4096];
let len = volume_mgr
.read(test_file, &mut contents)
.expect("read data");
if len != 3500 {
panic!("Failed to read all of TEST.DAT");
}
let mut hasher = sha2::Sha256::new();
hasher.update(&contents[0..3500]);
let hash = hasher.finalize();
assert_eq!(&hash[..], TEST_DAT_SHA256_SUM);
}
#[test]
fn read_file_prime_blocks() {
let time_source = utils::make_time_source();
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
let volume_mgr = embedded_sdmmc::VolumeManager::new(disk, time_source);
let fat16_volume = volume_mgr
.open_raw_volume(embedded_sdmmc::VolumeIdx(0))
.expect("open volume 0");
let root_dir = volume_mgr
.open_root_dir(fat16_volume)
.expect("open root dir");
let test_dir = volume_mgr
.open_dir(root_dir, "TEST")
.expect("Open test dir");
let test_file = volume_mgr
.open_file_in_dir(test_dir, "TEST.DAT", embedded_sdmmc::Mode::ReadOnly)
.expect("open test file");
let mut contents = Vec::new();
let mut partial = false;
while !volume_mgr.file_eof(test_file).expect("check eof") {
let mut buffer = [0u8; 53];
let len = volume_mgr.read(test_file, &mut buffer).expect("read data");
if len != buffer.len() {
if partial {
panic!("Two partial reads!");
} else {
partial = true;
}
}
contents.extend(&buffer[0..len]);
}
let mut hasher = sha2::Sha256::new();
hasher.update(&contents[0..3500]);
let hash = hasher.finalize();
assert_eq!(&hash[..], TEST_DAT_SHA256_SUM);
}
#[test]
fn read_file_backwards() {
let time_source = utils::make_time_source();
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
let volume_mgr = embedded_sdmmc::VolumeManager::new(disk, time_source);
let fat16_volume = volume_mgr
.open_raw_volume(embedded_sdmmc::VolumeIdx(0))
.expect("open volume 0");
let root_dir = volume_mgr
.open_root_dir(fat16_volume)
.expect("open root dir");
let test_dir = volume_mgr
.open_dir(root_dir, "TEST")
.expect("Open test dir");
let test_file = volume_mgr
.open_file_in_dir(test_dir, "TEST.DAT", embedded_sdmmc::Mode::ReadOnly)
.expect("open test file");
let mut contents = std::collections::VecDeque::new();
const CHUNK_SIZE: u32 = 100;
let length = volume_mgr.file_length(test_file).expect("file length");
let mut read = 0;
volume_mgr.file_seek_from_end(test_file, 0).expect("seek");
while read < length {
volume_mgr
.file_seek_from_current(test_file, -(CHUNK_SIZE as i32))
.expect("seek");
let mut buffer = [0u8; CHUNK_SIZE as usize];
let len = volume_mgr.read(test_file, &mut buffer).expect("read");
assert_eq!(len, CHUNK_SIZE as usize);
contents.push_front(buffer.to_vec());
read += CHUNK_SIZE;
volume_mgr
.file_seek_from_current(test_file, -(CHUNK_SIZE as i32))
.expect("seek");
}
assert_eq!(read, length);
let flat: Vec<u8> = contents.iter().flatten().copied().collect();
let mut hasher = sha2::Sha256::new();
hasher.update(flat);
let hash = hasher.finalize();
assert_eq!(&hash[..], TEST_DAT_SHA256_SUM);
}
#[test]
fn read_file_with_odd_seek() {
let time_source = utils::make_time_source();
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
let volume_mgr = embedded_sdmmc::VolumeManager::new(disk, time_source);
let volume = volume_mgr
.open_volume(embedded_sdmmc::VolumeIdx(0))
.unwrap();
let root_dir = volume.open_root_dir().unwrap();
let f = root_dir
.open_file_in_dir("64MB.DAT", embedded_sdmmc::Mode::ReadOnly)
.unwrap();
f.seek_from_start(0x2c).unwrap();
while f.offset() < 1000000 {
let mut buffer = [0u8; 2048];
f.read(&mut buffer).unwrap();
f.seek_from_current(-1024).unwrap();
}
}