Bitcoin ABC 0.32.4
P2P Digital Currency
streams.h
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef BITCOIN_STREAMS_H
7#define BITCOIN_STREAMS_H
8
9#include <serialize.h>
10#include <span.h>
12
13#include <algorithm>
14#include <cassert>
15#include <cstdint>
16#include <cstdio>
17#include <cstring>
18#include <ios>
19#include <limits>
20#include <optional>
21#include <string>
22#include <utility>
23#include <vector>
24
25template <typename Stream> class OverrideStream {
26 Stream *stream;
27
28 const int nType;
29 const int nVersion;
30
31public:
32 OverrideStream(Stream *stream_, int nType_, int nVersion_)
33 : stream(stream_), nType(nType_), nVersion(nVersion_) {}
34
35 template <typename T> OverrideStream<Stream> &operator<<(const T &obj) {
36 ::Serialize(*this, obj);
37 return (*this);
38 }
39
40 template <typename T> OverrideStream<Stream> &operator>>(T &&obj) {
41 ::Unserialize(*this, obj);
42 return (*this);
43 }
44
45 void write(Span<const std::byte> src) { stream->write(src); }
46
47 void read(Span<std::byte> dst) { stream->read(dst); }
48
49 int GetVersion() const { return nVersion; }
50 int GetType() const { return nType; }
51 void ignore(size_t size) { return stream->ignore(size); }
52};
53
54template <typename S> OverrideStream<S> WithOrVersion(S *s, int nVersionFlag) {
55 return OverrideStream<S>(s, s->GetType(), s->GetVersion() | nVersionFlag);
56}
57
64public:
73 CVectorWriter(int nTypeIn, int nVersionIn, std::vector<uint8_t> &vchDataIn,
74 size_t nPosIn)
75 : nType(nTypeIn), nVersion(nVersionIn), vchData(vchDataIn),
76 nPos(nPosIn) {
77 if (nPos > vchData.size()) {
78 vchData.resize(nPos);
79 }
80 }
85 template <typename... Args>
86 CVectorWriter(int nTypeIn, int nVersionIn, std::vector<uint8_t> &vchDataIn,
87 size_t nPosIn, Args &&...args)
88 : CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn) {
89 ::SerializeMany(*this, std::forward<Args>(args)...);
90 }
92 assert(nPos <= vchData.size());
93 size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
94 if (nOverwrite) {
95 memcpy(vchData.data() + nPos, src.data(), nOverwrite);
96 }
97 if (nOverwrite < src.size()) {
98 vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite,
99 UCharCast(src.end()));
100 }
101 nPos += src.size();
102 }
103 template <typename T> CVectorWriter &operator<<(const T &obj) {
104 ::Serialize(*this, obj);
105 return (*this);
106 }
107 int GetVersion() const { return nVersion; }
108 int GetType() const { return nType; }
109 void seek(size_t nSize) {
110 nPos += nSize;
111 if (nPos > vchData.size()) {
112 vchData.resize(nPos);
113 }
114 }
115
116private:
117 const int nType;
118 const int nVersion;
119 std::vector<uint8_t> &vchData;
120 size_t nPos;
121};
122
127private:
128 const int m_type;
129 const int m_version;
131
132public:
138 SpanReader(int type, int version, Span<const uint8_t> data)
139 : m_type(type), m_version(version), m_data(data) {}
140
141 template <typename T> SpanReader &operator>>(T &obj) {
142 ::Unserialize(*this, obj);
143 return (*this);
144 }
145
146 int GetVersion() const { return m_version; }
147 int GetType() const { return m_type; }
148
149 size_t size() const { return m_data.size(); }
150 bool empty() const { return m_data.empty(); }
151
153 if (dst.size() == 0) {
154 return;
155 }
156
157 // Read from the beginning of the buffer
158 if (dst.size() > m_data.size()) {
159 throw std::ios_base::failure("SpanReader::read(): end of data");
160 }
161 memcpy(dst.data(), m_data.data(), dst.size());
162 m_data = m_data.subspan(dst.size());
163 }
164};
165
174protected:
177 unsigned int nReadPos{0};
178
179public:
180 typedef vector_type::allocator_type allocator_type;
181 typedef vector_type::size_type size_type;
182 typedef vector_type::difference_type difference_type;
183 typedef vector_type::reference reference;
184 typedef vector_type::const_reference const_reference;
185 typedef vector_type::value_type value_type;
186 typedef vector_type::iterator iterator;
187 typedef vector_type::const_iterator const_iterator;
188 typedef vector_type::reverse_iterator reverse_iterator;
189
190 explicit DataStream() {}
193 : vch(sp.data(), sp.data() + sp.size()) {}
194
195 std::string str() const {
196 return std::string{UCharCast(data()), UCharCast(data() + size())};
197 }
198
199 //
200 // Vector subset
201 //
202 const_iterator begin() const { return vch.begin() + nReadPos; }
203 iterator begin() { return vch.begin() + nReadPos; }
204 const_iterator end() const { return vch.end(); }
205 iterator end() { return vch.end(); }
206 size_type size() const { return vch.size() - nReadPos; }
207 bool empty() const { return vch.size() == nReadPos; }
209 vch.resize(n + nReadPos, c);
210 }
211 void reserve(size_type n) { vch.reserve(n + nReadPos); }
213 return vch[pos + nReadPos];
214 }
215 reference operator[](size_type pos) { return vch[pos + nReadPos]; }
216 void clear() {
217 vch.clear();
218 nReadPos = 0;
219 }
220 value_type *data() { return vch.data() + nReadPos; }
221 const value_type *data() const { return vch.data() + nReadPos; }
222
223 void insert(iterator it, std::vector<value_type>::const_iterator first,
224 std::vector<value_type>::const_iterator last) {
225 if (last == first) {
226 return;
227 }
228
229 assert(last - first > 0);
230 if (it == vch.begin() + nReadPos &&
231 (unsigned int)(last - first) <= nReadPos) {
232 // special case for inserting at the front when there's room
233 nReadPos -= (last - first);
234 memcpy(&vch[nReadPos], &first[0], last - first);
235 } else {
236 vch.insert(it, first, last);
237 }
238 }
239
240 // This was added to have full compat with the std::vector interface but is
241 // unused (except in a Bitcoin ABC specific test in stream_tests)
242 void insert(iterator it, const value_type *first, const value_type *last) {
243 if (last == first) {
244 return;
245 }
246
247 assert(last - first > 0);
248 if (it == vch.begin() + nReadPos &&
249 (unsigned int)(last - first) <= nReadPos) {
250 // special case for inserting at the front when there's room
251 nReadPos -= (last - first);
252 memcpy(&vch[nReadPos], &first[0], last - first);
253 } else {
254 vch.insert(it, first, last);
255 }
256 }
257
259 if (it == vch.begin() + nReadPos) {
260 // special case for erasing from the front
261 if (++nReadPos >= vch.size()) {
262 // whenever we reach the end, we take the opportunity to clear
263 // the buffer
264 nReadPos = 0;
265 return vch.erase(vch.begin(), vch.end());
266 }
267 return vch.begin() + nReadPos;
268 } else {
269 return vch.erase(it);
270 }
271 }
272
274 if (first == vch.begin() + nReadPos) {
275 // special case for erasing from the front
276 if (last == vch.end()) {
277 nReadPos = 0;
278 return vch.erase(vch.begin(), vch.end());
279 } else {
280 nReadPos = (last - vch.begin());
281 return last;
282 }
283 } else
284 return vch.erase(first, last);
285 }
286
287 inline void Compact() {
288 vch.erase(vch.begin(), vch.begin() + nReadPos);
289 nReadPos = 0;
290 }
291
292 bool Rewind(std::optional<size_type> n = std::nullopt) {
293 // Total rewind if no size is passed
294 if (!n) {
295 nReadPos = 0;
296 return true;
297 }
298 // Rewind by n characters if the buffer hasn't been compacted yet
299 if (*n > nReadPos) {
300 return false;
301 }
302 nReadPos -= *n;
303 return true;
304 }
305
306 //
307 // Stream subset
308 //
309 bool eof() const { return size() == 0; }
310 int in_avail() const { return size(); }
311
313 if (dst.size() == 0) {
314 return;
315 }
316
317 // Read from the beginning of the buffer
318 unsigned int nReadPosNext = nReadPos + dst.size();
319 if (nReadPosNext > vch.size()) {
320 throw std::ios_base::failure("DataStream::read(): end of data");
321 }
322 memcpy(dst.data(), &vch[nReadPos], dst.size());
323 if (nReadPosNext == vch.size()) {
324 nReadPos = 0;
325 vch.clear();
326 return;
327 }
328 nReadPos = nReadPosNext;
329 }
330
331 void ignore(int nSize) {
332 // Ignore from the beginning of the buffer
333 if (nSize < 0) {
334 throw std::ios_base::failure(
335 "DataStream::ignore(): nSize negative");
336 }
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");
342 }
343 nReadPos = 0;
344 vch.clear();
345 return;
346 }
347 nReadPos = nReadPosNext;
348 }
349
351 // Write to the end of the buffer
352 vch.insert(vch.end(), src.begin(), src.end());
353 }
354
355 template <typename Stream> void Serialize(Stream &s) const {
356 // Special case: stream << stream concatenates like stream += stream
357 if (!vch.empty()) {
358 s.write(MakeByteSpan(vch));
359 }
360 }
361
362 template <typename T> DataStream &operator<<(const T &obj) {
363 ::Serialize(*this, obj);
364 return (*this);
365 }
366
367 template <typename T> DataStream &operator>>(T &&obj) {
368 ::Unserialize(*this, obj);
369 return (*this);
370 }
371
377 void Xor(const std::vector<uint8_t> &key) {
378 if (key.size() == 0) {
379 return;
380 }
381
382 for (size_type i = 0, j = 0; i != size(); i++) {
383 vch[i] ^= std::byte{key[j++]};
384
385 // This potentially acts on very many bytes of data, so it's
386 // important that we calculate `j`, i.e. the `key` index in this way
387 // instead of doing a %, which would effectively be a division for
388 // each byte Xor'd -- much slower than need be.
389 if (j == key.size()) j = 0;
390 }
391 }
392};
393
394class CDataStream : public DataStream {
395private:
396 int nType;
398
399public:
400 explicit CDataStream(int nTypeIn, int nVersionIn)
401 : nType{nTypeIn}, nVersion{nVersionIn} {}
402
403 explicit CDataStream(Span<const uint8_t> sp, int type, int version)
404 : CDataStream{AsBytes(sp), type, version} {}
405 explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn)
406 : DataStream{sp}, nType{nTypeIn}, nVersion{nVersionIn} {}
407
408 int GetType() const { return nType; }
409 void SetVersion(int n) { nVersion = n; }
410 int GetVersion() const { return nVersion; }
411
412 template <typename T> CDataStream &operator<<(const T &obj) {
413 ::Serialize(*this, obj);
414 return *this;
415 }
416
417 template <typename T> CDataStream &operator>>(T &&obj) {
418 ::Unserialize(*this, obj);
419 return *this;
420 }
421};
422
423template <typename IStream> class BitStreamReader {
424private:
425 IStream &m_istream;
426
429 uint8_t m_buffer{0};
430
434 int m_offset{8};
435
436public:
437 explicit BitStreamReader(IStream &istream) : m_istream(istream) {}
438
443 uint64_t Read(int nbits) {
444 if (nbits < 0 || nbits > 64) {
445 throw std::out_of_range("nbits must be between 0 and 64");
446 }
447
448 uint64_t data = 0;
449 while (nbits > 0) {
450 if (m_offset == 8) {
452 m_offset = 0;
453 }
454
455 int bits = std::min(8 - m_offset, nbits);
456 data <<= bits;
457 data |= static_cast<uint8_t>(m_buffer << m_offset) >> (8 - bits);
458 m_offset += bits;
459 nbits -= bits;
460 }
461 return data;
462 }
463};
464
465template <typename OStream> class BitStreamWriter {
466private:
467 OStream &m_ostream;
468
471 uint8_t m_buffer{0};
472
476 int m_offset{0};
477
478public:
479 explicit BitStreamWriter(OStream &ostream) : m_ostream(ostream) {}
480
482
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");
490 }
491
492 while (nbits > 0) {
493 int bits = std::min(8 - m_offset, nbits);
494 m_buffer |= (data << (64 - nbits)) >> (64 - 8 + m_offset);
495 m_offset += bits;
496 nbits -= bits;
497
498 if (m_offset == 8) {
499 Flush();
500 }
501 }
502 }
503
508 void Flush() {
509 if (m_offset == 0) {
510 return;
511 }
512
514 m_buffer = 0;
515 m_offset = 0;
516 }
517};
518
526class AutoFile {
527protected:
528 std::FILE *m_file;
529
530public:
531 explicit AutoFile(std::FILE *file) : m_file{file} {}
532
534
535 // Disallow copies
536 AutoFile(const AutoFile &) = delete;
537 AutoFile &operator=(const AutoFile &) = delete;
538
539 bool feof() const { return std::feof(m_file); }
540
541 int fclose() {
542 if (auto rel{release()}) {
543 return std::fclose(rel);
544 }
545 return 0;
546 }
547
554 std::FILE *release() {
555 std::FILE *ret{m_file};
556 m_file = nullptr;
557 return ret;
558 }
559
565 std::FILE *Get() const { return m_file; }
566
568 bool IsNull() const { return m_file == nullptr; }
569
571 std::size_t detail_fread(Span<std::byte> dst);
572
573 //
574 // Stream subset
575 //
576 void read(Span<std::byte> dst);
577 void ignore(size_t nSize);
579
580 template <typename T> AutoFile &operator<<(const T &obj) {
581 ::Serialize(*this, obj);
582 return *this;
583 }
584
585 template <typename T> AutoFile &operator>>(T &&obj) {
586 ::Unserialize(*this, obj);
587 return *this;
588 }
589};
590
591class CAutoFile : public AutoFile {
592private:
593 const int nType;
594 const int nVersion;
595
596public:
597 CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
598 : AutoFile{filenew}, nType(nTypeIn), nVersion(nVersionIn) {}
599 int GetType() const { return nType; }
600 int GetVersion() const { return nVersion; }
601
602 template <typename T> CAutoFile &operator<<(const T &obj) {
603 ::Serialize(*this, obj);
604 return (*this);
605 }
606
607 template <typename T> CAutoFile &operator>>(T &&obj) {
608 ::Unserialize(*this, obj);
609 return (*this);
610 }
611};
612
622private:
623 const int nType;
624 const int nVersion;
625
627 FILE *src;
629 uint64_t nSrcPos;
631 uint64_t nReadPos;
633 uint64_t nReadLimit;
635 uint64_t nRewind;
637 std::vector<std::byte> vchBuf;
638
640 bool Fill() {
641 unsigned int pos = nSrcPos % vchBuf.size();
642 unsigned int readNow = vchBuf.size() - pos;
643 unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind;
644 if (nAvail < readNow) {
645 readNow = nAvail;
646 }
647 if (readNow == 0) {
648 return false;
649 }
650 size_t nBytes = fread((void *)&vchBuf[pos], 1, readNow, src);
651 if (nBytes == 0) {
652 throw std::ios_base::failure(
653 feof(src) ? "CBufferedFile::Fill: end of file"
654 : "CBufferedFile::Fill: fread failed");
655 }
656 nSrcPos += nBytes;
657 return true;
658 }
659
665 std::pair<std::byte *, size_t> AdvanceStream(size_t length) {
667 if (nReadPos + length > nReadLimit) {
668 throw std::ios_base::failure(
669 "Attempt to position past buffer limit");
670 }
671 // If there are no bytes available, read from the file.
672 if (nReadPos == nSrcPos && length > 0) {
673 Fill();
674 }
675
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)};
680 size_t advance{
681 std::min({length, buffer_available, bytes_until_source_pos})};
682 nReadPos += advance;
683 return std::make_pair(&vchBuf[buffer_offset], advance);
684 }
685
686public:
687 CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn,
688 int nTypeIn, int nVersionIn)
689 : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0),
690 nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn),
691 vchBuf(nBufSize, std::byte{0}) {
692 if (nRewindIn >= nBufSize) {
693 throw std::ios_base::failure(
694 "Rewind limit must be less than buffer size");
695 }
696 src = fileIn;
697 }
698
700
701 // Disallow copies
702 CBufferedFile(const CBufferedFile &) = delete;
704
705 int GetVersion() const { return nVersion; }
706 int GetType() const { return nType; }
707
708 void fclose() {
709 if (src) {
710 ::fclose(src);
711 src = nullptr;
712 }
713 }
714
716 bool eof() const { return nReadPos == nSrcPos && feof(src); }
717
720 while (dst.size() > 0) {
721 auto [buffer_pointer, length]{AdvanceStream(dst.size())};
722 memcpy(dst.data(), buffer_pointer, length);
723 dst = dst.subspan(length);
724 }
725 }
726
729 void SkipTo(const uint64_t file_pos) {
730 assert(file_pos >= nReadPos);
731 while (nReadPos < file_pos) {
732 AdvanceStream(file_pos - nReadPos);
733 }
734 }
735
737 uint64_t GetPos() const { return nReadPos; }
738
740 bool SetPos(uint64_t nPos) {
741 size_t bufsize = vchBuf.size();
742 if (nPos + bufsize < nSrcPos) {
743 // rewinding too far, rewind as far as possible
744 nReadPos = nSrcPos - bufsize;
745 return false;
746 }
747 if (nPos > nSrcPos) {
748 // can't go this far forward, go as far as possible
750 return false;
751 }
752 nReadPos = nPos;
753 return true;
754 }
755
758 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
759 if (nPos < nReadPos) {
760 return false;
761 }
762 nReadLimit = nPos;
763 return true;
764 }
765
766 template <typename T> CBufferedFile &operator>>(T &&obj) {
767 ::Unserialize(*this, obj);
768 return (*this);
769 }
770
772 void FindByte(std::byte byte) {
773 // For best performance, avoid mod operation within the loop.
774 size_t buf_offset{size_t(nReadPos % uint64_t(vchBuf.size()))};
775 while (true) {
776 if (nReadPos == nSrcPos) {
777 // No more bytes available; read from the file into the buffer,
778 // setting nSrcPos to one beyond the end of the new data.
779 // Throws exception if end-of-file reached.
780 Fill();
781 }
782 const size_t len{std::min<size_t>(vchBuf.size() - buf_offset,
783 nSrcPos - nReadPos)};
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))};
787 nReadPos += inc;
788 if (inc < len) {
789 break;
790 }
791 buf_offset += inc;
792 if (buf_offset >= vchBuf.size()) {
793 buf_offset = 0;
794 }
795 }
796 }
797};
798
799#endif // BITCOIN_STREAMS_H
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:526
bool feof() const
Definition: streams.h:539
std::FILE * release()
Get wrapped FILE* with transfer of ownership.
Definition: streams.h:554
void ignore(size_t nSize)
Definition: streams.cpp:22
AutoFile & operator=(const AutoFile &)=delete
~AutoFile()
Definition: streams.h:533
std::FILE * m_file
Definition: streams.h:528
void read(Span< std::byte > dst)
Definition: streams.cpp:15
AutoFile & operator<<(const T &obj)
Definition: streams.h:580
AutoFile(const AutoFile &)=delete
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:568
std::FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:565
AutoFile & operator>>(T &&obj)
Definition: streams.h:585
std::size_t detail_fread(Span< std::byte > dst)
Implementation detail, only used internally.
Definition: streams.cpp:8
void write(Span< const std::byte > src)
Definition: streams.cpp:39
AutoFile(std::FILE *file)
Definition: streams.h:531
int fclose()
Definition: streams.h:541
uint8_t m_buffer
Buffered byte read in from the input stream.
Definition: streams.h:429
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
Definition: streams.h:443
BitStreamReader(IStream &istream)
Definition: streams.h:437
IStream & m_istream
Definition: streams.h:425
int m_offset
Number of high order bits in m_buffer already returned by previous Read() calls.
Definition: streams.h:434
void Write(uint64_t data, int nbits)
Write the nbits least significant bits of a 64-bit int to the output stream.
Definition: streams.h:487
OStream & m_ostream
Definition: streams.h:467
uint8_t m_buffer
Buffered byte waiting to be written to the output stream.
Definition: streams.h:471
BitStreamWriter(OStream &ostream)
Definition: streams.h:479
int m_offset
Number of high order bits in m_buffer already written by previous Write() calls and not yet flushed t...
Definition: streams.h:476
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
Definition: streams.h:508
CAutoFile & operator>>(T &&obj)
Definition: streams.h:607
const int nType
Definition: streams.h:593
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
Definition: streams.h:597
int GetType() const
Definition: streams.h:599
const int nVersion
Definition: streams.h:594
CAutoFile & operator<<(const T &obj)
Definition: streams.h:602
int GetVersion() const
Definition: streams.h:600
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
Definition: streams.h:621
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
Prevent reading beyond a certain position.
Definition: streams.h:758
uint64_t nReadLimit
up to which position we're allowed to read
Definition: streams.h:633
int GetVersion() const
Definition: streams.h:705
bool Fill()
read data from the source to fill the buffer
Definition: streams.h:640
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn)
Definition: streams.h:687
uint64_t nRewind
how many bytes we guarantee to rewind
Definition: streams.h:635
void read(Span< std::byte > dst)
read a number of bytes
Definition: streams.h:719
std::vector< std::byte > vchBuf
the buffer
Definition: streams.h:637
uint64_t GetPos() const
return the current reading position
Definition: streams.h:737
CBufferedFile & operator>>(T &&obj)
Definition: streams.h:766
void FindByte(std::byte byte)
search for a given byte in the stream, and remain positioned on it
Definition: streams.h:772
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...
Definition: streams.h:665
FILE * src
source file
Definition: streams.h:627
~CBufferedFile()
Definition: streams.h:699
int GetType() const
Definition: streams.h:706
uint64_t nSrcPos
how many bytes have been read from source
Definition: streams.h:629
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Definition: streams.h:729
bool SetPos(uint64_t nPos)
rewind to a given reading position
Definition: streams.h:740
const int nType
Definition: streams.h:623
CBufferedFile & operator=(const CBufferedFile &)=delete
uint64_t nReadPos
how many bytes have been read from this
Definition: streams.h:631
CBufferedFile(const CBufferedFile &)=delete
const int nVersion
Definition: streams.h:624
void fclose()
Definition: streams.h:708
bool eof() const
check whether we're at the end of the source file
Definition: streams.h:716
int nVersion
Definition: streams.h:397
void SetVersion(int n)
Definition: streams.h:409
int nType
Definition: streams.h:396
CDataStream & operator<<(const T &obj)
Definition: streams.h:412
int GetType() const
Definition: streams.h:408
CDataStream(int nTypeIn, int nVersionIn)
Definition: streams.h:400
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
Definition: streams.h:405
int GetVersion() const
Definition: streams.h:410
CDataStream & operator>>(T &&obj)
Definition: streams.h:417
CDataStream(Span< const uint8_t > sp, int type, int version)
Definition: streams.h:403
Minimal stream for overwriting and/or appending to an existing byte vector.
Definition: streams.h:63
void write(Span< const std::byte > src)
Definition: streams.h:91
const int nVersion
Definition: streams.h:118
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn, Args &&...args)
(other params same as above)
Definition: streams.h:86
std::vector< uint8_t > & vchData
Definition: streams.h:119
const int nType
Definition: streams.h:117
void seek(size_t nSize)
Definition: streams.h:109
int GetType() const
Definition: streams.h:108
size_t nPos
Definition: streams.h:120
CVectorWriter & operator<<(const T &obj)
Definition: streams.h:103
int GetVersion() const
Definition: streams.h:107
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn)
Definition: streams.h:73
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:173
void write(Span< const value_type > src)
Definition: streams.h:350
DataStream & operator<<(const T &obj)
Definition: streams.h:362
bool empty() const
Definition: streams.h:207
vector_type::difference_type difference_type
Definition: streams.h:182
size_type size() const
Definition: streams.h:206
DataStream & operator>>(T &&obj)
Definition: streams.h:367
reference operator[](size_type pos)
Definition: streams.h:215
void Xor(const std::vector< uint8_t > &key)
XOR the contents of this stream with a certain key.
Definition: streams.h:377
void Serialize(Stream &s) const
Definition: streams.h:355
void resize(size_type n, value_type c=value_type{})
Definition: streams.h:208
void insert(iterator it, const value_type *first, const value_type *last)
Definition: streams.h:242
const_reference operator[](size_type pos) const
Definition: streams.h:212
void insert(iterator it, std::vector< value_type >::const_iterator first, std::vector< value_type >::const_iterator last)
Definition: streams.h:223
DataStream(Span< const value_type > sp)
Definition: streams.h:192
void ignore(int nSize)
Definition: streams.h:331
vector_type::size_type size_type
Definition: streams.h:181
iterator erase(iterator it)
Definition: streams.h:258
SerializeData vector_type
Definition: streams.h:175
vector_type vch
Definition: streams.h:176
const value_type * data() const
Definition: streams.h:221
vector_type::const_reference const_reference
Definition: streams.h:184
value_type * data()
Definition: streams.h:220
vector_type::const_iterator const_iterator
Definition: streams.h:187
DataStream(Span< const uint8_t > sp)
Definition: streams.h:191
void reserve(size_type n)
Definition: streams.h:211
vector_type::reverse_iterator reverse_iterator
Definition: streams.h:188
iterator begin()
Definition: streams.h:203
const_iterator begin() const
Definition: streams.h:202
void read(Span< value_type > dst)
Definition: streams.h:312
DataStream()
Definition: streams.h:190
vector_type::iterator iterator
Definition: streams.h:186
vector_type::value_type value_type
Definition: streams.h:185
bool eof() const
Definition: streams.h:309
std::string str() const
Definition: streams.h:195
vector_type::allocator_type allocator_type
Definition: streams.h:180
const_iterator end() const
Definition: streams.h:204
void Compact()
Definition: streams.h:287
void clear()
Definition: streams.h:216
unsigned int nReadPos
Definition: streams.h:177
iterator end()
Definition: streams.h:205
bool Rewind(std::optional< size_type > n=std::nullopt)
Definition: streams.h:292
vector_type::reference reference
Definition: streams.h:183
int in_avail() const
Definition: streams.h:310
iterator erase(iterator first, iterator last)
Definition: streams.h:273
const int nVersion
Definition: streams.h:29
void ignore(size_t size)
Definition: streams.h:51
OverrideStream(Stream *stream_, int nType_, int nVersion_)
Definition: streams.h:32
void read(Span< std::byte > dst)
Definition: streams.h:47
void write(Span< const std::byte > src)
Definition: streams.h:45
OverrideStream< Stream > & operator>>(T &&obj)
Definition: streams.h:40
Stream * stream
Definition: streams.h:26
int GetVersion() const
Definition: streams.h:49
const int nType
Definition: streams.h:28
int GetType() const
Definition: streams.h:50
OverrideStream< Stream > & operator<<(const T &obj)
Definition: streams.h:35
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:94
constexpr std::size_t size() const noexcept
Definition: span.h:210
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Definition: span.h:219
constexpr C * data() const noexcept
Definition: span.h:199
constexpr C * begin() const noexcept
Definition: span.h:200
constexpr bool empty() const noexcept
Definition: span.h:214
constexpr C * end() const noexcept
Definition: span.h:201
Minimal stream for reading from an existing byte array by Span.
Definition: streams.h:126
bool empty() const
Definition: streams.h:150
const int m_type
Definition: streams.h:128
size_t size() const
Definition: streams.h:149
Span< const uint8_t > m_data
Definition: streams.h:130
SpanReader & operator>>(T &obj)
Definition: streams.h:141
const int m_version
Definition: streams.h:129
int GetType() const
Definition: streams.h:147
void read(Span< std::byte > dst)
Definition: streams.h:152
SpanReader(int type, int version, Span< const uint8_t > data)
Definition: streams.h:138
int GetVersion() const
Definition: streams.h:146
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
void Serialize(Stream &, V)=delete
void SerializeMany(Stream &s)
Definition: serialize.h:1151
void Unserialize(Stream &, V)=delete
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:302
uint8_t * UCharCast(char *c)
Definition: span.h:310
Span< const std::byte > AsBytes(Span< T > s) noexcept
Definition: span.h:295
OverrideStream< S > WithOrVersion(S *s, int nVersionFlag)
Definition: streams.h:54
assert(!tx.IsCoinBase())
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.
Definition: zeroafterfree.h:42