1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 2// xml_wiarchive_impl.ipp: 3 4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 5// Distributed under the Boost Software License, Version 1.0. (See 6// accompanying file LICENSE_1_0.txt or copy at 7// http://www.boost.org/LICENSE_1_0.txt) 8 9// See http://www.boost.org for updates, documentation, and revision history. 10 11#include <cstring> 12#if defined(BOOST_NO_STDC_NAMESPACE) 13namespace std{ 14 using ::memcpy; 15} //std 16#endif 17 18#include <boost/config.hpp> // msvc 6.0 needs this to suppress warnings 19#ifndef BOOST_NO_STD_WSTREAMBUF 20 21#include <boost/assert.hpp> 22#include <algorithm> // std::copy 23#include <boost/detail/workaround.hpp> // Dinkumware and RogueWave 24#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) 25#include <boost/archive/dinkumware.hpp> 26#endif 27 28#include <boost/io/ios_state.hpp> 29#include <boost/core/uncaught_exceptions.hpp> 30#include <boost/core/no_exceptions_support.hpp> 31#include <boost/serialization/string.hpp> 32 33#include <boost/archive/basic_xml_archive.hpp> 34#include <boost/archive/xml_wiarchive.hpp> 35 36#include <boost/archive/xml_archive_exception.hpp> 37#include <boost/archive/iterators/mb_from_wchar.hpp> 38 39#include <boost/archive/detail/utf8_codecvt_facet.hpp> 40 41#include "basic_xml_grammar.hpp" 42 43namespace boost { 44namespace archive { 45 46/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 47// implemenations of functions specific to wide char archives 48 49namespace { // anonymous 50 51void copy_to_ptr(char * s, const std::wstring & ws){ 52 std::copy( 53 iterators::mb_from_wchar<std::wstring::const_iterator>( 54 ws.begin() 55 ), 56 iterators::mb_from_wchar<std::wstring::const_iterator>( 57 ws.end() 58 ), 59 s 60 ); 61 s[ws.size()] = 0; 62} 63 64} // anonymous 65 66template<class Archive> 67BOOST_WARCHIVE_DECL void 68xml_wiarchive_impl<Archive>::load(std::string & s){ 69 std::wstring ws; 70 bool result = gimpl->parse_string(is, ws); 71 if(! result) 72 boost::serialization::throw_exception( 73 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) 74 ); 75 #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) 76 if(NULL != s.data()) 77 #endif 78 s.resize(0); 79 s.reserve(ws.size()); 80 std::copy( 81 iterators::mb_from_wchar<std::wstring::iterator>( 82 ws.begin() 83 ), 84 iterators::mb_from_wchar<std::wstring::iterator>( 85 ws.end() 86 ), 87 std::back_inserter(s) 88 ); 89} 90 91#ifndef BOOST_NO_STD_WSTRING 92template<class Archive> 93BOOST_WARCHIVE_DECL void 94xml_wiarchive_impl<Archive>::load(std::wstring & ws){ 95 bool result = gimpl->parse_string(is, ws); 96 if(! result) 97 boost::serialization::throw_exception( 98 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) 99 ); 100} 101#endif 102 103template<class Archive> 104BOOST_WARCHIVE_DECL void 105xml_wiarchive_impl<Archive>::load(char * s){ 106 std::wstring ws; 107 bool result = gimpl->parse_string(is, ws); 108 if(! result) 109 boost::serialization::throw_exception( 110 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) 111 ); 112 copy_to_ptr(s, ws); 113} 114 115#ifndef BOOST_NO_INTRINSIC_WCHAR_T 116template<class Archive> 117BOOST_WARCHIVE_DECL void 118xml_wiarchive_impl<Archive>::load(wchar_t * ws){ 119 std::wstring twstring; 120 bool result = gimpl->parse_string(is, twstring); 121 if(! result) 122 boost::serialization::throw_exception( 123 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) 124 ); 125 std::memcpy(ws, twstring.c_str(), twstring.size()); 126 ws[twstring.size()] = L'\0'; 127} 128#endif 129 130template<class Archive> 131BOOST_WARCHIVE_DECL void 132xml_wiarchive_impl<Archive>::load_override(class_name_type & t){ 133 const std::wstring & ws = gimpl->rv.class_name; 134 if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) 135 boost::serialization::throw_exception( 136 archive_exception(archive_exception::invalid_class_name) 137 ); 138 copy_to_ptr(t, ws); 139} 140 141template<class Archive> 142BOOST_WARCHIVE_DECL void 143xml_wiarchive_impl<Archive>::init(){ 144 gimpl->init(is); 145 this->set_library_version( 146 boost::serialization::library_version_type(gimpl->rv.version) 147 ); 148} 149 150template<class Archive> 151BOOST_WARCHIVE_DECL 152xml_wiarchive_impl<Archive>::xml_wiarchive_impl( 153 std::wistream &is_, 154 unsigned int flags 155) : 156 basic_text_iprimitive<std::wistream>( 157 is_, 158 true // don't change the codecvt - use the one below 159 ), 160 basic_xml_iarchive<Archive>(flags), 161 gimpl(new xml_wgrammar()) 162{ 163 if(0 == (flags & no_codecvt)){ 164 archive_locale = std::locale( 165 is_.getloc(), 166 new boost::archive::detail::utf8_codecvt_facet 167 ); 168 // libstdc++ crashes without this 169 is_.sync(); 170 is_.imbue(archive_locale); 171 } 172} 173 174template<class Archive> 175BOOST_WARCHIVE_DECL 176xml_wiarchive_impl<Archive>::~xml_wiarchive_impl(){ 177 if(boost::core::uncaught_exceptions() > 0) 178 return; 179 if(0 == (this->get_flags() & no_header)){ 180 gimpl->windup(is); 181 } 182} 183 184} // namespace archive 185} // namespace boost 186 187#endif // BOOST_NO_STD_WSTREAMBUF 188