Subject: Re: [Boost-bugs] [Boost C++ Libraries] #11981: boost::archive::xml_woarchive with locale dosen't work
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-09-29 10:38:08
#11981: boost::archive::xml_woarchive with locale dosen't work
-------------------------+-------------------------------------------------
Reporter: anonymous | Owner: Robert Ramey
Type: Bugs | Status: reopened
Milestone: To Be | Component: serialization
Determined |
Version: Boost | Severity: Regression
1.65.0 | Keywords: locale, xml_woarchive,
Resolution: | serialization
-------------------------+-------------------------------------------------
Changes (by matsu):
* status: closed => reopened
* version: Boost 1.60.0 => Boost 1.65.0
* resolution: wontfix =>
Comment:
This problem still exists on boost 1.65.1.
Platform. Windows 10 Japanese 64bit. Visual Studio 2017 Update 1.
Abort is called at this line.
{{{
oa << boost::serialization::make_nvp("string", std::string("æ¥æ¬èªæåå
"));
}}}
This is because std::string is not always UTF-8 encoding.
It depends on the locale, in my case it is Shift_JIS encording.
But utf8_codecvt_facet is always used in xml_woarchive_impl.ipp.
I have changed utf8_codecvt_facet to mbstowcs_s and it works well.
mbstowcs_s refers the locale and converts accordingly.
xml_woarchive_impl.ipp
{{{
#define BOOST_NO_UTF8 // my change
#ifdef BOOST_NO_UTF8
#include <stdlib.h>
#else
#include <boost/archive/iterators/wchar_from_mb.hpp>
#endif
// copy chars to output escaping to xml and widening characters as we go
template<class InputIterator>
void save_iterator(std::wostream &os, InputIterator begin, InputIterator
end){
#ifdef BOOST_NO_UTF8
std::size_t len = end - begin + 1;
std::vector<wchar_t> dst(len);
if (::mbstowcs_s(&len, dst.data(), len, begin, len - 1) != 0) {
throw std::system_error(errno, std::system_category());
}
std::copy(
dst.data(),
dst.data() + len - 1,
boost::archive::iterators::ostream_iterator<wchar_t>(os)
);
#else
typedef iterators::wchar_from_mb<
iterators::xml_escape<InputIterator>
> xmbtows;
std::copy(
xmbtows(begin),
xmbtows(end),
boost::archive::iterators::ostream_iterator<wchar_t>(os)
);
#endif
}
}}}
xml_wiarchive_impl.ipp
{{{
#define BOOST_NO_UTF8 // my change
#ifdef BOOST_NO_UTF8
#include <stdlib.h>
#else
#include <boost/archive/iterators/wchar_from_mb.hpp>
#endif
void copy_to_ptr(char * s, const std::wstring & ws){
#ifdef BOOST_NO_UTF8
std::size_t len = ws.size() * sizeof(wchar_t) + 1;
if (::wcstombs_s(&len, s, len, ws.c_str(), len - 1) != 0) {
throw std::system_error(errno, std::system_category());
}
#else
std::copy(
iterators::mb_from_wchar<std::wstring::const_iterator>(
ws.begin()
),
iterators::mb_from_wchar<std::wstring::const_iterator>(
ws.end()
),
s
);
s[ws.size()] = 0;
#endif
}
template<class Archive>
BOOST_WARCHIVE_DECL void
xml_wiarchive_impl<Archive>::load(std::string & s){
std::wstring ws;
bool result = gimpl->parse_string(is, ws);
if(! result)
boost::serialization::throw_exception(
xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
);
#if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
if(NULL != s.data())
#endif
s.resize(0);
#ifdef BOOST_NO_UTF8
std::size_t len = ws.size() * sizeof(wchar_t) + 1;
s.resize(len);
if (::wcstombs_s(&len, &s[0], len, ws.c_str(), _TRUNCATE) != 0) {
throw std::system_error(errno, std::system_category());
}
s.resize(len - 1);
#else
s.reserve(ws.size());
std::copy(
iterators::mb_from_wchar<std::wstring::iterator>(
ws.begin()
),
iterators::mb_from_wchar<std::wstring::iterator>(
ws.end()
),
std::back_inserter(s)
);
#endif
}
}}}
-- Ticket URL: <https://svn.boost.org/trac10/boost/ticket/11981#comment:7> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-09-29 10:44:22 UTC