序列化(Serialization)
是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化
std::array<int, 1> arr = {147};
std::initializer_list<int> lst = {951, 623};
std::vector<int> vec = {123, 456, 789};
ntl::Serialization ser2 = ntl::Serializer::serialize(arr);
ntl::Serialization ser3 = ntl::Serializer::serialize(lst);
ntl::Serialization ser4 = ntl::Serializer::serialize(vec);
反序列化
std::vector<int> vec2;
std::vector<int> vec3;
std::vector<int> vec4;
ntl::Deserializer::deserialize(ser2, vec2);
ntl::Deserializer::deserialize(ser3, vec3);
ntl::Deserializer::deserialize(ser4, vec4);
序列化的代码算不上多,但也不少,可以在github上找到完整版
Serializable就是能被序列化的对象,有三个接口:
virtual Serialization serialize() = 0;
virtual Serialization serialize() const = 0;
virtual SelfType &deserialize(const Serialization &serialization) = 0;
用于序列化与反序列化
/// @brief 可序列化的对象
class NTL_ALIGN Serializable : public Object
{
public:
using SelfType = Serializable;
using ParentType = Object;
public:
constexpr Serializable() noexcept = default;
constexpr explicit Serializable(const SelfType &from) noexcept = default;
~Serializable() override = default;
public:
constexpr SelfType &operator=(const SelfType &from) noexcept = default;
public:
/// @brief 序列化本对象
/// @return 序列
virtual Serialization serialize() = 0;
/// @brief 序列化本对象
/// @return 序列
virtual Serialization serialize() const = 0;
/// @brief 反序列化至本对象
/// @param serialization 序列
/// @return 本对象
virtual SelfType &deserialize(const Serialization &serialization) = 0;
};
Serialization就更简单的,就是一封装了的字符串
/// @brief 序列
class NTL_ALIGN Serialization : public Object
{
public:
using SelfType = Serialization;
using ParentType = Object;
protected:
/// @brief 序列
String m_serialization;
public:
Serialization() = default;
explicit Serialization(const String &serialization);
explicit Serialization(const SelfType &from) = default;
~Serialization() override = default;
public:
SelfType &operator=(const SelfType &from) = default;
operator String();
operator String() const;
public:
/// @brief 获取序列
/// @return 序列
const ntl::String &get_serialization() const;
/// @brief 设置序列
/// @param serialization 序列
/// @return 本对象
SelfType &set_serialization(const ntl::String &serialization);
};
Serializer主要负责序列化基础类型
/// @brief 序列化器
class NTL_ALIGN Serializer : public Object
{
public:
using SelfType = Serializer;
using ParentType = Object;
public:
Serializer() = default;
explicit Serializer(const SelfType &from) = default;
~Serializer() override = default;
public:
SelfType &operator=(const SelfType &from) = default;
public:
static Serialization serialize(const Serializable &object);
static Serialization serialize(char value);
template <typename ValueType>
static Serialization serialize(const ValueType &value);
template <typename CharTraitsType, typename AllocatorType>
static Serialization serialize(const std::basic_string<Char, CharTraitsType, AllocatorType> &str);
template <typename ElementType, std::size_t size>
static Serialization serialize(const std::array<ElementType, size> &container);
template <typename ElementType, typename AllocatorType>
static Serialization serialize(const std::vector<ElementType, AllocatorType> &container);
template <typename ElementType>
static Serialization serialize(const std::initializer_list<ElementType> &container);
template <typename IteratorType>
static Serialization serialize_container(const IteratorType &begin, const IteratorType &end);
template <typename ElementType>
static Serialization serialize_container(const ElementType *begin, SizeT size);
};
Deserializer也是一样的,但是多了对序列的检查
其中用于检测的正则表达式长这样:
String Deserializer::regex_is_integer = NTL_STRING("[0-9]+");
String Deserializer::regex_is_float0 = NTL_STRING("[0-9]+[fd]?");
String Deserializer::regex_is_float1 = NTL_STRING("[0-9]+.[fd]?");
String Deserializer::regex_is_float2 = NTL_STRING(".[0-9]+[fd]?");
String Deserializer::regex_is_float3 = NTL_STRING("[0-9]+.[0-9]+[fd]?");
String Deserializer::regex_is_string = NTL_STRING("\"(.*)\"");
/// @brief 反序列化器
class NTL_ALIGN Deserializer : public Object
{
public:
using SelfType = Deserializer;
using ParentType = Object;
/// @brief 整数
static String regex_is_integer;
/// @brief 浮点数,形如123
static String regex_is_float0;
/// @brief 浮点数,形如123.
static String regex_is_float1;
/// @brief 浮点数,形如.123
static String regex_is_float2;
/// @brief 浮点数,形如123.123
static String regex_is_float3;
/// @brief 是否为字符串,形如"abc"
static String regex_is_string;
public:
Deserializer() = default;
explicit Deserializer(const SelfType &from) = default;
~Deserializer() override = default;
public:
SelfType &operator=(const SelfType &from) = default;
public:
template <typename ResultType>
static ResultType deserialize(const Serialization &serialization);
static void deserialize(const Serialization &serialization, Serializable &result);
static void deserialize(const Serialization &serialization, char &result);
static void deserialize(const Serialization &serialization, short &result);
static void deserialize(const Serialization &serialization, int &result);
static void deserialize(const Serialization &serialization, long &result);
static void deserialize(const Serialization &serialization, long long &result);
static void deserialize(const Serialization &serialization, float &result);
static void deserialize(const Serialization &serialization, double &result);
template <typename CharTraitsType, typename AllocatorType>
static void deserialize(const Serialization &serialization, std::basic_string<Char, CharTraitsType, AllocatorType> &result);
template <typename ElementType>
static void deserialize(const Serialization &serialization, std::vector<ElementType> &result);
public:
/// @brief 生成一个异常
/// @param type 类型
/// @return 异常
static InvalidArgumentException make_exception(const String &type);
/// @brief 检查是否为整数
/// @param serialization 序列
/// @return 是否为整数
static bool is_integer(const Serialization &serialization);
/// @brief 检查是否为浮点数
/// @param serialization 序列
/// @return 是否为浮点数
static bool is_float(const Serialization &serialization);
/// @brief 检查是否为字符串
/// @param serialization 序列
/// @return 是否为字符串
static bool is_string(const Serialization &serialization);
};