Bitcoin ABC  0.29.2
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 
25 template <typename Stream> class OverrideStream {
26  Stream *stream;
27 
28  const int nType;
29  const int nVersion;
30 
31 public:
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 
56 template <typename S> OverrideStream<S> WithOrVersion(S *s, int nVersionFlag) {
57  return OverrideStream<S>(s, s->GetType(), s->GetVersion() | nVersionFlag);
58 }
59 
66 public:
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 
119 private:
120  const int nType;
121  const int nVersion;
122  std::vector<uint8_t> &vchData;
123  size_t nPos;
124 };
125 
129 class SpanReader {
130 private:
131  const int m_type;
132  const int m_version;
134 
135 public:
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 
156  void read(Span<std::byte> dst) {
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 
177 class CDataStream {
178 protected:
181  unsigned int nReadPos{0};
182 
183  int nType;
184  int nVersion;
185 
186 public:
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 
341  void read(Span<value_type> dst) {
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 
425 template <typename IStream> class BitStreamReader {
426 private:
427  IStream &m_istream;
428 
431  uint8_t m_buffer{0};
432 
436  int m_offset{8};
437 
438 public:
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) {
453  m_istream >> m_buffer;
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 
467 template <typename OStream> class BitStreamWriter {
468 private:
469  OStream &m_ostream;
470 
473  uint8_t m_buffer{0};
474 
478  int m_offset{0};
479 
480 public:
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 
515  m_ostream << m_buffer;
516  m_buffer = 0;
517  m_offset = 0;
518  }
519 };
520 
528 class AutoFile {
529 protected:
530  FILE *file;
531 
532 public:
533  explicit AutoFile(FILE *filenew) : file{filenew} {}
534 
535  ~AutoFile() { fclose(); }
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  //
575  void read(Span<std::byte> dst) {
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 
631 class CAutoFile : public AutoFile {
632 private:
633  const int nType;
634  const int nVersion;
635 
636 public:
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 
672 private:
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) {
716  assert(nReadPos <= nSrcPos);
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 
736 public:
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 
769  void read(Span<std::byte> dst) {
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
799  nReadPos = nSrcPos;
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(uint8_t ch) {
824  while (true) {
825  if (nReadPos == nSrcPos) {
826  Fill();
827  }
828  if (vchBuf[nReadPos % vchBuf.size()] == std::byte{ch}) {
829  break;
830  }
831  nReadPos++;
832  }
833  }
834 };
835 
836 #endif // BITCOIN_STREAMS_H
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:528
FILE * file
Definition: streams.h:530
FILE * release()
Get wrapped FILE* with transfer of ownership.
Definition: streams.h:556
void ignore(size_t nSize)
Definition: streams.h:587
~AutoFile()
Definition: streams.h:535
void read(Span< std::byte > dst)
Definition: streams.h:575
AutoFile(FILE *filenew)
Definition: streams.h:533
AutoFile(const AutoFile &)=delete
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:570
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:567
AutoFile & operator=(const AutoFile &)=delete
AutoFile & operator<<(const T &obj)
Definition: streams.h:614
AutoFile & operator>>(T &&obj)
Definition: streams.h:622
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
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
CAutoFile & operator<<(const T &obj)
Definition: streams.h:642
const int nVersion
Definition: streams.h:634
int GetVersion() const
Definition: streams.h:640
CAutoFile & operator>>(T &&obj)
Definition: streams.h:652
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
Definition: streams.h:671
CBufferedFile & operator>>(T &&obj)
Definition: streams.h:816
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
void FindByte(uint8_t ch)
search for a given byte in the stream, and remain positioned on it
Definition: streams.h:823
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
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
uint64_t nReadPos
how many bytes have been read from this
Definition: streams.h:681
CBufferedFile(const CBufferedFile &)=delete
CBufferedFile & operator=(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 & operator>>(T &&obj)
Definition: streams.h:397
int nVersion
Definition: streams.h:184
SerializeData vector_type
Definition: streams.h:179
value_type * data()
Definition: streams.h:243
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
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 * rdbuf()
Definition: streams.h:333
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_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
bool empty() const
Definition: streams.h:224
vector_type::const_iterator const_iterator
Definition: streams.h:194
vector_type::iterator iterator
Definition: streams.h:193
const value_type * data() const
Definition: streams.h:244
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
CDataStream & operator<<(const T &obj)
Definition: streams.h:391
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
CVectorWriter & operator<<(const T &obj)
Definition: streams.h:105
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
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
Stream * stream
Definition: streams.h:26
OverrideStream< Stream > & operator<<(const T &obj)
Definition: streams.h:35
OverrideStream< Stream > & operator>>(T &&obj)
Definition: streams.h:41
int GetVersion() const
Definition: streams.h:51
const int nType
Definition: streams.h:28
int GetType() const
Definition: streams.h:52
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 C * data() const noexcept
Definition: span.h:198
constexpr C * end() const noexcept
Definition: span.h:200
constexpr C * begin() const noexcept
Definition: span.h:199
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Definition: span.h:218
constexpr bool empty() const noexcept
Definition: span.h:213
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
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 & operator>>(T &obj)
Definition: streams.h:144
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:257
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
Span< const std::byte > AsBytes(Span< T > s) noexcept
Definition: span.h:294
uint8_t * UCharCast(char *c)
Definition: span.h:309
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