使用boost序列化的UnicodeString

icu::UnicodeString with boost serialize

本文关键字:UnicodeString 序列化 boost 使用      更新时间:2023-10-16

我正在尝试用boost序列化库序列化icu::UnicodeString,但我遇到了麻烦。

icu::UnicodeString没有序列化它所需的序列化函数。所以我试着创造它,但我不确定如何制作这些。示例代码:

#include <map>
#include <sstream>
#include <fstream>
#include <unicode/unistr.h>
#include <unicode/ustream.h>
#include <boost/serialization/map.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
namespace boost {
namespace serialization {
template<class Archive>
inline void save(
    Archive & ar,
    const icu_55::UnicodeString& str,
    const unsigned int /* file_version */
){
}
template<class Archive>
inline void load(
    Archive & ar,
    icu_55::UnicodeString& str,
    const unsigned int /* file_version */
){
}
// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive>
inline void serialize(
    Archive & ar,
    icu_55::UnicodeString& str,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, str, file_version);
}
} // serialization
} // namespace boost
int main()
{
   std::map<icu::UnicodeString, int> map = {{"asssdasd",2}, {"qwe",1}, {"Zxc",55}};
   std::stringstream ss;
   boost::archive::text_oarchive oarch(ss);
   oarch << map;
   std::map<icu::UnicodeString, int> new_map;
   boost::archive::text_iarchive iarch(ss);
   iarch >> new_map;
   std::cout << (map == new_map) << std::endl;
}

编译g++ -o new new.cpp -std=c++11 -lboost_serialization -licuuc

目前未实现"保存"answers"加载"功能。我试着只做在boost手册中使用的ar & str;语句,但我得到了一个分割错误,我也无法修复。

我从来没有直接使用过LibICU,所以也许有人可以检查一下这段代码。

然而,从我使用Boost序列化的经验来看,我认为这应该是有帮助的:

template <class Archive>
inline void save(Archive &ar, icu_55::UnicodeString const &str, const unsigned int) {
    auto sz = str.getCapacity();
    auto len = str.length();
    auto buf = str.getBuffer();
    if (!buf) throw std::invalid_argument("str");
    ar & sz & len & boost::serialization::make_array(buf, sz);
}
template <class Archive>
inline void load(Archive &ar, icu_55::UnicodeString &str, const unsigned int)
{
    size_t sz, len;
    ar & sz & len;
    auto buf = str.getBuffer(sz);
    if (!buf) throw std::invalid_argument("str");
    try {
        ar & boost::serialization::make_array(buf, sz);
    } 
    catch(...) {
        str.releaseBuffer(len);
        throw;
    }
    str.releaseBuffer(len);
}

它适用于提供的简单测试用例:

#include <fstream>
#include <map>
#include <sstream>
#include <iostream>
#include <unicode/unistr.h>
#include <unicode/ustream.h>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/map.hpp>
namespace boost { namespace serialization {
    template <class Archive>
    inline void save(Archive &ar, icu_55::UnicodeString const &str, const unsigned int) {
        auto sz = str.getCapacity();
        auto len = str.length();
        auto buf = str.getBuffer();
        if (!buf) throw std::invalid_argument("str");
        ar & sz & len & boost::serialization::make_array(buf, sz);
    }
    template <class Archive>
    inline void load(Archive &ar, icu_55::UnicodeString &str, const unsigned int)
    {
        size_t sz, len;
        ar & sz & len;
        auto buf = str.getBuffer(sz);
        if (!buf) throw std::invalid_argument("str");
        try {
            ar & boost::serialization::make_array(buf, sz);
        } 
        catch(...) {
            str.releaseBuffer(len);
            throw;
        }
        str.releaseBuffer(len);
    }

    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template <class Archive>
    inline void serialize(Archive &ar, icu_55::UnicodeString &str, const unsigned int file_version) {
        boost::serialization::split_free(ar, str, file_version);
    }
} } // serialization // namespace boost
int main() {
    std::map<icu::UnicodeString, int> const map = { { "asssdasd", 2 }, { "qwe", 1 }, { "Zxc", 55 } };
    std::stringstream ss;
    {
        boost::archive::text_oarchive oarch(ss);
        oarch << map;
    }
    {
        std::map<icu::UnicodeString, int> new_map;
        boost::archive::text_iarchive iarch(ss);
        iarch >> new_map;
        std::cout << (map == new_map) << std::endl;
    }
}

打印

1