mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
merge bitcoin#23438: Use spans of std::byte in serialize
continuation of de54b878
from dash#5574
This commit is contained in:
parent
d3b282208b
commit
e933d78a88
@ -17,8 +17,8 @@
|
||||
static void DeserializeBlockTest(benchmark::Bench& bench)
|
||||
{
|
||||
CDataStream stream(benchmark::data::block813851, SER_NETWORK, PROTOCOL_VERSION);
|
||||
char a = '\0';
|
||||
stream.write(&a, 1); // Prevent compaction
|
||||
std::byte a{0};
|
||||
stream.write({&a, 1}); // Prevent compaction
|
||||
|
||||
bench.unit("block").run([&] {
|
||||
CBlock block;
|
||||
@ -31,8 +31,8 @@ static void DeserializeBlockTest(benchmark::Bench& bench)
|
||||
static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
|
||||
{
|
||||
CDataStream stream(benchmark::data::block813851, SER_NETWORK, PROTOCOL_VERSION);
|
||||
char a = '\0';
|
||||
stream.write(&a, 1); // Prevent compaction
|
||||
std::byte a{0};
|
||||
stream.write({&a, 1}); // Prevent compaction
|
||||
|
||||
ArgsManager bench_args;
|
||||
const auto chainParams = CreateChainParams(bench_args, CBaseChainParams::MAIN);
|
||||
|
@ -27,8 +27,8 @@ struct TestBlockAndIndex {
|
||||
TestBlockAndIndex()
|
||||
{
|
||||
CDataStream stream(benchmark::data::block813851, SER_NETWORK, PROTOCOL_VERSION);
|
||||
char a = '\0';
|
||||
stream.write(&a, 1); // Prevent compaction
|
||||
std::byte a{0};
|
||||
stream.write({&a, 1}); // Prevent compaction
|
||||
|
||||
stream >> block;
|
||||
|
||||
|
@ -66,7 +66,7 @@ void CBloomFilter::insert(const COutPoint& outpoint)
|
||||
{
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << outpoint;
|
||||
insert(stream);
|
||||
insert(MakeUCharSpan(stream));
|
||||
}
|
||||
|
||||
bool CBloomFilter::contains(Span<const unsigned char> vKey) const
|
||||
|
@ -167,7 +167,7 @@ public:
|
||||
template <typename Stream>
|
||||
inline void Serialize(Stream& s, const bool specificLegacyScheme) const
|
||||
{
|
||||
s.write(reinterpret_cast<const char*>(ToByteVector(specificLegacyScheme).data()), SerSize);
|
||||
s.write(AsBytes(Span{ToByteVector(specificLegacyScheme).data(), SerSize}));
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
@ -180,7 +180,7 @@ public:
|
||||
inline void Unserialize(Stream& s, const bool specificLegacyScheme)
|
||||
{
|
||||
std::array<uint8_t, SerSize> vecBytes{};
|
||||
s.read(reinterpret_cast<char*>(vecBytes.data()), SerSize);
|
||||
s.read(AsWritableBytes(Span{vecBytes.data(), SerSize}));
|
||||
SetByteVector(vecBytes, specificLegacyScheme);
|
||||
|
||||
if (!CheckMalleable(vecBytes, specificLegacyScheme)) {
|
||||
@ -456,7 +456,7 @@ public:
|
||||
bufLegacyScheme = specificLegacyScheme;
|
||||
hash.SetNull();
|
||||
}
|
||||
s.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
|
||||
s.write(MakeByteSpan(vecBytes));
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
@ -469,7 +469,7 @@ public:
|
||||
inline void Unserialize(Stream& s, const bool specificLegacyScheme) const
|
||||
{
|
||||
std::unique_lock<std::mutex> l(mutex);
|
||||
s.read(reinterpret_cast<char*>(vecBytes.data()), BLSObject::SerSize);
|
||||
s.read(AsWritableBytes(Span{vecBytes.data(), BLSObject::SerSize}));
|
||||
bufValid = true;
|
||||
bufLegacyScheme = specificLegacyScheme;
|
||||
objInitialized = false;
|
||||
@ -543,7 +543,7 @@ public:
|
||||
}
|
||||
if (hash.IsNull()) {
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
ss.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
|
||||
ss.write(MakeByteSpan(vecBytes));
|
||||
hash = ss.GetHash();
|
||||
}
|
||||
return hash;
|
||||
|
@ -109,7 +109,7 @@ public:
|
||||
ds.clear();
|
||||
|
||||
ds << _objects[i];
|
||||
blobs[i].assign(ds.begin(), ds.end());
|
||||
blobs[i].assign(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
return false;
|
||||
@ -122,7 +122,7 @@ public:
|
||||
{
|
||||
CDataStream ds(SER_NETWORK, nVersion);
|
||||
ds << obj;
|
||||
Blob blob(ds.begin(), ds.end());
|
||||
Blob blob(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
|
||||
return CBLSIESMultiRecipientBlobs::Encrypt(idx, recipient, blob);
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
|
||||
CDataStream GetKey() {
|
||||
leveldb::Slice slKey = piter->key();
|
||||
return CDataStream(MakeUCharSpan(slKey), SER_DISK, CLIENT_VERSION);
|
||||
return CDataStream{MakeByteSpan(slKey), SER_DISK, CLIENT_VERSION};
|
||||
}
|
||||
|
||||
unsigned int GetKeySize() {
|
||||
@ -179,7 +179,7 @@ public:
|
||||
template<typename V> bool GetValue(V& value) {
|
||||
leveldb::Slice slValue = piter->value();
|
||||
try {
|
||||
CDataStream ssValue(MakeUCharSpan(slValue), SER_DISK, CLIENT_VERSION);
|
||||
CDataStream ssValue{MakeByteSpan(slValue), SER_DISK, CLIENT_VERSION};
|
||||
ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
|
||||
ssValue >> value;
|
||||
} catch (const std::exception&) {
|
||||
@ -269,7 +269,7 @@ public:
|
||||
LogPrintf("LevelDB read failure: %s\n", status.ToString());
|
||||
dbwrapper_private::HandleError(status);
|
||||
}
|
||||
CDataStream ssValueTmp(MakeUCharSpan(strValue), SER_DISK, CLIENT_VERSION);
|
||||
CDataStream ssValueTmp{MakeByteSpan(strValue), SER_DISK, CLIENT_VERSION};
|
||||
ssValueTmp.Xor(obfuscate_key);
|
||||
ssValue = std::move(ssValueTmp);
|
||||
return true;
|
||||
|
@ -40,7 +40,7 @@ void SetTxPayload(CMutableTransaction& tx, const T& payload)
|
||||
{
|
||||
CDataStream ds(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ds << payload;
|
||||
tx.vExtraPayload.assign(ds.begin(), ds.end());
|
||||
tx.vExtraPayload.assign(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
|
||||
}
|
||||
|
||||
uint256 CalcTxInputsHash(const CTransaction& tx);
|
||||
|
@ -97,7 +97,7 @@ private:
|
||||
|
||||
// read data and checksum from file
|
||||
try {
|
||||
filein.read((char *)vchData.data(), dataSize);
|
||||
filein.read(MakeWritableByteSpan(vchData));
|
||||
filein >> hashIn;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
|
15
src/hash.h
15
src/hash.h
@ -124,8 +124,9 @@ public:
|
||||
int GetType() const { return nType; }
|
||||
int GetVersion() const { return nVersion; }
|
||||
|
||||
void write(const char *pch, size_t size) {
|
||||
ctx.Write((const unsigned char*)pch, size);
|
||||
void write(Span<const std::byte> src)
|
||||
{
|
||||
ctx.Write(UCharCast(src.data()), src.size());
|
||||
}
|
||||
|
||||
/** Compute the double-SHA256 hash of all data written to this object.
|
||||
@ -175,18 +176,18 @@ private:
|
||||
public:
|
||||
explicit CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {}
|
||||
|
||||
void read(char* pch, size_t nSize)
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
source->read(pch, nSize);
|
||||
this->write(pch, nSize);
|
||||
source->read(dst);
|
||||
this->write(dst);
|
||||
}
|
||||
|
||||
void ignore(size_t nSize)
|
||||
{
|
||||
char data[1024];
|
||||
std::byte data[1024];
|
||||
while (nSize > 0) {
|
||||
size_t now = std::min<size_t>(nSize, 1024);
|
||||
read(data, now);
|
||||
read({data, now});
|
||||
nSize -= now;
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ void CDKGPendingMessages::PushPendingMessage(NodeId from, PeerManager* peerman,
|
||||
auto pm = std::make_shared<CDataStream>(std::move(vRecv));
|
||||
|
||||
CHashWriter hw(SER_GETHASH, 0);
|
||||
hw.write(reinterpret_cast<const char*>(pm->data()), pm->size());
|
||||
hw.write(AsWritableBytes(Span{*pm}));
|
||||
uint256 hash = hw.GetHash();
|
||||
|
||||
if (from != -1) {
|
||||
|
@ -4289,11 +4289,11 @@ void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Spa
|
||||
CAutoFile f(fsbridge::fopen(path, "ab"), SER_DISK, CLIENT_VERSION);
|
||||
|
||||
ser_writedata64(f, now.count());
|
||||
f.write(msg_type.data(), msg_type.length());
|
||||
f.write(MakeByteSpan(msg_type));
|
||||
for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
|
||||
f << uint8_t{'\0'};
|
||||
}
|
||||
uint32_t size = data.size();
|
||||
ser_writedata32(f, size);
|
||||
f.write((const char*)data.data(), data.size());
|
||||
f.write(AsBytes(data));
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6
|
||||
|
||||
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error)
|
||||
{
|
||||
CDataStream ss_data(MakeUCharSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream ss_data(MakeByteSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ss_data >> psbt;
|
||||
if (!ss_data.empty()) {
|
||||
|
@ -135,14 +135,14 @@ public:
|
||||
{
|
||||
unsigned int len = size();
|
||||
::WriteCompactSize(s, len);
|
||||
s.write((char*)vch, len);
|
||||
s.write(AsBytes(Span{vch, len}));
|
||||
}
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
const unsigned int len(::ReadCompactSize(s));
|
||||
if (len <= SIZE) {
|
||||
s.read((char*)vch, len);
|
||||
s.read(AsWritableBytes(Span{vch, len}));
|
||||
if (len != size()) {
|
||||
Invalidate();
|
||||
}
|
||||
@ -269,7 +269,7 @@ struct CExtPubKey {
|
||||
::WriteCompactSize(s, len);
|
||||
unsigned char code[BIP32_EXTKEY_SIZE];
|
||||
Encode(code);
|
||||
s.write((const char *)&code[0], len);
|
||||
s.write(AsBytes(Span{&code[0], len}));
|
||||
}
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
@ -278,7 +278,7 @@ struct CExtPubKey {
|
||||
unsigned char code[BIP32_EXTKEY_SIZE];
|
||||
if (len != BIP32_EXTKEY_SIZE)
|
||||
throw std::runtime_error("Invalid extended key size\n");
|
||||
s.read((char *)&code[0], len);
|
||||
s.read(AsWritableBytes(Span{&code[0], len}));
|
||||
Decode(code);
|
||||
}
|
||||
};
|
||||
|
@ -229,7 +229,7 @@ static void FundSpecialTx(CWallet* pwallet, CMutableTransaction& tx, const Speci
|
||||
|
||||
CDataStream ds(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ds << payload;
|
||||
tx.vExtraPayload.assign(ds.begin(), ds.end());
|
||||
tx.vExtraPayload.assign(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
|
||||
|
||||
static const CTxOut dummyTxOut(0, CScript() << OP_RETURN);
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
@ -22,20 +22,23 @@ public:
|
||||
m_remaining(txToLen)
|
||||
{}
|
||||
|
||||
void read(char* pch, size_t nSize)
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
if (nSize > m_remaining)
|
||||
if (dst.size() > m_remaining) {
|
||||
throw std::ios_base::failure(std::string(__func__) + ": end of data");
|
||||
}
|
||||
|
||||
if (pch == nullptr)
|
||||
if (dst.data() == nullptr) {
|
||||
throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
|
||||
}
|
||||
|
||||
if (m_data == nullptr)
|
||||
if (m_data == nullptr) {
|
||||
throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
|
||||
}
|
||||
|
||||
memcpy(pch, m_data, nSize);
|
||||
m_remaining -= nSize;
|
||||
m_data += nSize;
|
||||
memcpy(dst.data(), m_data, dst.size());
|
||||
m_remaining -= dst.size();
|
||||
m_data += dst.size();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -1418,12 +1418,12 @@ public:
|
||||
it = itBegin;
|
||||
while (scriptCode.GetOp(it, opcode)) {
|
||||
if (opcode == OP_CODESEPARATOR) {
|
||||
s.write((char*)&itBegin[0], it-itBegin-1);
|
||||
s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin - 1)}));
|
||||
itBegin = it;
|
||||
}
|
||||
}
|
||||
if (itBegin != scriptCode.end())
|
||||
s.write((char*)&itBegin[0], it-itBegin);
|
||||
s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin)}));
|
||||
}
|
||||
|
||||
/** Serialize an input of txTo */
|
||||
|
@ -51,79 +51,72 @@ static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
|
||||
struct deserialize_type {};
|
||||
constexpr deserialize_type deserialize {};
|
||||
|
||||
//! Safely convert odd char pointer types to standard ones.
|
||||
inline char* CharCast(char* c) { return c; }
|
||||
inline char* CharCast(unsigned char* c) { return (char*)c; }
|
||||
inline const char* CharCast(const char* c) { return c; }
|
||||
inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
|
||||
|
||||
/*
|
||||
* Lowest-level serialization and conversion.
|
||||
* @note Sizes of these types are verified in the tests
|
||||
*/
|
||||
template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
|
||||
{
|
||||
s.write((char*)&obj, 1);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
|
||||
{
|
||||
obj = htole16(obj);
|
||||
s.write((char*)&obj, 2);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
|
||||
{
|
||||
obj = htobe16(obj);
|
||||
s.write((char*)&obj, 2);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
|
||||
{
|
||||
obj = htole32(obj);
|
||||
s.write((char*)&obj, 4);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
|
||||
{
|
||||
obj = htobe32(obj);
|
||||
s.write((char*)&obj, 4);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
|
||||
{
|
||||
obj = htole64(obj);
|
||||
s.write((char*)&obj, 8);
|
||||
s.write(AsBytes(Span{&obj, 1}));
|
||||
}
|
||||
template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
|
||||
{
|
||||
uint8_t obj;
|
||||
s.read((char*)&obj, 1);
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return obj;
|
||||
}
|
||||
template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
|
||||
{
|
||||
uint16_t obj;
|
||||
s.read((char*)&obj, 2);
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return le16toh(obj);
|
||||
}
|
||||
template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
|
||||
{
|
||||
uint16_t obj;
|
||||
s.read((char*)&obj, 2);
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return be16toh(obj);
|
||||
}
|
||||
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
|
||||
{
|
||||
uint32_t obj;
|
||||
s.read((char*)&obj, 4);
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return le32toh(obj);
|
||||
}
|
||||
template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
|
||||
{
|
||||
uint32_t obj;
|
||||
s.read((char*)&obj, 4);
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return be32toh(obj);
|
||||
}
|
||||
template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
|
||||
{
|
||||
uint64_t obj;
|
||||
s.read((char*)&obj, 8);
|
||||
s.read(AsWritableBytes(Span{&obj, 1}));
|
||||
return le64toh(obj);
|
||||
}
|
||||
|
||||
@ -131,7 +124,7 @@ template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Templates for serializing to anything that looks like a stream,
|
||||
// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
|
||||
// i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>)
|
||||
//
|
||||
|
||||
class CSizeComputer;
|
||||
@ -200,7 +193,7 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
|
||||
FORMATTER_METHODS(cls, obj)
|
||||
|
||||
#ifndef CHAR_EQUALS_INT8
|
||||
template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char
|
||||
template <typename Stream> void Serialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
|
||||
#endif
|
||||
template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
|
||||
@ -210,13 +203,13 @@ template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_wri
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
|
||||
template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); }
|
||||
template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
|
||||
template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(MakeByteSpan(a)); }
|
||||
template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(MakeByteSpan(a)); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(AsBytes(span)); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(AsBytes(span)); }
|
||||
|
||||
#ifndef CHAR_EQUALS_INT8
|
||||
template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
|
||||
template <typename Stream> void Unserialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
|
||||
#endif
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
|
||||
@ -226,9 +219,9 @@ template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a =
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
|
||||
template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
|
||||
template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); }
|
||||
template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
|
||||
template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(AsWritableBytes(span)); }
|
||||
|
||||
template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); }
|
||||
template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; }
|
||||
@ -426,11 +419,11 @@ inline unsigned int GetSizeOfFixedBitSet(size_t size)
|
||||
template<typename Stream>
|
||||
void WriteFixedBitSet(Stream& s, const std::vector<bool>& vec, size_t size)
|
||||
{
|
||||
std::vector<unsigned char> vBytes((size + 7) / 8);
|
||||
std::vector<uint8_t> vBytes((size + 7) / 8);
|
||||
size_t ms = std::min(size, vec.size());
|
||||
for (size_t p = 0; p < ms; p++)
|
||||
vBytes[p / 8] |= vec[p] << (p % 8);
|
||||
s.write((char*)vBytes.data(), vBytes.size());
|
||||
s.write(AsBytes(Span{vBytes}));
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
@ -438,8 +431,8 @@ void ReadFixedBitSet(Stream& s, std::vector<bool>& vec, size_t size)
|
||||
{
|
||||
vec.resize(size);
|
||||
|
||||
std::vector<unsigned char> vBytes((size + 7) / 8);
|
||||
s.read((char*)vBytes.data(), vBytes.size());
|
||||
std::vector<uint8_t> vBytes((size + 7) / 8);
|
||||
s.read(AsWritableBytes(Span{vBytes}));
|
||||
for (size_t p = 0; p < size; p++)
|
||||
vec[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
|
||||
if (vBytes.size() * 8 != size) {
|
||||
@ -660,10 +653,10 @@ struct CustomUintFormatter
|
||||
if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
|
||||
if (BigEndian) {
|
||||
uint64_t raw = htobe64(v);
|
||||
s.write(((const char*)&raw) + 8 - Bytes, Bytes);
|
||||
s.write({BytePtr(&raw) + 8 - Bytes, Bytes});
|
||||
} else {
|
||||
uint64_t raw = htole64(v);
|
||||
s.write((const char*)&raw, Bytes);
|
||||
s.write({BytePtr(&raw), Bytes});
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,10 +666,10 @@ struct CustomUintFormatter
|
||||
static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
|
||||
uint64_t raw = 0;
|
||||
if (BigEndian) {
|
||||
s.read(((char*)&raw) + 8 - Bytes, Bytes);
|
||||
s.read({BytePtr(&raw) + 8 - Bytes, Bytes});
|
||||
v = static_cast<I>(be64toh(raw));
|
||||
} else {
|
||||
s.read((char*)&raw, Bytes);
|
||||
s.read({BytePtr(&raw), Bytes});
|
||||
v = static_cast<I>(le64toh(raw));
|
||||
}
|
||||
}
|
||||
@ -719,7 +712,7 @@ struct LimitedStringFormatter
|
||||
throw std::ios_base::failure("String length limit exceeded");
|
||||
}
|
||||
v.resize(size);
|
||||
if (size != 0) s.read((char*)v.data(), size);
|
||||
if (size != 0) s.read(MakeWritableByteSpan(v));
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
@ -929,7 +922,7 @@ void Serialize(Stream& os, const std::basic_string<C>& str)
|
||||
{
|
||||
WriteCompactSize(os, str.size());
|
||||
if (!str.empty())
|
||||
os.write((char*)str.data(), str.size() * sizeof(C));
|
||||
os.write(MakeByteSpan(str));
|
||||
}
|
||||
|
||||
template<typename Stream, typename C>
|
||||
@ -938,7 +931,7 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
|
||||
unsigned int nSize = ReadCompactSize(is);
|
||||
str.resize(nSize);
|
||||
if (nSize != 0)
|
||||
is.read((char*)str.data(), nSize * sizeof(C));
|
||||
is.read(MakeWritableByteSpan(str));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -949,7 +942,7 @@ void Serialize(Stream& os, const std::basic_string_view<C>& str)
|
||||
{
|
||||
WriteCompactSize(os, str.size());
|
||||
if (!str.empty())
|
||||
os.write((char*)str.data(), str.size() * sizeof(C));
|
||||
os.write(AsBytes(Span{str.data(), str.size() * sizeof(C)}));
|
||||
}
|
||||
|
||||
template<typename Stream, typename C>
|
||||
@ -958,7 +951,7 @@ void Unserialize(Stream& is, std::basic_string_view<C>& str)
|
||||
unsigned int nSize = ReadCompactSize(is);
|
||||
str.resize(nSize);
|
||||
if (nSize != 0)
|
||||
is.read((char*)str.data(), nSize * sizeof(C));
|
||||
is.read(AsWritableBytes(Span{str.data(), nSize * sizeof(C)}));
|
||||
}
|
||||
|
||||
|
||||
@ -970,7 +963,7 @@ void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
|
||||
{
|
||||
WriteCompactSize(os, v.size());
|
||||
if (!v.empty())
|
||||
os.write((char*)v.data(), v.size() * sizeof(T));
|
||||
os.write(MakeByteSpan(v));
|
||||
}
|
||||
|
||||
template<typename Stream, unsigned int N, typename T, typename V>
|
||||
@ -997,7 +990,7 @@ void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
|
||||
{
|
||||
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
|
||||
v.resize_uninitialized(i + blk);
|
||||
is.read((char*)&v[i], blk * sizeof(T));
|
||||
is.read(AsWritableBytes(Span{&v[i], blk}));
|
||||
i += blk;
|
||||
}
|
||||
}
|
||||
@ -1024,7 +1017,7 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&
|
||||
{
|
||||
WriteCompactSize(os, v.size());
|
||||
if (!v.empty())
|
||||
os.write((char*)v.data(), v.size() * sizeof(T));
|
||||
os.write(MakeByteSpan(v));
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, typename A>
|
||||
@ -1063,7 +1056,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
|
||||
{
|
||||
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
|
||||
v.resize(i + blk);
|
||||
is.read((char*)&v[i], blk * sizeof(T));
|
||||
is.read(AsWritableBytes(Span{&v[i], blk}));
|
||||
i += blk;
|
||||
}
|
||||
}
|
||||
@ -1365,9 +1358,9 @@ protected:
|
||||
public:
|
||||
explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {}
|
||||
|
||||
void write(const char *psz, size_t _nSize)
|
||||
void write(Span<const std::byte> src)
|
||||
{
|
||||
this->nSize += _nSize;
|
||||
this->nSize += src.size();
|
||||
}
|
||||
|
||||
/** Pretend _nSize bytes are written, without specifying them. */
|
||||
|
@ -49,14 +49,14 @@ public:
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void write(const char* pch, size_t nSize)
|
||||
void write(Span<const std::byte> src)
|
||||
{
|
||||
stream->write(pch, nSize);
|
||||
stream->write(src);
|
||||
}
|
||||
|
||||
void read(char* pch, size_t nSize)
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
stream->read(pch, nSize);
|
||||
stream->read(dst);
|
||||
}
|
||||
|
||||
int GetVersion() const { return nVersion; }
|
||||
@ -94,17 +94,17 @@ class CVectorWriter
|
||||
{
|
||||
::SerializeMany(*this, std::forward<Args>(args)...);
|
||||
}
|
||||
void write(const char* pch, size_t nSize)
|
||||
void write(Span<const std::byte> src)
|
||||
{
|
||||
assert(nPos <= vchData.size());
|
||||
size_t nOverwrite = std::min(nSize, vchData.size() - nPos);
|
||||
size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
|
||||
if (nOverwrite) {
|
||||
memcpy(vchData.data() + nPos, reinterpret_cast<const unsigned char*>(pch), nOverwrite);
|
||||
memcpy(vchData.data() + nPos, src.data(), nOverwrite);
|
||||
}
|
||||
if (nOverwrite < nSize) {
|
||||
vchData.insert(vchData.end(), reinterpret_cast<const unsigned char*>(pch) + nOverwrite, reinterpret_cast<const unsigned char*>(pch) + nSize);
|
||||
if (nOverwrite < src.size()) {
|
||||
vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.end()));
|
||||
}
|
||||
nPos += nSize;
|
||||
nPos += src.size();
|
||||
}
|
||||
template<typename T>
|
||||
CVectorWriter& operator<<(const T& obj)
|
||||
@ -184,18 +184,18 @@ public:
|
||||
size_t size() const { return m_data.size(); }
|
||||
bool empty() const { return m_data.empty(); }
|
||||
|
||||
void read(char* dst, size_t n)
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
if (n == 0) {
|
||||
if (dst.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read from the beginning of the buffer
|
||||
if (n > m_data.size()) {
|
||||
if (dst.size() > m_data.size()) {
|
||||
throw std::ios_base::failure("SpanReader::read(): end of data");
|
||||
}
|
||||
memcpy(dst, m_data.data(), n);
|
||||
m_data = m_data.subspan(n);
|
||||
memcpy(dst.data(), m_data.data(), dst.size());
|
||||
m_data = m_data.subspan(dst.size());
|
||||
}
|
||||
};
|
||||
|
||||
@ -229,6 +229,7 @@ public:
|
||||
: nType{nTypeIn},
|
||||
nVersion{nVersionIn} {}
|
||||
|
||||
explicit CDataStream(Span<const uint8_t> sp, int type, int version) : CDataStream{AsBytes(sp), type, version} {}
|
||||
explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn)
|
||||
: vch(sp.data(), sp.data() + sp.size()),
|
||||
nType{nTypeIn},
|
||||
@ -244,7 +245,7 @@ public:
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
return (std::string(begin(), end()));
|
||||
return std::string{UCharCast(data()), UCharCast(data() + size())};
|
||||
}
|
||||
|
||||
|
||||
@ -365,16 +366,16 @@ public:
|
||||
void SetVersion(int n) { nVersion = n; }
|
||||
int GetVersion() const { return nVersion; }
|
||||
|
||||
void read(char* pch, size_t nSize)
|
||||
void read(Span<value_type> dst)
|
||||
{
|
||||
if (nSize == 0) return;
|
||||
if (dst.size() == 0) return;
|
||||
|
||||
// Read from the beginning of the buffer
|
||||
unsigned int nReadPosNext = nReadPos + nSize;
|
||||
unsigned int nReadPosNext = nReadPos + dst.size();
|
||||
if (nReadPosNext > vch.size()) {
|
||||
throw std::ios_base::failure("CDataStream::read(): end of data");
|
||||
}
|
||||
memcpy(pch, &vch[nReadPos], nSize);
|
||||
memcpy(dst.data(), &vch[nReadPos], dst.size());
|
||||
if (nReadPosNext == vch.size())
|
||||
{
|
||||
nReadPos = 0;
|
||||
@ -402,10 +403,10 @@ public:
|
||||
nReadPos = nReadPosNext;
|
||||
}
|
||||
|
||||
void write(const char* pch, size_t nSize)
|
||||
void write(Span<const value_type> src)
|
||||
{
|
||||
// Write to the end of the buffer
|
||||
vch.insert(vch.end(), pch, pch + nSize);
|
||||
vch.insert(vch.end(), src.begin(), src.end());
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
@ -413,7 +414,7 @@ public:
|
||||
{
|
||||
// Special case: stream << stream concatenates like stream += stream
|
||||
if (!vch.empty())
|
||||
s.write((char*)vch.data(), vch.size() * sizeof(value_type));
|
||||
s.write(MakeByteSpan(vch));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -444,7 +445,7 @@ public:
|
||||
}
|
||||
|
||||
for (size_type i = 0, j = 0; i != size(); i++) {
|
||||
vch[i] ^= key[j++];
|
||||
vch[i] ^= std::byte{key[j++]};
|
||||
|
||||
// This potentially acts on very many bytes of data, so it's
|
||||
// important that we calculate `j`, i.e. the `key` index in this
|
||||
@ -617,12 +618,13 @@ public:
|
||||
int GetType() const { return nType; }
|
||||
int GetVersion() const { return nVersion; }
|
||||
|
||||
void read(char* pch, size_t nSize)
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
if (!file)
|
||||
throw std::ios_base::failure("CAutoFile::read: file handle is nullptr");
|
||||
if (fread(pch, 1, nSize, file) != nSize)
|
||||
if (fread(dst.data(), 1, dst.size(), file) != dst.size()) {
|
||||
throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed");
|
||||
}
|
||||
}
|
||||
|
||||
void ignore(size_t nSize)
|
||||
@ -638,12 +640,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void write(const char* pch, size_t nSize)
|
||||
void write(Span<const std::byte> src)
|
||||
{
|
||||
if (!file)
|
||||
throw std::ios_base::failure("CAutoFile::write: file handle is nullptr");
|
||||
if (fwrite(pch, 1, nSize, file) != nSize)
|
||||
if (fwrite(src.data(), 1, src.size(), file) != src.size()) {
|
||||
throw std::ios_base::failure("CAutoFile::write: write failed");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -684,7 +687,7 @@ private:
|
||||
uint64_t nReadPos; //!< how many bytes have been read from this
|
||||
uint64_t nReadLimit; //!< up to which position we're allowed to read
|
||||
uint64_t nRewind; //!< how many bytes we guarantee to rewind
|
||||
std::vector<char> vchBuf; //!< the buffer
|
||||
std::vector<std::byte> vchBuf; //!< the buffer
|
||||
|
||||
protected:
|
||||
//! read data from the source to fill the buffer
|
||||
@ -705,8 +708,8 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
|
||||
nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, 0)
|
||||
CBufferedFile(FILE* fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn)
|
||||
: nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, std::byte{0})
|
||||
{
|
||||
if (nRewindIn >= nBufSize)
|
||||
throw std::ios_base::failure("Rewind limit must be less than buffer size");
|
||||
@ -739,22 +742,23 @@ public:
|
||||
}
|
||||
|
||||
//! read a number of bytes
|
||||
void read(char *pch, size_t nSize) {
|
||||
if (nSize + nReadPos > nReadLimit)
|
||||
void read(Span<std::byte> dst)
|
||||
{
|
||||
if (dst.size() + nReadPos > nReadLimit) {
|
||||
throw std::ios_base::failure("Read attempted past buffer limit");
|
||||
while (nSize > 0) {
|
||||
}
|
||||
while (dst.size() > 0) {
|
||||
if (nReadPos == nSrcPos)
|
||||
Fill();
|
||||
unsigned int pos = nReadPos % vchBuf.size();
|
||||
size_t nNow = nSize;
|
||||
size_t nNow = dst.size();
|
||||
if (nNow + pos > vchBuf.size())
|
||||
nNow = vchBuf.size() - pos;
|
||||
if (nNow + nReadPos > nSrcPos)
|
||||
nNow = nSrcPos - nReadPos;
|
||||
memcpy(pch, &vchBuf[pos], nNow);
|
||||
memcpy(dst.data(), &vchBuf[pos], nNow);
|
||||
nReadPos += nNow;
|
||||
pch += nNow;
|
||||
nSize -= nNow;
|
||||
dst = dst.subspan(nNow);
|
||||
}
|
||||
}
|
||||
|
||||
@ -797,12 +801,14 @@ public:
|
||||
}
|
||||
|
||||
//! search for a given byte in the stream, and remain positioned on it
|
||||
void FindByte(char ch) {
|
||||
void FindByte(uint8_t ch)
|
||||
{
|
||||
while (true) {
|
||||
if (nReadPos == nSrcPos)
|
||||
Fill();
|
||||
if (vchBuf[nReadPos % vchBuf.size()] == ch)
|
||||
if (vchBuf[nReadPos % vchBuf.size()] == std::byte{ch}) {
|
||||
break;
|
||||
}
|
||||
nReadPos++;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,6 @@ struct zero_after_free_allocator : public std::allocator<T> {
|
||||
};
|
||||
|
||||
/** Byte-vector that clears its contents before deletion. */
|
||||
using SerializeData = std::vector<uint8_t, zero_after_free_allocator<uint8_t>>;
|
||||
using SerializeData = std::vector<std::byte, zero_after_free_allocator<std::byte>>;
|
||||
|
||||
#endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H
|
||||
|
@ -41,8 +41,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
|
||||
stream << filter;
|
||||
|
||||
std::vector<uint8_t> expected = ParseHex("03614e9b050000000000000001");
|
||||
auto result{MakeUCharSpan(stream)};
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
|
||||
|
||||
BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!");
|
||||
}
|
||||
@ -67,8 +68,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
|
||||
stream << filter;
|
||||
|
||||
std::vector<uint8_t> expected = ParseHex("03ce4299050000000100008001");
|
||||
auto result{MakeUCharSpan(stream)};
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
|
||||
@ -87,8 +89,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
|
||||
stream << filter;
|
||||
|
||||
std::vector<unsigned char> expected = ParseHex("038fc16b080000000000000001");
|
||||
auto result{MakeUCharSpan(stream)};
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bloom_match)
|
||||
@ -443,8 +446,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
|
||||
merkleStream << merkleBlock;
|
||||
|
||||
std::vector<uint8_t> expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101");
|
||||
auto result{MakeUCharSpan(merkleStream)};
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), merkleStream.begin(), merkleStream.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), result.begin(), result.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(merkle_block_4)
|
||||
|
@ -22,16 +22,16 @@ FUZZ_TARGET(autofile)
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
[&] {
|
||||
std::array<uint8_t, 4096> arr{};
|
||||
std::array<std::byte, 4096> arr{};
|
||||
try {
|
||||
auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
|
||||
auto_file.read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
} catch (const std::ios_base::failure&) {
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
const std::array<uint8_t, 4096> arr{};
|
||||
const std::array<std::byte, 4096> arr{};
|
||||
try {
|
||||
auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
|
||||
auto_file.write({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
} catch (const std::ios_base::failure&) {
|
||||
}
|
||||
},
|
||||
|
@ -33,9 +33,9 @@ FUZZ_TARGET(buffered_file)
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
[&] {
|
||||
std::array<uint8_t, 4096> arr{};
|
||||
std::array<std::byte, 4096> arr{};
|
||||
try {
|
||||
opt_buffered_file->read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
|
||||
opt_buffered_file->read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
|
||||
} catch (const std::ios_base::failure&) {
|
||||
}
|
||||
},
|
||||
@ -53,7 +53,7 @@ FUZZ_TARGET(buffered_file)
|
||||
return;
|
||||
}
|
||||
try {
|
||||
opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>());
|
||||
opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<uint8_t>());
|
||||
} catch (const std::ios_base::failure&) {
|
||||
}
|
||||
},
|
||||
|
@ -215,11 +215,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
|
||||
stream >> deserialized_i8;
|
||||
assert(i8 == deserialized_i8 && stream.empty());
|
||||
|
||||
char deserialized_ch;
|
||||
stream << ch;
|
||||
stream >> deserialized_ch;
|
||||
assert(ch == deserialized_ch && stream.empty());
|
||||
|
||||
bool deserialized_b;
|
||||
stream << b;
|
||||
stream >> deserialized_b;
|
||||
|
@ -498,7 +498,6 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
WRITE_TO_STREAM_CASE(bool, fuzzed_data_provider.ConsumeBool()),
|
||||
WRITE_TO_STREAM_CASE(char, fuzzed_data_provider.ConsumeIntegral<char>()),
|
||||
WRITE_TO_STREAM_CASE(int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>()),
|
||||
WRITE_TO_STREAM_CASE(uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>()),
|
||||
WRITE_TO_STREAM_CASE(int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>()),
|
||||
@ -508,7 +507,7 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe
|
||||
WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()),
|
||||
WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()),
|
||||
WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)),
|
||||
WRITE_TO_STREAM_CASE(std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider)));
|
||||
WRITE_TO_STREAM_CASE(std::vector<uint8_t>, ConsumeRandomLengthIntegralVector<uint8_t>(fuzzed_data_provider)));
|
||||
} catch (const std::ios_base::failure&) {
|
||||
break;
|
||||
}
|
||||
@ -528,7 +527,6 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
READ_FROM_STREAM_CASE(bool),
|
||||
READ_FROM_STREAM_CASE(char),
|
||||
READ_FROM_STREAM_CASE(int8_t),
|
||||
READ_FROM_STREAM_CASE(uint8_t),
|
||||
READ_FROM_STREAM_CASE(int16_t),
|
||||
@ -538,7 +536,7 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no
|
||||
READ_FROM_STREAM_CASE(int64_t),
|
||||
READ_FROM_STREAM_CASE(uint64_t),
|
||||
READ_FROM_STREAM_CASE(std::string),
|
||||
READ_FROM_STREAM_CASE(std::vector<char>));
|
||||
READ_FROM_STREAM_CASE(std::vector<uint8_t>));
|
||||
} catch (const std::ios_base::failure&) {
|
||||
break;
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, uint32_t flag
|
||||
uint32_t libconsensus_flags{flags & dashconsensus_SCRIPT_FLAGS_VERIFY_ALL};
|
||||
if (libconsensus_flags == flags) {
|
||||
int expectedSuccessCode = expect ? 1 : 0;
|
||||
BOOST_CHECK_MESSAGE(dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
|
||||
BOOST_CHECK_MESSAGE(dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1421,7 +1421,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_returns_true)
|
||||
stream << spendTx;
|
||||
|
||||
dashconsensus_error err;
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
||||
BOOST_CHECK_EQUAL(result, 1);
|
||||
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_OK);
|
||||
}
|
||||
@ -1443,7 +1443,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_tx_index_err)
|
||||
stream << spendTx;
|
||||
|
||||
dashconsensus_error err;
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
||||
BOOST_CHECK_EQUAL(result, 0);
|
||||
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_TX_INDEX);
|
||||
}
|
||||
@ -1465,7 +1465,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_tx_size)
|
||||
stream << spendTx;
|
||||
|
||||
dashconsensus_error err;
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size() * 2, nIn, libconsensus_flags, &err);
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err);
|
||||
BOOST_CHECK_EQUAL(result, 0);
|
||||
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_TX_SIZE_MISMATCH);
|
||||
}
|
||||
@ -1487,7 +1487,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_tx_serialization)
|
||||
stream << 0xffffffff;
|
||||
|
||||
dashconsensus_error err;
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
||||
BOOST_CHECK_EQUAL(result, 0);
|
||||
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_TX_DESERIALIZE);
|
||||
}
|
||||
@ -1509,7 +1509,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_invalid_flags)
|
||||
stream << spendTx;
|
||||
|
||||
dashconsensus_error err;
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
|
||||
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
||||
BOOST_CHECK_EQUAL(result, 0);
|
||||
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_INVALID_FLAGS);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sizes)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(unsigned char), GetSerializeSize((unsigned char)0, 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
|
||||
@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(sizes)
|
||||
BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(bool(0), 0));
|
||||
|
||||
// Sanity-check GetSerializeSize and c++ type matching
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1U);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize((unsigned char)0, 0), 1U);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1U);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1U);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U);
|
||||
@ -186,76 +186,78 @@ BOOST_AUTO_TEST_CASE(noncanonical)
|
||||
std::vector<char>::size_type n;
|
||||
|
||||
// zero encoded with three bytes:
|
||||
ss.write("\xfd\x00\x00", 3);
|
||||
ss.write(MakeByteSpan("\xfd\x00\x00").first(3));
|
||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||
|
||||
// 0xfc encoded with three bytes:
|
||||
ss.write("\xfd\xfc\x00", 3);
|
||||
ss.write(MakeByteSpan("\xfd\xfc\x00").first(3));
|
||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||
|
||||
// 0xfd encoded with three bytes is OK:
|
||||
ss.write("\xfd\xfd\x00", 3);
|
||||
ss.write(MakeByteSpan("\xfd\xfd\x00").first(3));
|
||||
n = ReadCompactSize(ss);
|
||||
BOOST_CHECK(n == 0xfd);
|
||||
|
||||
// zero encoded with five bytes:
|
||||
ss.write("\xfe\x00\x00\x00\x00", 5);
|
||||
ss.write(MakeByteSpan("\xfe\x00\x00\x00\x00").first(5));
|
||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||
|
||||
// 0xffff encoded with five bytes:
|
||||
ss.write("\xfe\xff\xff\x00\x00", 5);
|
||||
ss.write(MakeByteSpan("\xfe\xff\xff\x00\x00").first(5));
|
||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||
|
||||
// zero encoded with nine bytes:
|
||||
ss.write("\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9);
|
||||
ss.write(MakeByteSpan("\xff\x00\x00\x00\x00\x00\x00\x00\x00").first(9));
|
||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||
|
||||
// 0x01ffffff encoded with nine bytes:
|
||||
ss.write("\xff\xff\xff\xff\x01\x00\x00\x00\x00", 9);
|
||||
ss.write(MakeByteSpan("\xff\xff\xff\xff\x01\x00\x00\x00\x00").first(9));
|
||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(insert_delete)
|
||||
{
|
||||
constexpr auto B2I{[](std::byte b) { return std::to_integer<uint8_t>(b); }};
|
||||
|
||||
// Test inserting/deleting bytes.
|
||||
CDataStream ss(SER_DISK, 0);
|
||||
BOOST_CHECK_EQUAL(ss.size(), 0U);
|
||||
|
||||
ss.write("\x00\x01\x02\xff", 4);
|
||||
ss.write(MakeByteSpan("\x00\x01\x02\xff").first(4));
|
||||
BOOST_CHECK_EQUAL(ss.size(), 4U);
|
||||
|
||||
char c = (char)11;
|
||||
uint8_t c{11};
|
||||
|
||||
// Inserting at beginning/end/middle:
|
||||
ss.insert(ss.begin(), c);
|
||||
ss.insert(ss.begin(), std::byte{c});
|
||||
BOOST_CHECK_EQUAL(ss.size(), 5U);
|
||||
BOOST_CHECK_EQUAL(ss[0], c);
|
||||
BOOST_CHECK_EQUAL(ss[1], 0);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[0]), c);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[1]), 0);
|
||||
|
||||
ss.insert(ss.end(), c);
|
||||
ss.insert(ss.end(), std::byte{c});
|
||||
BOOST_CHECK_EQUAL(ss.size(), 6U);
|
||||
BOOST_CHECK_EQUAL(ss[4], 0xff);
|
||||
BOOST_CHECK_EQUAL(ss[5], c);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[5]), c);
|
||||
|
||||
ss.insert(ss.begin()+2, c);
|
||||
ss.insert(ss.begin() + 2, std::byte{c});
|
||||
BOOST_CHECK_EQUAL(ss.size(), 7U);
|
||||
BOOST_CHECK_EQUAL(ss[2], c);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[2]), c);
|
||||
|
||||
// Delete at beginning/end/middle
|
||||
ss.erase(ss.begin());
|
||||
BOOST_CHECK_EQUAL(ss.size(), 6U);
|
||||
BOOST_CHECK_EQUAL(ss[0], 0);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[0]), 0);
|
||||
|
||||
ss.erase(ss.begin()+ss.size()-1);
|
||||
BOOST_CHECK_EQUAL(ss.size(), 5U);
|
||||
BOOST_CHECK_EQUAL(ss[4], 0xff);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff);
|
||||
|
||||
ss.erase(ss.begin()+1);
|
||||
BOOST_CHECK_EQUAL(ss.size(), 4U);
|
||||
BOOST_CHECK_EQUAL(ss[0], 0);
|
||||
BOOST_CHECK_EQUAL(ss[1], 1);
|
||||
BOOST_CHECK_EQUAL(ss[2], 2);
|
||||
BOOST_CHECK_EQUAL(ss[3], 0xff);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[0]), 0);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[1]), 1);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[2]), 2);
|
||||
BOOST_CHECK_EQUAL(B2I(ss[3]), 0xff);
|
||||
}
|
||||
|
||||
// Change struct size and check if it can be deserialized
|
||||
|
@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
||||
{
|
||||
std::vector<uint8_t> in;
|
||||
std::vector<std::byte> in;
|
||||
std::vector<char> expected_xor;
|
||||
std::vector<unsigned char> key;
|
||||
CDataStream ds(in, 0, 0);
|
||||
@ -174,8 +174,8 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
||||
std::string(expected_xor.begin(), expected_xor.end()),
|
||||
ds.str());
|
||||
|
||||
in.push_back('\x0f');
|
||||
in.push_back('\xf0');
|
||||
in.push_back(std::byte{0x0f});
|
||||
in.push_back(std::byte{0xf0});
|
||||
expected_xor.push_back('\xf0');
|
||||
expected_xor.push_back('\x0f');
|
||||
|
||||
@ -195,8 +195,8 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
||||
|
||||
in.clear();
|
||||
expected_xor.clear();
|
||||
in.push_back('\xf0');
|
||||
in.push_back('\x0f');
|
||||
in.push_back(std::byte{0xf0});
|
||||
in.push_back(std::byte{0x0f});
|
||||
expected_xor.push_back('\x0f');
|
||||
expected_xor.push_back('\x00');
|
||||
|
||||
|
@ -191,7 +191,7 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<CDBIterator> pcursor;
|
||||
std::pair<char, COutPoint> keyTmp;
|
||||
std::pair<uint8_t, COutPoint> keyTmp;
|
||||
|
||||
friend class CCoinsViewDB;
|
||||
};
|
||||
@ -299,7 +299,7 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, AddressType type
|
||||
pcursor->Seek(std::make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash)));
|
||||
|
||||
while (pcursor->Valid()) {
|
||||
std::pair<char,CAddressUnspentKey> key;
|
||||
std::pair<uint8_t, CAddressUnspentKey> key;
|
||||
if (pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.m_address_bytes == addressHash) {
|
||||
CAddressUnspentValue nValue;
|
||||
if (pcursor->GetValue(nValue)) {
|
||||
@ -343,7 +343,7 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, AddressType type,
|
||||
}
|
||||
|
||||
while (pcursor->Valid()) {
|
||||
std::pair<char,CAddressIndexKey> key;
|
||||
std::pair<uint8_t, CAddressIndexKey> key;
|
||||
if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.m_address_bytes == addressHash) {
|
||||
if (end > 0 && key.second.m_block_height > end) {
|
||||
break;
|
||||
@ -383,7 +383,7 @@ bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned i
|
||||
pcursor->Seek(std::make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low)));
|
||||
|
||||
while (pcursor->Valid()) {
|
||||
std::pair<char, CTimestampIndexKey> key;
|
||||
std::pair<uint8_t, CTimestampIndexKey> key;
|
||||
if (pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.m_block_time <= high) {
|
||||
hashes.push_back(key.second.m_block_hash);
|
||||
pcursor->Next();
|
||||
|
@ -78,13 +78,13 @@ public:
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
s.write((char*)m_data.data(), sizeof(m_data));
|
||||
s.write(MakeByteSpan(m_data));
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
s.read((char*)m_data.data(), sizeof(m_data));
|
||||
s.read(MakeWritableByteSpan(m_data));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5179,7 +5179,7 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
|
||||
try {
|
||||
// locate a header
|
||||
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
|
||||
blkdat.FindByte(char(m_params.MessageStart()[0]));
|
||||
blkdat.FindByte(m_params.MessageStart()[0]);
|
||||
nRewind = blkdat.GetPos() + 1;
|
||||
blkdat >> buf;
|
||||
if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
|
||||
|
@ -680,10 +680,10 @@ bool BerkeleyBatch::ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool&
|
||||
// Convert to streams
|
||||
ssKey.SetType(SER_DISK);
|
||||
ssKey.clear();
|
||||
ssKey.write((char*)datKey.get_data(), datKey.get_size());
|
||||
ssKey.write({BytePtr(datKey.get_data()), datKey.get_size()});
|
||||
ssValue.SetType(SER_DISK);
|
||||
ssValue.clear();
|
||||
ssValue.write((char*)datValue.get_data(), datValue.get_size());
|
||||
ssValue.write({BytePtr(datValue.get_data()), datValue.get_size()});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -755,7 +755,7 @@ bool BerkeleyBatch::ReadKey(CDataStream&& key, CDataStream& value)
|
||||
SafeDbt datValue;
|
||||
int ret = pdb->get(activeTxn, datKey, datValue, 0);
|
||||
if (ret == 0 && datValue.get_data() != nullptr) {
|
||||
value.write((char*)datValue.get_data(), datValue.get_size());
|
||||
value.write({BytePtr(datValue.get_data()), datValue.get_size()});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -394,9 +394,9 @@ bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value)
|
||||
return false;
|
||||
}
|
||||
// Leftmost column in result is index 0
|
||||
const char* data = reinterpret_cast<const char*>(sqlite3_column_blob(m_read_stmt, 0));
|
||||
int data_size = sqlite3_column_bytes(m_read_stmt, 0);
|
||||
value.write(data, data_size);
|
||||
const std::byte* data{BytePtr(sqlite3_column_blob(m_read_stmt, 0))};
|
||||
size_t data_size(sqlite3_column_bytes(m_read_stmt, 0));
|
||||
value.write({data, data_size});
|
||||
|
||||
sqlite3_clear_bindings(m_read_stmt);
|
||||
sqlite3_reset(m_read_stmt);
|
||||
@ -511,12 +511,12 @@ bool SQLiteBatch::ReadAtCursor(CDataStream& key, CDataStream& value, bool& compl
|
||||
}
|
||||
|
||||
// Leftmost column in result is index 0
|
||||
const char* key_data = reinterpret_cast<const char*>(sqlite3_column_blob(m_cursor_stmt, 0));
|
||||
int key_data_size = sqlite3_column_bytes(m_cursor_stmt, 0);
|
||||
key.write(key_data, key_data_size);
|
||||
const char* value_data = reinterpret_cast<const char*>(sqlite3_column_blob(m_cursor_stmt, 1));
|
||||
int value_data_size = sqlite3_column_bytes(m_cursor_stmt, 1);
|
||||
value.write(value_data, value_data_size);
|
||||
const std::byte* key_data{BytePtr(sqlite3_column_blob(m_cursor_stmt, 0))};
|
||||
size_t key_data_size(sqlite3_column_bytes(m_cursor_stmt, 0));
|
||||
key.write({key_data, key_data_size});
|
||||
const std::byte* value_data{BytePtr(sqlite3_column_blob(m_cursor_stmt, 1))};
|
||||
size_t value_data_size(sqlite3_column_bytes(m_cursor_stmt, 1));
|
||||
value.write({value_data, value_data_size});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user