Skip to content

Commit 4892fb1

Browse files
agrifrafalh
authored andcommitted
add method to File to get extents on-disk
1 parent 2d6bca2 commit 4892fb1

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/file.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ pub struct File<'a, IO: ReadWriteSeek, TP, OCC> {
2525
fs: &'a FileSystem<IO, TP, OCC>,
2626
}
2727

28+
/// An extent containing a file's data on disk.
29+
///
30+
/// This is created by the `extents` method on `File`, and represents
31+
/// a byte range on the disk that contains a file's data. All values
32+
/// are in bytes.
33+
#[derive(Clone, Debug)]
34+
pub struct Extent {
35+
pub offset: u64,
36+
pub size: u32,
37+
}
38+
2839
impl<'a, IO: ReadWriteSeek, TP, OCC> File<'a, IO, TP, OCC> {
2940
pub(crate) fn new(
3041
first_cluster: Option<u32>,
@@ -74,6 +85,39 @@ impl<'a, IO: ReadWriteSeek, TP, OCC> File<'a, IO, TP, OCC> {
7485
}
7586
}
7687

88+
/// Get the extents of a file on disk.
89+
///
90+
/// This returns an iterator over the byte ranges on-disk occupied by
91+
/// this file.
92+
pub fn extents(&mut self) -> impl Iterator<Item=Result<Extent, Error<IO::Error>>> + 'a {
93+
94+
let fs = self.fs;
95+
let cluster_size = fs.cluster_size();
96+
let mut bytes_left = match self.size() {
97+
Some(s) => s,
98+
None => return None.into_iter().flatten(),
99+
};
100+
let first = match self.first_cluster {
101+
Some(f) => f,
102+
None => return None.into_iter().flatten(),
103+
};
104+
105+
Some(core::iter::once(Ok(first)).chain(fs.cluster_iter(first))
106+
.map(move |cluster_err| {
107+
match cluster_err {
108+
Ok(cluster) => {
109+
let size = cluster_size.min(bytes_left);
110+
bytes_left -= size;
111+
Ok(Extent {
112+
offset: fs.offset_from_cluster(cluster),
113+
size: size,
114+
})
115+
},
116+
Err(e) => Err(e),
117+
}
118+
})).into_iter().flatten()
119+
}
120+
77121
pub(crate) fn abs_pos(&self) -> Option<u64> {
78122
// Returns current position relative to filesystem start
79123
// Note: when between clusters it returns position after previous cluster

0 commit comments

Comments
 (0)