isolated one problem with codecvt facets

This commit is contained in:
Robert Ramey
2015-10-22 04:42:22 -07:00
parent 53a0388fec
commit a64bf6e4d5
20 changed files with 89 additions and 107 deletions

View File

@@ -52,6 +52,7 @@ namespace std{
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/codecvt_null.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
@@ -77,7 +78,15 @@ public:
}
#ifndef BOOST_NO_STD_LOCALE
// note order! - if you change this, libstd++ will fail!
// a) create new locale with new codecvt facet
// b) save current locale
// c) change locale to new one
// d) use stream buffer
// e) change locale back to original
// f) destroy new codecvt facet
boost::archive::codecvt_null<Elem> codecvt_null_facet;
basic_streambuf_locale_saver<Elem, Tr> locale_saver;
std::locale archive_locale;
#endif

View File

@@ -47,6 +47,7 @@ namespace std{
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/codecvt_null.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
@@ -72,7 +73,15 @@ public:
return static_cast<Archive *>(this);
}
#ifndef BOOST_NO_STD_LOCALE
// note order! - if you change this, libstd++ will fail!
// a) create new locale with new codecvt facet
// b) save current locale
// c) change locale to new one
// d) use stream buffer
// e) change locale back to original
// f) destroy new codecvt facet
boost::archive::codecvt_null<Elem> codecvt_null_facet;
basic_streambuf_locale_saver<Elem, Tr> locale_saver;
std::locale archive_locale;
#endif
// default saving of primitives.

View File

@@ -45,19 +45,10 @@ class basic_streambuf_locale_saver :
private boost::noncopyable
{
public:
typedef ::std::basic_streambuf<Ch, Tr> state_type;
typedef ::std::locale aspect_type;
explicit basic_streambuf_locale_saver(std::basic_streambuf<Ch, Tr> &s) :
m_streambuf(s),
m_locale(s.getloc())
{}
explicit basic_streambuf_locale_saver(
std::basic_streambuf<Ch, Tr> &s,
std::locale const &l
) :
m_streambuf(s),
m_locale(s.pubimbue(l))
{}
~basic_streambuf_locale_saver(){
m_streambuf.pubsync();
m_streambuf.pubimbue(m_locale);

View File

@@ -68,12 +68,19 @@ protected:
io::ios_precision_saver precision_saver;
#ifndef BOOST_NO_STD_LOCALE
basic_streambuf_locale_saver<
typename IStream::char_type,
typename IStream::traits_type
> locale_saver;
// note order! - if you change this, libstd++ will fail!
// a) create new locale with new codecvt facet
// b) save current locale
// c) change locale to new one
// d) use stream buffer
// e) change locale back to original
// f) destroy new codecvt facet
boost::archive::codecvt_null<typename IStream::char_type> codecvt_null_facet;
std::locale archive_locale;
basic_streambuf_locale_saver<
typename IStream::char_type,
typename IStream::traits_type
> locale_saver;
#endif
template<class T>

View File

@@ -52,9 +52,9 @@ namespace std{
#include <boost/integer.hpp>
#include <boost/io/ios_state.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/codecvt_null.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -71,12 +71,19 @@ protected:
io::ios_precision_saver precision_saver;
#ifndef BOOST_NO_STD_LOCALE
// note order! - if you change this, libstd++ will fail!
// a) create new locale with new codecvt facet
// b) save current locale
// c) change locale to new one
// d) use stream buffer
// e) change locale back to original
// f) destroy new codecvt facet
boost::archive::codecvt_null<typename OStream::char_type> codecvt_null_facet;
std::locale archive_locale;
basic_streambuf_locale_saver<
typename OStream::char_type,
typename OStream::traits_type
> locale_saver;
boost::archive::codecvt_null<typename OStream::char_type> codecvt_null_facet;
std::locale archive_locale;
#endif
/////////////////////////////////////////////////////////

View File

@@ -40,7 +40,7 @@ class basic_pointer_oserializer;
//////////////////////////////////////////////////////////////////////
// class basic_oarchive - write serialized objects to an output stream
class BOOST_SYMBOL_VISIBLE basic_oarchive :
class BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_oarchive :
private boost::noncopyable,
public boost::archive::detail::helper_collection
{
@@ -59,20 +59,20 @@ class BOOST_SYMBOL_VISIBLE basic_oarchive :
virtual void vsave(const class_name_type & t) = 0;
virtual void vsave(const tracking_type t) = 0;
protected:
BOOST_ARCHIVE_DECL basic_oarchive(unsigned int flags = 0);
BOOST_ARCHIVE_DECL boost::archive::detail::helper_collection &
BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_oarchive(unsigned int flags = 0);
BOOST_ARCHIVE_OR_WARCHIVE_DECL boost::archive::detail::helper_collection &
get_helper_collection();
virtual BOOST_ARCHIVE_DECL ~basic_oarchive();
virtual BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_oarchive();
public:
// note: NOT part of the public interface
BOOST_ARCHIVE_DECL void register_basic_serializer(
BOOST_ARCHIVE_OR_WARCHIVE_DECL void register_basic_serializer(
const basic_oserializer & bos
);
BOOST_ARCHIVE_DECL void save_object(
BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_object(
const void *x,
const basic_oserializer & bos
);
BOOST_ARCHIVE_DECL void save_pointer(
BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_pointer(
const void * t,
const basic_pointer_oserializer * bpos_ptr
);
@@ -80,9 +80,9 @@ public:
vsave(NULL_POINTER_TAG);
}
// real public interface starts here
BOOST_ARCHIVE_DECL void end_preamble(); // default implementation does nothing
BOOST_ARCHIVE_DECL library_version_type get_library_version() const;
BOOST_ARCHIVE_DECL unsigned int get_flags() const;
BOOST_ARCHIVE_OR_WARCHIVE_DECL void end_preamble(); // default implementation does nothing
BOOST_ARCHIVE_OR_WARCHIVE_DECL library_version_type get_library_version() const;
BOOST_ARCHIVE_OR_WARCHIVE_DECL unsigned int get_flags() const;
};
} // namespace detail

View File

@@ -7,6 +7,8 @@
#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
#include <boost/config.hpp>
#ifdef BOOST_NO_CXX11_HDR_CODECVT
#define BOOST_UTF8_BEGIN_NAMESPACE \
namespace boost { namespace archive { namespace detail {
@@ -18,6 +20,11 @@
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_DECL
#undef BOOST_UTF8_BEGIN_NAMESPACE
#else
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif // BOOST_NO_CXX11_HDR_CODECVT
#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP

View File

@@ -148,7 +148,8 @@ basic_binary_iprimitive<Archive, Elem, Tr>::basic_binary_iprimitive(
#ifndef BOOST_NO_STD_LOCALE
m_sb(sb),
codecvt_null_facet(1),
archive_locale(sb.getloc(), & codecvt_null_facet)
archive_locale(sb.getloc(), & codecvt_null_facet),
locale_saver(m_sb)
{
if(! no_codecvt){
m_sb.pubimbue(archive_locale);

View File

@@ -101,7 +101,8 @@ basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
#ifndef BOOST_NO_STD_LOCALE
m_sb(sb),
codecvt_null_facet(1),
archive_locale(sb.getloc(), & codecvt_null_facet)
archive_locale(sb.getloc(), & codecvt_null_facet),
locale_saver(m_sb)
{
if(! no_codecvt){
m_sb.pubimbue(archive_locale);
@@ -112,6 +113,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
{}
#endif
/*
// some libraries including stl and libcomo fail if the
// buffer isn't flushed before the code_cvt facet is changed.
// I think this is a bug. We explicity invoke sync to when
@@ -133,21 +135,13 @@ class output_streambuf_access : public std::basic_streambuf<Elem, Tr> {
}
};
} // detail
*/
// scoped_ptr requires that g be a complete type at time of
// destruction so define destructor here rather than in the header
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_oprimitive<Archive, Elem, Tr>::~basic_binary_oprimitive(){
// flush buffer
//destructor can't throw
BOOST_TRY{
static_cast<detail::output_streambuf_access<Elem, Tr> &>(m_sb).sync();
}
BOOST_CATCH(...){
}
BOOST_CATCH_END
}
basic_binary_oprimitive<Archive, Elem, Tr>::~basic_binary_oprimitive(){}
} // namespace archive
} // namespace boost

View File

@@ -8,8 +8,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cstddef> // size_t
#include <cstddef> // NULL
#include <cstddef> // size_t, NULL
#include <limits> // NULL
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)

View File

@@ -157,7 +157,7 @@ xml_wiarchive_impl<Archive>::xml_wiarchive_impl(
),
basic_xml_iarchive<Archive>(flags),
codecvt_utf8_facet(1),
archive_locale(is_.getloc(), & codecvt_utf8_facet),
archive_locale(is_.rdbuf()->getloc(), & codecvt_utf8_facet),
gimpl(new xml_wgrammar())
{
if(0 == (flags & no_codecvt)){

View File

@@ -120,13 +120,7 @@ xml_woarchive_impl<Archive>::xml_woarchive_impl(
),
basic_xml_oarchive<Archive>(flags),
codecvt_utf8_facet(1),
archive_locale(os_.getloc(), & codecvt_utf8_facet)
{
// Standard behavior is that imbue can be called
// a) before output is invoked or
// b) after flush has been called. This prevents one-to-many
// transforms (such as one to many transforms from getting
// mixed up.
archive_locale(os_.rdbuf()->getloc(), & codecvt_utf8_facet){
if(0 == (flags & no_codecvt)){
os.rdbuf()->pubimbue(archive_locale);
}

View File

@@ -26,15 +26,7 @@ namespace std{
using ::mbstate_t;
} // namespace std
#endif
#ifdef BOOST_NO_CXX11_HDR_CODECVT
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#else
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
namespace boost {

View File

@@ -21,7 +21,6 @@
#include <cstddef> // size_t
#include <cwchar> // mbstate_t
#include <algorithm> // copy
#include <boost/array.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
@@ -29,18 +28,11 @@ namespace std{
using ::mbstate_t;
} // namespace std
#endif
#ifdef BOOST_NO_CXX11_HDR_CODECVT
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#else
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif
#include <boost/serialization/throw_exception.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
#include <boost/array.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <iostream>

View File

@@ -29,15 +29,7 @@
#include <boost/archive/basic_xml_iarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/serialization/item_version_type.hpp>
#ifdef BOOST_NO_CXX11_HDR_CODECVT
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#else
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header

View File

@@ -20,7 +20,6 @@
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <cstddef> // size_t
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
@@ -36,15 +35,7 @@ namespace std{
#include <boost/archive/basic_xml_oarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/serialization/item_version_type.hpp>
#ifdef BOOST_NO_CXX11_HDR_CODECVT
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#else
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header