Serileştirmeyi uygulamak için aşağıdaki şablonu kullanıyorum:
template <class T, class Mode = void> struct Serializer
{
template <class OutputCharIterator>
static void serializeImpl(const T &object, OutputCharIterator &&it)
{
object.template serializeThis<Mode>(it);
}
template <class InputCharIterator>
static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
{
return T::template deserializeFrom<Mode>(it, end);
}
};
template <class Mode = void, class T, class OutputCharIterator>
void serialize(const T &object, OutputCharIterator &&it)
{
Serializer<T, Mode>::serializeImpl(object, it);
}
template <class T, class Mode = void, class InputCharIterator>
T deserialize(InputCharIterator &&it, InputCharIterator &&end)
{
return Serializer<T, Mode>::deserializeImpl(it, end);
}
template <class Mode = void, class T, class InputCharIterator>
void deserialize(T &result, InputCharIterator &&it, InputCharIterator &&end)
{
result = Serializer<T, Mode>::deserializeImpl(it, end);
}
İşte T
size serialize istediğiniz tip olduğu Mode
gibi serileştirme farklı türde birbirinden ayırt edebilmek için kukla türüdür. aynı tamsayı küçük endian, büyük endian, varint vb.
Varsayılan olarak Serializer
, görevi serileştirilen nesneye delege eder. Yerleşik türler için bir şablon uzmanlığı yapmalısınız Serializer
.
Kolaylık fonksiyonu şablonları da sunulmaktadır.
Örneğin, işaretsiz tam sayıların küçük endian serileştirmesi:
struct LittleEndianMode
{
};
template <class T>
struct Serializer<
T, std::enable_if_t<std::is_unsigned<T>::value, LittleEndianMode>>
{
template <class InputCharIterator>
static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
{
T res = 0;
for (size_t i = 0; i < sizeof(T); i++)
{
if (it == end) break;
res |= static_cast<T>(*it) << (CHAR_BIT * i);
it++;
}
return res;
}
template <class OutputCharIterator>
static void serializeImpl(T number, OutputCharIterator &&it)
{
for (size_t i = 0; i < sizeof(T); i++)
{
*it = (number >> (CHAR_BIT * i)) & 0xFF;
it++;
}
}
};
Sonra serileştirmek için:
std::vector<char> serialized;
uint32_t val = 42;
serialize<LittleEndianMode>(val, std::back_inserter(serialized));
Serisini kaldırmak için:
uint32_t val;
deserialize(val, serialized.begin(), serialized.end());
Soyut yineleyici mantığı nedeniyle, herhangi bir yineleyici (örn. Akış yineleyicileri), işaretçi vb.