Bitcoin ABC 0.30.5
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 to this stream
37 ::Serialize(*this, obj);
38 return (*this);
39 }
40
41 template <typename T> OverrideStream<Stream> &operator>>(T &&obj) {
42 // Unserialize from this stream
43 ::Unserialize(*this, obj);
44 return (*this);
45 }
46
47 void write(Span<const std::byte> src) { stream->write(src); }
48
49 void read(Span<std::byte> dst) { stream->read(dst); }
50
51 int GetVersion() const { return nVersion; }
52 int GetType() const { return nType; }
53 void ignore(size_t size) { return stream->ignore(size); }
54};
55
56template <typename S> OverrideStream<S> WithOrVersion(S *s, int nVersionFlag) {
57 return OverrideStream<S>(s, s->GetType(), s->GetVersion() | nVersionFlag);
58}
59
66public:
75 CVectorWriter(int nTypeIn, int nVersionIn, std::vector<uint8_t> &vchDataIn,
76 size_t nPosIn)
77 : nType(nTypeIn), nVersion(nVersionIn), vchData(vchDataIn),
78 nPos(nPosIn) {
79 if (nPos > vchData.size()) {
80 vchData.resize(nPos);
81 }
82 }
87 template <typename... Args>
88 CVectorWriter(int nTypeIn, int nVersionIn, std::vector<uint8_t> &vchDataIn,
89 size_t nPosIn, Args &&...args)
90 : CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn) {
91 ::SerializeMany(*this, std::forward<Args>(args)...);
92 }
94 assert(nPos <= vchData.size());
95 size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
96 if (nOverwrite) {
97 memcpy(vchData.data() + nPos, src.data(), nOverwrite);
98 }
99 if (nOverwrite < src.size()) {
100 vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite,
101 UCharCast(src.end()));
102 }
103 nPos += src.size();
104 }
105 template <typename T> CVectorWriter &operator<<(const T &obj) {
106 // Serialize to this stream
107 ::Serialize(*this, obj);
108 return (*this);
109 }
110 int GetVersion() const { return nVersion; }
111 int GetType() const { return nType; }
112 void seek(size_t nSize) {
113 nPos += nSize;
114 if (nPos > vchData.size()) {
115 vchData.resize(nPos);
116 }
117 }
118
119private:
120 const int nType;
121 const int nVersion;
122 std::vector<uint8_t> &vchData;
123 size_t nPos;
124};
125
130private:
131 const int m_type;
132 const int m_version;
134
135public:
141 SpanReader(int type, int version, Span<const uint8_t> data)
142 : m_type(type), m_version(version), m_data(data) {}
143
144 template <typename T> SpanReader &operator>>(T &obj) {
145 // Unserialize from this stream
146 ::Unserialize(*this, obj);
147 return (*this);
148 }
149
150 int GetVersion() const { return m_version; }
151 int GetType() const { return m_type; }
152
153 size_t size() const { return m_data.size(); }
154 bool empty() const { return m_data.empty(); }
155
157 if (dst.size() == 0) {
158 return;
159 }
160
161 // Read from the beginning of the buffer
162 if (dst.size() > m_data.size()) {
163 throw std::ios_base::failure("SpanReader::read(): end of data");
164 }
165 memcpy(dst.data(), m_data.data(), dst.size());
166 m_data = m_data.subspan(dst.size());
167 }
168};
169
178protected:
181 unsigned int nReadPos{0};
182
183 int nType;
185
186public:
187 typedef vector_type::allocator_type allocator_type;
188 typedef vector_type::size_type size_type;
189 typedef vector_type::difference_type difference_type;
190 typedef vector_type::reference reference;
191 typedef vector_type::const_reference const_reference;
192 typedef vector_type::value_type value_type;
193 typedef vector_type::iterator iterator;
194 typedef vector_type::const_iterator const_iterator;
195 typedef vector_type::reverse_iterator reverse_iterator;
196
197 explicit CDataStream(int nTypeIn, int nVersionIn)
198 : nType{nTypeIn}, nVersion{nVersionIn} {}
199
200 explicit CDataStream(Span<const uint8_t> sp, int type, int version)
201 : CDataStream{AsBytes(sp), type, version} {}
202 explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn)
203 : vch(sp.data(), sp.data() + sp.size()), nType{nTypeIn},
204 nVersion{nVersionIn} {}
205
206 template <typename... Args>
207 CDataStream(int nTypeIn, int nVersionIn, Args &&...args)
208 : nType{nTypeIn}, nVersion{nVersionIn} {
209 ::SerializeMany(*this, std::forward<Args>(args)...);
210 }
211
212 std::string str() const {
213 return std::string{UCharCast(data()), UCharCast(data() + size())};
214 }
215
216 //
217 // Vector subset
218 //
219 const_iterator begin() const { return vch.begin() + nReadPos; }
220 iterator begin() { return vch.begin() + nReadPos; }
221 const_iterator end() const { return vch.end(); }
222 iterator end() { return vch.end(); }
223 size_type size() const { return vch.size() - nReadPos; }
224 bool empty() const { return vch.size() == nReadPos; }
226 vch.resize(n + nReadPos, c);
227 }
228 void reserve(size_type n) { vch.reserve(n + nReadPos); }
230 return vch[pos + nReadPos];
231 }
232 reference operator[](size_type pos) { return vch[pos + nReadPos]; }
233 void clear() {
234 vch.clear();
235 nReadPos = 0;
236 }
238 return vch.insert(it, x);
239 }
240 void insert(iterator it, size_type n, const value_type x) {
241 vch.insert(it, n, x);
242 }
243 value_type *data() { return vch.data() + nReadPos; }
244 const value_type *data() const { return vch.data() + nReadPos; }
245
246 void insert(iterator it, std::vector<value_type>::const_iterator first,
247 std::vector<value_type>::const_iterator last) {
248 if (last == first) {
249 return;
250 }
251
252 assert(last - first > 0);
253 if (it == vch.begin() + nReadPos &&
254 (unsigned int)(last - first) <= nReadPos) {
255 // special case for inserting at the front when there's room
256 nReadPos -= (last - first);
257 memcpy(&vch[nReadPos], &first[0], last - first);
258 } else {
259 vch.insert(it, first, last);
260 }
261 }
262
263 // This was added to have full compat with the std::vector interface but is
264 // unused (except in a Bitcoin ABC specific test in stream_tests)
265 void insert(iterator it, const value_type *first, const value_type *last) {
266 if (last == first) {
267 return;
268 }
269
270 assert(last - first > 0);
271 if (it == vch.begin() + nReadPos &&
272 (unsigned int)(last - first) <= nReadPos) {
273 // special case for inserting at the front when there's room
274 nReadPos -= (last - first);
275 memcpy(&vch[nReadPos], &first[0], last - first);
276 } else {
277 vch.insert(it, first, last);
278 }
279 }
280
282 if (it == vch.begin() + nReadPos) {
283 // special case for erasing from the front
284 if (++nReadPos >= vch.size()) {
285 // whenever we reach the end, we take the opportunity to clear
286 // the buffer
287 nReadPos = 0;
288 return vch.erase(vch.begin(), vch.end());
289 }
290 return vch.begin() + nReadPos;
291 } else {
292 return vch.erase(it);
293 }
294 }
295
297 if (first == vch.begin() + nReadPos) {
298 // special case for erasing from the front
299 if (last == vch.end()) {
300 nReadPos = 0;
301 return vch.erase(vch.begin(), vch.end());
302 } else {
303 nReadPos = (last - vch.begin());
304 return last;
305 }
306 } else
307 return vch.erase(first, last);
308 }
309
310 inline void Compact() {
311 vch.erase(vch.begin(), vch.begin() + nReadPos);
312 nReadPos = 0;
313 }
314
315 bool Rewind(std::optional<size_type> n = std::nullopt) {
316 // Total rewind if no size is passed
317 if (!n) {
318 nReadPos = 0;
319 return true;
320 }
321 // Rewind by n characters if the buffer hasn't been compacted yet
322 if (*n > nReadPos) {
323 return false;
324 }
325 nReadPos -= *n;
326 return true;
327 }
328
329 //
330 // Stream subset
331 //
332 bool eof() const { return size() == 0; }
333 CDataStream *rdbuf() { return this; }
334 int in_avail() const { return size(); }
335
336 void SetType(int n) { nType = n; }
337 int GetType() const { return nType; }
338 void SetVersion(int n) { nVersion = n; }
339 int GetVersion() const { return nVersion; }
340
342 if (dst.size() == 0) {
343 return;
344 }
345
346 // Read from the beginning of the buffer
347 unsigned int nReadPosNext = nReadPos + dst.size();
348 if (nReadPosNext > vch.size()) {
349 throw std::ios_base::failure("CDataStream::read(): end of data");
350 }
351 memcpy(dst.data(), &vch[nReadPos], dst.size());
352 if (nReadPosNext == vch.size()) {
353 nReadPos = 0;
354 vch.clear();
355 return;
356 }
357 nReadPos = nReadPosNext;
358 }
359
360 void ignore(int nSize) {
361 // Ignore from the beginning of the buffer
362 if (nSize < 0) {
363 throw std::ios_base::failure(
364 "CDataStream::ignore(): nSize negative");
365 }
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");
371 }
372 nReadPos = 0;
373 vch.clear();
374 return;
375 }
376 nReadPos = nReadPosNext;
377 }
378
380 // Write to the end of the buffer
381 vch.insert(vch.end(), src.begin(), src.end());
382 }
383
384 template <typename Stream> void Serialize(Stream &s) const {
385 // Special case: stream << stream concatenates like stream += stream
386 if (!vch.empty()) {
387 s.write(MakeByteSpan(vch));
388 }
389 }
390
391 template <typename T> CDataStream &operator<<(const T &obj) {
392 // Serialize to this stream
393 ::Serialize(*this, obj);
394 return (*this);
395 }
396
397 template <typename T> CDataStream &operator>>(T &&obj) {
398 // Unserialize from this stream
399 ::Unserialize(*this, obj);
400 return (*this);
401 }
402
408 void Xor(const std::vector<uint8_t> &key) {
409 if (key.size() == 0) {
410 return;
411 }
412
413 for (size_type i = 0, j = 0; i != size(); i++) {
414 vch[i] ^= std::byte{key[j++]};
415
416 // This potentially acts on very many bytes of data, so it's
417 // important that we calculate `j`, i.e. the `key` index in this way
418 // instead of doing a %, which would effectively be a division for
419 // each byte Xor'd -- much slower than need be.
420 if (j == key.size()) j = 0;
421 }
422 }
423};
424
425template <typename IStream> class BitStreamReader {
426private:
427 IStream &m_istream;
428
431 uint8_t m_buffer{0};
432
436 int m_offset{8};
437
438public:
439 explicit BitStreamReader(IStream &istream) : m_istream(istream) {}
440
445 uint64_t Read(int nbits) {
446 if (nbits < 0 || nbits > 64) {
447 throw std::out_of_range("nbits must be between 0 and 64");
448 }
449
450 uint64_t data = 0;
451 while (nbits > 0) {
452 if (m_offset == 8) {
454 m_offset = 0;
455 }
456
457 int bits = std::min(8 - m_offset, nbits);
458 data <<= bits;
459 data |= static_cast<uint8_t>(m_buffer << m_offset) >> (8 - bits);
460 m_offset += bits;
461 nbits -= bits;
462 }
463 return data;
464 }
465};
466
467template <typename OStream> class BitStreamWriter {
468private:
469 OStream &m_ostream;
470
473 uint8_t m_buffer{0};
474
478 int m_offset{0};
479
480public:
481 explicit BitStreamWriter(OStream &ostream) : m_ostream(ostream) {}
482
484
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");
492 }
493
494 while (nbits > 0) {
495 int bits = std::min(8 - m_offset, nbits);
496 m_buffer |= (data << (64 - nbits)) >> (64 - 8 + m_offset);
497 m_offset += bits;
498 nbits -= bits;
499
500 if (m_offset == 8) {
501 Flush();
502 }
503 }
504 }
505
510 void Flush() {
511 if (m_offset == 0) {
512 return;
513 }
514
516 m_buffer = 0;
517 m_offset = 0;
518 }
519};
520
528class AutoFile {
529protected:
530 FILE *file;
531
532public:
533 explicit AutoFile(FILE *filenew) : file{filenew} {}
534
536
537 // Disallow copies
538 AutoFile(const AutoFile &) = delete;
539 AutoFile &operator=(const AutoFile &) = delete;
540
541 int fclose() {
542 int retval{0};
543 if (file) {
544 retval = ::fclose(file);
545 file = nullptr;
546 }
547 return retval;
548 }
549
556 FILE *release() {
557 FILE *ret = file;
558 file = nullptr;
559 return ret;
560 }
561
567 FILE *Get() const { return file; }
568
570 bool IsNull() const { return (file == nullptr); }
571
572 //
573 // Stream subset
574 //
576 if (!file) {
577 throw std::ios_base::failure(
578 "AutoFile::read: file handle is nullptr");
579 }
580 if (fread(dst.data(), 1, dst.size(), file) != dst.size()) {
581 throw std::ios_base::failure(feof(file)
582 ? "AutoFile::read: end of file"
583 : "AutoFile::read: fread failed");
584 }
585 }
586
587 void ignore(size_t nSize) {
588 if (!file) {
589 throw std::ios_base::failure(
590 "AutoFile::ignore: file handle is nullptr");
591 }
592 uint8_t data[4096];
593 while (nSize > 0) {
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");
599 }
600 nSize -= nNow;
601 }
602 }
603
605 if (!file) {
606 throw std::ios_base::failure(
607 "AutoFile::write: file handle is nullptr");
608 }
609 if (fwrite(src.data(), 1, src.size(), file) != src.size()) {
610 throw std::ios_base::failure("AutoFile::write: write failed");
611 }
612 }
613
614 template <typename T> AutoFile &operator<<(const T &obj) {
615 if (!file)
616 throw std::ios_base::failure(
617 "AutoFile::operator<<: file handle is nullptr");
618 ::Serialize(*this, obj);
619 return *this;
620 }
621
622 template <typename T> AutoFile &operator>>(T &&obj) {
623 if (!file)
624 throw std::ios_base::failure(
625 "AutoFile::operator>>: file handle is nullptr");
626 ::Unserialize(*this, obj);
627 return *this;
628 }
629};
630
631class CAutoFile : public AutoFile {
632private:
633 const int nType;
634 const int nVersion;
635
636public:
637 CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
638 : AutoFile{filenew}, nType(nTypeIn), nVersion(nVersionIn) {}
639 int GetType() const { return nType; }
640 int GetVersion() const { return nVersion; }
641
642 template <typename T> CAutoFile &operator<<(const T &obj) {
643 // Serialize to this stream
644 if (!file) {
645 throw std::ios_base::failure(
646 "CAutoFile::operator<<: file handle is nullptr");
647 }
648 ::Serialize(*this, obj);
649 return (*this);
650 }
651
652 template <typename T> CAutoFile &operator>>(T &&obj) {
653 // Unserialize from this stream
654 if (!file) {
655 throw std::ios_base::failure(
656 "CAutoFile::operator>>: file handle is nullptr");
657 }
658 ::Unserialize(*this, obj);
659 return (*this);
660 }
661};
662
672private:
673 const int nType;
674 const int nVersion;
675
677 FILE *src;
679 uint64_t nSrcPos;
681 uint64_t nReadPos;
683 uint64_t nReadLimit;
685 uint64_t nRewind;
687 std::vector<std::byte> vchBuf;
688
690 bool Fill() {
691 unsigned int pos = nSrcPos % vchBuf.size();
692 unsigned int readNow = vchBuf.size() - pos;
693 unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind;
694 if (nAvail < readNow) {
695 readNow = nAvail;
696 }
697 if (readNow == 0) {
698 return false;
699 }
700 size_t nBytes = fread((void *)&vchBuf[pos], 1, readNow, src);
701 if (nBytes == 0) {
702 throw std::ios_base::failure(
703 feof(src) ? "CBufferedFile::Fill: end of file"
704 : "CBufferedFile::Fill: fread failed");
705 }
706 nSrcPos += nBytes;
707 return true;
708 }
709
715 std::pair<std::byte *, size_t> AdvanceStream(size_t length) {
717 if (nReadPos + length > nReadLimit) {
718 throw std::ios_base::failure(
719 "Attempt to position past buffer limit");
720 }
721 // If there are no bytes available, read from the file.
722 if (nReadPos == nSrcPos && length > 0) {
723 Fill();
724 }
725
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)};
730 size_t advance{
731 std::min({length, buffer_available, bytes_until_source_pos})};
732 nReadPos += advance;
733 return std::make_pair(&vchBuf[buffer_offset], advance);
734 }
735
736public:
737 CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn,
738 int nTypeIn, int nVersionIn)
739 : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0),
740 nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn),
741 vchBuf(nBufSize, std::byte{0}) {
742 if (nRewindIn >= nBufSize) {
743 throw std::ios_base::failure(
744 "Rewind limit must be less than buffer size");
745 }
746 src = fileIn;
747 }
748
750
751 // Disallow copies
752 CBufferedFile(const CBufferedFile &) = delete;
754
755 int GetVersion() const { return nVersion; }
756 int GetType() const { return nType; }
757
758 void fclose() {
759 if (src) {
760 ::fclose(src);
761 src = nullptr;
762 }
763 }
764
766 bool eof() const { return nReadPos == nSrcPos && feof(src); }
767
770 while (dst.size() > 0) {
771 auto [buffer_pointer, length]{AdvanceStream(dst.size())};
772 memcpy(dst.data(), buffer_pointer, length);
773 dst = dst.subspan(length);
774 }
775 }
776
779 void SkipTo(const uint64_t file_pos) {
780 assert(file_pos >= nReadPos);
781 while (nReadPos < file_pos) {
782 AdvanceStream(file_pos - nReadPos);
783 }
784 }
785
787 uint64_t GetPos() const { return nReadPos; }
788
790 bool SetPos(uint64_t nPos) {
791 size_t bufsize = vchBuf.size();
792 if (nPos + bufsize < nSrcPos) {
793 // rewinding too far, rewind as far as possible
794 nReadPos = nSrcPos - bufsize;
795 return false;
796 }
797 if (nPos > nSrcPos) {
798 // can't go this far forward, go as far as possible
800 return false;
801 }
802 nReadPos = nPos;
803 return true;
804 }
805
808 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
809 if (nPos < nReadPos) {
810 return false;
811 }
812 nReadLimit = nPos;
813 return true;
814 }
815
816 template <typename T> CBufferedFile &operator>>(T &&obj) {
817 // Unserialize from this stream
818 ::Unserialize(*this, obj);
819 return (*this);
820 }
821
823 void FindByte(std::byte byte) {
824 // For best performance, avoid mod operation within the loop.
825 size_t buf_offset{size_t(nReadPos % uint64_t(vchBuf.size()))};
826 while (true) {
827 if (nReadPos == nSrcPos) {
828 // No more bytes available; read from the file into the buffer,
829 // setting nSrcPos to one beyond the end of the new data.
830 // Throws exception if end-of-file reached.
831 Fill();
832 }
833 const size_t len{std::min<size_t>(vchBuf.size() - buf_offset,
834 nSrcPos - nReadPos)};
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))};
838 nReadPos += inc;
839 if (inc < len) {
840 break;
841 }
842 buf_offset += inc;
843 if (buf_offset >= vchBuf.size()) {
844 buf_offset = 0;
845 }
846 }
847 }
848};
849
850#endif // BITCOIN_STREAMS_H
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:528
FILE * file
Definition: streams.h:530
void ignore(size_t nSize)
Definition: streams.h:587
AutoFile & operator=(const AutoFile &)=delete
~AutoFile()
Definition: streams.h:535
void read(Span< std::byte > dst)
Definition: streams.h:575
AutoFile(FILE *filenew)
Definition: streams.h:533
AutoFile & operator<<(const T &obj)
Definition: streams.h:614
AutoFile(const AutoFile &)=delete
FILE * release()
Get wrapped FILE* with transfer of ownership.
Definition: streams.h:556
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:570
AutoFile & operator>>(T &&obj)
Definition: streams.h:622
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:567
void write(Span< const std::byte > src)
Definition: streams.h:604
int fclose()
Definition: streams.h:541
uint8_t m_buffer
Buffered byte read in from the input stream.
Definition: streams.h:431
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
Definition: streams.h:445
BitStreamReader(IStream &istream)
Definition: streams.h:439
IStream & m_istream
Definition: streams.h:427
int m_offset
Number of high order bits in m_buffer already returned by previous Read() calls.
Definition: streams.h:436
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:489
OStream & m_ostream
Definition: streams.h:469
uint8_t m_buffer
Buffered byte waiting to be written to the output stream.
Definition: streams.h:473
BitStreamWriter(OStream &ostream)
Definition: streams.h:481
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:478
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
Definition: streams.h:510
CAutoFile & operator>>(T &&obj)
Definition: streams.h:652
const int nType
Definition: streams.h:633
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
Definition: streams.h:637
int GetType() const
Definition: streams.h:639
const int nVersion
Definition: streams.h:634
CAutoFile & operator<<(const T &obj)
Definition: streams.h:642
int GetVersion() const
Definition: streams.h:640
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
Definition: streams.h:671
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
Prevent reading beyond a certain position.
Definition: streams.h:808
uint64_t nReadLimit
up to which position we're allowed to read
Definition: streams.h:683
int GetVersion() const
Definition: streams.h:755
bool Fill()
read data from the source to fill the buffer
Definition: streams.h:690
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn)
Definition: streams.h:737
uint64_t nRewind
how many bytes we guarantee to rewind
Definition: streams.h:685
void read(Span< std::byte > dst)
read a number of bytes
Definition: streams.h:769
std::vector< std::byte > vchBuf
the buffer
Definition: streams.h:687
uint64_t GetPos() const
return the current reading position
Definition: streams.h:787
CBufferedFile & operator>>(T &&obj)
Definition: streams.h:816
void FindByte(std::byte byte)
search for a given byte in the stream, and remain positioned on it
Definition: streams.h:823
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:715
FILE * src
source file
Definition: streams.h:677
~CBufferedFile()
Definition: streams.h:749
int GetType() const
Definition: streams.h:756
uint64_t nSrcPos
how many bytes have been read from source
Definition: streams.h:679
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Definition: streams.h:779
bool SetPos(uint64_t nPos)
rewind to a given reading position
Definition: streams.h:790
const int nType
Definition: streams.h:673
CBufferedFile & operator=(const CBufferedFile &)=delete
uint64_t nReadPos
how many bytes have been read from this
Definition: streams.h:681
CBufferedFile(const CBufferedFile &)=delete
const int nVersion
Definition: streams.h:674
void fclose()
Definition: streams.h:758
bool eof() const
check whether we're at the end of the source file
Definition: streams.h:766
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:177
CDataStream * rdbuf()
Definition: streams.h:333
int nVersion
Definition: streams.h:184
SerializeData vector_type
Definition: streams.h:179
const_iterator begin() const
Definition: streams.h:219
void SetVersion(int n)
Definition: streams.h:338
vector_type::allocator_type allocator_type
Definition: streams.h:187
void insert(iterator it, std::vector< value_type >::const_iterator first, std::vector< value_type >::const_iterator last)
Definition: streams.h:246
int nType
Definition: streams.h:183
CDataStream & operator<<(const T &obj)
Definition: streams.h:391
vector_type::reference reference
Definition: streams.h:190
int GetType() const
Definition: streams.h:337
CDataStream(int nTypeIn, int nVersionIn)
Definition: streams.h:197
void read(Span< value_type > dst)
Definition: streams.h:341
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
Definition: streams.h:202
iterator begin()
Definition: streams.h:220
int GetVersion() const
Definition: streams.h:339
iterator insert(iterator it, const value_type x)
Definition: streams.h:237
int in_avail() const
Definition: streams.h:334
void reserve(size_type n)
Definition: streams.h:228
vector_type::value_type value_type
Definition: streams.h:192
const value_type * data() const
Definition: streams.h:244
const_iterator end() const
Definition: streams.h:221
iterator end()
Definition: streams.h:222
void write(Span< const value_type > src)
Definition: streams.h:379
void Xor(const std::vector< uint8_t > &key)
XOR the contents of this stream with a certain key.
Definition: streams.h:408
void insert(iterator it, const value_type *first, const value_type *last)
Definition: streams.h:265
iterator erase(iterator first, iterator last)
Definition: streams.h:296
vector_type::size_type size_type
Definition: streams.h:188
const_reference operator[](size_type pos) const
Definition: streams.h:229
void Compact()
Definition: streams.h:310
bool Rewind(std::optional< size_type > n=std::nullopt)
Definition: streams.h:315
reference operator[](size_type pos)
Definition: streams.h:232
void SetType(int n)
Definition: streams.h:336
vector_type::reverse_iterator reverse_iterator
Definition: streams.h:195
void Serialize(Stream &s) const
Definition: streams.h:384
vector_type::difference_type difference_type
Definition: streams.h:189
void ignore(int nSize)
Definition: streams.h:360
CDataStream(int nTypeIn, int nVersionIn, Args &&...args)
Definition: streams.h:207
std::string str() const
Definition: streams.h:212
CDataStream & operator>>(T &&obj)
Definition: streams.h:397
bool empty() const
Definition: streams.h:224
value_type * data()
Definition: streams.h:243
vector_type::const_iterator const_iterator
Definition: streams.h:194
vector_type::iterator iterator
Definition: streams.h:193
void resize(size_type n, value_type c=value_type{})
Definition: streams.h:225
bool eof() const
Definition: streams.h:332
vector_type vch
Definition: streams.h:180
iterator erase(iterator it)
Definition: streams.h:281
vector_type::const_reference const_reference
Definition: streams.h:191
size_type size() const
Definition: streams.h:223
void clear()
Definition: streams.h:233
void insert(iterator it, size_type n, const value_type x)
Definition: streams.h:240
CDataStream(Span< const uint8_t > sp, int type, int version)
Definition: streams.h:200
unsigned int nReadPos
Definition: streams.h:181
Minimal stream for overwriting and/or appending to an existing byte vector.
Definition: streams.h:65
void write(Span< const std::byte > src)
Definition: streams.h:93
const int nVersion
Definition: streams.h:121
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn, Args &&...args)
(other params same as above)
Definition: streams.h:88
std::vector< uint8_t > & vchData
Definition: streams.h:122
const int nType
Definition: streams.h:120
void seek(size_t nSize)
Definition: streams.h:112
int GetType() const
Definition: streams.h:111
size_t nPos
Definition: streams.h:123
CVectorWriter & operator<<(const T &obj)
Definition: streams.h:105
int GetVersion() const
Definition: streams.h:110
CVectorWriter(int nTypeIn, int nVersionIn, std::vector< uint8_t > &vchDataIn, size_t nPosIn)
Definition: streams.h:75
const int nVersion
Definition: streams.h:29
void ignore(size_t size)
Definition: streams.h:53
OverrideStream(Stream *stream_, int nType_, int nVersion_)
Definition: streams.h:32
void read(Span< std::byte > dst)
Definition: streams.h:49
void write(Span< const std::byte > src)
Definition: streams.h:47
OverrideStream< Stream > & operator>>(T &&obj)
Definition: streams.h:41
Stream * stream
Definition: streams.h:26
int GetVersion() const
Definition: streams.h:51
const int nType
Definition: streams.h:28
int GetType() const
Definition: streams.h:52
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:93
constexpr std::size_t size() const noexcept
Definition: span.h:209
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Definition: span.h:218
constexpr C * data() const noexcept
Definition: span.h:198
constexpr C * begin() const noexcept
Definition: span.h:199
constexpr bool empty() const noexcept
Definition: span.h:213
constexpr C * end() const noexcept
Definition: span.h:200
Minimal stream for reading from an existing byte array by Span.
Definition: streams.h:129
bool empty() const
Definition: streams.h:154
const int m_type
Definition: streams.h:131
size_t size() const
Definition: streams.h:153
Span< const uint8_t > m_data
Definition: streams.h:133
SpanReader & operator>>(T &obj)
Definition: streams.h:144
const int m_version
Definition: streams.h:132
int GetType() const
Definition: streams.h:151
void read(Span< std::byte > dst)
Definition: streams.h:156
SpanReader(int type, int version, Span< const uint8_t > data)
Definition: streams.h:141
int GetVersion() const
Definition: streams.h:150
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
void SerializeMany(Stream &s)
Definition: serialize.h:1202
void Unserialize(Stream &, char)=delete
void Serialize(Stream &, char)=delete
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:301
uint8_t * UCharCast(char *c)
Definition: span.h:309
Span< const std::byte > AsBytes(Span< T > s) noexcept
Definition: span.h:294
OverrideStream< S > WithOrVersion(S *s, int nVersionFlag)
Definition: streams.h:56
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