Skip to content

Commit 760bb7f

Browse files
Expose directory tell, seek and rewind functionnality
1 parent f1c9abe commit 760bb7f

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

src/fs.rs

+66
Original file line numberDiff line numberDiff line change
@@ -1033,13 +1033,79 @@ impl ReadDirAllocation {
10331033
}
10341034
}
10351035

1036+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
1037+
pub struct DirIterationTell {
1038+
tell_result: u32,
1039+
}
1040+
10361041
pub struct ReadDir<'a, 'b, S: driver::Storage> {
10371042
alloc: RefCell<&'b mut ReadDirAllocation>,
10381043
fs: &'b Filesystem<'a, S>,
10391044
#[cfg(feature = "dir-entry-path")]
10401045
path: PathBuf,
10411046
}
10421047

1048+
impl<'a, 'b, S: driver::Storage> ReadDir<'a, 'b, S> {
1049+
/// Return the position of the directory
1050+
///
1051+
/// The returned offset is only meant to be consumed by seek and may not make
1052+
/// sense, but does indicate the current position in the directory iteration.
1053+
///
1054+
/// Returns the position of the directory, which can be returned to using [`seek`](Self::seek).
1055+
pub fn tell(&self) -> Result<DirIterationTell> {
1056+
let value = unsafe {
1057+
ll::lfs_dir_tell(
1058+
&mut self.fs.alloc.borrow_mut().state,
1059+
&mut self.alloc.borrow_mut().state,
1060+
)
1061+
};
1062+
if value < 0 {
1063+
Err(io::result_from((), value).unwrap_err())
1064+
} else {
1065+
Ok(DirIterationTell {
1066+
tell_result: value as u32,
1067+
})
1068+
}
1069+
}
1070+
1071+
/// Change the position of the directory
1072+
///
1073+
/// The new off must be a value previous returned from [`tell`](Self::tell) and specifies
1074+
/// an absolute offset in the directory seek.
1075+
pub fn seek(&mut self, state: DirIterationTell) -> Result<DirIterationTell> {
1076+
let value = unsafe {
1077+
ll::lfs_dir_seek(
1078+
&mut self.fs.alloc.borrow_mut().state,
1079+
&mut self.alloc.borrow_mut().state,
1080+
state.tell_result,
1081+
)
1082+
};
1083+
if value < 0 {
1084+
Err(io::result_from((), value).unwrap_err())
1085+
} else {
1086+
Ok(DirIterationTell {
1087+
tell_result: value as u32,
1088+
})
1089+
}
1090+
}
1091+
1092+
/// Change the position of the directory to the beginning of the directory
1093+
pub fn rewind(&mut self) -> Result<()> {
1094+
let res = unsafe {
1095+
ll::lfs_dir_rewind(
1096+
&mut self.fs.alloc.borrow_mut().state,
1097+
&mut self.alloc.borrow_mut().state,
1098+
)
1099+
};
1100+
1101+
if res < 0 {
1102+
Err(io::result_from((), res).unwrap_err())
1103+
} else {
1104+
Ok(())
1105+
}
1106+
}
1107+
}
1108+
10431109
impl<'a, 'b, S: driver::Storage> Iterator for ReadDir<'a, 'b, S> {
10441110
type Item = Result<DirEntry>;
10451111

src/tests.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,16 @@ fn test_iter_dirs() {
449449
file.set_len(37)?;
450450
fs.create_file_and_then(b"/tmp/file.b\0".try_into()?, |file| file.set_len(42))
451451
})?;
452+
let mut tells = Vec::new();
452453

453-
fs.read_dir_and_then(b"/tmp\0".try_into()?, |dir| {
454+
fs.read_dir_and_then(b"/tmp\0".try_into()?, |mut dir| {
454455
let mut found_files: usize = 0;
455456
let mut sizes = [0usize; 4];
457+
let mut i = 0;
456458

457-
for (i, entry) in dir.enumerate() {
459+
tells.push(dir.tell()?);
460+
while let Some(entry) = dir.next() {
461+
tells.push(dir.tell()?);
458462
let entry = entry?;
459463

460464
// assert_eq!(entry.file_name(), match i {
@@ -467,13 +471,31 @@ fn test_iter_dirs() {
467471

468472
sizes[i] = entry.metadata().len();
469473
found_files += 1;
474+
i += 1;
470475
}
471476

472477
assert_eq!(sizes, [0, 0, 37, 42]);
473478
assert_eq!(found_files, 4);
474479

480+
for (i, tell) in tells.iter().enumerate() {
481+
dir.rewind().unwrap();
482+
let mut found_files: usize = 0;
483+
let mut sizes = Vec::new();
484+
dir.seek(*tell)?;
485+
486+
for entry in &mut dir {
487+
let entry = entry?;
488+
sizes.push(entry.metadata().len());
489+
found_files += 1;
490+
}
491+
492+
assert_eq!(sizes, [0, 0, 37, 42][i..]);
493+
assert_eq!(found_files, 4 - i);
494+
}
475495
Ok(())
476496
})
497+
.unwrap();
498+
Ok(())
477499
})
478500
.unwrap();
479501
}

0 commit comments

Comments
 (0)