c++ - 使用 XML 宽存档 boost juce::String 的反序列化问题

标签 c++ serialization boost

我正在使用 boost::serialize 来序列化我使用 f.i 的文档。一个 juce::String。像这样:

template<class Archive>
void serialize( Archive & ar, const unsigned int version )
{
    ar & boost::serialization::make_nvp("title", m_docTitle);
    ...
}

为了让 boost::serialize 接受 juce::String 作为原始类型,我做了:

#include <boost/serialization/string.hpp>

template<class IStream>
inline IStream& operator >> (IStream& stream, juce::String& s)
{
    std::wstring t;
    stream >> t;
    s = juce::String(t.c_str());
    return stream;
}

BOOST_CLASS_IMPLEMENTATION(juce::String, boost::serialization::primitive_type)

编译得很好。序列化工作正常,我得到了 XML 中的条目:

<title>DocumentTitle</title>

本应如此。但是,在反序列化时,我可以在 >> 运算符中跟踪返回的字符串是:

"DocumentTitle</title>"

即一些 XML 已被“分解”,这当然会导致“输入流错误”异常。

最奇怪的是,直到一周前我才开始工作... :( 我不知道是什么让它现在不起作用...

编辑:显示重现行为的一个小示例代码,唯一的依赖是 boost :

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>

#include <boost/archive/xml_woarchive.hpp>
#include <boost/archive/xml_wiarchive.hpp>
#include <sstream>

class JuceString
{
public:
    JuceString(const std::wstring& str = L"") : m_str(str) {;}
    JuceString(const JuceString& other) : m_str(other.m_str) {;}
    JuceString& operator = (const JuceString& other)
    {
        if (this != &other)
        {
            m_str = other.m_str;
        }
        return *this;
    }
    const wchar_t* toWideCharPointer() const {
        return m_str.c_str();
    }

private:
    std::wstring m_str;
};

template <class OStream>
OStream& operator<< (OStream& stream, const JuceString& stringToWrite)
{
    return stream << stringToWrite.toWideCharPointer();
}

template <class IStream>
IStream& operator>> (IStream& stream, JuceString& s)
{
    std::wstring t;
    stream >> t;
    s = JuceString(t.c_str());
    return stream;
}

BOOST_CLASS_IMPLEMENTATION(JuceString, boost::serialization::primitive_type)


class Doc
{
    friend class boost::serialization::access;

    template<class Archive>
    void serialize( Archive & ar, const unsigned int version )
    {
        ar & boost::serialization::make_nvp("title", m_title);
    }

public:
    Doc() {;}
    Doc(const std::wstring& s) : m_title(s) {;}

private:
    JuceString m_title;
};


int main (int argc, char* argv[])
{
    std::wstringstream stream;
    {
        // Serializing document
        Doc doc(L"DocumentTitle");
        boost::archive::xml_woarchive oa(stream);
        oa << boost::serialization::make_nvp("Document", doc);
    }
    {
        // Deserializing document
        Doc doc;
        try
        {
            boost::archive::xml_wiarchive ia(stream);
            ia >> boost::serialization::make_nvp("Document", doc);
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

    }
    return 0;
}

使用文本存档代替两种方式都很好......

最佳答案

最后,我通过使用 boost basic_xml_grammar 来解析 operator>> 中的字符串,让它开始工作(对于 XML 归档 nota bene),如下所示:

typedef boost::archive::basic_xml_grammar<wchar_t> xml_wgrammar;

template <class IStream>
IStream& operator>> (IStream& stream, JuceString& s)
{
    std::wstring t;
    xml_wgrammar grammar;
    if (!grammar.parse_string(stream, t))
    {
        boost::serialization::throw_exception(
            boost::archive::xml_archive_exception(boost::archive::xml_archive_exception::xml_archive_parsing_error)
        );
    }
    s = JuceString(t.c_str());
    return stream;
}

这将确保字符串被正确解析。

关于c++ - 使用 XML 宽存档 boost juce::String 的反序列化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6126133/

相关文章:

c++ - 有间接仿函数吗?

.net - DataContractSerializer 与 XmlSerializer : Pros and Cons of each serializer

c++ - 正则表达式搜索匹配不使用组

c++ - union 中的 boost::optional<>?

c++ - Boost 二进制文件读取错误 unsupported version

c++ - boost multi_index_container、范围变异算法和常量

c++ - 出于对 SO 中旧帖子的好奇,如何使用智能指针进行类型删除

c++ - Int to Float to Int转换精度损失

c++ - 非菱形继承(钻石问题)树中的虚拟继承 - 内存和行为副作用

iphone - NSJSONSerialization 出错 - JSON 写入中的类型无效(菜单)