Skip to content

Commit 1447766

Browse files
Expose directory tell, seek and rewind functionnality
1 parent 9d86d0e commit 1447766

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
@@ -1007,13 +1007,79 @@ impl ReadDirAllocation {
10071007
}
10081008
}
10091009

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

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

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)