Minimal stream for overwriting and/or appending to an existing byte vector * * The referenced vector will grow as necessary */
| 32 | * The referenced vector will grow as necessary |
| 33 | */ |
| 34 | class VectorWriter |
| 35 | { |
| 36 | public: |
| 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> |
| 69 | VectorWriter& operator<<(const T& obj) |
| 70 | { |
| 71 | ::Serialize(*this, obj); |
| 72 | return (*this); |
| 73 | } |
| 74 | |
| 75 | private: |
| 76 | std::vector<unsigned char>& vchData; |
| 77 | size_t nPos; |
| 78 | }; |
| 79 | |
| 80 | /** Minimal stream for reading from an existing byte array by std::span. |
| 81 | */ |
nothing calls this directly
no test coverage detected