Cereal 序列化 CString Vector
Cereal serialize CString Vector
编辑:// 由于下面的答案,它开始工作了,添加了当前正在工作的代码和测试用例,以防有人发现它有用。
// Add as another type for Cereal or inside string.hpp in Cereal includes
template<class Archive> inline
void CEREAL_SAVE_FUNCTION_NAME(Archive & ar, CString str)
{
// Save number of chars + the data
size_type size = (str.GetLength() + 1) * sizeof(TCHAR);
ar(size);
ar(binary_data(str.GetBuffer(), static_cast<std::size_t>(size)));
str.ReleaseBuffer();
}
template<class Archive> inline
void CEREAL_LOAD_FUNCTION_NAME(Archive & ar, CString & str)
{
size_type size;
ar(size);
ar(binary_data(str.GetBuffer(static_cast<std::size_t>(size)), static_cast<std::size_t>(size)));
str.ReleaseBuffer();
}
下面是我用来测试的代码,它正确输出了向量的所有元素。
class Stuff
{
public:
Stuff() {}
std::vector<CString> vec;
private:
friend class cereal::access;
template <class Archive>
void serialize(Archive & ar)
{
ar(vec);
}
};
int main()
{
Stuff myStuff, otherStuff;
myStuff.vec.push_back(L"Testing different length CStrings");
myStuff.vec.push_back(L"Separator");
myStuff.vec.push_back(L"Is it working yet??");
myStuff.vec.push_back(L"1234567890");
myStuff.vec.push_back(L"TestingTestingTestingtestingTesting");
{
std::ofstream file("out.txt", std::ios::binary);
cereal::BinaryOutputArchive output(file);
output(myStuff);
}
{
std::ifstream file("out.txt", std::ios::binary);
cereal::BinaryInputArchive input(file);
input(otherStuff);
}
int nSize = otherStuff.vec.size();
for (int x = 0; x < nSize; x++)
{
std::wcout << (LPCWSTR)otherStuff.vec[x] << std::endl;
}
return 0;
}
感谢 Barmak Shemirani 的帮助。
如果你的序列化class知道如何处理std::vector<std::string>
(你应该用不同大小的字符串测试它)它可能也知道如何处理CString
(宽字符版本)通过将其视为二进制数据,假设文件以二进制形式打开。
需要这些标志才能在 Windows 中以二进制模式打开:
std::ofstream file("out.txt", std::ios::binary);
std::ifstream file("out.txt", std::ios::binary);
如果序列化class使用文本文件存储,那么就不要使用二进制方式,看下一行:
或者,您可以将 CString
(UTF16) 转换为 UTF8
std::vector<std::string> vec;
vec.push_back((const char*)CW2A(L"abc-unicode-ελληνική", CP_UTF8));
从存档中读取后,您必须转换回 CString
:
CString s = CA2W(vec[0].c_str(), CP_UTF8);
在二进制中,使用正确的大小来保存 CString
。类似于:
CEREAL_SAVE_FUNCTION_NAME...
size_type size = (str.GetLength() + 1) * sizeof(TCHAR);
ar(size);
ar(binary_data(str.GetBuffer(), size));
str.ReleaseBuffer();
读入 CString
时,通过调用 str.GetBuffer(size)
而非 str.GetBuffer()
确保缓冲区足够大代码应如下所示:
CEREAL_LOAD_FUNCTION_NAME...
size_type size;
ar(size);
ar(binary_data(str.GetBuffer(size), size);
str.ReleaseBuffer();
要序列化向量,请保存向量的维度,然后保存每个向量元素。读取向量维度,然后从存档中读取那么多元素。除非你的序列化 class 对此有自动化。
编辑:// 由于下面的答案,它开始工作了,添加了当前正在工作的代码和测试用例,以防有人发现它有用。
// Add as another type for Cereal or inside string.hpp in Cereal includes
template<class Archive> inline
void CEREAL_SAVE_FUNCTION_NAME(Archive & ar, CString str)
{
// Save number of chars + the data
size_type size = (str.GetLength() + 1) * sizeof(TCHAR);
ar(size);
ar(binary_data(str.GetBuffer(), static_cast<std::size_t>(size)));
str.ReleaseBuffer();
}
template<class Archive> inline
void CEREAL_LOAD_FUNCTION_NAME(Archive & ar, CString & str)
{
size_type size;
ar(size);
ar(binary_data(str.GetBuffer(static_cast<std::size_t>(size)), static_cast<std::size_t>(size)));
str.ReleaseBuffer();
}
下面是我用来测试的代码,它正确输出了向量的所有元素。
class Stuff
{
public:
Stuff() {}
std::vector<CString> vec;
private:
friend class cereal::access;
template <class Archive>
void serialize(Archive & ar)
{
ar(vec);
}
};
int main()
{
Stuff myStuff, otherStuff;
myStuff.vec.push_back(L"Testing different length CStrings");
myStuff.vec.push_back(L"Separator");
myStuff.vec.push_back(L"Is it working yet??");
myStuff.vec.push_back(L"1234567890");
myStuff.vec.push_back(L"TestingTestingTestingtestingTesting");
{
std::ofstream file("out.txt", std::ios::binary);
cereal::BinaryOutputArchive output(file);
output(myStuff);
}
{
std::ifstream file("out.txt", std::ios::binary);
cereal::BinaryInputArchive input(file);
input(otherStuff);
}
int nSize = otherStuff.vec.size();
for (int x = 0; x < nSize; x++)
{
std::wcout << (LPCWSTR)otherStuff.vec[x] << std::endl;
}
return 0;
}
感谢 Barmak Shemirani 的帮助。
如果你的序列化class知道如何处理std::vector<std::string>
(你应该用不同大小的字符串测试它)它可能也知道如何处理CString
(宽字符版本)通过将其视为二进制数据,假设文件以二进制形式打开。
需要这些标志才能在 Windows 中以二进制模式打开:
std::ofstream file("out.txt", std::ios::binary);
std::ifstream file("out.txt", std::ios::binary);
如果序列化class使用文本文件存储,那么就不要使用二进制方式,看下一行:
或者,您可以将 CString
(UTF16) 转换为 UTF8
std::vector<std::string> vec;
vec.push_back((const char*)CW2A(L"abc-unicode-ελληνική", CP_UTF8));
从存档中读取后,您必须转换回 CString
:
CString s = CA2W(vec[0].c_str(), CP_UTF8);
在二进制中,使用正确的大小来保存
CString
。类似于:
CEREAL_SAVE_FUNCTION_NAME...
size_type size = (str.GetLength() + 1) * sizeof(TCHAR);
ar(size);
ar(binary_data(str.GetBuffer(), size));
str.ReleaseBuffer();
读入 CString
时,通过调用 str.GetBuffer(size)
而非 str.GetBuffer()
确保缓冲区足够大代码应如下所示:
CEREAL_LOAD_FUNCTION_NAME...
size_type size;
ar(size);
ar(binary_data(str.GetBuffer(size), size);
str.ReleaseBuffer();
要序列化向量,请保存向量的维度,然后保存每个向量元素。读取向量维度,然后从存档中读取那么多元素。除非你的序列化 class 对此有自动化。