6#ifndef BITCOIN_STREAMS_H
7#define BITCOIN_STREAMS_H
73 CVectorWriter(
int nTypeIn,
int nVersionIn, std::vector<uint8_t> &vchDataIn,
85 template <
typename... Args>
86 CVectorWriter(
int nTypeIn,
int nVersionIn, std::vector<uint8_t> &vchDataIn,
87 size_t nPosIn, Args &&...args)
97 if (nOverwrite < src.
size()) {
153 if (dst.
size() == 0) {
159 throw std::ios_base::failure(
"SpanReader::read(): end of data");
224 std::vector<value_type>::const_iterator last) {
231 (
unsigned int)(last - first) <=
nReadPos) {
236 vch.insert(it, first, last);
249 (
unsigned int)(last - first) <=
nReadPos) {
254 vch.insert(it, first, last);
265 return vch.erase(
vch.begin(),
vch.end());
269 return vch.erase(it);
276 if (last ==
vch.end()) {
278 return vch.erase(
vch.begin(),
vch.end());
284 return vch.erase(first, last);
292 bool Rewind(std::optional<size_type> n = std::nullopt) {
313 if (dst.
size() == 0) {
319 if (nReadPosNext >
vch.size()) {
320 throw std::ios_base::failure(
"DataStream::read(): end of data");
323 if (nReadPosNext ==
vch.size()) {
334 throw std::ios_base::failure(
335 "DataStream::ignore(): nSize negative");
337 unsigned int nReadPosNext =
nReadPos + nSize;
338 if (nReadPosNext >=
vch.size()) {
339 if (nReadPosNext >
vch.size()) {
340 throw std::ios_base::failure(
341 "DataStream::ignore(): end of data");
355 template <
typename Stream>
void Serialize(Stream &s)
const {
377 void Xor(
const std::vector<uint8_t> &key) {
378 if (key.size() == 0) {
383 vch[i] ^= std::byte{key[j++]};
389 if (j == key.size()) j = 0;
444 if (nbits < 0 || nbits > 64) {
445 throw std::out_of_range(
"nbits must be between 0 and 64");
455 int bits = std::min(8 -
m_offset, nbits);
457 data |=
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
487 void Write(uint64_t data,
int nbits) {
488 if (nbits < 0 || nbits > 64) {
489 throw std::out_of_range(
"nbits must be between 0 and 64");
493 int bits = std::min(8 -
m_offset, nbits);
543 return std::fclose(rel);
577 void ignore(
size_t nSize);
642 unsigned int readNow =
vchBuf.size() - pos;
644 if (nAvail < readNow) {
650 size_t nBytes = fread((
void *)&
vchBuf[pos], 1, readNow,
src);
652 throw std::ios_base::failure(
653 feof(
src) ?
"CBufferedFile::Fill: end of file"
654 :
"CBufferedFile::Fill: fread failed");
668 throw std::ios_base::failure(
669 "Attempt to position past buffer limit");
676 size_t buffer_offset{
static_cast<size_t>(
nReadPos %
vchBuf.size())};
677 size_t buffer_available{
678 static_cast<size_t>(
vchBuf.size() - buffer_offset)};
679 size_t bytes_until_source_pos{
static_cast<size_t>(
nSrcPos -
nReadPos)};
681 std::min({length, buffer_available, bytes_until_source_pos})};
683 return std::make_pair(&
vchBuf[buffer_offset], advance);
688 int nTypeIn,
int nVersionIn)
692 if (nRewindIn >= nBufSize) {
693 throw std::ios_base::failure(
694 "Rewind limit must be less than buffer size");
720 while (dst.
size() > 0) {
722 memcpy(dst.
data(), buffer_pointer, length);
741 size_t bufsize =
vchBuf.size();
742 if (nPos + bufsize <
nSrcPos) {
758 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
782 const size_t len{std::min<size_t>(
vchBuf.size() - buf_offset,
784 const auto it_start{
vchBuf.begin() + buf_offset};
785 const auto it_find{std::find(it_start, it_start + len,
byte)};
786 const size_t inc{size_t(std::distance(it_start, it_find))};
792 if (buf_offset >=
vchBuf.size()) {
Non-refcounted RAII wrapper for FILE*.
std::FILE * release()
Get wrapped FILE* with transfer of ownership.
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
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
std::FILE * Get() const
Get wrapped FILE* without transfer of ownership.
AutoFile & operator>>(T &&obj)
std::size_t detail_fread(Span< std::byte > dst)
Implementation detail, only used internally.
void write(Span< const std::byte > src)
AutoFile(std::FILE *file)
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
CDataStream & operator<<(const T &obj)
CDataStream(int nTypeIn, int nVersionIn)
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
CDataStream & operator>>(T &&obj)
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)
Double ended buffer combining vector and stream-like interfaces.
void write(Span< const value_type > src)
DataStream & operator<<(const T &obj)
vector_type::difference_type difference_type
DataStream & operator>>(T &&obj)
reference operator[](size_type pos)
void Xor(const std::vector< uint8_t > &key)
XOR the contents of this stream with a certain key.
void Serialize(Stream &s) const
void resize(size_type n, value_type c=value_type{})
void insert(iterator it, const value_type *first, const value_type *last)
const_reference operator[](size_type pos) const
void insert(iterator it, std::vector< value_type >::const_iterator first, std::vector< value_type >::const_iterator last)
DataStream(Span< const value_type > sp)
vector_type::size_type size_type
iterator erase(iterator it)
SerializeData vector_type
const value_type * data() const
vector_type::const_reference const_reference
vector_type::const_iterator const_iterator
DataStream(Span< const uint8_t > sp)
void reserve(size_type n)
vector_type::reverse_iterator reverse_iterator
const_iterator begin() const
void read(Span< value_type > dst)
vector_type::iterator iterator
vector_type::value_type value_type
vector_type::allocator_type allocator_type
const_iterator end() const
bool Rewind(std::optional< size_type > n=std::nullopt)
vector_type::reference reference
iterator erase(iterator first, iterator last)
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 Serialize(Stream &, V)=delete
void SerializeMany(Stream &s)
void Unserialize(Stream &, V)=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.