@@ -16,6 +16,23 @@ use heapless::Vec;
16
16
17
17
static ID_GENERATOR : IdGenerator = IdGenerator :: new ( ) ;
18
18
19
+ #[ derive( PartialEq , Eq ) ]
20
+ struct UniqueCluster {
21
+ volume_idx : VolumeIdx ,
22
+ cluster : Cluster ,
23
+ search_id : SearchId ,
24
+ }
25
+
26
+ impl UniqueCluster {
27
+ fn compare_volume_and_cluster ( & self , volume_idx : VolumeIdx , cluster : Cluster ) -> bool {
28
+ self . volume_idx == volume_idx && self . cluster == cluster
29
+ }
30
+
31
+ fn compare_id ( & self , search_id : SearchId ) -> bool {
32
+ self . search_id == search_id
33
+ }
34
+ }
35
+
19
36
/// A `VolumeManager` wraps a block device and gives access to the volumes within it.
20
37
pub struct VolumeManager < D , T , const MAX_DIRS : usize = 4 , const MAX_FILES : usize = 4 >
21
38
where
25
42
{
26
43
pub ( crate ) block_device : D ,
27
44
pub ( crate ) timesource : T ,
28
- open_dirs : Vec < ( VolumeIdx , Cluster , SearchId ) , MAX_DIRS > ,
29
- open_files : Vec < ( VolumeIdx , Cluster , SearchId ) , MAX_FILES > ,
45
+ open_dirs : Vec < UniqueCluster , MAX_DIRS > ,
46
+ open_files : Vec < UniqueCluster , MAX_FILES > ,
30
47
}
31
48
32
49
impl < D , T > VolumeManager < D , T , 4 , 4 >
@@ -161,15 +178,19 @@ where
161
178
// Find a free directory entry, and check the root dir isn't open. As
162
179
// we already know the root dir's magic cluster number, we can do both
163
180
// checks in one loop.
164
- for ( v , c , _ ) in self . open_dirs . iter ( ) {
165
- if * v == volume. idx && * c == Cluster :: ROOT_DIR {
181
+ for u in self . open_dirs . iter ( ) {
182
+ if u . compare_volume_and_cluster ( volume. idx , Cluster :: ROOT_DIR ) {
166
183
return Err ( Error :: DirAlreadyOpen ) ;
167
184
}
168
185
}
169
186
let search_id = ID_GENERATOR . next ( ) ;
170
187
// Remember this open directory
171
188
self . open_dirs
172
- . push ( ( volume. idx , Cluster :: ROOT_DIR , search_id) )
189
+ . push ( UniqueCluster {
190
+ volume_idx : volume. idx ,
191
+ cluster : Cluster :: ROOT_DIR ,
192
+ search_id,
193
+ } )
173
194
. map_err ( |_| Error :: TooManyOpenDirs ) ?;
174
195
175
196
Ok ( Directory {
@@ -205,15 +226,19 @@ where
205
226
}
206
227
207
228
// Check it's not already open
208
- for dir_table_row in self . open_dirs . iter ( ) {
209
- if dir_table_row . 0 == volume. idx && dir_table_row . 1 == dir_entry. cluster {
229
+ for d in self . open_dirs . iter ( ) {
230
+ if d . compare_volume_and_cluster ( volume. idx , dir_entry. cluster ) {
210
231
return Err ( Error :: DirAlreadyOpen ) ;
211
232
}
212
233
}
213
234
// Remember this open directory.
214
235
let search_id = ID_GENERATOR . next ( ) ;
215
236
self . open_dirs
216
- . push ( ( volume. idx , dir_entry. cluster , search_id) )
237
+ . push ( UniqueCluster {
238
+ volume_idx : volume. idx ,
239
+ cluster : dir_entry. cluster ,
240
+ search_id,
241
+ } )
217
242
. map_err ( |_| Error :: TooManyOpenDirs ) ?;
218
243
219
244
Ok ( Directory {
@@ -226,7 +251,7 @@ where
226
251
/// and so must close it if you want to do something with it.
227
252
pub fn close_dir ( & mut self , volume : & Volume , dir : Directory ) {
228
253
for ( i, d) in self . open_dirs . iter ( ) . enumerate ( ) {
229
- if d. 2 == dir. search_id {
254
+ if d. compare_id ( dir. search_id ) {
230
255
self . open_dirs . swap_remove ( i) ;
231
256
break ;
232
257
}
@@ -271,8 +296,8 @@ where
271
296
return Err ( Error :: TooManyOpenFiles ) ;
272
297
}
273
298
// Check it's not already open
274
- for dir_table_row in self . open_files . iter ( ) {
275
- if dir_table_row . 0 == volume. idx && dir_table_row . 1 == dir_entry. cluster {
299
+ for d in self . open_files . iter ( ) {
300
+ if d . compare_volume_and_cluster ( volume. idx , dir_entry. cluster ) {
276
301
return Err ( Error :: DirAlreadyOpen ) ;
277
302
}
278
303
}
@@ -340,7 +365,11 @@ where
340
365
} ;
341
366
// Remember this open file
342
367
self . open_files
343
- . push ( ( volume. idx , file. starting_cluster , search_id) )
368
+ . push ( UniqueCluster {
369
+ volume_idx : volume. idx ,
370
+ cluster : file. starting_cluster ,
371
+ search_id,
372
+ } )
344
373
. map_err ( |_| Error :: TooManyOpenDirs ) ?;
345
374
346
375
Ok ( file)
@@ -404,7 +433,11 @@ where
404
433
405
434
// Remember this open file
406
435
self . open_files
407
- . push ( ( volume. idx , file. starting_cluster , search_id) )
436
+ . push ( UniqueCluster {
437
+ volume_idx : volume. idx ,
438
+ cluster : file. starting_cluster ,
439
+ search_id,
440
+ } )
408
441
. map_err ( |_| Error :: TooManyOpenFiles ) ?;
409
442
410
443
Ok ( file)
@@ -419,18 +452,6 @@ where
419
452
}
420
453
}
421
454
422
- /// Get the next entry in open_files list
423
- fn get_open_files_row ( & self ) -> Result < usize , Error < D :: Error > > {
424
- // Find a free directory entry
425
- let mut open_files_row = None ;
426
- for ( i, d) in self . open_files . iter ( ) . enumerate ( ) {
427
- if d. 1 == Cluster :: INVALID {
428
- open_files_row = Some ( i) ;
429
- }
430
- }
431
- open_files_row. ok_or ( Error :: TooManyOpenFiles )
432
- }
433
-
434
455
/// Delete a closed file with the given full path, if exists.
435
456
pub fn delete_file_in_dir (
436
457
& mut self ,
@@ -451,7 +472,7 @@ where
451
472
}
452
473
453
474
for d in self . open_files . iter_mut ( ) {
454
- if d. 0 == volume. idx && d . 1 == dir_entry. cluster {
475
+ if d. compare_volume_and_cluster ( volume. idx , dir_entry. cluster ) {
455
476
return Err ( Error :: FileIsOpen ) ;
456
477
}
457
478
}
@@ -610,7 +631,7 @@ where
610
631
/// Close a file with the given full path.
611
632
pub fn close_file ( & mut self , volume : & Volume , file : File ) -> Result < ( ) , Error < D :: Error > > {
612
633
for ( i, f) in self . open_files . iter ( ) . enumerate ( ) {
613
- if f. 2 == file. search_id {
634
+ if f. compare_id ( file. search_id ) {
614
635
self . open_files . swap_remove ( i) ;
615
636
break ;
616
637
}
@@ -620,11 +641,7 @@ where
620
641
621
642
/// Check if any files or folders are open.
622
643
pub fn has_open_handles ( & self ) -> bool {
623
- !self
624
- . open_dirs
625
- . iter ( )
626
- . chain ( self . open_files . iter ( ) )
627
- . all ( |( _, c, _) | c == & Cluster :: INVALID )
644
+ !( self . open_dirs . is_empty ( ) || self . open_files . is_empty ( ) )
628
645
}
629
646
630
647
/// Consume self and return BlockDevice and TimeSource
0 commit comments