Skip to content

Commit b85b147

Browse files
committed
Re-wrote API.
Now File and Directory are just integers, and they are joined by Volume. All the info is stored inside the volume manager. The upside is you no longer have to pass the right volume along with your file handle! It also becomes much easier to implement a Drop trait on File if you want (although we don't for the reasons explained in the comments). The downside is the File object no longer has any methods. The upside is that it's much easier to store files.
1 parent 9dc3ea4 commit b85b147

23 files changed

+1146
-918
lines changed

README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,35 @@ let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source);
2323
// It doesn't hold a reference to the Volume Manager and so must be passed back
2424
// to every Volume Manager API call. This makes it easier to handle multiple
2525
// volumes in parallel.
26-
let mut volume0 = volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0))?;
26+
let volume0 = volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0))?;
2727
println!("Volume 0: {:?}", volume0);
2828
// Open the root directory (passing in the volume we're using).
2929
let root_dir = volume_mgr.open_root_dir(&volume0)?;
3030
// Open a file called "MY_FILE.TXT" in the root directory
31-
let mut my_file = volume_mgr.open_file_in_dir(
32-
&mut volume0,
33-
&root_dir,
31+
let my_file = volume_mgr.open_file_in_dir(
32+
root_dir,
3433
"MY_FILE.TXT",
3534
embedded_sdmmc::Mode::ReadOnly,
3635
)?;
3736
// Print the contents of the file
38-
while !my_file.eof() {
37+
while !volume_manager.file_eof(my_file).unwrap() {
3938
let mut buffer = [0u8; 32];
4039
let num_read = volume_mgr.read(&volume0, &mut my_file, &mut buffer)?;
4140
for b in &buffer[0..num_read] {
4241
print!("{}", *b as char);
4342
}
4443
}
45-
volume_mgr.close_file(&volume0, my_file)?;
46-
volume_mgr.close_dir(&volume0, root_dir);
44+
volume_mgr.close_file(my_file)?;
45+
volume_mgr.close_dir(root_dir)?;
4746
```
4847

4948
### Open directories and files
5049

51-
By default the `VolumeManager` will initialize with a maximum number of `4` open directories and files. This can be customized by specifying the `MAX_DIR` and `MAX_FILES` generic consts of the `VolumeManager`:
50+
By default the `VolumeManager` will initialize with a maximum number of `4` open directories, files and volumes. This can be customized by specifying the `MAX_DIR`, `MAX_FILES` and `MAX_VOLUMES` generic consts of the `VolumeManager`:
5251

5352
```rust
54-
// Create a volume manager with a maximum of 6 open directories and 12 open files
55-
let mut cont: VolumeManager<_, _, 6, 12> = VolumeManager::new_with_limits(block, time_source);
53+
// Create a volume manager with a maximum of 6 open directories, 12 open files, and 4 volumes (or partitions)
54+
let mut cont: VolumeManager<_, _, 6, 12, 4> = VolumeManager::new_with_limits(block, time_source);
5655
```
5756

5857
## Supported features

examples/create_test.rs

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -118,34 +118,30 @@ fn main() {
118118
.map_err(Error::DeviceError)
119119
.unwrap();
120120
println!("lbd: {:?}", lbd);
121-
let mut volume_mgr = VolumeManager::new(lbd, Clock);
121+
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
122+
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
122123
for volume_idx in 0..=3 {
123-
let volume = volume_mgr.get_volume(VolumeIdx(volume_idx));
124+
let volume = volume_mgr.open_volume(VolumeIdx(volume_idx));
124125
println!("volume {}: {:#?}", volume_idx, volume);
125-
if let Ok(mut volume) = volume {
126-
let root_dir = volume_mgr.open_root_dir(&volume).unwrap();
126+
if let Ok(volume) = volume {
127+
let root_dir = volume_mgr.open_root_dir(volume).unwrap();
127128
println!("\tListing root directory:");
128129
volume_mgr
129-
.iterate_dir(&volume, &root_dir, |x| {
130+
.iterate_dir(root_dir, |x| {
130131
println!("\t\tFound: {:?}", x);
131132
})
132133
.unwrap();
133134
println!("\nCreating file {}...", FILE_TO_CREATE);
134135
// This will panic if the file already exists, use ReadWriteCreateOrAppend or
135136
// ReadWriteCreateOrTruncate instead
136-
let mut f = volume_mgr
137-
.open_file_in_dir(
138-
&mut volume,
139-
&root_dir,
140-
FILE_TO_CREATE,
141-
Mode::ReadWriteCreate,
142-
)
137+
let f = volume_mgr
138+
.open_file_in_dir(root_dir, FILE_TO_CREATE, Mode::ReadWriteCreate)
143139
.unwrap();
144140
println!("\nReading from file");
145141
println!("FILE STARTS:");
146-
while !f.eof() {
142+
while !volume_mgr.file_eof(f).unwrap() {
147143
let mut buffer = [0u8; 32];
148-
let num_read = volume_mgr.read(&volume, &mut f, &mut buffer).unwrap();
144+
let num_read = volume_mgr.read(f, &mut buffer).unwrap();
149145
for b in &buffer[0..num_read] {
150146
if *b == 10 {
151147
print!("\\n");
@@ -162,32 +158,27 @@ fn main() {
162158
buffer.push(b'\n');
163159
}
164160
println!("\nAppending to file");
165-
let num_written1 = volume_mgr.write(&mut volume, &mut f, &buffer1[..]).unwrap();
166-
let num_written = volume_mgr.write(&mut volume, &mut f, &buffer[..]).unwrap();
161+
let num_written1 = volume_mgr.write(f, &buffer1[..]).unwrap();
162+
let num_written = volume_mgr.write(f, &buffer[..]).unwrap();
167163
println!("Number of bytes written: {}\n", num_written + num_written1);
168-
volume_mgr.close_file(&mut volume, f).unwrap();
164+
volume_mgr.close_file(f).unwrap();
169165

170-
let mut f = volume_mgr
171-
.open_file_in_dir(
172-
&mut volume,
173-
&root_dir,
174-
FILE_TO_CREATE,
175-
Mode::ReadWriteCreateOrAppend,
176-
)
166+
let f = volume_mgr
167+
.open_file_in_dir(root_dir, FILE_TO_CREATE, Mode::ReadWriteCreateOrAppend)
177168
.unwrap();
178-
f.seek_from_start(0).unwrap();
169+
volume_mgr.file_seek_from_start(f, 0).unwrap();
179170

180171
println!("\tFinding {}...", FILE_TO_CREATE);
181172
println!(
182173
"\tFound {}?: {:?}",
183174
FILE_TO_CREATE,
184-
volume_mgr.find_directory_entry(&volume, &root_dir, FILE_TO_CREATE)
175+
volume_mgr.find_directory_entry(root_dir, FILE_TO_CREATE)
185176
);
186177
println!("\nReading from file");
187178
println!("FILE STARTS:");
188-
while !f.eof() {
179+
while !volume_mgr.file_eof(f).unwrap() {
189180
let mut buffer = [0u8; 32];
190-
let num_read = volume_mgr.read(&volume, &mut f, &mut buffer).unwrap();
181+
let num_read = volume_mgr.read(f, &mut buffer).unwrap();
191182
for b in &buffer[0..num_read] {
192183
if *b == 10 {
193184
print!("\\n");
@@ -196,7 +187,7 @@ fn main() {
196187
}
197188
}
198189
println!("EOF");
199-
volume_mgr.close_file(&mut volume, f).unwrap();
190+
volume_mgr.close_file(f).unwrap();
200191
}
201192
}
202193
}

examples/delete_test.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,53 +118,49 @@ fn main() {
118118
.map_err(Error::DeviceError)
119119
.unwrap();
120120
println!("lbd: {:?}", lbd);
121-
let mut volume_mgr = VolumeManager::new(lbd, Clock);
121+
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
122+
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
122123
for volume_idx in 0..=3 {
123-
let volume = volume_mgr.get_volume(VolumeIdx(volume_idx));
124+
let volume = volume_mgr.open_volume(VolumeIdx(volume_idx));
124125
println!("volume {}: {:#?}", volume_idx, volume);
125-
if let Ok(mut volume) = volume {
126-
let root_dir = volume_mgr.open_root_dir(&volume).unwrap();
126+
if let Ok(volume) = volume {
127+
let root_dir = volume_mgr.open_root_dir(volume).unwrap();
127128
println!("\tListing root directory:");
128129
volume_mgr
129-
.iterate_dir(&volume, &root_dir, |x| {
130+
.iterate_dir(root_dir, |x| {
130131
println!("\t\tFound: {:?}", x);
131132
})
132133
.unwrap();
133134
println!("\nCreating file {}...", FILE_TO_DELETE);
134135
// This will panic if the file already exists, use ReadWriteCreateOrAppend or
135136
// ReadWriteCreateOrTruncate instead
136137
let f = volume_mgr
137-
.open_file_in_dir(
138-
&mut volume,
139-
&root_dir,
140-
FILE_TO_DELETE,
141-
Mode::ReadWriteCreate,
142-
)
138+
.open_file_in_dir(root_dir, FILE_TO_DELETE, Mode::ReadWriteCreate)
143139
.unwrap();
144140

145141
println!("\tFinding {}...", FILE_TO_DELETE);
146142
println!(
147143
"\tFound {}?: {:?}",
148144
FILE_TO_DELETE,
149-
volume_mgr.find_directory_entry(&volume, &root_dir, FILE_TO_DELETE)
145+
volume_mgr.find_directory_entry(root_dir, FILE_TO_DELETE)
150146
);
151147

152-
match volume_mgr.delete_file_in_dir(&volume, &root_dir, FILE_TO_DELETE) {
148+
match volume_mgr.delete_file_in_dir(root_dir, FILE_TO_DELETE) {
153149
Ok(()) => (),
154150
Err(error) => println!("\tCannot delete file: {:?}", error),
155151
}
156152
println!("\tClosing {}...", FILE_TO_DELETE);
157-
volume_mgr.close_file(&mut volume, f).unwrap();
153+
volume_mgr.close_file(f).unwrap();
158154

159-
match volume_mgr.delete_file_in_dir(&volume, &root_dir, FILE_TO_DELETE) {
155+
match volume_mgr.delete_file_in_dir(root_dir, FILE_TO_DELETE) {
160156
Ok(()) => println!("\tDeleted {}.", FILE_TO_DELETE),
161157
Err(error) => println!("\tCannot delete {}: {:?}", FILE_TO_DELETE, error),
162158
}
163159
println!("\tFinding {}...", FILE_TO_DELETE);
164160
println!(
165161
"\tFound {}?: {:?}",
166162
FILE_TO_DELETE,
167-
volume_mgr.find_directory_entry(&volume, &root_dir, FILE_TO_DELETE)
163+
volume_mgr.find_directory_entry(root_dir, FILE_TO_DELETE)
168164
);
169165
}
170166
}

examples/readme_test.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,26 +90,22 @@ fn main() -> Result<(), Error> {
9090
// It doesn't hold a reference to the Volume Manager and so must be passed back
9191
// to every Volume Manager API call. This makes it easier to handle multiple
9292
// volumes in parallel.
93-
let mut volume0 = volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0))?;
93+
let volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?;
9494
println!("Volume 0: {:?}", volume0);
9595
// Open the root directory (passing in the volume we're using).
96-
let root_dir = volume_mgr.open_root_dir(&volume0)?;
96+
let root_dir = volume_mgr.open_root_dir(volume0)?;
9797
// Open a file called "MY_FILE.TXT" in the root directory
98-
let mut my_file = volume_mgr.open_file_in_dir(
99-
&mut volume0,
100-
&root_dir,
101-
"MY_FILE.TXT",
102-
embedded_sdmmc::Mode::ReadOnly,
103-
)?;
98+
let my_file =
99+
volume_mgr.open_file_in_dir(root_dir, "MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?;
104100
// Print the contents of the file
105-
while !my_file.eof() {
101+
while !volume_mgr.file_eof(my_file).unwrap() {
106102
let mut buffer = [0u8; 32];
107-
let num_read = volume_mgr.read(&volume0, &mut my_file, &mut buffer)?;
103+
let num_read = volume_mgr.read(my_file, &mut buffer)?;
108104
for b in &buffer[0..num_read] {
109105
print!("{}", *b as char);
110106
}
111107
}
112-
volume_mgr.close_file(&mut volume0, my_file)?;
113-
volume_mgr.close_dir(&volume0, root_dir);
108+
volume_mgr.close_file(my_file)?;
109+
volume_mgr.close_dir(root_dir)?;
114110
Ok(())
115111
}

examples/test_mount.rs

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -121,31 +121,32 @@ fn main() {
121121
.map_err(Error::DeviceError)
122122
.unwrap();
123123
println!("lbd: {:?}", lbd);
124-
let mut volume_mgr = VolumeManager::new(lbd, Clock);
124+
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
125+
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
125126
for i in 0..=3 {
126-
let volume = volume_mgr.get_volume(VolumeIdx(i));
127+
let volume = volume_mgr.open_volume(VolumeIdx(i));
127128
println!("volume {}: {:#?}", i, volume);
128-
if let Ok(mut volume) = volume {
129-
let root_dir = volume_mgr.open_root_dir(&volume).unwrap();
129+
if let Ok(volume) = volume {
130+
let root_dir = volume_mgr.open_root_dir(volume).unwrap();
130131
println!("\tListing root directory:");
131132
volume_mgr
132-
.iterate_dir(&volume, &root_dir, |x| {
133+
.iterate_dir(root_dir, |x| {
133134
println!("\t\tFound: {:?}", x);
134135
})
135136
.unwrap();
136137
println!("\tFinding {}...", FILE_TO_PRINT);
137138
println!(
138139
"\tFound {}?: {:?}",
139140
FILE_TO_PRINT,
140-
volume_mgr.find_directory_entry(&volume, &root_dir, FILE_TO_PRINT)
141+
volume_mgr.find_directory_entry(root_dir, FILE_TO_PRINT)
141142
);
142-
let mut f = volume_mgr
143-
.open_file_in_dir(&mut volume, &root_dir, FILE_TO_PRINT, Mode::ReadOnly)
143+
let f = volume_mgr
144+
.open_file_in_dir(root_dir, FILE_TO_PRINT, Mode::ReadOnly)
144145
.unwrap();
145146
println!("FILE STARTS:");
146-
while !f.eof() {
147+
while !volume_mgr.file_eof(f).unwrap() {
147148
let mut buffer = [0u8; 32];
148-
let num_read = volume_mgr.read(&volume, &mut f, &mut buffer).unwrap();
149+
let num_read = volume_mgr.read(f, &mut buffer).unwrap();
149150
for b in &buffer[0..num_read] {
150151
if *b == 10 {
151152
print!("\\n");
@@ -156,42 +157,52 @@ fn main() {
156157
println!("EOF");
157158
// Can't open file twice
158159
assert!(volume_mgr
159-
.open_file_in_dir(&mut volume, &root_dir, FILE_TO_PRINT, Mode::ReadOnly)
160+
.open_file_in_dir(root_dir, FILE_TO_PRINT, Mode::ReadOnly)
160161
.is_err());
161-
volume_mgr.close_file(&mut volume, f).unwrap();
162+
volume_mgr.close_file(f).unwrap();
162163

163-
let test_dir = volume_mgr.open_dir(&volume, &root_dir, "TEST").unwrap();
164+
let test_dir = volume_mgr.open_dir(root_dir, "TEST").unwrap();
164165
// Check we can't open it twice
165-
assert!(volume_mgr.open_dir(&volume, &root_dir, "TEST").is_err());
166+
assert!(volume_mgr.open_dir(root_dir, "TEST").is_err());
166167
// Print the contents
167168
println!("\tListing TEST directory:");
168169
volume_mgr
169-
.iterate_dir(&volume, &test_dir, |x| {
170+
.iterate_dir(test_dir, |x| {
170171
println!("\t\tFound: {:?}", x);
171172
})
172173
.unwrap();
173-
volume_mgr.close_dir(&volume, test_dir);
174+
volume_mgr.close_dir(test_dir).unwrap();
174175

175176
// Checksum example file. We just sum the bytes, as a quick and dirty checksum.
176177
// We also read in a weird block size, just to exercise the offset calculation code.
177-
let mut f = volume_mgr
178-
.open_file_in_dir(&mut volume, &root_dir, FILE_TO_CHECKSUM, Mode::ReadOnly)
178+
let f = volume_mgr
179+
.open_file_in_dir(root_dir, FILE_TO_CHECKSUM, Mode::ReadOnly)
179180
.unwrap();
180-
println!("Checksuming {} bytes of {}", f.length(), FILE_TO_CHECKSUM);
181+
println!(
182+
"Checksuming {} bytes of {}",
183+
volume_mgr.file_length(f).unwrap(),
184+
FILE_TO_CHECKSUM
185+
);
181186
let mut csum = 0u32;
182-
while !f.eof() {
187+
while !volume_mgr.file_eof(f).unwrap() {
183188
let mut buffer = [0u8; 2047];
184-
let num_read = volume_mgr.read(&volume, &mut f, &mut buffer).unwrap();
189+
let num_read = volume_mgr.read(f, &mut buffer).unwrap();
185190
for b in &buffer[0..num_read] {
186191
csum += u32::from(*b);
187192
}
188193
}
189-
println!("Checksum over {} bytes: {}", f.length(), csum);
190-
volume_mgr.close_file(&mut volume, f).unwrap();
194+
println!(
195+
"\nChecksum over {} bytes: {}",
196+
volume_mgr.file_length(f).unwrap(),
197+
csum
198+
);
199+
// Should be all zero bytes
200+
assert_eq!(csum, 0);
201+
volume_mgr.close_file(f).unwrap();
191202

192-
assert!(volume_mgr.open_root_dir(&volume).is_err());
193-
volume_mgr.close_dir(&volume, root_dir);
194-
assert!(volume_mgr.open_root_dir(&volume).is_ok());
203+
assert!(volume_mgr.open_root_dir(volume).is_err());
204+
assert!(volume_mgr.close_dir(root_dir).is_ok());
205+
assert!(volume_mgr.open_root_dir(volume).is_ok());
195206
}
196207
}
197208
}

0 commit comments

Comments
 (0)