streams: Create VectorReader stream interface for vectors.
This is a read analogue for the existing CVectorWriter.
This commit is contained in:
parent
021dce935a
commit
947133dec9
1 changed files with 74 additions and 0 deletions
|
@ -139,6 +139,80 @@ private:
|
||||||
size_t nPos;
|
size_t nPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Minimal stream for reading from an existing vector by reference
|
||||||
|
*/
|
||||||
|
class VectorReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const int m_type;
|
||||||
|
const int m_version;
|
||||||
|
const std::vector<unsigned char>& m_data;
|
||||||
|
size_t m_pos = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param[in] type Serialization Type
|
||||||
|
* @param[in] version Serialization Version (including any flags)
|
||||||
|
* @param[in] data Referenced byte vector to overwrite/append
|
||||||
|
* @param[in] pos Starting position. Vector index where reads should start.
|
||||||
|
*/
|
||||||
|
VectorReader(int type, int version, const std::vector<unsigned char>& data, size_t pos)
|
||||||
|
: m_type(type), m_version(version), m_data(data)
|
||||||
|
{
|
||||||
|
seek(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (other params same as above)
|
||||||
|
* @param[in] args A list of items to deserialize starting at pos.
|
||||||
|
*/
|
||||||
|
template <typename... Args>
|
||||||
|
VectorReader(int type, int version, const std::vector<unsigned char>& data, size_t pos,
|
||||||
|
Args&&... args)
|
||||||
|
: VectorReader(type, version, data, pos)
|
||||||
|
{
|
||||||
|
::UnserializeMany(*this, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
VectorReader& operator>>(T& obj)
|
||||||
|
{
|
||||||
|
// Unserialize from this stream
|
||||||
|
::Unserialize(*this, obj);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetVersion() const { return m_version; }
|
||||||
|
int GetType() const { return m_type; }
|
||||||
|
|
||||||
|
size_t size() const { return m_data.size() - m_pos; }
|
||||||
|
bool empty() const { return m_data.size() == m_pos; }
|
||||||
|
|
||||||
|
void read(char* dst, size_t n)
|
||||||
|
{
|
||||||
|
if (n == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from the beginning of the buffer
|
||||||
|
size_t pos_next = m_pos + n;
|
||||||
|
if (pos_next > m_data.size()) {
|
||||||
|
throw std::ios_base::failure("VectorReader::read(): end of data");
|
||||||
|
}
|
||||||
|
memcpy(dst, m_data.data() + m_pos, n);
|
||||||
|
m_pos = pos_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
void seek(size_t n)
|
||||||
|
{
|
||||||
|
m_pos += n;
|
||||||
|
if (m_pos > m_data.size()) {
|
||||||
|
throw std::ios_base::failure("VectorReader::seek(): end of data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** Double ended buffer combining vector and stream-like interfaces.
|
/** Double ended buffer combining vector and stream-like interfaces.
|
||||||
*
|
*
|
||||||
* >> and << read and write unformatted data using the above serialization templates.
|
* >> and << read and write unformatted data using the above serialization templates.
|
||||||
|
|
Loading…
Add table
Reference in a new issue