From: Arik Sosman Date: Thu, 15 Aug 2024 01:51:39 +0000 (-0700) Subject: Reimplement io::Cursor. X-Git-Tag: v0.0.124-beta~9^2~8 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=40b04000aafa33fb7e390da512ed04f64733e3a0;p=rust-lightning Reimplement io::Cursor. The `bitcoin::io` Cursor will miss a bunch of functionality that we were using that we will reimplement here, most critically `set_position`. --- diff --git a/lightning/src/io/mod.rs b/lightning/src/io/mod.rs index 169885b4f..1efcd4511 100644 --- a/lightning/src/io/mod.rs +++ b/lightning/src/io/mod.rs @@ -4,3 +4,75 @@ pub use core2::io::*; #[cfg(feature = "std")] /// Re-export of either `core2::io` or `std::io`, depending on the `std` feature flag. pub use std::io::*; + +/// Emulation of std::io::Cursor +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct Cursor { + inner: T, + pos: u64, +} + +impl Cursor { + /// Creates a `Cursor` by wrapping `inner`. + #[inline] + pub fn new(inner: T) -> Cursor { + Cursor { pos: 0, inner } + } + + /// Returns the position read up to thus far. + #[inline] + pub fn position(&self) -> u64 { + self.pos + } + + /// Returns the inner buffer. + /// + /// This is the whole wrapped buffer, including the bytes already read. + #[inline] + pub fn into_inner(self) -> T { + self.inner + } + + /// Gets a reference to the underlying value in this cursor. + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying value in this cursor. + /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying value as it may corrupt this cursor's position. + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Sets the position of this cursor. + pub fn set_position(&mut self, pos: u64) { + self.pos = pos; + } +} + +impl> Read for Cursor { + fn read(&mut self, buf: &mut [u8]) -> Result { + let n = Read::read(&mut self.fill_buf()?, buf)?; + self.pos += n as u64; + Ok(n) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { + let n = buf.len(); + Read::read_exact(&mut self.fill_buf()?, buf)?; + self.pos += n as u64; + Ok(()) + } +} + +impl> BufRead for Cursor { + fn fill_buf(&mut self) -> Result<&[u8]> { + let amt = core::cmp::min(self.pos, self.inner.as_ref().len() as u64); + Ok(&self.inner.as_ref()[(amt as usize)..]) + } + fn consume(&mut self, amt: usize) { + self.pos += amt as u64; + } +}