6 #ifndef BITCOIN_STREAMS_H 7 #define BITCOIN_STREAMS_H 30 if (key.
size() == 0) {
33 key_offset %= key.
size();
35 for (
size_t i = 0, j = key_offset; i != write.
size(); i++) {
48 template<
typename Stream>
110 template <
typename... Args>
122 if (nOverwrite < src.
size()) {
174 if (dst.
size() == 0) {
180 throw std::ios_base::failure(
"SpanReader::read(): end of data");
243 bool Rewind(std::optional<size_type> n = std::nullopt)
266 if (dst.
size() == 0)
return;
270 if (!next_read_pos.has_value() || next_read_pos.value() >
vch.size()) {
271 throw std::ios_base::failure(
"DataStream::read(): end of data");
274 if (next_read_pos.value() ==
vch.size()) {
286 if (!next_read_pos.has_value() || next_read_pos.value() >
vch.size()) {
287 throw std::ios_base::failure(
"DataStream::ignore(): end of data");
289 if (next_read_pos.value() ==
vch.size()) {
322 void Xor(
const std::vector<unsigned char>& key)
349 template <
typename T>
356 template <
typename T>
364 template <
typename IStream>
386 if (nbits < 0 || nbits > 64) {
387 throw std::out_of_range(
"nbits must be between 0 and 64");
397 int bits = std::min(8 -
m_offset, nbits);
399 data |=
static_cast<uint8_t
>(m_buffer << m_offset) >> (8 - bits);
407 template <
typename OStream>
433 void Write(uint64_t data,
int nbits) {
434 if (nbits < 0 || nbits > 64) {
435 throw std::out_of_range(
"nbits must be between 0 and 64");
439 int bits = std::min(8 -
m_offset, nbits);
477 explicit AutoFile(std::FILE* file, std::vector<std::byte> data_xor={}) :
m_file{file},
m_xor{std::move(data_xor)} {}
489 if (
auto rel{
release()})
return std::fclose(rel);
521 void ignore(
size_t nSize);
524 template <
typename T>
531 template <
typename T>
545 explicit CAutoFile(std::FILE* file,
int version, std::vector<std::byte> data_xor = {}) :
AutoFile{file, std::move(data_xor)},
nVersion{version} {}
582 unsigned int readNow =
vchBuf.size() - pos;
584 if (nAvail < readNow)
590 throw std::ios_base::failure{
m_src.
feof() ?
"BufferedFile::Fill: end of file" :
"BufferedFile::Fill: fread failed"};
605 throw std::ios_base::failure(
"Attempt to position past buffer limit");
611 size_t buffer_available{
static_cast<size_t>(
vchBuf.size() - buffer_offset)};
613 size_t advance{std::min({length, buffer_available, bytes_until_source_pos})};
615 return std::make_pair(&
vchBuf[buffer_offset], advance);
622 if (nRewindIn >= nBufSize)
623 throw std::ios_base::failure(
"Rewind limit must be less than buffer size");
636 while (dst.
size() > 0) {
638 memcpy(dst.
data(), buffer_pointer, length);
658 size_t bufsize =
vchBuf.size();
659 if (nPos + bufsize <
nSrcPos) {
675 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
701 const auto it_start{
vchBuf.begin() + buf_offset};
702 const auto it_find{std::find(it_start, it_start + len, byte)};
703 const size_t inc{size_t(std::distance(it_start, it_find))};
705 if (inc < len)
break;
707 if (buf_offset >=
vchBuf.size()) buf_offset = 0;
712 #endif // BITCOIN_STREAMS_H CVectorWriter & operator<<(const T &obj)
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Span< const unsigned char > m_data
std::vector< std::byte > vchBuf
the buffer
uint64_t GetPos() const
return the current reading position
void reserve(size_type n)
vector_type::const_reference const_reference
vector_type::iterator iterator
SpanReader(int version, Span< const unsigned char > data)
void read(Span< std::byte > dst)
std::vector< unsigned char > & vchData
constexpr C * end() const noexcept
void Unserialize(Stream &, char)=delete
AutoFile & operator>>(T &&obj)
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
constexpr std::size_t size() const noexcept
CVectorWriter(int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn)
vector_type::difference_type difference_type
uint64_t nRewind
how many bytes we guarantee to rewind
std::FILE * Get() const
Get wrapped FILE* without transfer of ownership.
OverrideStream< Stream > & operator<<(const T &obj)
Wrapper around a CAutoFile& that implements a ring buffer to deserialize from.
void ignore(size_t num_ignore)
void write(Span< const value_type > src)
void Write(uint64_t data, int nbits)
Write the nbits least significant bits of a 64-bit int to the output stream.
vector_type::value_type value_type
std::FILE * release()
Get wrapped FILE* with transfer of ownership.
Non-refcounted RAII wrapper for FILE*.
CDataStream(int nTypeIn, int nVersionIn)
uint8_t m_buffer
Buffered byte read in from the input stream.
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
prevent reading beyond a certain position no argument removes the limit
Minimal stream for reading from an existing byte array by Span.
std::optional< T > CheckedAdd(const T i, const T j) noexcept
DataStream(Span< const uint8_t > sp)
vector_type::size_type m_read_pos
CAutoFile & operator>>(T &&obj)
vector_type::size_type size_type
void Xor(Span< std::byte > write, Span< const std::byte > key, size_t key_offset=0)
BitStreamReader(IStream &istream)
vector_type::reverse_iterator reverse_iterator
const_iterator end() const
bool Rewind(std::optional< size_type > n=std::nullopt)
DataStream(Span< const value_type > sp)
Double ended buffer combining vector and stream-like interfaces.
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.
DataStream & operator<<(const T &obj)
AutoFile & operator<<(const T &obj)
void write(Span< const std::byte > src)
BufferedFile & operator>>(T &&obj)
CDataStream & operator>>(T &&obj)
vector_type::allocator_type allocator_type
vector_type::const_iterator const_iterator
uint64_t nSrcPos
how many bytes have been read from source
void Serialize(Stream &, char)=delete
bool Fill()
read data from the source to fill the buffer
AutoFile & operator=(const AutoFile &)=delete
OverrideStream(Stream *stream_, int nVersion_)
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...
void read(Span< std::byte > dst)
SerializeData vector_type
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
const_reference operator[](size_type pos) const
DataStream & operator>>(T &&obj)
const std::vector< std::byte > m_xor
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
void FindByte(std::byte byte)
search for a given byte in the stream, and remain positioned on it
const_iterator begin() const
void write(Span< const std::byte > src)
constexpr C * begin() const noexcept
uint8_t m_buffer
Buffered byte waiting to be written to the output stream.
void resize(size_type n, value_type c=value_type{})
int m_offset
Number of high order bits in m_buffer already written by previous Write() calls and not yet flushed t...
bool SetPos(uint64_t nPos)
rewind to a given reading position
CDataStream & operator<<(const T &obj)
const value_type * data() const
constexpr C * data() const noexcept
AutoFile(std::FILE *file, std::vector< std::byte > data_xor={})
int m_offset
Number of high order bits in m_buffer already returned by previous Read() calls.
reference operator[](size_type pos)
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
Span< const std::byte > MakeByteSpan(V &&v) noexcept
uint64_t nReadLimit
up to which position we're allowed to read
constexpr bool empty() const noexcept
Span< const std::byte > AsBytes(Span< T > s) noexcept
bool eof() const
check whether we're at the end of the source file
CDataStream(Span< const uint8_t > sp, int type, int version)
unsigned char * UCharCast(char *c)
void SerializeMany(Stream &s, const Args &... args)
Support for (un)serializing many things at once.
A Span is an object that can refer to a contiguous sequence of objects.
void read(Span< std::byte > dst)
read a number of bytes
vector_type::reference reference
std::size_t detail_fread(Span< std::byte > dst)
Implementation detail, only used internally.
void read(Span< std::byte > dst)
void read(Span< value_type > dst)
BufferedFile(CAutoFile &file, uint64_t nBufSize, uint64_t nRewindIn)
OverrideStream< Stream > & operator>>(T &&obj)
CVectorWriter(int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn, Args &&... args)
CAutoFile & operator<<(const T &obj)
SpanReader & operator>>(T &&obj)
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
CAutoFile(std::FILE *file, int version, std::vector< std::byte > data_xor={})
void write(Span< const std::byte > src)
void ignore(size_t nSize)
BitStreamWriter(OStream &ostream)
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
uint64_t m_read_pos
how many bytes have been read from this