rust: Add `cxx` version of `RustStream`

This commit is contained in:
Jack Grigg 2023-01-24 02:16:51 +00:00
parent 9e1efad2d1
commit 908675b5b9
4 changed files with 68 additions and 0 deletions

View File

@ -56,6 +56,7 @@ CXXBRIDGE_RS = \
rust/src/equihash.rs \
rust/src/orchard_bundle.rs \
rust/src/sapling.rs \
rust/src/streams.rs \
rust/src/wallet_scanner.rs
CXXBRIDGE_H = \
rust/gen/include/rust/blake2b.h \
@ -63,6 +64,7 @@ CXXBRIDGE_H = \
rust/gen/include/rust/equihash.h \
rust/gen/include/rust/orchard_bundle.h \
rust/gen/include/rust/sapling.h \
rust/gen/include/rust/streams.h \
rust/gen/include/rust/wallet_scanner.h
CXXBRIDGE_CPP = \
rust/gen/src/blake2b.cpp \
@ -70,6 +72,7 @@ CXXBRIDGE_CPP = \
rust/gen/src/equihash.cpp \
rust/gen/src/orchard_bundle.cpp \
rust/gen/src/sapling.cpp \
rust/gen/src/streams.cpp \
rust/gen/src/wallet_scanner.cpp
# We add a rust/cxx.h include to indicate that we provide this (via the rustcxx depends

View File

@ -72,6 +72,7 @@ mod orchard_bundle;
mod orchard_ffi;
mod orchard_keys_ffi;
mod sapling;
mod streams;
mod transaction_ffi;
mod unified_keys_ffi;
mod wallet;

47
src/rust/src/streams.rs Normal file
View File

@ -0,0 +1,47 @@
use std::io;
use std::pin::Pin;
#[cxx::bridge]
pub(crate) mod ffi {
extern "C++" {
include!("streams.h");
#[cxx_name = "RustDataStream"]
type RustStream;
unsafe fn read_u8(self: Pin<&mut RustStream>, pch: *mut u8, nSize: usize) -> Result<()>;
unsafe fn write_u8(self: Pin<&mut RustStream>, pch: *const u8, nSize: usize) -> Result<()>;
}
impl UniquePtr<RustStream> {}
}
pub struct CppStream<'a> {
inner: Pin<&'a mut ffi::RustStream>,
}
impl<'a> From<Pin<&'a mut ffi::RustStream>> for CppStream<'a> {
fn from(inner: Pin<&'a mut ffi::RustStream>) -> Self {
Self { inner }
}
}
impl<'a> io::Read for CppStream<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
unsafe { self.inner.as_mut().read_u8(buf.as_mut_ptr(), buf.len()) }
.map(|()| buf.len())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
}
impl<'a> io::Write for CppStream<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
unsafe { self.inner.as_mut().write_u8(buf.as_ptr(), buf.len()) }
.map(|()| buf.len())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

View File

@ -317,6 +317,11 @@ public:
void SetVersion(int n) { nVersion = n; }
int GetVersion() const { return nVersion; }
void read_u8(unsigned char* pch, size_t nSize)
{
read(reinterpret_cast<char*>(pch), nSize);
}
void read(char* pch, size_t nSize)
{
if (nSize == 0) return;
@ -360,6 +365,11 @@ public:
nReadPos = nReadPosNext;
}
void write_u8(const unsigned char* pch, size_t nSize)
{
write(reinterpret_cast<const char*>(pch), nSize);
}
void write(const char* pch, size_t nSize)
{
// Write to the end of the buffer
@ -424,6 +434,13 @@ public:
};
/**
* Concrete instantiation of a data stream, enabling them to be passed into Rust code.
*
* TODO: Rename this to RustStream once the non-`cxx` usages have been migrated to `cxx`.
*/
typedef CBaseDataStream<CSerializeData> RustDataStream;