6 #ifndef BITCOIN_STREAMS_H
7 #define BITCOIN_STREAMS_H
26 template<
typename Stream>
93 template <
typename... Args>
94 CVectorWriter(
int nTypeIn,
int nVersionIn, std::vector<unsigned char>& vchDataIn,
size_t nPosIn, Args&&...
args) :
CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn)
105 if (nOverwrite < src.
size()) {
167 if (dst.
size() == 0) {
173 throw std::ios_base::failure(
"SpanReader::read(): end of data");
236 bool Rewind(std::optional<size_type> n = std::nullopt)
259 if (dst.
size() == 0)
return;
263 if (!next_read_pos.has_value() || next_read_pos.value() >
vch.size()) {
264 throw std::ios_base::failure(
"DataStream::read(): end of data");
267 if (next_read_pos.value() ==
vch.size()) {
279 if (!next_read_pos.has_value() || next_read_pos.value() >
vch.size()) {
280 throw std::ios_base::failure(
"DataStream::ignore(): end of data");
282 if (next_read_pos.value() ==
vch.size()) {
296 template<
typename Stream>
325 void Xor(
const std::vector<unsigned char>& key)
327 if (key.size() == 0) {
332 vch[i] ^= std::byte{key[j++]};
365 template <
typename T>
372 template <
typename T>
380 template <
typename IStream>
402 if (nbits < 0 || nbits > 64) {
403 throw std::out_of_range(
"nbits must be between 0 and 64");
413 int bits = std::min(8 -
m_offset, nbits);
415 data |=
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
423 template <
typename OStream>
449 void Write(uint64_t data,
int nbits) {
450 if (nbits < 0 || nbits > 64) {
451 throw std::out_of_range(
"nbits must be between 0 and 64");
455 int bits = std::min(8 -
m_offset, nbits);
535 if (!
file)
throw std::ios_base::failure(
"AutoFile::read: file handle is nullptr");
537 throw std::ios_base::failure(feof(
file) ?
"AutoFile::read: end of file" :
"AutoFile::read: fread failed");
543 if (!
file)
throw std::ios_base::failure(
"AutoFile::ignore: file handle is nullptr");
544 unsigned char data[4096];
546 size_t nNow = std::min<size_t>(nSize,
sizeof(data));
547 if (fread(data, 1, nNow,
file) != nNow)
548 throw std::ios_base::failure(feof(
file) ?
"AutoFile::ignore: end of file" :
"AutoFile::read: fread failed");
555 if (!
file)
throw std::ios_base::failure(
"AutoFile::write: file handle is nullptr");
557 throw std::ios_base::failure(
"AutoFile::write: write failed");
561 template <
typename T>
564 if (!
file)
throw std::ios_base::failure(
"AutoFile::operator<<: file handle is nullptr");
569 template <
typename T>
572 if (!
file)
throw std::ios_base::failure(
"AutoFile::operator>>: file handle is nullptr");
594 throw std::ios_base::failure(
"CAutoFile::operator<<: file handle is nullptr");
604 throw std::ios_base::failure(
"CAutoFile::operator>>: file handle is nullptr");
632 unsigned int readNow =
vchBuf.size() - pos;
634 if (nAvail < readNow)
638 size_t nBytes = fread((
void*)&
vchBuf[pos], 1, readNow,
src);
640 throw std::ios_base::failure(feof(
src) ?
"CBufferedFile::Fill: end of file" :
"CBufferedFile::Fill: fread failed");
655 throw std::ios_base::failure(
"Attempt to position past buffer limit");
661 size_t buffer_available{
static_cast<size_t>(
vchBuf.size() - buffer_offset)};
663 size_t advance{std::min({length, buffer_available, bytes_until_source_pos})};
665 return std::make_pair(&
vchBuf[buffer_offset], advance);
669 CBufferedFile(FILE* fileIn, uint64_t nBufSize, uint64_t nRewindIn,
int nTypeIn,
int nVersionIn)
672 if (nRewindIn >= nBufSize)
673 throw std::ios_base::failure(
"Rewind limit must be less than buffer size");
705 while (dst.
size() > 0) {
707 memcpy(dst.
data(), buffer_pointer, length);
727 size_t bufsize =
vchBuf.size();
728 if (nPos + bufsize <
nSrcPos) {
744 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
Non-refcounted RAII wrapper for FILE*.
FILE * release()
Get wrapped FILE* with transfer of ownership.
void ignore(size_t nSize)
void read(Span< std::byte > dst)
AutoFile(const AutoFile &)=delete
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
AutoFile & operator=(const AutoFile &)=delete
AutoFile & operator<<(const T &obj)
AutoFile & operator>>(T &&obj)
void write(Span< const std::byte > src)
uint8_t m_buffer
Buffered byte read in from the input stream.
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
BitStreamReader(IStream &istream)
int m_offset
Number of high order bits in m_buffer already returned by previous Read() calls.
void Write(uint64_t data, int nbits)
Write the nbits least significant bits of a 64-bit int to the output stream.
uint8_t m_buffer
Buffered byte waiting to be written to the output stream.
BitStreamWriter(OStream &ostream)
int m_offset
Number of high order bits in m_buffer already written by previous Write() calls and not yet flushed t...
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
CAutoFile & operator<<(const T &obj)
CAutoFile & operator>>(T &&obj)
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
CBufferedFile & operator>>(T &&obj)
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
prevent reading beyond a certain position no argument removes the limit
uint64_t nReadLimit
up to which position we're allowed to read
void FindByte(uint8_t ch)
search for a given byte in the stream, and remain positioned on it
bool Fill()
read data from the source to fill the buffer
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn)
uint64_t nRewind
how many bytes we guarantee to rewind
void read(Span< std::byte > dst)
read a number of bytes
std::vector< std::byte > vchBuf
the buffer
uint64_t GetPos() const
return the current reading position
uint64_t nSrcPos
how many bytes have been read from source
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
std::pair< std::byte *, size_t > AdvanceStream(size_t length)
Advance the stream's read pointer (m_read_pos) by up to 'length' bytes, filling the buffer from the f...
uint64_t m_read_pos
how many bytes have been read from this
bool SetPos(uint64_t nPos)
rewind to a given reading position
CBufferedFile(const CBufferedFile &)=delete
CBufferedFile & operator=(const CBufferedFile &)=delete
bool eof() const
check whether we're at the end of the source file
CDataStream & operator>>(T &&obj)
CDataStream(int nTypeIn, int nVersionIn)
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
CDataStream(Span< const uint8_t > sp, int type, int version)
CDataStream & operator<<(const T &obj)
void write(Span< const std::byte > src)
CVectorWriter & operator<<(const T &obj)
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn, Args &&... args)
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn)
std::vector< unsigned char > & vchData
Double ended buffer combining vector and stream-like interfaces.
void write(Span< const value_type > src)
vector_type::difference_type difference_type
reference operator[](size_type pos)
void Serialize(Stream &s) const
void resize(size_type n, value_type c=value_type{})
const_reference operator[](size_type pos) const
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
DataStream(Span< const value_type > sp)
vector_type::size_type size_type
SerializeData vector_type
vector_type::const_reference const_reference
const value_type * data() const
vector_type::const_iterator const_iterator
DataStream(Span< const uint8_t > sp)
void reserve(size_type n)
vector_type::reverse_iterator reverse_iterator
DataStream & operator>>(T &&obj)
const_iterator begin() const
void read(Span< value_type > dst)
vector_type::size_type m_read_pos
vector_type::iterator iterator
vector_type::value_type value_type
void ignore(size_t num_ignore)
vector_type::allocator_type allocator_type
const_iterator end() const
bool Rewind(std::optional< size_type > n=std::nullopt)
vector_type::reference reference
DataStream & operator<<(const T &obj)
OverrideStream(Stream *stream_, int nType_, int nVersion_)
void read(Span< std::byte > dst)
void write(Span< const std::byte > src)
OverrideStream< Stream > & operator<<(const T &obj)
OverrideStream< Stream > & operator>>(T &&obj)
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
constexpr C * data() const noexcept
constexpr C * end() const noexcept
constexpr C * begin() const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
constexpr bool empty() const noexcept
Minimal stream for reading from an existing byte array by Span.
SpanReader(int type, int version, Span< const unsigned char > data)
Span< const unsigned char > m_data
SpanReader & operator>>(T &&obj)
void read(Span< std::byte > dst)
std::optional< T > CheckedAdd(const T i, const T j) noexcept
void SerializeMany(Stream &s)
void Unserialize(Stream &, char)=delete
void Serialize(Stream &, char)=delete
unsigned char * UCharCast(char *c)
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Span< const std::byte > AsBytes(Span< T > s) noexcept
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.