mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-10-11 03:53:22 +02:00
net: add CVectorWriter and CNetMsgMaker
CVectorWriter is useful for overwriting or appending an existing byte vector. CNetMsgMaker is a shortcut for creating messages on-the-fly which are suitable for pushing to CConnman.
This commit is contained in:
@@ -69,6 +69,75 @@ OverrideStream<S> WithOrVersion(S* s, int nVersionFlag)
|
||||
return OverrideStream<S>(s, s->GetType(), s->GetVersion() | nVersionFlag);
|
||||
}
|
||||
|
||||
/* Minimal stream for overwriting and/or appending to an existing byte vector
|
||||
*
|
||||
* The referenced vector will grow as necessary
|
||||
*/
|
||||
class CVectorWriter
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
* @param[in] nTypeIn Serialization Type
|
||||
* @param[in] nVersionIn Serialization Version (including any flags)
|
||||
* @param[in] vchDataIn Referenced byte vector to overwrite/append
|
||||
* @param[in] nPosIn Starting position. Vector index where writes should start. The vector will initially
|
||||
* grow as necessary to max(index, vec.size()). So to append, use vec.size().
|
||||
*/
|
||||
CVectorWriter(int nTypeIn, int nVersionIn, std::vector<unsigned char>& vchDataIn, size_t nPosIn) : nType(nTypeIn), nVersion(nVersionIn), vchData(vchDataIn), nPos(nPosIn)
|
||||
{
|
||||
if(nPos > vchData.size())
|
||||
vchData.resize(nPos);
|
||||
}
|
||||
/*
|
||||
* (other params same as above)
|
||||
* @param[in] args A list of items to serialize starting at nPos.
|
||||
*/
|
||||
template <typename... Args>
|
||||
CVectorWriter(int nTypeIn, int nVersionIn, std::vector<unsigned char>& vchDataIn, size_t nPosIn, Args&&... args) : CVectorWriter(nTypeIn, nVersionIn, vchDataIn, nPosIn)
|
||||
{
|
||||
::SerializeMany(*this, std::forward<Args>(args)...);
|
||||
}
|
||||
void write(const char* pch, size_t nSize)
|
||||
{
|
||||
assert(nPos <= vchData.size());
|
||||
size_t nOverwrite = std::min(nSize, vchData.size() - nPos);
|
||||
if (nOverwrite) {
|
||||
memcpy(vchData.data() + nPos, reinterpret_cast<const unsigned char*>(pch), nOverwrite);
|
||||
}
|
||||
if (nOverwrite < nSize) {
|
||||
vchData.insert(vchData.end(), reinterpret_cast<const unsigned char*>(pch) + nOverwrite, reinterpret_cast<const unsigned char*>(pch) + nSize);
|
||||
}
|
||||
nPos += nSize;
|
||||
}
|
||||
template<typename T>
|
||||
CVectorWriter& operator<<(const T& obj)
|
||||
{
|
||||
// Serialize to this stream
|
||||
::Serialize(*this, obj);
|
||||
return (*this);
|
||||
}
|
||||
int GetVersion() const
|
||||
{
|
||||
return nVersion;
|
||||
}
|
||||
int GetType() const
|
||||
{
|
||||
return nType;
|
||||
}
|
||||
void seek(size_t nSize)
|
||||
{
|
||||
nPos += nSize;
|
||||
if(nPos > vchData.size())
|
||||
vchData.resize(nPos);
|
||||
}
|
||||
private:
|
||||
const int nType;
|
||||
const int nVersion;
|
||||
std::vector<unsigned char>& vchData;
|
||||
size_t nPos;
|
||||
};
|
||||
|
||||
/** Double ended buffer combining vector and stream-like interfaces.
|
||||
*
|
||||
* >> and << read and write unformatted data using the above serialization templates.
|
||||
|
Reference in New Issue
Block a user