如何load/savewxStringfrom/towxStream或wxMemoryBuffer?
How to load/save wxString from/to wxStream or wxMemoryBuffer?
我有自己的 class (nBuffer) 就像 wxMemoryBuffer 我用它来 load/save 自定义数据,它比使用流更方便,因为我有很多针对不同数据类型的重载方法基于这些:
class nBuffer
{ // ...
bool wr(void* buf, long unsigned int length);// write
bool rd(void* buf, long unsigned int length);// read
}
我正在尝试为 load/save wxString from/to 这个缓冲区实现方法。
对于 wxWidgets 2.8,我使用了下一个代码(简化):
bool nBuffer::wrString(wxString s)
{ // save string:
int32 lng=s.Length()*4;
wr(&lng,4);// length
wr(s.GetData(),lng);// string itself
return true;
}
bool nBuffer::rdString(wxString &s)
{ // load string:
uint32 lng;
rd(&lng,4);// length
s.Alloc(lng);
rd(s.GetWriteBuf(lng),lng);// string itself
s.UngetWriteBuf();
s=s.Left(lng/4);
return true;
}
此代码不好,因为:
假设每个字符串字符有4个字节的数据(可能更少),
使用 wxWidgets 3.0,wxString.GetData()
returns wxCStrData
而不是 *void
,所以编译器在 wr(s.GetData(),lng);
上失败,我有不知道如何将其转换为简单的字节缓冲区。
奇怪,但我发现 什么都没有 谷歌搜索了几个小时...而且我在 wxWidgets 文档中没有发现任何有用的东西。
题目是:
这是将wxString转换为字节缓冲区的首选、正确且安全的方式,
同样将字节缓冲区转换回wxString。
对于任意的 wxString,您需要将它们序列化为 UTF-8 或 UTF-16 格式。前者是数据交换的事实上的标准,所以我建议使用它,但如果您知道您的数据偏向于使用 space 少于 space 的字符,您可能更喜欢 UTF-16 UTF-8 并且 space 保存对您很重要。
假设您使用 UTF-8,序列化是使用 utf8_str()
方法完成的:
wxScopedCharBuffer const utf8 = s.utf8_str();
wr(utf8.data(), utf8.length());
反序列化就像使用 wxString::FromUTF8(data, length)
.
一样简单
对于 UTF-16,您可以使用通用的 mb_str(wxMBConvUTF16)
和 wxString(data, wxMBConvUTF16, length)
方法,这些方法也可以与 wxMBConvUTF8
一起使用,但上面的 UTF-8 特定方法更方便并且,在某些构建配置中,效率更高。
我有自己的 class (nBuffer) 就像 wxMemoryBuffer 我用它来 load/save 自定义数据,它比使用流更方便,因为我有很多针对不同数据类型的重载方法基于这些:
class nBuffer
{ // ...
bool wr(void* buf, long unsigned int length);// write
bool rd(void* buf, long unsigned int length);// read
}
我正在尝试为 load/save wxString from/to 这个缓冲区实现方法。 对于 wxWidgets 2.8,我使用了下一个代码(简化):
bool nBuffer::wrString(wxString s)
{ // save string:
int32 lng=s.Length()*4;
wr(&lng,4);// length
wr(s.GetData(),lng);// string itself
return true;
}
bool nBuffer::rdString(wxString &s)
{ // load string:
uint32 lng;
rd(&lng,4);// length
s.Alloc(lng);
rd(s.GetWriteBuf(lng),lng);// string itself
s.UngetWriteBuf();
s=s.Left(lng/4);
return true;
}
此代码不好,因为:
假设每个字符串字符有4个字节的数据(可能更少),
使用 wxWidgets 3.0,
wxString.GetData()
returnswxCStrData
而不是*void
,所以编译器在wr(s.GetData(),lng);
上失败,我有不知道如何将其转换为简单的字节缓冲区。
奇怪,但我发现 什么都没有 谷歌搜索了几个小时...而且我在 wxWidgets 文档中没有发现任何有用的东西。
题目是:
这是将wxString转换为字节缓冲区的首选、正确且安全的方式,
同样将字节缓冲区转换回wxString。
对于任意的 wxString,您需要将它们序列化为 UTF-8 或 UTF-16 格式。前者是数据交换的事实上的标准,所以我建议使用它,但如果您知道您的数据偏向于使用 space 少于 space 的字符,您可能更喜欢 UTF-16 UTF-8 并且 space 保存对您很重要。
假设您使用 UTF-8,序列化是使用 utf8_str()
方法完成的:
wxScopedCharBuffer const utf8 = s.utf8_str();
wr(utf8.data(), utf8.length());
反序列化就像使用 wxString::FromUTF8(data, length)
.
对于 UTF-16,您可以使用通用的 mb_str(wxMBConvUTF16)
和 wxString(data, wxMBConvUTF16, length)
方法,这些方法也可以与 wxMBConvUTF8
一起使用,但上面的 UTF-8 特定方法更方便并且,在某些构建配置中,效率更高。