6 #ifndef BITCOIN_STREAMS_H
7 #define BITCOIN_STREAMS_H
47 void write(
const char *pch,
size_t nSize) {
stream->write(pch, nSize); }
49 void read(
char *pch,
size_t nSize) {
stream->read(pch, nSize); }
75 CVectorWriter(
int nTypeIn,
int nVersionIn, std::vector<uint8_t> &vchDataIn,
87 template <
typename... Args>
88 CVectorWriter(
int nTypeIn,
int nVersionIn, std::vector<uint8_t> &vchDataIn,
89 size_t nPosIn, Args &&...args)
93 void write(
const char *pch,
size_t nSize) {
95 size_t nOverwrite = std::min(nSize,
vchData.size() -
nPos);
98 reinterpret_cast<const uint8_t *
>(pch), nOverwrite);
100 if (nOverwrite < nSize) {
102 reinterpret_cast<const uint8_t *
>(pch) + nOverwrite,
103 reinterpret_cast<const uint8_t *
>(pch) + nSize);
149 throw std::ios_base::failure(
150 "VectorReader(...): end of data (m_pos > m_data.size())");
158 template <
typename... Args>
160 size_t pos, Args &&...args)
177 void read(
char *dst,
size_t n) {
183 size_t pos_next =
m_pos + n;
184 if (pos_next >
m_data.size()) {
185 throw std::ios_base::failure(
"VectorReader::read(): end of data");
226 template <
typename... Args>
260 vch.insert(it, n, x);
266 std::vector<uint8_t>::const_iterator last) {
273 (
unsigned int)(last - first) <=
nReadPos) {
278 vch.insert(it, first, last);
289 (
unsigned int)(last - first) <=
nReadPos) {
294 vch.insert(it, first, last);
305 return vch.erase(
vch.begin(),
vch.end());
309 return vch.erase(it);
316 if (last ==
vch.end()) {
318 return vch.erase(
vch.begin(),
vch.end());
324 return vch.erase(first, last);
332 bool Rewind(std::optional<size_type> n = std::nullopt) {
358 void read(
char *pch,
size_t nSize) {
364 unsigned int nReadPosNext =
nReadPos + nSize;
365 if (nReadPosNext >
vch.size()) {
366 throw std::ios_base::failure(
"CDataStream::read(): end of data");
369 if (nReadPosNext ==
vch.size()) {
380 throw std::ios_base::failure(
381 "CDataStream::ignore(): nSize negative");
383 unsigned int nReadPosNext =
nReadPos + nSize;
384 if (nReadPosNext >=
vch.size()) {
385 if (nReadPosNext >
vch.size()) {
386 throw std::ios_base::failure(
387 "CDataStream::ignore(): end of data");
396 void write(
const char *pch,
size_t nSize) {
398 vch.insert(
vch.end(), pch, pch + nSize);
401 template <
typename Stream>
void Serialize(Stream &s)
const {
425 void Xor(
const std::vector<uint8_t> &key) {
426 if (key.size() == 0) {
437 if (j == key.size()) j = 0;
463 if (nbits < 0 || nbits > 64) {
464 throw std::out_of_range(
"nbits must be between 0 and 64");
474 int bits = std::min(8 -
m_offset, nbits);
476 data |=
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
506 void Write(uint64_t data,
int nbits) {
507 if (nbits < 0 || nbits > 64) {
508 throw std::out_of_range(
"nbits must be between 0 and 64");
512 int bits = std::min(8 -
m_offset, nbits);
592 void read(
char *pch,
size_t nSize) {
594 throw std::ios_base::failure(
595 "AutoFile::read: file handle is nullptr");
597 if (fread(pch, 1, nSize,
file) != nSize) {
598 throw std::ios_base::failure(feof(
file)
599 ?
"AutoFile::read: end of file"
600 :
"AutoFile::read: fread failed");
606 throw std::ios_base::failure(
607 "AutoFile::ignore: file handle is nullptr");
611 size_t nNow = std::min<size_t>(nSize,
sizeof(data));
612 if (fread(data, 1, nNow,
file) != nNow) {
613 throw std::ios_base::failure(
614 feof(
file) ?
"AutoFile::ignore: end of file"
615 :
"AutoFile::read: fread failed");
621 void write(
const char *pch,
size_t nSize) {
623 throw std::ios_base::failure(
624 "AutoFile::write: file handle is nullptr");
626 if (fwrite(pch, 1, nSize,
file) != nSize) {
627 throw std::ios_base::failure(
"AutoFile::write: write failed");
633 throw std::ios_base::failure(
634 "AutoFile::operator<<: file handle is nullptr");
641 throw std::ios_base::failure(
642 "AutoFile::operator>>: file handle is nullptr");
662 throw std::ios_base::failure(
663 "CAutoFile::operator<<: file handle is nullptr");
672 throw std::ios_base::failure(
673 "CAutoFile::operator>>: file handle is nullptr");
710 unsigned int readNow =
vchBuf.size() - pos;
712 if (nAvail < readNow) {
718 size_t nBytes = fread((
void *)&
vchBuf[pos], 1, readNow,
src);
720 throw std::ios_base::failure(
721 feof(
src) ?
"CBufferedFile::Fill: end of file"
722 :
"CBufferedFile::Fill: fread failed");
730 int nTypeIn,
int nVersionIn)
734 if (nRewindIn >= nBufSize) {
735 throw std::ios_base::failure(
736 "Rewind limit must be less than buffer size");
761 void read(
char *pch,
size_t nSize) {
763 throw std::ios_base::failure(
"Read attempted past buffer limit");
771 if (nNow + pos >
vchBuf.size()) {
772 nNow =
vchBuf.size() - pos;
777 memcpy(pch, &
vchBuf[pos], nNow);
789 size_t bufsize =
vchBuf.size();
790 if (nPos + bufsize <
nSrcPos) {
806 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)
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.
void write(const char *pch, size_t nSize)
AutoFile & operator=(const AutoFile &)=delete
AutoFile & operator<<(const T &obj)
AutoFile & operator>>(T &&obj)
void read(char *pch, size_t nSize)
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.
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 & operator>>(T &&obj)
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)
vector_type::reference reference
CDataStream(int nTypeIn, int nVersionIn)
void reserve(size_type n)
vector_type::value_type value_type
CDataStream & operator+=(const CDataStream &b)
void insert(iterator it, size_type n, const uint8_t x)
const_iterator end() const
void Xor(const std::vector< uint8_t > &key)
XOR the contents of this stream with a certain key.
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
CDataStream(int nTypeIn, int nVersionIn, Args &&...args)
void resize(size_type n, value_type c=0)
vector_type::const_iterator const_iterator
vector_type::iterator iterator
const value_type * data() const
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)
CDataStream & operator<<(const T &obj)
Minimal stream for overwriting and/or appending to an existing byte vector.
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn, Args &&...args)
(other params same as above)
std::vector< uint8_t > & vchData
CVectorWriter & operator<<(const T &obj)
void write(const char *pch, size_t nSize)
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn)
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)
A Span is an object that can refer to a contiguous sequence of objects.
Minimal stream for reading from an existing vector by reference.
VectorReader(int type, int version, const std::vector< uint8_t > &data, size_t pos, Args &&...args)
(other params same as above)
const std::vector< uint8_t > & m_data
void read(char *dst, size_t n)
VectorReader(int type, int version, const std::vector< uint8_t > &data, size_t pos)
VectorReader & operator>>(T &obj)
void SerializeMany(Stream &s)
void Serialize(Stream &s, char a)
void Unserialize(Stream &s, char &a)
void UnserializeMany(Stream &s)
OverrideStream< S > WithOrVersion(S *s, int nVersionFlag)
std::vector< uint8_t, zero_after_free_allocator< uint8_t > > SerializeData
Byte-vector that clears its contents before deletion.