diff --git a/src/hash.h b/src/hash.h index 52babf8b1d9..5e9a2bd648e 100644 --- a/src/hash.h +++ b/src/hash.h @@ -107,6 +107,10 @@ public: { ctx.Write(UCharCast(src.data()), src.size()); } + void write(std::byte src) + { + ctx.Write(UCharCast(&src), 1); + } /** Compute the double-SHA256 hash of all data written to this object. * @@ -194,6 +198,11 @@ public: m_source.write(src); HashWriter::write(src); } + void write(std::byte src) + { + m_source.write(src); + HashWriter::write(src); + } template HashedSourceWriter& operator<<(const T& obj) diff --git a/src/serialize.h b/src/serialize.h index fa85663ad31..0b75a1e3a44 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -53,7 +53,7 @@ constexpr deserialize_type deserialize {}; */ template inline void ser_writedata8(Stream &s, uint8_t obj) { - s.write(AsBytes(Span{&obj, 1})); + s.write(std::byte{obj}); } template inline void ser_writedata16(Stream &s, uint16_t obj) { @@ -1067,6 +1067,10 @@ public: { this->nSize += src.size(); } + void write(std::byte) + { + this->nSize += 1; + } /** Pretend _nSize bytes are written, without specifying them. */ void seek(size_t _nSize) @@ -1131,6 +1135,7 @@ public: template ParamsStream& operator<<(const U& obj) { ::Serialize(*this, obj); return *this; } template ParamsStream& operator>>(U&& obj) { ::Unserialize(*this, obj); return *this; } void write(Span src) { GetStream().write(src); } + void write(std::byte src) { GetStream().write(src); } void read(Span dst) { GetStream().read(dst); } void ignore(size_t num) { GetStream().ignore(num); } bool eof() const { return GetStream().eof(); } diff --git a/src/streams.cpp b/src/streams.cpp index bec505ebc3a..51b8c4aa087 100644 --- a/src/streams.cpp +++ b/src/streams.cpp @@ -111,6 +111,24 @@ void AutoFile::write_large(Span src) if (m_position) *m_position += src.size(); } +void AutoFile::write(std::byte val) +{ + if (!m_file) throw std::ios_base::failure("AutoFile::write: file handle is nullptr"); + if (!m_obfuscation) { + if (fwrite(&val, 1, 1, m_file) != 1) { + throw std::ios_base::failure("AutoFile::write: write failed"); + } + if (m_position.has_value()) *m_position += 1; + } else { + if (!m_position.has_value()) throw std::ios_base::failure("AutoFile::write: position unknown"); + auto src{Span{&val, 1}}; + m_obfuscation(src, *m_position); + if (fwrite(src.data(), 1, 1, m_file) != 1) { + throw std::ios_base::failure{"XorFile::write: failed"}; + } + *m_position += 1; + } +} bool AutoFile::Commit() { return ::FileCommit(m_file); diff --git a/src/streams.h b/src/streams.h index e1b324b52d8..b4a17702b9a 100644 --- a/src/streams.h +++ b/src/streams.h @@ -62,6 +62,16 @@ public: } nPos += src.size(); } + void write(std::byte val) + { + assert(nPos <= vchData.size()); + if (nPos < vchData.size()) { + vchData[nPos] = static_cast(val); + } else { + vchData.push_back(static_cast(val)); + } + nPos += 1; + } template VectorWriter& operator<<(const T& obj) { @@ -233,6 +243,11 @@ public: // Write to the end of the buffer vch.insert(vch.end(), src.begin(), src.end()); } + void write(value_type val) + { + // Push single value to the end of the buffer + vch.push_back(val); + } template DataStream& operator<<(const T& obj) @@ -427,6 +442,7 @@ public: void ignore(size_t nSize); void write(Span src); void write_large(Span src); // Note that src will be mutated + void write(std::byte src); template AutoFile& operator<<(const T& obj)