Skip to content

Commit db2f57f

Browse files
authored
Merge pull request #23 from glbsalazar/support_delete
Add support for file deletion
2 parents 6071df4 + 677376a commit db2f57f

File tree

4 files changed

+365
-37
lines changed

4 files changed

+365
-37
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
22
**/*.rs.bk
33
Cargo.lock
4+
disk.img

examples/delete_test.rs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
//! # Tests the Embedded SDMMC Library
2+
//! ```bash
3+
//! $ cargo run --example delete_test -- /dev/mmcblk0
4+
//! $ cargo run --example delete_test -- /dev/sda
5+
//! ```
6+
//!
7+
//! If you pass a block device it should be unmounted. No testing has been
8+
//! performed with Windows raw block devices - please report back if you try
9+
//! this! There is a gzipped example disk image which you can gunzip and test
10+
//! with if you don't have a suitable block device.
11+
//!
12+
//! ```bash
13+
//! zcat ./disk.img.gz > ./disk.img
14+
//! $ cargo run --example delete_test -- ./disk.img
15+
//! ```
16+
17+
extern crate embedded_sdmmc;
18+
19+
const FILE_TO_DELETE: &'static str = "DELETE.TXT";
20+
21+
use embedded_sdmmc::{
22+
Block, BlockCount, BlockDevice, BlockIdx, Controller, Error, Mode, TimeSource, Timestamp,
23+
VolumeIdx,
24+
};
25+
use std::cell::RefCell;
26+
use std::fs::{File, OpenOptions};
27+
use std::io::prelude::*;
28+
use std::io::SeekFrom;
29+
use std::path::Path;
30+
31+
#[derive(Debug)]
32+
struct LinuxBlockDevice {
33+
file: RefCell<File>,
34+
print_blocks: bool,
35+
}
36+
37+
impl LinuxBlockDevice {
38+
fn new<P>(device_name: P, print_blocks: bool) -> Result<LinuxBlockDevice, std::io::Error>
39+
where
40+
P: AsRef<Path>,
41+
{
42+
Ok(LinuxBlockDevice {
43+
file: RefCell::new(
44+
OpenOptions::new()
45+
.read(true)
46+
.write(true)
47+
.open(device_name)?,
48+
),
49+
print_blocks,
50+
})
51+
}
52+
}
53+
54+
impl BlockDevice for LinuxBlockDevice {
55+
type Error = std::io::Error;
56+
57+
fn read(
58+
&self,
59+
blocks: &mut [Block],
60+
start_block_idx: BlockIdx,
61+
reason: &str,
62+
) -> Result<(), Self::Error> {
63+
self.file
64+
.borrow_mut()
65+
.seek(SeekFrom::Start(start_block_idx.into_bytes()))?;
66+
for block in blocks.iter_mut() {
67+
self.file.borrow_mut().read_exact(&mut block.contents)?;
68+
if self.print_blocks {
69+
println!(
70+
"Read block ({}) {:?}: {:?}",
71+
reason, start_block_idx, &block
72+
);
73+
}
74+
}
75+
Ok(())
76+
}
77+
78+
fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
79+
self.file
80+
.borrow_mut()
81+
.seek(SeekFrom::Start(start_block_idx.into_bytes()))?;
82+
for block in blocks.iter() {
83+
self.file.borrow_mut().write_all(&block.contents)?;
84+
if self.print_blocks {
85+
println!("Wrote: {:?}", &block);
86+
}
87+
}
88+
Ok(())
89+
}
90+
91+
fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
92+
let num_blocks = self.file.borrow().metadata().unwrap().len() / 512;
93+
Ok(BlockCount(num_blocks as u32))
94+
}
95+
}
96+
97+
struct Clock;
98+
99+
impl TimeSource for Clock {
100+
fn get_timestamp(&self) -> Timestamp {
101+
Timestamp {
102+
year_since_1970: 0,
103+
zero_indexed_month: 0,
104+
zero_indexed_day: 0,
105+
hours: 0,
106+
minutes: 0,
107+
seconds: 0,
108+
}
109+
}
110+
}
111+
112+
fn main() {
113+
env_logger::init();
114+
let mut args = std::env::args().skip(1);
115+
let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into());
116+
let print_blocks = args.find(|x| x == "-v").map(|_| true).unwrap_or(false);
117+
let lbd = LinuxBlockDevice::new(filename, print_blocks)
118+
.map_err(Error::DeviceError)
119+
.unwrap();
120+
println!("lbd: {:?}", lbd);
121+
let mut controller = Controller::new(lbd, Clock);
122+
for volume_idx in 0..=3 {
123+
let volume = controller.get_volume(VolumeIdx(volume_idx));
124+
println!("volume {}: {:#?}", volume_idx, volume);
125+
if let Ok(mut volume) = volume {
126+
let root_dir = controller.open_root_dir(&volume).unwrap();
127+
println!("\tListing root directory:");
128+
controller
129+
.iterate_dir(&volume, &root_dir, |x| {
130+
println!("\t\tFound: {:?}", x);
131+
})
132+
.unwrap();
133+
println!("\nCreating file {}...", FILE_TO_DELETE);
134+
// This will panic if the file already exists, use ReadWriteCreateOrAppend or
135+
// ReadWriteCreateOrTruncate instead
136+
let f = controller
137+
.open_file_in_dir(
138+
&mut volume,
139+
&root_dir,
140+
FILE_TO_DELETE,
141+
Mode::ReadWriteCreate,
142+
)
143+
.unwrap();
144+
145+
println!("\tFinding {}...", FILE_TO_DELETE);
146+
println!(
147+
"\tFound {}?: {:?}",
148+
FILE_TO_DELETE,
149+
controller.find_directory_entry(&volume, &root_dir, FILE_TO_DELETE)
150+
);
151+
152+
match controller.delete_file_in_dir(&volume, &root_dir, FILE_TO_DELETE) {
153+
Ok(()) => (),
154+
Err(error) => println!("\tCannot delete file: {:?}", error),
155+
}
156+
println!("\tClosing {}...", FILE_TO_DELETE);
157+
controller.close_file(&volume, f).unwrap();
158+
159+
match controller.delete_file_in_dir(&volume, &root_dir, FILE_TO_DELETE) {
160+
Ok(()) => println!("\tDeleted {}.", FILE_TO_DELETE),
161+
Err(error) => println!("\tCannot delete {}: {:?}", FILE_TO_DELETE, error),
162+
}
163+
println!("\tFinding {}...", FILE_TO_DELETE);
164+
println!(
165+
"\tFound {}?: {:?}",
166+
FILE_TO_DELETE,
167+
controller.find_directory_entry(&volume, &root_dir, FILE_TO_DELETE)
168+
);
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)