Bitcoin Core 29.99.0
P2P Digital Currency
streams.h
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-present 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 <logging.h>
10#include <serialize.h>
11#include <span.h>
13#include <util/check.h>
14#include <util/obfuscation.h>
15#include <util/overflow.h>
16#include <util/syserror.h>
17
18#include <algorithm>
19#include <cassert>
20#include <cstddef>
21#include <cstdint>
22#include <cstdio>
23#include <cstring>
24#include <ios>
25#include <limits>
26#include <optional>
27#include <string>
28#include <vector>
29
30/* Minimal stream for overwriting and/or appending to an existing byte vector
31 *
32 * The referenced vector will grow as necessary
33 */
35{
36public:
37/*
38 * @param[in] vchDataIn Referenced byte vector to overwrite/append
39 * @param[in] nPosIn Starting position. Vector index where writes should start. The vector will initially
40 * grow as necessary to max(nPosIn, vec.size()). So to append, use vec.size().
41*/
42 VectorWriter(std::vector<unsigned char>& vchDataIn, size_t nPosIn) : vchData{vchDataIn}, nPos{nPosIn}
43 {
44 if(nPos > vchData.size())
45 vchData.resize(nPos);
46 }
47/*
48 * (other params same as above)
49 * @param[in] args A list of items to serialize starting at nPosIn.
50*/
51 template <typename... Args>
52 VectorWriter(std::vector<unsigned char>& vchDataIn, size_t nPosIn, Args&&... args) : VectorWriter{vchDataIn, nPosIn}
53 {
54 ::SerializeMany(*this, std::forward<Args>(args)...);
55 }
56 void write(std::span<const std::byte> src)
57 {
58 assert(nPos <= vchData.size());
59 size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
60 if (nOverwrite) {
61 memcpy(vchData.data() + nPos, src.data(), nOverwrite);
62 }
63 if (nOverwrite < src.size()) {
64 vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.data() + src.size()));
65 }
66 nPos += src.size();
67 }
68 template <typename T>
70 {
71 ::Serialize(*this, obj);
72 return (*this);
73 }
74
75private:
76 std::vector<unsigned char>& vchData;
77 size_t nPos;
78};
79
83{
84private:
85 std::span<const std::byte> m_data;
86
87public:
91 explicit SpanReader(std::span<const unsigned char> data) : m_data{std::as_bytes(data)} {}
92 explicit SpanReader(std::span<const std::byte> data) : m_data{data} {}
93
94 template<typename T>
96 {
97 ::Unserialize(*this, obj);
98 return (*this);
99 }
100
101 size_t size() const { return m_data.size(); }
102 bool empty() const { return m_data.empty(); }
103
104 void read(std::span<std::byte> dst)
105 {
106 if (dst.size() == 0) {
107 return;
108 }
109
110 // Read from the beginning of the buffer
111 if (dst.size() > m_data.size()) {
112 throw std::ios_base::failure("SpanReader::read(): end of data");
113 }
114 memcpy(dst.data(), m_data.data(), dst.size());
115 m_data = m_data.subspan(dst.size());
116 }
117
118 void ignore(size_t n)
119 {
120 m_data = m_data.subspan(n);
121 }
122};
123
130{
131protected:
134 vector_type::size_type m_read_pos{0};
135
136public:
137 typedef vector_type::allocator_type allocator_type;
138 typedef vector_type::size_type size_type;
139 typedef vector_type::difference_type difference_type;
140 typedef vector_type::reference reference;
141 typedef vector_type::const_reference const_reference;
142 typedef vector_type::value_type value_type;
143 typedef vector_type::iterator iterator;
144 typedef vector_type::const_iterator const_iterator;
145 typedef vector_type::reverse_iterator reverse_iterator;
146
147 explicit DataStream() = default;
148 explicit DataStream(std::span<const uint8_t> sp) : DataStream{std::as_bytes(sp)} {}
149 explicit DataStream(std::span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {}
150
151 std::string str() const
152 {
153 return std::string{UCharCast(data()), UCharCast(data() + size())};
154 }
155
156
157 //
158 // Vector subset
159 //
160 const_iterator begin() const { return vch.begin() + m_read_pos; }
161 iterator begin() { return vch.begin() + m_read_pos; }
162 const_iterator end() const { return vch.end(); }
163 iterator end() { return vch.end(); }
164 size_type size() const { return vch.size() - m_read_pos; }
165 bool empty() const { return vch.size() == m_read_pos; }
166 void resize(size_type n, value_type c = value_type{}) { vch.resize(n + m_read_pos, c); }
167 void reserve(size_type n) { vch.reserve(n + m_read_pos); }
168 const_reference operator[](size_type pos) const { return vch[pos + m_read_pos]; }
170 void clear() { vch.clear(); m_read_pos = 0; }
171 value_type* data() { return vch.data() + m_read_pos; }
172 const value_type* data() const { return vch.data() + m_read_pos; }
173
174 inline void Compact()
175 {
176 vch.erase(vch.begin(), vch.begin() + m_read_pos);
177 m_read_pos = 0;
178 }
179
180 bool Rewind(std::optional<size_type> n = std::nullopt)
181 {
182 // Total rewind if no size is passed
183 if (!n) {
184 m_read_pos = 0;
185 return true;
186 }
187 // Rewind by n characters if the buffer hasn't been compacted yet
188 if (*n > m_read_pos)
189 return false;
190 m_read_pos -= *n;
191 return true;
192 }
193
194
195 //
196 // Stream subset
197 //
198 bool eof() const { return size() == 0; }
199 int in_avail() const { return size(); }
200
201 void read(std::span<value_type> dst)
202 {
203 if (dst.size() == 0) return;
204
205 // Read from the beginning of the buffer
206 auto next_read_pos{CheckedAdd(m_read_pos, dst.size())};
207 if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
208 throw std::ios_base::failure("DataStream::read(): end of data");
209 }
210 memcpy(dst.data(), &vch[m_read_pos], dst.size());
211 if (next_read_pos.value() == vch.size()) {
212 m_read_pos = 0;
213 vch.clear();
214 return;
215 }
216 m_read_pos = next_read_pos.value();
217 }
218
219 void ignore(size_t num_ignore)
220 {
221 // Ignore from the beginning of the buffer
222 auto next_read_pos{CheckedAdd(m_read_pos, num_ignore)};
223 if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
224 throw std::ios_base::failure("DataStream::ignore(): end of data");
225 }
226 if (next_read_pos.value() == vch.size()) {
227 m_read_pos = 0;
228 vch.clear();
229 return;
230 }
231 m_read_pos = next_read_pos.value();
232 }
233
234 void write(std::span<const value_type> src)
235 {
236 // Write to the end of the buffer
237 vch.insert(vch.end(), src.begin(), src.end());
238 }
239
240 template<typename T>
242 {
243 ::Serialize(*this, obj);
244 return (*this);
245 }
246
247 template <typename T>
249 {
250 ::Unserialize(*this, obj);
251 return (*this);
252 }
253
255 size_t GetMemoryUsage() const noexcept;
256};
257
258template <typename IStream>
260{
261private:
262 IStream& m_istream;
263
266 uint8_t m_buffer{0};
267
271 int m_offset{8};
272
273public:
274 explicit BitStreamReader(IStream& istream) : m_istream(istream) {}
275
279 uint64_t Read(int nbits) {
280 if (nbits < 0 || nbits > 64) {
281 throw std::out_of_range("nbits must be between 0 and 64");
282 }
283
284 uint64_t data = 0;
285 while (nbits > 0) {
286 if (m_offset == 8) {
287 m_istream >> m_buffer;
288 m_offset = 0;
289 }
290
291 int bits = std::min(8 - m_offset, nbits);
292 data <<= bits;
293 data |= static_cast<uint8_t>(m_buffer << m_offset) >> (8 - bits);
294 m_offset += bits;
295 nbits -= bits;
296 }
297 return data;
298 }
299};
300
301template <typename OStream>
303{
304private:
305 OStream& m_ostream;
306
309 uint8_t m_buffer{0};
310
314 int m_offset{0};
315
316public:
317 explicit BitStreamWriter(OStream& ostream) : m_ostream(ostream) {}
318
320 {
321 Flush();
322 }
323
327 void Write(uint64_t data, int nbits) {
328 if (nbits < 0 || nbits > 64) {
329 throw std::out_of_range("nbits must be between 0 and 64");
330 }
331
332 while (nbits > 0) {
333 int bits = std::min(8 - m_offset, nbits);
334 m_buffer |= (data << (64 - nbits)) >> (64 - 8 + m_offset);
335 m_offset += bits;
336 nbits -= bits;
337
338 if (m_offset == 8) {
339 Flush();
340 }
341 }
342 }
343
347 void Flush() {
348 if (m_offset == 0) {
349 return;
350 }
351
352 m_ostream << m_buffer;
353 m_buffer = 0;
354 m_offset = 0;
355 }
356};
357
371{
372protected:
373 std::FILE* m_file;
375 std::optional<int64_t> m_position;
376 bool m_was_written{false};
377
378public:
379 explicit AutoFile(std::FILE* file, const Obfuscation& obfuscation = {});
380
382 {
383 if (m_was_written) {
384 // Callers that wrote to the file must have closed it explicitly
385 // with the fclose() method and checked that the close succeeded.
386 // This is because here in the destructor we have no way to signal
387 // errors from fclose() which, after write, could mean the file is
388 // corrupted and must be handled properly at the call site.
389 // Destructors in C++ cannot signal an error to the callers because
390 // they do not return a value and are not allowed to throw exceptions.
391 Assume(IsNull());
392 }
393
394 if (fclose() != 0) {
395 LogError("Failed to close file: %s", SysErrorString(errno));
396 }
397 }
398
399 // Disallow copies
400 AutoFile(const AutoFile&) = delete;
401 AutoFile& operator=(const AutoFile&) = delete;
402
403 bool feof() const { return std::feof(m_file); }
404
405 [[nodiscard]] int fclose()
406 {
407 if (auto rel{release()}) return std::fclose(rel);
408 return 0;
409 }
410
415 std::FILE* release()
416 {
417 std::FILE* ret{m_file};
418 m_file = nullptr;
419 return ret;
420 }
421
424 bool IsNull() const { return m_file == nullptr; }
425
427 void SetObfuscation(const Obfuscation& obfuscation) { m_obfuscation = obfuscation; }
428
430 std::size_t detail_fread(std::span<std::byte> dst);
431
433 void seek(int64_t offset, int origin);
434
436 int64_t tell();
437
439 bool Commit();
440
442 bool Truncate(unsigned size);
443
445 void write_buffer(std::span<std::byte> src);
446
447 //
448 // Stream subset
449 //
450 void read(std::span<std::byte> dst);
451 void ignore(size_t nSize);
452 void write(std::span<const std::byte> src);
453
454 template <typename T>
455 AutoFile& operator<<(const T& obj)
456 {
457 ::Serialize(*this, obj);
458 return *this;
459 }
460
461 template <typename T>
463 {
464 ::Unserialize(*this, obj);
465 return *this;
466 }
467};
468
469using DataBuffer = std::vector<std::byte>;
470
478{
479private:
481 uint64_t nSrcPos{0};
482 uint64_t m_read_pos{0};
483 uint64_t nReadLimit;
484 uint64_t nRewind;
486
488 bool Fill() {
489 unsigned int pos = nSrcPos % vchBuf.size();
490 unsigned int readNow = vchBuf.size() - pos;
491 unsigned int nAvail = vchBuf.size() - (nSrcPos - m_read_pos) - nRewind;
492 if (nAvail < readNow)
493 readNow = nAvail;
494 if (readNow == 0)
495 return false;
496 size_t nBytes{m_src.detail_fread(std::span{vchBuf}.subspan(pos, readNow))};
497 if (nBytes == 0) {
498 throw std::ios_base::failure{m_src.feof() ? "BufferedFile::Fill: end of file" : "BufferedFile::Fill: fread failed"};
499 }
500 nSrcPos += nBytes;
501 return true;
502 }
503
509 std::pair<std::byte*, size_t> AdvanceStream(size_t length)
510 {
511 assert(m_read_pos <= nSrcPos);
512 if (m_read_pos + length > nReadLimit) {
513 throw std::ios_base::failure("Attempt to position past buffer limit");
514 }
515 // If there are no bytes available, read from the file.
516 if (m_read_pos == nSrcPos && length > 0) Fill();
517
518 size_t buffer_offset{static_cast<size_t>(m_read_pos % vchBuf.size())};
519 size_t buffer_available{static_cast<size_t>(vchBuf.size() - buffer_offset)};
520 size_t bytes_until_source_pos{static_cast<size_t>(nSrcPos - m_read_pos)};
521 size_t advance{std::min({length, buffer_available, bytes_until_source_pos})};
522 m_read_pos += advance;
523 return std::make_pair(&vchBuf[buffer_offset], advance);
524 }
525
526public:
527 BufferedFile(AutoFile& file LIFETIMEBOUND, uint64_t nBufSize, uint64_t nRewindIn)
528 : m_src{file}, nReadLimit{std::numeric_limits<uint64_t>::max()}, nRewind{nRewindIn}, vchBuf(nBufSize, std::byte{0})
529 {
530 if (nRewindIn >= nBufSize)
531 throw std::ios_base::failure("Rewind limit must be less than buffer size");
532 }
533
535 bool eof() const {
536 return m_read_pos == nSrcPos && m_src.feof();
537 }
538
540 void read(std::span<std::byte> dst)
541 {
542 while (dst.size() > 0) {
543 auto [buffer_pointer, length]{AdvanceStream(dst.size())};
544 memcpy(dst.data(), buffer_pointer, length);
545 dst = dst.subspan(length);
546 }
547 }
548
551 void SkipTo(const uint64_t file_pos)
552 {
553 assert(file_pos >= m_read_pos);
554 while (m_read_pos < file_pos) AdvanceStream(file_pos - m_read_pos);
555 }
556
558 uint64_t GetPos() const {
559 return m_read_pos;
560 }
561
563 bool SetPos(uint64_t nPos) {
564 size_t bufsize = vchBuf.size();
565 if (nPos + bufsize < nSrcPos) {
566 // rewinding too far, rewind as far as possible
567 m_read_pos = nSrcPos - bufsize;
568 return false;
569 }
570 if (nPos > nSrcPos) {
571 // can't go this far forward, go as far as possible
572 m_read_pos = nSrcPos;
573 return false;
574 }
575 m_read_pos = nPos;
576 return true;
577 }
578
581 bool SetLimit(uint64_t nPos = std::numeric_limits<uint64_t>::max()) {
582 if (nPos < m_read_pos)
583 return false;
584 nReadLimit = nPos;
585 return true;
586 }
587
588 template<typename T>
590 ::Unserialize(*this, obj);
591 return (*this);
592 }
593
595 void FindByte(std::byte byte)
596 {
597 // For best performance, avoid mod operation within the loop.
598 size_t buf_offset{size_t(m_read_pos % uint64_t(vchBuf.size()))};
599 while (true) {
600 if (m_read_pos == nSrcPos) {
601 // No more bytes available; read from the file into the buffer,
602 // setting nSrcPos to one beyond the end of the new data.
603 // Throws exception if end-of-file reached.
604 Fill();
605 }
606 const size_t len{std::min<size_t>(vchBuf.size() - buf_offset, nSrcPos - m_read_pos)};
607 const auto it_start{vchBuf.begin() + buf_offset};
608 const auto it_find{std::find(it_start, it_start + len, byte)};
609 const size_t inc{size_t(std::distance(it_start, it_find))};
610 m_read_pos += inc;
611 if (inc < len) break;
612 buf_offset += inc;
613 if (buf_offset >= vchBuf.size()) buf_offset = 0;
614 }
615 }
616};
617
623template <typename S>
625{
628 size_t m_buf_pos;
629
630public:
632 explicit BufferedReader(S&& stream LIFETIMEBOUND, size_t size = 1 << 16)
633 requires std::is_rvalue_reference_v<S&&>
634 : m_src{stream}, m_buf(size), m_buf_pos{size} {}
635
636 void read(std::span<std::byte> dst)
637 {
638 if (const auto available{std::min(dst.size(), m_buf.size() - m_buf_pos)}) {
639 std::copy_n(m_buf.begin() + m_buf_pos, available, dst.begin());
640 m_buf_pos += available;
641 dst = dst.subspan(available);
642 }
643 if (dst.size()) {
644 assert(m_buf_pos == m_buf.size());
645 m_src.read(dst);
646
647 m_buf_pos = 0;
648 m_buf.resize(m_src.detail_fread(m_buf));
649 }
650 }
651
652 template <typename T>
654 {
655 Unserialize(*this, obj);
656 return *this;
657 }
658};
659
665template <typename S>
667{
670 size_t m_buf_pos{0};
671
672public:
673 explicit BufferedWriter(S& stream LIFETIMEBOUND, size_t size = 1 << 16) : m_dst{stream}, m_buf(size) {}
674
675 ~BufferedWriter() { flush(); }
676
677 void flush()
678 {
679 if (m_buf_pos) m_dst.write_buffer(std::span{m_buf}.first(m_buf_pos));
680 m_buf_pos = 0;
681 }
682
683 void write(std::span<const std::byte> src)
684 {
685 while (const auto available{std::min(src.size(), m_buf.size() - m_buf_pos)}) {
686 std::copy_n(src.begin(), available, m_buf.begin() + m_buf_pos);
687 m_buf_pos += available;
688 if (m_buf_pos == m_buf.size()) flush();
689 src = src.subspan(available);
690 }
691 }
692
693 template <typename T>
695 {
696 Serialize(*this, obj);
697 return *this;
698 }
699};
700
701#endif // BITCOIN_STREAMS_H
#define LIFETIMEBOUND
Definition: attributes.h:16
int ret
ArgsManager & args
Definition: bitcoind.cpp:277
#define Assume(val)
Assume is the identity function.
Definition: check.h:118
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:371
bool feof() const
Definition: streams.h:403
std::FILE * release()
Get wrapped FILE* with transfer of ownership.
Definition: streams.h:415
AutoFile & operator=(const AutoFile &)=delete
~AutoFile()
Definition: streams.h:381
std::FILE * m_file
Definition: streams.h:373
void SetObfuscation(const Obfuscation &obfuscation)
Continue with a different XOR key.
Definition: streams.h:427
AutoFile & operator<<(const T &obj)
Definition: streams.h:455
std::size_t detail_fread(std::span< std::byte > dst)
Implementation detail, only used internally.
Definition: streams.cpp:21
AutoFile(const AutoFile &)=delete
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:424
AutoFile & operator>>(T &&obj)
Definition: streams.h:462
std::optional< int64_t > m_position
Definition: streams.h:375
Obfuscation m_obfuscation
Definition: streams.h:374
int fclose()
Definition: streams.h:405
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
Definition: streams.h:279
BitStreamReader(IStream &istream)
Definition: streams.h:274
IStream & m_istream
Definition: streams.h:262
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:327
OStream & m_ostream
Definition: streams.h:305
BitStreamWriter(OStream &ostream)
Definition: streams.h:317
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
Definition: streams.h:347
Wrapper around an AutoFile& that implements a ring buffer to deserialize from.
Definition: streams.h:478
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:509
uint64_t nRewind
how many bytes we guarantee to rewind
Definition: streams.h:484
void read(std::span< std::byte > dst)
read a number of bytes
Definition: streams.h:540
BufferedFile(AutoFile &file LIFETIMEBOUND, uint64_t nBufSize, uint64_t nRewindIn)
Definition: streams.h:527
bool eof() const
check whether we're at the end of the source file
Definition: streams.h:535
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:581
DataBuffer vchBuf
Definition: streams.h:485
BufferedFile & operator>>(T &&obj)
Definition: streams.h:589
uint64_t GetPos() const
return the current reading position
Definition: streams.h:558
uint64_t nReadLimit
up to which position we're allowed to read
Definition: streams.h:483
void SkipTo(const uint64_t file_pos)
Move the read position ahead in the stream to the given position.
Definition: streams.h:551
void FindByte(std::byte byte)
search for a given byte in the stream, and remain positioned on it
Definition: streams.h:595
bool Fill()
read data from the source to fill the buffer
Definition: streams.h:488
AutoFile & m_src
Definition: streams.h:480
bool SetPos(uint64_t nPos)
rewind to a given reading position
Definition: streams.h:563
Wrapper that buffers reads from an underlying stream.
Definition: streams.h:625
size_t m_buf_pos
Definition: streams.h:628
DataBuffer m_buf
Definition: streams.h:627
BufferedReader(S &&stream LIFETIMEBOUND, size_t size=1<< 16)
Requires stream ownership to prevent leaving the stream at an unexpected position after buffered read...
Definition: streams.h:632
BufferedReader & operator>>(T &&obj)
Definition: streams.h:653
void read(std::span< std::byte > dst)
Definition: streams.h:636
Wrapper that buffers writes to an underlying stream.
Definition: streams.h:667
DataBuffer m_buf
Definition: streams.h:669
void write(std::span< const std::byte > src)
Definition: streams.h:683
void flush()
Definition: streams.h:677
BufferedWriter & operator<<(const T &obj)
Definition: streams.h:694
BufferedWriter(S &stream LIFETIMEBOUND, size_t size=1<< 16)
Definition: streams.h:673
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:130
DataStream & operator<<(const T &obj)
Definition: streams.h:241
bool empty() const
Definition: streams.h:165
vector_type::difference_type difference_type
Definition: streams.h:139
void write(std::span< const value_type > src)
Definition: streams.h:234
size_type size() const
Definition: streams.h:164
DataStream & operator>>(T &&obj)
Definition: streams.h:248
reference operator[](size_type pos)
Definition: streams.h:169
void resize(size_type n, value_type c=value_type{})
Definition: streams.h:166
const_reference operator[](size_type pos) const
Definition: streams.h:168
void read(std::span< value_type > dst)
Definition: streams.h:201
vector_type::size_type size_type
Definition: streams.h:138
SerializeData vector_type
Definition: streams.h:132
vector_type vch
Definition: streams.h:133
const value_type * data() const
Definition: streams.h:172
vector_type::const_reference const_reference
Definition: streams.h:141
value_type * data()
Definition: streams.h:171
vector_type::const_iterator const_iterator
Definition: streams.h:144
void reserve(size_type n)
Definition: streams.h:167
vector_type::reverse_iterator reverse_iterator
Definition: streams.h:145
DataStream(std::span< const value_type > sp)
Definition: streams.h:149
iterator begin()
Definition: streams.h:161
const_iterator begin() const
Definition: streams.h:160
vector_type::size_type m_read_pos
Definition: streams.h:134
vector_type::iterator iterator
Definition: streams.h:143
vector_type::value_type value_type
Definition: streams.h:142
DataStream(std::span< const uint8_t > sp)
Definition: streams.h:148
bool eof() const
Definition: streams.h:198
std::string str() const
Definition: streams.h:151
void ignore(size_t num_ignore)
Definition: streams.h:219
vector_type::allocator_type allocator_type
Definition: streams.h:137
const_iterator end() const
Definition: streams.h:162
void Compact()
Definition: streams.h:174
void clear()
Definition: streams.h:170
size_t GetMemoryUsage() const noexcept
Compute total memory usage of this object (own memory + any dynamic memory).
Definition: streams.cpp:126
iterator end()
Definition: streams.h:163
bool Rewind(std::optional< size_type > n=std::nullopt)
Definition: streams.h:180
DataStream()=default
vector_type::reference reference
Definition: streams.h:140
int in_avail() const
Definition: streams.h:199
Minimal stream for reading from an existing byte array by std::span.
Definition: streams.h:83
bool empty() const
Definition: streams.h:102
SpanReader & operator>>(T &&obj)
Definition: streams.h:95
std::span< const std::byte > m_data
Definition: streams.h:85
size_t size() const
Definition: streams.h:101
SpanReader(std::span< const std::byte > data)
Definition: streams.h:92
void read(std::span< std::byte > dst)
Definition: streams.h:104
void ignore(size_t n)
Definition: streams.h:118
SpanReader(std::span< const unsigned char > data)
Definition: streams.h:91
std::vector< unsigned char > & vchData
Definition: streams.h:76
VectorWriter & operator<<(const T &obj)
Definition: streams.h:69
size_t nPos
Definition: streams.h:77
void write(std::span< const std::byte > src)
Definition: streams.h:56
VectorWriter(std::vector< unsigned char > &vchDataIn, size_t nPosIn, Args &&... args)
Definition: streams.h:52
VectorWriter(std::vector< unsigned char > &vchDataIn, size_t nPosIn)
Definition: streams.h:42
#define LogError(...)
Definition: logging.h:358
std::optional< T > CheckedAdd(const T i, const T j) noexcept
Definition: overflow.h:26
#define S(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
void Serialize(Stream &, V)=delete
void SerializeMany(Stream &s, const Args &... args)
Support for (un)serializing many things at once.
Definition: serialize.h:985
void Unserialize(Stream &, V)=delete
unsigned char * UCharCast(char *c)
Definition: span.h:95
std::vector< std::byte > DataBuffer
Definition: streams.h:469
std::string SysErrorString(int err)
Return system error string from errno value.
Definition: syserror.cpp:19
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:49