Skip to content

Commit 5a900ed

Browse files
Expose directory tell, seek and rewind functionnality
1 parent 6564fff commit 5a900ed

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

src/fs.rs

+66
Original file line numberDiff line numberDiff line change
@@ -1005,13 +1005,79 @@ impl ReadDirAllocation {
10051005
}
10061006
}
10071007

1008+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
1009+
pub struct DirIterationTell {
1010+
tell_result: u32,
1011+
}
1012+
10081013
pub struct ReadDir<'a, 'b, S: driver::Storage> {
10091014
alloc: RefCell<&'b mut ReadDirAllocation>,
10101015
fs: &'b Filesystem<'a, S>,
10111016
#[cfg(feature = "dir-entry-path")]
10121017
path: PathBuf,
10131018
}
10141019

1020+
impl<'a, 'b, S: driver::Storage> ReadDir<'a, 'b, S> {
1021+
/// Return the position of the directory
1022+
///
1023+
/// The returned offset is only meant to be consumed by seek and may not make
1024+
/// sense, but does indicate the current position in the directory iteration.
1025+
///
1026+
/// Returns the position of the directory, which can be returned to using [`seek`](Self::seek).
1027+
pub fn tell(&self) -> Result<DirIterationTell> {
1028+
let value = unsafe {
1029+
ll::lfs_dir_tell(
1030+
&mut self.fs.alloc.borrow_mut().state,
1031+
&mut self.alloc.borrow_mut().state,
1032+
)
1033+
};
1034+
if value < 0 {
1035+
Err(io::result_from((), value).unwrap_err())
1036+
} else {
1037+
Ok(DirIterationTell {
1038+
tell_result: value as u32,
1039+
})
1040+
}
1041+
}
1042+
1043+
/// Change the position of the directory
1044+
///
1045+
/// The new off must be a value previous returned from [`tell`](Self::tell) and specifies
1046+
/// an absolute offset in the directory seek.
1047+
pub fn seek(&mut self, state: DirIterationTell) -> Result<DirIterationTell> {
1048+
let value = unsafe {
1049+
ll::lfs_dir_seek(
1050+
&mut self.fs.alloc.borrow_mut().state,
1051+
&mut self.alloc.borrow_mut().state,
1052+
state.tell_result,
1053+
)
1054+
};
1055+
if value < 0 {
1056+
Err(io::result_from((), value).unwrap_err())
1057+
} else {
1058+
Ok(DirIterationTell {
1059+
tell_result: value as u32,
1060+
})
1061+
}
1062+
}
1063+
1064+
/// Change the position of the directory to the beginning of the directory
1065+
pub fn rewind(&mut self) -> Result<()> {
1066+
let res = unsafe {
1067+
ll::lfs_dir_rewind(
1068+
&mut self.fs.alloc.borrow_mut().state,
1069+
&mut self.alloc.borrow_mut().state,
1070+
)
1071+
};
1072+
1073+
if res < 0 {
1074+
Err(io::result_from((), res).unwrap_err())
1075+
} else {
1076+
Ok(())
1077+
}
1078+
}
1079+
}
1080+
10151081
impl<'a, 'b, S: driver::Storage> Iterator for ReadDir<'a, 'b, S> {
10161082
type Item = Result<DirEntry>;
10171083

src/tests.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,16 @@ fn test_iter_dirs() {
419419
file.set_len(37)?;
420420
fs.create_file_and_then(b"/tmp/file.b\0".try_into()?, |file| file.set_len(42))
421421
})?;
422+
let mut tells = Vec::new();
422423

423424
fs.read_dir_and_then(b"/tmp\0".try_into()?, |dir| {
424425
let mut found_files: usize = 0;
425426
let mut sizes = [0usize; 4];
427+
let mut i = 0;
426428

427-
for (i, entry) in dir.enumerate() {
429+
tells.push(dir.tell()?);
430+
while let Some(entry) = dir.next() {
431+
tells.push(dir.tell()?);
428432
let entry = entry?;
429433

430434
// assert_eq!(entry.file_name(), match i {
@@ -437,13 +441,31 @@ fn test_iter_dirs() {
437441

438442
sizes[i] = entry.metadata().len();
439443
found_files += 1;
444+
i += 1;
440445
}
441446

442447
assert_eq!(sizes, [0, 0, 37, 42]);
443448
assert_eq!(found_files, 4);
444449

450+
for i in 0..5 {
451+
dir.rewind().unwrap();
452+
let mut found_files: usize = 0;
453+
let mut sizes = Vec::new();
454+
dir.seek(tells[i])?;
455+
456+
while let Some(entry) = dir.next() {
457+
let entry = entry?;
458+
sizes.push(entry.metadata().len());
459+
found_files += 1;
460+
}
461+
462+
assert_eq!(sizes, [0, 0, 37, 42][i..]);
463+
assert_eq!(found_files, 4 - i);
464+
}
445465
Ok(())
446466
})
467+
.unwrap();
468+
Ok(())
447469
})
448470
.unwrap();
449471
}

0 commit comments

Comments
 (0)