From b43c0bb3efaad67259ce077ee89ef152b47a5d5f Mon Sep 17 00:00:00 2001 From: edef Date: Sun, 24 Apr 2022 23:14:44 +0000 Subject: ripple/fossil: implement io::Seek for RawBlob Change-Id: I625530fe2f4db89be5889e46f0a5ed50727c8cd1 --- ripple/fossil/src/lib.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'ripple/fossil/src/lib.rs') 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 { + 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 { + 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 { + Ok(self.position) + } +} + pub type Digest = blake3::Hash; pub struct Directory { -- cgit 1.4.1