6#ifndef BITCOIN_STREAMS_H 
    7#define BITCOIN_STREAMS_H 
   25template<
typename Stream>
 
   52    void write(
const char* pch, 
size_t nSize)
 
   57    void read(
char* pch, 
size_t nSize)
 
   92    template <
typename... Args>
 
   93    CVectorWriter(
int nTypeIn, 
int nVersionIn, std::vector<unsigned char>& vchDataIn, 
size_t nPosIn, Args&&... args) : 
CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn)
 
   97    void write(
const char* pch, 
size_t nSize)
 
  100        size_t nOverwrite = std::min(nSize, 
vchData.size() - 
nPos);
 
  102            memcpy(
vchData.data() + 
nPos, 
reinterpret_cast<const unsigned char*
>(pch), nOverwrite);
 
  104        if (nOverwrite < nSize) {
 
  105            vchData.insert(
vchData.end(), 
reinterpret_cast<const unsigned char*
>(pch) + nOverwrite, 
reinterpret_cast<const unsigned char*
>(pch) + nSize);
 
  138    const std::vector<unsigned char>& 
m_data;
 
  149    VectorReader(
int type, 
int version, 
const std::vector<unsigned char>& data, 
size_t pos)
 
  153            throw std::ios_base::failure(
"VectorReader(...): end of data (m_pos > m_data.size())");
 
  161    template <
typename... Args>
 
  162    VectorReader(
int type, 
int version, 
const std::vector<unsigned char>& data, 
size_t pos,
 
  190        size_t pos_next = 
m_pos + n;
 
  191        if (pos_next > 
m_data.size()) {
 
  192            throw std::ios_base::failure(
"VectorReader::read(): end of data");
 
  234    template <
typename... Args>
 
  244        return (std::string(
begin(), 
end()));
 
  267    void insert(
iterator it, std::vector<uint8_t>::const_iterator first, std::vector<uint8_t>::const_iterator last)
 
  269        if (last == first) 
return;
 
  278            vch.insert(it, first, last);
 
  283        if (last == first) 
return;
 
  292            vch.insert(it, first, last);
 
  304                return vch.erase(
vch.begin(), 
vch.end());
 
  309            return vch.erase(it);
 
  317            if (last == 
vch.end())
 
  320                return vch.erase(
vch.begin(), 
vch.end());
 
  329            return vch.erase(first, last);
 
  338    bool Rewind(std::optional<size_type> n = std::nullopt)
 
  365    void read(
char* pch, 
size_t nSize)
 
  367        if (nSize == 0) 
return;
 
  370        unsigned int nReadPosNext = 
nReadPos + nSize;
 
  371        if (nReadPosNext > 
vch.size()) {
 
  372            throw std::ios_base::failure(
"CDataStream::read(): end of data");
 
  375        if (nReadPosNext == 
vch.size())
 
  388            throw std::ios_base::failure(
"CDataStream::ignore(): nSize negative");
 
  390        unsigned int nReadPosNext = 
nReadPos + nSize;
 
  391        if (nReadPosNext >= 
vch.size())
 
  393            if (nReadPosNext > 
vch.size())
 
  394                throw std::ios_base::failure(
"CDataStream::ignore(): end of data");
 
  402    void write(
const char* pch, 
size_t nSize)
 
  405        vch.insert(
vch.end(), pch, pch + nSize);
 
  408    template<
typename Stream>
 
  437    void Xor(
const std::vector<unsigned char>& key)
 
  439        if (key.size() == 0) {
 
  456template <
typename IStream>
 
  478        if (nbits < 0 || nbits > 64) {
 
  479            throw std::out_of_range(
"nbits must be between 0 and 64");
 
  489            int bits = std::min(8 - 
m_offset, nbits);
 
  491            data |= 
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
 
  499template <
typename OStream>
 
  525    void Write(uint64_t data, 
int nbits) {
 
  526        if (nbits < 0 || nbits > 64) {
 
  527            throw std::out_of_range(
"nbits must be between 0 and 64");
 
  531            int bits = std::min(8 - 
m_offset, nbits);
 
  617    void read(
char* pch, 
size_t nSize)
 
  620            throw std::ios_base::failure(
"CAutoFile::read: file handle is nullptr");
 
  621        if (fread(pch, 1, nSize, 
file) != nSize)
 
  622            throw std::ios_base::failure(feof(
file) ? 
"CAutoFile::read: end of file" : 
"CAutoFile::read: fread failed");
 
  628            throw std::ios_base::failure(
"CAutoFile::ignore: file handle is nullptr");
 
  629        unsigned char data[4096];
 
  631            size_t nNow = std::min<size_t>(nSize, 
sizeof(data));
 
  632            if (fread(data, 1, nNow, 
file) != nNow)
 
  633                throw std::ios_base::failure(feof(
file) ? 
"CAutoFile::ignore: end of file" : 
"CAutoFile::read: fread failed");
 
  638    void write(
const char* pch, 
size_t nSize)
 
  641            throw std::ios_base::failure(
"CAutoFile::write: file handle is nullptr");
 
  642        if (fwrite(pch, 1, nSize, 
file) != nSize)
 
  643            throw std::ios_base::failure(
"CAutoFile::write: write failed");
 
  651            throw std::ios_base::failure(
"CAutoFile::operator<<: file handle is nullptr");
 
  661            throw std::ios_base::failure(
"CAutoFile::operator>>: file handle is nullptr");
 
  690        unsigned int readNow = 
vchBuf.size() - pos;
 
  692        if (nAvail < readNow)
 
  696        size_t nBytes = fread((
void*)&
vchBuf[pos], 1, readNow, 
src);
 
  698            throw std::ios_base::failure(feof(
src) ? 
"CBufferedFile::Fill: end of file" : 
"CBufferedFile::Fill: fread failed");
 
  705    CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, 
int nTypeIn, 
int nVersionIn) :
 
  708        if (nRewindIn >= nBufSize)
 
  709            throw std::ios_base::failure(
"Rewind limit must be less than buffer size");
 
  739    void read(
char *pch, 
size_t nSize) {
 
  741            throw std::ios_base::failure(
"Read attempted past buffer limit");
 
  747            if (nNow + pos > 
vchBuf.size())
 
  748                nNow = 
vchBuf.size() - pos;
 
  751            memcpy(pch, &
vchBuf[pos], nNow);
 
  765        size_t bufsize = 
vchBuf.size();
 
  766        if (nPos + bufsize < 
nSrcPos) {
 
  782    bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
 
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.
Non-refcounted RAII wrapper for FILE*.
CAutoFile & operator=(const CAutoFile &)=delete
CAutoFile & operator>>(T &&obj)
void ignore(size_t nSize)
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
FILE * release()
Get wrapped FILE* with transfer of ownership.
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
void write(const char *pch, size_t nSize)
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
CAutoFile(const CAutoFile &)=delete
CAutoFile & operator<<(const T &obj)
void read(char *pch, size_t nSize)
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
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(char 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
uint64_t GetPos() const
return the current reading position
std::vector< char > vchBuf
the buffer
void read(char *pch, size_t nSize)
read a number of bytes
CBufferedFile & operator>>(T &&obj)
uint64_t nSrcPos
how many bytes have been read from source
bool SetPos(uint64_t nPos)
rewind to a given reading position
CBufferedFile & operator=(const CBufferedFile &)=delete
uint64_t nReadPos
how many bytes have been read from this
CBufferedFile(const CBufferedFile &)=delete
bool eof() const
check whether we're at the end of the source file
Double ended buffer combining vector and stream-like interfaces.
SerializeData vector_type
const_iterator begin() const
vector_type::allocator_type allocator_type
CDataStream(Span< const uint8_t > sp, int nTypeIn, int nVersionIn)
iterator insert(iterator it, const uint8_t x)
CDataStream & operator<<(const T &obj)
vector_type::reference reference
CDataStream(int nTypeIn, int nVersionIn)
CDataStream(int nTypeIn, int nVersionIn, Args &&... args)
void reserve(size_type n)
vector_type::value_type value_type
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
void insert(iterator it, size_type n, const uint8_t x)
const value_type * data() const
const_iterator end() const
iterator erase(iterator first, iterator last)
void read(char *pch, size_t nSize)
vector_type::size_type size_type
const_reference operator[](size_type pos) const
bool Rewind(std::optional< size_type > n=std::nullopt)
reference operator[](size_type pos)
vector_type::reverse_iterator reverse_iterator
void insert(iterator it, const char *first, const char *last)
void Serialize(Stream &s) const
vector_type::difference_type difference_type
void resize(size_type n, value_type c=0)
CDataStream & operator>>(T &&obj)
vector_type::const_iterator const_iterator
vector_type::iterator iterator
iterator erase(iterator it)
vector_type::const_reference const_reference
void insert(iterator it, std::vector< uint8_t >::const_iterator first, std::vector< uint8_t >::const_iterator last)
void write(const char *pch, size_t nSize)
void write(const char *pch, size_t nSize)
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn, Args &&... args)
CVectorWriter & operator<<(const T &obj)
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn)
std::vector< unsigned char > & vchData
OverrideStream(Stream *stream_, int nType_, int nVersion_)
OverrideStream< Stream > & operator>>(T &&obj)
void read(char *pch, size_t nSize)
OverrideStream< Stream > & operator<<(const T &obj)
void write(const char *pch, size_t nSize)
A Span is an object that can refer to a contiguous sequence of objects.
Minimal stream for reading from an existing vector by reference.
const std::vector< unsigned char > & m_data
VectorReader(int type, int version, const std::vector< unsigned char > &data, size_t pos)
VectorReader(int type, int version, const std::vector< unsigned char > &data, size_t pos, Args &&... args)
(other params same as above)
void read(char *dst, size_t n)
VectorReader & operator>>(T &&obj)
#define T(expected, seed, data)
void SerializeMany(Stream &s)
void Serialize(Stream &s, char a)
void Unserialize(Stream &s, char &a)
void UnserializeMany(Stream &s)
std::vector< uint8_t, zero_after_free_allocator< uint8_t > > SerializeData
Byte-vector that clears its contents before deletion.