Skip to content

Commit 6f0a3c9

Browse files
Expose directory tell, seek and rewind functionnality
1 parent fdf1a1b commit 6f0a3c9

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
@@ -480,12 +480,16 @@ fn test_iter_dirs() {
480480
file.set_len(37)?;
481481
fs.create_file_and_then(b"/tmp/file.b\0".try_into()?, |file| file.set_len(42))
482482
})?;
483+
let mut tells = Vec::new();
483484

484-
fs.read_dir_and_then(b"/tmp\0".try_into()?, |dir| {
485+
fs.read_dir_and_then(b"/tmp\0".try_into()?, |mut dir| {
485486
let mut found_files: usize = 0;
486487
let mut sizes = [0usize; 4];
488+
let mut i = 0;
487489

488-
for (i, entry) in dir.enumerate() {
490+
tells.push(dir.tell()?);
491+
while let Some(entry) = dir.next() {
492+
tells.push(dir.tell()?);
489493
let entry = entry?;
490494

491495
// assert_eq!(entry.file_name(), match i {
@@ -498,13 +502,31 @@ fn test_iter_dirs() {
498502

499503
sizes[i] = entry.metadata().len();
500504
found_files += 1;
505+
i += 1;
501506
}
502507

503508
assert_eq!(sizes, [0, 0, 37, 42]);
504509
assert_eq!(found_files, 4);
505510

511+
for (i, tell) in tells.iter().enumerate() {
512+
dir.rewind().unwrap();
513+
let mut found_files: usize = 0;
514+
let mut sizes = Vec::new();
515+
dir.seek(*tell)?;
516+
517+
for entry in &mut dir {
518+
let entry = entry?;
519+
sizes.push(entry.metadata().len());
520+
found_files += 1;
521+
}
522+
523+
assert_eq!(sizes, [0, 0, 37, 42][i..]);
524+
assert_eq!(found_files, 4 - i);
525+
}
506526
Ok(())
507527
})
528+
.unwrap();
529+
Ok(())
508530
})
509531
.unwrap();
510532
}

0 commit comments

Comments
 (0)