#ifndef OMNISTREAM_SIMPLEVERSIONEDSERIALIZATION_H
#define OMNISTREAM_SIMPLEVERSIONEDSERIALIZATION_H
#include <vector>
#include <stdexcept>
#include <memory>
#include "core/include/common.h"
#include "core/memory/DataOutputSerializer.h"
#include "core/io/SimpleVersionedSerializer.h"
#include "SimpleVersionedSerializer.h"
class SimpleVersionedSerialization {
public:
template <typename T>
static void writeVersionAndSerialize(
SimpleVersionedSerializer<T>& serializer, const T& obj, DataOutputSerializer& out)
{
std::vector<uint8_t> serialized = serializer.serialize(obj);
out.writeInt(serializer.getVersion());
out.writeInt(serialized.size());
out.write(serialized.data(), serialized.size(), 0, serialized.size());
}
template <typename T>
static void writeVersionAndSerializeList(
SimpleVersionedSerializer<T>& serializer, const std::vector<T>& objList, DataOutputSerializer& out)
{
out.writeInt(serializer.getVersion());
out.writeInt(objList.size());
for (const T& obj : objList) {
std::vector<uint8_t> serialized = serializer.serialize(obj);
out.writeInt(serialized.size());
out.write(serialized.data(), serialized.size(), 0, serialized.size());
}
}
template <typename T>
static std::vector<uint8_t> writeVersionAndSerialize(SimpleVersionedSerializer<T>& serializer, const T& obj)
{
std::vector<uint8_t> result;
int version = serializer.getVersion();
result.push_back((version >> 24) & 0xFF);
result.push_back((version >> 16) & 0xFF);
result.push_back((version >> 8) & 0xFF);
result.push_back(version & 0xFF);
std::vector<uint8_t> serialized = serializer.serialize(obj);
int length = serialized.size();
result.push_back((length >> 24) & 0xFF);
result.push_back((length >> 16) & 0xFF);
result.push_back((length >> 8) & 0xFF);
result.push_back(length & 0xFF);
result.insert(result.end(), serialized.begin(), serialized.end());
return result;
}
template <typename T>
static T* readVersionAndDeSerialize(SimpleVersionedSerializer<T>& serializer, std::vector<uint8_t>& bytes)
{
if (bytes.size() < 8) {
INFO_RELEASE("Exception: Insufficient data for version deserialization, size=" << bytes.size());
throw std::runtime_error("Insufficient data for version deserialization");
}
int version = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
int length = (bytes[4] << 24) | (bytes[5] << 16) | (bytes[6] << 8) | bytes[7];
std::vector<uint8_t> serializedData(bytes.begin() + 8, bytes.end());
return serializer.deserialize(version, serializedData);
}
template <typename T>
static T* readVersionAndDeSerialize(SimpleVersionedSerializer<T>& serializer, DataInputDeserializer& input)
{
int version = input.readInt();
int dataSize = input.readInt();
std::vector<uint8_t> data(dataSize);
input.readFully(data.data(), dataSize, 0, dataSize);
return serializer.deserialize(version, data);
}
template <typename T>
static std::vector<T>* readVersionAndDeserializeList(
SimpleVersionedSerializer<T>& serializer, DataInputDeserializer& in)
{
int serializerVersion = in.readInt();
int dataSize = in.readInt();
std::vector<T>* data = new std::vector<T>();
data->reserve(dataSize);
for (int ignored = 0; ignored < dataSize; ++ignored) {
int datumSize = in.readInt();
std::vector<uint8_t> datum(datumSize);
in.readFully(datum.data(), datumSize, 0, datumSize);
T* element = serializer.deserialize(serializerVersion, datum);
data->push_back(std::move(*element));
}
return data;
}
};
#endif