diff --git a/data/Deserializer.h b/data/Deserializer.h index ec77f2bc..2a2d99ea 100644 --- a/data/Deserializer.h +++ b/data/Deserializer.h @@ -19,13 +19,15 @@ namespace cpputils { int32_t readInt32(); uint64_t readUint64(); int64_t readInt64(); - Data readData(); std::string readString(); + Data readData(); + Data readTailData(); void finished(); private: template DataType _read(); + Data _readData(size_t size); size_t _pos; const Data *_source; @@ -84,6 +86,15 @@ namespace cpputils { if (_pos + size > _source->size()) { throw std::runtime_error("Deserialization failed - size overflow"); } + return _readData(size); + } + + inline Data Deserializer::readTailData() { + uint64_t size = _source->size() - _pos; + return _readData(size); + } + + inline Data Deserializer::_readData(uint64_t size) { Data result(size); std::memcpy(static_cast(result.data()), static_cast(_source->dataOffset(_pos)), size); _pos += size; diff --git a/data/Serializer.h b/data/Serializer.h index e308c729..f1f8b42c 100644 --- a/data/Serializer.h +++ b/data/Serializer.h @@ -4,6 +4,7 @@ #include "Data.h" #include "../macros.h" +#include "../assert/assert.h" #include namespace cpputils { @@ -21,8 +22,12 @@ namespace cpputils { void writeInt32(int32_t value); void writeUint64(uint64_t value); void writeInt64(int64_t value); - void writeData(const Data &value); void writeString(const std::string &value); + void writeData(const Data &value); + + // Write the data as last element when serializing. + // It does not store a data size but limits the size by the size of the serialization result + void writeTailData(const Data &value); static size_t DataSize(const Data &value); static size_t StringSize(const std::string &value); @@ -31,6 +36,7 @@ namespace cpputils { private: template void _write(DataType obj); + void _writeData(const Data &value); size_t _pos; Data _result; @@ -85,6 +91,19 @@ namespace cpputils { inline void Serializer::writeData(const Data &data) { writeUint64(data.size()); + _writeData(data); + } + + inline size_t Serializer::DataSize(const Data &data) { + return sizeof(uint64_t) + data.size(); + } + + inline void Serializer::writeTailData(const Data &data) { + ASSERT(_pos + data.size() == _result.size(), "Not enough data given to write until the end of the stream"); + _writeData(data); + } + + inline void Serializer::_writeData(const Data &data) { if (_pos + data.size() > _result.size()) { throw std::runtime_error("Serialization failed - size overflow"); } @@ -92,10 +111,6 @@ namespace cpputils { _pos += data.size(); } - inline size_t Serializer::DataSize(const Data &data) { - return sizeof(uint64_t) + data.size(); - } - inline void Serializer::writeString(const std::string &value) { size_t size = value.size() + 1; // +1 for the nullbyte if (_pos + size > _result.size()) {