6 #ifndef BITCOIN_STREAMS_H
7 #define BITCOIN_STREAMS_H
23 template<
typename Stream>
50 void write(
const char* pch,
size_t nSize)
55 void read(
char* pch,
size_t nSize)
90 template <
typename... Args>
91 CVectorWriter(
int nTypeIn,
int nVersionIn, std::vector<unsigned char>& vchDataIn,
size_t nPosIn, Args&&... args) :
CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn)
95 void write(
const char* pch,
size_t nSize)
98 size_t nOverwrite = std::min(nSize,
vchData.size() -
nPos);
100 memcpy(
vchData.data() +
nPos,
reinterpret_cast<const unsigned char*
>(pch), nOverwrite);
102 if (nOverwrite < nSize) {
103 vchData.insert(
vchData.end(),
reinterpret_cast<const unsigned char*
>(pch) + nOverwrite,
reinterpret_cast<const unsigned char*
>(pch) + nSize);
136 const std::vector<unsigned char>&
m_data;
147 VectorReader(
int type,
int version,
const std::vector<unsigned char>& data,
size_t pos)
151 throw std::ios_base::failure(
"VectorReader(...): end of data (m_pos > m_data.size())");
159 template <
typename... Args>
160 VectorReader(
int type,
int version,
const std::vector<unsigned char>& data,
size_t pos,
188 size_t pos_next =
m_pos + n;
189 if (pos_next >
m_data.size()) {
190 throw std::ios_base::failure(
"VectorReader::read(): end of data");
225 Init(nTypeIn, nVersionIn);
230 Init(nTypeIn, nVersionIn);
233 CDataStream(
const char* pbegin,
const char* pend,
int nTypeIn,
int nVersionIn) :
vch(pbegin, pend)
235 Init(nTypeIn, nVersionIn);
240 Init(nTypeIn, nVersionIn);
245 Init(nTypeIn, nVersionIn);
250 Init(nTypeIn, nVersionIn);
253 template <
typename... Args>
256 Init(nTypeIn, nVersionIn);
260 void Init(
int nTypeIn,
int nVersionIn)
282 return (std::string(
begin(),
end()));
305 void insert(
iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
307 if (last == first)
return;
308 assert(last - first > 0);
316 vch.insert(
it, first, last);
321 if (last == first)
return;
322 assert(last - first > 0);
330 vch.insert(
it, first, last);
342 return vch.erase(
vch.begin(),
vch.end());
347 return vch.erase(
it);
355 if (last ==
vch.end())
358 return vch.erase(
vch.begin(),
vch.end());
367 return vch.erase(first, last);
398 void read(
char* pch,
size_t nSize)
400 if (nSize == 0)
return;
403 unsigned int nReadPosNext =
nReadPos + nSize;
404 if (nReadPosNext >
vch.size()) {
405 throw std::ios_base::failure(
"CDataStream::read(): end of data");
408 if (nReadPosNext ==
vch.size())
421 throw std::ios_base::failure(
"CDataStream::ignore(): nSize negative");
423 unsigned int nReadPosNext =
nReadPos + nSize;
424 if (nReadPosNext >=
vch.size())
426 if (nReadPosNext >
vch.size())
427 throw std::ios_base::failure(
"CDataStream::ignore(): end of data");
435 void write(
const char* pch,
size_t nSize)
438 vch.insert(
vch.end(), pch, pch + nSize);
441 template<
typename Stream>
475 void Xor(
const std::vector<unsigned char>& key)
477 if (key.size() == 0) {
494 template <
typename IStream>
516 if (nbits < 0 || nbits > 64) {
517 throw std::out_of_range(
"nbits must be between 0 and 64");
527 int bits = std::min(8 -
m_offset, nbits);
529 data |=
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
537 template <
typename OStream>
563 void Write(uint64_t data,
int nbits) {
564 if (nbits < 0 || nbits > 64) {
565 throw std::out_of_range(
"nbits must be between 0 and 64");
569 int bits = std::min(8 -
m_offset, nbits);
655 void read(
char* pch,
size_t nSize)
658 throw std::ios_base::failure(
"CAutoFile::read: file handle is nullptr");
659 if (fread(pch, 1, nSize,
file) != nSize)
660 throw std::ios_base::failure(feof(
file) ?
"CAutoFile::read: end of file" :
"CAutoFile::read: fread failed");
666 throw std::ios_base::failure(
"CAutoFile::ignore: file handle is nullptr");
667 unsigned char data[4096];
669 size_t nNow = std::min<size_t>(nSize,
sizeof(data));
670 if (fread(data, 1, nNow,
file) != nNow)
671 throw std::ios_base::failure(feof(
file) ?
"CAutoFile::ignore: end of file" :
"CAutoFile::read: fread failed");
676 void write(
const char* pch,
size_t nSize)
679 throw std::ios_base::failure(
"CAutoFile::write: file handle is nullptr");
680 if (fwrite(pch, 1, nSize,
file) != nSize)
681 throw std::ios_base::failure(
"CAutoFile::write: write failed");
689 throw std::ios_base::failure(
"CAutoFile::operator<<: file handle is nullptr");
699 throw std::ios_base::failure(
"CAutoFile::operator>>: file handle is nullptr");
728 unsigned int readNow =
vchBuf.size() - pos;
730 if (nAvail < readNow)
734 size_t nBytes = fread((
void*)&
vchBuf[pos], 1, readNow,
src);
736 throw std::ios_base::failure(feof(
src) ?
"CBufferedFile::Fill: end of file" :
"CBufferedFile::Fill: fread failed");
743 CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn,
int nTypeIn,
int nVersionIn) :
746 if (nRewindIn >= nBufSize)
747 throw std::ios_base::failure(
"Rewind limit must be less than buffer size");
777 void read(
char *pch,
size_t nSize) {
779 throw std::ios_base::failure(
"Read attempted past buffer limit");
785 if (nNow + pos >
vchBuf.size())
786 nNow =
vchBuf.size() - pos;
803 size_t bufsize =
vchBuf.size();
804 if (nPos + bufsize <
nSrcPos) {
820 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*.
FILE * release()
Get wrapped FILE* with transfer of ownership.
void ignore(size_t nSize)
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
void write(const char *pch, size_t nSize)
CAutoFile & operator=(const CAutoFile &)=delete
CAutoFile & operator<<(const T &obj)
CAutoFile(const CAutoFile &)=delete
CAutoFile & operator>>(T &&obj)
void read(char *pch, size_t nSize)
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(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
uint64_t nSrcPos
how many bytes have been read from source
bool SetPos(uint64_t nPos)
rewind to a given reading position
uint64_t nReadPos
how many bytes have been read from this
CBufferedFile(const CBufferedFile &)=delete
CBufferedFile & operator=(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.
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn)
CDataStream & operator>>(T &&obj)
const_iterator begin() const
vector_type::allocator_type allocator_type
vector_type::reference reference
CDataStream(const vector_type &vchIn, int nTypeIn, int nVersionIn)
CDataStream(int nTypeIn, int nVersionIn)
CDataStream(const std::vector< char > &vchIn, int nTypeIn, int nVersionIn)
CDataStream(int nTypeIn, int nVersionIn, Args &&... args)
void reserve(size_type n)
vector_type::value_type value_type
CDataStream & operator+=(const CDataStream &b)
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
CSerializeData vector_type
const_iterator end() const
void GetAndClear(CSerializeData &d)
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
void insert(iterator it, size_type n, const char x)
reference operator[](size_type pos)
vector_type::reverse_iterator reverse_iterator
void Init(int nTypeIn, int nVersionIn)
void insert(iterator it, const char *first, const char *last)
void Serialize(Stream &s) const
vector_type::difference_type difference_type
void insert(iterator it, std::vector< char >::const_iterator first, std::vector< char >::const_iterator last)
void resize(size_type n, value_type c=0)
CDataStream(const char *pbegin, const char *pend, int nTypeIn, int nVersionIn)
vector_type::const_iterator const_iterator
vector_type::iterator iterator
const value_type * data() const
CDataStream(const std::vector< unsigned char > &vchIn, int nTypeIn, int nVersionIn)
iterator erase(iterator it)
vector_type::const_reference const_reference
friend CDataStream operator+(const CDataStream &a, const CDataStream &b)
void write(const char *pch, size_t nSize)
CDataStream & operator<<(const T &obj)
iterator insert(iterator it, const char x=char())
CVectorWriter & operator<<(const T &obj)
void write(const char *pch, size_t nSize)
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
OverrideStream(Stream *stream_, int nType_, int nVersion_)
void read(char *pch, size_t nSize)
OverrideStream< Stream > & operator<<(const T &obj)
OverrideStream< Stream > & operator>>(T &&obj)
void write(const char *pch, size_t nSize)
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)
void * memcpy(void *a, const void *b, size_t c)
std::deque< CInv >::iterator it
void SerializeMany(Stream &s)
void Serialize(Stream &s, char a)
void Unserialize(Stream &s, char &a)
void UnserializeMany(Stream &s)
std::vector< char, zero_after_free_allocator< char > > CSerializeData