diff options
Diffstat (limited to 'ripple/fossil/src')
-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 { |