Skip to content

Commit 40b0400

Browse files
committed
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`.
1 parent b05113a commit 40b0400

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

lightning/src/io/mod.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,75 @@ pub use core2::io::*;
44
#[cfg(feature = "std")]
55
/// Re-export of either `core2::io` or `std::io`, depending on the `std` feature flag.
66
pub use std::io::*;
7+
8+
/// Emulation of std::io::Cursor
9+
#[derive(Clone, Debug, Default, Eq, PartialEq)]
10+
pub struct Cursor<T> {
11+
inner: T,
12+
pos: u64,
13+
}
14+
15+
impl<T> Cursor<T> {
16+
/// Creates a `Cursor` by wrapping `inner`.
17+
#[inline]
18+
pub fn new(inner: T) -> Cursor<T> {
19+
Cursor { pos: 0, inner }
20+
}
21+
22+
/// Returns the position read up to thus far.
23+
#[inline]
24+
pub fn position(&self) -> u64 {
25+
self.pos
26+
}
27+
28+
/// Returns the inner buffer.
29+
///
30+
/// This is the whole wrapped buffer, including the bytes already read.
31+
#[inline]
32+
pub fn into_inner(self) -> T {
33+
self.inner
34+
}
35+
36+
/// Gets a reference to the underlying value in this cursor.
37+
pub fn get_ref(&self) -> &T {
38+
&self.inner
39+
}
40+
41+
/// Gets a mutable reference to the underlying value in this cursor.
42+
///
43+
/// Care should be taken to avoid modifying the internal I/O state of the
44+
/// underlying value as it may corrupt this cursor's position.
45+
pub fn get_mut(&mut self) -> &mut T {
46+
&mut self.inner
47+
}
48+
49+
/// Sets the position of this cursor.
50+
pub fn set_position(&mut self, pos: u64) {
51+
self.pos = pos;
52+
}
53+
}
54+
55+
impl<T: AsRef<[u8]>> Read for Cursor<T> {
56+
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
57+
let n = Read::read(&mut self.fill_buf()?, buf)?;
58+
self.pos += n as u64;
59+
Ok(n)
60+
}
61+
62+
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
63+
let n = buf.len();
64+
Read::read_exact(&mut self.fill_buf()?, buf)?;
65+
self.pos += n as u64;
66+
Ok(())
67+
}
68+
}
69+
70+
impl<T: AsRef<[u8]>> BufRead for Cursor<T> {
71+
fn fill_buf(&mut self) -> Result<&[u8]> {
72+
let amt = core::cmp::min(self.pos, self.inner.as_ref().len() as u64);
73+
Ok(&self.inner.as_ref()[(amt as usize)..])
74+
}
75+
fn consume(&mut self, amt: usize) {
76+
self.pos += amt as u64;
77+
}
78+
}

0 commit comments

Comments
 (0)