Bitcoin Core  26.1.0
P2P Digital Currency
streams.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 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 #include <util/overflow.h>
13 
14 #include <algorithm>
15 #include <assert.h>
16 #include <cstddef>
17 #include <cstdio>
18 #include <ios>
19 #include <limits>
20 #include <optional>
21 #include <stdint.h>
22 #include <string.h>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 namespace util {
28 inline void Xor(Span<std::byte> write, Span<const std::byte> key, size_t key_offset = 0)
29 {
30  if (key.size() == 0) {
31  return;
32  }
33  key_offset %= key.size();
34 
35  for (size_t i = 0, j = key_offset; i != write.size(); i++) {
36  write[i] ^= key[j++];
37 
38  // This potentially acts on very many bytes of data, so it's
39  // important that we calculate `j`, i.e. the `key` index in this
40  // way instead of doing a %, which would effectively be a division
41  // for each byte Xor'd -- much slower than need be.
42  if (j == key.size())
43  j = 0;
44  }
45 }
46 } // namespace util
47 
48 template<typename Stream>
50 {
51  Stream* stream;
52 
53  const int nVersion;
54 
55 public:
56  OverrideStream(Stream* stream_, int nVersion_) : stream{stream_}, nVersion{nVersion_} {}
57 
58  template<typename T>
60  {
61  ::Serialize(*this, obj);
62  return (*this);
63  }
64 
65  template<typename T>
67  {
68  ::Unserialize(*this, obj);
69  return (*this);
70  }
71 
73  {
74  stream->write(src);
75  }
76 
78  {
79  stream->read(dst);
80  }
81 
82  int GetVersion() const { return nVersion; }
83  size_t size() const { return stream->size(); }
84  void ignore(size_t size) { return stream->ignore(size); }
85 };
86 
87 /* Minimal stream for overwriting and/or appending to an existing byte vector
88  *
89  * The referenced vector will grow as necessary
90  */
92 {
93  public:
94 
95 /*
96  * @param[in] nVersionIn Serialization Version (including any flags)
97  * @param[in] vchDataIn Referenced byte vector to overwrite/append
98  * @param[in] nPosIn Starting position. Vector index where writes should start. The vector will initially
99  * grow as necessary to max(nPosIn, vec.size()). So to append, use vec.size().
100 */
101  CVectorWriter(int nVersionIn, std::vector<unsigned char>& vchDataIn, size_t nPosIn) : nVersion{nVersionIn}, vchData{vchDataIn}, nPos{nPosIn}
102  {
103  if(nPos > vchData.size())
104  vchData.resize(nPos);
105  }
106 /*
107  * (other params same as above)
108  * @param[in] args A list of items to serialize starting at nPosIn.
109 */
110  template <typename... Args>
111  CVectorWriter(int nVersionIn, std::vector<unsigned char>& vchDataIn, size_t nPosIn, Args&&... args) : CVectorWriter{nVersionIn, vchDataIn, nPosIn}
112  {
113  ::SerializeMany(*this, std::forward<Args>(args)...);
114  }
116  {
117  assert(nPos <= vchData.size());
118  size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
119  if (nOverwrite) {
120  memcpy(vchData.data() + nPos, src.data(), nOverwrite);
121  }
122  if (nOverwrite < src.size()) {
123  vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.end()));
124  }
125  nPos += src.size();
126  }
127  template<typename T>
129  {
130  ::Serialize(*this, obj);
131  return (*this);
132  }
133  int GetVersion() const
134  {
135  return nVersion;
136  }
137 
138 private:
139  const int nVersion;
140  std::vector<unsigned char>& vchData;
141  size_t nPos;
142 };
143 
147 {
148 private:
149  const int m_version;
151 
152 public:
158  : m_version{version}, m_data{data} {}
159 
160  template<typename T>
162  {
163  ::Unserialize(*this, obj);
164  return (*this);
165  }
166 
167  int GetVersion() const { return m_version; }
168 
169  size_t size() const { return m_data.size(); }
170  bool empty() const { return m_data.empty(); }
171 
173  {
174  if (dst.size() == 0) {
175  return;
176  }
177 
178  // Read from the beginning of the buffer
179  if (dst.size() > m_data.size()) {
180  throw std::ios_base::failure("SpanReader::read(): end of data");
181  }
182  memcpy(dst.data(), m_data.data(), dst.size());
183  m_data = m_data.subspan(dst.size());
184  }
185 };
186 
193 {
194 protected:
197  vector_type::size_type m_read_pos{0};
198 
199 public:
200  typedef vector_type::allocator_type allocator_type;
201  typedef vector_type::size_type size_type;
202  typedef vector_type::difference_type difference_type;
203  typedef vector_type::reference reference;
204  typedef vector_type::const_reference const_reference;
205  typedef vector_type::value_type value_type;
206  typedef vector_type::iterator iterator;
207  typedef vector_type::const_iterator const_iterator;
208  typedef vector_type::reverse_iterator reverse_iterator;
209 
210  explicit DataStream() {}
212  explicit DataStream(Span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {}
213 
214  std::string str() const
215  {
216  return std::string{UCharCast(data()), UCharCast(data() + size())};
217  }
218 
219 
220  //
221  // Vector subset
222  //
223  const_iterator begin() const { return vch.begin() + m_read_pos; }
224  iterator begin() { return vch.begin() + m_read_pos; }
225  const_iterator end() const { return vch.end(); }
226  iterator end() { return vch.end(); }
227  size_type size() const { return vch.size() - m_read_pos; }
228  bool empty() const { return vch.size() == m_read_pos; }
229  void resize(size_type n, value_type c = value_type{}) { vch.resize(n + m_read_pos, c); }
230  void reserve(size_type n) { vch.reserve(n + m_read_pos); }
231  const_reference operator[](size_type pos) const { return vch[pos + m_read_pos]; }
232  reference operator[](size_type pos) { return vch[pos + m_read_pos]; }
233  void clear() { vch.clear(); m_read_pos = 0; }
234  value_type* data() { return vch.data() + m_read_pos; }
235  const value_type* data() const { return vch.data() + m_read_pos; }
236 
237  inline void Compact()
238  {
239  vch.erase(vch.begin(), vch.begin() + m_read_pos);
240  m_read_pos = 0;
241  }
242 
243  bool Rewind(std::optional<size_type> n = std::nullopt)
244  {
245  // Total rewind if no size is passed
246  if (!n) {
247  m_read_pos = 0;
248  return true;
249  }
250  // Rewind by n characters if the buffer hasn't been compacted yet
251  if (*n > m_read_pos)
252  return false;
253  m_read_pos -= *n;
254  return true;
255  }
256 
257 
258  //
259  // Stream subset
260  //
261  bool eof() const { return size() == 0; }
262  int in_avail() const { return size(); }
263 
265  {
266  if (dst.size() == 0) return;
267 
268  // Read from the beginning of the buffer
269  auto next_read_pos{CheckedAdd(m_read_pos, dst.size())};
270  if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
271  throw std::ios_base::failure("DataStream::read(): end of data");
272  }
273  memcpy(dst.data(), &vch[m_read_pos], dst.size());
274  if (next_read_pos.value() == vch.size()) {
275  m_read_pos = 0;
276  vch.clear();
277  return;
278  }
279  m_read_pos = next_read_pos.value();
280  }
281 
282  void ignore(size_t num_ignore)
283  {
284  // Ignore from the beginning of the buffer
285  auto next_read_pos{CheckedAdd(m_read_pos, num_ignore)};
286  if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
287  throw std::ios_base::failure("DataStream::ignore(): end of data");
288  }
289  if (next_read_pos.value() == vch.size()) {
290  m_read_pos = 0;
291  vch.clear();
292  return;
293  }
294  m_read_pos = next_read_pos.value();
295  }
296 
298  {
299  // Write to the end of the buffer
300  vch.insert(vch.end(), src.begin(), src.end());
301  }
302 
303  template<typename T>
304  DataStream& operator<<(const T& obj)
305  {
306  ::Serialize(*this, obj);
307  return (*this);
308  }
309 
310  template<typename T>
312  {
313  ::Unserialize(*this, obj);
314  return (*this);
315  }
316 
322  void Xor(const std::vector<unsigned char>& key)
323  {
325  }
326 };
327 
328 class CDataStream : public DataStream
329 {
330 private:
331  int nType;
332  int nVersion;
333 
334 public:
335  explicit CDataStream(int nTypeIn, int nVersionIn)
336  : nType{nTypeIn},
337  nVersion{nVersionIn} {}
338 
339  explicit CDataStream(Span<const uint8_t> sp, int type, int version) : CDataStream{AsBytes(sp), type, version} {}
340  explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn)
341  : DataStream{sp},
342  nType{nTypeIn},
343  nVersion{nVersionIn} {}
344 
345  int GetType() const { return nType; }
346  void SetVersion(int n) { nVersion = n; }
347  int GetVersion() const { return nVersion; }
348 
349  template <typename T>
350  CDataStream& operator<<(const T& obj)
351  {
352  ::Serialize(*this, obj);
353  return *this;
354  }
355 
356  template <typename T>
358  {
359  ::Unserialize(*this, obj);
360  return *this;
361  }
362 };
363 
364 template <typename IStream>
366 {
367 private:
368  IStream& m_istream;
369 
372  uint8_t m_buffer{0};
373 
377  int m_offset{8};
378 
379 public:
380  explicit BitStreamReader(IStream& istream) : m_istream(istream) {}
381 
385  uint64_t Read(int nbits) {
386  if (nbits < 0 || nbits > 64) {
387  throw std::out_of_range("nbits must be between 0 and 64");
388  }
389 
390  uint64_t data = 0;
391  while (nbits > 0) {
392  if (m_offset == 8) {
393  m_istream >> m_buffer;
394  m_offset = 0;
395  }
396 
397  int bits = std::min(8 - m_offset, nbits);
398  data <<= bits;
399  data |= static_cast<uint8_t>(m_buffer << m_offset) >> (8 - bits);
400  m_offset += bits;
401  nbits -= bits;
402  }
403  return data;
404  }
405 };
406 
407 template <typename OStream>
409 {
410 private:
411  OStream& m_ostream;
412 
415  uint8_t m_buffer{0};
416 
420  int m_offset{0};
421 
422 public:
423  explicit BitStreamWriter(OStream& ostream) : m_ostream(ostream) {}
424 
426  {
427  Flush();
428  }
429 
433  void Write(uint64_t data, int nbits) {
434  if (nbits < 0 || nbits > 64) {
435  throw std::out_of_range("nbits must be between 0 and 64");
436  }
437 
438  while (nbits > 0) {
439  int bits = std::min(8 - m_offset, nbits);
440  m_buffer |= (data << (64 - nbits)) >> (64 - 8 + m_offset);
441  m_offset += bits;
442  nbits -= bits;
443 
444  if (m_offset == 8) {
445  Flush();
446  }
447  }
448  }
449 
453  void Flush() {
454  if (m_offset == 0) {
455  return;
456  }
457 
458  m_ostream << m_buffer;
459  m_buffer = 0;
460  m_offset = 0;
461  }
462 };
463 
470 class AutoFile
471 {
472 protected:
473  std::FILE* m_file;
474  const std::vector<std::byte> m_xor;
475 
476 public:
477  explicit AutoFile(std::FILE* file, std::vector<std::byte> data_xor={}) : m_file{file}, m_xor{std::move(data_xor)} {}
478 
479  ~AutoFile() { fclose(); }
480 
481  // Disallow copies
482  AutoFile(const AutoFile&) = delete;
483  AutoFile& operator=(const AutoFile&) = delete;
484 
485  bool feof() const { return std::feof(m_file); }
486 
487  int fclose()
488  {
489  if (auto rel{release()}) return std::fclose(rel);
490  return 0;
491  }
492 
497  std::FILE* release()
498  {
499  std::FILE* ret{m_file};
500  m_file = nullptr;
501  return ret;
502  }
503 
508  std::FILE* Get() const { return m_file; }
509 
512  bool IsNull() const { return m_file == nullptr; }
513 
515  std::size_t detail_fread(Span<std::byte> dst);
516 
517  //
518  // Stream subset
519  //
520  void read(Span<std::byte> dst);
521  void ignore(size_t nSize);
522  void write(Span<const std::byte> src);
523 
524  template <typename T>
525  AutoFile& operator<<(const T& obj)
526  {
527  ::Serialize(*this, obj);
528  return *this;
529  }
530 
531  template <typename T>
533  {
534  ::Unserialize(*this, obj);
535  return *this;
536  }
537 };
538 
539 class CAutoFile : public AutoFile
540 {
541 private:
542  const int nVersion;
543 
544 public:
545  explicit CAutoFile(std::FILE* file, int version, std::vector<std::byte> data_xor = {}) : AutoFile{file, std::move(data_xor)}, nVersion{version} {}
546  int GetVersion() const { return nVersion; }
547 
548  template<typename T>
549  CAutoFile& operator<<(const T& obj)
550  {
551  ::Serialize(*this, obj);
552  return (*this);
553  }
554 
555  template<typename T>
557  {
558  ::Unserialize(*this, obj);
559  return (*this);
560  }
561 };
562 
570 {
571 private:
573  uint64_t nSrcPos{0};
574  uint64_t m_read_pos{0};
575  uint64_t nReadLimit;
576  uint64_t nRewind;
577  std::vector<std::byte> vchBuf;
578 
580  bool Fill() {
581  unsigned int pos = nSrcPos % vchBuf.size();
582  unsigned int readNow = vchBuf.size() - pos;
583  unsigned int nAvail = vchBuf.size() - (nSrcPos - m_read_pos) - nRewind;
584  if (nAvail < readNow)
585  readNow = nAvail;
586  if (readNow == 0)
587  return false;
588  size_t nBytes{m_src.detail_fread(Span{vchBuf}.subspan(pos, readNow))};
589  if (nBytes == 0) {
590  throw std::ios_base::failure{m_src.feof() ? "BufferedFile::Fill: end of file" : "BufferedFile::Fill: fread failed"};
591  }
592  nSrcPos += nBytes;
593  return true;
594  }
595 
601  std::pair<std::byte*, size_t> AdvanceStream(size_t length)
602  {
604  if (m_read_pos + length > nReadLimit) {
605  throw std::ios_base::failure("Attempt to position past buffer limit");
606  }
607  // If there are no bytes available, read from the file.
608  if (m_read_pos == nSrcPos && length > 0) Fill();
609 
610  size_t buffer_offset{static_cast<size_t>(m_read_pos % vchBuf.size())};
611  size_t buffer_available{static_cast<size_t>(vchBuf.size() - buffer_offset)};
612  size_t bytes_until_source_pos{static_cast<size_t>(nSrcPos - m_read_pos)};
613  size_t advance{std::min({length, buffer_available, bytes_until_source_pos})};
614  m_read_pos += advance;
615  return std::make_pair(&vchBuf[buffer_offset], advance);
616  }
617 
618 public:
619  BufferedFile(CAutoFile& file, uint64_t nBufSize, uint64_t nRewindIn)
620  : m_src{file}, nReadLimit{std::numeric_limits<uint64_t>::max()}, nRewind{nRewindIn}, vchBuf(nBufSize, std::byte{0})
621  {
622  if (nRewindIn >= nBufSize)
623  throw std::ios_base::failure("Rewind limit must be less than buffer size");
624  }
625 
626  int GetVersion() const { return m_src.GetVersion(); }
627 
629  bool eof() const {
630  return m_read_pos == nSrcPos && m_src.feof();
631  }
632 
635  {
636  while (dst.size() > 0) {
637  auto [buffer_pointer, length]{AdvanceStream(dst.size())};
638  memcpy(dst.data(), buffer_pointer, length);
639  dst = dst.subspan(length);
640  }
641  }
642 
645  void SkipTo(const uint64_t file_pos)
646  {
647  assert(file_pos >= m_read_pos);
648  while (m_read_pos < file_pos) AdvanceStream(file_pos - m_read_pos);
649  }
650 
652  uint64_t GetPos() const {
653  return m_read_pos;
654  }
655 
657  bool SetPos(uint64_t nPos) {
658  size_t bufsize = vchBuf.size();
659  if (nPos + bufsize < nSrcPos) {
660  // rewinding too far, rewind as far as possible
661  m_read_pos = nSrcPos - bufsize;
662  return false;
663  }
664  if (nPos > nSrcPos) {
665  // can't go this far forward, go as far as possible
667  return false;
668  }
669  m_read_pos = nPos;
670  return true;
671  }
672 
675  bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
676  if (nPos < m_read_pos)
677  return false;
678  nReadLimit = nPos;
679  return true;
680  }
681 
682  template<typename T>
684  ::Unserialize(*this, obj);
685  return (*this);
686  }
687 
689  void FindByte(std::byte byte)
690  {
691  // For best performance, avoid mod operation within the loop.
692  size_t buf_offset{size_t(m_read_pos % uint64_t(vchBuf.size()))};
693  while (true) {
694  if (m_read_pos == nSrcPos) {
695  // No more bytes available; read from the file into the buffer,
696  // setting nSrcPos to one beyond the end of the new data.
697  // Throws exception if end-of-file reached.
698  Fill();
699  }
700  const size_t len{std::min<size_t>(vchBuf.size() - buf_offset, nSrcPos - m_read_pos)};
701  const auto it_start{vchBuf.begin() + buf_offset};
702  const auto it_find{std::find(it_start, it_start + len, byte)};
703  const size_t inc{size_t(std::distance(it_start, it_find))};
704  m_read_pos += inc;
705  if (inc < len) break;
706  buf_offset += inc;
707  if (buf_offset >= vchBuf.size()) buf_offset = 0;
708  }
709  }
710 };
711 
712 #endif // BITCOIN_STREAMS_H
CVectorWriter & operator<<(const T &obj)
Definition: streams.h:128
bool eof() const
Definition: streams.h:261
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Definition: span.h:194
Span< const unsigned char > m_data
Definition: streams.h:150
int GetVersion() const
Definition: streams.h:167
int ret
void ignore(size_t size)
Definition: streams.h:84
std::vector< std::byte > vchBuf
the buffer
Definition: streams.h:577
uint64_t GetPos() const
return the current reading position
Definition: streams.h:652
void reserve(size_type n)
Definition: streams.h:230
vector_type::const_reference const_reference
Definition: streams.h:204
vector_type::iterator iterator
Definition: streams.h:206
SpanReader(int version, Span< const unsigned char > data)
Definition: streams.h:157
void read(Span< std::byte > dst)
Definition: streams.h:77
std::vector< unsigned char > & vchData
Definition: streams.h:140
assert(!tx.IsCoinBase())
void Compact()
Definition: streams.h:237
int GetVersion() const
Definition: streams.h:347
constexpr C * end() const noexcept
Definition: span.h:175
size_t nPos
Definition: streams.h:141
int GetType() const
Definition: streams.h:345
const int nVersion
Definition: streams.h:542
void Unserialize(Stream &, char)=delete
AutoFile & operator>>(T &&obj)
Definition: streams.h:532
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:264
int in_avail() const
Definition: streams.h:262
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Definition: streams.h:645
constexpr std::size_t size() const noexcept
Definition: span.h:186
~AutoFile()
Definition: streams.h:479
size_t size() const
Definition: streams.h:169
CVectorWriter(int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn)
Definition: streams.h:101
vector_type::difference_type difference_type
Definition: streams.h:202
uint64_t nRewind
how many bytes we guarantee to rewind
Definition: streams.h:576
std::FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:508
OverrideStream< Stream > & operator<<(const T &obj)
Definition: streams.h:59
Wrapper around a CAutoFile& that implements a ring buffer to deserialize from.
Definition: streams.h:569
void ignore(size_t num_ignore)
Definition: streams.h:282
void write(Span< const value_type > src)
Definition: streams.h:297
bool feof() const
Definition: streams.h:485
iterator end()
Definition: streams.h:226
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:433
int GetVersion() const
Definition: streams.h:82
vector_type::value_type value_type
Definition: streams.h:205
int GetVersion() const
Definition: streams.h:546
std::FILE * release()
Get wrapped FILE* with transfer of ownership.
Definition: streams.h:497
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:470
bool empty() const
Definition: streams.h:228
CDataStream(int nTypeIn, int nVersionIn)
Definition: streams.h:335
value_type * data()
Definition: streams.h:234
bool empty() const
Definition: streams.h:170
uint8_t m_buffer
Buffered byte read in from the input stream.
Definition: streams.h:372
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
prevent reading beyond a certain position no argument removes the limit
Definition: streams.h:675
Minimal stream for reading from an existing byte array by Span.
Definition: streams.h:146
std::optional< T > CheckedAdd(const T i, const T j) noexcept
Definition: overflow.h:24
DataStream(Span< const uint8_t > sp)
Definition: streams.h:211
vector_type::size_type m_read_pos
Definition: streams.h:197
CAutoFile & operator>>(T &&obj)
Definition: streams.h:556
vector_type::size_type size_type
Definition: streams.h:201
void Xor(Span< std::byte > write, Span< const std::byte > key, size_t key_offset=0)
Definition: streams.h:28
BitStreamReader(IStream &istream)
Definition: streams.h:380
vector_type::reverse_iterator reverse_iterator
Definition: streams.h:208
const_iterator end() const
Definition: streams.h:225
bool Rewind(std::optional< size_type > n=std::nullopt)
Definition: streams.h:243
std::FILE * m_file
Definition: streams.h:473
DataStream(Span< const value_type > sp)
Definition: streams.h:212
ArgsManager & args
Definition: bitcoind.cpp:269
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:192
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.
Definition: zeroafterfree.h:49
CAutoFile & m_src
Definition: streams.h:572
DataStream & operator<<(const T &obj)
Definition: streams.h:304
AutoFile & operator<<(const T &obj)
Definition: streams.h:525
void write(Span< const std::byte > src)
Definition: streams.h:115
BufferedFile & operator>>(T &&obj)
Definition: streams.h:683
CDataStream & operator>>(T &&obj)
Definition: streams.h:357
vector_type::allocator_type allocator_type
Definition: streams.h:200
vector_type::const_iterator const_iterator
Definition: streams.h:207
uint64_t nSrcPos
how many bytes have been read from source
Definition: streams.h:573
void Serialize(Stream &, char)=delete
IStream & m_istream
Definition: streams.h:368
bool Fill()
read data from the source to fill the buffer
Definition: streams.h:580
AutoFile & operator=(const AutoFile &)=delete
OverrideStream(Stream *stream_, int nVersion_)
Definition: streams.h:56
std::pair< std::byte *, size_t > AdvanceStream(size_t length)
Advance the stream&#39;s read pointer (m_read_pos) by up to &#39;length&#39; bytes, filling the buffer from the f...
Definition: streams.h:601
size_t size() const
Definition: streams.h:83
int GetVersion() const
Definition: streams.h:133
void read(Span< std::byte > dst)
Definition: streams.cpp:24
SerializeData vector_type
Definition: streams.h:195
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
Definition: streams.h:385
const_reference operator[](size_type pos) const
Definition: streams.h:231
DataStream & operator>>(T &&obj)
Definition: streams.h:311
const std::vector< std::byte > m_xor
Definition: streams.h:474
void Flush()
Flush any unwritten bits to the output stream, padding with 0&#39;s to the next byte boundary.
Definition: streams.h:453
void FindByte(std::byte byte)
search for a given byte in the stream, and remain positioned on it
Definition: streams.h:689
const_iterator begin() const
Definition: streams.h:223
void write(Span< const std::byte > src)
Definition: streams.h:72
size_type size() const
Definition: streams.h:227
constexpr C * begin() const noexcept
Definition: span.h:174
std::string str() const
Definition: streams.h:214
uint8_t m_buffer
Buffered byte waiting to be written to the output stream.
Definition: streams.h:415
void resize(size_type n, value_type c=value_type{})
Definition: streams.h:229
const int nVersion
Definition: streams.h:139
void clear()
Definition: streams.h:233
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:420
const int nVersion
Definition: streams.h:53
bool SetPos(uint64_t nPos)
rewind to a given reading position
Definition: streams.h:657
CDataStream & operator<<(const T &obj)
Definition: streams.h:350
const value_type * data() const
Definition: streams.h:235
constexpr C * data() const noexcept
Definition: span.h:173
AutoFile(std::FILE *file, std::vector< std::byte > data_xor={})
Definition: streams.h:477
int m_offset
Number of high order bits in m_buffer already returned by previous Read() calls.
Definition: streams.h:377
DataStream()
Definition: streams.h:210
reference operator[](size_type pos)
Definition: streams.h:232
void Xor(const std::vector< unsigned char > &key)
XOR the contents of this stream with a certain key.
Definition: streams.h:322
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:259
int nVersion
Definition: streams.h:332
uint64_t nReadLimit
up to which position we&#39;re allowed to read
Definition: streams.h:575
int fclose()
Definition: streams.h:487
constexpr bool empty() const noexcept
Definition: span.h:188
Span< const std::byte > AsBytes(Span< T > s) noexcept
Definition: span.h:248
bool eof() const
check whether we&#39;re at the end of the source file
Definition: streams.h:629
CDataStream(Span< const uint8_t > sp, int type, int version)
Definition: streams.h:339
unsigned char * UCharCast(char *c)
Definition: span.h:270
const int m_version
Definition: streams.h:149
void SerializeMany(Stream &s, const Args &... args)
Support for (un)serializing many things at once.
Definition: serialize.h:1015
A Span is an object that can refer to a contiguous sequence of objects.
Definition: solver.h:20
int GetVersion() const
Definition: streams.h:626
OStream & m_ostream
Definition: streams.h:411
vector_type vch
Definition: streams.h:196
void read(Span< std::byte > dst)
read a number of bytes
Definition: streams.h:634
iterator begin()
Definition: streams.h:224
vector_type::reference reference
Definition: streams.h:203
std::size_t detail_fread(Span< std::byte > dst)
Implementation detail, only used internally.
Definition: streams.cpp:10
void read(Span< std::byte > dst)
Definition: streams.h:172
void SetVersion(int n)
Definition: streams.h:346
void read(Span< value_type > dst)
Definition: streams.h:264
BufferedFile(CAutoFile &file, uint64_t nBufSize, uint64_t nRewindIn)
Definition: streams.h:619
OverrideStream< Stream > & operator>>(T &&obj)
Definition: streams.h:66
CVectorWriter(int nVersionIn, std::vector< unsigned char > &vchDataIn, size_t nPosIn, Args &&... args)
Definition: streams.h:111
int nType
Definition: streams.h:331
Stream * stream
Definition: streams.h:51
CAutoFile & operator<<(const T &obj)
Definition: streams.h:549
SpanReader & operator>>(T &&obj)
Definition: streams.h:161
CDataStream(Span< const value_type > sp, int nTypeIn, int nVersionIn)
Definition: streams.h:340
CAutoFile(std::FILE *file, int version, std::vector< std::byte > data_xor={})
Definition: streams.h:545
void write(Span< const std::byte > src)
Definition: streams.cpp:44
void ignore(size_t nSize)
Definition: streams.cpp:31
BitStreamWriter(OStream &ostream)
Definition: streams.h:423
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:512
uint64_t m_read_pos
how many bytes have been read from this
Definition: streams.h:574