Bitcoin ABC  0.26.3
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(const char *pch, size_t nSize) { stream->write(pch, nSize); }
48 
49  void read(char *pch, size_t nSize) { stream->read(pch, nSize); }
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  }
93  void write(const char *pch, size_t nSize) {
94  assert(nPos <= vchData.size());
95  size_t nOverwrite = std::min(nSize, vchData.size() - nPos);
96  if (nOverwrite) {
97  memcpy(vchData.data() + nPos,
98  reinterpret_cast<const uint8_t *>(pch), nOverwrite);
99  }
100  if (nOverwrite < nSize) {
101  vchData.insert(vchData.end(),
102  reinterpret_cast<const uint8_t *>(pch) + nOverwrite,
103  reinterpret_cast<const uint8_t *>(pch) + nSize);
104  }
105  nPos += nSize;
106  }
107  template <typename T> CVectorWriter &operator<<(const T &obj) {
108  // Serialize to this stream
109  ::Serialize(*this, obj);
110  return (*this);
111  }
112  int GetVersion() const { return nVersion; }
113  int GetType() const { return nType; }
114  void seek(size_t nSize) {
115  nPos += nSize;
116  if (nPos > vchData.size()) {
117  vchData.resize(nPos);
118  }
119  }
120 
121 private:
122  const int nType;
123  const int nVersion;
124  std::vector<uint8_t> &vchData;
125  size_t nPos;
126 };
127 
132 private:
133  const int m_type;
134  const int m_version;
135  const std::vector<uint8_t> &m_data;
136  size_t m_pos = 0;
137 
138 public:
145  VectorReader(int type, int version, const std::vector<uint8_t> &data,
146  size_t pos)
147  : m_type(type), m_version(version), m_data(data), m_pos(pos) {
148  if (m_pos > m_data.size()) {
149  throw std::ios_base::failure(
150  "VectorReader(...): end of data (m_pos > m_data.size())");
151  }
152  }
153 
158  template <typename... Args>
159  VectorReader(int type, int version, const std::vector<uint8_t> &data,
160  size_t pos, Args &&...args)
161  : VectorReader(type, version, data, pos) {
162  ::UnserializeMany(*this, std::forward<Args>(args)...);
163  }
164 
165  template <typename T> VectorReader &operator>>(T &obj) {
166  // Unserialize from this stream
167  ::Unserialize(*this, obj);
168  return (*this);
169  }
170 
171  int GetVersion() const { return m_version; }
172  int GetType() const { return m_type; }
173 
174  size_t size() const { return m_data.size() - m_pos; }
175  bool empty() const { return m_data.size() == m_pos; }
176 
177  void read(char *dst, size_t n) {
178  if (n == 0) {
179  return;
180  }
181 
182  // Read from the beginning of the buffer
183  size_t pos_next = m_pos + n;
184  if (pos_next > m_data.size()) {
185  throw std::ios_base::failure("VectorReader::read(): end of data");
186  }
187  memcpy(dst, m_data.data() + m_pos, n);
188  m_pos = pos_next;
189  }
190 };
191 
199 class CDataStream {
200 protected:
203  unsigned int nReadPos{0};
204 
205  int nType;
206  int nVersion;
207 
208 public:
209  typedef vector_type::allocator_type allocator_type;
210  typedef vector_type::size_type size_type;
211  typedef vector_type::difference_type difference_type;
212  typedef vector_type::reference reference;
213  typedef vector_type::const_reference const_reference;
214  typedef vector_type::value_type value_type;
215  typedef vector_type::iterator iterator;
216  typedef vector_type::const_iterator const_iterator;
217  typedef vector_type::reverse_iterator reverse_iterator;
218 
219  explicit CDataStream(int nTypeIn, int nVersionIn)
220  : nType{nTypeIn}, nVersion{nVersionIn} {}
221 
222  explicit CDataStream(Span<const uint8_t> sp, int nTypeIn, int nVersionIn)
223  : vch(sp.data(), sp.data() + sp.size()), nType{nTypeIn},
224  nVersion{nVersionIn} {}
225 
226  template <typename... Args>
227  CDataStream(int nTypeIn, int nVersionIn, Args &&...args)
228  : nType{nTypeIn}, nVersion{nVersionIn} {
229  ::SerializeMany(*this, std::forward<Args>(args)...);
230  }
231 
233  vch.insert(vch.end(), b.begin(), b.end());
234  return *this;
235  }
236 
237  std::string str() const { return (std::string(begin(), end())); }
238 
239  //
240  // Vector subset
241  //
242  const_iterator begin() const { return vch.begin() + nReadPos; }
243  iterator begin() { return vch.begin() + nReadPos; }
244  const_iterator end() const { return vch.end(); }
245  iterator end() { return vch.end(); }
246  size_type size() const { return vch.size() - nReadPos; }
247  bool empty() const { return vch.size() == nReadPos; }
248  void resize(size_type n, value_type c = 0) { vch.resize(n + nReadPos, c); }
249  void reserve(size_type n) { vch.reserve(n + nReadPos); }
251  return vch[pos + nReadPos];
252  }
253  reference operator[](size_type pos) { return vch[pos + nReadPos]; }
254  void clear() {
255  vch.clear();
256  nReadPos = 0;
257  }
258  iterator insert(iterator it, const uint8_t x) { return vch.insert(it, x); }
259  void insert(iterator it, size_type n, const uint8_t x) {
260  vch.insert(it, n, x);
261  }
262  value_type *data() { return vch.data() + nReadPos; }
263  const value_type *data() const { return vch.data() + nReadPos; }
264 
265  void insert(iterator it, std::vector<uint8_t>::const_iterator first,
266  std::vector<uint8_t>::const_iterator last) {
267  if (last == first) {
268  return;
269  }
270 
271  assert(last - first > 0);
272  if (it == vch.begin() + nReadPos &&
273  (unsigned int)(last - first) <= nReadPos) {
274  // special case for inserting at the front when there's room
275  nReadPos -= (last - first);
276  memcpy(&vch[nReadPos], &first[0], last - first);
277  } else {
278  vch.insert(it, first, last);
279  }
280  }
281 
282  void insert(iterator it, const char *first, const char *last) {
283  if (last == first) {
284  return;
285  }
286 
287  assert(last - first > 0);
288  if (it == vch.begin() + nReadPos &&
289  (unsigned int)(last - first) <= nReadPos) {
290  // special case for inserting at the front when there's room
291  nReadPos -= (last - first);
292  memcpy(&vch[nReadPos], &first[0], last - first);
293  } else {
294  vch.insert(it, first, last);
295  }
296  }
297 
299  if (it == vch.begin() + nReadPos) {
300  // special case for erasing from the front
301  if (++nReadPos >= vch.size()) {
302  // whenever we reach the end, we take the opportunity to clear
303  // the buffer
304  nReadPos = 0;
305  return vch.erase(vch.begin(), vch.end());
306  }
307  return vch.begin() + nReadPos;
308  } else {
309  return vch.erase(it);
310  }
311  }
312 
314  if (first == vch.begin() + nReadPos) {
315  // special case for erasing from the front
316  if (last == vch.end()) {
317  nReadPos = 0;
318  return vch.erase(vch.begin(), vch.end());
319  } else {
320  nReadPos = (last - vch.begin());
321  return last;
322  }
323  } else
324  return vch.erase(first, last);
325  }
326 
327  inline void Compact() {
328  vch.erase(vch.begin(), vch.begin() + nReadPos);
329  nReadPos = 0;
330  }
331 
332  bool Rewind(std::optional<size_type> n = std::nullopt) {
333  // Total rewind if no size is passed
334  if (!n) {
335  nReadPos = 0;
336  return true;
337  }
338  // Rewind by n characters if the buffer hasn't been compacted yet
339  if (*n > nReadPos) {
340  return false;
341  }
342  nReadPos -= *n;
343  return true;
344  }
345 
346  //
347  // Stream subset
348  //
349  bool eof() const { return size() == 0; }
350  CDataStream *rdbuf() { return this; }
351  int in_avail() const { return size(); }
352 
353  void SetType(int n) { nType = n; }
354  int GetType() const { return nType; }
355  void SetVersion(int n) { nVersion = n; }
356  int GetVersion() const { return nVersion; }
357 
358  void read(char *pch, size_t nSize) {
359  if (nSize == 0) {
360  return;
361  }
362 
363  // Read from the beginning of the buffer
364  unsigned int nReadPosNext = nReadPos + nSize;
365  if (nReadPosNext > vch.size()) {
366  throw std::ios_base::failure("CDataStream::read(): end of data");
367  }
368  memcpy(pch, &vch[nReadPos], nSize);
369  if (nReadPosNext == vch.size()) {
370  nReadPos = 0;
371  vch.clear();
372  return;
373  }
374  nReadPos = nReadPosNext;
375  }
376 
377  void ignore(int nSize) {
378  // Ignore from the beginning of the buffer
379  if (nSize < 0) {
380  throw std::ios_base::failure(
381  "CDataStream::ignore(): nSize negative");
382  }
383  unsigned int nReadPosNext = nReadPos + nSize;
384  if (nReadPosNext >= vch.size()) {
385  if (nReadPosNext > vch.size()) {
386  throw std::ios_base::failure(
387  "CDataStream::ignore(): end of data");
388  }
389  nReadPos = 0;
390  vch.clear();
391  return;
392  }
393  nReadPos = nReadPosNext;
394  }
395 
396  void write(const char *pch, size_t nSize) {
397  // Write to the end of the buffer
398  vch.insert(vch.end(), pch, pch + nSize);
399  }
400 
401  template <typename Stream> void Serialize(Stream &s) const {
402  // Special case: stream << stream concatenates like stream += stream
403  if (!vch.empty()) {
404  s.write((char *)vch.data(), vch.size() * sizeof(value_type));
405  }
406  }
407 
408  template <typename T> CDataStream &operator<<(const T &obj) {
409  // Serialize to this stream
410  ::Serialize(*this, obj);
411  return (*this);
412  }
413 
414  template <typename T> CDataStream &operator>>(T &&obj) {
415  // Unserialize from this stream
416  ::Unserialize(*this, obj);
417  return (*this);
418  }
419 
425  void Xor(const std::vector<uint8_t> &key) {
426  if (key.size() == 0) {
427  return;
428  }
429 
430  for (size_type i = 0, j = 0; i != size(); i++) {
431  vch[i] ^= key[j++];
432 
433  // This potentially acts on very many bytes of data, so it's
434  // important that we calculate `j`, i.e. the `key` index in this way
435  // instead of doing a %, which would effectively be a division for
436  // each byte Xor'd -- much slower than need be.
437  if (j == key.size()) j = 0;
438  }
439  }
440 };
441 
442 template <typename IStream> class BitStreamReader {
443 private:
444  IStream &m_istream;
445 
448  uint8_t m_buffer{0};
449 
453  int m_offset{8};
454 
455 public:
456  explicit BitStreamReader(IStream &istream) : m_istream(istream) {}
457 
462  uint64_t Read(int nbits) {
463  if (nbits < 0 || nbits > 64) {
464  throw std::out_of_range("nbits must be between 0 and 64");
465  }
466 
467  uint64_t data = 0;
468  while (nbits > 0) {
469  if (m_offset == 8) {
470  m_istream >> m_buffer;
471  m_offset = 0;
472  }
473 
474  int bits = std::min(8 - m_offset, nbits);
475  data <<= bits;
476  data |= static_cast<uint8_t>(m_buffer << m_offset) >> (8 - bits);
477  m_offset += bits;
478  nbits -= bits;
479  }
480  return data;
481  }
482 };
483 
484 template <typename OStream> class BitStreamWriter {
485 private:
486  OStream &m_ostream;
487 
490  uint8_t m_buffer{0};
491 
495  int m_offset{0};
496 
497 public:
498  explicit BitStreamWriter(OStream &ostream) : m_ostream(ostream) {}
499 
501 
506  void Write(uint64_t data, int nbits) {
507  if (nbits < 0 || nbits > 64) {
508  throw std::out_of_range("nbits must be between 0 and 64");
509  }
510 
511  while (nbits > 0) {
512  int bits = std::min(8 - m_offset, nbits);
513  m_buffer |= (data << (64 - nbits)) >> (64 - 8 + m_offset);
514  m_offset += bits;
515  nbits -= bits;
516 
517  if (m_offset == 8) {
518  Flush();
519  }
520  }
521  }
522 
527  void Flush() {
528  if (m_offset == 0) {
529  return;
530  }
531 
532  m_ostream << m_buffer;
533  m_buffer = 0;
534  m_offset = 0;
535  }
536 };
537 
545 class AutoFile {
546 protected:
547  FILE *file;
548 
549 public:
550  explicit AutoFile(FILE *filenew) : file{filenew} {}
551 
552  ~AutoFile() { fclose(); }
553 
554  // Disallow copies
555  AutoFile(const AutoFile &) = delete;
556  AutoFile &operator=(const AutoFile &) = delete;
557 
558  int fclose() {
559  int retval{0};
560  if (file) {
561  retval = ::fclose(file);
562  file = nullptr;
563  }
564  return retval;
565  }
566 
573  FILE *release() {
574  FILE *ret = file;
575  file = nullptr;
576  return ret;
577  }
578 
584  FILE *Get() const { return file; }
585 
587  bool IsNull() const { return (file == nullptr); }
588 
589  //
590  // Stream subset
591  //
592  void read(char *pch, size_t nSize) {
593  if (!file) {
594  throw std::ios_base::failure(
595  "AutoFile::read: file handle is nullptr");
596  }
597  if (fread(pch, 1, nSize, file) != nSize) {
598  throw std::ios_base::failure(feof(file)
599  ? "AutoFile::read: end of file"
600  : "AutoFile::read: fread failed");
601  }
602  }
603 
604  void ignore(size_t nSize) {
605  if (!file) {
606  throw std::ios_base::failure(
607  "AutoFile::ignore: file handle is nullptr");
608  }
609  uint8_t data[4096];
610  while (nSize > 0) {
611  size_t nNow = std::min<size_t>(nSize, sizeof(data));
612  if (fread(data, 1, nNow, file) != nNow) {
613  throw std::ios_base::failure(
614  feof(file) ? "AutoFile::ignore: end of file"
615  : "AutoFile::read: fread failed");
616  }
617  nSize -= nNow;
618  }
619  }
620 
621  void write(const char *pch, size_t nSize) {
622  if (!file) {
623  throw std::ios_base::failure(
624  "AutoFile::write: file handle is nullptr");
625  }
626  if (fwrite(pch, 1, nSize, file) != nSize) {
627  throw std::ios_base::failure("AutoFile::write: write failed");
628  }
629  }
630 
631  template <typename T> AutoFile &operator<<(const T &obj) {
632  if (!file)
633  throw std::ios_base::failure(
634  "AutoFile::operator<<: file handle is nullptr");
635  ::Serialize(*this, obj);
636  return *this;
637  }
638 
639  template <typename T> AutoFile &operator>>(T &&obj) {
640  if (!file)
641  throw std::ios_base::failure(
642  "AutoFile::operator>>: file handle is nullptr");
643  ::Unserialize(*this, obj);
644  return *this;
645  }
646 };
647 
648 class CAutoFile : public AutoFile {
649 private:
650  const int nType;
651  const int nVersion;
652 
653 public:
654  CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
655  : AutoFile{filenew}, nType(nTypeIn), nVersion(nVersionIn) {}
656  int GetType() const { return nType; }
657  int GetVersion() const { return nVersion; }
658 
659  template <typename T> CAutoFile &operator<<(const T &obj) {
660  // Serialize to this stream
661  if (!file) {
662  throw std::ios_base::failure(
663  "CAutoFile::operator<<: file handle is nullptr");
664  }
665  ::Serialize(*this, obj);
666  return (*this);
667  }
668 
669  template <typename T> CAutoFile &operator>>(T &&obj) {
670  // Unserialize from this stream
671  if (!file) {
672  throw std::ios_base::failure(
673  "CAutoFile::operator>>: file handle is nullptr");
674  }
675  ::Unserialize(*this, obj);
676  return (*this);
677  }
678 };
679 
689 private:
690  const int nType;
691  const int nVersion;
692 
694  FILE *src;
696  uint64_t nSrcPos;
698  uint64_t nReadPos;
700  uint64_t nReadLimit;
702  uint64_t nRewind;
704  std::vector<char> vchBuf;
705 
706 protected:
708  bool Fill() {
709  unsigned int pos = nSrcPos % vchBuf.size();
710  unsigned int readNow = vchBuf.size() - pos;
711  unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind;
712  if (nAvail < readNow) {
713  readNow = nAvail;
714  }
715  if (readNow == 0) {
716  return false;
717  }
718  size_t nBytes = fread((void *)&vchBuf[pos], 1, readNow, src);
719  if (nBytes == 0) {
720  throw std::ios_base::failure(
721  feof(src) ? "CBufferedFile::Fill: end of file"
722  : "CBufferedFile::Fill: fread failed");
723  }
724  nSrcPos += nBytes;
725  return true;
726  }
727 
728 public:
729  CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn,
730  int nTypeIn, int nVersionIn)
731  : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0),
732  nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn),
733  vchBuf(nBufSize, 0) {
734  if (nRewindIn >= nBufSize) {
735  throw std::ios_base::failure(
736  "Rewind limit must be less than buffer size");
737  }
738  src = fileIn;
739  }
740 
742 
743  // Disallow copies
744  CBufferedFile(const CBufferedFile &) = delete;
746 
747  int GetVersion() const { return nVersion; }
748  int GetType() const { return nType; }
749 
750  void fclose() {
751  if (src) {
752  ::fclose(src);
753  src = nullptr;
754  }
755  }
756 
758  bool eof() const { return nReadPos == nSrcPos && feof(src); }
759 
761  void read(char *pch, size_t nSize) {
762  if (nSize + nReadPos > nReadLimit) {
763  throw std::ios_base::failure("Read attempted past buffer limit");
764  }
765  while (nSize > 0) {
766  if (nReadPos == nSrcPos) {
767  Fill();
768  }
769  unsigned int pos = nReadPos % vchBuf.size();
770  size_t nNow = nSize;
771  if (nNow + pos > vchBuf.size()) {
772  nNow = vchBuf.size() - pos;
773  }
774  if (nNow + nReadPos > nSrcPos) {
775  nNow = nSrcPos - nReadPos;
776  }
777  memcpy(pch, &vchBuf[pos], nNow);
778  nReadPos += nNow;
779  pch += nNow;
780  nSize -= nNow;
781  }
782  }
783 
785  uint64_t GetPos() const { return nReadPos; }
786 
788  bool SetPos(uint64_t nPos) {
789  size_t bufsize = vchBuf.size();
790  if (nPos + bufsize < nSrcPos) {
791  // rewinding too far, rewind as far as possible
792  nReadPos = nSrcPos - bufsize;
793  return false;
794  }
795  if (nPos > nSrcPos) {
796  // can't go this far forward, go as far as possible
797  nReadPos = nSrcPos;
798  return false;
799  }
800  nReadPos = nPos;
801  return true;
802  }
803 
806  bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
807  if (nPos < nReadPos) {
808  return false;
809  }
810  nReadLimit = nPos;
811  return true;
812  }
813 
814  template <typename T> CBufferedFile &operator>>(T &&obj) {
815  // Unserialize from this stream
816  ::Unserialize(*this, obj);
817  return (*this);
818  }
819 
821  void FindByte(char ch) {
822  while (true) {
823  if (nReadPos == nSrcPos) {
824  Fill();
825  }
826  if (vchBuf[nReadPos % vchBuf.size()] == ch) {
827  break;
828  }
829  nReadPos++;
830  }
831  }
832 };
833 
834 #endif // BITCOIN_STREAMS_H
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:545
FILE * file
Definition: streams.h:547
FILE * release()
Get wrapped FILE* with transfer of ownership.
Definition: streams.h:573
void ignore(size_t nSize)
Definition: streams.h:604
~AutoFile()
Definition: streams.h:552
AutoFile(FILE *filenew)
Definition: streams.h:550
AutoFile(const AutoFile &)=delete
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:587
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:584
void write(const char *pch, size_t nSize)
Definition: streams.h:621
AutoFile & operator=(const AutoFile &)=delete
AutoFile & operator<<(const T &obj)
Definition: streams.h:631
AutoFile & operator>>(T &&obj)
Definition: streams.h:639
void read(char *pch, size_t nSize)
Definition: streams.h:592
int fclose()
Definition: streams.h:558
uint8_t m_buffer
Buffered byte read in from the input stream.
Definition: streams.h:448
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
Definition: streams.h:462
BitStreamReader(IStream &istream)
Definition: streams.h:456
IStream & m_istream
Definition: streams.h:444
int m_offset
Number of high order bits in m_buffer already returned by previous Read() calls.
Definition: streams.h:453
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:506
OStream & m_ostream
Definition: streams.h:486
uint8_t m_buffer
Buffered byte waiting to be written to the output stream.
Definition: streams.h:490
BitStreamWriter(OStream &ostream)
Definition: streams.h:498
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:495
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
Definition: streams.h:527
const int nType
Definition: streams.h:650
CAutoFile(FILE *filenew, int nTypeIn, int nVersionIn)
Definition: streams.h:654
int GetType() const
Definition: streams.h:656
CAutoFile & operator<<(const T &obj)
Definition: streams.h:659
const int nVersion
Definition: streams.h:651
int GetVersion() const
Definition: streams.h:657
CAutoFile & operator>>(T &&obj)
Definition: streams.h:669
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
Definition: streams.h:688
CBufferedFile & operator>>(T &&obj)
Definition: streams.h:814
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
Prevent reading beyond a certain position.
Definition: streams.h:806
uint64_t nReadLimit
up to which position we're allowed to read
Definition: streams.h:700
void FindByte(char ch)
search for a given byte in the stream, and remain positioned on it
Definition: streams.h:821
int GetVersion() const
Definition: streams.h:747
bool Fill()
read data from the source to fill the buffer
Definition: streams.h:708
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn)
Definition: streams.h:729
uint64_t nRewind
how many bytes we guarantee to rewind
Definition: streams.h:702
uint64_t GetPos() const
return the current reading position
Definition: streams.h:785
std::vector< char > vchBuf
the buffer
Definition: streams.h:704
void read(char *pch, size_t nSize)
read a number of bytes
Definition: streams.h:761
FILE * src
source file
Definition: streams.h:694
~CBufferedFile()
Definition: streams.h:741
int GetType() const
Definition: streams.h:748
uint64_t nSrcPos
how many bytes have been read from source
Definition: streams.h:696
bool SetPos(uint64_t nPos)
rewind to a given reading position
Definition: streams.h:788
const int nType
Definition: streams.h:690
uint64_t nReadPos
how many bytes have been read from this
Definition: streams.h:698
CBufferedFile(const CBufferedFile &)=delete
CBufferedFile & operator=(const CBufferedFile &)=delete
const int nVersion
Definition: streams.h:691
void fclose()
Definition: streams.h:750
bool eof() const
check whether we're at the end of the source file
Definition: streams.h:758
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:199
CDataStream & operator>>(T &&obj)
Definition: streams.h:414
int nVersion
Definition: streams.h:206
SerializeData vector_type
Definition: streams.h:201
value_type * data()
Definition: streams.h:262
const_iterator begin() const
Definition: streams.h:242
void SetVersion(int n)
Definition: streams.h:355
vector_type::allocator_type allocator_type
Definition: streams.h:209
int nType
Definition: streams.h:205
CDataStream(Span< const uint8_t > sp, int nTypeIn, int nVersionIn)
Definition: streams.h:222
iterator insert(iterator it, const uint8_t x)
Definition: streams.h:258
vector_type::reference reference
Definition: streams.h:212
int GetType() const
Definition: streams.h:354
CDataStream(int nTypeIn, int nVersionIn)
Definition: streams.h:219
CDataStream * rdbuf()
Definition: streams.h:350
iterator begin()
Definition: streams.h:243
int GetVersion() const
Definition: streams.h:356
int in_avail() const
Definition: streams.h:351
void reserve(size_type n)
Definition: streams.h:249
vector_type::value_type value_type
Definition: streams.h:214
CDataStream & operator+=(const CDataStream &b)
Definition: streams.h:232
void insert(iterator it, size_type n, const uint8_t x)
Definition: streams.h:259
const_iterator end() const
Definition: streams.h:244
iterator end()
Definition: streams.h:245
void Xor(const std::vector< uint8_t > &key)
XOR the contents of this stream with a certain key.
Definition: streams.h:425
iterator erase(iterator first, iterator last)
Definition: streams.h:313
void read(char *pch, size_t nSize)
Definition: streams.h:358
vector_type::size_type size_type
Definition: streams.h:210
const_reference operator[](size_type pos) const
Definition: streams.h:250
void Compact()
Definition: streams.h:327
bool Rewind(std::optional< size_type > n=std::nullopt)
Definition: streams.h:332
reference operator[](size_type pos)
Definition: streams.h:253
void SetType(int n)
Definition: streams.h:353
vector_type::reverse_iterator reverse_iterator
Definition: streams.h:217
void insert(iterator it, const char *first, const char *last)
Definition: streams.h:282
void Serialize(Stream &s) const
Definition: streams.h:401
vector_type::difference_type difference_type
Definition: streams.h:211
void ignore(int nSize)
Definition: streams.h:377
CDataStream(int nTypeIn, int nVersionIn, Args &&...args)
Definition: streams.h:227
void resize(size_type n, value_type c=0)
Definition: streams.h:248
std::string str() const
Definition: streams.h:237
bool empty() const
Definition: streams.h:247
vector_type::const_iterator const_iterator
Definition: streams.h:216
vector_type::iterator iterator
Definition: streams.h:215
const value_type * data() const
Definition: streams.h:263
bool eof() const
Definition: streams.h:349
vector_type vch
Definition: streams.h:202
iterator erase(iterator it)
Definition: streams.h:298
vector_type::const_reference const_reference
Definition: streams.h:213
size_type size() const
Definition: streams.h:246
void clear()
Definition: streams.h:254
void insert(iterator it, std::vector< uint8_t >::const_iterator first, std::vector< uint8_t >::const_iterator last)
Definition: streams.h:265
void write(const char *pch, size_t nSize)
Definition: streams.h:396
unsigned int nReadPos
Definition: streams.h:203
CDataStream & operator<<(const T &obj)
Definition: streams.h:408
Minimal stream for overwriting and/or appending to an existing byte vector.
Definition: streams.h:65
const int nVersion
Definition: streams.h:123
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:124
CVectorWriter & operator<<(const T &obj)
Definition: streams.h:107
const int nType
Definition: streams.h:122
void seek(size_t nSize)
Definition: streams.h:114
void write(const char *pch, size_t nSize)
Definition: streams.h:93
int GetType() const
Definition: streams.h:113
size_t nPos
Definition: streams.h:125
int GetVersion() const
Definition: streams.h:112
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
Stream * stream
Definition: streams.h:26
void read(char *pch, size_t nSize)
Definition: streams.h:49
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
void write(const char *pch, size_t nSize)
Definition: streams.h:47
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
Minimal stream for reading from an existing vector by reference.
Definition: streams.h:131
int GetType() const
Definition: streams.h:172
VectorReader(int type, int version, const std::vector< uint8_t > &data, size_t pos, Args &&...args)
(other params same as above)
Definition: streams.h:159
size_t m_pos
Definition: streams.h:136
int GetVersion() const
Definition: streams.h:171
const int m_version
Definition: streams.h:134
bool empty() const
Definition: streams.h:175
const std::vector< uint8_t > & m_data
Definition: streams.h:135
const int m_type
Definition: streams.h:133
size_t size() const
Definition: streams.h:174
void read(char *dst, size_t n)
Definition: streams.h:177
VectorReader(int type, int version, const std::vector< uint8_t > &data, size_t pos)
Definition: streams.h:145
VectorReader & operator>>(T &obj)
Definition: streams.h:165
void SerializeMany(Stream &s)
Definition: serialize.h:1203
void Serialize(Stream &s, char a)
Definition: serialize.h:242
void Unserialize(Stream &s, char &a)
Definition: serialize.h:294
void UnserializeMany(Stream &s)
Definition: serialize.h:1211
OverrideStream< S > WithOrVersion(S *s, int nVersionFlag)
Definition: streams.h:56
assert(!tx.IsCoinBase())
std::vector< uint8_t, zero_after_free_allocator< uint8_t > > SerializeData
Byte-vector that clears its contents before deletion.
Definition: zeroafterfree.h:43