diff options
author | edef <edef@unfathomable.blue> | 2022-04-24 23:14:44 +0000 |
---|---|---|
committer | edef <edef@unfathomable.blue> | 2022-04-24 23:14:44 +0000 |
commit | b43c0bb3efaad67259ce077ee89ef152b47a5d5f (patch) | |
tree | bee55aeee04984c937e56143df3e9fa41bf3ebde /ripple/fossil | |
parent | 7d904668a7a923aad6795d7bbcde39712e131b22 (diff) | |
download | unf-legacy-b43c0bb3efaad67259ce077ee89ef152b47a5d5f.tar.zst |
ripple/fossil: implement io::Seek for RawBlob
Change-Id: I625530fe2f4db89be5889e46f0a5ed50727c8cd1
Diffstat (limited to 'ripple/fossil')
-rw-r--r-- | ripple/fossil/src/lib.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/ripple/fossil/src/lib.rs b/ripple/fossil/src/lib.rs index 753c3d6..93a1a88 100644 --- a/ripple/fossil/src/lib.rs +++ b/ripple/fossil/src/lib.rs @@ -234,6 +234,45 @@ impl io::Read for RawBlob<'_> { } } +// TODO(edef): use checked_add_signed when mixed_integer_ops stabilises +fn checked_add_signed(lhs: u64, rhs: i64) -> Option<u64> { + if rhs >= 0 { + lhs.checked_add(rhs as u64) + } else { + lhs.checked_sub(rhs.unsigned_abs()) + } +} + +impl io::Seek for RawBlob<'_> { + fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> { + let pos = match pos { + io::SeekFrom::Start(n) => Some(n), + io::SeekFrom::End(n) => checked_add_signed(self.slice.length, n), + io::SeekFrom::Current(n) => checked_add_signed(self.position, n), + }; + + match pos { + Some(n) if n <= self.slice.length => { + self.position = n; + Ok(self.position) + } + _ => Err(io::Error::new( + io::ErrorKind::InvalidInput, + "seek out of range", + )), + } + } + + fn rewind(&mut self) -> io::Result<()> { + self.position = 0; + Ok(()) + } + + fn stream_position(&mut self) -> io::Result<u64> { + Ok(self.position) + } +} + pub type Digest = blake3::Hash; pub struct Directory { |