Skip to content

Commit 947133d

Browse files
Jim Posenjimpo
authored andcommitted
streams: Create VectorReader stream interface for vectors.
This is a read analogue for the existing CVectorWriter.
1 parent 021dce9 commit 947133d

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

src/streams.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,80 @@ class CVectorWriter
139139
size_t nPos;
140140
};
141141

142+
/** Minimal stream for reading from an existing vector by reference
143+
*/
144+
class VectorReader
145+
{
146+
private:
147+
const int m_type;
148+
const int m_version;
149+
const std::vector<unsigned char>& m_data;
150+
size_t m_pos = 0;
151+
152+
public:
153+
154+
/*
155+
* @param[in] type Serialization Type
156+
* @param[in] version Serialization Version (including any flags)
157+
* @param[in] data Referenced byte vector to overwrite/append
158+
* @param[in] pos Starting position. Vector index where reads should start.
159+
*/
160+
VectorReader(int type, int version, const std::vector<unsigned char>& data, size_t pos)
161+
: m_type(type), m_version(version), m_data(data)
162+
{
163+
seek(pos);
164+
}
165+
166+
/*
167+
* (other params same as above)
168+
* @param[in] args A list of items to deserialize starting at pos.
169+
*/
170+
template <typename... Args>
171+
VectorReader(int type, int version, const std::vector<unsigned char>& data, size_t pos,
172+
Args&&... args)
173+
: VectorReader(type, version, data, pos)
174+
{
175+
::UnserializeMany(*this, std::forward<Args>(args)...);
176+
}
177+
178+
template<typename T>
179+
VectorReader& operator>>(T& obj)
180+
{
181+
// Unserialize from this stream
182+
::Unserialize(*this, obj);
183+
return (*this);
184+
}
185+
186+
int GetVersion() const { return m_version; }
187+
int GetType() const { return m_type; }
188+
189+
size_t size() const { return m_data.size() - m_pos; }
190+
bool empty() const { return m_data.size() == m_pos; }
191+
192+
void read(char* dst, size_t n)
193+
{
194+
if (n == 0) {
195+
return;
196+
}
197+
198+
// Read from the beginning of the buffer
199+
size_t pos_next = m_pos + n;
200+
if (pos_next > m_data.size()) {
201+
throw std::ios_base::failure("VectorReader::read(): end of data");
202+
}
203+
memcpy(dst, m_data.data() + m_pos, n);
204+
m_pos = pos_next;
205+
}
206+
207+
void seek(size_t n)
208+
{
209+
m_pos += n;
210+
if (m_pos > m_data.size()) {
211+
throw std::ios_base::failure("VectorReader::seek(): end of data");
212+
}
213+
}
214+
};
215+
142216
/** Double ended buffer combining vector and stream-like interfaces.
143217
*
144218
* >> and << read and write unformatted data using the above serialization templates.

0 commit comments

Comments
 (0)