6#ifndef BITCOIN_STREAMS_H
7#define BITCOIN_STREAMS_H
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)
99 if (nOverwrite < src.
size()) {
157 if (dst.
size() == 0) {
163 throw std::ios_base::failure(
"SpanReader::read(): end of data");
206 template <
typename... Args>
238 return vch.insert(it, x);
241 vch.insert(it, n, x);
247 std::vector<value_type>::const_iterator last) {
254 (
unsigned int)(last - first) <=
nReadPos) {
259 vch.insert(it, first, last);
272 (
unsigned int)(last - first) <=
nReadPos) {
277 vch.insert(it, first, last);
288 return vch.erase(
vch.begin(),
vch.end());
292 return vch.erase(it);
299 if (last ==
vch.end()) {
301 return vch.erase(
vch.begin(),
vch.end());
307 return vch.erase(first, last);
315 bool Rewind(std::optional<size_type> n = std::nullopt) {
342 if (dst.
size() == 0) {
348 if (nReadPosNext >
vch.size()) {
349 throw std::ios_base::failure(
"CDataStream::read(): end of data");
352 if (nReadPosNext ==
vch.size()) {
363 throw std::ios_base::failure(
364 "CDataStream::ignore(): nSize negative");
366 unsigned int nReadPosNext =
nReadPos + nSize;
367 if (nReadPosNext >=
vch.size()) {
368 if (nReadPosNext >
vch.size()) {
369 throw std::ios_base::failure(
370 "CDataStream::ignore(): end of data");
384 template <
typename Stream>
void Serialize(Stream &s)
const {
408 void Xor(
const std::vector<uint8_t> &key) {
409 if (key.size() == 0) {
414 vch[i] ^= std::byte{key[j++]};
420 if (j == key.size()) j = 0;
446 if (nbits < 0 || nbits > 64) {
447 throw std::out_of_range(
"nbits must be between 0 and 64");
457 int bits = std::min(8 -
m_offset, nbits);
459 data |=
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
489 void Write(uint64_t data,
int nbits) {
490 if (nbits < 0 || nbits > 64) {
491 throw std::out_of_range(
"nbits must be between 0 and 64");
495 int bits = std::min(8 -
m_offset, nbits);
577 throw std::ios_base::failure(
578 "AutoFile::read: file handle is nullptr");
581 throw std::ios_base::failure(feof(
file)
582 ?
"AutoFile::read: end of file"
583 :
"AutoFile::read: fread failed");
589 throw std::ios_base::failure(
590 "AutoFile::ignore: file handle is nullptr");
594 size_t nNow = std::min<size_t>(nSize,
sizeof(data));
595 if (fread(data, 1, nNow,
file) != nNow) {
596 throw std::ios_base::failure(
597 feof(
file) ?
"AutoFile::ignore: end of file"
598 :
"AutoFile::read: fread failed");
606 throw std::ios_base::failure(
607 "AutoFile::write: file handle is nullptr");
610 throw std::ios_base::failure(
"AutoFile::write: write failed");
616 throw std::ios_base::failure(
617 "AutoFile::operator<<: file handle is nullptr");
624 throw std::ios_base::failure(
625 "AutoFile::operator>>: file handle is nullptr");
645 throw std::ios_base::failure(
646 "CAutoFile::operator<<: file handle is nullptr");
655 throw std::ios_base::failure(
656 "CAutoFile::operator>>: file handle is nullptr");
692 unsigned int readNow =
vchBuf.size() - pos;
694 if (nAvail < readNow) {
700 size_t nBytes = fread((
void *)&
vchBuf[pos], 1, readNow,
src);
702 throw std::ios_base::failure(
703 feof(
src) ?
"CBufferedFile::Fill: end of file"
704 :
"CBufferedFile::Fill: fread failed");
718 throw std::ios_base::failure(
719 "Attempt to position past buffer limit");
726 size_t buffer_offset{
static_cast<size_t>(
nReadPos %
vchBuf.size())};
727 size_t buffer_available{
728 static_cast<size_t>(
vchBuf.size() - buffer_offset)};
729 size_t bytes_until_source_pos{
static_cast<size_t>(
nSrcPos -
nReadPos)};
731 std::min({length, buffer_available, bytes_until_source_pos})};
733 return std::make_pair(&
vchBuf[buffer_offset], advance);
738 int nTypeIn,
int nVersionIn)
742 if (nRewindIn >= nBufSize) {
743 throw std::ios_base::failure(
744 "Rewind limit must be less than buffer size");
770 while (dst.
size() > 0) {
772 memcpy(dst.
data(), buffer_pointer, length);
791 size_t bufsize =
vchBuf.size();
792 if (nPos + bufsize <
nSrcPos) {
808 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
833 const size_t len{std::min<size_t>(
vchBuf.size() - buf_offset,
835 const auto it_start{
vchBuf.begin() + buf_offset};
836 const auto it_find{std::find(it_start, it_start + len,
byte)};
837 const size_t inc{size_t(std::distance(it_start, it_find))};
843 if (buf_offset >=
vchBuf.size()) {
Non-refcounted RAII wrapper for FILE*.
void ignore(size_t nSize)
AutoFile & operator=(const AutoFile &)=delete
void read(Span< std::byte > dst)
AutoFile & operator<<(const T &obj)
AutoFile(const AutoFile &)=delete
FILE * release()
Get wrapped FILE* with transfer of ownership.
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
AutoFile & operator>>(T &&obj)
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
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 & operator>>(T &&obj)
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
CAutoFile & operator<<(const T &obj)
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.
uint64_t nReadLimit
up to which position we're allowed to read
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
CBufferedFile & operator>>(T &&obj)
void FindByte(std::byte byte)
search for a given byte in the stream, and remain positioned on it
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 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.
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
void insert(iterator it, std::vector< value_type >::const_iterator first, std::vector< value_type >::const_iterator last)
CDataStream & operator<<(const T &obj)
vector_type::reference reference
CDataStream(int nTypeIn, int nVersionIn)
void read(Span< value_type > dst)
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
iterator insert(iterator it, const value_type x)
void reserve(size_type n)
vector_type::value_type value_type
const value_type * data() const
const_iterator end() const
void write(Span< const value_type > src)
void Xor(const std::vector< uint8_t > &key)
XOR the contents of this stream with a certain key.
void insert(iterator it, const value_type *first, const value_type *last)
iterator erase(iterator first, iterator last)
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 Serialize(Stream &s) const
vector_type::difference_type difference_type
CDataStream(int nTypeIn, int nVersionIn, Args &&...args)
CDataStream & operator>>(T &&obj)
vector_type::const_iterator const_iterator
vector_type::iterator iterator
void resize(size_type n, value_type c=value_type{})
iterator erase(iterator it)
vector_type::const_reference const_reference
void insert(iterator it, size_type n, const value_type x)
CDataStream(Span< const uint8_t > sp, int type, int version)
Minimal stream for overwriting and/or appending to an existing byte vector.
void write(Span< const std::byte > src)
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)
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn)
OverrideStream(Stream *stream_, int nType_, int nVersion_)
void read(Span< std::byte > dst)
void write(Span< const std::byte > src)
OverrideStream< Stream > & operator>>(T &&obj)
OverrideStream< Stream > & operator<<(const T &obj)
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
constexpr C * data() const noexcept
constexpr C * begin() const noexcept
constexpr bool empty() const noexcept
constexpr C * end() const noexcept
Minimal stream for reading from an existing byte array by Span.
Span< const uint8_t > m_data
SpanReader & operator>>(T &obj)
void read(Span< std::byte > dst)
SpanReader(int type, int version, Span< const uint8_t > data)
Implement std::hash so RCUPtr can be used as a key for maps or sets.
void SerializeMany(Stream &s)
void Unserialize(Stream &, char)=delete
void Serialize(Stream &, char)=delete
Span< const std::byte > MakeByteSpan(V &&v) noexcept
uint8_t * UCharCast(char *c)
Span< const std::byte > AsBytes(Span< T > s) noexcept
OverrideStream< S > WithOrVersion(S *s, int nVersionFlag)
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.